feat: nostr-tools + ephemeral inquiry submission helper

The contact form's submissions land in the client's Nostr inbox
without ever touching a server we control. submitInquiry generates a
throwaway secp256k1 keypair per submission, wraps the payload as a
NIP-17 / NIP-59 gift-wrapped kind:1059 event (NIP-44 v2 encryption
inside), publishes through SimplePool to the configured relays, and
discards the ephemeral key. The visitor leaves no persistent identity.

VITE_OWNER_NPUB (the recipient) and VITE_NOSTR_RELAYS (optional
override of the default damus/nos.lol/relay.nostr.band set) are
read at build time. env.d.ts grows typed declarations so the rest
of the app catches typos at compile time.

The store is the boilerplate feature README's prescribed shape —
SimplePool + relays ref + Promise.allSettled-wrapped publish —
extended only with env-driven relay parsing. submitInquiry returns
{ok, acceptedBy, attempted} so the form can surface partial-relay
failures honestly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Padreug 2026-05-27 11:22:47 +02:00
commit dd4c87b548
5 changed files with 181 additions and 0 deletions

11
env.d.ts vendored
View file

@ -1 +1,12 @@
/// <reference types="vite/client" />
interface ImportMetaEnv {
/** Hex- or bech32-encoded npub of the inquiry recipient. */
readonly VITE_OWNER_NPUB?: string
/** Comma-separated wss:// relay list; falls back to a default set if unset. */
readonly VITE_NOSTR_RELAYS?: string
}
interface ImportMeta {
readonly env: ImportMetaEnv
}