mirror of
https://github.com/nostr-protocol/nips.git
synced 2025-12-09 00:28:51 +00:00
Compare commits
22 Commits
26-relays-
...
nip-27/mul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a39dd6de82 | ||
|
|
6a778af3da | ||
|
|
225e4774c8 | ||
|
|
ef1efd0d5f | ||
|
|
c9b89cf982 | ||
|
|
e621d78e28 | ||
|
|
8a94cc2f98 | ||
|
|
072783319d | ||
|
|
1228533c24 | ||
|
|
533d316170 | ||
|
|
ef059e0fde | ||
|
|
f6346b6e22 | ||
|
|
903cc0992e | ||
|
|
e8a501c08f | ||
|
|
68300c5990 | ||
|
|
6ee98c1bfb | ||
|
|
f5852fda83 | ||
|
|
ef0f8a1186 | ||
|
|
a902083bac | ||
|
|
d1b6bdb18e | ||
|
|
8bef0e9d79 | ||
|
|
f51ce9dc0e |
42
22.md
Normal file
42
22.md
Normal file
@@ -0,0 +1,42 @@
|
||||
NIP-22
|
||||
======
|
||||
|
||||
Event `created_at` Limits
|
||||
---------------------------
|
||||
|
||||
`draft` `optional` `author:jeffthibault` `author:Giszmo`
|
||||
|
||||
Relays may define both upper and lower limits within which they will consider an event's `created_at` to be acceptable. Both the upper and lower limits MUST be unix timestamps in seconds as defined in [NIP-01](01.md).
|
||||
|
||||
If a relay supports this NIP, the relay SHOULD send the client a `NOTICE` message saying the event was not stored for the `created_at` timestamp not being within the permitted limits.
|
||||
|
||||
Client Behavior
|
||||
---------------
|
||||
|
||||
Clients SHOULD use the [NIP-11](11.md) `supported_nips` field to learn if a relay uses event `created_at` time limits as defined by this NIP.
|
||||
|
||||
Motivation
|
||||
----------
|
||||
|
||||
This NIP formalizes restrictions on event timestamps as accepted by a relay and allows clients to be aware of relays that have these restrictions.
|
||||
|
||||
The event `created_at` field is just a unix timestamp and can be set to a time in the past or future. Relays accept and share events dated to 20 years ago or 50,000 years in the future. This NIP aims to define a way for relays that do not want to store events with *any* timestamp to set their own restrictions.
|
||||
|
||||
[Replaceable events](16.md#replaceable-events) can behave rather unexpected if the user wrote them - or tried to write them - with a wrong system clock. Persisting an update with a backdated system now would result in the update not getting persisted without a `NOTICE` and if they did the last update with a forward dated system, they will again fail to do another update with the now correct time.
|
||||
|
||||
A wide adoption of this nip could create a better user experience as it would decrease the amount of events that appear wildly out of order or even from impossible dates in the distant past or future.
|
||||
|
||||
Python Example
|
||||
--------------
|
||||
|
||||
```python
|
||||
import time
|
||||
|
||||
TIME = int(time.now)
|
||||
LOWER_LIMIT = TIME - (60 * 60 * 24) # Define lower limit as 1 day into the past
|
||||
UPPER_LIMIT = TIME + (60 * 15) # Define upper limit as 15 minutes into the future
|
||||
|
||||
if event.created_at not in range(LOWER_LIMIT, UPPER_LIMIT):
|
||||
# NOTE: This is one example of a notice message. Relays can change this to notify clients however they like.
|
||||
ws.send('["NOTICE", "The event created_at field is out of the acceptable range (-24h, +15min) for this relay and was not stored."]')
|
||||
```
|
||||
93
23.md
93
23.md
@@ -1,93 +0,0 @@
|
||||
NIP-23
|
||||
======
|
||||
|
||||
Relays List
|
||||
-----------
|
||||
|
||||
`draft` `optional` `author:fiatjaf` `author:cameri` `author:monlovesmango` `author:giszmo`
|
||||
|
||||
A special event with kind `10001`, meaning "relay list" is defined as having a list of tags, one for each relay the author uses.
|
||||
|
||||
The content is not used.
|
||||
|
||||
The tags consist of arrays of 3 elements: the first is the relay URL, the second is the _read_ condition, the third is the _write_ condition.
|
||||
|
||||
The _read_ condition consists of a string containing a rule that follows a subset of the [runes](https://pypi.org/project/runes/) language. Specifically only the `|`, `&`, `!`, `>`, `<`, `/` and `=` operators are allowed. When the rule is an empty string it evaluates to `true`. All the operators must be tested against all possible values in the case of filter values that consist of lists of values and also in the case of event tags that can have multiple values for the same tag -- in other words, the `=` may be interpreted as a `values.any(v => v == runeValue)` instead of an `values == runeValue` operator; the `<` may be interpreted as a `values.any(v => v < runeValue)` and so on. Event tags are identified just by their tag key (for example, `e` or `p`) without the `#` prefix used in filters.
|
||||
|
||||
The `read` rule operates on the values of the [NIP-01](01.md) **filter** object, while the `write` rule operates on the values of the **event** object.
|
||||
|
||||
When a `read` rule evaluates to `false` for a given **filter** the client SHOULD NOT send that filter in a `REQ` message to that relay.
|
||||
|
||||
When a `write` rule evaluates to `false` for a given **event** the client SHOULD NOT send that event in an `EVENT` message to that relay.
|
||||
|
||||
When a rule is malformed or the client is unable to parse it for any reason (for example, for not having implemented all the operators) it SHOULD treat it as `true` if it is a _read_ rule and `false` if it is a _write_ rule.
|
||||
|
||||
### Purposes
|
||||
|
||||
This NIP serves two purposes: (1) backup and interoperability of relay lists and relay specific rules between clients; and (2) sharing of relay URLs between users.
|
||||
|
||||
The first use case is meant to make it so users can open their client -- or different clients -- in different devices and have their list of relays automatically fetched from a default relay and start using their relays list without having to set everything up again.
|
||||
|
||||
For the second purpose, if any client decides to, they can show to the user what relays other users are using, suggest that or automatically add these to the user's relay list, this can take into account the rules or more likely not. The possibility of sharing a list of relays in standardized format is good for spreading information about relays and contributes to the censorship-resistance of the network.
|
||||
|
||||
### Use cases
|
||||
|
||||
A client can expose to the user a set of premade rule templates (the user doesn't have to see the rules) for common relay policies, for example:
|
||||
|
||||
- "do not use this relay for DMs": sets _write_ to `kind/4`
|
||||
- "only use this relay for DMs": sets _write_ to `kind=4` and _read_ to `kinds=4`
|
||||
- "this is Bob's personal relay, only use it to fetch Bob's events": sets _write_ to `!` and _read_ to `authors=<bob-pubkey>`
|
||||
- "this relay is full of spambots, do not get note replies from this relay": sets _read_ to `kinds=1&e!|kinds/1`
|
||||
- "this is my personal relay, only store my stuff in it": sets _read_ to `authors=<my-pubkey>` _write_ to `pubkey=<my-pubkey>`
|
||||
|
||||
### Examples
|
||||
|
||||
(Public keys are shortened to 4 characters for readability.)
|
||||
|
||||
- Rule evaluation examples:
|
||||
|
||||
- _read_
|
||||
|
||||
- for the filter `{"kinds": [0, 1, 2, 3], "authors": ["abcd", "1234"]}`
|
||||
|
||||
- `<empty>`: `true`
|
||||
- `!`: `invalid` -> `true`
|
||||
- `zjhcxb`: `invalid` -> `true`
|
||||
- `false`: `invalid` -> `true`
|
||||
- `true`: `invalid` -> `true`
|
||||
- `authors=7890`: `false`
|
||||
- `authors=7890|authors=1234`: `true`
|
||||
- `authors=7890&authors=1234`: `false`
|
||||
- `e!`: `true`
|
||||
- `e=5555`: `false`
|
||||
- `kinds=1|kinds=4`: `true`
|
||||
- `kinds<2`: `true`
|
||||
- `kinds>7`: `false`
|
||||
- `kinds=1|kinds=7&authors=8543|authors=1234`: `true`
|
||||
|
||||
- _write_
|
||||
|
||||
- for the event `{"kind": 7, "content": "banana", "tags": ["p", "6677"], "created_at": 123456789, "pubkey": "e3e3"}`
|
||||
|
||||
- `<empty>`: `true`
|
||||
- `!`: `invalid` -> `false`
|
||||
- `7237237`: `invalid` -> `false`
|
||||
- `****`: `invalid` -> `false`
|
||||
- `pubkey=7890`: `false`
|
||||
- `pubkey=e3e3`: `true`
|
||||
- `kind=7&p=6677`: `true`
|
||||
- `created_at>999999999|e=5a5a`: `false`
|
||||
|
||||
- Full example of a kind 10001 event:
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": 10001,
|
||||
"tags": [
|
||||
["wss://alicerelay.com/", "", ""],
|
||||
["wss://bobrelay.com/", "authors=ef87", "!"],
|
||||
["wss://carolrelay.com/", "", ""],
|
||||
],
|
||||
"content": "",
|
||||
...other fields
|
||||
```
|
||||
91
27.md
Normal file
91
27.md
Normal file
@@ -0,0 +1,91 @@
|
||||
NIP-27
|
||||
======
|
||||
|
||||
Restricted Tags
|
||||
---------------
|
||||
|
||||
`draft` `optional` `author:cameri`
|
||||
|
||||
This NIP extends the `<filters>` object described in `NIP-01` to contain
|
||||
arbitrary two-letter tags (known as restricted tags) prefixed by `#`, allowing
|
||||
for events with restricted tags to be queried. Any two-letter key prefixed by
|
||||
`#` is a restricted tag query and must be an array of strings.
|
||||
|
||||
The filter condition matches an event if and only if all of the restricted tags
|
||||
in the event are also present in a `<filters>` object. As such, relays should not
|
||||
forward events with restricted tags to clients without a strictly matching filter.
|
||||
|
||||
A client wishing to use restricted tags should only send events with restricted
|
||||
tags to relays that explicitly support NIP-27.
|
||||
|
||||
## Events
|
||||
|
||||
Clients wishing to send an event with a restricted tag may include one or more
|
||||
two-letter tags with a value set to an arbitrary string.
|
||||
|
||||
Suppose that Alice wants to send an event with the restricted tag `#ch`. The value
|
||||
of the `#ch` restricted tag is the following string: `/nostr/social`
|
||||
|
||||
Alice would construct the following message and send it to her favorite relay
|
||||
which happens to support restricted tags:
|
||||
|
||||
```json
|
||||
[
|
||||
"EVENT",
|
||||
{
|
||||
"id": "<id>",
|
||||
"pubkey": "<Alice's pubkey>",
|
||||
"created_at": 1231469640,
|
||||
"content": "Let's get the conversation started",
|
||||
"tags": [
|
||||
["ch", "/nostr/social"],
|
||||
],
|
||||
"sig": "<sig>"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Subscriptions
|
||||
|
||||
Clients wishing to subscribe to events with restricted tags MUST include a filter
|
||||
that matches all of the restricted tags in said events.
|
||||
|
||||
Suppose that Bob and Charlie both share Alice's interest and would like to stay
|
||||
up to date. Both would construct the following message to subscribe:
|
||||
|
||||
```json
|
||||
[
|
||||
"REQ",
|
||||
"<subscriptionId>",
|
||||
{
|
||||
"#ch": ["/nostr/social"]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
# Use Cases
|
||||
|
||||
1. Subreddit/IRC-like channels (e.g. `{ "#ch": ["r/oldschoolcool"] }`) over Nostr.
|
||||
2. Forums. (e.g. General/Support subforum at itguys.com forum
|
||||
`{ "#fr": ["itguys.com"], "#sb": ["General/Support"] }`)
|
||||
3. Clients wishing to filter out all the noise from the broad public events may
|
||||
choose to only subscribe to events with restricted tags. Apps/games/bots leveraging
|
||||
Nostr may prefer communicating using NIP-27 to namespace their communications.
|
||||
4. A restricted tag with a hard-to-guess value can be used for increased isolation
|
||||
in communications without the expectation of privacy. A "channel-hopping" algorithm
|
||||
shared by clients may improve isolation in this scenario.
|
||||
5. Two or more parties may initiate contact publicly using Direct Messaging to then
|
||||
upgrade their communications to using events with restricted tags with a hard-to-guess
|
||||
value before continuing their exchange. Parties can re-negotiate a new hard-to-guess
|
||||
value at any point.
|
||||
6. Live events can take advantage of ephemeral events and events with restricted
|
||||
tags for exclusivity during the event.
|
||||
7. Smart contracts may communicate with individual clients using events with
|
||||
restricted tags.
|
||||
8. Developers debugging in Nostr can use events with restricted tags to avoid spamming
|
||||
others in public relays.
|
||||
|
||||
|
||||
# Notes
|
||||
|
||||
1. Events with restricted tags are public and offer no privacy.
|
||||
22
README.md
22
README.md
@@ -18,21 +18,21 @@ NIPs stand for **Nostr Implementation Possibilities**. They exist to document wh
|
||||
- [NIP-14: Subject tag in text events.](14.md)
|
||||
- [NIP-15: End of Stored Events Notice](15.md)
|
||||
- [NIP-16: Event Treatment](16.md)
|
||||
- [NIP-23: Relays List](23.md)
|
||||
- [NIP-22: Event created_at Limits](22.md)
|
||||
- [NIP-25: Reactions](25.md)
|
||||
- [NIP-27: Restricted events](27.md)
|
||||
|
||||
## Event Kinds
|
||||
|
||||
| kind | description | NIP |
|
||||
| ------ | --------------------------- | ------ |
|
||||
| 0 | Metadata | 1, 5 |
|
||||
| 1 | Text | 1 |
|
||||
| 2 | Recommend Relay | 1 |
|
||||
| 3 | Contacts | 2 |
|
||||
| 4 | Encrypted Direct Messages | 4 |
|
||||
| 5 | Event Deletion | 9 |
|
||||
| 7 | Reaction | 25 |
|
||||
| 10001 | Relays List | 23 |
|
||||
| kind | description | NIP |
|
||||
|------|---------------------------|------|
|
||||
| 0 | Metadata | 1, 5 |
|
||||
| 1 | Text | 1 |
|
||||
| 2 | Recommend Relay | 1 |
|
||||
| 3 | Contacts | 2 |
|
||||
| 4 | Encrypted Direct Messages | 4 |
|
||||
| 5 | Event Deletion | 9 |
|
||||
| 7 | Reaction | 25 |
|
||||
|
||||
Please update this list when proposing NIPs introducing new event kinds.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user