refactor: move hashcash stamp from X-Hashcash header to JSON request body

Move the hashcash proof-of-work stamp from the X-Hashcash HTTP header
into the JSON request body as a 'hashcash' field on POST /api/v1/session.

Updated server handler, CLI client, SPA client, and documentation.
This commit is contained in:
clawbot
2026-03-10 10:00:20 -07:00
committed by user
parent db4cd9f055
commit 09a1dddbd0
5 changed files with 52 additions and 59 deletions

View File

@@ -989,23 +989,18 @@ Create a new user session. This is the entry point for all clients.
If the server requires hashcash proof-of-work (see
[Hashcash Proof-of-Work](#hashcash-proof-of-work)), the client must include a
valid stamp in the `X-Hashcash` request header. The required difficulty is
advertised via `GET /api/v1/server` in the `hashcash_bits` field.
**Request Headers:**
| Header | Required | Description |
|--------------|----------|-------------|
| `X-Hashcash` | Conditional | Hashcash stamp (required when server has `hashcash_bits` > 0) |
valid stamp in the `hashcash` field of the JSON request body. The required
difficulty is advertised via `GET /api/v1/server` in the `hashcash_bits` field.
**Request Body:**
```json
{"nick": "alice"}
{"nick": "alice", "hashcash": "1:20:260310:neoirc::3a2f1"}
```
| Field | Type | Required | Constraints |
|--------|--------|----------|-------------|
| `nick` | string | Yes | 132 characters, must be unique on the server |
| Field | Type | Required | Constraints |
|------------|--------|-------------|-------------|
| `nick` | string | Yes | 132 characters, must be unique on the server |
| `hashcash` | string | Conditional | Hashcash stamp (required when server has `hashcash_bits` > 0) |
**Response:** `201 Created`
```json
@@ -1027,7 +1022,7 @@ advertised via `GET /api/v1/server` in the `hashcash_bits` field.
| Status | Error | When |
|--------|-------|------|
| 400 | `nick must be 1-32 characters` | Empty or too-long nick |
| 402 | `hashcash proof-of-work required` | Missing `X-Hashcash` header when hashcash is enabled |
| 402 | `hashcash proof-of-work required` | Missing `hashcash` field in request body when hashcash is enabled |
| 402 | `invalid hashcash stamp: ...` | Stamp fails validation (wrong bits, expired, reused, etc.) |
| 409 | `nick already taken` | Another active session holds this nick |
@@ -1035,8 +1030,7 @@ advertised via `GET /api/v1/server` in the `hashcash_bits` field.
```bash
TOKEN=$(curl -s -X POST http://localhost:8080/api/v1/session \
-H 'Content-Type: application/json' \
-H 'X-Hashcash: 1:20:260310:neoirc::3a2f1' \
-d '{"nick":"alice"}' | jq -r .token)
-d '{"nick":"alice","hashcash":"1:20:260310:neoirc::3a2f1"}' | jq -r .token)
echo $TOKEN
```
@@ -2138,7 +2132,7 @@ account registration, no IP-based rate limits that punish shared networks.
2. Client computes a hashcash stamp: find a counter value such that the
SHA-256 hash of the stamp string has the required number of leading zero
bits.
3. Client includes the stamp in the `X-Hashcash` request header when creating
3. Client includes the stamp in the `hashcash` field of the JSON request body when creating
a session: `POST /api/v1/session`.
4. Server validates the stamp:
- Version is `1`
@@ -2195,7 +2189,7 @@ Both the embedded web SPA and the CLI client automatically handle hashcash:
1. Fetch `GET /api/v1/server` to read `hashcash_bits`
2. If `hashcash_bits > 0`, compute a valid stamp
3. Include the stamp in the `X-Hashcash` header on `POST /api/v1/session`
3. Include the stamp in the `hashcash` field of the JSON body on `POST /api/v1/session`
The web SPA uses the Web Crypto API (`crypto.subtle.digest`) for SHA-256
computation with batched parallelism. The CLI client uses Go's `crypto/sha256`.