mirror of
https://github.com/nostr-protocol/nips.git
synced 2024-11-15 00:09:08 -05:00
315 lines
12 KiB
Markdown
315 lines
12 KiB
Markdown
NIP-11
|
|
======
|
|
|
|
Relay Information Document
|
|
---------------------------
|
|
|
|
`draft` `optional`
|
|
|
|
Relays may provide server metadata to clients to inform them of capabilities, administrative contacts, and various server attributes. This is made available as a JSON document over HTTP, on the same URI as the relay's websocket.
|
|
|
|
When a relay receives an HTTP(s) request with an `Accept` header of `application/nostr+json` to a URI supporting WebSocket upgrades, they SHOULD return a document with the following structure.
|
|
|
|
```json
|
|
{
|
|
"name": <string identifying relay>,
|
|
"description": <string with detailed information>,
|
|
"pubkey": <administrative contact pubkey>,
|
|
"contact": <administrative alternate contact>,
|
|
"supported_nips": <a list of NIP numbers supported by the relay>,
|
|
"software": <string identifying relay software URL>,
|
|
"version": <string version identifier>
|
|
}
|
|
```
|
|
|
|
Any field may be omitted, and clients MUST ignore any additional fields they do not understand. Relays MUST accept CORS requests by sending `Access-Control-Allow-Origin`, `Access-Control-Allow-Headers`, and `Access-Control-Allow-Methods` headers.
|
|
|
|
Field Descriptions
|
|
------------------
|
|
|
|
### Name
|
|
|
|
A relay may select a `name` for use in client software. This is a string, and SHOULD be less than 30 characters to avoid client truncation.
|
|
|
|
### Description
|
|
|
|
Detailed plain-text information about the relay may be contained in the `description` string. It is recommended that this contain no markup, formatting or line breaks for word wrapping, and simply use double newline characters to separate paragraphs. There are no limitations on length.
|
|
|
|
### Pubkey
|
|
|
|
An administrative contact may be listed with a `pubkey`, in the same format as Nostr events (32-byte hex for a `secp256k1` public key). If a contact is listed, this provides clients with a recommended address to send encrypted direct messages (See `NIP-04`) to a system administrator. Expected uses of this address are to report abuse or illegal content, file bug reports, or request other technical assistance.
|
|
|
|
Relay operators have no obligation to respond to direct messages.
|
|
|
|
### Contact
|
|
|
|
An alternative contact may be listed under the `contact` field as well, with the same purpose as `pubkey`. Use of a Nostr public key and direct message SHOULD be preferred over this. Contents of this field SHOULD be a URI, using schemes such as `mailto` or `https` to provide users with a means of contact.
|
|
|
|
### Supported NIPs
|
|
|
|
As the Nostr protocol evolves, some functionality may only be available by relays that implement a specific `NIP`. This field is an array of the integer identifiers of `NIP`s that are implemented in the relay. Examples would include `1`, for `"NIP-01"` and `9`, for `"NIP-09"`. Client-side `NIPs` SHOULD NOT be advertised, and can be ignored by clients.
|
|
|
|
### Software
|
|
|
|
The relay server implementation MAY be provided in the `software` attribute. If present, this MUST be a URL to the project's homepage.
|
|
|
|
### Version
|
|
|
|
The relay MAY choose to publish its software version as a string attribute. The string format is defined by the relay implementation. It is recommended this be a version number or commit identifier.
|
|
|
|
Extra Fields
|
|
------------
|
|
|
|
### Server Limitations
|
|
|
|
These are limitations imposed by the relay on clients. Your client
|
|
should expect that requests which exceed these *practical* limitations
|
|
are rejected or fail immediately.
|
|
|
|
```json
|
|
{
|
|
"limitation": {
|
|
"max_message_length": 16384,
|
|
"max_subscriptions": 20,
|
|
"max_filters": 100,
|
|
"max_limit": 5000,
|
|
"max_subid_length": 100,
|
|
"max_event_tags": 100,
|
|
"max_content_length": 8196,
|
|
"min_pow_difficulty": 30,
|
|
"auth_required": true,
|
|
"payment_required": true,
|
|
"restricted_writes": true,
|
|
"created_at_lower_limit": 31536000,
|
|
"created_at_upper_limit": 3
|
|
},
|
|
...
|
|
}
|
|
```
|
|
|
|
- `max_message_length`: this is the maximum number of bytes for incoming JSON that the relay
|
|
will attempt to decode and act upon. When you send large subscriptions, you will be
|
|
limited by this value. It also effectively limits the maximum size of any event. Value is
|
|
calculated from `[` to `]` and is after UTF-8 serialization (so some unicode characters
|
|
will cost 2-3 bytes). It is equal to the maximum size of the WebSocket message frame.
|
|
|
|
- `max_subscriptions`: total number of subscriptions that may be
|
|
active on a single websocket connection to this relay. It's possible
|
|
that authenticated clients with a (paid) relationship to the relay
|
|
may have higher limits.
|
|
|
|
- `max_filters`: maximum number of filter values in each subscription.
|
|
Must be one or higher.
|
|
|
|
- `max_subid_length`: maximum length of subscription id as a string.
|
|
|
|
- `max_limit`: the relay server will clamp each filter's `limit` value to this number.
|
|
This means the client won't be able to get more than this number
|
|
of events from a single subscription filter. This clamping is typically done silently
|
|
by the relay, but with this number, you can know that there are additional results
|
|
if you narrowed your filter's time range or other parameters.
|
|
|
|
- `max_event_tags`: in any event, this is the maximum number of elements in the `tags` list.
|
|
|
|
- `max_content_length`: maximum number of characters in the `content`
|
|
field of any event. This is a count of unicode characters. After
|
|
serializing into JSON it may be larger (in bytes), and is still
|
|
subject to the `max_message_length`, if defined.
|
|
|
|
- `min_pow_difficulty`: new events will require at least this difficulty of PoW,
|
|
based on [NIP-13](13.md), or they will be rejected by this server.
|
|
|
|
- `auth_required`: this relay requires [NIP-42](42.md) authentication
|
|
to happen before a new connection may perform any other action.
|
|
Even if set to False, authentication may be required for specific actions.
|
|
|
|
- `payment_required`: this relay requires payment before a new connection may perform any action.
|
|
|
|
- `restricted_writes`: this relay requires some kind of condition to be fulfilled in order to
|
|
accept events (not necessarily, but including `payment_required` and `min_pow_difficulty`).
|
|
This should only be set to `true` when users are expected to know the relay policy before trying
|
|
to write to it -- like belonging to a special pubkey-based whitelist or writing only events of
|
|
a specific niche kind or content. Normal anti-spam heuristics, for example, do not qualify.
|
|
|
|
- `created_at_lower_limit`: 'created_at' lower limit
|
|
|
|
- `created_at_upper_limit`: 'created_at' upper limit
|
|
|
|
### Event Retention
|
|
|
|
There may be a cost associated with storing data forever, so relays
|
|
may wish to state retention times. The values stated here are defaults
|
|
for unauthenticated users and visitors. Paid users would likely have
|
|
other policies.
|
|
|
|
Retention times are given in seconds, with `null` indicating infinity.
|
|
If zero is provided, this means the event will not be stored at
|
|
all, and preferably an error will be provided when those are received.
|
|
|
|
```json
|
|
{
|
|
"retention": [
|
|
{"kinds": [0, 1, [5, 7], [40, 49]], "time": 3600},
|
|
{"kinds": [[40000, 49999]], "time": 100},
|
|
{"kinds": [[30000, 39999]], "count": 1000},
|
|
{"time": 3600, "count": 10000}
|
|
]
|
|
}
|
|
```
|
|
|
|
`retention` is a list of specifications: each will apply to either all kinds, or
|
|
a subset of kinds. Ranges may be specified for the kind field as a tuple of inclusive
|
|
start and end values. Events of indicated kind (or all) are then limited to a `count`
|
|
and/or time period.
|
|
|
|
It is possible to effectively blacklist Nostr-based protocols that rely on
|
|
a specific `kind` number, by giving a retention time of zero for those `kind` values.
|
|
While that is unfortunate, it does allow clients to discover servers that will
|
|
support their protocol quickly via a single HTTP fetch.
|
|
|
|
There is no need to specify retention times for _ephemeral events_ since they are not retained.
|
|
|
|
### Content Limitations
|
|
|
|
Some relays may be governed by the arbitrary laws of a nation state. This
|
|
may limit what content can be stored in cleartext on those relays. All
|
|
clients are encouraged to use encryption to work around this limitation.
|
|
|
|
It is not possible to describe the limitations of each country's laws
|
|
and policies which themselves are typically vague and constantly shifting.
|
|
|
|
Therefore, this field allows the relay operator to indicate which
|
|
countries' laws might end up being enforced on them, and then
|
|
indirectly on their users' content.
|
|
|
|
Users should be able to avoid relays in countries they don't like,
|
|
and/or select relays in more favourable zones. Exposing this
|
|
flexibility is up to the client software.
|
|
|
|
```json
|
|
{
|
|
"relay_countries": [ "CA", "US" ],
|
|
...
|
|
}
|
|
```
|
|
|
|
- `relay_countries`: a list of two-level ISO country codes (ISO 3166-1 alpha-2) whose
|
|
laws and policies may affect this relay. `EU` may be used for European Union countries.
|
|
|
|
Remember that a relay may be hosted in a country which is not the
|
|
country of the legal entities who own the relay, so it's very
|
|
likely a number of countries are involved.
|
|
|
|
|
|
### Community Preferences
|
|
|
|
For public text notes at least, a relay may try to foster a
|
|
local community. This would encourage users to follow the global
|
|
feed on that relay, in addition to their usual individual follows.
|
|
To support this goal, relays MAY specify some of the following values.
|
|
|
|
```json
|
|
{
|
|
"language_tags": ["en", "en-419"],
|
|
"tags": ["sfw-only", "bitcoin-only", "anime"],
|
|
"posting_policy": "https://example.com/posting-policy.html",
|
|
...
|
|
}
|
|
```
|
|
|
|
- `language_tags` is an ordered list
|
|
of [IETF language tags](https://en.wikipedia.org/wiki/IETF_language_tag) indicating
|
|
the major languages spoken on the relay.
|
|
|
|
- `tags` is a list of limitations on the topics to be discussed.
|
|
For example `sfw-only` indicates that only "Safe For Work" content
|
|
is encouraged on this relay. This relies on assumptions of what the
|
|
"work" "community" feels "safe" talking about. In time, a common
|
|
set of tags may emerge that allow users to find relays that suit
|
|
their needs, and client software will be able to parse these tags easily.
|
|
The `bitcoin-only` tag indicates that any *altcoin*, *"crypto"* or *blockchain*
|
|
comments will be ridiculed without mercy.
|
|
|
|
- `posting_policy` is a link to a human-readable page which specifies the
|
|
community policies for the relay. In cases where `sfw-only` is True, it's
|
|
important to link to a page which gets into the specifics of your posting policy.
|
|
|
|
The `description` field should be used to describe your community
|
|
goals and values, in brief. The `posting_policy` is for additional
|
|
detail and legal terms. Use the `tags` field to signify limitations
|
|
on content, or topics to be discussed, which could be machine
|
|
processed by appropriate client software.
|
|
|
|
### Pay-to-Relay
|
|
|
|
Relays that require payments may want to expose their fee schedules.
|
|
|
|
```json
|
|
{
|
|
"payments_url": "https://my-relay/payments",
|
|
"fees": {
|
|
"admission": [{ "amount": 1000000, "unit": "msats" }],
|
|
"subscription": [{ "amount": 5000000, "unit": "msats", "period": 2592000 }],
|
|
"publication": [{ "kinds": [4], "amount": 100, "unit": "msats" }],
|
|
},
|
|
...
|
|
}
|
|
```
|
|
|
|
### Icon
|
|
|
|
A URL pointing to an image to be used as an icon for the relay. Recommended to be squared in shape.
|
|
|
|
```json
|
|
{
|
|
"icon": "https://nostr.build/i/53866b44135a27d624e99c6165cabd76ac8f72797209700acb189fce75021f47.jpg",
|
|
...
|
|
}
|
|
```
|
|
|
|
### Examples
|
|
|
|
As of 2 May 2023 the following command provided these results:
|
|
|
|
```
|
|
~> curl -H "Accept: application/nostr+json" https://eden.nostr.land | jq
|
|
|
|
{
|
|
"description": "nostr.land family of relays (us-or-01)",
|
|
"name": "nostr.land",
|
|
"pubkey": "52b4a076bcbbbdc3a1aefa3735816cf74993b1b8db202b01c883c58be7fad8bd",
|
|
"software": "custom",
|
|
"supported_nips": [
|
|
1,
|
|
2,
|
|
4,
|
|
9,
|
|
11,
|
|
12,
|
|
16,
|
|
20,
|
|
22,
|
|
28,
|
|
33,
|
|
40
|
|
],
|
|
"version": "1.0.1",
|
|
"limitation": {
|
|
"payment_required": true,
|
|
"max_message_length": 65535,
|
|
"max_event_tags": 2000,
|
|
"max_subscriptions": 20,
|
|
"auth_required": false
|
|
},
|
|
"payments_url": "https://eden.nostr.land",
|
|
"fees": {
|
|
"subscription": [
|
|
{
|
|
"amount": 2500000,
|
|
"unit": "msats",
|
|
"period": 2592000
|
|
}
|
|
]
|
|
},
|
|
}
|