Documentation
¶
Index ¶
- func AppRelaysHandler(w http.ResponseWriter, r *http.Request)
- func AuthChallengeHandler(w http.ResponseWriter, r *http.Request)
- func AuthRequestsHandler(w http.ResponseWriter, r *http.Request)
- func BuildMediaServersHandler(w http.ResponseWriter, r *http.Request)
- func BuildProfileHandler(w http.ResponseWriter, r *http.Request)
- func BuildRelayListHandler(w http.ResponseWriter, r *http.Request)
- func ClientConnectHandler(w http.ResponseWriter, r *http.Request)
- func ClientDisconnectHandler(w http.ResponseWriter, r *http.Request)
- func ClientRelaysHandler(w http.ResponseWriter, r *http.Request)
- func ClientStatusHandler(w http.ResponseWriter, r *http.Request)
- func DiscoverRelaysHandler(w http.ResponseWriter, r *http.Request)
- func FixedRelaysHandler(w http.ResponseWriter, r *http.Request)
- func GetCacheHandler(w http.ResponseWriter, r *http.Request)
- func GetSessionHandler(w http.ResponseWriter, r *http.Request)
- func GetSuggestedMediaServersHandler(w http.ResponseWriter, r *http.Request)
- func GetUserMediaServersHandler(w http.ResponseWriter, r *http.Request)
- func GetUserProfileHandler(w http.ResponseWriter, r *http.Request)
- func GetUserRelayListsHandler(w http.ResponseWriter, r *http.Request)
- func GetUserRelaysHandler(w http.ResponseWriter, r *http.Request)
- func HandleAmberCallback(w http.ResponseWriter, r *http.Request)
- func KeyDeriveHandler(w http.ResponseWriter, r *http.Request)
- func KeyGenerationHandler(w http.ResponseWriter, r *http.Request)
- func KeyValidationHandler(w http.ResponseWriter, r *http.Request)
- func KnownRelaysHandler(w http.ResponseWriter, r *http.Request)
- func LoginHandler(w http.ResponseWriter, r *http.Request)
- func LogoutHandler(w http.ResponseWriter, r *http.Request)
- func Nip19DecodeHandler(w http.ResponseWriter, r *http.Request)
- func PingHandler(w http.ResponseWriter, r *http.Request)
- func PingRelaysHandler(w http.ResponseWriter, r *http.Request)
- func PrivateKeyConversionHandler(w http.ResponseWriter, r *http.Request)
- func PublicKeyConversionHandler(w http.ResponseWriter, r *http.Request)
- func PublishEventHandler(w http.ResponseWriter, r *http.Request)
- func PublishSignedHandler(w http.ResponseWriter, r *http.Request)
- func PublishSignedStreamHandler(w http.ResponseWriter, r *http.Request)
- func QueryEventsHandler(w http.ResponseWriter, r *http.Request)
- func RefreshCacheHandler(w http.ResponseWriter, r *http.Request)
- func RelayInfoHandler(w http.ResponseWriter, r *http.Request)
- func RemoveAuthHandler(w http.ResponseWriter, r *http.Request)
- func ResolveEventHandler(w http.ResponseWriter, r *http.Request)
- func StreamHandler(w http.ResponseWriter, r *http.Request)
- func SubmitAuthHandler(w http.ResponseWriter, r *http.Request)
- type AppRelaysPayload
- type ClientRelaysResponse
- type FixedRelaysRequest
- type FixedRelaysResponse
- type KeyGenerationResponse
- type KeyValidationResponse
- type MediaServerEntry
- type MediaServersBuildRequest
- type Nip19DecodeRequest
- type ProfileBuildRequest
- type PublishEventRequest
- type PublishEventResponse
- type PublishSignedRequest
- type PublishSignedResponse
- type RelayListBuildRequest
- type RelayStatus
- type UserMediaServersResponse
- type UserRelayListsResponse
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AppRelaysHandler ¶ added in v0.8.0
func AppRelaysHandler(w http.ResponseWriter, r *http.Request)
AppRelaysHandler gets (GET) or replaces (POST) the logged-in user's app-relay preferences. POST sets all four roles from the payload; an empty list clears that role's override (falling back to the configured default). The preferences are this user's alone. Session-gated.
@Summary Get or set app-relay preferences @Description This user's locally-configured Indexer/Broadcast/Local/Trusted relays. GET returns them; POST replaces them. @Tags client @Produce json @Success 200 {object} AppRelaysPayload @Failure 401 {string} string "Authentication required" @Router /api/v1/client/app-relays [get]
func AuthChallengeHandler ¶ added in v0.8.1
func AuthChallengeHandler(w http.ResponseWriter, r *http.Request)
AuthChallengeHandler opens the logged-in user's own connection to a relay and returns the NIP-42 challenge the relay issued on it, for the browser to sign. AUTH is per connection, so each user answers a challenge on a socket only their requests use. Session-gated.
@Summary Get a NIP-42 AUTH challenge for this user @Tags client @Accept json @Produce json @Param body body object{relay=string} true "Relay URL" @Success 200 {object} map[string]any @Failure 400 {string} string "Invalid request" @Failure 401 {string} string "Authentication required" @Router /api/v1/client/auth/challenge [post]
func AuthRequestsHandler ¶ added in v0.8.0
func AuthRequestsHandler(w http.ResponseWriter, r *http.Request)
AuthRequestsHandler lists the relays asking the logged-in user for NIP-42 AUTH, each with whether this user has authenticated to it. Session-gated; one user's AUTH state is never shown to, or shared with, another.
@Summary List NIP-42 AUTH requests @Description Relays that have challenged for AUTH, with this user's authed status. @Tags client @Produce json @Success 200 {array} core.AuthState @Failure 401 {string} string "Authentication required" @Router /api/v1/client/auth-requests [get]
func BuildMediaServersHandler ¶ added in v0.8.0
func BuildMediaServersHandler(w http.ResponseWriter, r *http.Request)
BuildMediaServersHandler assembles an UNSIGNED media-server list event for the session user, preserving any non-server tags on their existing list, and returns it for the browser to sign. Publish the signed event via /api/v1/events/publish.
@Summary Build a media-server list event @Description Assemble an unsigned Blossom (10063) or NIP-96 (10096) server-list event for the session user, preserving non-server tags, and return it to sign client-side. @Tags client @Accept json @Produce json @Success 200 {object} relay.Event @Failure 400 {string} string "Invalid request" @Failure 401 {string} string "Authentication required" @Router /api/v1/user/media-servers/build [post]
func BuildProfileHandler ¶ added in v0.8.0
func BuildProfileHandler(w http.ResponseWriter, r *http.Request)
BuildProfileHandler merges the supplied field edits over the user's existing kind-0 metadata and returns the UNSIGNED result for the browser to sign. The merge preserves every existing content field and tag — only edited fields are changed, and each is dual-written to content and a tag (see core.AssembleProfileEvent).
@Summary Build an updated profile event @Description Merge field edits over an existing kind-0 (preserving all other fields/tags) and return the unsigned event to sign client-side. @Tags client @Accept json @Produce json @Success 200 {object} relay.Event @Failure 400 {string} string "Invalid request" @Failure 401 {string} string "Authentication required" @Failure 403 {string} string "Pubkey mismatch" @Router /api/v1/user/profile/build [post]
func BuildRelayListHandler ¶ added in v0.8.0
func BuildRelayListHandler(w http.ResponseWriter, r *http.Request)
BuildRelayListHandler assembles an UNSIGNED relay-list event for the session user, preserving any non-relay tags on their existing list, and returns it for the browser to sign. Publish the signed event via /api/v1/events/publish.
@Summary Build a relay-list event @Description Assemble an unsigned NIP-65 (10002) / NIP-17 (10050) / NIP-51 (10006/10007/10012) relay-list event for the session user, preserving non-relay tags, and return it to sign client-side. @Tags client @Accept json @Produce json @Success 200 {object} relay.Event @Failure 400 {string} string "Invalid request" @Failure 401 {string} string "Authentication required" @Router /api/v1/user/relay-list/build [post]
func ClientConnectHandler ¶ added in v0.4.12
func ClientConnectHandler(w http.ResponseWriter, r *http.Request)
ClientConnectHandler connects the client to a relay Usage: POST /api/v1/client/connect/relay.damus.io?read=true&write=false
@Summary Connect to a relay @Description Dials the relay (auto-detecting `ws://` vs `wss://`) and adds it to the logged-in user's managed relay list with the requested permissions. @Tags client-relays @Produce json @Param domain path string true "Relay domain (no scheme)" @Param read query bool false "Permission to subscribe from this relay (default true)" @Param write query bool false "Permission to publish to this relay (default true)" @Success 200 {object} map[string]interface{} @Failure 400 {object} map[string]interface{} "Missing domain or no permissions enabled" @Failure 401 {object} map[string]string "Login required" @Failure 405 {string} string "Method not allowed" @Failure 500 {object} map[string]interface{} "Connect failed" @Router /api/v1/client/connect/{domain} [post]
func ClientDisconnectHandler ¶ added in v0.4.12
func ClientDisconnectHandler(w http.ResponseWriter, r *http.Request)
ClientDisconnectHandler disconnects the client from a relay Usage: POST /api/v1/client/disconnect/relay.damus.io
@Summary Disconnect from a relay @Description Removes the relay from the logged-in user's managed list and closes the pooled WebSocket if one is open. @Tags client-relays @Produce json @Param domain path string true "Relay domain (no scheme)" @Success 200 {object} map[string]interface{} @Failure 400 {object} map[string]string "Missing domain" @Failure 401 {object} map[string]string "Login required" @Failure 404 {object} map[string]interface{} "Relay not in user's list" @Failure 405 {string} string "Method not allowed" @Failure 500 {object} map[string]interface{} "Disconnect failed" @Router /api/v1/client/disconnect/{domain} [post]
func ClientRelaysHandler ¶ added in v0.4.12
func ClientRelaysHandler(w http.ResponseWriter, r *http.Request)
ClientRelaysHandler returns the client's configured relays and their status Works with or without authentication - returns user relays if authenticated, app relays if not
@Summary List client relays @Description Returns the client's currently-configured relays with read/write permissions and live connection state. Falls back to the default index relays when no session is active. @Tags client-relays @Produce json @Param ping query string false "Set to `true` to measure latency for each relay" @Success 200 {object} ClientRelaysResponse @Failure 405 {string} string "Method not allowed" @Failure 500 {string} string "Failed to retrieve client relays" @Router /api/v1/client/relays [get]
func ClientStatusHandler ¶ added in v0.8.0
func ClientStatusHandler(w http.ResponseWriter, r *http.Request)
ClientStatusHandler returns the core client's relay-pool status — how many relays are tracked versus currently connected — for the dashboard's relay indicator.
@Summary Core client relay status @Description Relay pool counts (total, connected, pinned, leased) plus the index relay seed list. @Tags client @Produce json @Success 200 {object} map[string]interface{} @Failure 405 {string} string "Method not allowed" @Router /api/v1/client/status [get]
func DiscoverRelaysHandler ¶ added in v0.8.0
func DiscoverRelaysHandler(w http.ResponseWriter, r *http.Request)
DiscoverRelaysHandler triggers a NIP-66 discovery pass on demand — find monitors, pull their relay sets, refresh consensus — so the known-relays browser (Discovery tab) doesn't have to wait on the periodic roll. Session- gated. Blocks until the pass finishes (a few seconds) under its own timeout, then returns the resulting browsable / discovered counts.
@Summary Trigger NIP-66 relay discovery @Description Run a monitor-discovery + consensus refresh pass now; returns the new browsable/discovered counts. @Tags client @Produce json @Success 200 {object} map[string]int @Failure 401 {string} string "Authentication required" @Router /api/v1/client/discover [post]
func FixedRelaysHandler ¶ added in v0.8.0
func FixedRelaysHandler(w http.ResponseWriter, r *http.Request)
FixedRelaysHandler enables or disables the fixed-relay override — the advanced opt-out that bypasses the outbox model and uses a fixed read/write set (the "proxy" / aggregator override). Off by default and discouraged.
@Summary Set the fixed-relay override @Description Enable (with read/write sets) or disable the fixed-relay override that bypasses outbox routing. Session-gated. @Tags client @Accept json @Produce json @Success 200 {object} FixedRelaysResponse @Failure 401 {string} string "Authentication required" @Router /api/v1/client/fixed-relays [post]
func GetCacheHandler ¶ added in v0.4.1
func GetCacheHandler(w http.ResponseWriter, r *http.Request)
GetCacheHandler returns the cached user data as JSON (no session data) Automatically refreshes cache if expired or missing
@Summary Get cached user data @Description Returns the cached profile, mailboxes (kind 10002), and managed client relay list for the logged-in user. Rebuilds the cache on miss. @Tags client-cache @Produce json @Success 200 {object} map[string]interface{} @Failure 401 {string} string "User not logged in" @Failure 500 {string} string "Failed to load user data" @Router /api/v1/cache [get]
func GetSessionHandler ¶ added in v0.4.1
func GetSessionHandler(w http.ResponseWriter, r *http.Request)
GetSessionHandler returns the current user's session data as JSON (auth state only)
@Summary Get current session @Description Returns the logged-in user's pubkey, sign-in mode (read-only/write), and signing method. 401 if no active session. @Tags client-auth @Produce json @Success 200 {object} map[string]interface{} @Failure 401 {string} string "No active session found" @Router /api/v1/session [get]
func GetSuggestedMediaServersHandler ¶ added in v0.8.0
func GetSuggestedMediaServersHandler(w http.ResponseWriter, r *http.Request)
GetSuggestedMediaServersHandler returns grain's curated quick-add media-server suggestions (Blossom preferred, NIP-96 legacy fallback) for the settings page.
@Summary Get suggested media servers @Description grain's curated quick-add media-server suggestions, Blossom preferred with NIP-96 as a legacy fallback. @Tags client @Produce json @Success 200 {array} core.MediaServerInfo @Router /api/v1/media-servers/suggested [get]
func GetUserMediaServersHandler ¶ added in v0.8.0
func GetUserMediaServersHandler(w http.ResponseWriter, r *http.Request)
GetUserMediaServersHandler resolves a user's Blossom (kind 10063) and NIP-96 (kind 10096) media-server lists and annotates each entry with grain's static capability metadata. Defaults to the session user when no pubkey is given.
@Summary Get a user's media servers @Description Resolve a user's Blossom (kind 10063) and NIP-96 (kind 10096) media-server lists, annotated with grain's capability metadata. Defaults to the session user. @Tags client @Produce json @Param pubkey query string false "Hex pubkey (defaults to the session user)" @Success 200 {object} UserMediaServersResponse @Failure 401 {string} string "Authentication required or pubkey parameter needed" @Router /api/v1/user/media-servers [get]
func GetUserProfileHandler ¶ added in v0.4.1
func GetUserProfileHandler(w http.ResponseWriter, r *http.Request)
GetUserProfileHandler fetches user profile using core client
@Summary Get user profile @Description Fetches the kind-0 profile event for the given pubkey from outbox relays. Falls back to the logged-in user's pubkey if `pubkey` is omitted. @Tags client-events @Produce json @Param pubkey query string false "Hex pubkey (defaults to current session)" @Success 200 {object} map[string]interface{} @Failure 401 {string} string "Authentication required" @Failure 404 {string} string "Profile not found" @Failure 503 {string} string "No relay connections available" @Router /api/v1/user/profile [get]
func GetUserRelayListsHandler ¶ added in v0.8.0
func GetUserRelayListsHandler(w http.ResponseWriter, r *http.Request)
GetUserRelayListsHandler resolves a user's relay lists (NIP-65 10002, NIP-17 10050, NIP-51 10006/10007/10012) for the relay manager. Defaults to the session user when no pubkey is given.
@Summary Get a user's relay lists @Description Resolve a user's NIP-65 / NIP-17 / NIP-51 relay lists for the relay manager. Defaults to the session user. @Tags client @Produce json @Param pubkey query string false "Hex pubkey (defaults to the session user)" @Success 200 {object} UserRelayListsResponse @Failure 401 {string} string "Authentication required or pubkey parameter needed" @Router /api/v1/user/relay-lists [get]
func GetUserRelaysHandler ¶ added in v0.4.1
func GetUserRelaysHandler(w http.ResponseWriter, r *http.Request)
GetUserRelaysHandler fetches user relay list using core client
@Summary Get user relays @Description Fetches the kind-10002 relay list (mailboxes) for the given pubkey. Falls back to the logged-in user's pubkey if `pubkey` is omitted. @Tags client-events @Produce json @Param pubkey query string false "Hex pubkey (defaults to current session)" @Success 200 {object} map[string]interface{} @Failure 401 {string} string "Authentication required" @Failure 404 {string} string "Relays not found" @Failure 503 {string} string "No relay connections available" @Router /api/v1/user/relays [get]
func HandleAmberCallback ¶ added in v0.4.1
func HandleAmberCallback(w http.ResponseWriter, r *http.Request)
HandleAmberCallback is the redirect target for NIP-55 (Amber).
Mill's <nostr-signer> opens `nostrsigner://...?callbackUrl=...`; Amber bounces back with `?event=<pubkey-or-signed-event>&error=` on that URL. The page rendered here loads the bundled mill script so its boot-time hook (see nip55.js around line 17) captures the query params, stores them under `mill:amber:result` in localStorage, and notifies the opener window via postMessage. `MILL.deliverAmberCallback({autoClose:true})` finishes the handshake and closes the popup.
The server intentionally does NOT create the session here. The pubkey funnels back into mill in the opener window; the bridge (www/static/js/mill-bridge.js) is what POSTs /api/v1/auth/login with the resolved method and pubkey. Keeping session creation in one path (the bridge) means there's a single contract with the session manager regardless of signing method.
@Summary Amber NIP-55 callback @Description Landing page hit by the Amber signer app. Loads mill, which forwards the result to the opener window and closes the popup. Session creation lives in the front-end mill bridge, not here. @Tags client-auth @Param event query string false "Amber response: pubkey hex (get_public_key) or signed event JSON" @Param error query string false "Amber error message, if user rejected" @Produce html @Success 200 {string} string "HTML bridge page" @Router /api/v1/auth/amber-callback [get]
func KeyDeriveHandler ¶ added in v0.4.12
func KeyDeriveHandler(w http.ResponseWriter, r *http.Request)
KeyDeriveHandler derives public key from private key
@Summary Derive public key @Description Derives the pubkey (hex + npub) from a private key supplied in the URL path. Accepts either hex or nsec format. @Tags client-keys @Produce json @Param key path string true "Private key (hex or nsec)" @Success 200 {object} map[string]string @Failure 400 {object} map[string]string "Invalid key" @Failure 405 {string} string "Method not allowed" @Router /api/v1/keys/derive/{key} [get]
func KeyGenerationHandler ¶ added in v0.4.12
func KeyGenerationHandler(w http.ResponseWriter, r *http.Request)
KeyGenerationHandler generates a new random Nostr key pair
@Summary Generate keypair @Description Generates a fresh secp256k1 keypair and returns both the hex and bech32 (nsec/npub) forms. Pure utility — the relay does not store the private key. @Tags client-keys @Produce json @Success 200 {object} KeyGenerationResponse @Failure 405 {string} string "Method not allowed" @Failure 500 {object} KeyGenerationResponse "Key pair generation failed" @Router /api/v1/keys/generate [get]
func KeyValidationHandler ¶ added in v0.4.12
func KeyValidationHandler(w http.ResponseWriter, r *http.Request)
KeyValidationHandler validates any key type (hex, npub, or nsec)
@Summary Validate key @Description Reports whether the supplied string is a well-formed key, and what type (hex, npub, nsec). Does not distinguish public from private when given raw hex. @Tags client-keys @Produce json @Param key path string true "Key to validate" @Success 200 {object} KeyValidationResponse @Failure 400 {object} map[string]string "Key parameter required" @Failure 405 {string} string "Method not allowed" @Router /api/v1/keys/validate/{key} [get]
func KnownRelaysHandler ¶ added in v0.8.0
func KnownRelaysHandler(w http.ResponseWriter, r *http.Request)
KnownRelaysHandler lists every relay the client is aware of (the "known" set: config seeds + pooled + directory-resolved) with its live pool status, for the relay manager's known-relays browser. Per-relay NIP-11 detail is fetched lazily via /api/v1/relay-info. Session-gated.
@Summary List known relays @Description Every relay the client is aware of, with live pool status (connected/pinned/leased). @Tags client @Produce json @Success 200 {array} core.KnownRelayStatus @Failure 401 {string} string "Authentication required" @Router /api/v1/client/known-relays [get]
func LoginHandler ¶ added in v0.4.1
func LoginHandler(w http.ResponseWriter, r *http.Request)
LoginHandler handles user login requests via API Initializes user by fetching mailboxes, setting app relays, getting metadata from outboxes, caching the data, and creating session with appropriate signing capabilities
@Summary Log in @Description Creates a session for the given pubkey. Fetches mailboxes and metadata from outbox relays as a side effect. Set `requestedMode=write` and provide a signing method to enable event publishing. @Tags client-auth @Accept json @Produce json @Param body body session.SessionInitRequest true "Login parameters" @Success 200 {object} session.Response @Failure 400 {object} session.Response "Invalid request" @Failure 405 {string} string "Method not allowed" @Failure 500 {object} session.Response "Failed to create session" @Router /api/v1/auth/login [post]
func LogoutHandler ¶ added in v0.4.1
func LogoutHandler(w http.ResponseWriter, r *http.Request)
LogoutHandler handles user logout requests via API
@Summary Log out @Description Clears the active session cookie. Idempotent — succeeds even if no session was active. @Tags client-auth @Produce json @Success 200 {object} map[string]interface{} @Failure 405 {string} string "Method not allowed" @Router /api/v1/auth/logout [post]
func Nip19DecodeHandler ¶ added in v0.5.0
func Nip19DecodeHandler(w http.ResponseWriter, r *http.Request)
Nip19DecodeHandler decodes NIP-19 bech32 entities (npub, note, nprofile, nevent, naddr) Accepts both GET (URL path) and POST (JSON body) requests to handle long entities
@Summary Decode NIP-19 entity @Description Decodes any NIP-19 bech32 entity (npub, nsec, note, nprofile, nevent, naddr). POST accepts entities too long for a URL path. @Tags client-keys @Accept json @Produce json @Param entity path string false "NIP-19 entity (GET path form)" @Param body body Nip19DecodeRequest false "NIP-19 entity (POST body form)" @Success 200 {object} map[string]interface{} @Failure 400 {object} map[string]string "Invalid entity" @Failure 405 {string} string "Method not allowed" @Router /api/v1/keys/decode/nip19/{entity} [get]
func PingHandler ¶ added in v0.4.12
func PingHandler(w http.ResponseWriter, r *http.Request)
PingHandler pings any relay and returns response time and connection status Now supports domain-in-path with auto ws/wss detection Usage: GET /api/v1/ping/relay.damus.io
@Summary Ping a relay @Description Opens a WebSocket to the given relay and reports the dial latency. Tries `wss://` first, falls back to `ws://`. @Tags client-relays @Produce json @Param domain path string true "Relay domain (no scheme)" @Success 200 {object} map[string]interface{} @Failure 400 {object} map[string]string "Missing domain" @Failure 405 {string} string "Method not allowed" @Router /api/v1/ping/{domain} [get]
func PingRelaysHandler ¶ added in v0.8.0
func PingRelaysHandler(w http.ResponseWriter, r *http.Request)
PingRelaysHandler measures TCP-connect latency for a set of relays, for the known-relays browser's "fastest first" sort. The browser sends only the rows currently in view (capped here too), so this never probes the whole known set. Session-gated. Results are short-TTL-cached server-side.
@Summary Ping relays @Description TCP-connect latency (ms, -1 = unreachable) for a set of relays. Capped at 80 URLs per call. @Tags client @Accept json @Produce json @Param body body object{urls=[]string} true "Relay URLs to ping" @Success 200 {object} map[string]int @Failure 401 {string} string "Authentication required" @Router /api/v1/relays/ping [post]
func PrivateKeyConversionHandler ¶ added in v0.4.12
func PrivateKeyConversionHandler(w http.ResponseWriter, r *http.Request)
PrivateKeyConversionHandler converts between hex and nsec formats
@Summary Convert private key @Description Converts the supplied private key between hex and nsec. Detects direction from the prefix. @Tags client-keys @Produce json @Param key path string true "Private key (hex or nsec)" @Success 200 {object} map[string]string @Failure 400 {object} map[string]string "Invalid key" @Failure 405 {string} string "Method not allowed" @Router /api/v1/keys/convert/private/{key} [get]
func PublicKeyConversionHandler ¶ added in v0.4.12
func PublicKeyConversionHandler(w http.ResponseWriter, r *http.Request)
PublicKeyConversionHandler converts between hex and npub formats
@Summary Convert public key @Description Converts the supplied public key between hex and npub. Detects direction from the prefix. @Tags client-keys @Produce json @Param key path string true "Public key (hex or npub)" @Success 200 {object} map[string]string @Failure 400 {object} map[string]string "Invalid key" @Failure 405 {string} string "Method not allowed" @Router /api/v1/keys/convert/public/{key} [get]
func PublishEventHandler ¶ added in v0.4.1
func PublishEventHandler(w http.ResponseWriter, r *http.Request)
PublishEventHandler handles event publishing requests
@Summary Publish event @Description Builds, signs (server-side using the supplied private key), and broadcasts a Nostr event to the user's outbox relays plus any extras specified in `relays`. @Tags client-events @Accept json @Produce json @Param body body PublishEventRequest true "Event to publish" @Success 200 {object} PublishEventResponse @Failure 400 {string} string "Invalid request body" @Failure 401 {string} string "Authentication required" @Failure 405 {string} string "Method not allowed" @Failure 500 {object} PublishEventResponse "Publish failed" @Router /api/v1/publish [post]
func PublishSignedHandler ¶ added in v0.8.0
func PublishSignedHandler(w http.ResponseWriter, r *http.Request)
PublishSignedHandler broadcasts a client-signed event via the outbox model. Unlike /api/v1/publish (which signs server-side from a private key), this accepts an already-signed event — the dashboard signs with the user's NIP-07 / NIP-46 / Amber signer in the browser.
@Summary Publish a pre-signed event @Description Verify a client-signed event belongs to the session user, then broadcast it to the outbox-routed relays. @Tags client-events @Accept json @Produce json @Success 200 {object} PublishSignedResponse @Failure 400 {object} PublishSignedResponse @Failure 401 {string} string "Authentication required" @Failure 403 {object} PublishSignedResponse @Router /api/v1/events/publish [post]
func PublishSignedStreamHandler ¶ added in v0.8.0
func PublishSignedStreamHandler(w http.ResponseWriter, r *http.Request)
PublishSignedStreamHandler is the streaming counterpart of PublishSignedHandler: it broadcasts a client-signed event and streams each relay's result as NDJSON (one JSON object per line) the moment it resolves, so the browser can show a live, count-up broadcast toast.
@Summary Publish a pre-signed event (streaming) @Description Verify a client-signed event belongs to the session user, broadcast it via the outbox model, and stream per-relay results as newline-delimited JSON. @Tags client-events @Accept json @Produce application/x-ndjson @Success 200 {string} string "NDJSON stream of start/result/done lines" @Failure 401 {string} string "Authentication required" @Failure 403 {string} string "Pubkey mismatch" @Router /api/v1/events/publish/stream [post]
func QueryEventsHandler ¶ added in v0.4.1
func QueryEventsHandler(w http.ResponseWriter, r *http.Request)
QueryEventsHandler handles event querying using core client
@Summary Query events @Description Issues a Nostr REQ to the connected relays with the filter built from query params. Returns deduplicated, time-sorted events. Caps results at 500 by default. @Tags client-events @Produce json @Param authors query []string false "Pubkey filter (repeatable)" collectionFormat(multi) @Param kinds query []int false "Kind filter (repeatable)" collectionFormat(multi) @Param ids query []string false "Event id filter (repeatable)" collectionFormat(multi) @Param since query int false "created_at lower bound (Unix seconds)" @Param until query int false "created_at upper bound (Unix seconds)" @Param limit query int false "Max events to return" @Success 200 {object} map[string]interface{} @Failure 400 {string} string "Invalid query parameters" @Failure 404 {string} string "Event not found (only when querying a single id)" @Failure 503 {string} string "No relay connections available" @Router /api/v1/events/query [get]
func RefreshCacheHandler ¶ added in v0.4.1
func RefreshCacheHandler(w http.ResponseWriter, r *http.Request)
RefreshCacheHandler manually refreshes cache for the current user
@Summary Force cache refresh @Description Clears and rebuilds the cached user data from outbox relays. Useful after profile updates. @Tags client-cache @Produce json @Success 200 {object} map[string]interface{} @Failure 401 {string} string "User not logged in" @Failure 405 {string} string "Method not allowed" @Failure 500 {string} string "Failed to refresh cache" @Router /api/v1/cache/refresh [post]
func RelayInfoHandler ¶ added in v0.8.0
func RelayInfoHandler(w http.ResponseWriter, r *http.Request)
RelayInfoHandler returns a relay's NIP-11 document (TTL-cached) for the known-relays browser's per-relay detail. Query: ?url=<relay url>. Returns an empty object when the relay advertises no NIP-11. Session-gated.
@Summary Get a relay's NIP-11 info @Description A relay's NIP-11 document (name, software, supported NIPs, auth/payment flags), cached. @Tags client @Produce json @Param url query string true "Relay URL" @Success 200 {object} core.RelayInfo @Failure 401 {string} string "Authentication required" @Router /api/v1/relay-info [get]
func RemoveAuthHandler ¶ added in v0.8.0
func RemoveAuthHandler(w http.ResponseWriter, r *http.Request)
RemoveAuthHandler ends the logged-in user's NIP-42 session with a relay by closing their own connection to it. Session-gated.
@Summary Revoke a relay's AUTH for this user @Tags client @Accept json @Produce json @Param body body object{relay=string} true "Relay URL" @Success 200 {object} map[string]any @Failure 401 {string} string "Authentication required" @Router /api/v1/client/auth/remove [post]
func ResolveEventHandler ¶ added in v0.8.0
func ResolveEventHandler(w http.ResponseWriter, r *http.Request)
ResolveEventHandler resolves a SINGLE event by id, escalating across relay sets until it turns up: the local relay (grain itself) → the author's outbox relays → explicit relay hints → the wider discovered set. It returns as soon as the event is found, or 404 after every tier misses.
Why this exists separately from QueryEventsHandler: that handler fans out to the connected *index* pool with no relay hints — right for metadata and relay lists, wrong for arbitrary notes. The note you click in the live feed lives on grain's OWN relay, which isn't in the connected pool, so tier 1 queries it directly; and when it isn't local, the author's pubkey lets us route to their outbox (the outbox model) instead of guessing.
Query: GET /api/v1/events/{id}?author=<hex>&relays=<comma-separated urls>
@Summary Resolve a single event by id (outbox-aware) @Description Escalating lookup: local relay → author outbox → relay hints → discovered set; returns on first hit. @Tags client @Produce json @Param id path string true "Event ID (hex)" @Param author query string false "Author pubkey (hex) — enables outbox routing" @Param relays query string false "Comma-separated relay hints to try" @Success 200 {object} map[string]nostr.Event @Failure 404 {object} map[string]string "Event not found" @Router /api/v1/events/{id} [get]
func StreamHandler ¶ added in v0.8.0
func StreamHandler(w http.ResponseWriter, r *http.Request)
StreamHandler is the per-session SSE channel grain pushes live updates to (the login-hydration live-sync #87 and the streaming fetch path #77). The browser connects once via EventSource; grain streams JSON messages — one per `data:` line — until the client disconnects. A heartbeat comment keeps the connection (and any intermediary) alive.
@Summary Live update stream (SSE) @Description Per-session Server-Sent Events channel for live updates. Connect with EventSource. @Tags client @Produce text/event-stream @Success 200 {string} string "SSE stream" @Failure 401 {string} string "Authentication required" @Router /api/v1/stream [get]
func SubmitAuthHandler ¶ added in v0.8.0
func SubmitAuthHandler(w http.ResponseWriter, r *http.Request)
SubmitAuthHandler answers a relay's NIP-42 challenge for the logged-in user with a browser-signed kind-22242 event. The event must be signed by the session's pubkey and answer the challenge from AuthChallengeHandler; it is sent on the user's own connection. Session-gated.
@Summary Answer a NIP-42 AUTH challenge @Description Send a browser-signed kind-22242 auth event on this user's connection. @Tags client @Accept json @Produce json @Param body body object{relay=string,event=object} true "Relay URL + signed kind-22242 event" @Success 200 {object} map[string]any @Failure 400 {string} string "Invalid request" @Failure 401 {string} string "Authentication required" @Router /api/v1/client/auth [post]
Types ¶
type AppRelaysPayload ¶ added in v0.8.0
type AppRelaysPayload struct {
Indexer []string `json:"indexer"`
Broadcast []string `json:"broadcast"`
Local []string `json:"local"`
Trusted []string `json:"trusted"`
}
AppRelaysPayload is the session's locally-configured ("app") relay roles — editable preferences seeded from the operator's config, not published Nostr lists. Indexer drives discovery; Broadcast mirrors writes; Local/Trusted are stored but inert until their wiring lands (Local routing; Trusted NIP-42 AUTH).
type ClientRelaysResponse ¶ added in v0.4.12
type ClientRelaysResponse struct {
Relays []RelayStatus `json:"relays"`
Count int `json:"count"`
}
ClientRelaysResponse represents the response for client relays
type FixedRelaysRequest ¶ added in v0.8.0
type FixedRelaysRequest struct {
Enabled bool `json:"enabled"`
Read []string `json:"read"`
Write []string `json:"write"`
}
FixedRelaysRequest sets or clears the fixed-relay override.
type FixedRelaysResponse ¶ added in v0.8.0
type FixedRelaysResponse struct {
Enabled bool `json:"enabled"`
}
FixedRelaysResponse reports the override state after the change.
type KeyGenerationResponse ¶ added in v0.4.12
type KeyGenerationResponse struct {
PrivateKey string `json:"private_key,omitempty"` // hex format
PublicKey string `json:"public_key,omitempty"` // hex format
Nsec string `json:"nsec,omitempty"` // bech32 format
Npub string `json:"npub,omitempty"` // bech32 format
Error string `json:"error,omitempty"`
}
KeyGenerationResponse represents the response structure for key generation
type KeyValidationResponse ¶ added in v0.4.12
type KeyValidationResponse struct {
Valid bool `json:"valid"`
Type string `json:"type"`
Error string `json:"error,omitempty"`
}
KeyValidationResponse represents the response structure for key validation
type MediaServerEntry ¶ added in v0.8.0
type MediaServerEntry struct {
URL string `json:"url"`
Kind string `json:"kind"` // "blossom" | "nip96"
Primary bool `json:"primary"` // first in its list (the upload default)
Name string `json:"name,omitempty"` // display name, when known
Cost string `json:"cost,omitempty"` // "free" | "paid" | "" (unknown)
Retention string `json:"retention,omitempty"` // "permanent" | "ephemeral" | "" (unknown)
Mirror bool `json:"mirror"` // accepts BUD-04 /mirror
Note string `json:"note,omitempty"`
CTA string `json:"cta,omitempty"`
Known bool `json:"known"` // grain has capability metadata for this URL
}
MediaServerEntry is a resolved media server annotated with grain's static capability metadata (when the server is one grain knows).
type MediaServersBuildRequest ¶ added in v0.8.0
type MediaServersBuildRequest struct {
Kind int `json:"kind"` // 10063 (Blossom) or 10096 (NIP-96)
Servers []string `json:"servers"` // ordered base URLs, primary first
ClientTag *bool `json:"client_tag,omitempty"` // nil = config default; else per-user override (#99)
}
MediaServersBuildRequest carries the desired ordered server list for one media-server list kind.
type Nip19DecodeRequest ¶ added in v0.5.0
type Nip19DecodeRequest struct {
Entity string `json:"entity"`
}
Nip19DecodeRequest represents the request body for NIP-19 decoding
type ProfileBuildRequest ¶ added in v0.8.0
type ProfileBuildRequest struct {
Event *nostr.Event `json:"event"` // existing kind-0 (may be null for a first profile)
Edits map[string]string `json:"edits"`
ClientTag *bool `json:"client_tag,omitempty"` // nil = config default; else per-user override (#99)
}
ProfileBuildRequest carries the user's existing kind-0 event and the field edits to apply.
type PublishEventRequest ¶ added in v0.4.1
type PublishEventRequest struct {
Kind int `json:"kind"`
Content string `json:"content"`
Tags [][]string `json:"tags,omitempty"`
PrivateKey string `json:"privateKey,omitempty"`
Relays []string `json:"relays,omitempty"`
}
PublishEventRequest represents the request structure for publishing events
type PublishEventResponse ¶ added in v0.4.1
type PublishEventResponse struct {
Success bool `json:"success"`
EventID string `json:"eventId,omitempty"`
Event *nostr.Event `json:"event,omitempty"`
Results []core.BroadcastResult `json:"results"`
Summary core.BroadcastSummary `json:"summary"`
Error string `json:"error,omitempty"`
}
PublishEventResponse represents the response structure for publishing events
type PublishSignedRequest ¶ added in v0.8.0
PublishSignedRequest carries a fully-signed event to broadcast.
type PublishSignedResponse ¶ added in v0.8.0
type PublishSignedResponse struct {
Success bool `json:"success"`
EventID string `json:"eventId,omitempty"`
Relays []string `json:"relays"`
Results []core.BroadcastResult `json:"results"`
Error string `json:"error,omitempty"`
}
PublishSignedResponse reports where a signed event was published.
type RelayListBuildRequest ¶ added in v0.8.0
type RelayListBuildRequest struct {
Kind int `json:"kind"` // 10002 | 10050 | 10006 | 10007 | 10012
Entries []core.RelayListEntry `json:"entries"` // ordered; Read/Write apply to 10002 only
ClientTag *bool `json:"client_tag,omitempty"` // nil = config default; else per-user override (#99)
}
RelayListBuildRequest carries the desired relay list for one kind.
type RelayStatus ¶ added in v0.4.12
type RelayStatus struct {
URL string `json:"url"`
Connected bool `json:"connected"`
Status string `json:"status"`
Latency *int64 `json:"latency,omitempty"` // Ping latency in milliseconds
LastChecked time.Time `json:"last_checked"`
Read bool `json:"read"`
Write bool `json:"write"`
AddedAt time.Time `json:"added_at"`
}
RelayStatus represents the status of a relay connection
type UserMediaServersResponse ¶ added in v0.8.0
type UserMediaServersResponse struct {
Pubkey string `json:"pubkey"`
HasAny bool `json:"hasAny"`
Blossom []MediaServerEntry `json:"blossom"`
NIP96 []MediaServerEntry `json:"nip96"`
}
UserMediaServersResponse is a user's resolved Blossom + NIP-96 media-server lists. HasAny drives the "set up media servers" prompt on upload.
type UserRelayListsResponse ¶ added in v0.8.0
type UserRelayListsResponse struct {
Pubkey string `json:"pubkey"`
NIP65 []core.RelayListEntry `json:"nip65"` // 10002, with read/write flags
DM []string `json:"dm"` // 10050
Blocked []string `json:"blocked"` // 10006
Search []string `json:"search"` // 10007
Favorites []string `json:"favorites"` // 10012
Private []string `json:"private"` // 10013 (NIP-37) — usually empty; entries are encrypted
Encrypted core.EncryptedFlags `json:"encrypted"` // NIP-51/37 lists with private (encrypted) entries
// EncryptedContent is the raw encrypted blob per list so the browser can
// decrypt it with the user's signer on demand (#100). grain never decrypts.
EncryptedContent core.EncryptedContent `json:"encrypted_content"`
}
UserRelayListsResponse is a user's resolved relay lists across the kinds the relay manager edits.
Source Files
¶
- amber.go
- appRelays.go
- cache.go
- clientConnect.go
- clientDisconnect.go
- clientRelays.go
- clientStatus.go
- clienttag.go
- events.go
- keysConvert.go
- keysDerive.go
- keysGenerate.go
- keysValidate.go
- knownRelays.go
- login.go
- logout.go
- mediaServers.go
- nip19Decode.go
- nip42.go
- pingRelays.go
- profile.go
- relayList.go
- relayPing.go
- resolveEvent.go
- session.go
- sessionUser.go
- stream.go