9.7 KiB
NIP-79
Nostr Relay Chat
draft
optional
IRC is a very old style of instant messaging that has been used on the internet since 1988 when the first form was written and deployed at University of Oulu in Finland by Jarkko Oikarinen.
There has been numerous additions to the protocol and the latest version is 3. This NIP is for something that is a lot more like the original, and will be primarily for a purely synchronous, and asynchronous messaging will be possible only via clients implementing a message cache and uploading them to their follows when they connect, so the relay is by default never retaining the message stream (saving data storage and query processing).
If users want asynchronous message delivery, there is existing kinds for this purpose, this NIP only concerns itself with synchronous messaging, and only defines ephemeral message kinds. It is a bare minimal specification, there is no explicit moderation capability, only user's own mute lists to have the relay not send them spam, and the use of hashtags as a channel specifier.
Mimetypes
the m
tag is already normalized as meaning "mimetype" in teh http protocol sense, and we are going to maintain this.
so, messages can have a mimetype m
tag, and normally that will be text/markdown
but it can also be text/html
or
other things.
this should be not optional
all messages using the kinds defined in this protocol must use an m
tag.
Message Kinds
There are three new event kinds defined for this protocol:
- NRCMessage - a message posted by the user to be broadcast to active subscribers
- NRCStatus - a message indicating that a specific user is connected or is about to disconnect
- NRCGroup - a wrapped message that was received by one relay and forwarded to others
NRCMessage 23514
This message type simply contains a text message in an optionally minimalistic Markdown format, suggested to implement the following basic markdown features:
- Bold, Italic, Underline, Strikethrough, Monospace
backticks
- Hyperlinks (though http/s prefixes SHOULD also cause the client to render a hyperlink)
- Headers 1 to 6
- Double linefeed paragraph separation
- Images/embeds - but also optionally render them if the file extension is recognised
- Preformatted monospaced via either indentation or (optionally syntax labeled) triple backtick fences
The reason for supporting these features is to facilitate use of the chat for technical discussions. It is OPTIONAL to actually implement (since for a TTY or speech based client this may not be practical to render).
Mentions should use the same syntax as kind 1 notes, with the nostr:
protocol prefix and the bech32 entity reference.
Special handling for replies in the context of the ephemeral messages should be used as described below regarding
replies and quotes, so that anyone who has connected since a replied to message can still see the message.
NRCStatus 23515
This message type is simply an "online/offline" text in the "content" field, and is used to facilitate "join/part" messages to be rendered. This also facilitates the ability for direct messages to be resent if the receiver was offline. This message should be sent periodically, like once every 60 seconds or so, in order to function as a dead man switch if the offline message fails to send.
NRCGroup 23516
In order to facilitate more resilience, it is possible to join a group of relays together and have the above messages propagate across all members of the group. The relay must be in the follow list of the recipient and authenticated, and then they can forward messages they have received from their client, wrapped as stringified JSON inside a 23516 kind event.
For efficiency of filtering, all encapsulated events inside a 23516 must have the npubs in a p
tag that are found in
the stringified json inside, which should be copied from further 23516 events at any level of depth. Compliance with
this should be verified by relays and failure to do this correctly should result in halting relaying of events from this
relay, messages should be simply dropped, and the sender will likely automatically drop the connection due to not
getting OK acks anymore.
The initiation of this process starts with this message kind with no content, and this causes the recipient to add a subscription for forwarding events received by the relay of the 235xx kind wrapped in a 23516 to the sender of this empty message. This will cease when the socket is disconnected. The wrapped events are sent as-is to all listeners subscribed to the event kind, so long as the p tags validate against the p tags in the layers of forwarded messages.
When a relay has more than two other relays joined with it in a group, it will only send messages it receives to two of the 3+ other relays, ensuring that the volume of messages is received at most 2-3 times by other members of the group. A buffer of recently broadcast IDs should be maintained along with their timestamp of being received, and after they are more than 30 seconds old, they can be safely removed.
The messages will be propagated including the forwarding wrapper, so as a message group gets larger, the messages will be 3 and more layers deep. There is no real need to have groups get much larger than maybe 16 so a depth of 5-7 is likely the maximum practical, and a relay can refuse to forward messages that are more than some specified depth.
For protection against spam, multiple measures can be applied:
- Relays will not accept group join subscriptions from an npub on the owners' mute lists
- Clients can subscribe to only 23514 and 23516 events and not see events relayed from other group relay members
- Relays won't send events to clients if the npub of the sender is on their mute list, thus users can mute group member propagated messages, as well as separately filtering out relays and users npubs contained within
With all these measures in place, open membership based groups across multiple relays can function without central coordination.
Chatrooms via Hashtags
The simple use of t
tags and a hashtag MUST be recognised as meaning a message is sent to subscribers interested in
this specific chatroom. #general
will be a default in clients for the initial room that is rendered in an not yet
configured client, clients should receive all events in the background and populate a hashtag list to enable favourites.
The hashtag of a message should also appear in all 23516 group forwarded messages tags as well to facilitate easier processing, in addition to all npubs appearing in encapsulated messages. Messages can only have one hashtag.
Messages with hashtags should be whitelist propagated to users who have the hashtag in their follow list, AND NOT in the mute list.
Automatic Filtering
Follow lists include hashtags, and relays should only send messages that are on the user's follow list OR are tagged with a hashtag they follow AND NOT users or hashtags on their mute list. This is additionally facilitated by Directory Spidering to gather the available user information required. Additionally, active subscriptions for hashtags should be considered a temporary white list for allowed npubs, AND NOT those the user has designated a mute for.
Directory Spidering
Relays supporting this NIP should include a "directory spider" feature that periodically polls all the relays that it can find from user's relay lists NIP-65 and NIP-17 Direct Messaging relays all following event kinds:
- 10002 Relay List Metadata
- 10050 Direct Message Relay Lists
in order to gather all relevant relays to the users who are permitted to use the relay (this is most easily implemented by designated relay "owners" whose follow lists designate first level allowed users and the lists of these follows are additionally permitted in order to facilitate easy access, this can be informal, or on a paid subscription basis).
Further, to facilitate necessary user interface features, all following kinds of users permitted to use the relay should be sought and cached:
- 0 ProfileMetadata
- 3 FollowList
- 10000 MuteList
- 5 Event Deletion
- 1984 Reporting
The relay lists can be used to acquire a set of sources to interrogate, and from there these event kinds are needed in order to implement the features of this NIP.
Direct Messages
Contain P
(private) tags that designate the recipient,and are only sent to the users authed with the designated public
key, and are additionally encrypted using NIP-44. These may only be sent to a user with the matching pubkey as
the one designated in the P
tag. If the user is not online, the message will be dropped, and resending will be the
responsibility of the client, which may also give the user the option to send a standard 1059/1060 gift wrapped
persistent private message, which is specified elsewhere.
Resending, Quoting and Replying
Clients should enable the feature for users to resend events that are cached in their client, which will be the original event stringified in the content field, signed with a new, current timestamp.
To keep things simple, making a reply should wrap the replied to message in a prior message, and the reply itself is a subsequent message with an "e" tag marked "reply" in the same way as used for kind 1 text notes.
Denial of Service Countermeasures
The main kind of DoS attack on a relay hosting a chat service as described here is that of channel stuffing. This can be mitigated by using a reasonable averaging window that simply drops messages that exceed a volume of characters beyond the capability of a human to input, which would be around 1kb/minute maximum bytes of text, measured by the size of the content field of the events. A further limit could cap individual event content size to equivalent to about the same as a printed page of text, or about 4096 characters max for a post size.