#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.Cors; 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)] [EnableCors(CorsPolicies.All)] public class GreenfieldStoreLightningAddressesController : ControllerBase { private readonly LightningAddressService _lightningAddressService; public GreenfieldStoreLightningAddressesController( LightningAddressService lightningAddressService) { _lightningAddressService = lightningAddressService; } private LightningAddressData ToModel(BTCPayServer.Data.LightningAddressData data) { var blob = data.GetBlob(); if (blob is null) return new LightningAddressData(); 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 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 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 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 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 }.SetBlob(new LightningAddressDataBlob() { Max = data.Max, Min = data.Min, CurrencyCode = data.CurrencyCode }))) { return await GetStoreLightningAddress(storeId, username); } return this.CreateAPIError((int)HttpStatusCode.BadRequest, "username-already-used", "The username is already in use by another store."); } } }