@speeddev/l402-express 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -22
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -28,28 +28,28 @@ Express middleware that enforces [L402](https://docs.lightning.engineering/the-l
|
|
|
28
28
|
|
|
29
29
|
L402 is an HTTP-native payment protocol built on Lightning Network. The flow has three steps:
|
|
30
30
|
|
|
31
|
-
1. **Challenge** — a client makes a request to a protected endpoint without payment credentials. The middleware responds with `402 Payment Required`, a Lightning invoice (created
|
|
31
|
+
1. **Challenge** — a client makes a request to a protected endpoint without payment credentials. The middleware responds with `402 Payment Required`, a Lightning invoice (created using your Speed account's API Key), and a signed macaroon.
|
|
32
32
|
2. **Payment** — the client pays the Lightning invoice and receives a preimage (proof of payment).
|
|
33
33
|
3. **Access** — the client retries the request with an `Authorization: L402 <macaroon>:<preimage>` header. The middleware verifies the macaroon signature, the caveats (method, path, amount, currency, expiry), and the preimage against the payment hash. On success the request is forwarded to your route handler.
|
|
34
34
|
|
|
35
|
-
Responses to verified requests are cached for the duration of the macaroon's TTL (10 minutes), so replaying a valid credential returns the cached response instantly without hitting your handler again.
|
|
35
|
+
> **Note:** Responses to verified requests are cached for the duration of the macaroon's TTL (default 10 minutes), so replaying a valid credential returns the cached response instantly without hitting your handler again.
|
|
36
36
|
|
|
37
37
|
---
|
|
38
38
|
|
|
39
39
|
## Prerequisites
|
|
40
40
|
|
|
41
41
|
- **Node.js 18 or higher**
|
|
42
|
-
- **Express 4 or higher**
|
|
43
|
-
- **A Speed account and API key** — sign up and manage keys at [app.tryspeed.com/
|
|
42
|
+
- **Express 4.19.2 or higher**
|
|
43
|
+
- **A Speed account and API key** — sign up and manage keys at - [app.tryspeed.com/apikeys/restricted-keys](https://app.tryspeed.com/apikeys/restricted-keys)
|
|
44
44
|
|
|
45
45
|
### Getting a Speed API key
|
|
46
46
|
|
|
47
|
-
1. Log in to the [Speed
|
|
48
|
-
2.
|
|
49
|
-
3.
|
|
50
|
-
|
|
47
|
+
1. Log in to the [Speed Merchant](https://app.tryspeed.com/dashboard).
|
|
48
|
+
2. Navigate to **Developers → API keys → Standard keys**.
|
|
49
|
+
3. Create a **Restricted Key** : Speed recommends using a restricted key (rk_live_...) for the speedApiKey option. While creating the restricted key, select Core → Payments as the module and grant Write permission.
|
|
50
|
+
|
|
51
|
+
Standard secret keys (sk_live_...) will also work, but they provide broader account privileges (including Send functionality). Hence for better security and least-privilege access, we recommend using a restricted key.
|
|
51
52
|
|
|
52
|
-
Use your **publishable key** or **secret key** as the `speedApiKey` option. The publishable key is sufficient for creating payments. Secret keys (`sk_test_…` / `sk_live_…`) work too but carry broader account privileges — prefer the publishable key when it covers your use case.
|
|
53
53
|
|
|
54
54
|
---
|
|
55
55
|
|
|
@@ -83,7 +83,7 @@ app.use(
|
|
|
83
83
|
{
|
|
84
84
|
method: 'GET',
|
|
85
85
|
path: '/api/report',
|
|
86
|
-
amount:
|
|
86
|
+
amount: 1,
|
|
87
87
|
currency: 'USD',
|
|
88
88
|
targetCurrency: 'SATS',
|
|
89
89
|
},
|
|
@@ -108,7 +108,7 @@ Any route not listed in `configs` passes through freely without a payment check.
|
|
|
108
108
|
|
|
109
109
|
| Option | Type | Required | Description |
|
|
110
110
|
|---|---|---|---|
|
|
111
|
-
| `speedApiKey` | `string` | Yes | Your Speed
|
|
111
|
+
| `speedApiKey` | `string` | Yes | Your Speed API key (`rk_live_…` or `sk_live_…`). |
|
|
112
112
|
| `macaroonSecret` | `string` | Yes | 32-byte hex-encoded secret used to sign and verify macaroons. Generate one with `npx l402-generate-secret`. |
|
|
113
113
|
| `caveatTtlMs` | `number` | No | Macaroon TTL in milliseconds. Defaults to 10 minutes when omitted. Must be a positive number if provided. |
|
|
114
114
|
| `configs` | `RouteConfig[]` | Yes | Array of route-level payment rules. |
|
|
@@ -117,10 +117,10 @@ Any route not listed in `configs` passes through freely without a payment check.
|
|
|
117
117
|
|
|
118
118
|
| Field | Type | Required | Description |
|
|
119
119
|
|---|---|---|---|
|
|
120
|
-
| `method` | `string` | Yes | HTTP method to match
|
|
120
|
+
| `method` | `string` | Yes | HTTP method to match (e.g. `'GET'`, `'POST'`). Case-insensitive — normalized to uppercase automatically. |
|
|
121
121
|
| `path` | `string` | Yes | [path-to-regexp](https://github.com/pillarjs/path-to-regexp) pattern (e.g. `'/api/resource/:id'`). |
|
|
122
|
-
| `amount` | `number` | Yes | Payment amount
|
|
123
|
-
| `currency` | `string` | Yes | ISO 4217 currency code for the payment amount (e.g. `'USD'`, `'EUR'`, `'SATS'`). |
|
|
122
|
+
| `amount` | `number` | Yes | Payment amount you intend to collect. |
|
|
123
|
+
| `currency` | `string` | Yes | ISO 4217 [currency code](https://apidocs.tryspeed.com/reference/enum-base-currency) for the payment amount (e.g. `'USD'`, `'EUR'`, `'SATS'`). |
|
|
124
124
|
| `targetCurrency` | `string` | No | Cryptocurrency to settle in: `'SATS'`, `'USDT'`, or `'USDC'`. Defaults to `'SATS'` when omitted. |
|
|
125
125
|
|
|
126
126
|
**Example — charge $2.50 USD, settle in SATS:**
|
|
@@ -129,7 +129,7 @@ Any route not listed in `configs` passes through freely without a payment check.
|
|
|
129
129
|
{
|
|
130
130
|
method: 'POST',
|
|
131
131
|
path: '/api/generate',
|
|
132
|
-
amount:
|
|
132
|
+
amount: 2.5,
|
|
133
133
|
currency: 'USD',
|
|
134
134
|
targetCurrency: 'SATS',
|
|
135
135
|
}
|
|
@@ -170,13 +170,11 @@ Rotate this secret if you suspect it has been compromised. All previously issued
|
|
|
170
170
|
|
|
171
171
|
## API key security
|
|
172
172
|
|
|
173
|
-
Speed API keys carry full account privileges. Follow these practices:
|
|
174
|
-
|
|
175
173
|
- **Never** embed secret keys in client-side code, public repositories, or anywhere outside a secure server environment.
|
|
176
|
-
- Store keys in environment variables or a secrets manager (e.g. AWS Secrets Manager, HashiCorp Vault).
|
|
177
|
-
- Use **Test mode keys** (`sk_test_…`) during development and **Live mode keys** (`sk_live_…`) in production only.
|
|
178
|
-
- If a key is compromised, rotate it immediately from **Developers → API keys** in the [Speed dashboard](https://app.tryspeed.com/dashboard). A rotated key is permanently disabled; you cannot rotate the same key again within 24 hours.
|
|
179
174
|
- Consider [restricted API keys](https://app.tryspeed.com/apikeys/restricted-keys) to limit the scope of what each key can do.
|
|
175
|
+
- Store keys in environment variables or a secrets manager (e.g. AWS Secrets Manager, HashiCorp Vault).
|
|
176
|
+
- If a key is compromised, rotate it immediately from the [Speed dashboard](https://app.tryspeed.com/dashboard).
|
|
177
|
+
|
|
180
178
|
|
|
181
179
|
---
|
|
182
180
|
|
|
@@ -195,7 +193,7 @@ l402Middleware({
|
|
|
195
193
|
Recommended `.env` layout (use [dotenv](https://github.com/motdotla/dotenv) or your platform's secret injection):
|
|
196
194
|
|
|
197
195
|
```env
|
|
198
|
-
SPEED_KEY=
|
|
196
|
+
SPEED_KEY=rk_live_...
|
|
199
197
|
SPEED_MACAROON_SECRET=<64-char hex from npx l402-generate-secret>
|
|
200
198
|
```
|
|
201
199
|
|
|
@@ -209,7 +207,7 @@ SPEED_MACAROON_SECRET=<64-char hex from npx l402-generate-secret>
|
|
|
209
207
|
| `400` | `Authorization` header present but malformed or macaroon verification failed. | `{ "message": "Malformed 'authorization' header" }` |
|
|
210
208
|
| `401` | Preimage does not match the payment hash in the macaroon. | `{ "message": "Invalid payment preimage" }` |
|
|
211
209
|
| `409` | A request with the same macaroon is already being processed. | `{ "message": "Payment is already being processed" }` |
|
|
212
|
-
| `500` | Speed API call failed
|
|
210
|
+
| `500` | Speed API call failed due to any reason. | `{ "message": "Internal server error" }` |
|
|
213
211
|
|
|
214
212
|
### WWW-Authenticate header format
|
|
215
213
|
|
package/package.json
CHANGED