mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2026-01-26 01:14:20 +01:00
Greenfield: Lightning addresses API (#4546)
* Greenfield: Lightning addresses API * add docs * Apply suggestions from code review Co-authored-by: d11n <mail@dennisreimann.de>
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
#nullable enable
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Abstractions.Extensions;
|
||||
using BTCPayServer.Client;
|
||||
using BTCPayServer.Data;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using AuthenticationSchemes = BTCPayServer.Abstractions.Constants.AuthenticationSchemes;
|
||||
using LightningAddressData = BTCPayServer.Client.Models.LightningAddressData;
|
||||
|
||||
namespace BTCPayServer.Controllers.Greenfield
|
||||
{
|
||||
[ApiController]
|
||||
[Authorize(AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
||||
public class GreenfieldStoreLightningAddressesController : ControllerBase
|
||||
{
|
||||
private readonly LightningAddressService _lightningAddressService;
|
||||
|
||||
public GreenfieldStoreLightningAddressesController(
|
||||
LightningAddressService lightningAddressService)
|
||||
{
|
||||
_lightningAddressService = lightningAddressService;
|
||||
}
|
||||
|
||||
private LightningAddressData ToModel(BTCPayServer.Data.LightningAddressData data)
|
||||
{
|
||||
var blob = data.Blob.GetBlob<LightningAddressDataBlob>();
|
||||
return new LightningAddressData()
|
||||
{
|
||||
Username = data.Username, Max = blob.Max, Min = blob.Min, CurrencyCode = blob.CurrencyCode
|
||||
};
|
||||
}
|
||||
|
||||
[Authorize(Policy = Policies.CanViewStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
||||
[HttpGet("~/api/v1/stores/{storeId}/lightning-addresses")]
|
||||
public async Task<IActionResult> GetStoreLightningAddresses(string storeId)
|
||||
{
|
||||
return Ok((await _lightningAddressService.Get(new LightningAddressQuery() {StoreIds = new[] {storeId}}))
|
||||
.Select(ToModel).ToArray());
|
||||
}
|
||||
|
||||
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
||||
[HttpDelete("~/api/v1/stores/{storeId}/lightning-addresses/{username}")]
|
||||
public async Task<IActionResult> RemoveStoreLightningAddress(string storeId, string username)
|
||||
{
|
||||
if (await _lightningAddressService.Remove(username, storeId))
|
||||
{
|
||||
return Ok();
|
||||
}
|
||||
return
|
||||
this.CreateAPIError(404, "lightning-address-not-found", "The lightning address was not present.");
|
||||
|
||||
}
|
||||
|
||||
[Authorize(Policy = Policies.CanViewStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
||||
[HttpGet("~/api/v1/stores/{storeId}/lightning-addresses/{username}")]
|
||||
public async Task<IActionResult> GetStoreLightningAddress(string storeId, string username)
|
||||
{
|
||||
var res = await _lightningAddressService.Get(new LightningAddressQuery()
|
||||
{
|
||||
Usernames = new[] {username}, StoreIds = new[] {storeId},
|
||||
});
|
||||
return res?.Any() is true ? Ok(ToModel(res.First())) : this.CreateAPIError(404, "lightning-address-not-found", "The lightning address was not present.");
|
||||
}
|
||||
|
||||
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
||||
[HttpPost("~/api/v1/stores/{storeId}/lightning-addresses/{username}")]
|
||||
public async Task<IActionResult> AddOrUpdateStoreLightningAddress(
|
||||
string storeId, string username, LightningAddressData data)
|
||||
{
|
||||
if (data.Min <= 0)
|
||||
{
|
||||
ModelState.AddModelError(nameof(data.Min), "Minimum must be greater than 0 if provided.");
|
||||
return this.CreateValidationError(ModelState);
|
||||
}
|
||||
|
||||
if (await _lightningAddressService.Set(new Data.LightningAddressData()
|
||||
{
|
||||
StoreDataId = storeId,
|
||||
Username = username,
|
||||
Blob = new LightningAddressDataBlob()
|
||||
{
|
||||
Max = data.Max, Min = data.Min, CurrencyCode = data.CurrencyCode
|
||||
}.SerializeBlob()
|
||||
}))
|
||||
{
|
||||
return await GetStoreLightningAddress(storeId, username);
|
||||
}
|
||||
|
||||
return this.CreateAPIError((int)HttpStatusCode.BadRequest, "username-already-used",
|
||||
"The username is already in use by another store.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ using NBXplorer.Models;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using InvoiceData = BTCPayServer.Client.Models.InvoiceData;
|
||||
using Language = BTCPayServer.Client.Models.Language;
|
||||
using LightningAddressData = BTCPayServer.Client.Models.LightningAddressData;
|
||||
using NotificationData = BTCPayServer.Client.Models.NotificationData;
|
||||
using PaymentRequestData = BTCPayServer.Client.Models.PaymentRequestData;
|
||||
using PayoutData = BTCPayServer.Client.Models.PayoutData;
|
||||
@@ -1232,5 +1233,27 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
{
|
||||
return GetFromActionResult<PayoutData>(await GetController<GreenfieldPullPaymentController>().GetStorePayout(storeId, payoutId));
|
||||
}
|
||||
|
||||
public override async Task<LightningAddressData[]> GetStoreLightningAddresses(string storeId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return GetFromActionResult<LightningAddressData[]>(await GetController<GreenfieldStoreLightningAddressesController>().GetStoreLightningAddresses(storeId));
|
||||
}
|
||||
|
||||
public override async Task<LightningAddressData> GetStoreLightningAddress(string storeId, string username, CancellationToken token = default)
|
||||
{
|
||||
return GetFromActionResult<LightningAddressData>(await GetController<GreenfieldStoreLightningAddressesController>().GetStoreLightningAddress(storeId, username));
|
||||
}
|
||||
|
||||
public override async Task<LightningAddressData> AddOrUpdateStoreLightningAddress(string storeId, string username, LightningAddressData data,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return GetFromActionResult<LightningAddressData>(await GetController<GreenfieldStoreLightningAddressesController>().AddOrUpdateStoreLightningAddress(storeId, username, data));
|
||||
}
|
||||
|
||||
public override async Task RemoveStoreLightningAddress(string storeId, string username, CancellationToken token = default)
|
||||
{
|
||||
HandleActionResult(await GetController<GreenfieldStoreLightningAddressesController>().RemoveStoreLightningAddress(storeId, username));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,8 +60,9 @@ public class LightningAddressService
|
||||
|
||||
public async Task<bool> Set(LightningAddressData data)
|
||||
{
|
||||
data.Username = NormalizeUsername(data.Username);
|
||||
await using var context = _applicationDbContextFactory.CreateContext();
|
||||
var result = (await GetCore(context, new LightningAddressQuery() { Usernames = new[] { data.Username } }))
|
||||
var result = (await GetCore(context, new LightningAddressQuery() { Usernames = new[] { data.Username} }))
|
||||
.FirstOrDefault();
|
||||
if (result is not null)
|
||||
{
|
||||
@@ -73,7 +74,6 @@ public class LightningAddressService
|
||||
context.Remove(result);
|
||||
}
|
||||
|
||||
data.Username = NormalizeUsername(data.Username);
|
||||
await context.AddAsync(data);
|
||||
await context.SaveChangesAsync();
|
||||
_memoryCache.Remove(GetKey(data.Username));
|
||||
@@ -82,6 +82,7 @@ public class LightningAddressService
|
||||
|
||||
public async Task<bool> Remove(string username, string? storeId = null)
|
||||
{
|
||||
username = NormalizeUsername(username);
|
||||
await using var context = _applicationDbContextFactory.CreateContext();
|
||||
var x = (await GetCore(context, new LightningAddressQuery() { Usernames = new[] { username } })).FirstOrDefault();
|
||||
if (x is null)
|
||||
|
||||
@@ -30,6 +30,7 @@ using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using NBitcoin;
|
||||
using Newtonsoft.Json;
|
||||
using LightningAddressData = BTCPayServer.Data.LightningAddressData;
|
||||
using MarkPayoutRequest = BTCPayServer.HostedServices.MarkPayoutRequest;
|
||||
|
||||
namespace BTCPayServer
|
||||
|
||||
Reference in New Issue
Block a user