Documentation
¶
Index ¶
- func AppRelaysHandler(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 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 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 ¶
func AppRelaysHandler(w http.ResponseWriter, r *http.Request)
AppRelaysHandler gets (GET) or replaces (POST) the session's app-relay preferences. POST sets all four roles from the payload; an empty list clears that role (Indexer then falls back to the configured default). Session-gated.
@Summary Get or set app-relay preferences @Description The session'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 AuthRequestsHandler ¶
func AuthRequestsHandler(w http.ResponseWriter, r *http.Request)
AuthRequestsHandler lists the relays that have issued a NIP-42 AUTH challenge this session, each with whether we've already authed. Session-gated.
@Summary List NIP-42 AUTH requests @Description Relays that have challenged the client for AUTH, with session 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 ¶
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 ¶
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 ¶
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 ¶
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 FixedRelaysHandler ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
func RemoveAuthHandler(w http.ResponseWriter, r *http.Request)
RemoveAuthHandler forgets a relay's session AUTH state (revoke trust). Session-gated.
@Summary Revoke a relay's session AUTH @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 StreamHandler ¶
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 ¶
func SubmitAuthHandler(w http.ResponseWriter, r *http.Request)
SubmitAuthHandler relays a browser-signed kind-22242 event to a relay, answering its NIP-42 challenge. The browser builds + signs the event (it holds the key); grain only forwards it on the challenged connection. Session-gated.
@Summary Answer a NIP-42 AUTH challenge @Description Relay a browser-signed kind-22242 auth event to a relay. @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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
PublishSignedRequest carries a fully-signed event to broadcast.
type PublishSignedResponse ¶
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 ¶
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 ¶
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 ¶
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
- session.go
- stream.go