Parrhesia.API.Events
(parrhesia v0.14.0)
Copy Markdown
Canonical event publish, query, and count API.
This is the main in-process API for working with Nostr events. It applies the same core validation and policy checks used by the relay edge, but without going through a socket or HTTP transport.
All public functions expect opts[:context] to contain a Parrhesia.API.RequestContext.
That context drives authorization, caller attribution, and downstream policy behavior.
publish/2 intentionally returns {:ok, %PublishResult{accepted: false}} for policy and
storage rejections so callers can mirror relay OK semantics without treating a rejected
event as a process error.
Summary
Functions
Counts events matching the given filters.
Paginates stored events for a single filter using keyset cursors.
Validates, authorizes, persists, and fans out an event.
Batch variant of publish/2 for trusted sync paths that have already received a page of
remote events in one transport frame.
Queries stored events plus any dynamic NIP-43 events visible to the caller.
Functions
@spec count( [map()], keyword() ) :: {:ok, non_neg_integer() | map()} | {:error, term()}
Counts events matching the given filters.
Required options:
:context- aParrhesia.API.RequestContext
Supported options:
:validate_filters?- skips filter validation whenfalse:authorize_read?- skips read policy checks whenfalse:options- when set to a map, returns a NIP-45-style payload instead of a bare integer
When opts[:options] is a map, the result shape is %{"count" => count, "approximate" => false}.
If opts[:options]["hll"] is true and the feature is enabled, an "hll" field is included.
Paginates stored events for a single filter using keyset cursors.
Unlike query/2, this bypasses NIP-01 newest-first ordering and any dynamic NIP-43
expansion; it returns the persisted-event slice that strictly satisfies the keyset
bounds in the requested order. Intended for the Parrhesia SYNC-PAGE wire frame.
Required options:
:context- aParrhesia.API.RequestContext
Supported options:
:order-:asc(default) or:desc:limit- max events returned (caller is responsible for capping):after_key,:until_key-{created_at, event_id_hex}keyset bounds:validate_filters?,:authorize_read?- same semantics asquery/2
@spec publish( map(), keyword() ) :: {:ok, Parrhesia.API.Events.PublishResult.t()} | {:error, term()}
Validates, authorizes, persists, and fans out an event.
Required options:
:context- aParrhesia.API.RequestContext
Supported options:
:max_event_bytes- overrides the configured max encoded event size:role,:path,:private_key,:configured_private_key- forwarded to the NIP-43 helper flow
Return semantics:
{:ok, %PublishResult{accepted: true}}for accepted events{:ok, %PublishResult{accepted: false}}for rejected or duplicate events{:error, :invalid_context}only when the call itself is malformed
@spec publish_many( [map()], keyword() ) :: {:ok, [Parrhesia.API.Events.PublishResult.t()]} | {:error, term()}
Batch variant of publish/2 for trusted sync paths that have already received a page of
remote events in one transport frame.
Untrusted callers still run full event validation. Trusted sync callers skip duplicate
signature/hash/future-timestamp validation because the source Parrhesia node already
validated before storage. Regular persisted events are inserted with a storage-level batch
operation and dispatched as a batch. Control and ephemeral events fall back to publish/2
because their side effects are not bulk-safe.
Queries stored events plus any dynamic NIP-43 events visible to the caller.
Required options:
:context- aParrhesia.API.RequestContext
Supported options:
:max_filter_limit- overrides the configured per-filter limit:validate_filters?- skips filter validation whenfalse:authorize_read?- skips read policy checks whenfalse
The skip flags are primarily for internal composition, such as Parrhesia.API.Stream.
External callers should normally leave them enabled.