The Nostr protocol: its events, its names and its relays. Nothing here is about podcasts.
An event is the JSON object of NIP-01 as plain data with string keys, as a relay gives it. Show no event whose id and signature aren't verified, since a relay can send anything.
The Nostr protocol: its events, its names and its relays. Nothing here is about podcasts. An event is the JSON object of NIP-01 as plain data with string keys, as a relay gives it. Show no event whose id and signature aren't verified, since a relay can send anything.
(close-message id)The message that ends the subscription id: the CLOSE of NIP-01.
The message that ends the subscription `id`: the CLOSE of NIP-01.
(decode s)What the name s names, as a map with its :type, or nil for another
text and for the name of a secret key. The name is one of NIP-19, e.g.
npub1…, or a nostr: URI of NIP-21 with such a name.
{:type :npub :public-key "3bf0…"}
{:type :note :id "5c83…"}
{:type :nprofile :public-key "3bf0…" :relays ["wss://r.x.com"]}
{:type :nevent :id "5c83…" :relays […] :author "3bf0…" :kind 1}
{:type :naddr :identifier "…" :relays […] :author "3bf0…" :kind 30023}
The ids and the keys are in hexadecimal, as the events have them. A field that NIP-19 doesn't define is left out, as NIP-19 asks.
What the name `s` names, as a map with its :type, or nil for another
text and for the name of a secret key. The name is one of NIP-19, e.g.
npub1…, or a nostr: URI of NIP-21 with such a name.
{:type :npub :public-key "3bf0…"}
{:type :note :id "5c83…"}
{:type :nprofile :public-key "3bf0…" :relays ["wss://r.x.com"]}
{:type :nevent :id "5c83…" :relays […] :author "3bf0…" :kind 1}
{:type :naddr :identifier "…" :relays […] :author "3bf0…" :kind 30023}
The ids and the keys are in hexadecimal, as the events have them. A
field that NIP-19 doesn't define is left out, as NIP-19 asks.The limits of an exchange with a relay that its request doesn't set. One answer has at most :max-events events, and the relay sends at most :max-bytes characters.
The limits of an exchange with a relay that its request doesn't set. One answer has at most :max-events events, and the relay sends at most :max-bytes characters.
(encode {:keys [type id public-key identifier author kind relays] :as x})The name of NIP-19 for x, a map of the form that decode gives, or nil
when x names nothing of its type.
A relay with more than 255 bytes in its URL is left out.
The name of NIP-19 for `x`, a map of the form that decode gives, or nil when `x` names nothing of its type. A relay with more than 255 bytes in its URL is left out.
(event-id event)The id that NIP-01 gives event: the SHA-256 of its fields, in
hexadecimal.
The id that NIP-01 gives `event`: the SHA-256 of its fields, in hexadecimal.
(event-message event)The message that gives a relay the event: the EVENT of NIP-01, as
JSON.
The message that gives a relay the `event`: the EVENT of NIP-01, as JSON.
(event? x)Whether x has the form of an event of NIP-01, with each of its
fields of the right type.
Whether `x` has the form of an event of NIP-01, with each of its fields of the right type.
(matches? filter event)Whether event passes the filter of NIP-01, a map with keys such as
"ids", "kinds" and "#e".
A key that NIP-01 doesn't define lets every event pass, and so does "limit", which counts events.
Whether `event` passes the `filter` of NIP-01, a map with keys such as "ids", "kinds" and "#e". A key that NIP-01 doesn't define lets every event pass, and so does "limit", which counts events.
(parts event)The parts of the content of event, in their order. The content of a
note is plain text, and some of its words name other things. Each part
is a map with its :type:
{:type :text :text "Is this "}
{:type :mention :public-key "5f7a…" :uri "nostr:npub1…"}
{:type :reference
:target {:type :nevent :id "…" :kind 1}
:uri "nostr:nevent1…"}
{:type :link :url "https://example.org/"}
{:type :hashtag :tag "podcast"}
A mention is a nostr: URI with the name of a profile, and a reference is one with the name of an event, as NIP-27 defines. The :target of a reference is the decoded name. A hashtag is a word after a number sign that the event names in a t tag, as NIP-24 defines. A mention of a profile can have :relays.
The parts of the content of `event`, in their order. The content of a
note is plain text, and some of its words name other things. Each part
is a map with its :type:
{:type :text :text "Is this "}
{:type :mention :public-key "5f7a…" :uri "nostr:npub1…"}
{:type :reference
:target {:type :nevent :id "…" :kind 1}
:uri "nostr:nevent1…"}
{:type :link :url "https://example.org/"}
{:type :hashtag :tag "podcast"}
A mention is a nostr: URI with the name of a profile, and a reference is
one with the name of an event, as NIP-27 defines. The :target of a
reference is the decoded name. A hashtag is a word after a number sign
that the event names in a t tag, as NIP-24 defines. A mention of a
profile can have :relays.(public? url)Whether the host of the relay at url is on the public internet.
Whether the host of the relay at `url` is on the public internet.
(read-message text)The message text of a relay, as a map with its :type, or nil when it
isn't a message of a relay.
{:type :event :subscription "…" :event {…}}
{:type :eose :subscription "…"} ; the relay has no more
{:type :closed :subscription "…" :message "…"}
{:type :notice :message "…"}
{:type :ok :id "…" :accepted? true :message "…"}
{:type :auth :challenge "…"} ; NIP-42
NIP-01 defines the first five, in its section From relay to client.
The message `text` of a relay, as a map with its :type, or nil when it
isn't a message of a relay.
{:type :event :subscription "…" :event {…}}
{:type :eose :subscription "…"} ; the relay has no more
{:type :closed :subscription "…" :message "…"}
{:type :notice :message "…"}
{:type :ok :id "…" :accepted? true :message "…"}
{:type :auth :challenge "…"} ; NIP-42
NIP-01 defines the first five, in its section From relay to client.(received answer text {:keys [max-events max-bytes until published] :as limits})The answer of a relay with the message text read into it, within
the limits. An exchange starts with an empty map.
{:events [{…}] :notices ["…"] :complete? true :done? true}
The answer is :done? when the exchange ends. It ends in these cases:
The answer has :auth? when the relay asks who the reader is, as NIP-42 defines.
An exchange that gives the relay an event has the id of the event as
:published in limits, and :until says when it ends:
In both cases, it ends when the relay refuses the event, and :refused is the reason of the relay. If you hold your own connection, give the relay the event when the answer is :complete?, since the relay has the subscription then.
The events are only those of the subscription of the exchange, as the relay gives them, and they aren't verified.
The `answer` of a relay with the message `text` read into it, within
the `limits`. An exchange starts with an empty map.
{:events [{…}] :notices ["…"] :complete? true :done? true}
The answer is :done? when the exchange ends. It ends in these cases:
- The relay has no more events, and the answer is :complete?.
- The relay closes the subscription, and :closed is its reason.
- A limit is reached, and :truncated names it.
The answer has :auth? when the relay asks who the reader is, as NIP-42
defines.
An exchange that gives the relay an event has the id of the event as
:published in `limits`, and :until says when it ends:
- With :until :ok, it ends when the relay takes the event, and the
answer is :accepted?.
- With :until :event, it ends at the first event that comes, and not
when the relay has no more events.
In both cases, it ends when the relay refuses the event, and :refused
is the reason of the relay. If you hold your own connection, give the
relay the event when the answer is :complete?, since the relay has the
subscription then.
The events are only those of the subscription of the exchange, as the
relay gives them, and they aren't verified.(relay-url s)The URL s of a relay in a normal form, or nil when it isn't a ws or
wss URL with a host. The form is trimmed, with the scheme and the host
in lower case, and without a slash at the end.
The URL `s` of a relay in a normal form, or nil when it isn't a ws or wss URL with a host. The form is trimmed, with the scheme and the host in lower case, and without a slash at the end.
(request-message id filters)The message that asks a relay for the events of filters, under the
subscription id: the REQ of NIP-01, as JSON.
The message that asks a relay for the events of `filters`, under the subscription `id`: the REQ of NIP-01, as JSON.
(send! {:keys [url filters event allow-pred]
:or {allow-pred (constantly true)}
:as request})Ask the relay of the request for the events of its filters, and give
what it answers. On the JVM it gives the response, and in ClojureScript
a promise of it.
{:url "wss://relay.example"
:filters [{"kinds" [1111] "#I" ["podcast:item:guid:…"]
"limit" 100}]}
The exchange is one subscription. It opens a WebSocket, sends the REQ of NIP-01, reads until the relay sends EOSE, and closes. The response has the :url and the :events, with the other keys of received. A relay that doesn't answer in time gives the events that came, with :timeout? true.
The request has these keys:
It throws ::refused for a URL that :allow-pred refuses or that isn't the URL of a relay, and ::failed when the relay gives no connection.
With an :event, the request gives the relay that event as the EVENT of NIP-01. The filters are then for the answer to the event, and the exchange ends at the first event of the filters that comes. The event goes out when the relay has the subscription, which the relay tells with EOSE, so the event doesn't go to a relay that refuses the subscription. Without filters, the event goes out at once, and the exchange ends when the relay takes it.
The response has :sent? true when the event went out. It has :accepted? true when the relay took the event, and :refused with the reason of the relay when it didn't. An exception of ::failed has :sent? true in its data when the event went out before the failure. Without :sent?, the event never went out.
The events aren't verified, and they needn't pass the filters.
Ask the relay of the `request` for the events of its filters, and give
what it answers. On the JVM it gives the response, and in ClojureScript
a promise of it.
{:url "wss://relay.example"
:filters [{"kinds" [1111] "#I" ["podcast:item:guid:…"]
"limit" 100}]}
The exchange is one subscription. It opens a WebSocket, sends the REQ
of NIP-01, reads until the relay sends EOSE, and closes. The response
has the :url and the :events, with the other keys of received. A relay
that doesn't answer in time gives the events that came, with :timeout?
true.
The `request` has these keys:
- :url, the URL of the relay
- :filters, the filters of NIP-01
- :event, a signed event to give the relay
- :timeout-seconds, :max-events and :max-bytes, which default to those
of default-limits
- :allow-pred, a predicate of the URL of the relay, as public? is
- :user-agent, the User-Agent on the JVM, client/user-agent by default
It throws ::refused for a URL that :allow-pred refuses or that isn't the URL
of a relay, and ::failed when the relay gives no connection.
With an :event, the request gives the relay that event as the EVENT of
NIP-01. The filters are then for the answer to the event, and the
exchange ends at the first event of the filters that comes. The event
goes out when the relay has the subscription, which the relay tells
with EOSE, so the event doesn't go to a relay that refuses the
subscription. Without filters, the event goes out at once, and the
exchange ends when the relay takes it.
The response has :sent? true when the event went out. It has :accepted?
true when the relay took the event, and :refused with the reason of the
relay when it didn't. An exception of ::failed has :sent? true in its
data when the event went out before the failure. Without :sent?, the
event never went out.
The events aren't verified, and they needn't pass the filters.(signed event secret-key aux)The event signed with secret-key and aux: with the public key of
the owner, the id of NIP-01 and the signature of BIP-340. Nil when
secret-key isn't a secret key.
(signed {"kind" 1 "created_at" 1790000000
"tags" [] "content" "Hi"}
secret-key
aux)
The event has its kind and its time, in seconds. Its tags and its
content are empty when it has none. The aux is 32 random bytes in
hexadecimal that nobody can guess, new for each signature.
How long it takes depends on the secret key.
The `event` signed with `secret-key` and `aux`: with the public key of
the owner, the id of NIP-01 and the signature of BIP-340. Nil when
`secret-key` isn't a secret key.
(signed {"kind" 1 "created_at" 1790000000
"tags" [] "content" "Hi"}
secret-key
aux)
The `event` has its kind and its time, in seconds. Its tags and its
content are empty when it has none. The `aux` is 32 random bytes in
hexadecimal that nobody can guess, new for each signature.
How long it takes depends on the secret key.(tag-values event k)The values of the tags of event with the name k: the second part of
each such tag, in the order of the tags.
The values of the tags of `event` with the name `k`: the second part of each such tag, in the order of the tags.
(uri x)The nostr: URI of NIP-21 for x, a map of the form that decode gives,
or nil when x names nothing of its type.
The nostr: URI of NIP-21 for `x`, a map of the form that decode gives, or nil when `x` names nothing of its type.
(verified? event)Whether event is an event whose id is the id of its content, and
whose signature is that of the owner of its public key.
NIP-01 defines the id, and BIP-340 defines the signature.
Whether `event` is an event whose id is the id of its content, and whose signature is that of the owner of its public key. NIP-01 defines the id, and BIP-340 defines the signature.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |