nostr/nips/01.md

5.5 KiB

NIP-01

Basic protocol flow description

draft mandatory author:fiatjaf

This NIP defines the basic protocol that should be implemented by everybody. New NIPs may add new optional (or mandatory) fields and messages and features to the structures and flows described here.

Events and signatures

Each user has a keypair. Signatures, public key and encodings are done according to the Schnorr signatures standard for the curve secp256k1.

The single object type that exists is the event, which has the following format on the wire:

{
  "id": <32-bytes sha256 of the the serialized event data>
  "pubkey": <32-bytes hex-encoded public key of the event creator>,
  "created_at": <unix timestamp in seconds>,
  "kind": <integer>,
  "tags": [
    ["e", <32-bytes hex of the id of another event>, <recommended relay URL>],
    ["p", <32-bytes hex of the key>, <recommended relay URL>],
    ... // other kinds of tags may be included later
  ]
  "content": <arbitrary string>,
  "sig": <64-bytes signature of the sha256 hash of the serialized event data, which is the same as the "id" field>,
}

To obtain the event.id, we sha256 the serialized event. The serialization is done over the UTF-8 JSON-serialized string (with no indentation or extra spaces) of the following structure:

[
  0,
  <pubkey, as a (lowercase) hex string>,
  <created_at, as a number>,
  <kind, as a number>,
  <tags, as an array of arrays>,
  <content>, as a string
]

Communication between clients and relays

Relays expose a websocket endpoint to which clients can connect.

From client to relay: sending events and creating subscriptions

Clients can send 3 types of messages, which must be JSON arrays, according to the following patterns:

  • ["EVENT", <event JSON as defined above>], used to publish events.
  • ["REQ", <id>, <filter JSON>...], used to request events and subscribe to new updates.
  • ["CLOSE", <id>], used to stop previous subscriptions.

<id> is a random string that should be used to represent a subscription. The same

<filters> is a JSON object that determines what events will be sent in that subscription, it can have the following attributes:

{
  "id": <the id of an event>,
  "kind": <a kind number>
  "#e": <an event id that is referenced in an "e" tag>,
  "#p": <a pubkey that is referenced in a "p" tag>,
  "since": <a timestamp, events must be newer than this to pass>,
  "until": <a timestamp, events must be older than this to pass>,
  "authors": <a list of pubkeys, the pubkey of an event must be one of these>
}

Upon receiving a REQ message, the relay MUST query its internal database and return events that match the filter, then store that filter and send again all future events it receives to that same websocket until the websocket is closed, the CLOSE event is received with the same <id> or a new REQ is sent using the same id, in which case it should overwrite the previous subscription.

All conditions of a filter that are specified must be valid for an event for it to pass the filter, i.e., multiple conditions are interpreted as && conditions.

A REQ message may contain multiple filters. In this case events that match any of the filters are to be returned, i.e., multiple filters are to be interpreted as || conditions.

From relay to client: sending events and notices

Relays can send 2 types of messages, which must also be JSON arrays, according to the following patterns:

  • ["EVENT", <subscription id>, <event JSON as defined above>], used to send events requested by clients.
  • ["NOTICE", <message>], used to send human-readable error messages or other things to clients.

This NIP defines no rules for how NOTICE messages should be sent or treated.

EVENT messages MUST be sent only with a subscription ID related to a subscription previously initiated by the client (using the REQ message above).

Basic Event Kinds

  • 0: set_metadata: the content is set to a stringified JSON object {name: <string>, about: <string>, picture: <url, string>} describing the user who created the event. A relay may delete past set_metadata events once it gets a new one for the same pubkey.
  • 1: text_note: the content is set to the text content of a note (anything the user wants to say).
  • 2: recommend_server: the content is set to the URL (e.g., https://somerelay.com) of a relay the event creator wants to recommend to its followers.

A relay may choose to treat different message kinds differently, but it should default to returning all event kinds, even when it doesn't know what they mean.

Other Notes:

  • Clients should not open more than one websocket to each relay. It also is advised that clients do not open more than 3 subscriptions to the same relay. 3 is enough for most use cases and relays should impose limits to prevent over usage by clients.
  • The tags array can store any kind of tag the message may be related to. This NIP defines "p" — meaning "profile", which points to a pubkey of someone that is referred to in the event —, and "e" — meaning "event", which points to the id of an event this event is quoting, replying to or referring to somehow.
  • The <recommended relay URL> item present on the "e" and "p" tags is an optional (could be set to "") URL of a relay the client could attempt to connect to fetch the tagged event or other events from a tagged profile. It MAY be ignored, but it exists to increase censorship resistance and make the spread of relay addresses more seamless across clients.