mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-02-22 14:22:40 +01:00
Lightning: Allow specifying explicit amount for invoices (#3753)
* Upgrade Lightning lib * Lightning: Allow specifying explicit amount for invoices * Fix tests
This commit is contained in:
parent
f3f605a90f
commit
6d76771b16
8 changed files with 21 additions and 30 deletions
|
@ -29,7 +29,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="NBitcoin" Version="7.0.1" />
|
<PackageReference Include="NBitcoin" Version="7.0.1" />
|
||||||
<PackageReference Include="BTCPayServer.Lightning.Common" Version="1.3.2" />
|
<PackageReference Include="BTCPayServer.Lightning.Common" Version="1.3.3" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using BTCPayServer.Client.JsonConverters;
|
using BTCPayServer.Client.JsonConverters;
|
||||||
using BTCPayServer.JsonConverters;
|
using BTCPayServer.JsonConverters;
|
||||||
|
using BTCPayServer.Lightning;
|
||||||
using NBitcoin;
|
using NBitcoin;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
@ -15,5 +16,8 @@ namespace BTCPayServer.Client.Models
|
||||||
|
|
||||||
[JsonConverter(typeof(MoneyJsonConverter))]
|
[JsonConverter(typeof(MoneyJsonConverter))]
|
||||||
public Money MaxFeeFlat { get; set; }
|
public Money MaxFeeFlat { get; set; }
|
||||||
|
|
||||||
|
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
||||||
|
public LightMoney Amount { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1518,11 +1518,9 @@ namespace BTCPayServer.Tests
|
||||||
var lnurlResponse2 = await fetchedReuqest.SendRequest(new LightMoney(0.000002m, LightMoneyUnit.BTC),
|
var lnurlResponse2 = await fetchedReuqest.SendRequest(new LightMoney(0.000002m, LightMoneyUnit.BTC),
|
||||||
network, new HttpClient(), comment: "lol2");
|
network, new HttpClient(), comment: "lol2");
|
||||||
Assert.Equal(new LightMoney(0.000002m, LightMoneyUnit.BTC), lnurlResponse2.GetPaymentRequest(network).MinimumAmount);
|
Assert.Equal(new LightMoney(0.000002m, LightMoneyUnit.BTC), lnurlResponse2.GetPaymentRequest(network).MinimumAmount);
|
||||||
await Assert.ThrowsAnyAsync<LightningRPCException>(async () =>
|
// Initial bolt was cancelled
|
||||||
{
|
var res = await s.Server.CustomerLightningD.Pay(lnurlResponse.Pr);
|
||||||
// Initial bolt was cancelled
|
Assert.Equal(PayResult.Error, res.Result);
|
||||||
await s.Server.CustomerLightningD.Pay(lnurlResponse.Pr);
|
|
||||||
});
|
|
||||||
|
|
||||||
await s.Server.CustomerLightningD.Pay(lnurlResponse2.Pr);
|
await s.Server.CustomerLightningD.Pay(lnurlResponse2.Pr);
|
||||||
await TestUtils.EventuallyAsync(async () =>
|
await TestUtils.EventuallyAsync(async () =>
|
||||||
|
|
|
@ -4,7 +4,6 @@ using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Lightning;
|
using BTCPayServer.Lightning;
|
||||||
using BTCPayServer.Lightning.CLightning;
|
using BTCPayServer.Lightning.CLightning;
|
||||||
|
@ -174,11 +173,11 @@ namespace BTCPayServer.Tests
|
||||||
SendLightningPaymentAsync(invoice).GetAwaiter().GetResult();
|
SendLightningPaymentAsync(invoice).GetAwaiter().GetResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SendLightningPaymentAsync(Invoice invoice)
|
public async Task<PayResponse> SendLightningPaymentAsync(Invoice invoice)
|
||||||
{
|
{
|
||||||
var bolt11 = invoice.CryptoInfo.Where(o => o.PaymentUrls.BOLT11 != null).First().PaymentUrls.BOLT11;
|
var bolt11 = invoice.CryptoInfo.Where(o => o.PaymentUrls.BOLT11 != null).First().PaymentUrls.BOLT11;
|
||||||
bolt11 = bolt11.Replace("lightning:", "", StringComparison.OrdinalIgnoreCase);
|
bolt11 = bolt11.Replace("lightning:", "", StringComparison.OrdinalIgnoreCase);
|
||||||
await CustomerLightningD.Pay(bolt11);
|
return await CustomerLightningD.Pay(bolt11);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<T> WaitForEvent<T>(Func<Task> action, Func<T, bool> correctEvent = null)
|
public async Task<T> WaitForEvent<T>(Func<Task> action, Func<T, bool> correctEvent = null)
|
||||||
|
|
|
@ -5,8 +5,6 @@ using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Security;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
@ -17,7 +15,6 @@ using BTCPayServer.Abstractions.Extensions;
|
||||||
using BTCPayServer.Abstractions.Models;
|
using BTCPayServer.Abstractions.Models;
|
||||||
using BTCPayServer.Client;
|
using BTCPayServer.Client;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
using BTCPayServer.Configuration;
|
|
||||||
using BTCPayServer.Controllers;
|
using BTCPayServer.Controllers;
|
||||||
using BTCPayServer.Data;
|
using BTCPayServer.Data;
|
||||||
using BTCPayServer.Events;
|
using BTCPayServer.Events;
|
||||||
|
@ -26,7 +23,6 @@ using BTCPayServer.Fido2.Models;
|
||||||
using BTCPayServer.HostedServices;
|
using BTCPayServer.HostedServices;
|
||||||
using BTCPayServer.Hosting;
|
using BTCPayServer.Hosting;
|
||||||
using BTCPayServer.Lightning;
|
using BTCPayServer.Lightning;
|
||||||
using BTCPayServer.Lightning.CLightning;
|
|
||||||
using BTCPayServer.Models;
|
using BTCPayServer.Models;
|
||||||
using BTCPayServer.Models.AccountViewModels;
|
using BTCPayServer.Models.AccountViewModels;
|
||||||
using BTCPayServer.Models.AppViewModels;
|
using BTCPayServer.Models.AppViewModels;
|
||||||
|
@ -39,33 +35,26 @@ using BTCPayServer.Payments;
|
||||||
using BTCPayServer.Payments.Bitcoin;
|
using BTCPayServer.Payments.Bitcoin;
|
||||||
using BTCPayServer.Payments.Lightning;
|
using BTCPayServer.Payments.Lightning;
|
||||||
using BTCPayServer.Payments.PayJoin.Sender;
|
using BTCPayServer.Payments.PayJoin.Sender;
|
||||||
using BTCPayServer.Rating;
|
|
||||||
using BTCPayServer.Security.Bitpay;
|
using BTCPayServer.Security.Bitpay;
|
||||||
using BTCPayServer.Services;
|
using BTCPayServer.Services;
|
||||||
using BTCPayServer.Services.Apps;
|
using BTCPayServer.Services.Apps;
|
||||||
using BTCPayServer.Services.Invoices;
|
using BTCPayServer.Services.Invoices;
|
||||||
using BTCPayServer.Services.Labels;
|
|
||||||
using BTCPayServer.Services.Mails;
|
using BTCPayServer.Services.Mails;
|
||||||
using BTCPayServer.Services.Rates;
|
using BTCPayServer.Services.Rates;
|
||||||
using BTCPayServer.Storage.Models;
|
using BTCPayServer.Storage.Models;
|
||||||
using BTCPayServer.Storage.Services.Providers.FileSystemStorage.Configuration;
|
using BTCPayServer.Storage.Services.Providers.FileSystemStorage.Configuration;
|
||||||
using BTCPayServer.Storage.ViewModels;
|
using BTCPayServer.Storage.ViewModels;
|
||||||
using BTCPayServer.Tests.Logging;
|
|
||||||
using BTCPayServer.Validation;
|
|
||||||
using ExchangeSharp;
|
using ExchangeSharp;
|
||||||
using Fido2NetLib;
|
using Fido2NetLib;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using NBitcoin;
|
using NBitcoin;
|
||||||
using NBitcoin.DataEncoders;
|
using NBitcoin.DataEncoders;
|
||||||
using NBitcoin.Payment;
|
using NBitcoin.Payment;
|
||||||
using NBitcoin.Socks;
|
|
||||||
using NBitpayClient;
|
using NBitpayClient;
|
||||||
using NBXplorer;
|
using NBXplorer;
|
||||||
using NBXplorer.DerivationStrategy;
|
|
||||||
using NBXplorer.Models;
|
using NBXplorer.Models;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
@ -390,11 +379,9 @@ namespace BTCPayServer.Tests
|
||||||
Assert.Equal(InvoiceExceptionStatus.None, fetchedInvoice.ExceptionStatus);
|
Assert.Equal(InvoiceExceptionStatus.None, fetchedInvoice.ExceptionStatus);
|
||||||
|
|
||||||
//BTCPay will attempt to cancel previous bolt11 invoices so that there are less weird edge case scenarios
|
//BTCPay will attempt to cancel previous bolt11 invoices so that there are less weird edge case scenarios
|
||||||
TestLogs.LogInformation($"Attempting to pay invoice {invoice.Id} original full amount bolt11 invoice ");
|
TestLogs.LogInformation($"Attempting to pay invoice {invoice.Id} original full amount bolt11 invoice");
|
||||||
await Assert.ThrowsAsync<LightningRPCException>(async () =>
|
var res = await tester.SendLightningPaymentAsync(invoice);
|
||||||
{
|
Assert.Equal(PayResult.Error, res.Result);
|
||||||
await tester.SendLightningPaymentAsync(invoice);
|
|
||||||
});
|
|
||||||
|
|
||||||
//NOTE: Eclair does not support cancelling invoice so the below test case would make sense for it
|
//NOTE: Eclair does not support cancelling invoice so the below test case would make sense for it
|
||||||
// TestLogs.LogInformation($"Paying invoice {invoice.Id} original full amount bolt11 invoice ");
|
// TestLogs.LogInformation($"Paying invoice {invoice.Id} original full amount bolt11 invoice ");
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="BIP78.Sender" Version="0.2.2" />
|
<PackageReference Include="BIP78.Sender" Version="0.2.2" />
|
||||||
<PackageReference Include="BTCPayServer.Hwi" Version="2.0.2" />
|
<PackageReference Include="BTCPayServer.Hwi" Version="2.0.2" />
|
||||||
<PackageReference Include="BTCPayServer.Lightning.All" Version="1.3.6" />
|
<PackageReference Include="BTCPayServer.Lightning.All" Version="1.3.7" />
|
||||||
<PackageReference Include="BuildBundlerMinifier" Version="3.2.449" />
|
<PackageReference Include="BuildBundlerMinifier" Version="3.2.449" />
|
||||||
<PackageReference Include="BundlerMinifier.Core" Version="3.2.435" />
|
<PackageReference Include="BundlerMinifier.Core" Version="3.2.435" />
|
||||||
<PackageReference Include="BundlerMinifier.TagHelpers" Version="3.2.435" />
|
<PackageReference Include="BundlerMinifier.TagHelpers" Version="3.2.435" />
|
||||||
|
|
|
@ -6,10 +6,8 @@ using BTCPayServer.Abstractions.Contracts;
|
||||||
using BTCPayServer.Abstractions.Extensions;
|
using BTCPayServer.Abstractions.Extensions;
|
||||||
using BTCPayServer.Client;
|
using BTCPayServer.Client;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
using BTCPayServer.HostedServices;
|
|
||||||
using BTCPayServer.Lightning;
|
using BTCPayServer.Lightning;
|
||||||
using BTCPayServer.Security;
|
using BTCPayServer.Security;
|
||||||
using BTCPayServer.Services;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
|
@ -187,8 +185,8 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||||
return this.CreateValidationError(ModelState);
|
return this.CreateValidationError(ModelState);
|
||||||
}
|
}
|
||||||
|
|
||||||
var param = lightningInvoice?.MaxFeeFlat != null || lightningInvoice?.MaxFeePercent != null
|
var param = lightningInvoice?.MaxFeeFlat != null || lightningInvoice?.MaxFeePercent != null || lightningInvoice?.Amount != null
|
||||||
? new PayInvoiceParams { MaxFeePercent = lightningInvoice.MaxFeePercent, MaxFeeFlat = lightningInvoice.MaxFeeFlat }
|
? new PayInvoiceParams { MaxFeePercent = lightningInvoice.MaxFeePercent, MaxFeeFlat = lightningInvoice.MaxFeeFlat, Amount = lightningInvoice.Amount }
|
||||||
: null;
|
: null;
|
||||||
var result = await lightningClient.Pay(lightningInvoice.BOLT11, param, cancellationToken);
|
var result = await lightningClient.Pay(lightningInvoice.BOLT11, param, cancellationToken);
|
||||||
|
|
||||||
|
|
|
@ -204,6 +204,11 @@
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "The BOLT11 of the invoice to pay"
|
"description": "The BOLT11 of the invoice to pay"
|
||||||
},
|
},
|
||||||
|
"amount": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Optional explicit payment amount in millisatoshi (if specified, it overrides the BOLT11 amount)",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
"maxFeePercent": {
|
"maxFeePercent": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"format": "float",
|
"format": "float",
|
||||||
|
|
Loading…
Add table
Reference in a new issue