This NIP defines the mandatory part of the Nostr protocol. New NIPs may add new fields, message kinds, and features to the structures and flows described here.
Use an secp256k1 ECDSA library to sign the `.id` with the user's private key.
This is the same curve used by Bitcoin. Signatures and encodings follow the [Schnorr signatures standard for the curve `secp256k1`](https://bips.xyz/340) specification.
Parameterized Replaceable events MUST include a `d` tag with an unmodifiable identifier as value to be used as a reference. Tag values that reference the newest replaceable event MUST use this format: `<kind>:<32-byte lowercase hex of a pubkey>:<d-tag value>`. The `d` tag MUST be unique within the same kind and pubkey.
In case of replaceable events with the same timestamp, the event with the lowest `.id` (first in lexical order) SHOULD be retained. Older versions MAY be kept but SHOULD not be returned on queries.
This NIP defines the `kind:0` as **User Metadata**. The `.content` is set to a stringified JSON object `{name: <user's name, string>, about: <string>, picture: <url, string>}`. Since other attributes might exist, Clients SHOULD preserve any unsupported attribute when updating this event.
Each tag is an array of strings of arbitrary size. Their meaning is determined by the event `.kind`. Tags with the same name might have entirely different meanings in different kinds.
The first element of the tag array is referred to as the tag _name_ and the second as the tag _value_. All elements after the second do not have a conventional name.
This NIP defines the format of 3 standard referencing tags: `e`, `p`, and `a`. Tags `e`, `p` can be used to reference events and pubkeys respectively, and tag `a` references the latest version of a replaceable event. Clients MAY `a`- and `e`-tag parameterized replaceables simultaneously.
Relays are not expected to communicate with one another. It's the Client's responsibility to discover which relays have the event set their user wants to see.
Clients SHOULD open a single WebSocket connection to each relay and use it for all their subscriptions. Relays MAY limit the number of connections from specific IP/client/etc.
Clients fetch events using a **subscription** message with one or more filters. Upon receipt, the Relay MUST query its database, return all events that match the filter and keep applying the filter to all connections, returning new events in real-time as they arrive.
`subscription_id` is a non-empty string with a maximum length of 64 chars. Relays MUST manage `<subscription_id>`s independently for each WebSocket connection. `<subscription_id>`s are not globally unique.
Array attributes (i.e. `ids`, `authors`, `kinds`, and tag filters) represent a logical OR statement. At least one of the arrays' values must match the respective field in the event to be considered a match. In the case of tag attributes such as `#e`, for which an event may have multiple values, the event and filter condition values must have at least one item in common.
The `since` and `until` attributes are used to specify the time range of events returned in the subscription. An event matches the filter if `since <= created_at <= until` holds.
The `limit` attribute informs the maximum number of events to return, sorted by `.created_at` from newest to oldest. It operates over the previously stored events and is ignored afterward.
Once all matching events are sent, an `EOSE` message follows to indicate the _end of stored events_ and the beginning of events newly received in real-time.
`CLOSED` messages can be when the relay refuses to fulfill a `REQ` or when it decides to kill a subscription before a client has disconnected or sent a `CLOSE`, a `CLOSED` message is sent:
`OK` messages MUST be sent in response to `EVENT` messages received from clients, they must have the 3rd parameter set to `true` when an event has been accepted by the relay, `false` otherwise. The 4th parameter MUST always be present, but MAY be an empty string when the 3rd is `true`.
If present, the message MUST be a string formed by a machine-readable single-word prefix followed by a `:` and then a human-readable message.
The standardized machine-readable prefixes for `OK` and `CLOSED` are: `duplicate`, `pow`, `blocked`, `rate-limited`, `invalid`, and `error` for when none of that fits.