NostrServices/NostrRelay/Extensions.cs

86 lines
3.0 KiB
C#

using System.Net.WebSockets;
using Newtonsoft.Json;
using Nostr.Client.Json;
namespace NostrRelay;
public static class Extensions
{
public static void MapRelay<TRelay>(this WebApplication app, string path,
RelayDocument? document = null,
string? landingPage = null)
where TRelay : INostrRelay, IDisposable
{
app.MapGet(path, async ctx =>
{
if (ctx.WebSockets.IsWebSocketRequest)
{
var logger = app.Services.GetRequiredService<ILogger<NostrRelay<TRelay>>>();
using var handler = app.Services.GetRequiredService<TRelay>();
try
{
var ws = await ctx.WebSockets.AcceptWebSocketAsync();
var wsCtx = new NostrClientContext(ws, ctx.Connection.RemoteIpAddress!,
ctx.Request.Headers.UserAgent.FirstOrDefault() ?? string.Empty);
var nostrRelay = new NostrRelay<TRelay>(handler, wsCtx, ctx.RequestAborted, logger);
await nostrRelay.Read();
await ws.CloseAsync(WebSocketCloseStatus.NormalClosure, null, ctx.RequestAborted);
}
catch (Exception ex)
{
logger.LogDebug(ex.Message);
}
}
else
{
var isRelayDocRequest = ctx.Request.Headers.Accept.FirstOrDefault()
?.Equals("application/nostr+json", StringComparison.InvariantCultureIgnoreCase) ?? false;
if (isRelayDocRequest)
{
var doc = document ?? new RelayDocument
{
Name = typeof(TRelay).Name,
Description = "NostrServices C# Relay Framework",
Pubkey = "63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed",
SupportedNips = [1],
Software = "NostrServices",
Icon = "https://void.cat/d/CtXsF5EvqNLG3K85TgezCt.webp",
Limitation = new()
{
RestrictedWrites = false,
AuthRequired = false,
PaymentRequired = false
}
};
if (ctx.Response.Headers.AccessControlAllowOrigin.Count == 0)
{
ctx.Response.Headers.AccessControlAllowOrigin = "*";
}
ctx.Response.ContentType = "application/json";
await ctx.Response.WriteAsync(JsonConvert.SerializeObject(doc, NostrSerializer.Settings));
}
else
{
ctx.Response.ContentType = "text/html";
await ctx.Response.WriteAsync(landingPage ?? @$"
<html>
<head>
<title>NostrServices Relay</title>
</head>
<body>
<h1>Welcome to {typeof(TRelay).Name}</h1>
</body>
</html>
");
}
}
});
}
}