mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-02-20 13:34:37 +01:00
Lightning payment info and fee handling (#3454)
* Lightning payment info and fee handling Builds on the additions in btcpayserver/BTCPayServer.Lightning#59 and btcpayserver/BTCPayServer.Lightning#61. Adds payment information (total amount and fees) to the API response and allows to set an optional maximum fee percentage when paying. * Add max fee flat
This commit is contained in:
parent
2a884d6f38
commit
cd3807a3d8
11 changed files with 97 additions and 26 deletions
|
@ -28,8 +28,8 @@
|
|||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NBitcoin" Version="6.0.19" />
|
||||
<PackageReference Include="BTCPayServer.Lightning.Common" Version="1.3.0" />
|
||||
<PackageReference Include="NBitcoin" Version="7.0.1" />
|
||||
<PackageReference Include="BTCPayServer.Lightning.Common" Version="1.3.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -54,8 +54,7 @@ namespace BTCPayServer.Client
|
|||
return await HandleResponse<string>(response);
|
||||
}
|
||||
|
||||
|
||||
public virtual async Task PayLightningInvoice(string cryptoCode, PayLightningInvoiceRequest request,
|
||||
public virtual async Task<LightningPaymentData> PayLightningInvoice(string cryptoCode, PayLightningInvoiceRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (request == null)
|
||||
|
@ -63,7 +62,7 @@ namespace BTCPayServer.Client
|
|||
var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/server/lightning/{cryptoCode}/invoices/pay", bodyPayload: request,
|
||||
method: HttpMethod.Post), token);
|
||||
await HandleResponse(response);
|
||||
return await HandleResponse<LightningPaymentData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<LightningInvoiceData> GetLightningInvoice(string cryptoCode,
|
||||
|
|
15
BTCPayServer.Client/Models/LightningPaymentData.cs
Normal file
15
BTCPayServer.Client/Models/LightningPaymentData.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
using BTCPayServer.Client.JsonConverters;
|
||||
using BTCPayServer.Lightning;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BTCPayServer.Client.Models
|
||||
{
|
||||
public class LightningPaymentData
|
||||
{
|
||||
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
||||
public LightMoney TotalAmount { get; set; }
|
||||
|
||||
[JsonConverter(typeof(LightMoneyJsonConverter))]
|
||||
public LightMoney FeeAmount { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,8 +1,20 @@
|
|||
#nullable enable
|
||||
using BTCPayServer.Client.JsonConverters;
|
||||
using BTCPayServer.JsonConverters;
|
||||
using NBitcoin;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BTCPayServer.Client.Models
|
||||
{
|
||||
public class PayLightningInvoiceRequest
|
||||
{
|
||||
[Newtonsoft.Json.JsonProperty("BOLT11")]
|
||||
[JsonProperty("BOLT11")]
|
||||
public string BOLT11 { get; set; }
|
||||
|
||||
[JsonProperty(ItemConverterType = typeof(NumericStringJsonConverter))]
|
||||
public float? MaxFeePercent { get; set; }
|
||||
|
||||
[JsonConverter(typeof(MoneyJsonConverter))]
|
||||
public Money? MaxFeeFlat { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.0.1" />
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
|
||||
<PackageReference Include="NBitcoin" Version="6.0.19" />
|
||||
<PackageReference Include="NBitcoin" Version="7.0.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="DigitalRuby.ExchangeSharp" Version="0.6.3" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="BIP78.Sender" Version="0.2.2" />
|
||||
<PackageReference Include="BTCPayServer.Hwi" Version="2.0.2" />
|
||||
<PackageReference Include="BTCPayServer.Lightning.All" Version="1.3.0" />
|
||||
<PackageReference Include="BTCPayServer.Lightning.All" Version="1.3.2" />
|
||||
<PackageReference Include="BuildBundlerMinifier" Version="3.2.449" />
|
||||
<PackageReference Include="BundlerMinifier.Core" Version="3.2.435" />
|
||||
<PackageReference Include="BundlerMinifier.TagHelpers" Version="3.2.435" />
|
||||
|
|
|
@ -178,19 +178,23 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||
{
|
||||
return this.CreateValidationError(ModelState);
|
||||
}
|
||||
|
||||
var result = await lightningClient.Pay(lightningInvoice.BOLT11);
|
||||
switch (result.Result)
|
||||
|
||||
var param = lightningInvoice?.MaxFeeFlat != null || lightningInvoice?.MaxFeePercent != null
|
||||
? new PayInvoiceParams { MaxFeePercent = lightningInvoice.MaxFeePercent, MaxFeeFlat = lightningInvoice.MaxFeeFlat }
|
||||
: null;
|
||||
var result = await lightningClient.Pay(lightningInvoice.BOLT11, param);
|
||||
|
||||
return result.Result switch
|
||||
{
|
||||
case PayResult.CouldNotFindRoute:
|
||||
return this.CreateAPIError("could-not-find-route", "Impossible to find a route to the peer");
|
||||
case PayResult.Error:
|
||||
return this.CreateAPIError("generic-error", result.ErrorDetail);
|
||||
case PayResult.Ok:
|
||||
return Ok();
|
||||
default:
|
||||
throw new NotSupportedException("Unsupported Payresult");
|
||||
}
|
||||
PayResult.CouldNotFindRoute => this.CreateAPIError("could-not-find-route", "Impossible to find a route to the peer"),
|
||||
PayResult.Error => this.CreateAPIError("generic-error", result.ErrorDetail),
|
||||
PayResult.Ok => Ok(new LightningPaymentData
|
||||
{
|
||||
TotalAmount = result.Details?.TotalAmount,
|
||||
FeeAmount = result.Details?.FeeAmount
|
||||
}),
|
||||
_ => throw new NotSupportedException("Unsupported Payresult")
|
||||
};
|
||||
}
|
||||
|
||||
public virtual async Task<IActionResult> GetInvoice(string cryptoCode, string id)
|
||||
|
@ -253,7 +257,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||
|
||||
private LightningInvoiceData ToModel(LightningInvoice invoice)
|
||||
{
|
||||
return new LightningInvoiceData()
|
||||
return new LightningInvoiceData
|
||||
{
|
||||
Amount = invoice.Amount,
|
||||
Id = invoice.Id,
|
||||
|
|
|
@ -497,10 +497,11 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||
await _lightningNodeApiController.GetDepositAddress(cryptoCode));
|
||||
}
|
||||
|
||||
public override async Task PayLightningInvoice(string cryptoCode, PayLightningInvoiceRequest request,
|
||||
public override async Task<LightningPaymentData> PayLightningInvoice(string cryptoCode, PayLightningInvoiceRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
HandleActionResult(await _lightningNodeApiController.PayInvoice(cryptoCode, request));
|
||||
return GetFromActionResult<LightningPaymentData>(
|
||||
await _lightningNodeApiController.PayInvoice(cryptoCode, request));
|
||||
}
|
||||
|
||||
public override async Task<LightningInvoiceData> GetLightningInvoice(string cryptoCode, string invoiceId,
|
||||
|
@ -518,7 +519,6 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||
await _lightningNodeApiController.CreateInvoice(cryptoCode, request));
|
||||
}
|
||||
|
||||
|
||||
private T GetFromActionResult<T>(IActionResult result)
|
||||
{
|
||||
HandleActionResult(result);
|
||||
|
|
|
@ -70,6 +70,20 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"LightningPaymentData": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"totalAmount": {
|
||||
"type": "string",
|
||||
"description": "The total amount (including fees) in millisatoshi"
|
||||
},
|
||||
"feeAmount": {
|
||||
"type": "string",
|
||||
"description": "The total fees in millisatoshi"
|
||||
}
|
||||
}
|
||||
},
|
||||
"LightningInvoiceData": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
|
@ -141,6 +155,19 @@
|
|||
"BOLT11": {
|
||||
"type": "string",
|
||||
"description": "The BOLT11 of the invoice to pay"
|
||||
},
|
||||
"maxFeePercent": {
|
||||
"type": "string",
|
||||
"format": "float",
|
||||
"nullable": true,
|
||||
"description": "The fee limit expressed as a percentage of the payment amount",
|
||||
"example": "6.15"
|
||||
},
|
||||
"maxFeeFlat": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "The fee limit expressed as a fixed amount in satoshi",
|
||||
"example": "21"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -361,7 +361,14 @@
|
|||
"operationId": "InternalLightningNodeApi_PayInvoice",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successfully paid"
|
||||
"description": "Successfully paid",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/LightningPaymentData"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Unable to validate the request",
|
||||
|
|
|
@ -428,7 +428,14 @@
|
|||
"operationId": "StoreLightningNodeApi_PayInvoice",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successfully paid"
|
||||
"description": "Successfully paid",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/LightningPaymentData"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Unable to validate the request",
|
||||
|
|
Loading…
Add table
Reference in a new issue