Installation
Quickstart
Self-hosted mode (bring your own provider)
l402.Options
| Field | Type | Default | Description |
|---|---|---|---|
PriceSats | int | required | Price per call in satoshis |
Lightning | LightningProvider | required | Your Lightning backend (use NewBlinkProvider) |
OnPayment | func(L402Token, int) | � | Callback fired after each verified payment |
l402.Middleware(opts Options, next http.Handler) http.Handler
Returns an http.Handler compatible with net/http, Chi, Gorilla Mux, and any standard Go HTTP framework.
Behavior
| Request | Response |
|---|---|
No Authorization header | 402 + WWW-Authenticate: L402 macaroon="...", invoice="lnbc..." |
Valid L402 <macaroon>:<preimage> | next.ServeHTTP(w, r) |
| Invalid or expired token | 401 Unauthorized |
| Replayed preimage | 401 Token already used |
402 response body
LightningProvider interface
OnPayment callback
Verification
SHA256(preimage) == paymentHash is verified locally in memory � sub-millisecond, no network call on the hot path. Token expiry (exp field in the macaroon) is checked in the same operation.
The replay guard uses an in-memory map by default (safe for a single process). For multi-instance deployments, use a shared store (Redis or similar) � which adds a 5�50 ms round-trip per verified request.
Chi router example
l402.Middleware returns a standard http.Handler, so it works directly with Chi’s r.Handle:
Error codes
| Status | Meaning |
|---|---|
402 | No payment token � pay the invoice |
401 | Invalid token or expired macaroon |
401 | Replayed token (preimage already used) |