Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,8 @@ Example:
"params": {
"recipient_pubky": "pubky<creator_z32>",
"amount": "50000",
"asset": "BTC"
"asset": "BTC",
"payment_in": 24
}
}
],
Expand Down Expand Up @@ -487,7 +488,7 @@ For example:

A submitted proof bundle is sent by the viewer before verification. It is not stored as an entitlement unless verification succeeds.

For `paykit-payment`, the content lock criterion params are exactly `recipient_pubky`, positive base-unit string `amount`, and non-empty `asset`. `recipient_pubky` must equal the content-lock creator. In v1 it must be the lock's only criterion, referenced exactly once by the lock logic. The submitted proof carries no payment details in its proof payload; it uses top-level `reader_public_key` plus the canonical `pubky_lock_resource` so the Lock Server can create the Paykit invoice.
For `paykit-payment`, the content lock criterion params are exactly `recipient_pubky`, positive base-unit string `amount`, non-empty `asset`, and positive whole-hour JSON `u64` `payment_in`. `recipient_pubky` must equal the content-lock creator. In v1 it must be the lock's only criterion, referenced exactly once by the lock logic. The submitted proof carries no payment details in its proof payload; it uses top-level `reader_public_key` plus the canonical `pubky_lock_resource` so the Lock Server can create the Paykit invoice.

Example:

Expand Down
4 changes: 3 additions & 1 deletion docs/ADRs/0020-locks-paykit-v1-integration-boundary.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@ The v1 content-lock criterion has verifier wire value `paykit-payment` and param
{
"recipient_pubky": "pubky<creator>",
"amount": "50000",
"asset": "BTC"
"asset": "BTC",
"payment_in": 24
}
```

- `recipient_pubky` must equal the canonical content-lock creator.
- `amount` is a positive decimal integer string in the asset's base unit.
- `asset` is an opaque, non-empty string to Locks. Paykit Server owns deployment-specific asset support and base-unit interpretation.
- `payment_in` is a required, nonzero JSON `u64` number of whole hours in Locks policy.
- V1 permits exactly one payment criterion, referenced exactly once by the lock logic, and exactly one submitted payment proof.
- The submitted payment proof payload is `{}`. `reader_public_key` is top-level submission data.
- Content-lock authoring does not require runtime Paykit configuration or availability.
Expand Down
9 changes: 6 additions & 3 deletions docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ The Lock Server has one non-production route family and one authenticated creato
- Can run in `development`, `staging`, or `production`.
- Require `Authorization: Bearer <frontend_session_token>`.
- Derive creator identity from the frontend session. Request-body `creator` is rejected for authenticated routes.
- A guarded path can be owned by only one managed Content Lock for that creator. Creating a different Lock ID for an owned path returns `409 content_lock_path_conflict`.
- Missing/unknown/expired frontend sessions use the JSON error envelope (`401 frontend_session_unavailable` or `401 frontend_session_expired`).
- Missing/revoked creator-granted homeserver authority remains a separate operational error (`503 creator_authority_unavailable`).
- Creator authority status route: `GET /creator/authority-status`
Expand All @@ -50,7 +51,7 @@ Gated-off routes are plain Axum `404 Not Found` responses because the route is i
| --- | --- | --- | --- | --- |
| `PUT /creator/priv-resources/content/<path>` | `200` JSON storage-authoritative guarded-resource descriptor | Requires `Authorization: Bearer <frontend_session_token>`. Raw bytes body; declared `Content-Type` is validated. | No bearer secrets or raw bytes in response. The returned MIME comes from storage readback and may differ from the request header. | `400 invalid_request`, `401 frontend_session_unavailable`, `401 frontend_session_expired`, `413 payload_too_large`, `503 creator_authority_unavailable` |
| `DELETE /creator/priv-resources/content/<path>` | `204` empty response | Requires `Authorization: Bearer <frontend_session_token>`. | No bearer secrets or raw bytes in response. | `401 frontend_session_unavailable`, `401 frontend_session_expired`, `404 guarded_resource_not_found`, `503 creator_authority_unavailable` |
| `POST /creator/content-locks` | `200` JSON content lock | Requires `Authorization: Bearer <frontend_session_token>`. | No bearer secrets in response. | `400 invalid_request`, `404 guarded_resource_not_found`, `401 frontend_session_unavailable`, `401 frontend_session_expired`, `503 creator_authority_unavailable` |
| `POST /creator/content-locks` | `200` JSON content lock | Requires `Authorization: Bearer <frontend_session_token>`. | No bearer secrets in response. | `400 invalid_request`, `401 frontend_session_unavailable`, `401 frontend_session_expired`, `404 guarded_resource_not_found`, `409 content_lock_path_conflict`, `503 creator_authority_unavailable` |
| `POST /creator/lock-service-config` | `200` JSON lock-service pointer | Requires `Authorization: Bearer <frontend_session_token>`. | No bearer secrets in response. | `400 invalid_request`, `401 frontend_session_unavailable`, `401 frontend_session_expired`, `503 creator_authority_unavailable` |
| `GET /connect` | `200` HTML Lock-Server-hosted connect shell | No bearer auth. Mounted when `[creator_authority_acquisition].enabled = true`; `return_to` must match `allowed_return_origins` or explicit wildcard policy. | HTML intentionally contains the secret-bearing Pubky authorization URL on Lock Server origin; response must not contain frontend session token, one-time code, or creator authority secret. | `400 invalid_request`, `503 creator_authority_unavailable`, `404` when route gated off |
| `POST /connect/{flow_id}/complete` | `303` redirect to stored `return_to` | No bearer auth. Mounted when `[creator_authority_acquisition].enabled = true`; stored `return_to` is revalidated before redirect. | `Location` contains only callback `state` and one-time `code`; no authorization URL, frontend session token, or creator authority secret. | `400 invalid_request`, `404 creator_connect_flow_unavailable`, `410 creator_connect_flow_expired`, `503 creator_authority_unavailable`, `404` when route gated off |
Expand Down Expand Up @@ -104,6 +105,7 @@ Stable error codes and statuses mirror `locks-server/src/api/errors.rs` tests:
| `frontend_session_expired` | 401 | Frontend session token existed but expired. |
| `frontend_session_state_mismatch` | 400 | One-time code exchange state did not match. |
| `creator_authority_unavailable` | 503 | Creator-granted homeserver authority is unavailable or could not be revalidated. |
| `content_lock_path_conflict` | 409 | The creator-scoped guarded path already has an in-flight or published Content Lock owner. |
| `task_state_conflict` | 409 | Submission or completion conflicts with existing task state. |
| `unsupported_verifier_type` | 422 | Proof references a verifier unavailable in the current runtime. |
| `paykit_not_configured` | 422 | A `paykit-payment` proof was submitted to a Lock Server without a `[paykit]` runtime section. |
Expand Down Expand Up @@ -395,11 +397,12 @@ Every referenced guarded resource must currently exist for the same creator/path
{
"recipient_pubky": "pubky<recipient>",
"amount": "50000",
"asset": "BTC"
"asset": "BTC",
"payment_in": 24
}
```

`recipient_pubky` must be a valid Pubky public key string equal to the content-lock creator, `amount` must be a positive base-unit integer encoded as a string, and `asset` must be a non-empty string. The lock params do not include Paykit server URLs, account IDs, memos, expiry, payment references, or reader identity. A v1 content lock that uses `paykit-payment` must contain exactly that one criterion, and its `all` or `any` lock logic must reference that criterion exactly once. Mixed criteria, multiple payment criteria, recipient/creator mismatch, and duplicate or mismatched logic references return `400 invalid_request`.
`recipient_pubky` must be a valid Pubky public key string equal to the content-lock creator, `amount` must be a positive base-unit integer encoded as a string, `asset` must be a non-empty string, and `payment_in` must be a positive whole-hour JSON `u64`. The lock params do not include Paykit server URLs, account IDs, memos, expiry, payment references, or reader identity. A v1 content lock that uses `paykit-payment` must contain exactly that one criterion, and its `all` or `any` lock logic must reference that criterion exactly once. Mixed criteria, multiple payment criteria, recipient/creator mismatch, and duplicate or mismatched logic references return `400 invalid_request`.

#### Request

Expand Down
Loading
Loading