Skip to main content

Installation

go get github.com/shinydapps/l402-kit/go@v1.0.1
The module requires Go 1.21+.

Quick start

package main

import (
    "encoding/json"
    "net/http"
    l402 "github.com/shinydapps/l402-kit/go"
)

func main() {
    mux := http.NewServeMux()

    protected := l402.Middleware(l402.Options{
        PriceSats:        10,
        LightningAddress: "you@blink.sv",
    })

    mux.Handle("/api/data", protected(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "application/json")
        json.NewEncoder(w).Encode(map[string]string{"data": "premium content"})
    })))

    http.ListenAndServe(":8080", mux)
}

l402.Options

FieldTypeRequiredDescription
PriceSatsint64Amount in satoshis per call
LightningAddressstringYour Lightning address (you@blink.sv)
InvoiceExpiryintInvoice TTL in seconds (default: 3600)

l402.Middleware(opts Options)

Returns an func(http.Handler) http.Handler compatible with net/http, Chi, Gorilla Mux, and any standard Go HTTP framework. First call (no token):
HTTP 402 Payment Required
WWW-Authenticate: L402 macaroon="...", invoice="lnbc..."
Subsequent call (with payment proof):
Authorization: L402 <macaroon>:<preimage>
→ HTTP 200 OK

Verification

The middleware verifies SHA256(preimage) == paymentHash locally — no external call on the hot path. Replay prevention: each preimage is checked against Supabase (unique constraint) before access is granted.

Error codes

StatusMeaning
402No payment token — pay the invoice
401Invalid preimage (wrong payment proof)
401Replayed token (already used)

Contact

Questions or access issues: shinydapps@gmail.com · Lightning: shinydapps@blink.sv