feat: NIP-17 gift-wrapped check-in DM on confirmation (#5) #12

Merged
padreug merged 4 commits from feat/checkin-dm into main 2026-07-19 20:55:34 +00:00
Showing only changes of commit 43d071756e - Show all commits

docs: document the NIP-17/59 check-in DM flow

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019VUQCfdqiLSsFS2jcGnaFD
Padreug 2026-07-19 20:34:12 +02:00

View file

@ -93,10 +93,28 @@ with a logged warning and the booking flow (HTTP/RPC) is unaffected.
`sign_event` but its `nip44_encrypt` raises (bunker-forward by design, lnbits `sign_event` but its `nip44_encrypt` raises (bunker-forward by design, lnbits
#18). So **public** events (listing `30402`, calendar `31923`, availability #18). So **public** events (listing `30402`, calendar `31923`, availability
`22001` — availability is public info, so `22000/22001` are plaintext) publish `22001` — availability is public info, so `22000/22001` are plaintext) publish
today; **encrypted** events (reservation `30078`, and the `#5` check-in DM) today; **encrypted** events (reservation `30078`, and the check-in DM)
sign-encrypt via the operator signer and soft-fail with a clear log until the sign-encrypt via the operator signer and soft-fail with a clear log until the
operator has a bunker/server-signing signer. Nothing crashes either way. operator has a bunker/server-signing signer. Nothing crashes either way.
### Check-in DM (NIP-17 / NIP-59) — issue #5
On settlement (`tasks.on_invoice_paid`), the guest is sent their private
check-in details (address, gate code from `room.checkin_instructions`, plus
times/policy from settings) as a **gift-wrapped** DM, built in
`nostr/giftwrap.py` from core primitives (no vendored crypto):
1. **rumor** (kind 14, unsigned) — the message; sender is the operator.
2. **seal** (kind 13) — NIP-44-encrypts the rumor to the guest, **signed by
the operator** via the signer abstraction (bunker-forward; this is the
layer that soft-fails on a LocalSigner).
3. **gift wrap** (kind 1059) — NIP-44-encrypts the seal with a throwaway
**ephemeral** key (core `nip44_encrypt` + `sign_event`, local — no bunker
round-trip); only public metadata is the recipient `p`-tag. Seal + wrap
`created_at` are randomised into the past per NIP-59.
Best-effort: a DM failure never undoes a confirmed, paid booking.
## Happy path ## Happy path
```mermaid ```mermaid