feat: expose Chatelet over the LNbits nostr transport (#1)
Register kind-21000 RPC handlers on the core nostr_transport dispatcher so the booking flow runs over relays with no HTTP, mirroring lnurlp: - operator (AUTH_WALLET): room create/update/publish, block create — all ownership-checked; room_list_mine (AUTH_ACCOUNT). - public (AUTH_NONE): room_list/get (wallet id stripped), availability, booking_request, booking_get. Guest identity is the signed sender_pubkey, so no guest_pubkey is trusted from the body. - register_link_owner_resolver(tag=chatelet, key=booking_id) lets the operator stream settlements via subscribe_payments. Handlers delegate to services.py — no logic duplicated. Graceful no-op if the core transport module isn't in this LNbits build (pre-#4). Guests can't subscribe to the operator wallet, so they poll booking_get to confirm. Note documented in event-flow.md: with availability now an RPC, the custom kind:22000/22001 pair is redundant for RPC clients (revisit in #2). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019VUQCfdqiLSsFS2jcGnaFD
This commit is contained in:
parent
5cfc9b893d
commit
5b176e5186
3 changed files with 291 additions and 9 deletions
|
|
@ -7,9 +7,45 @@ How rooms, guests, LNbits, and relays interact. The guiding rule:
|
|||
> Lightning payment is the confirmation.
|
||||
|
||||
Two doors lead into the *same* booking flow — the REST API
|
||||
([`../views_api.py`](../views_api.py)) and the Nostr subscription
|
||||
([`../nostr/service.py`](../nostr/service.py)). Both funnel through
|
||||
[`../crud.py`](../crud.py) so arbitration + quoting live in one place.
|
||||
([`../views_api.py`](../views_api.py)) and the Nostr-transport RPC layer
|
||||
([`../transport_rpcs.py`](../transport_rpcs.py)). Both delegate to
|
||||
[`../services.py`](../services.py) (orchestration) over
|
||||
[`../crud.py`](../crud.py) (persistence) so arbitration + quoting live in one
|
||||
place and can't drift between doors.
|
||||
|
||||
## Door 2: RPC over the core nostr transport
|
||||
|
||||
The core LNbits nostr transport (`lnbits.core.services.nostr_transport`) is a
|
||||
**kind-21000 encrypted RPC bus** (NIP-44), not a general event publisher.
|
||||
Chatelet registers handlers on it in `chatelet_start()` so the whole booking
|
||||
flow runs over relays with no HTTP:
|
||||
|
||||
| RPC | Auth | Purpose |
|
||||
|---|---|---|
|
||||
| `chatelet_room_create` / `_update` / `_publish` | wallet | operator room CRUD (ownership-checked) |
|
||||
| `chatelet_block_create` | wallet | operator blocks a range |
|
||||
| `chatelet_room_list_mine` | account | operator's rooms across their wallets |
|
||||
| `chatelet_room_list` / `_get` | none | public discovery (active rooms, wallet id stripped) |
|
||||
| `chatelet_availability` | none | is a range free + a quote |
|
||||
| `chatelet_booking_request` | none | guest requests a stay (guest id = signed `sender_pubkey`) |
|
||||
| `chatelet_booking_get` | none | guest reads back their booking (ownership by `sender_pubkey`) |
|
||||
|
||||
Guest identity is the `sender_pubkey` the dispatcher lifts off the signed
|
||||
kind-21000 event — unspoofable, and it means no separate `guest_pubkey` is
|
||||
trusted from the body.
|
||||
|
||||
**Payment confirmation over RPC:** `subscribe_payments` is wallet-owner
|
||||
scoped, so the *operator* can stream booking settlements
|
||||
(`subscribe_payments({tag:"chatelet", link_id:<booking_id>})`, wired via
|
||||
`register_link_owner_resolver`). A **guest** can't subscribe to the operator's
|
||||
wallet, so the guest confirms by polling `chatelet_booking_get` until
|
||||
`confirmed` (a guest push would need a NIP-17 DM — issue #5).
|
||||
|
||||
> **Consequence for the custom kinds:** with availability answered by the
|
||||
> `chatelet_availability` RPC, the ephemeral `kind:22000/22001` availability
|
||||
> query/response (ADR-0001) is **redundant for RPC clients**. It is only worth
|
||||
> keeping if we want non-RPC Nostr clients to query availability by publishing
|
||||
> an event. Revisit when the public-discovery transport is chosen (issue #2).
|
||||
|
||||
## Actors
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue