L402Server.AspNetCore
0.1.2
dotnet add package L402Server.AspNetCore --version 0.1.2
NuGet\Install-Package L402Server.AspNetCore -Version 0.1.2
<PackageReference Include="L402Server.AspNetCore" Version="0.1.2" />
<PackageVersion Include="L402Server.AspNetCore" Version="0.1.2" />
<PackageReference Include="L402Server.AspNetCore" />
paket add L402Server.AspNetCore --version 0.1.2
#r "nuget: L402Server.AspNetCore, 0.1.2"
#:package L402Server.AspNetCore@0.1.2
#addin nuget:?package=L402Server.AspNetCore&version=0.1.2
#tool nuget:?package=L402Server.AspNetCore&version=0.1.2
L402Server.AspNetCore
ASP.NET Core middleware for L402. Drop one line into any ASP.NET API to charge per-request Lightning payments. Built on L402Server — Lightning Enable handles invoices, macaroons, and payment verification; your API stays where it is.
Install
dotnet add package L402Server.AspNetCore
Target: .NET 8.0+.
30-second example
using L402Server.AspNetCore;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddL402AspNetCore(opts =>
{
opts.ApiKey = builder.Configuration["LightningEnable:ApiKey"]!;
});
var app = builder.Build();
app.UseRouting();
app.UseL402();
app.MapControllers();
app.Run();
Then mark any controller action with [L402(PriceSats = 100)] and that endpoint is gated behind a 100-sat L402 payment:
[ApiController]
[Route("api/premium")]
public class PremiumController : ControllerBase
{
[HttpGet("weather")]
[L402(PriceSats = 100)]
public IActionResult Weather() => Ok(new { temp = 72 });
}
That's it. The middleware handles:
- Issuing
402 Payment Requiredwith a Lightning invoice on unauthenticated requests - Verifying
Authorization: L402 <macaroon>:<preimage>on retries - Stashing the verified credential in
HttpContext.Items[L402HttpContextKeys.VerificationResult]
Endpoints without [L402] pass through ungated.
Pricing patterns
Per-route attributes (compile-time prices)
[HttpGet("forecast"), L402(PriceSats = 100)]
public IActionResult Forecast() => Ok(...);
[HttpGet("premium-llm"), L402(PriceSats = 500, Description = "GPT-4 backed")]
public IActionResult PremiumLlm() => Ok(...);
Global flat price (gates everything mounted under the middleware)
app.UseL402(opts => opts.DefaultPriceSats = 100);
Function-form pricing (variable per request)
app.UseL402(opts =>
{
opts.PriceSelector = ctx => ValueTask.FromResult(
ctx.Request.Query["model"] == "premium" ? 500 : 100);
});
Resolution order: PriceSelector > [L402(PriceSats)] attribute > DefaultPriceSats. If none → request passes through ungated.
Verified credential on downstream handlers
[HttpGet("weather"), L402(PriceSats = 100)]
public IActionResult Weather(HttpContext ctx)
{
var result = (VerificationResult)ctx.Items[L402HttpContextKeys.VerificationResult]!;
_logger.LogInformation("Served {Resource} for {Sats} sats ({Hash})",
result.Resource, result.AmountSats, result.PaymentHash);
return Ok(new { temp = 72 });
}
Configuration
| Option | Type | Default | Notes |
|---|---|---|---|
DefaultPriceSats |
int? |
null |
Flat price applied when no [L402] attribute is present |
PriceSelector |
Func<HttpContext, ValueTask<int>>? |
null |
Variable pricing per request; overrides attribute + default |
ResourceSelector |
Func<HttpContext, string>? |
HttpContext.Request.Path |
Bound as a macaroon caveat |
DescriptionSelector |
Func<HttpContext, string?>? |
null |
Shown to the payer in their wallet |
IdempotencyKeySelector |
Func<HttpContext, string?>? |
null |
Sends X-Idempotency-Key for retry-safe challenge minting |
OnInvalidToken |
Func<HttpContext, VerificationResult, ValueTask>? |
sends 401 |
Custom handler — e.g. send a fresh 402 instead |
Two integration modes
Lightning Enable supports two integration shapes:
- Proxy mode — point Lightning Enable at your API URL; we forward authenticated requests on your behalf.
- Native mode — install this middleware in your existing API. Lightning Enable handles payment; your API handles everything else. This middleware is the Native mode for ASP.NET Core.
How the protocol works under the hood
Every paid request makes one round-trip to the Lightning Enable hosted API. The middleware never holds key material, never signs macaroons, never verifies preimages locally — all of that is in the hosted backend. The middleware itself is HTTP-client glue.
What you pay for with your Lightning Enable subscription: the protocol broker that lets this be one line of middleware.
Sibling packages
L402Server— the SDK this middleware is built on. Use directly for non-ASP.NET-Core .NET hosts.L402Requests— consumer-side HTTP client. Auto-pays L402 challenges.
Contributing
Open source under MIT. Issues and PRs welcome.
License
MIT © Refined Element
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- L402Server (>= 0.1.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.