From 90c827a3eb0f8cf0bef3bc781e87fab511e1723b Mon Sep 17 00:00:00 2001 From: Kukks Date: Thu, 9 Feb 2023 16:06:25 +0100 Subject: [PATCH] nostr plugin --- BTCPayServerPlugins.sln | 30 ++-- .../BTCPayServer.Plugins.NIP05.csproj | 40 +++++ Plugins/BTCPayServer.Plugins.NIP05/Dockerfile | 18 +++ .../BTCPayServer.Plugins.NIP05/NFCPlugin.cs | 22 +++ .../Nip5Controller.cs | 128 ++++++++++++++++ .../Nip5Response.cs | 10 ++ .../Nip5StoreSettings.cs | 14 ++ .../Views/Nip5/Edit.cshtml | 145 ++++++++++++++++++ .../Views/Shared/Nip05Nav.cshtml | 19 +++ .../_ViewImports.cshtml | 5 + 10 files changed, 421 insertions(+), 10 deletions(-) create mode 100644 Plugins/BTCPayServer.Plugins.NIP05/BTCPayServer.Plugins.NIP05.csproj create mode 100644 Plugins/BTCPayServer.Plugins.NIP05/Dockerfile create mode 100644 Plugins/BTCPayServer.Plugins.NIP05/NFCPlugin.cs create mode 100644 Plugins/BTCPayServer.Plugins.NIP05/Nip5Controller.cs create mode 100644 Plugins/BTCPayServer.Plugins.NIP05/Nip5Response.cs create mode 100644 Plugins/BTCPayServer.Plugins.NIP05/Nip5StoreSettings.cs create mode 100644 Plugins/BTCPayServer.Plugins.NIP05/Views/Nip5/Edit.cshtml create mode 100644 Plugins/BTCPayServer.Plugins.NIP05/Views/Shared/Nip05Nav.cshtml create mode 100644 Plugins/BTCPayServer.Plugins.NIP05/_ViewImports.cshtml diff --git a/BTCPayServerPlugins.sln b/BTCPayServerPlugins.sln index bca6356..8927b83 100644 --- a/BTCPayServerPlugins.sln +++ b/BTCPayServerPlugins.sln @@ -43,6 +43,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BTCPayServer.Plugins.LSP", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BTCPayServer.PluginPacker", "submodules\btcpayserver\BTCPayServer.PluginPacker\BTCPayServer.PluginPacker.csproj", "{2FDF2D41-8E75-49F6-9F4D-9E9AECE7922F}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BTCPayServer.Plugins.NIP05", "Plugins\BTCPayServer.Plugins.NIP05\BTCPayServer.Plugins.NIP05.csproj", "{362D2175-9632-418E-95B1-5D638C52ECA6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -61,12 +63,12 @@ Global {D1D1116C-38F9-4EA3-AC65-A75FEA82E5C8}.Altcoins-Release|Any CPU.Build.0 = Release|Any CPU {B19C9F52-DC47-466D-8B5C-2D202B7B003F}.Release|Any CPU.ActiveCfg = Release|Any CPU {B19C9F52-DC47-466D-8B5C-2D202B7B003F}.Release|Any CPU.Build.0 = Release|Any CPU - {B19C9F52-DC47-466D-8B5C-2D202B7B003F}.Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU - {B19C9F52-DC47-466D-8B5C-2D202B7B003F}.Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU {B19C9F52-DC47-466D-8B5C-2D202B7B003F}.Altcoins-Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU {B19C9F52-DC47-466D-8B5C-2D202B7B003F}.Altcoins-Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU {B19C9F52-DC47-466D-8B5C-2D202B7B003F}.Altcoins-Release|Any CPU.ActiveCfg = Altcoins-Release|Any CPU {B19C9F52-DC47-466D-8B5C-2D202B7B003F}.Altcoins-Release|Any CPU.Build.0 = Altcoins-Release|Any CPU + {B19C9F52-DC47-466D-8B5C-2D202B7B003F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B19C9F52-DC47-466D-8B5C-2D202B7B003F}.Debug|Any CPU.Build.0 = Debug|Any CPU {AD9635BB-C70E-4676-BB04-900D51B01666}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {AD9635BB-C70E-4676-BB04-900D51B01666}.Debug|Any CPU.Build.0 = Debug|Any CPU {AD9635BB-C70E-4676-BB04-900D51B01666}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -77,12 +79,12 @@ Global {AD9635BB-C70E-4676-BB04-900D51B01666}.Altcoins-Release|Any CPU.Build.0 = Release|Any CPU {8F158B88-0FEE-44FF-8552-7C0F17D5C508}.Release|Any CPU.ActiveCfg = Release|Any CPU {8F158B88-0FEE-44FF-8552-7C0F17D5C508}.Release|Any CPU.Build.0 = Release|Any CPU - {8F158B88-0FEE-44FF-8552-7C0F17D5C508}.Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU - {8F158B88-0FEE-44FF-8552-7C0F17D5C508}.Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU {8F158B88-0FEE-44FF-8552-7C0F17D5C508}.Altcoins-Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU {8F158B88-0FEE-44FF-8552-7C0F17D5C508}.Altcoins-Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU {8F158B88-0FEE-44FF-8552-7C0F17D5C508}.Altcoins-Release|Any CPU.ActiveCfg = Altcoins-Release|Any CPU {8F158B88-0FEE-44FF-8552-7C0F17D5C508}.Altcoins-Release|Any CPU.Build.0 = Altcoins-Release|Any CPU + {8F158B88-0FEE-44FF-8552-7C0F17D5C508}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8F158B88-0FEE-44FF-8552-7C0F17D5C508}.Debug|Any CPU.Build.0 = Debug|Any CPU {DF85EFA4-0EF5-4A99-853F-E6F9C88E3F8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {DF85EFA4-0EF5-4A99-853F-E6F9C88E3F8C}.Debug|Any CPU.Build.0 = Debug|Any CPU {DF85EFA4-0EF5-4A99-853F-E6F9C88E3F8C}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -93,28 +95,28 @@ Global {DF85EFA4-0EF5-4A99-853F-E6F9C88E3F8C}.Altcoins-Release|Any CPU.Build.0 = Release|Any CPU {2C5C4DF9-BA1F-4671-9F24-B22D7C9C3D21}.Release|Any CPU.ActiveCfg = Release|Any CPU {2C5C4DF9-BA1F-4671-9F24-B22D7C9C3D21}.Release|Any CPU.Build.0 = Release|Any CPU - {2C5C4DF9-BA1F-4671-9F24-B22D7C9C3D21}.Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU - {2C5C4DF9-BA1F-4671-9F24-B22D7C9C3D21}.Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU {2C5C4DF9-BA1F-4671-9F24-B22D7C9C3D21}.Altcoins-Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU {2C5C4DF9-BA1F-4671-9F24-B22D7C9C3D21}.Altcoins-Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU {2C5C4DF9-BA1F-4671-9F24-B22D7C9C3D21}.Altcoins-Release|Any CPU.ActiveCfg = Altcoins-Release|Any CPU {2C5C4DF9-BA1F-4671-9F24-B22D7C9C3D21}.Altcoins-Release|Any CPU.Build.0 = Altcoins-Release|Any CPU + {2C5C4DF9-BA1F-4671-9F24-B22D7C9C3D21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2C5C4DF9-BA1F-4671-9F24-B22D7C9C3D21}.Debug|Any CPU.Build.0 = Debug|Any CPU {D7E7309D-C4F4-496A-B2C8-BC5D3991B9C0}.Release|Any CPU.ActiveCfg = Release|Any CPU {D7E7309D-C4F4-496A-B2C8-BC5D3991B9C0}.Release|Any CPU.Build.0 = Release|Any CPU - {D7E7309D-C4F4-496A-B2C8-BC5D3991B9C0}.Debug|Any CPU.ActiveCfg = Altcoins-Release|Any CPU - {D7E7309D-C4F4-496A-B2C8-BC5D3991B9C0}.Debug|Any CPU.Build.0 = Altcoins-Release|Any CPU {D7E7309D-C4F4-496A-B2C8-BC5D3991B9C0}.Altcoins-Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU {D7E7309D-C4F4-496A-B2C8-BC5D3991B9C0}.Altcoins-Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU {D7E7309D-C4F4-496A-B2C8-BC5D3991B9C0}.Altcoins-Release|Any CPU.ActiveCfg = Altcoins-Release|Any CPU {D7E7309D-C4F4-496A-B2C8-BC5D3991B9C0}.Altcoins-Release|Any CPU.Build.0 = Altcoins-Release|Any CPU + {D7E7309D-C4F4-496A-B2C8-BC5D3991B9C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D7E7309D-C4F4-496A-B2C8-BC5D3991B9C0}.Debug|Any CPU.Build.0 = Debug|Any CPU {3F2E0BA0-9EA7-490F-894D-F9703F35B174}.Release|Any CPU.ActiveCfg = Release|Any CPU {3F2E0BA0-9EA7-490F-894D-F9703F35B174}.Release|Any CPU.Build.0 = Release|Any CPU - {3F2E0BA0-9EA7-490F-894D-F9703F35B174}.Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU - {3F2E0BA0-9EA7-490F-894D-F9703F35B174}.Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU {3F2E0BA0-9EA7-490F-894D-F9703F35B174}.Altcoins-Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU {3F2E0BA0-9EA7-490F-894D-F9703F35B174}.Altcoins-Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU {3F2E0BA0-9EA7-490F-894D-F9703F35B174}.Altcoins-Release|Any CPU.ActiveCfg = Altcoins-Release|Any CPU {3F2E0BA0-9EA7-490F-894D-F9703F35B174}.Altcoins-Release|Any CPU.Build.0 = Altcoins-Release|Any CPU + {3F2E0BA0-9EA7-490F-894D-F9703F35B174}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3F2E0BA0-9EA7-490F-894D-F9703F35B174}.Debug|Any CPU.Build.0 = Debug|Any CPU {CCDE6E23-60B7-4B12-95AA-91CB40DBC3BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CCDE6E23-60B7-4B12-95AA-91CB40DBC3BD}.Debug|Any CPU.Build.0 = Debug|Any CPU {CCDE6E23-60B7-4B12-95AA-91CB40DBC3BD}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -203,6 +205,14 @@ Global {2FDF2D41-8E75-49F6-9F4D-9E9AECE7922F}.Altcoins-Debug|Any CPU.Build.0 = Debug|Any CPU {2FDF2D41-8E75-49F6-9F4D-9E9AECE7922F}.Altcoins-Release|Any CPU.ActiveCfg = Debug|Any CPU {2FDF2D41-8E75-49F6-9F4D-9E9AECE7922F}.Altcoins-Release|Any CPU.Build.0 = Debug|Any CPU + {362D2175-9632-418E-95B1-5D638C52ECA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {362D2175-9632-418E-95B1-5D638C52ECA6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {362D2175-9632-418E-95B1-5D638C52ECA6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {362D2175-9632-418E-95B1-5D638C52ECA6}.Release|Any CPU.Build.0 = Release|Any CPU + {362D2175-9632-418E-95B1-5D638C52ECA6}.Altcoins-Debug|Any CPU.ActiveCfg = Debug|Any CPU + {362D2175-9632-418E-95B1-5D638C52ECA6}.Altcoins-Debug|Any CPU.Build.0 = Debug|Any CPU + {362D2175-9632-418E-95B1-5D638C52ECA6}.Altcoins-Release|Any CPU.ActiveCfg = Debug|Any CPU + {362D2175-9632-418E-95B1-5D638C52ECA6}.Altcoins-Release|Any CPU.Build.0 = Debug|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {B19C9F52-DC47-466D-8B5C-2D202B7B003F} = {9E04ECE9-E304-4FF2-9CBC-83256E6C6962} diff --git a/Plugins/BTCPayServer.Plugins.NIP05/BTCPayServer.Plugins.NIP05.csproj b/Plugins/BTCPayServer.Plugins.NIP05/BTCPayServer.Plugins.NIP05.csproj new file mode 100644 index 0000000..20871bf --- /dev/null +++ b/Plugins/BTCPayServer.Plugins.NIP05/BTCPayServer.Plugins.NIP05.csproj @@ -0,0 +1,40 @@ + + + + + + net6.0 + 10 + + + + + Nostr NIP5 + Allows you to verify your nostr account + 1.0.0 + + + + true + false + true + + + + + + StaticWebAssetsEnabled=false + false + runtime;native;build;buildTransitive;contentFiles + + + + + + + + + + + + diff --git a/Plugins/BTCPayServer.Plugins.NIP05/Dockerfile b/Plugins/BTCPayServer.Plugins.NIP05/Dockerfile new file mode 100644 index 0000000..d133ec5 --- /dev/null +++ b/Plugins/BTCPayServer.Plugins.NIP05/Dockerfile @@ -0,0 +1,18 @@ +FROM mcr.microsoft.com/dotnet/runtime:6.0 AS base +WORKDIR /app + +FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build +WORKDIR /src +COPY ["Plugins/BTCPayServer.Plugins.NIP05/BTCPayServer.Plugins.NIP05.csproj", "Plugins/BTCPayServer.Plugins.NIP05/"] +RUN dotnet restore "Plugins/BTCPayServer.Plugins.NIP05/BTCPayServer.Plugins.NIP05.csproj" +COPY . . +WORKDIR "/src/Plugins/BTCPayServer.Plugins.NIP05" +RUN dotnet build "BTCPayServer.Plugins.NIP05.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "BTCPayServer.Plugins.NIP05.csproj" -c Release -o /app/publish + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "BTCPayServer.Plugins.NIP05.dll"] diff --git a/Plugins/BTCPayServer.Plugins.NIP05/NFCPlugin.cs b/Plugins/BTCPayServer.Plugins.NIP05/NFCPlugin.cs new file mode 100644 index 0000000..8880349 --- /dev/null +++ b/Plugins/BTCPayServer.Plugins.NIP05/NFCPlugin.cs @@ -0,0 +1,22 @@ +using BTCPayServer.Abstractions.Contracts; +using BTCPayServer.Abstractions.Models; +using BTCPayServer.Abstractions.Services; +using Microsoft.Extensions.DependencyInjection; + +namespace BTCPayServer.Plugins.NIP05 +{ + public class Nip05Plugin : BaseBTCPayServerPlugin + { + public override IBTCPayServerPlugin.PluginDependency[] Dependencies { get; } = + { + new() { Identifier = nameof(BTCPayServer), Condition = ">=1.7.8" } + }; + public override void Execute(IServiceCollection applicationBuilder) + { + + applicationBuilder.AddSingleton(new UIExtension("Nip05Nav", + "store-integrations-nav")); + base.Execute(applicationBuilder); + } + } +} diff --git a/Plugins/BTCPayServer.Plugins.NIP05/Nip5Controller.cs b/Plugins/BTCPayServer.Plugins.NIP05/Nip5Controller.cs new file mode 100644 index 0000000..5c04b01 --- /dev/null +++ b/Plugins/BTCPayServer.Plugins.NIP05/Nip5Controller.cs @@ -0,0 +1,128 @@ +#nullable enable +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using BTCPayServer.Abstractions.Constants; +using BTCPayServer.Client; +using BTCPayServer.Services.Stores; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Cors; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Caching.Memory; + +namespace BTCPayServer.Plugins.NIP05; + +[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)] +[Route("stores/{storeId}/plugins/nip5")] +public class Nip5Controller : Controller +{ + private readonly StoreRepository _storeRepository; + private readonly IMemoryCache _memoryCache; + + public Nip5Controller() + { + } + + public Nip5Controller(StoreRepository storeRepository, + IMemoryCache memoryCache) + { + _storeRepository = storeRepository; + _memoryCache = memoryCache; + } + + [HttpGet] + public async Task Edit(string storeId) + { + var settings = await _storeRepository.GetSettingAsync(storeId, "NIP05"); + return View(settings ?? new()); + } + + [HttpPost] + public async Task Edit(string storeId, Nip5StoreSettings settings, string command) + { + if (command == "remove") + { + var settingss = await _storeRepository.GetSettingAsync(storeId, "NIP05"); + if (settingss is not null) + { + await _storeRepository.UpdateSetting(storeId, "NIP05", null); + + _memoryCache.Remove($"NIP05_{settingss.Name.ToLowerInvariant()}"); + } + + return RedirectToAction("Edit", new {storeId}); + } + + if (!ModelState.IsValid) + { + return View(settings); + } + + settings.Relays = settings.Relays + ?.Where(s => !string.IsNullOrEmpty(s) && Uri.TryCreate(s, UriKind.Absolute, out _)).ToArray(); + var found = await Get(settings.Name.ToLowerInvariant()); + if (found.storeId is not null && storeId != found.storeId) + { + ModelState.AddModelError(nameof(settings.Name), "Name is already in use. Choose something else"); + + return View(settings); + } + + var settingssx = await _storeRepository.GetSettingAsync(storeId, "NIP05"); + if (settingssx is not null) + { + _memoryCache.Remove($"NIP05_{settingssx.Name.ToLowerInvariant()}"); + } + + await _storeRepository.UpdateSetting(storeId, "NIP05", settings); + return RedirectToAction("Edit", new {storeId}); + } + + private async Task<(string? storeId, Nip5StoreSettings? settings)> Get(string name) + { + var rex = await _memoryCache.GetOrCreateAsync<(string? storeId, Nip5StoreSettings? settings)>( + $"NIP05_{name.ToLowerInvariant()}", + async entry => + { + entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(10); + + var store = await _storeRepository.GetSettingsAsync("NIP05"); + + KeyValuePair matched = store.FirstOrDefault(pair => + pair.Value.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)); + + return (matched.Key, matched.Value); + }); + if (rex.storeId is null) + { + _memoryCache.Remove($"NIP05_{name.ToLowerInvariant()}"); + } + + return rex; + } + + [HttpGet("~/.well-known/nostr.json")] + [EnableCors(CorsPolicies.All)] + [IgnoreAntiforgeryToken] + public async Task GetUser([FromQuery] string name) + { + var result = await Get(name); + + return result.storeId is null + ? NotFound() + : Ok(new Nip5Response() + { + Names = new Dictionary() + { + {name, result.settings.PubKey} + }, + Relays = result.settings.Relays?.Any() is true + ? new Dictionary() + { + {result.settings.PubKey, result.settings.Relays} + } + : null + }); + } +} \ No newline at end of file diff --git a/Plugins/BTCPayServer.Plugins.NIP05/Nip5Response.cs b/Plugins/BTCPayServer.Plugins.NIP05/Nip5Response.cs new file mode 100644 index 0000000..0e093c1 --- /dev/null +++ b/Plugins/BTCPayServer.Plugins.NIP05/Nip5Response.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +public class Nip5Response +{ + [JsonProperty("names")] public Dictionary Names { get; set; } + + [JsonProperty("relays", NullValueHandling = NullValueHandling.Ignore)] + public Dictionary? Relays { get; set; } +} \ No newline at end of file diff --git a/Plugins/BTCPayServer.Plugins.NIP05/Nip5StoreSettings.cs b/Plugins/BTCPayServer.Plugins.NIP05/Nip5StoreSettings.cs new file mode 100644 index 0000000..d8d7c61 --- /dev/null +++ b/Plugins/BTCPayServer.Plugins.NIP05/Nip5StoreSettings.cs @@ -0,0 +1,14 @@ +#nullable enable +using System.ComponentModel.DataAnnotations; + +namespace BTCPayServer.Plugins.NIP05 +{ +} + +public class Nip5StoreSettings +{ + [Required] public string PubKey { get; set; } + [Required] public string Name { get; set; } + + public string[]? Relays { get; set; } +} \ No newline at end of file diff --git a/Plugins/BTCPayServer.Plugins.NIP05/Views/Nip5/Edit.cshtml b/Plugins/BTCPayServer.Plugins.NIP05/Views/Nip5/Edit.cshtml new file mode 100644 index 0000000..8cec5cf --- /dev/null +++ b/Plugins/BTCPayServer.Plugins.NIP05/Views/Nip5/Edit.cshtml @@ -0,0 +1,145 @@ +@using BTCPayServer.Abstractions.Extensions +@using Microsoft.AspNetCore.Mvc.TagHelpers +@model Nip5StoreSettings +@{ + ViewData.SetActivePage("Nostr NIP05", "Nostr NIP05", "Nostr NIP05"); +} + + + +

@ViewData["Title"]

+ +
+
+
+
+
+ + + +
+
+ + + +
+
+
+ + + + + + + + + @if (Model.Relays is not null) + { + @for (var index = 0; index < Model.Relays.Length; index++) + { + + + + + } + } + +
+ Relay + + Actions +
+ + + +
+ +
+
+
+ + + + @if (Model.Name is not null) + { + + } +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/Plugins/BTCPayServer.Plugins.NIP05/Views/Shared/Nip05Nav.cshtml b/Plugins/BTCPayServer.Plugins.NIP05/Views/Shared/Nip05Nav.cshtml new file mode 100644 index 0000000..31d9260 --- /dev/null +++ b/Plugins/BTCPayServer.Plugins.NIP05/Views/Shared/Nip05Nav.cshtml @@ -0,0 +1,19 @@ +@using BTCPayServer.Abstractions.Contracts +@using BTCPayServer.Abstractions.Extensions +@using BTCPayServer.Client +@using Microsoft.AspNetCore.Mvc.TagHelpers +@inject IScopeProvider ScopeProvider +@{ + var storeId = ScopeProvider.GetCurrentStoreId(); +} +@if (!string.IsNullOrEmpty(storeId)) +{ + +} diff --git a/Plugins/BTCPayServer.Plugins.NIP05/_ViewImports.cshtml b/Plugins/BTCPayServer.Plugins.NIP05/_ViewImports.cshtml new file mode 100644 index 0000000..d897d63 --- /dev/null +++ b/Plugins/BTCPayServer.Plugins.NIP05/_ViewImports.cshtml @@ -0,0 +1,5 @@ +@using BTCPayServer.Abstractions.Services +@inject Safe Safe +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +@addTagHelper *, BTCPayServer +@addTagHelper *, BTCPayServer.Abstractions \ No newline at end of file