Compare commits

...

120 Commits

Author SHA1 Message Date
Leo Wandersleb
013d94a840 Add Parametrized Replaceable events to kind list 2023-01-17 14:11:49 -03:00
marc@roosoft.com
1840c5cbdf removed kind 6 since NIP-18 has been removed from the spec 2023-01-16 16:57:43 -03:00
fiatjaf
7349643069 remove NIP-18, it is not really a standard.
closes https://github.com/nostr-protocol/nips/issues/173
2023-01-16 15:58:53 -03:00
fiatjaf
be0a426745 Merge pull request #141 from nostr-protocol/auth 2023-01-16 08:28:02 -03:00
fiatjaf
e5ae318984 add nos2x-fox to NIP-07 implementations. 2023-01-15 20:05:52 -03:00
Vasilios Daskalopoulos
7d79205537 fix erroneous reference to pubkey 2023-01-15 17:53:34 -03:00
Vasilios Daskalopoulos
132100fd16 fix minor typo 2023-01-15 17:53:34 -03:00
fiatjaf
230f63dd5f nip-07 extensions to also add .id and .pubkey when signing. 2023-01-15 15:37:42 -03:00
monlovesmango
f0842438c1 clarify top level reply behavior 2023-01-15 09:18:15 -03:00
monlovesmango
6f5f9856b9 define 'mention' tag 2023-01-15 09:18:15 -03:00
monlovesmango
5355edb9cb add 'mention' marker
I think that adding a mention marker would eliminate ambiguity for clients supporting both the deprecated and preferred conventions. I also think that this would allow for extensibility in adding new types of event mentions (for example if we want to add context for a note).
2023-01-15 09:18:15 -03:00
benthecarman
0019a206a3 NIP25: allow for emojis to be considered dislikes 2023-01-11 17:47:26 -03:00
Leo Wandersleb
6074116053 Update 42.md
Co-authored-by: Ricardo Arturo Cabral Mejía <me@ricardocabral.io>
2023-01-11 00:05:15 -03:00
kdmukai
e55c86d207 NIP-26: Change example condition to expire at a future date (#157)
also Regenerate example PKs and improve organization/presentation.
2023-01-07 20:12:48 -03:00
fiatjaf
6a70967f0e add challenge from relay. 2023-01-07 19:53:42 -03:00
Jeff Thibault
741ac01b97 NIP-22: use nip-20; minor updates 2023-01-07 17:53:24 -03:00
Luke Childs
01a3090c6a NIP05 Improve CORS header check command 2023-01-06 12:18:20 -03:00
fiatjaf
8c3c421715 merge NIP-35 into NIP-05. 2023-01-04 10:34:24 -03:00
fiatjaf
4472f9bbd9 add NIP-33 to README. 2023-01-04 10:26:08 -03:00
fiatjaf
50faceef09 clarify created_at and auth session duration. 2023-01-04 10:24:37 -03:00
Semisol
018c45966e Add NIP-33 Parameterized replaceable events (#54)
Co-authored-by: Semisol <45574030+Semisol@users.noreply.github.com>
Co-authored-by: Ricardo Arturo Cabral Mejía <me@ricardocabral.io>
2023-01-04 10:20:27 -03:00
fiatjaf
4a5202646a use "OK" message. 2023-01-02 17:26:41 -03:00
fiatjaf
c80be21cd4 drastically simplify @semisol's auth NIP. 2023-01-02 16:56:44 -03:00
Semisol
b9467cb428 nip41: allow for delegated events 2023-01-02 16:53:10 -03:00
Semisol
df28376064 nip41: fix outdated kind 2023-01-02 16:53:10 -03:00
Semisol
a04da3f176 nip-41: fix kind mismatch on example event 2023-01-02 16:53:10 -03:00
Semisol
82aafbef39 add nip-41: authentication 2023-01-02 16:53:10 -03:00
fiatjaf
39aec23a1d NIP18: Reposts (#140)
Co-authored-by: Leo Wandersleb <leo@leowandersleb.de>
2023-01-02 16:15:42 -03:00
fiatjaf
3dd52e5cb4 increase requirements for nips. 2023-01-02 07:17:13 -03:00
@RandyMcMillan
da7899cebe 25.md:15: interepreted ==> interpreted 2023-01-01 08:48:29 -03:00
Blake Jakopovic
329cd8d8a1 Update 19.md
Fixed typo
2022-12-30 09:05:15 -03:00
fiatjaf
0ca9be8224 clarify nip19 purpose. 2022-12-29 21:02:32 -03:00
Lyle Pratt
a37a27afb9 Make it clear that NIP-05 Keys should be in Hex
There has been some confusion about whether npub keys are supported by this spec. According to @fiatjaf only Hex keys are supported. https://twitter.com/fiatjaf/status/1608606752987316224?s=20&t=6fJLD3077byuoTm96kva1g
2022-12-29 20:52:54 -03:00
majestrate
d41834fa51 update NIP-05 addressing reflectivity. (#128) 2022-12-29 11:01:35 -03:00
ok300
570bc59e7d Update e-tag type for direct reply 2022-12-29 11:00:55 -03:00
ok300
c5d2135158 Clarify marked e-tags for direct replies 2022-12-29 11:00:55 -03:00
fiatjaf
997254ad7a clarify that nip-05 identifiers should not be treated as primary keys. 2022-12-29 10:54:37 -03:00
fiatjaf
81a87f7bf2 add examples for nip19. 2022-12-27 07:55:20 -03:00
sgmoore
cee42f806e Minor grammar fixes
Minor grammar fix at line 13, 83, 85. and 111.
2022-12-26 17:19:38 -03:00
fiatjaf
37caf77b01 Merge pull request #119 from mikedilger/nip35 2022-12-26 12:12:02 -03:00
Mike Dilger
0091582eb2 Note about serving from a dynamic webserver 2022-12-27 04:09:03 +13:00
Mike Dilger
544ec6dcc8 remove invalid trailing comma in JSON 2022-12-27 04:05:54 +13:00
Hampus Sjöberg
e79c84aecc LUD-01: fix typo for the desc of event kind 2 2022-12-24 20:38:34 -03:00
fiatjaf
745297e8c4 add blockcore to nip-07 and mark extra methods as optional. 2022-12-18 06:35:30 -03:00
alex
c840d75ce0 nip-07: add the missing functions
as per conversation in t.me/nostr_protcol

getRelays, nip04.encrypt and nip04.decrypt - these are already implemented
by nos2x and getalby.
2022-12-18 06:29:29 -03:00
sgmoore
da6a7d0ee3 Minor grammar fixes
Minor grammar fix at lines 22 and 93.
2022-12-17 22:34:29 -03:00
sgmoore
4f67f5c999 Minor grammar and spelling fixes
Minor grammar fix at line 48. Minor spelling fix at line 56.
2022-12-17 22:31:19 -03:00
sgmoore
8918dc06ee Minor grammar fixes
Minor grammar fixes at lines 9 and 93.
2022-12-17 22:28:49 -03:00
Leo Wandersleb
f4b6603df5 Merge pull request #97 from brugeman/patch-1 2022-12-17 14:32:47 -03:00
Artur Brugeman
92fbc49274 Add NIP-19 and 40 to README 2022-12-17 19:16:13 +03:00
fiatjaf
9e13889dee add NIP-19: bech32-encoding of stuff. (#57)
* add NIP-19: bech32-encoding of stuff.

* add note prefix for kind-01 notes.

* specify endianness.

* 1 byte for T and L.

* incorporate suggestions after feedback and discussions.

* fix typos.
2022-12-16 11:56:12 -03:00
Drewry Pope
0c7b732867 Improve Case Consistency 2022-12-16 11:50:59 -03:00
Leo Wandersleb
ba75c1b98b Merge pull request #87 from 0xtlt/master 2022-12-16 11:09:26 -03:00
Thomas
04a84aa545 Update 40.md
Co-authored-by: Leo Wandersleb <leo@leowandersleb.de>
2022-12-16 12:03:07 +01:00
Thomas
7ad1812b46 Update 40.md 2022-12-15 20:00:22 +01:00
Thomas
2561c2d1e6 Update 40.md 2022-12-15 19:59:17 +01:00
Thomas
0d93f3033e Update 40.md
Co-authored-by: Semisol <45574030+Semisol@users.noreply.github.com>
2022-12-15 19:58:40 +01:00
Jon Staab
5ef3b9c998 Remove username pattern requirements
Most implementation ignore this line. Enforcing that usernames not include spaces, special chracters, unicode, emojis, etc has no benefit and is unnecessarily user hostile.
2022-12-15 14:00:09 -03:00
Thomas
8d3f5c6e79 Update 40.md 2022-12-14 23:52:12 +01:00
Thomas
b859ae589b Update 40.md 2022-12-14 09:18:52 +01:00
Thomas
26e518da67 Update 40.md 2022-12-14 09:15:44 +01:00
Thomas
e9553eef4d Update 40.md
Co-authored-by: ok300 <106775972+ok300@users.noreply.github.com>
2022-12-14 09:12:44 +01:00
Thomas
7aad54ae7a Update 40.md
Co-authored-by: ok300 <106775972+ok300@users.noreply.github.com>
2022-12-14 09:12:15 +01:00
Thomas
07f13674f1 Update 40.md
Co-authored-by: ok300 <106775972+ok300@users.noreply.github.com>
2022-12-14 09:11:49 +01:00
Thomas
512aba18db Update 40.md
Co-authored-by: Ricardo Arturo Cabral Mejía <me@ricardocabral.io>
2022-12-12 08:55:57 +01:00
Mike Dilger
2fa78a8097 Note on nip-22 about moving old posts to a new relay 2022-12-10 21:38:19 -03:00
Thomas
3cfe0ef8ac Update 40.md 2022-12-10 23:51:04 +01:00
Thomas
a8caa03373 📝 Updated NIP 2022-12-10 23:49:59 +01:00
Jonathan Staab
67c021ae97 Clarify use of kind 1 and kind 1000-10000 2022-12-08 14:33:43 -03:00
Thomas
2cb5ddd910 [timestamp] Add UNIX timestamp in seconds
Co-authored-by: Leo Wandersleb <leo@leowandersleb.de>
2022-12-07 08:53:52 +01:00
Thomas
1bbae4d66b Update 40.md 2022-12-04 16:16:00 +01:00
Thomas
91bb09d1d3 Create 40.md 2022-12-04 16:14:31 +01:00
fiatjaf
5d292e0cbe nip-01: improve connection/subscriptions recommendation and remove the ill-advised 3 subscriptions limit. 2022-12-02 19:54:00 -03:00
Fernando López Guevara
27c6652e0e NIP-36 - sensitive content / content-warning (#82) 2022-12-01 20:41:15 -03:00
fiatjaf
bbc931d02d refine NIP rules. 2022-11-29 11:41:46 -03:00
monlovesmango
0dcf11df80 add nip-26 to readme 2022-11-28 14:31:50 -06:00
fiatjaf
9302c35573 add alby to NIP-07. 2022-11-27 12:03:46 -03:00
Jon Staab
cf5eaf6360 Amend NIP 11 to require CORS support 2022-11-25 13:03:03 -03:00
fiatjaf
743e43a8d4 finalize some NIPs we will not going to change anymore. 2022-11-22 14:52:34 -03:00
Michael Dilger
631e9760bf NIP-35 User Discovery (#73)
* Draft NIP for user discovery

* Renumber to NIP-35

* spelling fix

* Add to README

* fix quote

* and colon
2022-11-19 11:28:47 -08:00
Mike Dilger
c274c65856 Reword NIP-01 to clarify no line breaks. Existing language of "indentation" implies line breaks. 2022-11-15 17:36:13 -03:00
khimaros
a0852a7cbe stronger wording for relay deletion behavior
- change "MAY" to "SHOULD" for removing referenced events
- suggest indefinite retention for deletion events on relays
- include recommendation for clients to rebroadcast deletion events to relays
2022-11-14 14:52:29 -03:00
fiatjaf
30f1e64e01 Merge pull request #62 from jb55/command-results 2022-11-11 11:00:40 -03:00
alex
f09362695d nip16: clarify about the signers of replaceable events
A newer replaceable event must be signed by the same key.
2022-11-11 07:56:24 -03:00
William Casarin
c510e646d0 NIP-20: server errors happen! 2022-11-10 13:14:23 -08:00
William Casarin
ff26b959f8 NIP-20: More clarity around malformed vs invalid events 2022-11-10 12:55:44 -08:00
William Casarin
7569773ad6 NIP-20: add a note about client handling 2022-11-10 12:20:32 -08:00
William Casarin
e7f74d21c4 NIP-20: pow suggestion 2022-11-10 12:02:14 -08:00
William Casarin
a0b0a021a8 NIP-20: add "invalid" message suggestion 2022-11-10 11:57:52 -08:00
William Casarin
15514283f3 NIP-20: Command Results
When submitting events to relays, clients currently have no way to know
if an event was successfully committed to the database. This NIP
introduces the concept of command results which are like NOTICE's except
provide more information about if an event was accepted or rejected.
2022-11-10 10:29:11 -08:00
Blake Jakopovic
27683d3441 Update 10.md
Fixed typo
2022-11-08 16:45:40 -03:00
w3irdrobot
79bb56c2f4 Fix regex for SetMetadata in NIP1
It appears the regex given in NIP1 for setting the username in the setmetadata event was slightly off. I think the fix here is what was intended. Though I think what was meant here was pretty obvious, to make it easier on future developers, I updated the regex to something that should work with just copying and pasting.
2022-11-04 16:33:57 -03:00
William Casarin
b8b5e3aa40 nip25: fix code example
content should not be blank
2022-10-30 08:34:14 -07:00
DZ
6ba2fc3338 Update README.md 2022-10-26 09:54:23 -07:00
DZ
3c0c3ca0f3 Update README.md
add message-type tables
2022-10-26 09:54:23 -07:00
DZ
6d86133118 Update 01.md
fix indentation
2022-10-26 09:54:23 -07:00
Ricardo Arturo Cabral Mejía
147cd0a2ea Merge pull request #53 from Semisol/patch-1
nip16: small fix
2022-10-17 14:24:06 -04:00
Semisol
497d5d9ddf nip16: small fix 2022-10-16 20:24:21 +03:00
DZ
c8a95a0968 Update 01.md
fix typo
2022-10-07 17:17:34 -03:00
fiatjaf
b62aa418de Merge pull request #28 from Minds/minds-nip-26 2022-09-23 13:43:01 -03:00
Greg Heartsfield
fdbf817961 add kinds reserved by NIP-28 2022-09-11 08:23:02 -03:00
Greg Heartsfield
fadbcc0aee add NIP-28 link in README 2022-09-11 08:23:02 -03:00
Christopher David
3423a6dfbc NIP-28: Public Chat (#38) 2022-09-10 14:28:08 -03:00
Leo Wandersleb
3e0e6ca2d6 separate array elements with , 2022-09-02 18:47:42 -03:00
Mark Harding
78522b50a1 Changes based on feedback 2022-08-24 13:24:50 +01:00
William Casarin
7af2540c6e reactions: we should be able to react to any note
Signed-off-by: William Casarin <jb55@jb55.com>
2022-08-19 15:50:39 -07:00
Ricardo Arturo Cabral Mejía
533d316170 Remove NIP-27 2022-08-16 22:59:02 -04:00
Ricardo Arturo Cabral Mejía
ef059e0fde NIP-27 Multicasting 2022-08-16 22:57:22 -04:00
William Casarin
f6346b6e22 Merge pull request #22 from jeffthibault/nip22-unacceptable-event-time
NIP-22: event created_at limits
2022-08-15 13:09:53 -07:00
Jeff Thibault
903cc0992e add Giszmo, add comment in code example 2022-08-14 11:26:39 -04:00
Jeff Thibault
e8a501c08f Merge pull request #1 from Giszmo/nip22
reworded nip-22
2022-08-14 11:18:43 -04:00
Leo Wandersleb
68300c5990 reword nip22, mention replaceable events 2022-08-13 21:50:38 -04:00
Jeff Thibault
6ee98c1bfb spelling nit 2022-08-13 14:08:14 -04:00
Jeff Thibault
f5852fda83 add nip link to readme 2022-08-13 13:54:28 -04:00
Jeff Thibault
ef0f8a1186 rename and rewrite to be more generic 2022-08-13 13:52:14 -04:00
Jeff Thibault
a902083bac Merge branch 'nostr-protocol:master' into nip22-unacceptable-event-time 2022-08-13 10:03:37 -04:00
Mark Harding
e13f6d39b9 First draft of Delegated Event Signing 2022-08-04 09:33:38 +01:00
Jeff Thibault
d1b6bdb18e add relay logic 2022-07-22 12:53:54 -04:00
Jeff Thibault
8bef0e9d79 add that events from future are unacceptable 2022-07-22 12:45:14 -04:00
Jeff Thibault
f51ce9dc0e add nip22: unacceptable event created_at field 2022-07-22 11:50:07 -04:00
23 changed files with 800 additions and 59 deletions

19
01.md
View File

@@ -10,7 +10,7 @@ This NIP defines the basic protocol that should be implemented by everybody. New
## Events and signatures
Each user has a keypair. Signatures, public key and encodings are done according to the [Schnorr signatures standard for the curve `secp256k1`](https://bips.xyz/340).
Each user has a keypair. Signatures, public key, and encodings are done according to the [Schnorr signatures standard for the curve `secp256k1`](https://bips.xyz/340).
The only object type that exists is the `event`, which has the following format on the wire:
@@ -30,7 +30,7 @@ The only object type that exists is the `event`, which has the following format
}
```
To obtain the `event.id`, we `sha256` the serialized event. The serialization is done over the UTF-8 JSON-serialized string (with no indentation or extra spaces) of the following structure:
To obtain the `event.id`, we `sha256` the serialized event. The serialization is done over the UTF-8 JSON-serialized string (with no white space or line breaks) of the following structure:
```json
[
@@ -80,9 +80,9 @@ The `ids` and `authors` lists contain lowercase hexadecimal strings, which may e
All conditions of a filter that are specified must match for an event for it to pass the filter, i.e., multiple conditions are interpreted as `&&` conditions.
A `REQ` message may contain multiple filters. In this case events that match any of the filters are to be returned, i.e., multiple filters are to be interpreted as `||` conditions.
A `REQ` message may contain multiple filters. In this case, events that match any of the filters are to be returned, i.e., multiple filters are to be interpreted as `||` conditions.
The `limit` property of a filter is only valid for the initial query and can be ignored afterwards. When `limit: n` is present it is assumed that the the events returned in the initial query will be the latest `n` events. It is safe to return less events than `limit` specifies, but it is expected that relays do not return (much) more events than requested so clients don't get unnecessarily overwhelmed by data.
The `limit` property of a filter is only valid for the initial query and can be ignored afterward. When `limit: n` is present it is assumed that the events returned in the initial query will be the latest `n` events. It is safe to return less events than `limit` specifies, but it is expected that relays do not return (much) more events than requested so clients don't get unnecessarily overwhelmed by data.
### From relay to client: sending events and notices
@@ -98,16 +98,13 @@ This NIP defines no rules for how `NOTICE` messages should be sent or treated.
## Basic Event Kinds
- `0`: `set_metadata`: the `content` is set to a stringified JSON object `{name: <username>, about: <string>, picture: <url, string>}` describing the user who created the event. A relay may delete past `set_metadata` events once it gets a new one for the same pubkey.
* Where `<username>` is a string that matches the pattern: `[\w+\-]` (java regular epression). Or, in other words, a sequence of the following
characters: `[a-zA-Z_\-0-9]`. <br>
Thus `George-Washington-1776` is a valid `<username>`, but `George Washington` is not. Clients may reject metadata that does not comply.
- `1`: `text_note`: the `content` is set to the text content of a note (anything the user wants to say).
- `2`: `recommend_server`: the `content` is set to the URL (e.g., `https://somerelay.com`) of a relay the event creator wants to recommend to its followers.
- `1`: `text_note`: the `content` is set to the text content of a note (anything the user wants to say). Non-plaintext notes should instead use kind 1000-10000 as described in [NIP-16](16.md).
- `2`: `recommend_server`: the `content` is set to the URL (e.g., `wss://somerelay.com`) of a relay the event creator wants to recommend to its followers.
A relay may choose to treat different message kinds differently, and it may or may not choose to have a default way to handle kinds it doesn't know about.
## Other Notes:
- Clients should not open more than one websocket to each relay. It also is advised that clients do not open more than 3 subscriptions to the same relay. 3 is enough for most use cases and relays should impose limits to prevent over usage by clients.
- The `tags` array can store a tag identifier as the first element of each subarray, plus arbitrary information afterwards (always as strings). This NIP defines `"p"` — meaning "pubkey", which points to a pubkey of someone that is referred to in the event —, and `"e"` — meaning "event", which points to the id of an event this event is quoting, replying to or referring to somehow.
- Clients should not open more than one websocket to each relay. One channel can support an unlimited number of subscriptions, so clients should do that.
- The `tags` array can store a tag identifier as the first element of each subarray, plus arbitrary information afterward (always as strings). This NIP defines `"p"` — meaning "pubkey", which points to a pubkey of someone that is referred to in the event —, and `"e"` — meaning "event", which points to the id of an event this event is quoting, replying to or referring to somehow.
- The `<recommended relay URL>` item present on the `"e"` and `"p"` tags is an optional (could be set to `""`) URL of a relay the client could attempt to connect to fetch the tagged event or other events from a tagged profile. It MAY be ignored, but it exists to increase censorship resistance and make the spread of relay addresses more seamless across clients.

4
02.md
View File

@@ -4,7 +4,7 @@ NIP-02
Contact List and Petnames
-------------------------
`draft` `optional` `author:fiatjaf` `author:arcbtc`
`final` `optional` `author:fiatjaf` `author:arcbtc`
A special event with kind `3`, meaning "contact list" is defined as having a list of `p` tags, one for each of the followed/known profiles one is following.
@@ -38,7 +38,7 @@ A client may rely on the kind-3 event to display a list of followed people by pr
### Relay sharing
A client may publish a full list of contacts with good relays for each of their contacts so other clients may use these to update their internal relay lists if needed, increasing censorship-resistant.
A client may publish a full list of contacts with good relays for each of their contacts so other clients may use these to update their internal relay lists if needed, increasing censorship-resistance.
### Petname scheme

2
04.md
View File

@@ -4,7 +4,7 @@ NIP-04
Encrypted Direct Message
------------------------
`draft` `optional` `author:arcbtc`
`final` `optional` `author:arcbtc`
A special event with kind `4`, meaning "encrypted direct message". It is supposed to have the following attributes:

49
05.md
View File

@@ -4,13 +4,13 @@ NIP-05
Mapping Nostr keys to DNS-based internet identifiers
----------------------------------------------------
`draft` `optional` `author:fiatjaf`
`final` `optional` `author:fiatjaf` `author:mikedilger`
On events of type `0` (`set_metadata`) one can specify the key `"nip05"` with an [internet identifier](https://datatracker.ietf.org/doc/html/rfc5322#section-3.4.1) (an email-like address) as the value. Although there is a link to a very liberal "internet identifier" specification above, NIP-05 assumes the `<local-part>` part will be restricted to the characters `a-z0-9-_.`, case insensitive.
On events of kind `0` (`set_metadata`) one can specify the key `"nip05"` with an [internet identifier](https://datatracker.ietf.org/doc/html/rfc5322#section-3.4.1) (an email-like address) as the value. Although there is a link to a very liberal "internet identifier" specification above, NIP-05 assumes the `<local-part>` part will be restricted to the characters `a-z0-9-_.`, case insensitive.
Upon seeing that, the client splits the identifier into `<local-part>` and `<domain>` and use these values to make a GET request to `https://<domain>/.well-known/nostr.json?name=<local-part>`.
The result should be a JSON document object with a key `"names"` that should then be a mapping of names to public keys. If the public key for the given `<name>` matches the `pubkey` from the `set_metadata` event, the client then concludes that the given pubkey can indeed be referenced by its identifier.
The result should be a JSON document object with a key `"names"` that should then be a mapping of names to hex formatted public keys. If the public key for the given `<name>` matches the `pubkey` from the `set_metadata` event, the client then concludes that the given pubkey can indeed be referenced by its identifier.
### Example
@@ -33,19 +33,46 @@ It will make a GET request to `https://example.com/.well-known/nostr.json?name=b
"bob": "b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9"
}
}
```
````
That will mean everything is alright.
or with the **optional** `"relays"` attribute:
```json
{
"names": {
"bob": "b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9"
},
"relays": {
"b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9": [ "wss://relay.example.com", "wss://relay2.example.com" ]
}
}
````
If the pubkey matches the one given in `"names"` (as in the example above) that means the association is right and the `"nip05"` identifier is valid and can be displayed.
The optional `"relays"` attribute may contain an object with public keys as properties and arrays of relay URLs as values. When present, that can be used to help clients learn in which relays a that user may be found. Web servers which serve `/.well-known/nostr.json` files dynamically based on the query string SHOULD also serve the relays data for any name they serve in the same reply when that is available.
## Finding users from their NIP-05 identifier
A client may implement support for finding users' public keys from _internet identifiers_, the flow is the same as above, but reversed: first the client fetches the _well-known_ URL and from there it gets the public key of the user, then it tries to fetch the kind `0` event for that user and check if it has a matching `"nip05"`.
## Notes
### Clients must always follow public keys, not NIP-05 addresses
For example, if after finding that `bob@bob.com` has the public key `abc...def`, the user clicks a button to follow that profile, the client must keep a primary reference to `abc...def`, not `bob@bob.com`. If, for any reason, the address `https://bob.com/.well-known/nostr.json?name=bob` starts returning the public key `1d2...e3f` at any time in the future, the client must not replace `abc...def` in his list of followed profiles for the user (but it should stop displaying "bob@bob.com" for that user, as that will have become an invalid `"nip05"` property).
### Public keys must be in hex format
Keys must be returned in hex format. Keys in NIP-19 `npub` format are are only meant to be used for display in client UIs, not in this NIP.
### User Discovery implementation suggestion
A client can also use this to allow users to search other profiles. If a client has a search box or something like that, a user may be able to type "bob@example.com" there and the client would recognize that and do the proper queries to obtain a pubkey and suggest that to the user.
### Showing just the domain as an identifier
Clients may treat the identifier `_@domain` as the "root" identifier, and choose to display it as just the `<domain>`. For example, if Bob owns `bob.com`, he may not want an identifier like `bob@bob.com` as that is redundant. Instead Bob can use the identifier `_@bob.com` and expect Nostr clients to show and treat that as just `bob.com` for all purposes.
Clients may treat the identifier `_@domain` as the "root" identifier, and choose to display it as just the `<domain>`. For example, if Bob owns `bob.com`, he may not want an identifier like `bob@bob.com` as that is redundant. Instead, Bob can use the identifier `_@bob.com` and expect Nostr clients to show and treat that as just `bob.com` for all purposes.
### Reasoning for the `/.well-known/nostr.json?name=<local-part>` format
@@ -53,13 +80,19 @@ By adding the `<local-part>` as a query string instead of as part of the path th
### Allowing access from JavaScript apps
JavaScript Nostr apps may be restricted by browser [CORS][] policies that prevent them from accesing `/.well-known/nostr.json` on the user's domain. When CORS prevents JS from loading a resource, the JS program sees it as a network failure identical to the resource not existing, so it is not possible for a pure-JS app to tell the user for certain that the failure was caused by a CORS issue. JS Nostr apps that see network failures requesting `/.well-known/nostr.json` files may want to recommend to users that they check the CORS policy of their servers, e.g.:
JavaScript Nostr apps may be restricted by browser [CORS][] policies that prevent them from accessing `/.well-known/nostr.json` on the user's domain. When CORS prevents JS from loading a resource, the JS program sees it as a network failure identical to the resource not existing, so it is not possible for a pure-JS app to tell the user for certain that the failure was caused by a CORS issue. JS Nostr apps that see network failures requesting `/.well-known/nostr.json` files may want to recommend to users that they check the CORS policy of their servers, e.g.:
```bash
$ curl -sI https://example.com/.well-known/nostr.json?name=bob | grep ^Access-Control
$ curl -sI https://example.com/.well-known/nostr.json?name=bob | grep -i ^Access-Control
Access-Control-Allow-Origin: *
```
Users should ensure that their `/.well-known/nostr.json` is served with the HTTP header `Access-Control-Allow-Origin: *` to ensure it can be validated by pure JS apps running in modern browsers.
[CORS]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
### Security Constraints
The `/.well-known/nostr.json` endpoint MUST NOT return any HTTP redirects.
Fetchers MUST ignore any HTTP redirects given by the `/.well-known/nostr.json` endpoint.

16
07.md
View File

@@ -12,9 +12,19 @@ That object must define the following methods:
```
async window.nostr.getPublicKey(): string // returns a public key as hex
async window.nostr.signEvent(event: Event): Event // takes an event object and returns it with the `sig`
async window.nostr.signEvent(event: Event): Event // takes an event object, adds `id`, `pubkey` and `sig` and returns it
```
### Implementation example
Aside from these two basic above, the following functions can also be implemented optionally:
```
async window.nostr.getRelays(): { [url: string]: {read: boolean, write: boolean} } // returns a basic map of relay urls to relay policies
async window.nostr.nip04.encrypt(pubkey, plaintext): string // returns ciphertext and iv as specified in nip-04
async window.nostr.nip04.decrypt(pubkey, ciphertext): string // takes ciphertext and iv as specified in nip-04
```
- [nos2x](https://github.com/fiatjaf/nos2x) is available as a Chromium (and partially Firefox) extension that provides such capabilities.
### Implementation
- [nos2x](https://github.com/fiatjaf/nos2x)
- [Alby](https://getalby.com)
- [Blockcore](https://www.blockcore.net/wallet)
- [nos2x-fox](https://diegogurpegui.com/nos2x-fox/)

2
08.md
View File

@@ -4,7 +4,7 @@ NIP-08
Handling Mentions
-----------------
`draft` `optional` `author:fiatjaf` `author:scsibug`
`final` `optional` `author:fiatjaf` `author:scsibug`
This document standardizes the treatment given by clients of inline mentions of other events and pubkeys inside the content of `text_note`s.

6
09.md
View File

@@ -27,11 +27,13 @@ For example:
}
```
Relays MAY delete or stop publishing any referenced events that have an identical `pubkey` as the deletion request. Clients may hide or otherwise indicate a deletion status for referenced events.
Relays SHOULD delete or stop publishing any referenced events that have an identical `id` as the deletion request. Clients SHOULD hide or otherwise indicate a deletion status for referenced events.
Relays SHOULD continue to publish/share the deletion events indefinitely, as clients may already have the event that's intended to be deleted. Additionally, clients SHOULD broadcast deletion events to other relays which don't have it.
## Client Usage
Clients MAY choose to fully hide any events that are referenced by valid deletion events. This includes text notes, direct messages, or other yet-to-be defined event kinds. Alternatively, they MAY show the event along with an icon or other indication that the author has "disowned" the event. The `content` field MAY also be used to replace the deleted events own content, although a user interface should clearly indicate that this is a deletion reason, not the original content.
Clients MAY choose to fully hide any events that are referenced by valid deletion events. This includes text notes, direct messages, or other yet-to-be defined event kinds. Alternatively, they MAY show the event along with an icon or other indication that the author has "disowned" the event. The `content` field MAY also be used to replace the deleted event's own content, although a user interface should clearly indicate that this is a deletion reason, not the original content.
A client MUST validate that each event `pubkey` referenced in the `e` tag of the deletion request is identical to the deletion request `pubkey`, before hiding or deleting any event. Relays can not, in general, perform this validation and should not be treated as authoritative.

20
10.md
View File

@@ -13,7 +13,7 @@ This NIP describes how to use "e" and "p" tags in text events, especially those
## Positional "e" tags (DEPRECATED)
>This scheme is in common use; but should be considered deprecated.
`["e", <event-id> <relay-url>]` as per NIP-01.
`["e", <event-id>, <relay-url>]` as per NIP-01.
Where:
@@ -26,35 +26,37 @@ Where:
This event is not a reply to, nor does it refer to, any other event.
* One "e" tag: <br>
`["e",<id>]`: The id of the event to which this event is a reply.
`["e", <id>]`: The id of the event to which this event is a reply.
* Two "e" tags: `["e",<root-id>]`, `["e",<reply-id>]` <br>
* Two "e" tags: `["e", <root-id>]`, `["e", <reply-id>]` <br>
`<root-id>` is the id of the event at the root of the reply chain. `<reply-id>` is the id of the article to which this event is a reply.
* Many "e" tags: `["e",<root-id>]` `["e",<mention-id>]`, ..., `["e",<reply-id>]`<br>
* Many "e" tags: `["e", <root-id>]` `["e", <mention-id>]`, ..., `["e", <reply-id>]`<br>
There may be any number of `<mention-ids>`. These are the ids of events which may, or may not be in the reply chain.
They are citings from this event. `root-id` and `reply-id` are as above.
>This scheme is deprecated because it creates ambiguities that are difficult, or impossible to resolve when an event references another but is not a reply.
## Marked "e" tags (PREFERRED)
`["e", <event-id> <relay-url> <marker>]`
`["e", <event-id>, <relay-url>, <marker>]`
Where:
* `<event-id>` is the id of the event being referenced.
* `<relay-url>` is the URL of a recommended relay associated with the reference. It is NOT optional.
* `<marker>` is optional and if present is one of `"reply"` or `"root"`
* `<marker>` is optional and if present is one of `"reply"`, `"root"`, or `"mention"`
**The order of marked "e" tags is not relevant.** Those marked with `"reply"` denote the `<reply-id>`. Those marked with `"root"` denote the root id of the reply thread.
**The order of marked "e" tags is not relevant.** Those marked with `"reply"` denote the id of the reply event being responded to. Those marked with `"root"` denote the root id of the reply thread being responded to. For top level replies (those replying directly to the root event), only the `"root"` marker should be used. Those marked with `"mention"` denote a quoted or reposted event id.
>This scheme is preferred because it allows events to mention others without confusing them with `<relay-id>` or `<root-id>`.
A direct reply to the root of a thread should have a single marked "e" tag of type "root".
>This scheme is preferred because it allows events to mention others without confusing them with `<reply-id>` or `<root-id>`.
## The "p" tag
Used in a text event contains a list of pubkeys used to record who is involved in a reply thread.
When replying to a text event E the reply event's "p" tags should contain all of E's "p" tags as well as the `"pubkey"` of the of the event being replied to.
When replying to a text event E the reply event's "p" tags should contain all of E's "p" tags as well as the `"pubkey"` of the event being replied to.
Example: Given a text event authored by `a1` with "p" tags [`p1`, `p2`, `p3`] then the "p" tags of the reply should be [`a1`, `p1`, `p2`, `p3`]
in no particular order.

4
11.md
View File

@@ -22,7 +22,7 @@ When a relay receives an HTTP(s) request with an `Accept` header of `application
}
```
Any field may be omitted, and clients MUST ignore any additional fields they do not understand.
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
-----------------
@@ -47,7 +47,7 @@ An alternative contact may be listed under the `contact` field as well, with the
### 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.
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 ###

4
13.md
View File

@@ -6,7 +6,7 @@ Proof of Work
`draft` `optional` `author:jb55` `author:cameri`
This NIP defines a way to generate and interpret Proof of Work for nostr notes. Proof of Work (PoW) is a way to add a proof of computational work to a note. This is a bearer proof which all relays and clients can universally validate with a small amount of code. This proof can be used as a means of spam deterrence.
This NIP defines a way to generate and interpret Proof of Work for nostr notes. Proof of Work (PoW) is a way to add a proof of computational work to a note. This is a bearer proof that all relays and clients can universally validate with a small amount of code. This proof can be used as a means of spam deterrence.
`difficulty` is defined to be the number of leading zero bits in the `NIP-01` id. For example, an id of `000000000e9d97a1ab09fc381030b346cdd7a142ad57e6df0b46dc9bef6c7e2d` has a difficulty of `36` with `36` leading 0 bits.
@@ -90,4 +90,4 @@ $ echo '["REQ", "subid", {"ids": ["000000000"]}]' | websocat wss://some-relay.c
Delegated Proof of Work
-----------------------
Since the `NIP-01` note id does not commit to any signature, PoW can be outsourced to PoW providers, perhaps for a fee. This provides a way for clients to get their messages out to PoW restricted relays without having to do any work themselves, which is useful for energy constrained devices like on mobile
Since the `NIP-01` note id does not commit to any signature, PoW can be outsourced to PoW providers, perhaps for a fee. This provides a way for clients to get their messages out to PoW-restricted relays without having to do any work themselves, which is useful for energy constrained devices like on mobile

2
15.md
View File

@@ -4,7 +4,7 @@ NIP-15
End of Stored Events Notice
---------------------------
`draft` `optional` `author:Semisol`
`final` `optional` `author:Semisol`
Relays may support notifying clients when all stored events have been sent.

7
16.md
View File

@@ -8,10 +8,15 @@ Event Treatment
Relays may decide to allow replaceable and/or ephemeral events.
Regular Events
------------------
A *regular event* is defined as an event with a kind `1000 <= n < 10000`.
Upon a regular event being received, the relay SHOULD send it to all clients with a matching filter, and SHOULD store it. New events of the same kind do not affect previous events in any way.
Replaceable Events
------------------
A *replaceable event* is defined as an event with a kind `10000 <= n < 20000`.
Upon a replaceable event with a newer timestamp than the currently known latest replaceable event with the same kind, the old event SHOULD be discarded and replaced with the newer event.
Upon a replaceable event with a newer timestamp than the currently known latest replaceable event with the same kind being received, and signed by the same key, the old event SHOULD be discarded and replaced with the newer event.
Ephemeral Events
----------------

58
19.md Normal file
View File

@@ -0,0 +1,58 @@
NIP-19
======
bech32-encoded entities
-----------------------
`draft` `optional` `author:jb55` `author:fiatjaf` `author:Semisol`
This NIP standardizes bech32-formatted strings that can be used to display keys, ids and other information in clients. These formats are not meant to be used anywhere in the core protocol, they are only meant for displaying to users, copy-pasting, sharing, rendering QR codes and inputting data.
It is recommended that ids and keys are stored in either hex or binary format, since these formats are closer to what must actually be used the core protocol.
## Bare keys and ids
To prevent confusion and mixing between private keys, public keys and event ids, which are all 32 byte strings. bech32-(not-m) encoding with different prefixes can be used for each of these entities.
These are the possible bech32 prefixes:
- `npub`: public keys
- `nsec`: private keys
- `note`: note ids
Example: the hex public key `3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d` translates to `npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6`.
The bech32 encodings of keys and ids are not meant to be used inside the standard NIP-01 event formats or inside the filters, they're meant for human-friendlier display and input only. Clients should still accept keys in both hex and npub format for now, and convert internally.
## Shareable identifiers with extra metadata
When sharing a profile or an event, an app may decide to include relay information and other metadata such that other apps can locate and display these entities more easily.
For these events, the contents are a binary-encoded list of `TLV` (type-length-value), with `T` and `L` being 1 byte each (`uint8`, i.e. a number in the range of 0-255), and `V` being a sequence of bytes of the size indicated by `L`.
These are the possible bech32 prefixes with `TLV`:
- `nprofile`: a nostr profile
- `nevent`: a nostr event
These possible standardized `TLV` types are indicated here:
- `0`: `special`
- depends on the bech32 prefix:
- for `nprofile` it will be the 32 bytes of the profile public key
- for `nevent` it will be the 32 bytes of the event id
- `1`: `relay`
- A relay in which the entity (profile or event) is more likely to be found, encoded as UTF-8. This may be included multiple times.
## Examples
- `npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6` should decode into the public key hex `3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d` and vice-versa
- `nsec180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsgyumg0` should decode into the private key hex `3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d` and vice-versa
- `nprofile1qqsrhuxx8l9ex335q7he0f09aej04zpazpl0ne2cgukyawd24mayt8gpp4mhxue69uhhytnc9e3k7mgpz4mhxue69uhkg6nzv9ejuumpv34kytnrdaksjlyr9p` should decode into a profile with the following TLV items:
- pubkey: `3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d`
- relay: `wss://r.x.com`
- relay: `wss://djbas.sadkb.com`
## Notes
- `npub` keys MUST NOT be used in NIP-01 events or in NIP-05 JSON responses, only the hex format is supported there.

93
20.md Normal file
View File

@@ -0,0 +1,93 @@
NIP-20
======
Command Results
---------------
`draft` `optional` `author:jb55`
When submitting events to relays, clients currently have no way to know if an event was successfully committed to the database. This NIP introduces the concept of command results which are like NOTICE's except provide more information about if an event was accepted or rejected.
A command result is a JSON object with the following structure that is returned when an event is successfully saved to the database or rejected:
["OK", <event_id>, <true|false>, <message>]
Relays MUST return `true` when the event is a duplicate and has already been saved. The `message` SHOULD start with `duplicate:` in this case.
Relays MUST return `false` when the event was rejected and not saved.
The `message` SHOULD provide additional information as to why the command succeeded or failed.
The `message` SHOULD start with `blocked:` if the pubkey or network address has been blocked, banned, or is not on a whitelist.
The `message` SHOULD start with `invalid:` if the event is invalid or doesn't meet some specific criteria (created_at is too far off, id is wrong, signature is wrong, etc)
The `message` SHOULD start with `pow:` if the event doesn't meet some proof-of-work difficulty. The client MAY consult the relay metadata at this point to retrieve the required posting difficulty.
The `message` SHOULD start with `rate-limited:` if the event was rejected due to rate limiting techniques.
The `message` SHOULD start with `error:` if the event failed to save due to a server issue.
Ephemeral events are not acknowledged with OK responses, unless there is a failure.
If the event or `EVENT` command is malformed and could not be parsed, a NOTICE message SHOULD be used instead of a command result. This NIP only applies to non-malformed EVENT commands.
Examples
--------
Event successfully written to the database:
["OK", "b1a649ebe8b435ec71d3784793f3bbf4b93e64e17568a741aecd4c7ddeafce30", true, ""]
Event successfully written to the database because of a reason:
["OK", "b1a649ebe8b435ec71d3784793f3bbf4b93e64e17568a741aecd4c7ddeafce30", true, "pow: difficulty 25>=24"]
Event blocked due to ip filter
["OK", "b1a649ebe8...", false, "blocked: tor exit nodes not allowed"]
Event blocked due to pubkey ban
["OK", "b1a649ebe8...", false, "blocked: you are banned from posting here"]
Event blocked, pubkey not registered
["OK", "b1a649ebe8...", false, "blocked: please register your pubkey at https://my-expensive-relay.example.com"]
Event rejected, rate limited
["OK", "b1a649ebe8...", false, "rate-limited: slow down there chief"]
Event rejected, `created_at` too far off
["OK", "b1a649ebe8...", false, "invalid: event creation date is too far off from the current time. Is your system clock in sync?"]
Event rejected, insufficient proof-of-work difficulty
["OK", "b1a649ebe8...", false, "pow: difficulty 26 is less than 30"]
Event failed to save,
["OK", "b1a649ebe8...", false, "error: could not connect to the database"]
Client Handling
---------------
`messages` are meant for humans, with `reason:` prefixes so that clients can be slightly more intelligent with what to do with them. For example, with a `rate-limited:` reason the client may not show anything and simply try again with a longer timeout.
For the `pow:` prefix it may query relay metadata to get the updated difficulty requirement and try again in the background.
For the `invalid:` and `blocked`: prefix the client may wish to show these as styled error popups.
The prefixes include a colon so that the message can be cleanly separated from the prefix by taking everything after `:` and trimming it.
Future Extensions
-----------------
This proposal SHOULD be extended to support further commands in the future, such as REQ and AUTH. They are left out of this initial version to keep things simpler.

45
22.md Normal file
View File

@@ -0,0 +1,45 @@
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 [NIP-20](20.md) command result 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 notification 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.
Keep in mind that there is a use case where a user migrates their old posts onto a new relay. If a relay rejects events that were not recently created, it cannot serve this use case.
Python (pseudocode) Example
---------------------------
```python
import time
TIME = int(time.time())
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):
ws.send('["OK", event.id, False, "invalid: the event created_at field is out of the acceptable range (-24h, +15min) for this relay"]')
```
Note: These are just example limits, the relay operator can choose whatever limits they want.

8
25.md
View File

@@ -7,18 +7,18 @@ Reactions
`draft` `optional` `author:jb55`
A reaction is a `kind 7` note that is used to react to `kind 1` text notes.
A reaction is a `kind 7` note that is used to react to other notes.
The generic reaction, represented by the `content` set to a `+` string, SHOULD
be interpreted as a "like" or "upvote".
A reaction with `content` set to `-` SHOULD be interepreted as a "dislike" or
A reaction with `content` set to `-` SHOULD be interpreted as a "dislike" or
"downvote". It SHOULD NOT be counted as a "like", and MAY be displayed as a
downvote or dislike on a post. A client MAY also choose to tally likes against
dislikes in a reddit-like system of upvotes and downvotes, or display them as
separate tallys.
The `content` MAY be an emoji, in this case it MAY be interpreted as a "like",
The `content` MAY be an emoji, in this case it MAY be interpreted as a "like" or "dislike",
or the client MAY display this emoji reaction on the post.
Tags
@@ -42,7 +42,7 @@ func make_like_event(pubkey: String, privkey: String, liked: NostrEvent) -> Nost
}
tags.append(["e", liked.id])
tags.append(["p", liked.pubkey])
let ev = NostrEvent(content: "", pubkey: pubkey, kind: 7, tags: tags)
let ev = NostrEvent(content: "+", pubkey: pubkey, kind: 7, tags: tags)
ev.calculate_id()
ev.sign(privkey: privkey)
return ev

84
26.md Normal file
View File

@@ -0,0 +1,84 @@
NIP: 26
=======
Delegated Event Signing
-----
`draft` `optional` `author:markharding` `author:minds`
This NIP defines how events can be delegated so that they can be signed by other keypairs.
Another application of this proposal is to abstract away the use of the 'root' keypairs when interacting with clients. For example, a user could generate new keypairs for each client they wish to use and authorize those keypairs to generate events on behalf of their root pubkey, where the root keypair is stored in cold storage.
#### Introducing the 'delegation' tag
This NIP introduces a new tag: `delegation` which is formatted as follows:
```json
[
"delegation",
<pubkey of the delegator>,
<conditions query string>,
<64-bytes schnorr signature of the sha256 hash of the delegation token>
]
```
##### Delegation Token
The **delegation token** should be a 64-byte Schnorr signature of the sha256 hash of the following string:
```
nostr:delegation:<pubkey of publisher (delegatee)>:<conditions query string>
```
#### Example
```
# Delegator:
privkey: ee35e8bb71131c02c1d7e73231daa48e9953d329a4b701f7133c8f46dd21139c
pubkey: 8e0d3d3eb2881ec137a11debe736a9086715a8c8beeeda615780064d68bc25dd
# Delegatee:
privkey: 777e4f60b4aa87937e13acc84f7abcc3c93cc035cb4c1e9f7a9086dd78fffce1
pubkey: 477318cfb5427b9cfc66a9fa376150c1ddbc62115ae27cef72417eb959691396
```
Delegation string to grant note publishing authorization to the delegatee (477318cf) for the next 30 days.
```json
nostr:delegation:477318cfb5427b9cfc66a9fa376150c1ddbc62115ae27cef72417eb959691396:kind=1&created_at<1675721885
```
The delegator (8e0d3d3e) then signs the above delegation string, the result of which is the delegation token:
```
cbc49c65fe04a3181d72fb5a9f1c627e329d5f45d300a2dfed1c3e788b7834dad48a6d27d8e244af39c77381334ede97d4fd15abe80f35fda695fd9bd732aa1e
```
The delegatee (477318cf) can now construct an event on behalf of the delegator (8e0d3d3e). The delegatee then signs the event with its own private key and publishes.
```json
{
"id": "ac4c71e69c39b1bd605de812543ebfaf81d5af365354f061d48981fb61e00b8a",
"pubkey": "477318cfb5427b9cfc66a9fa376150c1ddbc62115ae27cef72417eb959691396",
"created_at": 1673129661,
"kind": 1,
"tags": [
[
"delegation",
"8e0d3d3eb2881ec137a11debe736a9086715a8c8beeeda615780064d68bc25dd",
"kind=1&created_at<1675721813",
"cbc49c65fe04a3181d72fb5a9f1c627e329d5f45d300a2dfed1c3e788b7834dad48a6d27d8e244af39c77381334ede97d4fd15abe80f35fda695fd9bd732aa1e"
]
],
"content": "Hello, world!",
"sig": "55ed9a78d6449b8c189b6dbc34bc4bcd34dcc79e6da6c9078268fe3d7c0cbe62b1b907ffb76ba591e83895b1329bf2e6e16f3b0cd5827272e420d419c6f0f0b5"
}
```
The event should be considered a valid delegation if the conditions are satisfied (`kind=1` and `created_at<1675721813` in this example) and, upon validation of the delegation token, are found to be unchanged from the conditions in the original delegation string.
Clients should display the delegated note as if it was published directly by the delegator (8e0d3d3e).
#### Relay & Client Querying Support
Relays should answer requests such as `["REQ", "", {"authors": ["A"]}]` by querying both the `pubkey` and delegation tags `[1]` value.

158
28.md Normal file
View File

@@ -0,0 +1,158 @@
NIP-28
======
Public Chat
-----------
`draft` `optional` `author:ChristopherDavid` `author:fiatjaf` `author:jb55` `author:Cameri`
This NIP defines new event kinds for public chat channels, channel messages, and basic client-side moderation.
It reserves five event kinds (40-44) for immediate use and five event kinds (45-49) for future use.
- `40 - channel create`
- `41 - channel metadata`
- `42 - channel message`
- `43 - hide message`
- `44 - mute user`
Client-centric moderation gives client developers discretion over what types of content they want included in their apps, while imposing no additional requirements on relays.
## Kind 40: Create channel
Create a public chat channel.
In the channel creation `content` field, Client SHOULD include basic channel metadata (`name`, `about`, `picture` as specified in kind 41).
```json
{
"content": "{\"name\": \"Demo Channel\", \"about\": \"A test channel.\", \"picture\": \"https://placekitten.com/200/200\"}",
...
}
```
## Kind 41: Set channel metadata
Update a channel's public metadata.
Clients and relays SHOULD handle kind 41 events similar to kind 0 `metadata` events.
Clients SHOULD ignore kind 41s from pubkeys other than the kind 40 pubkey.
Clients SHOULD support basic metadata fields:
- `name` - string - Channel name
- `about` - string - Channel description
- `picture` - string - URL of channel picture
Clients MAY add additional metadata fields.
Clients SHOULD use [NIP-10](10.md) marked "e" tags to recommend a relay.
```json
{
"content": "{\"name\": \"Updated Demo Channel\", \"about\": \"Updating a test channel.\", \"picture\": \"https://placekitten.com/201/201\"}",
"tags": [["e", <channel_create_event_id> <relay-url>]],
...
}
```
## Kind 42: Create channel message
Send a text message to a channel.
Clients SHOULD use [NIP-10](10.md) marked "e" tags to recommend a relay and specify whether it is a reply or root message.
Clients SHOULD append [NIP-10](10.md) "p" tags to replies.
Root message:
```json
{
"content": <string>,
"tags": [["e", <kind_40_event_id> <relay-url> "root"]],
...
}
```
Reply to another message:
```json
{
"content": <string>,
"tags": [
["e", <kind_42_event_id> <relay-url> "reply"],
["p", <pubkey> <relay-url>],
...
],
...
}
```
## Kind 43: Hide message
User no longer wants to see a certain message.
The `content` may optionally include metadata such as a `reason`.
Clients SHOULD hide event 42s shown to a given user, if there is an event 43 from that user matching the event 42 `id`.
Clients MAY hide event 42s for other users other than the user who sent the event 43.
(For example, if three users 'hide' an event giving a reason that includes the word 'pornography', a Nostr client that is an iOS app may choose to hide that message for all iOS clients.)
```json
{
"content": "{\"reason\": \"Dick pic\"}",
"tags": [["e", <kind_42_event_id>]],
...
}
```
## Kind 44: Mute user
User no longer wants to see messages from another user.
The `content` may optionally include metadata such as a `reason`.
Clients SHOULD hide event 42s shown to a given user, if there is an event 44 from that user matching the event 42 `pubkey`.
Clients MAY hide event 42s for users other than the user who sent the event 44.
```json
{
"content": "{\"reason\": \"Posting dick pics\"}",
"tags": [["p", <pubkey>]],
...
}
```
## NIP-10 relay recommendations
For [NIP-10](10.md) relay recommendations, clients generally SHOULD use the relay URL of the original (oldest) kind 40 event.
Clients MAY recommend any relay URL. For example, if a relay hosting the original kind 40 event for a channel goes offline, clients could instead fetch channel data from a backup relay, or a relay that clients trust more than the original relay.
Future extensibility
--------------------
We reserve event kinds 45-49 for other events related to chat, to potentially include new types of media (photo/video), moderation, or support of private or group messaging.
Motivation
----------
If we're solving censorship-resistant communication for social media, we may as well solve it also for Telegram-style messaging.
We can bring the global conversation out from walled gardens into a true public square open to all.
Additional info
---------------
- [Chat demo PR with fiatjaf+jb55 comments](https://github.com/ArcadeCity/arcade/pull/28)
- [Conversation about NIP16](https://t.me/nostr_protocol/29566)

32
33.md Normal file
View File

@@ -0,0 +1,32 @@
NIP-33
======
Parameterized Replaceable Events
--------------------------------
`draft` `optional` `author:Semisol` `author:Kukks` `author:Cameri` `author:Giszmo`
This NIP adds a new event range that allows for replacement of events that have the same `d` tag and kind unlike NIP-16 which only replaced by kind.
Implementation
--------------
A *parameterized replaceable event* is defined as an event with a kind `30000 <= n < 40000`.
Upon a parameterized replaceable event with a newer timestamp than the currently known latest
replaceable event with the same kind and first `d` tag value being received, the old event
SHOULD be discarded and replaced with the newer event.
A missing or a `d` tag with no value should be interpreted equivalent to a `d` tag with the
value as an empty string. Events from the same author with any of the following `tags`
replace each other:
* `"tags":[["d",""]]`
* `"tags":[]`: implicit `d` tag with empty value
* `"tags":[["d"]]`: implicit empty value `""`
* `"tags":[["d",""],["d","not empty"]]`: only first `d` tag is considered
* `"tags":[["d"],["d","some value"]]`: only first `d` tag is considered
* `"tags":[["e"]]`: same as no tags
Client Behavior
---------------
Clients SHOULD use the `supported_nips` field to learn if a relay supports this NIP.
Clients MAY send parameterized replaceable events to relays that may not support this NIP, and clients querying SHOULD be prepared for the relay to send multiple events and should use the latest one and are recommended to send a `#d` tag filter. Clients should account for the fact that missing `d` tags or ones with no value are not returned in tag filters, and are recommended to always include a `d` tag with a value.

34
36.md Normal file
View File

@@ -0,0 +1,34 @@
NIP-36
======
Sensitive Content / Content Warning
-----------------------------------
`draft` `optional` `author:fernandolguevara`
The `content-warning` tag enables users to specify if the event's content needs to be approved by readers to be shown.
Clients can hide the content until the user acts on it.
#### Spec
```
tag: content-warning
options:
- [reason]: optional
```
#### Example
```json
{
"pubkey": "<pub-key>",
"created_at": 1000000000,
"kind": 1,
"tags": [
["t", "hastag"],
["content-warning", "reason"] /* reason is optional */
],
"content": "sensitive content with #hastag\n",
"id": "<event-id>"
}
```

59
40.md Normal file
View File

@@ -0,0 +1,59 @@
NIP-40
======
Expiration Timestamp
-----------------------------------
`draft` `optional` `author:0xtlt`
The `expiration` tag enables users to specify a unix timestamp at which the message SHOULD be considered expired (by relays and clients) and SHOULD be deleted by relays.
#### Spec
```
tag: expiration
values:
- [UNIX timestamp in seconds]: required
```
#### Example
```json
{
"pubkey": "<pub-key>",
"created_at": 1000000000,
"kind": 1,
"tags": [
["expiration", "1600000000"]
],
"content": "This message will expire at the specified timestamp and be deleted by relays.\n",
"id": "<event-id>"
}
```
Note: The timestamp should be in the same format as the created_at timestamp and should be interpreted as the time at which the message should be deleted by relays.
Client Behavior
---------------
Clients SHOULD use the `supported_nips` field to learn if a relay supports this NIP. Clients SHOULD NOT send expiration events to relays that do not support this NIP.
Clients SHOULD ignore events that have expired.
Relay Behavior
--------------
Relays MAY NOT delete an expired message immediately on expiration and MAY persist them indefinitely.
Relays SHOULD NOT send expired events to clients, even if they are stored.
Relays SHOULD drop any events that are published to them if they are expired.
An expiration timestamp does not affect storage of ephemeral events.
Suggested Use Cases
-------------------
* Temporary announcements - This tag can be used to make temporary announcements. For example, an event organizer could use this tag to post announcements about an upcoming event.
* Limited-time offers - This tag can be used by businesses to make limited-time offers that expire after a certain amount of time. For example, a business could use this tag to make a special offer that is only available for a limited time.
#### Warning
The events could be downloaded by third parties as they are publicly accessible all the time on the relays.
So don't consider expiring messages as a security feature for your conversations or other uses.

88
42.md Normal file
View File

@@ -0,0 +1,88 @@
NIP-42
======
Authentication of clients to relays
-----------------------------------
`draft` `optional` `author:Semisol` `author:fiatjaf`
This NIP defines a way for clients to authenticate to relays by signing an ephemeral event.
## Motivation
A relay may want to require clients to authenticate to access restricted resources. For example,
- A relay may request payment or other forms of whitelisting to publish events -- this can naïvely be achieved by limiting publication
to events signed by the whitelisted key, but with this NIP they may choose to accept any events as long as they are published from an
authenticated user;
- A relay may limit access to `kind: 4` DMs to only the parties involved in the chat exchange, and for that it may require authentication
before clients can query for that kind.
- A relay may limit subscriptions of any kind to paying users or users whitelisted through any other means, and require authentication.
## Definitions
This NIP defines a new message, `AUTH`, which relays can send when they support authentication and clients can send to relays when they want
to authenticate. When sent by relays, the message is of the following form:
```
["AUTH", <challenge-string>]
```
And, when sent by clients, of the following form:
```
["AUTH", <signed-event-json>]
```
The signed event is an ephemeral event not meant to be published or queried, it must be of `kind: 22242` and it should have at least two tags,
one for the relay URL and one for the challenge string as received from the relay.
Relays MUST exclude `kind: 22242` events from being broadcasted to any client.
`created_at` should be the current time. Example:
```json
{
"id": "...",
"pubkey": "...",
"created_at": 1669695536,
"kind": 22242,
"tags": [
["relay", "wss://relay.example.com/"],
["challenge", "challengestringhere"]
],
"content": "",
"sig": "..."
}
```
## Protocol flow
At any moment the relay may send an `AUTH` message to the client containing a challenge. After receiving that the client may decide to
authenticate itself or not. The challenge is expected to be valid for the duration of the connection or until a next challenge is sent by
the relay.
The client may send an auth message right before performing an action for which it knows authentication will be required -- for example, right
before requesting `kind: 4` chat messages --, or it may do right on connection start or at some other moment it deems best. The authentication
is expected to last for the duration of the WebSocket connection.
Upon receiving a message from an unauthenticated user it can't fulfill without authentication, a relay may choose to notify the client. For
that it can use a `NOTICE` or `OK` message with a standard prefix `"restricted: "` that is readable both by humans and machines, for example:
```
["NOTICE", "restricted: we can't serve DMs to unauthenticated users, does your client implement NIP-42?"]
```
or it can return an `OK` message noting the reason an event was not written using the same prefix:
```
["OK", <event-id>, false, "restricted: we do not accept events from unauthenticated users, please sign up at https://example.com/"]
```
## Signed Event Verification
To verify `AUTH` messages, relays must ensure:
- that the `kind` is `22242`;
- that the event `created_at` is close (e.g. within ~10 minutes) of the current time;
- that the `"challenge"` tag matches the challenge sent before;
- that the `"relay"` tag matches the relay URL:
- URL normalization techniques can be applied. For most cases just checking if the domain name is correct should be enough.

View File

@@ -18,29 +18,70 @@ 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-19: bech32-encoded entities](19.md)
- [NIP-20: Command Results](20.md)
- [NIP-22: Event created_at Limits](22.md)
- [NIP-25: Reactions](25.md)
- [NIP-26: Delegated Event Signing](26.md)
- [NIP-28: Public Chat](28.md)
- [NIP-33: Parametrized Replaceable Events](33.md)
- [NIP-36: Sensitive Content](36.md)
- [NIP-40: Expiration Timestamp](40.md)
- [NIP-42: Authentication of clients to relays](42.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 |
|-------------|---------------------------------|------------------------|
| 0 | Metadata | [1](01.md), [5](05.md) |
| 1 | Text | [1](01.md) |
| 2 | Recommend Relay | [1](01.md) |
| 3 | Contacts | [2](02.md) |
| 4 | Encrypted Direct Messages | [4](04.md) |
| 5 | Event Deletion | [9](09.md) |
| 7 | Reaction | [25](25.md) |
| 40 | Channel Creation | [28](28.md) |
| 41 | Channel Metadata | [28](28.md) |
| 42 | Channel Message | [28](28.md) |
| 43 | Channel Hide Message | [28](28.md) |
| 44 | Channel Mute User | [28](28.md) |
| 45-49 | Public Chat Reserved | [28](28.md) |
| 22242 | Client Authentication | [42](42.md) |
| 10000-19999 | Replaceable Events | [16](16.md) |
| 20000-29999 | Ephemeral Events | [16](16.md) |
| 30000-39999 | Parametrized Replaceable Events | [33](33.md) |
Please update this list when proposing NIPs introducing new event kinds.
## Message types
### Client to Relay
| type | description | NIP |
|-------|-----------------------------------------------------|-------------|
| EVENT | used to publish events | [1](01.md) |
| REQ | used to request events and subscribe to new updates | [1](01.md) |
| CLOSE | used to stop previous subscriptions | [1](01.md) |
| AUTH | used to send authentication events | [42](42.md) |
### Relay to Client
| type | description | NIP |
|--------|---------------------------------------------------------|-------------|
| EVENT | used to send events requested to clients | [1](01.md) |
| NOTICE | used to send human-readable messages to clients | [1](01.md) |
| EOSE | used to notify clients all stored events have been sent | [15](15.md) |
| OK | used to notify clients if an EVENT was successuful | [20](20.md) |
| AUTH | used to send authentication challenges | [42](42.md) |
Please update these lists when proposing NIPs introducing new event kinds.
When experimenting with kinds, keep in mind the classification introduced by [NIP-16](16.md).
## Criteria for acceptance of NIPs
1. They should be implemented somewhere at least as a prototype somewhere.
1. They should be implemented in at least two clients and one relay -- when applicable.
2. They should make sense.
3. Other rules will be made up when necessary.
3. They should be optional and backwards-compatible: care must be taken such that clients and relays that choose to not implement them do not stop working when interacting with the ones that choose to.
4. There should be no more than one way of doing the same thing.
5. Other rules will be made up when necessary.
## License