Skip to content

Commit cc63f01

Browse files
committed
add README.md
Signed-off-by: Gustavo Chain <me@qustavo.cc>
1 parent 4acf973 commit cc63f01

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed

README.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# l402proxy
2+
3+
Drop an L402 payment gate in front of any HTTP service in one command.
4+
5+
No database, no ceremony — single binary + Lightning node.
6+
7+
## How it works
8+
9+
1. Request arrives with no auth → proxy responds `402 Payment Required` with a BOLT-11 invoice and a token in `WWW-Authenticate` and the JSON body
10+
2. Client pays the invoice, receives the preimage
11+
3. Client retries with `Authorization: L402 <token>:<preimage>` → proxy verifies payment → forwards to upstream
12+
13+
## Installation
14+
15+
```sh
16+
go install github.com/qustavo/l402proxy/cmd/l402proxy@latest
17+
```
18+
19+
## Usage
20+
21+
```sh
22+
l402proxy \
23+
--upstream http://localhost:3000 \
24+
--price 10sat \
25+
--lnd-host localhost:10009 \
26+
--lnd-macaroon ~/.lnd/data/chain/bitcoin/mainnet/admin.macaroon \
27+
--lnd-cert ~/.lnd/tls.cert \
28+
--secret-key $(openssl rand -hex 32)
29+
```
30+
31+
### Flags
32+
33+
| Flag | Default | Description |
34+
|---|---|---|
35+
| `--upstream` | required | URL of the backend service |
36+
| `--price` | required | Price per request (`10sat`, `1000msat`) |
37+
| `--listen` | `:8080` | Address to listen on |
38+
| `--lnd-host` | `localhost:10009` | LND gRPC host:port |
39+
| `--lnd-macaroon` | `~/.lnd/data/chain/bitcoin/mainnet/admin.macaroon` | Path to LND admin macaroon |
40+
| `--lnd-cert` | `~/.lnd/tls.cert` | Path to LND TLS cert |
41+
| `--service-name` | `l402proxy` | Label used in invoice memos |
42+
| `--secret-key` | auto-generated | Hex-encoded 32-byte HMAC secret (tokens won't survive restarts if omitted) |
43+
44+
## L402 flow (curl example)
45+
46+
**Step 1 — first request, no auth:**
47+
48+
```sh
49+
$ curl -i http://localhost:8080/api/data
50+
51+
HTTP/1.1 402 Payment Required
52+
WWW-Authenticate: L402 token="eyJ...", invoice="lnbc..."
53+
54+
{"token":"eyJ...","invoice":"lnbc...","amount_msat":10000}
55+
```
56+
57+
**Step 2 — pay the invoice, get the preimage:**
58+
59+
```sh
60+
$ lncli payinvoice lnbc...
61+
# → preimage: aabbccdd...
62+
```
63+
64+
**Step 3 — retry with credentials:**
65+
66+
```sh
67+
$ curl -H "Authorization: L402 eyJ...:aabbccdd..." http://localhost:8080/api/data
68+
69+
HTTP/1.1 200 OK
70+
...
71+
```
72+
73+
## Token format
74+
75+
`base64url(json_payload).hex(hmac_sha256)` — stateless, no database required. Token TTL is 24 hours.
76+
77+
## Comparison with Aperture
78+
79+
[Aperture](https://github.com/lightninglabs/aperture) is the reference L402 proxy by Lightning Labs.
80+
81+
| | Aperture | l402proxy |
82+
|---|---|---|
83+
| Database | etcd / Postgres / SQLite | None — stateless |
84+
| Config | Complex YAML | CLI flags |
85+
| LN backends | LND only | Pluggable interface |
86+
| Deployment | Multi-service setup | Single binary |
87+
| Use as library | No | Yes (Go middleware) |
88+
| Target audience | Production infra teams | Any developer, AI builders |
89+
90+
l402proxy is the zero-friction entry point — the thing you use to get started in 5 minutes.

0 commit comments

Comments
 (0)