feat: organizer ticket scanning over nostr-transport + secure legacy HTTP register endpoint #19
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "ticket-scanner-nostr"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
The events extension's first nostr-transport RPC: organizers scan
attendees' tickets at the door from the webapp, signing the
register call with their Nostr key. The dispatcher resolves pubkey
→ Account → wallet (
AUTH_WALLET); this handler adds event-levelownership verification on top.
Companion webapp PR pending. Backend ships first so the RPC is
registered before the webapp goes live (without the handler,
every scan attempt times out).
Commits
2b3d9dffeat: events_ticket_register RPC over nostr transport1d8dacbfix: require admin_key + owner check on PUT /tickets/registerRPC wire contract
events_ticket_registerAUTH_WALLET(caller must sign + provide wallet_id){ event_id: str, ticket_id: str }Ticketdict withregistered=True,reg_timestampsetresponse.error):"event_id and ticket_id are required"(bad request)"Ticket does not exist on this event"(404-ish)"Ticket not paid for"(paid=false)"Ticket already registered"(idempotent rejection)"Event does not exist""You do not own this event"(owner mismatch)"Wallet access required (provide wallet_id)"(from dispatcher)Registration in
events_start()is guarded withtry / except ImportErrorso the extension still loads on LNbits versions thatpre-date the transport (the HTTP path stays the fallback).
Legacy HTTP endpoint hardened
PUT /events/api/v1/tickets/register/{ticket_id}previously hadno auth decorator and no owner check. Any caller with a ticket
id could mark it registered. This PR adds
require_admin_key+the same
event.wallet ∈ user.wallet_idscheck as the RPC.The in-tree Quasar register page (
static/js/register.js)already sends the session admin_key via
LNbits.api.request, sothe LNbits admin UI keeps scanning cleanly. Breaking change
for any external integration that hit the unauthed endpoint —
they need to start sending an admin_key.
Smoke
docker restart regtest-lnbits-1→ events extension loads,log line:
[EVENTS] Registered nostr-transport RPC: events_ticket_register.curl -X PUT http://localhost:5001/events/api/v1/tickets/register/<any>without admin_key → 401 (was: 200/403 depending on ticket state).
Test plan
events_ticket_registerfrom a wallet that owns the event;response
status=OK, ticket row updated.status=ERROR,error="You do not own this event".error="Ticket not paid for".error="Ticket already registered"(idempotent).error="Ticket does not exist on this event".403 ("You do not own this event"). Owner's admin_key → 200 +
registered.
/events/register/<event_id>page stillscans (session admin_key still passes).
🤖 Generated with Claude Code
account.prvkey→ useresolve_signer(pre-cascade prerequisite for lnbits#17) #23