{"slug": "built-a-lightning-gated-reverse-proxy-that-charges-ai-scrapers", "title": "Built a Lightning-gated reverse proxy that charges AI scrapers", "summary": "A developer built Argentic, a Go-based reverse proxy that charges AI scrapers per request using Lightning Network payments via L402 credentials, returning a 402 Payment Required with a Bitcoin Lightning invoice when payment is missing. The proxy validates macaroons with caveats for path, method, expiry, and response size, and requires patching HTTP clients like httpx and aiohttp to auto-pay and retry. Pricing is configurable per endpoint, with default 1000 millisats per request and up to 5000 for premium paths, and it works with LND-compatible nodes.", "body_md": "# Built a Lightning-gated reverse proxy that charges AI scrapers\n\nThe stack is deliberately minimal — a Go proxy that intercepts inbound traffic, validates an L402 (LSAT + Lightning) credential, and either forwards the request or returns a `402 Payment Required`\n\nwith a fresh invoice. No accounts, no API keys, no Stripe. Just sats.\n\n```\nclient → [Argentic] → your API\n           │\n           └─ validates macaroon + preimage\n              │\n              ├─ valid → proxy request\n              └─ invalid → 402 + lightning invoice\n```\n\nEach macaroon carries caveats: target path, method, expiry timestamp, max response bytes. The preimage proves payment settled on-chain (well, off-chain via Lightning). Caveats are verified cryptographically — no database lookup needed.\n\nDeployment is a single binary plus a config file:\n\n```\nlisten: \":8080\"\nupstream: \"http://api.internal:8000\"\nlnd:\n  host: \"lnd:10009\"\n  macaroon_path: \"/data/admin.macaroon\"\n  tls_path: \"/data/tls.cert\"\npricing:\n  default: 1000  # millisats per request\n  paths:\n    \"/v1/premium\": 5000\n    \"/v1/bulk\": 100\nmacaroon:\n  expiry: \"24h\"\n  id_bytes: 16\n```\n\nThe pricing model is where it gets interesting. You can charge more for compute-heavy endpoints, less for cached reads, zero for health checks. Since the macaroon encodes the path, a single invoice can cover a batch of requests to the same tier — the agent presents the same preimage until expiry.\n\nTested it against a few open-source scraping frameworks. Most choke on `402`\n\nbecause they expect `429`\n\nor `403`\n\n. Had to patch `httpx`\n\nand `aiohttp`\n\nmiddleware to auto-pay and retry. That friction is the feature — it filters for agents that actually have a budget.\n\nOne gotcha: LND's `settleInvoice`\n\nRPC requires the preimage, but the proxy only sees the payment hash in the macaroon. Workaround is a background poller that indexes settled invoices by payment hash → preimage. Adds ~200ms latency on first request after payment. Acceptable for now.\n\n```\nfunc (p *Proxy) validateMacaroon(m *macaroon.Macaroon, preimage []byte) error {\n    // verify signature with root key\n    if !m.Verify(p.rootKey) {\n        return ErrInvalidSignature\n    }\n    // check caveats\n    for _, c := range m.Caveats() {\n        if !p.checkCaveat(c, preimage) {\n            return ErrCaveatFailed\n        }\n    }\n    // verify preimage hashes to payment_hash in macaroon\n    if !bytes.Equal(sha256.Sum256(preimage), m.PaymentHash()) {\n        return ErrPreimageMismatch\n    }\n    return nil\n}\n```\n\nStill deciding on the macaroon rotation strategy. Short expiry (1h) means frequent re-payment but tighter revocation. Long expiry (24h) reduces Lightning traffic but leaves a wider window if a preimage leaks. Leaning toward 4h with a refresh endpoint that issues a new macaroon for the same preimage.\n\nOpen question: should the proxy aggregate multiple requests into a single invoice (pay once, get N requests) or keep it strictly per-request? Per-request is simpler and maps cleanly to metered API pricing. Batch feels better for high-frequency agents but complicates caveat encoding.\n\nBinary and config examples at the repo. No Docker image yet — `go build`\n\nand drop it in front of whatever you're protecting. Works with any LND-compatible node (Core Lightning, LND, LDK).\n\nWhat's the most hostile scraping pattern you've seen that rate limits didn't stop?\n\n[Next Gen Z job anxiety hits new highs as AI coding agents ship →](/en/news/7155/)", "url": "https://wpnews.pro/news/built-a-lightning-gated-reverse-proxy-that-charges-ai-scrapers", "canonical_source": "https://promptcube3.com/en/news/7157/", "published_at": "2026-08-21 07:40:47+00:00", "updated_at": "2026-08-21 08:12:46.650102+00:00", "lang": "en", "topics": ["ai-infrastructure", "ai-tools", "ai-policy"], "entities": ["Argentic", "Go", "Lightning Network", "L402", "LND", "Core Lightning", "LDK", "httpx"], "alternates": {"html": "https://wpnews.pro/news/built-a-lightning-gated-reverse-proxy-that-charges-ai-scrapers", "markdown": "https://wpnews.pro/news/built-a-lightning-gated-reverse-proxy-that-charges-ai-scrapers.md", "text": "https://wpnews.pro/news/built-a-lightning-gated-reverse-proxy-that-charges-ai-scrapers.txt", "jsonld": "https://wpnews.pro/news/built-a-lightning-gated-reverse-proxy-that-charges-ai-scrapers.jsonld"}}