mirror of
https://github.com/nostr-protocol/nips.git
synced 2025-03-25 17:21:52 +01:00
Merge e398c267b47ee0724ee39d59ce89a38c32786caa into 0619f370bca3485bb9c5870bc2defa03c7c3d10e
This commit is contained in:
commit
11d38e5ecd
166
79.md
Normal file
166
79.md
Normal file
@ -0,0 +1,166 @@
|
||||
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](65.md) and [NIP-17](17.md) 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](44.md). 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.
|
Loading…
x
Reference in New Issue
Block a user