Expose event CRUD over nostr-transport (events_event_create / update / cancel / list) #21

Open
opened 2026-05-24 15:18:44 +00:00 by padreug · 0 comments
Owner

Context

PR #19 added the events extension's first nostr-transport RPC
(events_ticket_register). The webapp's other event-related ops
still go over HTTP via TicketApiService. Now that the transport
plumbing is in place, the obvious next step is moving event CRUD
to RPCs so organizers don't need an LNbits HTTP session at all —
the signed Nostr event IS the credential.

Proposed RPCs

RPC Auth Body Returns
events_event_create AUTH_WALLET CreateEvent shape (name, dates, capacity, price, currency, allow_fiat, categories, banner, location, …) Event dict
events_event_update AUTH_WALLET { event_id, patch: Partial<CreateEvent> } Event dict
events_event_cancel AUTH_WALLET { event_id } Event dict with canceled=True
events_event_delete AUTH_WALLET { event_id } { deleted: true }
events_event_list_mine AUTH_WALLET { all_wallets?: bool } list[Event]
events_event_approve AUTH_ACCOUNT (admin check inside handler) { event_id } Event dict
events_event_reject AUTH_ACCOUNT (admin check inside handler) { event_id } Event dict

Each handler reuses the existing CRUD / services functions; the
RPC wrapper translates auth + ownership checks the way
handle_events_ticket_register does today.

Webapp side

TicketApiService shrinks. Methods that were HTTP POST/PUT against
/events/api/v1/events/* become thin wrappers around
NostrTransportService.call(...). The transport service is already
in place from PR #73, so this is purely method-level migration —
no architectural change.

GET-style endpoints (/events/public, /events/{id}) should stay
on HTTP for now since they're public + don't benefit from the
encrypted RPC; switch later if/when the LNbits HTTP API gets fully
deprecated.

Phasing

Each RPC can land independently. Recommended order:

  1. events_event_create — biggest UX win (event creation no longer
    needs an admin_key in browser).
  2. events_event_update — same shape as create.
  3. events_event_cancel + events_event_delete — small additions.
  4. events_event_list_mine — replaces the
    fetchMyEvents(invoiceKey) HTTP call in useActivities.ts.
  5. events_event_approve / events_event_reject — admin-only,
    only matters for instances with auto_approve = false.

Each step is a small PR pair (one commit per RPC on the events
extension, one webapp commit swapping the call site).

Out of scope

  • tickets_* RPCs beyond register. The buyer-side requestTicket
    flow doesn't need encryption (it's already keyed by user_id
    via Bearer auth and the response carries a bolt11 anyone could
    intercept anyway — the security boundary is the wallet, not the
    request). Maybe revisit if the LNbits HTTP path goes away
    entirely.
  • The republish-all / republish-mine admin endpoints — those
    are one-shot migrations, no need to nostr-ify.

Why now (or whenever this gets picked up)

Stepping stone to the long-stated "depend completely on Nostr"
direction. Each RPC migration is small and low-risk; the
incremental nature means each PR ships value independently.

## Context PR #19 added the events extension's first nostr-transport RPC (`events_ticket_register`). The webapp's other event-related ops still go over HTTP via `TicketApiService`. Now that the transport plumbing is in place, the obvious next step is moving event CRUD to RPCs so organizers don't need an LNbits HTTP session at all — the signed Nostr event IS the credential. ## Proposed RPCs | RPC | Auth | Body | Returns | |---|---|---|---| | `events_event_create` | `AUTH_WALLET` | `CreateEvent` shape (name, dates, capacity, price, currency, allow_fiat, categories, banner, location, …) | `Event` dict | | `events_event_update` | `AUTH_WALLET` | `{ event_id, patch: Partial<CreateEvent> }` | `Event` dict | | `events_event_cancel` | `AUTH_WALLET` | `{ event_id }` | `Event` dict with `canceled=True` | | `events_event_delete` | `AUTH_WALLET` | `{ event_id }` | `{ deleted: true }` | | `events_event_list_mine` | `AUTH_WALLET` | `{ all_wallets?: bool }` | `list[Event]` | | `events_event_approve` | `AUTH_ACCOUNT` (admin check inside handler) | `{ event_id }` | `Event` dict | | `events_event_reject` | `AUTH_ACCOUNT` (admin check inside handler) | `{ event_id }` | `Event` dict | Each handler reuses the existing CRUD / services functions; the RPC wrapper translates auth + ownership checks the way `handle_events_ticket_register` does today. ## Webapp side `TicketApiService` shrinks. Methods that were HTTP POST/PUT against `/events/api/v1/events/*` become thin wrappers around `NostrTransportService.call(...)`. The transport service is already in place from PR #73, so this is purely method-level migration — no architectural change. GET-style endpoints (`/events/public`, `/events/{id}`) should stay on HTTP for now since they're public + don't benefit from the encrypted RPC; switch later if/when the LNbits HTTP API gets fully deprecated. ## Phasing Each RPC can land independently. Recommended order: 1. `events_event_create` — biggest UX win (event creation no longer needs an admin_key in browser). 2. `events_event_update` — same shape as create. 3. `events_event_cancel` + `events_event_delete` — small additions. 4. `events_event_list_mine` — replaces the `fetchMyEvents(invoiceKey)` HTTP call in `useActivities.ts`. 5. `events_event_approve` / `events_event_reject` — admin-only, only matters for instances with `auto_approve = false`. Each step is a small PR pair (one commit per RPC on the events extension, one webapp commit swapping the call site). ## Out of scope - `tickets_*` RPCs beyond register. The buyer-side `requestTicket` flow doesn't need encryption (it's already keyed by user_id via Bearer auth and the response carries a bolt11 anyone could intercept anyway — the security boundary is the wallet, not the request). Maybe revisit if the LNbits HTTP path goes away entirely. - The `republish-all` / `republish-mine` admin endpoints — those are one-shot migrations, no need to nostr-ify. ## Why now (or whenever this gets picked up) Stepping stone to the long-stated "depend completely on Nostr" direction. Each RPC migration is small and low-risk; the incremental nature means each PR ships value independently.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
aiolabs/events#21
No description provided.