upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--01.md10
-rw-r--r--05.md13
-rw-r--r--07.md4
-rw-r--r--09.md30
-rw-r--r--13.md10
-rw-r--r--15.md16
-rw-r--r--17.md2
-rw-r--r--19.md5
-rw-r--r--21.md2
-rw-r--r--23.md2
-rw-r--r--24.md6
-rw-r--r--25.md20
-rw-r--r--27.md2
-rw-r--r--29.md19
-rw-r--r--32.md21
-rw-r--r--33.md2
-rw-r--r--34.md32
-rw-r--r--38.md2
-rw-r--r--39.md4
-rw-r--r--45.md8
-rw-r--r--46.md8
-rw-r--r--47.md2
-rw-r--r--51.md4
-rw-r--r--52.md23
-rw-r--r--53.md2
-rw-r--r--54.md12
-rw-r--r--57.md2
-rw-r--r--58.md2
-rw-r--r--64.md146
-rw-r--r--65.md2
-rw-r--r--70.md45
-rw-r--r--71.md2
-rw-r--r--72.md45
-rw-r--r--73.md48
-rw-r--r--75.md4
-rw-r--r--78.md2
-rw-r--r--96.md2
-rw-r--r--99.md10
-rw-r--r--BREAKING.md6
-rw-r--r--README.md235
40 files changed, 582 insertions, 230 deletions
diff --git a/01.md b/01.md
index d298046..9e50204 100644
--- a/01.md
+++ b/01.md
@@ -78,8 +78,8 @@ This NIP defines 3 standard tags that can be used across all event kinds with th
78- The `e` tag, used to refer to an event: `["e", <32-bytes lowercase hex of the id of another event>, <recommended relay URL, optional>]` 78- The `e` tag, used to refer to an event: `["e", <32-bytes lowercase hex of the id of another event>, <recommended relay URL, optional>]`
79- The `p` tag, used to refer to another user: `["p", <32-bytes lowercase hex of a pubkey>, <recommended relay URL, optional>]` 79- The `p` tag, used to refer to another user: `["p", <32-bytes lowercase hex of a pubkey>, <recommended relay URL, optional>]`
80- The `a` tag, used to refer to a (maybe parameterized) replaceable event 80- The `a` tag, used to refer to a (maybe parameterized) replaceable event
81 - for a parameterized replaceable event: `["a", <kind integer>:<32-bytes lowercase hex of a pubkey>:<d tag value>, <recommended relay URL, optional>]` 81 - for an addressable event: `["a", <kind integer>:<32-bytes lowercase hex of a pubkey>:<d tag value>, <recommended relay URL, optional>]`
82 - for a non-parameterized replaceable event: `["a", <kind integer>:<32-bytes lowercase hex of a pubkey>:, <recommended relay URL, optional>]` 82 - for a normal replaceable event: `["a", <kind integer>:<32-bytes lowercase hex of a pubkey>:, <recommended relay URL, optional>]`
83 83
84As a convention, all single-letter (only english alphabet letters: a-z, A-Z) key tags are expected to be indexed by relays, such that it is possible, for example, to query or subscribe to events that reference the event `"5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"` by using the `{"#e": ["5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"]}` filter. 84As a convention, all single-letter (only english alphabet letters: a-z, A-Z) key tags are expected to be indexed by relays, such that it is possible, for example, to query or subscribe to events that reference the event `"5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"` by using the `{"#e": ["5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"]}` filter.
85 85
@@ -125,8 +125,8 @@ Clients can send 3 types of messages, which must be JSON arrays, according to th
125 "authors": <a list of lowercase pubkeys, the pubkey of an event must be one of these>, 125 "authors": <a list of lowercase pubkeys, the pubkey of an event must be one of these>,
126 "kinds": <a list of a kind numbers>, 126 "kinds": <a list of a kind numbers>,
127 "#<single-letter (a-zA-Z)>": <a list of tag values, for #e — a list of event ids, for #p — a list of pubkeys, etc.>, 127 "#<single-letter (a-zA-Z)>": <a list of tag values, for #e — a list of event ids, for #p — a list of pubkeys, etc.>,
128 "since": <an integer unix timestamp in seconds, events must be newer than this to pass>, 128 "since": <an integer unix timestamp in seconds. Events must have a created_at >= to this to pass>,
129 "until": <an integer unix timestamp in seconds, events must be older than this to pass>, 129 "until": <an integer unix timestamp in seconds. Events must have a created_at <= to this to pass>,
130 "limit": <maximum number of events relays SHOULD return in the initial query> 130 "limit": <maximum number of events relays SHOULD return in the initial query>
131} 131}
132``` 132```
@@ -143,7 +143,7 @@ All conditions of a filter that are specified must match for an event for it to
143 143
144A `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. 144A `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.
145 145
146The `limit` property of a filter is only valid for the initial query and MUST be ignored afterwards. When `limit: n` is present it is assumed that the events returned in the initial query will be the last `n` events ordered by the `created_at`. 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. 146The `limit` property of a filter is only valid for the initial query and MUST be ignored afterwards. When `limit: n` is present it is assumed that the events returned in the initial query will be the last `n` events ordered by the `created_at`. Newer events should appear first, and in the case of ties the event with the lowest id (first in lexical order) should be first. 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.
147 147
148### From relay to client: sending events and notices 148### From relay to client: sending events and notices
149 149
diff --git a/05.md b/05.md
index a1d488d..eeca551 100644
--- a/05.md
+++ b/05.md
@@ -58,6 +58,15 @@ A client may implement support for finding users' public keys from _internet ide
58 58
59## Notes 59## Notes
60 60
61### Identification, not verification
62
63The NIP-05 is not intended to _verify_ a user, but only to _identify_ them, for the purpose of facilitating the exchange of a contact or their search.
64Exceptions are people who own (e.g., a company) or are connected (e.g., a project) to a well-known domain, who can exploit NIP-05 as an attestation of their relationship with it, and thus to the organization behind it, thereby gaining an element of trust.
65
66### User discovery implementation suggestion
67
68A client can 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.
69
61### Clients must always follow public keys, not NIP-05 addresses 70### Clients must always follow public keys, not NIP-05 addresses
62 71
63For 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). 72For 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).
@@ -66,10 +75,6 @@ For example, if after finding that `bob@bob.com` has the public key `abc...def`,
66 75
67Keys must be returned in hex format. Keys in NIP-19 `npub` format are only meant to be used for display in client UIs, not in this NIP. 76Keys must be returned in hex format. Keys in NIP-19 `npub` format are only meant to be used for display in client UIs, not in this NIP.
68 77
69### User Discovery implementation suggestion
70
71A 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.
72
73### Showing just the domain as an identifier 78### Showing just the domain as an identifier
74 79
75Clients 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. 80Clients 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.
diff --git a/07.md b/07.md
index 6c66322..9f836d8 100644
--- a/07.md
+++ b/07.md
@@ -24,6 +24,10 @@ async window.nostr.nip44.encrypt(pubkey, plaintext): string // returns ciphertex
24async window.nostr.nip44.decrypt(pubkey, ciphertext): string // takes ciphertext as specified in nip-44 24async window.nostr.nip44.decrypt(pubkey, ciphertext): string // takes ciphertext as specified in nip-44
25``` 25```
26 26
27### Recommendation to Extension Authors
28To make sure that the `window.nostr` is available to nostr clients on page load, the authors who create Chromium and Firefox extensions should load their scripts by specifying `"run_at": "document_end"` in the extension's manifest.
29
30
27### Implementation 31### Implementation
28 32
29See https://github.com/aljazceru/awesome-nostr#nip-07-browser-extensions. 33See https://github.com/aljazceru/awesome-nostr#nip-07-browser-extensions.
diff --git a/09.md b/09.md
index 5e79ac2..e1be542 100644
--- a/09.md
+++ b/09.md
@@ -1,16 +1,14 @@
1NIP-09 1NIP-09
2====== 2======
3 3
4Event Deletion 4Event Deletion Request
5-------------- 5--------------
6 6
7`draft` `optional` 7`draft` `optional`
8 8
9A special event with kind `5`, meaning "deletion" is defined as having a list of one or more `e` tags, each referencing an event the author is requesting to be deleted. 9A special event with kind `5`, meaning "deletion request" is defined as having a list of one or more `e` or `a` tags, each referencing an event the author is requesting to be deleted. Deletion requests SHOULD include a `k` tag for the kind of each event being requested for deletion.
10 10
11Each tag entry must contain an "e" event id and/or `a` tags intended for deletion. 11The event's `content` field MAY contain a text note describing the reason for the deletion request.
12
13The event's `content` field MAY contain a text note describing the reason for the deletion.
14 12
15For example: 13For example:
16 14
@@ -21,31 +19,35 @@ For example:
21 "tags": [ 19 "tags": [
22 ["e", "dcd59..464a2"], 20 ["e", "dcd59..464a2"],
23 ["e", "968c5..ad7a4"], 21 ["e", "968c5..ad7a4"],
24 ["a", "<kind>:<pubkey>:<d-identifier>"] 22 ["a", "<kind>:<pubkey>:<d-identifier>"],
23 ["k", "1"],
24 ["k", "30023"]
25 ], 25 ],
26 "content": "these posts were published by accident", 26 "content": "these posts were published by accident",
27 ...other fields 27 ...other fields
28} 28}
29``` 29```
30 30
31Relays SHOULD delete or stop publishing any referenced events that have an identical `pubkey` as the deletion request. Clients SHOULD hide or otherwise indicate a deletion status for referenced events. 31Relays SHOULD delete or stop publishing any referenced events that have an identical `pubkey` as the deletion request. Clients SHOULD hide or otherwise indicate a deletion request status for referenced events.
32 32
33Relays 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. 33Relays SHOULD continue to publish/share the deletion request events indefinitely, as clients may already have the event that's intended to be deleted. Additionally, clients SHOULD broadcast deletion request events to other relays which don't have it.
34 34
35When an `a` tag is used, relays SHOULD delete all versions of the replaceable event up to the `created_at` timestamp of the deletion event. 35When an `a` tag is used, relays SHOULD delete all versions of the replaceable event up to the `created_at` timestamp of the deletion request event.
36 36
37## Client Usage 37## Client Usage
38 38
39Clients 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. 39Clients MAY choose to fully hide any events that are referenced by valid deletion request 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 request reason, not the original content.
40 40
41A 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. 41A 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.
42 42
43Clients display the deletion event itself in any way they choose, e.g., not at all, or with a prominent notice. 43Clients display the deletion request event itself in any way they choose, e.g., not at all, or with a prominent notice.
44
45Clients MAY choose to inform the user that their request for deletion does not guarantee deletion because it is impossible to delete events from all relays and clients.
44 46
45## Relay Usage 47## Relay Usage
46 48
47Relays MAY validate that a deletion event only references events that have the same `pubkey` as the deletion itself, however this is not required since relays may not have knowledge of all referenced events. 49Relays MAY validate that a deletion request event only references events that have the same `pubkey` as the deletion request itself, however this is not required since relays may not have knowledge of all referenced events.
48 50
49## Deleting a Deletion 51## Deletion Request of a Deletion Request
50 52
51Publishing a deletion event against a deletion has no effect. Clients and relays are not obliged to support "undelete" functionality. 53Publishing a deletion request event against a deletion request has no effect. Clients and relays are not obliged to support "unrequest deletion" functionality.
diff --git a/13.md b/13.md
index 99289c2..0900d2d 100644
--- a/13.md
+++ b/13.md
@@ -103,16 +103,6 @@ function countLeadingZeroes(hex) {
103} 103}
104``` 104```
105 105
106Querying relays for PoW notes
107-----------------------------
108
109If relays allow searching on prefixes, you can use this as a way to filter notes of a certain difficulty:
110
111```
112$ echo '["REQ", "subid", {"ids": ["000000000"]}]' | websocat wss://some-relay.com | jq -c '.[2]'
113{"id":"000000000121637feeb68a06c8fa7abd25774bdedfa9b6ef648386fb3b70c387", ...}
114```
115
116Delegated Proof of Work 106Delegated Proof of Work
117----------------------- 107-----------------------
118 108
diff --git a/15.md b/15.md
index 55814fb..2a4e2c2 100644
--- a/15.md
+++ b/15.md
@@ -6,7 +6,7 @@ Nostr Marketplace
6 6
7`draft` `optional` 7`draft` `optional`
8 8
9Based on https://github.com/lnbits/Diagon-Alley. 9Based on [Diagon-Alley](https://github.com/lnbits/Diagon-Alley).
10 10
11Implemented in [NostrMarket](https://github.com/lnbits/nostrmarket) and [Plebeian Market](https://github.com/PlebeianTech/plebeian-market). 11Implemented in [NostrMarket](https://github.com/lnbits/nostrmarket) and [Plebeian Market](https://github.com/PlebeianTech/plebeian-market).
12 12
@@ -139,7 +139,7 @@ Fields that are not self-explanatory:
139 139
140## Checkout events 140## Checkout events
141 141
142All checkout events are sent as JSON strings using ([NIP-04](https://github.com/nostr-protocol/nips/blob/master/04.md)). 142All checkout events are sent as JSON strings using [NIP-04](04.md).
143 143
144The `merchant` and the `customer` can exchange JSON messages that represent different actions. Each `JSON` message `MUST` have a `type` field indicating the what the JSON represents. Possible types: 144The `merchant` and the `customer` can exchange JSON messages that represent different actions. Each `JSON` message `MUST` have a `type` field indicating the what the JSON represents. Possible types:
145 145
@@ -150,7 +150,7 @@ The `merchant` and the `customer` can exchange JSON messages that represent diff
150| 2 | Merchant | Order Status Update | 150| 2 | Merchant | Order Status Update |
151 151
152### Step 1: `customer` order (event) 152### Step 1: `customer` order (event)
153The below JSON goes in content of [NIP-04](https://github.com/nostr-protocol/nips/blob/master/04.md). 153The below JSON goes in content of [NIP-04](04.md).
154 154
155```json 155```json
156{ 156{
@@ -182,7 +182,7 @@ _Open_: is `contact.nostr` required?
182 182
183Sent back from the merchant for payment. Any payment option is valid that the merchant can check. 183Sent back from the merchant for payment. Any payment option is valid that the merchant can check.
184 184
185The below JSON goes in `content` of [NIP-04](https://github.com/nostr-protocol/nips/blob/master/04.md). 185The below JSON goes in `content` of [NIP-04](04.md).
186 186
187`payment_options`/`type` include: 187`payment_options`/`type` include:
188 188
@@ -217,7 +217,7 @@ The below JSON goes in `content` of [NIP-04](https://github.com/nostr-protocol/n
217 217
218Once payment has been received and processed. 218Once payment has been received and processed.
219 219
220The below JSON goes in `content` of [NIP-04](https://github.com/nostr-protocol/nips/blob/master/04.md). 220The below JSON goes in `content` of [NIP-04](04.md).
221 221
222```json 222```json
223{ 223{
@@ -231,7 +231,7 @@ The below JSON goes in `content` of [NIP-04](https://github.com/nostr-protocol/n
231 231
232## Customize Marketplace 232## Customize Marketplace
233 233
234Create a customized user experience using the `naddr` from [NIP-19](https://github.com/nostr-protocol/nips/blob/master/19.md#shareable-identifiers-with-extra-metadata). The use of `naddr` enables easy sharing of marketplace events while incorporating a rich set of metadata. This metadata can include relays, merchant profiles, and more. Subsequently, it allows merchants to be grouped into a market, empowering the market creator to configure the marketplace's user interface and user experience, and share that marketplace. This customization can encompass elements such as market name, description, logo, banner, themes, and even color schemes, offering a tailored and unique marketplace experience. 234Create a customized user experience using the `naddr` from [NIP-19](19.md#shareable-identifiers-with-extra-metadata). The use of `naddr` enables easy sharing of marketplace events while incorporating a rich set of metadata. This metadata can include relays, merchant profiles, and more. Subsequently, it allows merchants to be grouped into a market, empowering the market creator to configure the marketplace's user interface and user experience, and share that marketplace. This customization can encompass elements such as market name, description, logo, banner, themes, and even color schemes, offering a tailored and unique marketplace experience.
235 235
236### Event `30019`: Create or update marketplace UI/UX 236### Event `30019`: Create or update marketplace UI/UX
237 237
@@ -300,7 +300,7 @@ This event leverages naddr to enable comprehensive customization and sharing of
300Bids are simply events of kind `1021` with a `content` field specifying the amount, in the currency of the auction. Bids must reference an auction. 300Bids are simply events of kind `1021` with a `content` field specifying the amount, in the currency of the auction. Bids must reference an auction.
301 301
302> [!NOTE] 302> [!NOTE]
303> Auctions can be edited as many times as desired (they are "parameterized replaceable events") by the author - even after the start_date, but they cannot be edited after they have received the first bid! This is enforced by the fact that bids reference the event ID of the auction (rather than the product UUID), which changes with every new version of the auctioned product. So a bid is always attached to one "version". Editing the auction after a bid would result in the new product losing the bid! 303> Auctions can be edited as many times as desired (they are "addressable events") by the author - even after the start_date, but they cannot be edited after they have received the first bid! This is enforced by the fact that bids reference the event ID of the auction (rather than the product UUID), which changes with every new version of the auctioned product. So a bid is always attached to one "version". Editing the auction after a bid would result in the new product losing the bid!
304 304
305### Event `1022`: Bid confirmation 305### Event `1022`: Bid confirmation
306 306
@@ -331,7 +331,7 @@ Another thing that can happen is - if bids happen very close to the end date of
331 331
332## Customer support events 332## Customer support events
333 333
334Customer support is handled over whatever communication method was specified. If communicating via nostr, NIP-04 is used https://github.com/nostr-protocol/nips/blob/master/04.md. 334Customer support is handled over whatever communication method was specified. If communicating via nostr, [NIP-04](04.md) is used.
335 335
336## Additional 336## Additional
337 337
diff --git a/17.md b/17.md
index 0f51367..d22dbde 100644
--- a/17.md
+++ b/17.md
@@ -102,7 +102,7 @@ Clients SHOULD publish kind `14` events to the `10050`-listed relays. If that is
102 102
103## Relays 103## Relays
104 104
105It's advisable that relays do not serve `kind:14` to clients other than the ones tagged in them. 105It's advisable that relays do not serve `kind:1059` to clients other than the ones tagged in them.
106 106
107It's advisable that users choose relays that conform to these practices. 107It's advisable that users choose relays that conform to these practices.
108 108
diff --git a/19.md b/19.md
index ef80887..3ea8e11 100644
--- a/19.md
+++ b/19.md
@@ -34,8 +34,8 @@ These are the possible bech32 prefixes with `TLV`:
34 34
35 - `nprofile`: a nostr profile 35 - `nprofile`: a nostr profile
36 - `nevent`: a nostr event 36 - `nevent`: a nostr event
37 - `nrelay`: a nostr relay
38 - `naddr`: a nostr _replaceable event_ coordinate 37 - `naddr`: a nostr _replaceable event_ coordinate
38 - `nrelay`: a nostr relay (deprecated)
39 39
40These possible standardized `TLV` types are indicated here: 40These possible standardized `TLV` types are indicated here:
41 41
@@ -43,8 +43,7 @@ These possible standardized `TLV` types are indicated here:
43 - depends on the bech32 prefix: 43 - depends on the bech32 prefix:
44 - for `nprofile` it will be the 32 bytes of the profile public key 44 - for `nprofile` it will be the 32 bytes of the profile public key
45 - for `nevent` it will be the 32 bytes of the event id 45 - for `nevent` it will be the 32 bytes of the event id
46 - for `nrelay`, this is the relay URL 46 - for `naddr`, it is the identifier (the `"d"` tag) of the event being referenced. For normal replaceable events use an empty string.
47 - for `naddr`, it is the identifier (the `"d"` tag) of the event being referenced. For non-parameterized replaceable events, use an empty string.
48- `1`: `relay` 47- `1`: `relay`
49 - for `nprofile`, `nevent` and `naddr`, _optionally_, a relay in which the entity (profile or event) is more likely to be found, encoded as ascii 48 - for `nprofile`, `nevent` and `naddr`, _optionally_, a relay in which the entity (profile or event) is more likely to be found, encoded as ascii
50 - this may be included multiple times 49 - this may be included multiple times
diff --git a/21.md b/21.md
index 6ed141a..988485d 100644
--- a/21.md
+++ b/21.md
@@ -10,7 +10,7 @@ This NIP standardizes the usage of a common URI scheme for maximum interoperabil
10 10
11The scheme is `nostr:`. 11The scheme is `nostr:`.
12 12
13The identifiers that come after are expected to be the same as those defined in [NIP-19](https://github.com/nostr-protocol/nips/blob/master/19.md) (except `nsec`). 13The identifiers that come after are expected to be the same as those defined in [NIP-19](19.md) (except `nsec`).
14 14
15## Examples 15## Examples
16 16
diff --git a/23.md b/23.md
index 382df83..d8fb51a 100644
--- a/23.md
+++ b/23.md
@@ -6,7 +6,7 @@ Long-form Content
6 6
7`draft` `optional` 7`draft` `optional`
8 8
9This NIP defines `kind:30023` (a _parameterized replaceable event_) for long-form text content, generally referred to as "articles" or "blog posts". `kind:30024` has the same structure as `kind:30023` and is used to save long form drafts. 9This NIP defines `kind:30023` (an _addressable event_) for long-form text content, generally referred to as "articles" or "blog posts". `kind:30024` has the same structure as `kind:30023` and is used to save long form drafts.
10 10
11"Social" clients that deal primarily with `kind:1` notes should not be expected to implement this NIP. 11"Social" clients that deal primarily with `kind:1` notes should not be expected to implement this NIP.
12 12
diff --git a/24.md b/24.md
index 3adec24..1afa7c7 100644
--- a/24.md
+++ b/24.md
@@ -39,5 +39,7 @@ tags
39 39
40These tags may be present in multiple event kinds. Whenever a different meaning is not specified by some more specific NIP, they have the following meanings: 40These tags may be present in multiple event kinds. Whenever a different meaning is not specified by some more specific NIP, they have the following meanings:
41 41
42 - `r`: a web URL the event is referring to in some way 42 - `r`: a web URL the event is referring to in some way.
43 - `title`: name of [NIP-51](51.md) sets, [NIP-52](52.md) calendar event, [NIP-53](53.md) live event or [NIP-99](99.md) listing 43 - `i`: an external id the event is referring to in some way - see [NIP-73](73.md).
44 - `title`: name of [NIP-51](51.md) sets, [NIP-52](52.md) calendar event, [NIP-53](53.md) live event or [NIP-99](99.md) listing.
45 - `t`: a hashtag. The value MUST be a lowercase string.
diff --git a/25.md b/25.md
index 17c203e..f038603 100644
--- a/25.md
+++ b/25.md
@@ -52,6 +52,26 @@ func make_like_event(pubkey: String, privkey: String, liked: NostrEvent) -> Nost
52} 52}
53``` 53```
54 54
55Reactions to a website
56---------------------
57
58If the target of the reaction is a website, the reaction MUST be a `kind 17` event and MUST include an `r` tag with the website's URL.
59
60```json
61{
62 "kind": 17,
63 "content": "⭐",
64 "tags": [
65 ["r", "https://example.com/"]
66 ],
67 ...other fields
68}
69```
70
71URLs SHOULD be [normalized](https://datatracker.ietf.org/doc/html/rfc3986#section-6), so that reactions to the same website are not omitted from queries.
72A fragment MAY be attached to the URL, to react to a section of the page.
73It should be noted that a URL with a fragment is not considered to be the same URL as the original.
74
55Custom Emoji Reaction 75Custom Emoji Reaction
56--------------------- 76---------------------
57 77
diff --git a/27.md b/27.md
index efd2c12..133f8ef 100644
--- a/27.md
+++ b/27.md
@@ -20,7 +20,7 @@ A reader client that receives an event with such `nostr:...` mentions in its `.c
20 20
21Suppose Bob is writing a note in a client that has search-and-autocomplete functionality for users that is triggered when they write the character `@`. 21Suppose Bob is writing a note in a client that has search-and-autocomplete functionality for users that is triggered when they write the character `@`.
22 22
23As Bob types `"hello @mat"` the client will prompt him to autocomplete with [mattn's profile](https://gateway.nostr.com/p/2c7cc62a697ea3a7826521f3fd34f0cb273693cbe5e9310f35449f43622a5cdc), showing a picture and name. 23As Bob types `"hello @mat"` the client will prompt him to autocomplete with [mattn's profile](https://njump.me/npub1937vv2nf06360qn9y8el6d8sevnndy7tuh5nzre4gj05xc32tnwqauhaj6), showing a picture and name.
24 24
25Bob presses "enter" and now he sees his typed note as `"hello @mattn"`, `@mattn` is highlighted, indicating that it is a mention. Internally, however, the event looks like this: 25Bob presses "enter" and now he sees his typed note as `"hello @mattn"`, `@mattn` is highlighted, indicating that it is a mention. Internally, however, the event looks like this:
26 26
diff --git a/29.md b/29.md
index 0f4a579..f867268 100644
--- a/29.md
+++ b/29.md
@@ -16,7 +16,7 @@ Normally a group will originally belong to one specific relay, but the community
16 16
17## Relay-generated events 17## Relay-generated events
18 18
19Relays are supposed to generate the events that describe group metadata and group admins. These are parameterized replaceable events signed by the relay keypair directly, with the group _id_ as the `d` tag. 19Relays are supposed to generate the events that describe group metadata and group admins. These are _addressable_ events signed by the relay keypair directly, with the group _id_ as the `d` tag.
20 20
21## Group identifier 21## Group identifier
22 22
@@ -93,6 +93,20 @@ Any user can send one of these events to the relay in order to be automatically
93} 93}
94``` 94```
95 95
96- *leave request* (`kind:9022`)
97
98Any user can send one of these events to the relay in order to be automatically removed from the group. The relay will automatically issue a `kind:9001` in response removing this user.
99
100```js
101{
102 "kind": 9022,
103 "content": "optional reason",
104 "tags": [
105 ["h", "<group-id>"]
106 ]
107}
108```
109
96- *moderation events* (`kinds:9000-9020`) (optional) 110- *moderation events* (`kinds:9000-9020`) (optional)
97 111
98Clients can send these events to a relay in order to accomplish a moderation action. Relays must check if the pubkey sending the event is capable of performing the given action. The relay may discard the event after taking action or keep it as a moderation log. 112Clients can send these events to a relay in order to accomplish a moderation action. Relays must check if the pubkey sending the event is capable of performing the given action. The relay may discard the event after taking action or keep it as a moderation log.
@@ -119,6 +133,8 @@ Each moderation action uses a different kind and requires different arguments, w
119| 9004 | `remove-permission` | `p` (pubkey), `permission` (name) | 133| 9004 | `remove-permission` | `p` (pubkey), `permission` (name) |
120| 9005 | `delete-event` | `e` (id hex) | 134| 9005 | `delete-event` | `e` (id hex) |
121| 9006 | `edit-group-status` | `public` or `private`, `open` or `closed` | 135| 9006 | `edit-group-status` | `public` or `private`, `open` or `closed` |
136| 9007 | `create-group` | |
137| 9008 | `delete-group` | |
122 138
123- *group metadata* (`kind:39000`) (optional) 139- *group metadata* (`kind:39000`) (optional)
124 140
@@ -159,6 +175,7 @@ The list of capabilities, as defined by this NIP, for now, is the following:
159- `add-permission` 175- `add-permission`
160- `remove-permission` 176- `remove-permission`
161- `edit-group-status` 177- `edit-group-status`
178- `delete-group`
162 179
163```js 180```js
164{ 181{
diff --git a/32.md b/32.md
index 79f5937..92d18eb 100644
--- a/32.md
+++ b/32.md
@@ -6,10 +6,9 @@ Labeling
6 6
7`draft` `optional` 7`draft` `optional`
8 8
9A label is a `kind 1985` event that is used to label other entities. This supports a number of use cases, 9This NIP defines two new indexable tags to label events and a new event kind (`kind:1985`) to attach those labels to existing events. This supports several use cases, including distributed moderation, collection management, license assignment, and content classification.
10including distributed moderation, collection management, license assignment, and content classification.
11 10
12This NIP introduces two new tags: 11New Tags:
13 12
14- `L` denotes a label namespace 13- `L` denotes a label namespace
15- `l` denotes a label 14- `l` denotes a label
@@ -129,10 +128,24 @@ is labeling their note as being related to Milan, Italy using ISO 3166-2.
129} 128}
130``` 129```
131 130
131Author is labeling their note language as English using ISO-639-1.
132
133```json
134{
135 "kind": 1,
136 "tags": [
137 ["L", "ISO-639-1"],
138 ["l", "en", "ISO-639-1"]
139 ],
140 "content": "English text",
141 ...
142}
143```
144
132Other Notes 145Other Notes
133----------- 146-----------
134 147
135When using this NIP to bulk-label many targets at once, events may be deleted and a replacement 148When using this NIP to bulk-label many targets at once, events may be requested for deletion using [NIP-09](09.md) and a replacement
136may be published. We have opted not to use parameterizable/replaceable events for this due to the 149may be published. We have opted not to use parameterizable/replaceable events for this due to the
137complexity in coming up with a standard `d` tag. In order to avoid ambiguity when querying, 150complexity in coming up with a standard `d` tag. In order to avoid ambiguity when querying,
138publishers SHOULD limit labeling events to a single namespace. 151publishers SHOULD limit labeling events to a single namespace.
diff --git a/33.md b/33.md
index 337a1f9..9c00d42 100644
--- a/33.md
+++ b/33.md
@@ -6,4 +6,4 @@ Parameterized Replaceable Events
6 6
7`final` `mandatory` 7`final` `mandatory`
8 8
9Moved to [NIP-01](01.md). 9Renamed to "Addressable events" and moved to [NIP-01](01.md).
diff --git a/34.md b/34.md
index fcc2cec..69f460b 100644
--- a/34.md
+++ b/34.md
@@ -35,6 +35,36 @@ The `r` tag annotated with the `"euc"` marker should be the commit ID of the ear
35 35
36Except `d`, all tags are optional. 36Except `d`, all tags are optional.
37 37
38## Repository state announcements
39
40An optional source of truth for the state of branches and tags in a repository.
41
42```jsonc
43{
44 "kind": 30618,
45 "content": "",
46 "tags": [
47 ["d", "<repo-id>"], // matches the identifier in the coresponding repository announcement
48 ["refs/<heads|tags>/<branch-or-tag-name>","<commit-id>"]
49 ["HEAD", "ref: refs/heads/<branch-name>"]
50 ]
51}
52```
53
54The `refs` tag may appear multiple times, or none.
55
56If no `refs` tags are present, the author is no longer tracking repository state using this event. This approach enables the author to restart tracking state at a later time unlike [NIP-09](09.md) deletion requests.
57
58The `refs` tag can be optionally extended to enable clients to identify how many commits ahead a ref is:
59
60```jsonc
61{
62 "tags": [
63 ["refs/<heads|tags>/<branch-or-tag-name>", "<commit-id>", "<shorthand-parent-commit-id>", "<shorthand-grandparent>", ...],
64 ]
65}
66```
67
38## Patches 68## Patches
39 69
40Patches can be sent by anyone to any repository. Patches to a specific repository SHOULD be sent to the relays specified in that repository's announcement event's `"relays"` tag. Patch events SHOULD include an `a` tag pointing to that repository's announcement address. 70Patches can be sent by anyone to any repository. Patches to a specific repository SHOULD be sent to the relays specified in that repository's announcement event's `"relays"` tag. Patch events SHOULD include an `a` tag pointing to that repository's announcement address.
@@ -53,7 +83,7 @@ The first patch revision in a patch revision SHOULD include a NIP-10 `e` `reply`
53 ["p", "<repository-owner>"], 83 ["p", "<repository-owner>"],
54 ["p", "<other-user>"], // optionally send the patch to another user to bring it to their attention 84 ["p", "<other-user>"], // optionally send the patch to another user to bring it to their attention
55 85
56 ["t", "root"], // ommited for additional patches in a series 86 ["t", "root"], // omitted for additional patches in a series
57 // for the first patch in a revision 87 // for the first patch in a revision
58 ["t", "root-revision"], 88 ["t", "root-revision"],
59 89
diff --git a/38.md b/38.md
index 4f2c06d..d841d76 100644
--- a/38.md
+++ b/38.md
@@ -13,7 +13,7 @@ This NIP enables a way for users to share live statuses such as what music they
13 13
14## Live Statuses 14## Live Statuses
15 15
16A special event with `kind:30315` "User Status" is defined as an *optionally expiring* _parameterized replaceable event_, where the `d` tag represents the status type: 16A special event with `kind:30315` "User Status" is defined as an *optionally expiring* _addressable event_, where the `d` tag represents the status type:
17 17
18For example: 18For example:
19 19
diff --git a/39.md b/39.md
index c819e43..b7c3b9c 100644
--- a/39.md
+++ b/39.md
@@ -12,9 +12,11 @@ Nostr protocol users may have other online identities such as usernames, profile
12 12
13## `i` tag on a metadata event 13## `i` tag on a metadata event
14 14
15A new optional `i` tag is introduced for `kind 0` metadata event contents in addition to name, about, picture fields as included in [NIP-01](https://github.com/nostr-protocol/nips/blob/master/01.md): 15A new optional `i` tag is introduced for `kind 0` metadata event defined in [NIP-01](01.md):
16```json 16```json
17{ 17{
18 "id": <id>,
19 "pubkey": <pubkey>,
18 "tags": [ 20 "tags": [
19 ["i", "github:semisol", "9721ce4ee4fceb91c9711ca2a6c9a5ab"], 21 ["i", "github:semisol", "9721ce4ee4fceb91c9711ca2a6c9a5ab"],
20 ["i", "twitter:semisol_public", "1619358434134196225"], 22 ["i", "twitter:semisol_public", "1619358434134196225"],
diff --git a/45.md b/45.md
index 780dfb6..6b25396 100644
--- a/45.md
+++ b/45.md
@@ -16,14 +16,14 @@ Some queries a client may want to execute against connected relays are prohibiti
16 16
17This NIP defines the verb `COUNT`, which accepts a subscription id and filters as specified in [NIP 01](01.md) for the verb `REQ`. Multiple filters are OR'd together and aggregated into a single count result. 17This NIP defines the verb `COUNT`, which accepts a subscription id and filters as specified in [NIP 01](01.md) for the verb `REQ`. Multiple filters are OR'd together and aggregated into a single count result.
18 18
19```json 19```
20["COUNT", <subscription_id>, <filters JSON>...] 20["COUNT", <subscription_id>, <filters JSON>...]
21``` 21```
22 22
23Counts are returned using a `COUNT` response in the form `{"count": <integer>}`. Relays may use probabilistic counts to reduce compute requirements. 23Counts are returned using a `COUNT` response in the form `{"count": <integer>}`. Relays may use probabilistic counts to reduce compute requirements.
24In case a relay uses probabilistic counts, it MAY indicate it in the response with `approximate` key i.e. `{"count": <integer>, "approximate": <true|false>}`. 24In case a relay uses probabilistic counts, it MAY indicate it in the response with `approximate` key i.e. `{"count": <integer>, "approximate": <true|false>}`.
25 25
26```json 26```
27["COUNT", <subscription_id>, {"count": <integer>}] 27["COUNT", <subscription_id>, {"count": <integer>}]
28``` 28```
29 29
@@ -33,14 +33,14 @@ Whenever the relay decides to refuse to fulfill the `COUNT` request, it MUST ret
33 33
34### Followers count 34### Followers count
35 35
36```json 36```
37["COUNT", <subscription_id>, {"kinds": [3], "#p": [<pubkey>]}] 37["COUNT", <subscription_id>, {"kinds": [3], "#p": [<pubkey>]}]
38["COUNT", <subscription_id>, {"count": 238}] 38["COUNT", <subscription_id>, {"count": 238}]
39``` 39```
40 40
41### Count posts and reactions 41### Count posts and reactions
42 42
43```json 43```
44["COUNT", <subscription_id>, {"kinds": [1, 7], "authors": [<pubkey>]}] 44["COUNT", <subscription_id>, {"kinds": [1, 7], "authors": [<pubkey>]}]
45["COUNT", <subscription_id>, {"count": 5}] 45["COUNT", <subscription_id>, {"count": 5}]
46``` 46```
diff --git a/46.md b/46.md
index 1528116..57fd2b0 100644
--- a/46.md
+++ b/46.md
@@ -28,7 +28,7 @@ The remote signer would provide a connection token in the form:
28bunker://<remote-user-pubkey>?relay=<wss://relay-to-connect-on>&relay=<wss://another-relay-to-connect-on>&secret=<optional-secret-value> 28bunker://<remote-user-pubkey>?relay=<wss://relay-to-connect-on>&relay=<wss://another-relay-to-connect-on>&secret=<optional-secret-value>
29``` 29```
30 30
31This token is pasted into the client by the user and the client then uses the details to connect to the remote signer via the specified relay(s). 31This token is pasted into the client by the user and the client then uses the details to connect to the remote signer via the specified relay(s). Optional secret can be used for single successfully established connection only, remote signer SHOULD ignore new attempts to establish connection with old optional secret.
32 32
33### Direct connection initiated by the client 33### Direct connection initiated by the client
34 34
@@ -101,7 +101,7 @@ nostrconnect://<local-keypair-pubkey>?relay=<wss://relay-to-connect-on>&metadata
101} 101}
102``` 102```
103 103
104The `content` field is a JSON-RPC-like message that is [NIP-04](https://github.com/nostr-protocol/nips/blob/master/04.md) encrypted and has the following structure: 104The `content` field is a JSON-RPC-like message that is [NIP-04](04.md) encrypted and has the following structure:
105 105
106```json 106```json
107{ 107{
@@ -148,7 +148,7 @@ The `connect` method may be provided with `optional_requested_permissions` for u
148} 148}
149``` 149```
150 150
151The `content` field is a JSON-RPC-like message that is [NIP-04](https://github.com/nostr-protocol/nips/blob/master/04.md) encrypted and has the following structure: 151The `content` field is a JSON-RPC-like message that is [NIP-04](04.md) encrypted and has the following structure:
152 152
153```json 153```json
154{ 154{
@@ -224,4 +224,4 @@ Coming soon...
224 224
225## References 225## References
226 226
227- [NIP-04 - Encryption](https://github.com/nostr-protocol/nips/blob/master/04.md) 227- [NIP-04 - Encryption](04.md)
diff --git a/47.md b/47.md
index 983d2c9..e4e432c 100644
--- a/47.md
+++ b/47.md
@@ -38,7 +38,7 @@ a plaintext string with the supported commands, space-separated, eg. `pay_invoic
38Both the request and response events SHOULD contain one `p` tag, containing the public key of the **wallet service** if this is a request, and the public key of the **user** if this is a response. The response event SHOULD contain an `e` tag with the id of the request event it is responding to. 38Both the request and response events SHOULD contain one `p` tag, containing the public key of the **wallet service** if this is a request, and the public key of the **user** if this is a response. The response event SHOULD contain an `e` tag with the id of the request event it is responding to.
39Optionally, a request can have an `expiration` tag that has a unix timestamp in seconds. If the request is received after this timestamp, it should be ignored. 39Optionally, a request can have an `expiration` tag that has a unix timestamp in seconds. If the request is received after this timestamp, it should be ignored.
40 40
41The content of requests and responses is encrypted with [NIP04](https://github.com/nostr-protocol/nips/blob/master/04.md), and is a JSON-RPCish object with a semi-fixed structure: 41The content of requests and responses is encrypted with [NIP04](04.md), and is a JSON-RPCish object with a semi-fixed structure:
42 42
43Request: 43Request:
44```jsonc 44```jsonc
diff --git a/51.md b/51.md
index fb40b26..f7a468e 100644
--- a/51.md
+++ b/51.md
@@ -16,7 +16,7 @@ When new items are added to an existing list, clients SHOULD append them to the
16 16
17## Standard lists 17## Standard lists
18 18
19Standard lists use non-parameterized replaceable events, meaning users may only have a single list of each kind. They have special meaning and clients may rely on them to augment a user's profile or browsing experience. 19Standard lists use normal replaceable events, meaning users may only have a single list of each kind. They have special meaning and clients may rely on them to augment a user's profile or browsing experience.
20 20
21For example, _mute list_ can contain the public keys of spammers and bad actors users don't want to see in their feeds or receive annoying notifications from. 21For example, _mute list_ can contain the public keys of spammers and bad actors users don't want to see in their feeds or receive annoying notifications from.
22 22
@@ -32,6 +32,7 @@ For example, _mute list_ can contain the public keys of spammers and bad actors
32| Simple groups | 10009 | [NIP-29](29.md) groups the user is in | `"group"` ([NIP-29](29.md) group ids + mandatory relay URL) | 32| Simple groups | 10009 | [NIP-29](29.md) groups the user is in | `"group"` ([NIP-29](29.md) group ids + mandatory relay URL) |
33| Interests | 10015 | topics a user may be interested in and pointers | `"t"` (hashtags) and `"a"` (kind:30015 interest set) | 33| Interests | 10015 | topics a user may be interested in and pointers | `"t"` (hashtags) and `"a"` (kind:30015 interest set) |
34| Emojis | 10030 | user preferred emojis and pointers to emoji sets | `"emoji"` (see [NIP-30](30.md)) and `"a"` (kind:30030 emoji set) | 34| Emojis | 10030 | user preferred emojis and pointers to emoji sets | `"emoji"` (see [NIP-30](30.md)) and `"a"` (kind:30030 emoji set) |
35| DM relays | 10050 | Where to receive [NIP-17](17.md) direct messages | `"relay"` (see [NIP-17](17.md)) |
35| Good wiki authors | 10101 | [NIP-54](54.md) user recommended wiki authors | `"p"` (pubkeys) | 36| Good wiki authors | 10101 | [NIP-54](54.md) user recommended wiki authors | `"p"` (pubkeys) |
36| Good wiki relays | 10102 | [NIP-54](54.md) relays deemed to only host useful articles | `"relay"` (relay URLs) | 37| Good wiki relays | 10102 | [NIP-54](54.md) relays deemed to only host useful articles | `"relay"` (relay URLs) |
37 38
@@ -50,6 +51,7 @@ Aside from their main identifier, the `"d"` tag, sets can optionally have a `"ti
50| Bookmark sets | 30003 | user-defined bookmarks categories , for when bookmarks must be in labeled separate groups | `"e"` (kind:1 notes), `"a"` (kind:30023 articles), `"t"` (hashtags), `"r"` (URLs) | 51| Bookmark sets | 30003 | user-defined bookmarks categories , for when bookmarks must be in labeled separate groups | `"e"` (kind:1 notes), `"a"` (kind:30023 articles), `"t"` (hashtags), `"r"` (URLs) |
51| Curation sets | 30004 | groups of articles picked by users as interesting and/or belonging to the same category | `"a"` (kind:30023 articles), `"e"` (kind:1 notes) | 52| Curation sets | 30004 | groups of articles picked by users as interesting and/or belonging to the same category | `"a"` (kind:30023 articles), `"e"` (kind:1 notes) |
52| Curation sets | 30005 | groups of videos picked by users as interesting and/or belonging to the same category | `"a"` (kind:34235 videos) | 53| Curation sets | 30005 | groups of videos picked by users as interesting and/or belonging to the same category | `"a"` (kind:34235 videos) |
54| Kind mute sets | 30007 | mute pubkeys by kinds<br>`"d"` tag MUST be the kind string | `"p"` (pubkeys) |
53| Interest sets | 30015 | interest topics represented by a bunch of "hashtags" | `"t"` (hashtags) | 55| Interest sets | 30015 | interest topics represented by a bunch of "hashtags" | `"t"` (hashtags) |
54| Emoji sets | 30030 | categorized emoji groups | `"emoji"` (see [NIP-30](30.md)) | 56| Emoji sets | 30030 | categorized emoji groups | `"emoji"` (see [NIP-30](30.md)) |
55| Release artifact sets | 30063 | groups of files of a software release | `"e"` (kind:1063 [file metadata](94.md) events), `"i"` (application identifier, typically reverse domain notation), `"version"` | 57| Release artifact sets | 30063 | groups of files of a software release | `"e"` (kind:1063 [file metadata](94.md) events), `"i"` (application identifier, typically reverse domain notation), `"version"` |
diff --git a/52.md b/52.md
index f35d904..c6d6b96 100644
--- a/52.md
+++ b/52.md
@@ -6,7 +6,7 @@ Calendar Events
6 6
7`draft` `optional` 7`draft` `optional`
8 8
9This specification defines calendar events representing an occurrence at a specific moment or between moments. These calendar events are _parameterized replaceable_ and deletable per [NIP-09](09.md). 9This specification defines calendar events representing an occurrence at a specific moment or between moments. These calendar events are _addressable_ and deletable per [NIP-09](09.md).
10 10
11Unlike the term `calendar event` specific to this NIP, the term `event` is used broadly in all the NIPs to describe any Nostr event. The distinction is being made here to discern between the two terms. 11Unlike the term `calendar event` specific to this NIP, the term `event` is used broadly in all the NIPs to describe any Nostr event. The distinction is being made here to discern between the two terms.
12 12
@@ -90,9 +90,12 @@ The list of tags are as follows:
90* `end` (optional) exclusive end Unix timestamp in seconds. If omitted, the calendar event ends instantaneously. 90* `end` (optional) exclusive end Unix timestamp in seconds. If omitted, the calendar event ends instantaneously.
91* `start_tzid` (optional) time zone of the start timestamp, as defined by the IANA Time Zone Database. e.g., `America/Costa_Rica` 91* `start_tzid` (optional) time zone of the start timestamp, as defined by the IANA Time Zone Database. e.g., `America/Costa_Rica`
92* `end_tzid` (optional) time zone of the end timestamp, as defined by the IANA Time Zone Database. e.g., `America/Costa_Rica`. If omitted and `start_tzid` is provided, the time zone of the end timestamp is the same as the start timestamp. 92* `end_tzid` (optional) time zone of the end timestamp, as defined by the IANA Time Zone Database. e.g., `America/Costa_Rica`. If omitted and `start_tzid` is provided, the time zone of the end timestamp is the same as the start timestamp.
93* `summary` (optional) brief description of the calendar event
94* `image` (optional) url of an image to use for the event
93* `location` (optional, repeated) location of the calendar event. e.g. address, GPS coordinates, meeting room name, link to video call 95* `location` (optional, repeated) location of the calendar event. e.g. address, GPS coordinates, meeting room name, link to video call
94* `g` (optional) [geohash](https://en.wikipedia.org/wiki/Geohash) to associate calendar event with a searchable physical location 96* `g` (optional) [geohash](https://en.wikipedia.org/wiki/Geohash) to associate calendar event with a searchable physical location
95* `p` (optional, repeated) 32-bytes hex pubkey of a participant, optional recommended relay URL, and participant's role in the meeting 97* `p` (optional, repeated) 32-bytes hex pubkey of a participant, optional recommended relay URL, and participant's role in the meeting
98* `l` (optional, repeated) label to categorize calendar event. e.g. `audiospace` to denote a scheduled event from a live audio space implementation such as cornychat.com
96* `t` (optional, repeated) hashtag to categorize calendar event 99* `t` (optional, repeated) hashtag to categorize calendar event
97* `r` (optional, repeated) references / links to web pages, documents, video calls, recorded videos, etc. 100* `r` (optional, repeated) references / links to web pages, documents, video calls, recorded videos, etc.
98 101
@@ -110,6 +113,8 @@ The following tags are deprecated:
110 ["d", "<UUID>"], 113 ["d", "<UUID>"],
111 114
112 ["title", "<title of calendar event>"], 115 ["title", "<title of calendar event>"],
116 ["summary", "<brief description of the calendar event>"],
117 ["image", "<string with image URI>"],
113 118
114 // Timestamps 119 // Timestamps
115 ["start", "<Unix timestamp in seconds>"], 120 ["start", "<Unix timestamp in seconds>"],
@@ -126,6 +131,10 @@ The following tags are deprecated:
126 ["p", "<32-bytes hex of a pubkey>", "<optional recommended relay URL>", "<role>"], 131 ["p", "<32-bytes hex of a pubkey>", "<optional recommended relay URL>", "<role>"],
127 ["p", "<32-bytes hex of a pubkey>", "<optional recommended relay URL>", "<role>"], 132 ["p", "<32-bytes hex of a pubkey>", "<optional recommended relay URL>", "<role>"],
128 133
134 // Labels (example using com.cornychat namespace denoting the event as an audiospace)
135 ["L", "com.cornychat"],
136 ["l", "audiospace", "com.cornychat"],
137
129 // Hashtags 138 // Hashtags
130 ["t", "<tag>"], 139 ["t", "<tag>"],
131 ["t", "<tag>"], 140 ["t", "<tag>"],
@@ -178,6 +187,10 @@ This NIP is intentionally not defining who is authorized to attend a calendar ev
178 187
179This NIP is also intentionally not defining what happens if a calendar event changes after an RSVP is submitted. 188This NIP is also intentionally not defining what happens if a calendar event changes after an RSVP is submitted.
180 189
190The RSVP MUST have an `a` tag of the event coordinates to the calendar event, and optionally an `e` tag of the id of the specific calendar event revision. If an `e` tag is present, clients SHOULD interpret it as an indication that the RSVP is a response to that revision of the calendar event, and MAY interpret it to not necessarily apply to other revisions of the calendar event.
191
192The RSVP MAY tag the author of the calendar event it is in response to using a `p` tag so that clients can easily query all RSVPs that pertain to the author.
193
181### Format 194### Format
182 195
183The format uses a parameterized replaceable event kind `31925`. 196The format uses a parameterized replaceable event kind `31925`.
@@ -185,10 +198,12 @@ The format uses a parameterized replaceable event kind `31925`.
185The `.content` of these events is optional and should be a free-form note that adds more context to this calendar event response. 198The `.content` of these events is optional and should be a free-form note that adds more context to this calendar event response.
186 199
187The list of tags are as follows: 200The list of tags are as follows:
188* `a` (required) reference tag to kind `31922` or `31923` calendar event being responded to. 201* `a` (required) coordinates to a kind `31922` or `31923` calendar event being responded to.
202* `e` (optional) event id of a kind `31922` or `31923` calendar event being responded to.
189* `d` (required) universally unique identifier. Generated by the client creating the calendar event RSVP. 203* `d` (required) universally unique identifier. Generated by the client creating the calendar event RSVP.
190* `status` (required) `accepted`, `declined`, or `tentative`. Determines attendance status to the referenced calendar event. 204* `status` (required) `accepted`, `declined`, or `tentative`. Determines attendance status to the referenced calendar event.
191* `fb` (optional) `free` or `busy`. Determines if the user would be free or busy for the duration of the calendar event. This tag must be omitted or ignored if the `status` label is set to `declined`. 205* `fb` (optional) `free` or `busy`. Determines if the user would be free or busy for the duration of the calendar event. This tag must be omitted or ignored if the `status` label is set to `declined`.
206* `p` (optional) pubkey of the author of the calendar event being responded to.
192 207
193```json 208```json
194{ 209{
@@ -198,10 +213,12 @@ The list of tags are as follows:
198 "kind": 31925, 213 "kind": 31925,
199 "content": "<note>", 214 "content": "<note>",
200 "tags": [ 215 "tags": [
201 ["a", "<31922 or 31923>:<calendar event author pubkey>:<d-identifier of calendar event>", "<optional relay url>"], 216 ["e", "<kind 31922 or 31923 event id", "<optional recommended relay URL>"]
217 ["a", "<31922 or 31923>:<calendar event author pubkey>:<d-identifier of calendar event>", "<optional recommended relay URL>"],
202 ["d", "<UUID>"], 218 ["d", "<UUID>"],
203 ["status", "<accepted/declined/tentative>"], 219 ["status", "<accepted/declined/tentative>"],
204 ["fb", "<free/busy>"], 220 ["fb", "<free/busy>"],
221 ["p", "<hex pubkey of kind 31922 or 31923 event>", "<optional recommended relay URL>"]
205 ] 222 ]
206} 223}
207``` 224```
diff --git a/53.md b/53.md
index 0b1cb81..15bdbc9 100644
--- a/53.md
+++ b/53.md
@@ -12,7 +12,7 @@ Service providers want to offer live activities to the Nostr network in such a w
12 12
13### Live Event 13### Live Event
14 14
15A special event with `kind:30311` "Live Event" is defined as a _parameterized replaceable event_ of public `p` tags. Each `p` tag SHOULD have a **displayable** marker name for the current role (e.g. `Host`, `Speaker`, `Participant`) of the user in the event and the relay information MAY be empty. This event will be constantly updated as participants join and leave the activity. 15A special event with `kind:30311` "Live Event" is defined as an _addressable event_ of public `p` tags. Each `p` tag SHOULD have a **displayable** marker name for the current role (e.g. `Host`, `Speaker`, `Participant`) of the user in the event and the relay information MAY be empty. This event will be constantly updated as participants join and leave the activity.
16 16
17For example: 17For example:
18 18
diff --git a/54.md b/54.md
index fe46918..cf22544 100644
--- a/54.md
+++ b/54.md
@@ -6,7 +6,7 @@ Wiki
6 6
7`draft` `optional` 7`draft` `optional`
8 8
9This NIP defines `kind:30818` (a _parameterized replaceable event_) for long-form text content similar to [NIP-23](23.md), but with one important difference: articles are meant to be descriptions, or encyclopedia entries, of particular subjects, and it's expected that multiple people will write articles about the exact same subjects, with either small variations or completely independent content. 9This NIP defines `kind:30818` (an _addressable event_) for long-form text content similar to [NIP-23](23.md), but with one important difference: articles are meant to be descriptions, or encyclopedia entries, of particular subjects, and it's expected that multiple people will write articles about the exact same subjects, with either small variations or completely independent content.
10 10
11Articles are identified by lowercase, normalized ascii `d` tags. 11Articles are identified by lowercase, normalized ascii `d` tags.
12 12
@@ -28,13 +28,13 @@ Articles are identified by lowercase, normalized ascii `d` tags.
28 28
29### Content rules 29### Content rules
30 30
31The content should be Markdown, following the same rules as of [NIP-23](23.md), although it takes some extra (optional) metadata tags: 31The content should be Asciidoc, following the same rules as of [NIP-23](23.md), although it takes some extra (optional) metadata tags:
32 32
33 - `title`: for when the display title should be different from the `d` tag. 33 - `title`: for when the display title should be different from the `d` tag.
34 - `summary`: for display in lists. 34 - `summary`: for display in lists.
35 - `a` and `e`: for referencing the original event a wiki article was forked from. 35 - `a` and `e`: for referencing the original event a wiki article was forked from.
36 36
37One extra functionality is added: **wikilinks**. Unlike normal Markdown links `[]()` that link to webpages, wikilinks `[[]]` link to other articles in the wiki. In this case, the wiki is the entirety of Nostr. Clicking on a wikilink should cause the client to ask relays for events with `d` tags equal to the target of that wikilink. 37One extra functionality is added: **wikilinks**. Unlike normal Asciidoc links `[]()` that link to webpages, wikilinks `[[]]` link to other articles in the wiki. In this case, the wiki is the entirety of Nostr. Clicking on a wikilink should cause the client to ask relays for events with `d` tags equal to the target of that wikilink.
38 38
39Wikilinks can take these two forms: 39Wikilinks can take these two forms:
40 40
@@ -86,12 +86,12 @@ This is a stronger signal of trust than a `+` reaction.
86 86
87This marker is useful when a user edits someone else's entry; if the original author includes the editor's changes and the editor doesn't want to keep/maintain an independent version, the `link` tag could effectively be a considered a "deletion" of the editor's version and putting that pubkey's WoT weight behind the original author's version. 87This marker is useful when a user edits someone else's entry; if the original author includes the editor's changes and the editor doesn't want to keep/maintain an independent version, the `link` tag could effectively be a considered a "deletion" of the editor's version and putting that pubkey's WoT weight behind the original author's version.
88 88
89Why Markdown? 89Why Asciidoc?
90------------- 90-------------
91 91
92If the idea is to make a wiki then the most obvious text format to use is probably the mediawiki/wikitext format used by Wikipedia since it's widely deployed in all mediawiki installations and used for decades with great success. However, it turns out that format is very bloated and convoluted, has way too many features and probably because of that it doesn't have many alternative implementations out there, and the ones that exist are not complete and don't look very trustworthy. Also it is very much a centralized format that can probably be changed at the whims of the Wikipedia owners. 92Wikitext is [garbage](nostr:nevent1qqsqt0gcggry60n72uglhuhypdlmr2dm6swjj69jex5v530gcpazlzsprpmhxue69uhhyetvv9ujumn0wdmksetjv5hxxmmdqy28wumn8ghj7un9d3shjtnyv9kh2uewd9hsygpm7rrrljungc6q0tuh5hj7ue863q73qlheu4vywtzwhx42a7j9n5ueneex) and Markdown is not powerful enough (besides being too freeform and unspecified and prone to generate incompatibilities in the future).
93 93
94On the other hand, Markdown has proven to work well for small scale wikis and one of the biggest wikis in the planet (which is not very often thought of as a wiki), [StackOverflow](https://stackoverflow.com) and its child sites, and also one of the biggest "personal wiki" software, [Obsidian](https://obsidian.md/). Markdown can probably deliver 95% of the functionality of wikitext. When augmented with tables, diagram generators and MathJax (which are common extensions that exist in the wild and can be included in this NIP) that rate probably goes to 99%, and its simplicity is a huge benefit that can't be overlooked. Wikitext format can also be transpíled into Markdown using Pandoc. Given all that, I think it's a reasonable suspicion that mediawiki is not inherently better than Markdown, the success of Wikipedia probably cannot be predicated on the syntax language choice. 94Asciidoc has a strict spec, multiple implementations in many languages, and support for features that are very much necessary in a wiki article, like _sidebars_, _tables_ (with rich markup inside cells), many levels of _headings_, _footnotes_, _superscript_ and _subscript_ markup and _description lists_. It is also arguably easier to read in its plaintext format than Markdown (and certainly much better than Wikitext).
95 95
96# Appendix 1: Merge requests 96# Appendix 1: Merge requests
97Users can request other users to get their entries merged into someone else's entry by creating a `kind:818` event. 97Users can request other users to get their entries merged into someone else's entry by creating a `kind:818` event.
diff --git a/57.md b/57.md
index d04eeff..1c0b314 100644
--- a/57.md
+++ b/57.md
@@ -36,7 +36,7 @@ A `zap request` is an event of kind `9734` that is _not_ published to relays, bu
36In addition, the event MAY include the following tags: 36In addition, the event MAY include the following tags:
37 37
38- `e` is an optional hex-encoded event id. Clients MUST include this if zapping an event rather than a person. 38- `e` is an optional hex-encoded event id. Clients MUST include this if zapping an event rather than a person.
39- `a` is an optional event coordinate that allows tipping parameterized replaceable events such as NIP-23 long-form notes. 39- `a` is an optional event coordinate that allows tipping addressable events such as NIP-23 long-form notes.
40 40
41Example: 41Example:
42 42
diff --git a/58.md b/58.md
index 4a9ed4c..438574b 100644
--- a/58.md
+++ b/58.md
@@ -9,7 +9,7 @@ Badges
9Three special events are used to define, award and display badges in 9Three special events are used to define, award and display badges in
10user profiles: 10user profiles:
11 11
121. A "Badge Definition" event is defined as a parameterized replaceable event with kind `30009` having a `d` tag with a value that uniquely identifies the badge (e.g. `bravery`) published by the badge issuer. Badge definitions can be updated. 121. A "Badge Definition" event is defined as an addressable event with kind `30009` having a `d` tag with a value that uniquely identifies the badge (e.g. `bravery`) published by the badge issuer. Badge definitions can be updated.
13 13
142. A "Badge Award" event is a kind `8` event with a single `a` tag referencing a "Badge Definition" event and one or more `p` tags, one for each pubkey the badge issuer wishes to award. Awarded badges are immutable and non-transferrable. 142. A "Badge Award" event is a kind `8` event with a single `a` tag referencing a "Badge Definition" event and one or more `p` tags, one for each pubkey the badge issuer wishes to award. Awarded badges are immutable and non-transferrable.
15 15
diff --git a/64.md b/64.md
new file mode 100644
index 0000000..6d8d373
--- /dev/null
+++ b/64.md
@@ -0,0 +1,146 @@
1NIP-64
2======
3
4Chess (Portable Game Notation)
5-----
6
7`draft` `optional`
8
9This NIP defines `kind:64` notes representing chess games in [PGN][pgn_specification] format, which can be read by humans and is also supported by most chess software.
10
11## Note
12
13### Content
14
15The `.content` of these notes is a string representing a [PGN-database][pgn_formal_syntax].
16
17### Notes
18
19```json
20{
21 "kind": 64,
22 "content": "1. e4 *",
23 ...
24}
25```
26
27```json
28{
29 "kind": 64,
30 "tags": [
31 ["alt", "Fischer vs. Spassky in Belgrade on 1992-11-04 (F/S Return Match, Round 29)"],
32 ...
33 ],
34 "content": "[Event \"F/S Return Match\"]\n[Site \"Belgrade, Serbia JUG\"]\n[Date \"1992.11.04\"]\n[Round \"29\"]\n[White \"Fischer, Robert J.\"]\n[Black \"Spassky, Boris V.\"]\n[Result \"1/2-1/2\"]\n\n1. e4 e5 2. Nf3 Nc6 3. Bb5 {This opening is called the Ruy Lopez.} 3... a6\n4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 d6 8. c3 O-O 9. h3 Nb8 10. d4 Nbd7\n11. c4 c6 12. cxb5 axb5 13. Nc3 Bb7 14. Bg5 b4 15. Nb1 h6 16. Bh4 c5 17. dxe5\nNxe4 18. Bxe7 Qxe7 19. exd6 Qf6 20. Nbd2 Nxd6 21. Nc4 Nxc4 22. Bxc4 Nb6\n23. Ne5 Rae8 24. Bxf7+ Rxf7 25. Nxf7 Rxe1+ 26. Qxe1 Kxf7 27. Qe3 Qg5 28. Qxg5\nhxg5 29. b3 Ke6 30. a3 Kd6 31. axb4 cxb4 32. Ra5 Nd5 33. f3 Bc8 34. Kf2 Bf5\n35. Ra7 g6 36. Ra6+ Kc5 37. Ke1 Nf4 38. g3 Nxh3 39. Kd2 Kb5 40. Rd6 Kc5 41. Ra6\nNf2 42. g4 Bd3 43. Re6 1/2-1/2"
35 ...
36}
37```
38
39## Client Behavior
40
41Clients SHOULD display the content represented as chessboard.
42
43Clients SHOULD publish PGN notes in ["export format"][pgn_export_format] ("strict mode", i.e. created by machines) but expect incoming notes to be in ["import format"][pgn_import_format] ("lax mode", i.e. created by humans).
44
45Clients SHOULD check whether the formatting is valid and all moves comply with chess rules.
46
47Clients MAY include additional tags (e.g. like [`"alt"`](https://github.com/nostr-protocol/nips/blob/master/31.md)) in order to represent the note to users of non-supporting clients.
48
49## Relay Behavior
50
51Relays MAY validate PGN contents and reject invalid notes.
52
53
54## Examples
55
56```pgn
57// A game where nothing is known. Game still in progress, game abandoned, or result otherwise unknown.
58// Maybe players died before a move has been made.
59*
60```
61
62```pgn
631. e4 *
64```
65
66```pgn
67[White "Fischer, Robert J."]
68[Black "Spassky, Boris V."]
69
701. e4 e5 2. Nf3 Nc6 3. Bb5 {This opening is called the Ruy Lopez.} *
71```
72
73```pgn
74[Event "F/S Return Match"]
75[Site "Belgrade, Serbia JUG"]
76[Date "1992.11.04"]
77[Round "29"]
78[White "Fischer, Robert J."]
79[Black "Spassky, Boris V."]
80[Result "1/2-1/2"]
81
821. e4 e5 2. Nf3 Nc6 3. Bb5 {This opening is called the Ruy Lopez.} 3... a6
834. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 d6 8. c3 O-O 9. h3 Nb8 10. d4 Nbd7
8411. c4 c6 12. cxb5 axb5 13. Nc3 Bb7 14. Bg5 b4 15. Nb1 h6 16. Bh4 c5 17. dxe5
85Nxe4 18. Bxe7 Qxe7 19. exd6 Qf6 20. Nbd2 Nxd6 21. Nc4 Nxc4 22. Bxc4 Nb6
8623. Ne5 Rae8 24. Bxf7+ Rxf7 25. Nxf7 Rxe1+ 26. Qxe1 Kxf7 27. Qe3 Qg5 28. Qxg5
87hxg5 29. b3 Ke6 30. a3 Kd6 31. axb4 cxb4 32. Ra5 Nd5 33. f3 Bc8 34. Kf2 Bf5
8835. Ra7 g6 36. Ra6+ Kc5 37. Ke1 Nf4 38. g3 Nxh3 39. Kd2 Kb5 40. Rd6 Kc5 41. Ra6
89Nf2 42. g4 Bd3 43. Re6 1/2-1/2
90```
91
92```pgn
93[Event "Hourly HyperBullet Arena"]
94[Site "https://lichess.org/wxx4GldJ"]
95[Date "2017.04.01"]
96[White "T_LUKE"]
97[Black "decidement"]
98[Result "1-0"]
99[UTCDate "2017.04.01"]
100[UTCTime "11:56:14"]
101[WhiteElo "2047"]
102[BlackElo "1984"]
103[WhiteRatingDiff "+10"]
104[BlackRatingDiff "-7"]
105[Variant "Standard"]
106[TimeControl "30+0"]
107[ECO "B00"]
108[Termination "Abandoned"]
109
1101. e4 1-0
111
112
113[Event "Hourly HyperBullet Arena"]
114[Site "https://lichess.org/rospUdSk"]
115[Date "2017.04.01"]
116[White "Bastel"]
117[Black "oslochess"]
118[Result "1-0"]
119[UTCDate "2017.04.01"]
120[UTCTime "11:55:56"]
121[WhiteElo "2212"]
122[BlackElo "2000"]
123[WhiteRatingDiff "+6"]
124[BlackRatingDiff "-4"]
125[Variant "Standard"]
126[TimeControl "30+0"]
127[ECO "A01"]
128[Termination "Normal"]
129
1301. b3 d5 2. Bb2 c6 3. Nc3 Bf5 4. d4 Nf6 5. e3 Nbd7 6. f4 Bg6 7. Nf3 Bh5 8. Bd3 e6 9. O-O Be7 10. Qe1 O-O 11. Ne5 Bg6 12. Nxg6 hxg6 13. e4 dxe4 14. Nxe4 Nxe4 15. Bxe4 Nf6 16. c4 Bd6 17. Bc2 Qc7 18. f5 Be7 19. fxe6 fxe6 20. Qxe6+ Kh8 21. Qh3+ Kg8 22. Bxg6 Qd7 23. Qe3 Bd6 24. Bf5 Qe7 25. Be6+ Kh8 26. Qh3+ Nh7 27. Bf5 Rf6 28. Qxh7# 1-0
131```
132
133## Resources
134- [PGN Specification][pgn_specification]: PGN (Portable Game Notation) specification
135- [PGN Specification Supplement](https://github.com/mliebelt/pgn-spec-commented/blob/main/pgn-spec-supplement.md): Addition for adding graphical elements, clock values, eval, ...
136- [PGN Formal Syntax][pgn_formal_syntax]
137- [PGN Seven Tag Roster][pgn_seven_tag_roster]
138- [PGN Import Format][pgn_import_format]
139- [PGN Export Format][pgn_export_format]
140- [lichess / pgn-viewer (GitHub)](https://github.com/lichess-org/pgn-viewer): PGN viewer widget, designed to be embedded in content pages
141
142[pgn_specification]: https://github.com/mliebelt/pgn-spec-commented/blob/main/pgn-specification.md
143[pgn_formal_syntax]: https://github.com/mliebelt/pgn-spec-commented/blob/main/pgn-specification.md#18-formal-syntax
144[pgn_seven_tag_roster]: https://github.com/mliebelt/pgn-spec-commented/blob/main/pgn-specification.md#811-seven-tag-roster
145[pgn_import_format]: https://github.com/mliebelt/pgn-spec-commented/blob/main/pgn-specification.md#31-import-format-allows-for-manually-prepared-data
146[pgn_export_format]: https://github.com/mliebelt/pgn-spec-commented/blob/main/pgn-specification.md#32-export-format-used-for-program-generated-output
diff --git a/65.md b/65.md
index 1a2d7e8..f32c965 100644
--- a/65.md
+++ b/65.md
@@ -37,7 +37,7 @@ When seeking events **about** a user, where the user was tagged, Clients SHOULD
37When broadcasting an event, Clients SHOULD: 37When broadcasting an event, Clients SHOULD:
38 38
39- Broadcast the event to the WRITE relays of the author 39- Broadcast the event to the WRITE relays of the author
40- Broadcast the event all READ relays of each tagged user 40- Broadcast the event to all READ relays of each tagged user
41 41
42## Motivation 42## Motivation
43 43
diff --git a/70.md b/70.md
new file mode 100644
index 0000000..043d5fb
--- /dev/null
+++ b/70.md
@@ -0,0 +1,45 @@
1NIP-70
2======
3
4Protected Events
5----------------
6
7`draft` `optional`
8
9When the `"-"` tag is present, that means the event is "protected".
10
11A protected event is an event that can only be published to relays by its author. This is achieved by relays ensuring that the author is [authenticated](42.md) before publishing their own events or by just rejecting events with `["-"]` outright.
12
13The default behavior of a relay MUST be to reject any event that contains `["-"]`.
14
15Relays that want to accept such events MUST first require that the client perform the [NIP-42](42.md) `AUTH` flow and then check if the authenticated client has the same pubkey as the event being published and only accept the event in that case.
16
17## The tag
18
19The tag is a simple tag with a single item: `["-"]`. It may be added to any event.
20
21## Example flow
22
23- User `79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798` connects to relay `wss://example.com`:
24
25```jsonc
26/* client: */
27["EVENT",{"id":"cb8feca582979d91fe90455867b34dbf4d65e4b86e86b3c68c368ca9f9eef6f2","pubkey":"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798","created_at":1707409439,"kind":1,"tags":[["-"]],"content":"hello members of the secret group","sig":"fa163f5cfb75d77d9b6269011872ee22b34fb48d23251e9879bb1e4ccbdd8aaaf4b6dc5f5084a65ef42c52fbcde8f3178bac3ba207de827ec513a6aa39fa684c"}]
28/* relay: */
29["AUTH", "<challenge>"]
30["OK", "cb8feca582979d91fe90455867b34dbf4d65e4b86e86b3c68c368ca9f9eef6f2", false, "auth-required: this event may only be published by its author"]
31/* client: */
32["AUTH", {}]
33["EVENT",{"id":"cb8feca582979d91fe90455867b34dbf4d65e4b86e86b3c68c368ca9f9eef6f2","pubkey":"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798","created_at":1707409439,"kind":1,"tags":[["-"]],"content":"hello members of the secret group","sig":"fa163f5cfb75d77d9b6269011872ee22b34fb48d23251e9879bb1e4ccbdd8aaaf4b6dc5f5084a65ef42c52fbcde8f3178bac3ba207de827ec513a6aa39fa684c"}]
34["OK", "cb8feca582979d91fe90455867b34dbf4d65e4b86e86b3c68c368ca9f9eef6f2", true, ""]
35```
36
37## Why
38
39There are multiple circumstances in which it would be beneficial to prevent the unlimited spreading of an event through all relays imaginable and restrict some to only a certain demographic or to a semi-closed community relay. Even when the information is public it may make sense to keep it compartimentalized across different relays.
40
41It's also possible to create closed access feeds with this when the publisher has some relationship with the relay and trusts the relay to not release their published events to anyone.
42
43Even though it's ultimately impossible to restrict the spread of information on the internet (for example, one of the members of the closed group may want to take an event intended to be restricted and republish it to other relays), most relays would be happy to not facilitate the acts of these so-called "pirates", in respect to the original decision of the author and therefore gladly reject these republish acts if given the means to.
44
45This NIP gives these authors and relays the means to clearly signal when a given event is not intended to be republished by third parties.
diff --git a/71.md b/71.md
index a811434..be1587c 100644
--- a/71.md
+++ b/71.md
@@ -6,7 +6,7 @@ Video Events
6 6
7`draft` `optional` 7`draft` `optional`
8 8
9This specification defines video events representing a dedicated post of externally hosted content. These video events are _parameterized replaceable_ and deletable per [NIP-09](09.md). 9This specification defines video events representing a dedicated post of externally hosted content. These video events are _addressable_ and delete-requestable per [NIP-09](09.md).
10 10
11Unlike a `kind 1` event with a video attached, Video Events are meant to contain all additional metadata concerning the subject media and to be surfaced in video-specific clients rather than general micro-blogging clients. The thought is for events of this kind to be referenced in a Netflix, YouTube, or TikTok like nostr client where the video itself is at the center of the experience. 11Unlike a `kind 1` event with a video attached, Video Events are meant to contain all additional metadata concerning the subject media and to be surfaced in video-specific clients rather than general micro-blogging clients. The thought is for events of this kind to be referenced in a Netflix, YouTube, or TikTok like nostr client where the video itself is at the center of the experience.
12 12
diff --git a/72.md b/72.md
index 5a8be0a..b2f523b 100644
--- a/72.md
+++ b/72.md
@@ -6,11 +6,11 @@ Moderated Communities (Reddit Style)
6 6
7`draft` `optional` 7`draft` `optional`
8 8
9The goal of this NIP is to create moderator-approved public communities around a topic. It defines the replaceable event `kind:34550` to define the community and the current list of moderators/administrators. Users that want to post into the community, simply tag any Nostr event with the community's `a` tag. Moderators issue an approval event `kind:4550` that links the community with the new post. 9The goal of this NIP is to enable public communities. It defines the replaceable event `kind:34550` to define the community and the current list of moderators/administrators. Users that want to post into the community, simply tag any Nostr event with the community's `a` tag. Moderators may issue an approval event `kind:4550`.
10 10
11# Community Definition 11# Community Definition
12 12
13`kind:34550` SHOULD include any field that helps define the community and the set of moderators. `relay` tags MAY be used to describe the preferred relay to download requests and approvals. 13`Kind:34550` SHOULD include any field that helps define the community and the set of moderators. `relay` tags MAY be used to describe the preferred relay to download requests and approvals. A community definition event's `d` tag MAY double as its name, but if a `name` tag is provided, it SHOULD be displayed instead of the `d` tag.
14 14
15```jsonc 15```jsonc
16{ 16{
@@ -18,6 +18,7 @@ The goal of this NIP is to create moderator-approved public communities around a
18 "kind": 34550, 18 "kind": 34550,
19 "tags": [ 19 "tags": [
20 ["d", "<community-d-identifier>"], 20 ["d", "<community-d-identifier>"],
21 ["name", "<Community name>"],
21 ["description", "<Community description>"], 22 ["description", "<Community description>"],
22 ["image", "<Community image url>", "<Width>x<Height>"], 23 ["image", "<Community image url>", "<Width>x<Height>"],
23 24
@@ -38,9 +39,9 @@ The goal of this NIP is to create moderator-approved public communities around a
38} 39}
39``` 40```
40 41
41# New Post Request 42# Posting to a community
42 43
43Any Nostr event can be submitted to a community by anyone for approval. Clients MUST add the community's `a` tag to the new post event in order to be presented for the moderator's approval. 44Any Nostr event can be posted to a community. Clients MUST add one or more community `a` tags, each with a recommended relay.
44 45
45```jsonc 46```jsonc
46{ 47{
@@ -53,11 +54,15 @@ Any Nostr event can be submitted to a community by anyone for approval. Clients
53} 54}
54``` 55```
55 56
56Community management clients MAY filter all mentions to a given `kind:34550` event and request moderators to approve each submission. Moderators MAY delete his/her approval of a post at any time using event deletions (See [NIP-09](09.md)). 57# Moderation
57 58
58# Post Approval by moderators 59Anyone may issue an approval event to express their opinion that a post is appropriate for a community. Clients MAY choose which approval events to honor, but SHOULD at least use ones published by the group's defined moderators.
59 60
60The post-approval event MUST include `a` tags of the communities the moderator is posting into (one or more), the `e` tag of the post and `p` tag of the author of the post (for approval notifications). The event SHOULD also include the stringified `post request` event inside the `.content` ([NIP-18-style](18.md)) and a `k` tag with the original post's event kind to allow filtering of approved posts by kind. 61An approval event MUST include one or more community `a` tags, an `e` or `a` tag pointing to the post, and the `p` tag of the author of the post (for approval notifications). `a` tag prefixes can be used to disambiguate between community and replaceable event pointers (community `a` tags always begin with `34550`).
62
63The event SHOULD also include the JSON-stringified `post request` event inside the `.content`, and a `k` tag with the original post's event kind to allow filtering of approved posts by kind.
64
65Moderators MAY request deletion of their approval of a post at any time using [NIP-09 event deletion requests](09.md).
61 66
62```jsonc 67```jsonc
63{ 68{
@@ -76,26 +81,16 @@ The post-approval event MUST include `a` tags of the communities the moderator i
76 81
77It's recommended that multiple moderators approve posts to avoid deleting them from the community when a moderator is removed from the owner's list. In case the full list of moderators must be rotated, the new moderator set must sign new approvals for posts in the past or the community will restart. The owner can also periodically copy and re-sign of each moderator's approval events to make sure posts don't disappear with moderators. 82It's recommended that multiple moderators approve posts to avoid deleting them from the community when a moderator is removed from the owner's list. In case the full list of moderators must be rotated, the new moderator set must sign new approvals for posts in the past or the community will restart. The owner can also periodically copy and re-sign of each moderator's approval events to make sure posts don't disappear with moderators.
78 83
79Post Approvals of replaceable events can be created in three ways: (i) by tagging the replaceable event as an `e` tag if moderators want to approve each individual change to the replaceable event; (ii) by tagging the replaceable event as an `a` tag if the moderator authorizes the replaceable event author to make changes without additional approvals and (iii) by tagging the replaceable event with both its `e` and `a` tag which empowers clients to display the original and updated versions of the event, with appropriate remarks in the UI. Since relays are instructed to delete old versions of a replaceable event, the `.content` of an `e`-approval MUST have the specific version of the event or Clients might not be able to find that version of the content anywhere. 84Approvals of replaceable events can be created in three ways:
80 85
81Clients SHOULD evaluate any non-`34550:*` `a` tag as posts to be included in all `34550:*` `a` tags. 861. By tagging the replaceable event as an `e` tag if moderators want to approve each individual change to the replaceable event
872. By tagging the replaceable event as an `a` tag if the moderator authorizes the replaceable event author to make changes without additional approvals and
883. By tagging the replaceable event with both its `e` and `a` tag which empowers clients to display the original and updated versions of the event, with appropriate remarks in the UI.
82 89
83# Displaying 90Since relays are instructed to delete old versions of a replaceable event, the `content` of an approval using an `e` tag MUST have the specific version of the event or clients might not be able to find that version of the content anywhere.
84 91
85Community clients SHOULD display posts that have been approved by at least 1 moderator or by the community owner. 92Clients SHOULD evaluate any non-`34550:*` `a` tag as posts to be approved for all `34550:*` `a` tags.
86 93
87The following filter displays the approved posts. 94# Cross-posting
88
89```json
90[
91 "REQ",
92 "_",
93 {
94 "authors": ["<owner-pubkey>", "<moderator1-pubkey>", "<moderator2-pubkey>", "<moderator3-pubkey>", ...],
95 "kinds": [4550],
96 "#a": ["34550:<Community event author pubkey>:<d-identifier of the community>"],
97 }
98]
99```
100 95
101Clients MAY hide approvals by blocked moderators at the user's request. 96Clients MAY support cross-posting between communities by posting a NIP 18 `kind 6` or `kind 16` repost to one or more communities using `a` tags as described above. The `content` of the repost MUST be the original event, not the approval event.
diff --git a/73.md b/73.md
new file mode 100644
index 0000000..12228d3
--- /dev/null
+++ b/73.md
@@ -0,0 +1,48 @@
1NIP-73
2======
3
4External Content IDs
5-------------------------
6
7`draft` `optional`
8
9There are certain established global content identifiers that would be useful to reference in nostr events so that clients can query all events assosiated with these ids.
10
11- Book [ISBNs](https://en.wikipedia.org/wiki/ISBN)
12- Podcast [GUIDs](https://podcastnamespace.org/tag/guid)
13- Movie [ISANs](https://en.wikipedia.org/wiki/International_Standard_Audiovisual_Number)
14
15Since the `i` tag is already used for similar references in kind-0 metadata events it makes sense to use it for these content ids as well.
16
17
18## Supported IDs
19
20### Books:
21
22- Book ISBN: `["i", "isbn:9780765382030"]` - https://isbnsearch.org/isbn/9780765382030
23
24Book ISBNs MUST be referenced _**without hyphens**_ as many book search APIs return the ISBNs without hyphens. Removing hypens from ISBNs is trivial, whereas adding the hyphens back in is non-trivial requiring a library.
25
26### Podcasts:
27
28- Podcast RSS Feed GUID: `["i", "podcast:guid:c90e609a-df1e-596a-bd5e-57bcc8aad6cc"]` - https://podcastindex.org/podcast/c90e609a-df1e-596a-bd5e-57bcc8aad6cc
29- Podcast RSS Item GUID: `["i", "podcast:item:guid:d98d189b-dc7b-45b1-8720-d4b98690f31f"]`
30- Podcast RSS Publisher GUID: `["i", "podcast:publisher:guid:18bcbf10-6701-4ffb-b255-bc057390d738"]`
31
32### Movies:
33
34- Movie ISAN: `["i", "isan:0000-0000-401A-0000-7"]` - https://web.isan.org/public/en/isan/0000-0000-401A-0000-7
35
36Movie ISANs SHOULD be referenced _**without the version part**_ as the versions / edits of movies are not relevant. More info on ISAN parts here - https://support.isan.org/hc/en-us/articles/360002783131-Records-relations-and-hierarchies-in-the-ISAN-Registry
37
38---
39
40### Optional URL Hints
41
42Each `i` tag MAY have a url hint as the second argument to redirect people to a website if the client isn't opinionated about how to interpret the id:
43
44`["i", "podcast:item:guid:d98d189b-dc7b-45b1-8720-d4b98690f31f", https://fountain.fm/episode/z1y9TMQRuqXl2awyrQxg]`
45
46`["i", "isan:0000-0000-401A-0000-7", https://www.imdb.com/title/tt0120737]`
47
48
diff --git a/75.md b/75.md
index c16436a..a6f2bff 100644
--- a/75.md
+++ b/75.md
@@ -53,11 +53,11 @@ The following tags are OPTIONAL.
53} 53}
54``` 54```
55 55
56The goal MAY include an `r` or `a` tag linking to a URL or parameterized replaceable event. 56The goal MAY include an `r` or `a` tag linking to a URL or addressable event.
57 57
58The goal MAY include multiple beneficiary pubkeys by specifying [`zap` tags](57.md#appendix-g-zap-tag-on-other-events). 58The goal MAY include multiple beneficiary pubkeys by specifying [`zap` tags](57.md#appendix-g-zap-tag-on-other-events).
59 59
60Parameterized replaceable events can link to a goal by using a `goal` tag specifying the event id and an optional relay hint. 60Addressable events can link to a goal by using a `goal` tag specifying the event id and an optional relay hint.
61 61
62```json 62```json
63{ 63{
diff --git a/78.md b/78.md
index 0f2fada..abdd1b2 100644
--- a/78.md
+++ b/78.md
@@ -12,7 +12,7 @@ Even though interoperability is great, some apps do not want or do not need inte
12 12
13## Nostr event 13## Nostr event
14 14
15This NIP specifies the use of event kind `30078` (parameterized replaceable event) with a `d` tag containing some reference to the app name and context -- or any other arbitrary string. `content` and other `tags` can be anything or in any format. 15This NIP specifies the use of event kind `30078` (an _addressable_ event) with a `d` tag containing some reference to the app name and context -- or any other arbitrary string. `content` and other `tags` can be anything or in any format.
16 16
17## Some use cases 17## Some use cases
18 18
diff --git a/96.md b/96.md
index 2f25351..be70999 100644
--- a/96.md
+++ b/96.md
@@ -301,7 +301,7 @@ Example Response:
301 // ...other metadata 301 // ...other metadata
302 ] 302 ]
303 "content": "haha funny meme", // caption 303 "content": "haha funny meme", // caption
304 "created_at": 1715691130 // upload timestmap 304 "created_at": 1715691130 // upload timestamp
305 }, 305 },
306 ... 306 ...
307 ] 307 ]
diff --git a/99.md b/99.md
index 93550d8..b1b7ce9 100644
--- a/99.md
+++ b/99.md
@@ -6,11 +6,11 @@ Classified Listings
6 6
7`draft` `optional` 7`draft` `optional`
8 8
9This NIP defines `kind:30402`: a parameterized replaceable event to describe classified listings that list any arbitrary product, service, or other thing for sale or offer and includes enough structured metadata to make them useful. 9This NIP defines `kind:30402`: an addressable event to describe classified listings that list any arbitrary product, service, or other thing for sale or offer and includes enough structured metadata to make them useful.
10 10
11The category of classifieds includes a very broad range of physical goods, services, work opportunities, rentals, free giveaways, personals, etc. and is distinct from the more strictly structured marketplaces defined in [NIP-15](https://github.com/nostr-protocol/nips/blob/master/15.md) that often sell many units of specific products through very specific channels. 11The category of classifieds includes a very broad range of physical goods, services, work opportunities, rentals, free giveaways, personals, etc. and is distinct from the more strictly structured marketplaces defined in [NIP-15](15.md) that often sell many units of specific products through very specific channels.
12 12
13The structure of these events is very similar to [NIP-23](https://github.com/nostr-protocol/nips/blob/master/23.md) long-form content events. 13The structure of these events is very similar to [NIP-23](23.md) long-form content events.
14 14
15### Draft / Inactive Listings 15### Draft / Inactive Listings
16 16
@@ -26,8 +26,8 @@ The `.pubkey` field of these events are treated as the party creating the listin
26 26
27### Metadata 27### Metadata
28 28
29- For "tags"/"hashtags" (i.e. categories or keywords of relevance for the listing) the `"t"` event tag should be used, as per [NIP-12](https://github.com/nostr-protocol/nips/blob/master/12.md). 29- For "tags"/"hashtags" (i.e. categories or keywords of relevance for the listing) the `"t"` event tag should be used, as per [NIP-12](12.md).
30- For images, whether included in the markdown content or not, clients SHOULD use `image` tags as described in [NIP-58](https://github.com/nostr-protocol/nips/blob/master/58.md). This allows clients to display images in carousel format more easily. 30- For images, whether included in the markdown content or not, clients SHOULD use `image` tags as described in [NIP-58](58.md). This allows clients to display images in carousel format more easily.
31 31
32The following tags, used for structured metadata, are standardized and SHOULD be included. Other tags may be added as necessary. 32The following tags, used for structured metadata, are standardized and SHOULD be included. Other tags may be added as necessary.
33 33
diff --git a/BREAKING.md b/BREAKING.md
index c8255cd..83b104b 100644
--- a/BREAKING.md
+++ b/BREAKING.md
@@ -5,6 +5,11 @@ reverse chronological order.
5 5
6| Date | Commit | NIP | Change | 6| Date | Commit | NIP | Change |
7| ----------- | --------- | -------- | ------ | 7| ----------- | --------- | -------- | ------ |
8| 2024-08-18 | [3aff37bd](https://github.com/nostr-protocol/nips/commit/3aff37bd) | [NIP-54](54.md) | content should be Asciidoc |
9| 2024-07-31 | [3ea2f1a4](https://github.com/nostr-protocol/nips/commit/3ea2f1a4) | [NIP-45](45.md) | [444ad28d](https://github.com/nostr-protocol/nips/commit/444ad28d) was reverted |
10| 2024-07-30 | [444ad28d](https://github.com/nostr-protocol/nips/commit/444ad28d) | [NIP-45](45.md) | NIP-45 was deprecated |
11| 2024-07-26 | [ecee40df](https://github.com/nostr-protocol/nips/commit/ecee40df) | [NIP-19](19.md) | `nrelay` was deprecated |
12| 2024-07-23 | [0227a2cd](https://github.com/nostr-protocol/nips/commit/0227a2cd) | [NIP-01](01.md) | events should be sorted by id after created_at |
8| 2024-06-06 | [58e94b20](https://github.com/nostr-protocol/nips/commit/58e94b20) | [NIP-25](25.md) | [8073c848](https://github.com/nostr-protocol/nips/commit/8073c848) was reverted | 13| 2024-06-06 | [58e94b20](https://github.com/nostr-protocol/nips/commit/58e94b20) | [NIP-25](25.md) | [8073c848](https://github.com/nostr-protocol/nips/commit/8073c848) was reverted |
9| 2024-06-06 | [a6dfc7b5](https://github.com/nostr-protocol/nips/commit/a6dfc7b5) | [NIP-55](55.md) | NIP number was changed | 14| 2024-06-06 | [a6dfc7b5](https://github.com/nostr-protocol/nips/commit/a6dfc7b5) | [NIP-55](55.md) | NIP number was changed |
10| 2024-05-25 | [5d1d1c17](https://github.com/nostr-protocol/nips/commit/5d1d1c17) | [NIP-71](71.md) | 'aes-256-gcm' tag was removed | 15| 2024-05-25 | [5d1d1c17](https://github.com/nostr-protocol/nips/commit/5d1d1c17) | [NIP-71](71.md) | 'aes-256-gcm' tag was removed |
@@ -43,6 +48,7 @@ reverse chronological order.
43| 2023-06-18 | [83cbd3e1](https://github.com/nostr-protocol/nips/commit/83cbd3e1) | [NIP-11](11.md) | 'image' was renamed to 'icon' | 48| 2023-06-18 | [83cbd3e1](https://github.com/nostr-protocol/nips/commit/83cbd3e1) | [NIP-11](11.md) | 'image' was renamed to 'icon' |
44| 2023-04-13 | [bf0a0da6](https://github.com/nostr-protocol/nips/commit/bf0a0da6) | [NIP-15](15.md) | different NIP was re-added as NIP-15 | 49| 2023-04-13 | [bf0a0da6](https://github.com/nostr-protocol/nips/commit/bf0a0da6) | [NIP-15](15.md) | different NIP was re-added as NIP-15 |
45| 2023-04-09 | [fb5b7c73](https://github.com/nostr-protocol/nips/commit/fb5b7c73) | [NIP-15](15.md) | NIP-15 was merged into NIP-01 | 50| 2023-04-09 | [fb5b7c73](https://github.com/nostr-protocol/nips/commit/fb5b7c73) | [NIP-15](15.md) | NIP-15 was merged into NIP-01 |
51| 2023-03-29 | [599e1313](https://github.com/nostr-protocol/nips/commit/599e1313) | [NIP-18](18.md) | NIP-18 was bring back |
46| 2023-03-15 | [e1004d3d](https://github.com/nostr-protocol/nips/commit/e1004d3d) | [NIP-19](19.md) | `1: relay` was changed to optionally | 52| 2023-03-15 | [e1004d3d](https://github.com/nostr-protocol/nips/commit/e1004d3d) | [NIP-19](19.md) | `1: relay` was changed to optionally |
47 53
48Breaking changes prior to 2023-03-01 are not yet documented. 54Breaking changes prior to 2023-03-01 are not yet documented.
diff --git a/README.md b/README.md
index 02773a5..80b8dcf 100644
--- a/README.md
+++ b/README.md
@@ -30,7 +30,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
30- [NIP-06: Basic key derivation from mnemonic seed phrase](06.md) 30- [NIP-06: Basic key derivation from mnemonic seed phrase](06.md)
31- [NIP-07: `window.nostr` capability for web browsers](07.md) 31- [NIP-07: `window.nostr` capability for web browsers](07.md)
32- [NIP-08: Handling Mentions](08.md) --- **unrecommended**: deprecated in favor of [NIP-27](27.md) 32- [NIP-08: Handling Mentions](08.md) --- **unrecommended**: deprecated in favor of [NIP-27](27.md)
33- [NIP-09: Event Deletion](09.md) 33- [NIP-09: Event Deletion Request](09.md)
34- [NIP-10: Conventions for clients' use of `e` and `p` tags in text events](10.md) 34- [NIP-10: Conventions for clients' use of `e` and `p` tags in text events](10.md)
35- [NIP-11: Relay Information Document](11.md) 35- [NIP-11: Relay Information Document](11.md)
36- [NIP-13: Proof of Work](13.md) 36- [NIP-13: Proof of Work](13.md)
@@ -73,9 +73,12 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
73- [NIP-57: Lightning Zaps](57.md) 73- [NIP-57: Lightning Zaps](57.md)
74- [NIP-58: Badges](58.md) 74- [NIP-58: Badges](58.md)
75- [NIP-59: Gift Wrap](59.md) 75- [NIP-59: Gift Wrap](59.md)
76- [NIP-64: Chess (PGN)](64.md)
76- [NIP-65: Relay List Metadata](65.md) 77- [NIP-65: Relay List Metadata](65.md)
78- [NIP-70: Protected Events](70.md)
77- [NIP-71: Video Events](71.md) 79- [NIP-71: Video Events](71.md)
78- [NIP-72: Moderated Communities](72.md) 80- [NIP-72: Moderated Communities](72.md)
81- [NIP-73: External Content IDs](73.md)
79- [NIP-75: Zap Goals](75.md) 82- [NIP-75: Zap Goals](75.md)
80- [NIP-78: Application-specific data](78.md) 83- [NIP-78: Application-specific data](78.md)
81- [NIP-84: Highlights](84.md) 84- [NIP-84: Highlights](84.md)
@@ -88,112 +91,116 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
88- [NIP-99: Classified Listings](99.md) 91- [NIP-99: Classified Listings](99.md)
89 92
90## Event Kinds 93## Event Kinds
91| kind | description | NIP | 94
92| ------------- | -------------------------- | ------------------------ | 95| kind | description | NIP |
93| `0` | User Metadata | [01](01.md) | 96| ------------- | ------------------------------- | -------------------------------------- |
94| `1` | Short Text Note | [01](01.md) | 97| `0` | User Metadata | [01](01.md) |
95| `2` | Recommend Relay | 01 (deprecated) | 98| `1` | Short Text Note | [01](01.md) |
96| `3` | Follows | [02](02.md) | 99| `2` | Recommend Relay | 01 (deprecated) |
97| `4` | Encrypted Direct Messages | [04](04.md) | 100| `3` | Follows | [02](02.md) |
98| `5` | Event Deletion | [09](09.md) | 101| `4` | Encrypted Direct Messages | [04](04.md) |
99| `6` | Repost | [18](18.md) | 102| `5` | Event Deletion Request | [09](09.md) |
100| `7` | Reaction | [25](25.md) | 103| `6` | Repost | [18](18.md) |
101| `8` | Badge Award | [58](58.md) | 104| `7` | Reaction | [25](25.md) |
102| `9` | Group Chat Message | [29](29.md) | 105| `8` | Badge Award | [58](58.md) |
103| `10` | Group Chat Threaded Reply | [29](29.md) | 106| `9` | Group Chat Message | [29](29.md) |
104| `11` | Group Thread | [29](29.md) | 107| `10` | Group Chat Threaded Reply | [29](29.md) |
105| `12` | Group Thread Reply | [29](29.md) | 108| `11` | Group Thread | [29](29.md) |
106| `13` | Seal | [59](59.md) | 109| `12` | Group Thread Reply | [29](29.md) |
107| `14` | Direct Message | [17](17.md) | 110| `13` | Seal | [59](59.md) |
108| `16` | Generic Repost | [18](18.md) | 111| `14` | Direct Message | [17](17.md) |
109| `40` | Channel Creation | [28](28.md) | 112| `16` | Generic Repost | [18](18.md) |
110| `41` | Channel Metadata | [28](28.md) | 113| `17` | Reaction to a website | [25](25.md) |
111| `42` | Channel Message | [28](28.md) | 114| `40` | Channel Creation | [28](28.md) |
112| `43` | Channel Hide Message | [28](28.md) | 115| `41` | Channel Metadata | [28](28.md) |
113| `44` | Channel Mute User | [28](28.md) | 116| `42` | Channel Message | [28](28.md) |
114| `818` | Merge Requests | [54](54.md) | 117| `43` | Channel Hide Message | [28](28.md) |
115| `1021` | Bid | [15](15.md) | 118| `44` | Channel Mute User | [28](28.md) |
116| `1022` | Bid confirmation | [15](15.md) | 119| `64` | Chess (PGN) | [64](64.md) |
117| `1040` | OpenTimestamps | [03](03.md) | 120| `818` | Merge Requests | [54](54.md) |
118| `1059` | Gift Wrap | [59](59.md) | 121| `1021` | Bid | [15](15.md) |
119| `1063` | File Metadata | [94](94.md) | 122| `1022` | Bid confirmation | [15](15.md) |
120| `1311` | Live Chat Message | [53](53.md) | 123| `1040` | OpenTimestamps | [03](03.md) |
121| `1617` | Patches | [34](34.md) | 124| `1059` | Gift Wrap | [59](59.md) |
122| `1621` | Issues | [34](34.md) | 125| `1063` | File Metadata | [94](94.md) |
123| `1622` | Replies | [34](34.md) | 126| `1311` | Live Chat Message | [53](53.md) |
124| `1630`-`1633` | Status | [34](34.md) | 127| `1617` | Patches | [34](34.md) |
125| `1971` | Problem Tracker | [nostrocket][nostrocket] | 128| `1621` | Issues | [34](34.md) |
126| `1984` | Reporting | [56](56.md) | 129| `1622` | Replies | [34](34.md) |
127| `1985` | Label | [32](32.md) | 130| `1630`-`1633` | Status | [34](34.md) |
128| `2003` | Torrent | [35](35.md) | 131| `1971` | Problem Tracker | [nostrocket][nostrocket] |
129| `2004` | Torrent Comment | [35](35.md) | 132| `1984` | Reporting | [56](56.md) |
130| `2022` | Coinjoin Pool | [joinstr][joinstr] | 133| `1985` | Label | [32](32.md) |
131| `4550` | Community Post Approval | [72](72.md) | 134| `2003` | Torrent | [35](35.md) |
132| `5000`-`5999` | Job Request | [90](90.md) | 135| `2004` | Torrent Comment | [35](35.md) |
133| `6000`-`6999` | Job Result | [90](90.md) | 136| `2022` | Coinjoin Pool | [joinstr][joinstr] |
134| `7000` | Job Feedback | [90](90.md) | 137| `4550` | Community Post Approval | [72](72.md) |
135| `9000`-`9030` | Group Control Events | [29](29.md) | 138| `5000`-`5999` | Job Request | [90](90.md) |
136| `9041` | Zap Goal | [75](75.md) | 139| `6000`-`6999` | Job Result | [90](90.md) |
137| `9734` | Zap Request | [57](57.md) | 140| `7000` | Job Feedback | [90](90.md) |
138| `9735` | Zap | [57](57.md) | 141| `9000`-`9030` | Group Control Events | [29](29.md) |
139| `9802` | Highlights | [84](84.md) | 142| `9041` | Zap Goal | [75](75.md) |
140| `10000` | Mute list | [51](51.md) | 143| `9734` | Zap Request | [57](57.md) |
141| `10001` | Pin list | [51](51.md) | 144| `9735` | Zap | [57](57.md) |
142| `10002` | Relay List Metadata | [65](65.md) | 145| `9802` | Highlights | [84](84.md) |
143| `10003` | Bookmark list | [51](51.md) | 146| `10000` | Mute list | [51](51.md) |
144| `10004` | Communities list | [51](51.md) | 147| `10001` | Pin list | [51](51.md) |
145| `10005` | Public chats list | [51](51.md) | 148| `10002` | Relay List Metadata | [65](65.md) |
146| `10006` | Blocked relays list | [51](51.md) | 149| `10003` | Bookmark list | [51](51.md) |
147| `10007` | Search relays list | [51](51.md) | 150| `10004` | Communities list | [51](51.md) |
148| `10009` | User groups | [51](51.md), [29](29.md) | 151| `10005` | Public chats list | [51](51.md) |
149| `10015` | Interests list | [51](51.md) | 152| `10006` | Blocked relays list | [51](51.md) |
150| `10030` | User emoji list | [51](51.md) | 153| `10007` | Search relays list | [51](51.md) |
151| `10050` | Relay list to receive DMs | [17](17.md) | 154| `10009` | User groups | [51](51.md), [29](29.md) |
152| `10096` | File storage server list | [96](96.md) | 155| `10015` | Interests list | [51](51.md) |
153| `13194` | Wallet Info | [47](47.md) | 156| `10030` | User emoji list | [51](51.md) |
154| `21000` | Lightning Pub RPC | [Lightning.Pub][lnpub] | 157| `10050` | Relay list to receive DMs | [51](51.md), [17](17.md) |
155| `22242` | Client Authentication | [42](42.md) | 158| `10096` | File storage server list | [96](96.md) |
156| `23194` | Wallet Request | [47](47.md) | 159| `13194` | Wallet Info | [47](47.md) |
157| `23195` | Wallet Response | [47](47.md) | 160| `21000` | Lightning Pub RPC | [Lightning.Pub][lnpub] |
158| `24133` | Nostr Connect | [46](46.md) | 161| `22242` | Client Authentication | [42](42.md) |
159| `27235` | HTTP Auth | [98](98.md) | 162| `23194` | Wallet Request | [47](47.md) |
160| `30000` | Follow sets | [51](51.md) | 163| `23195` | Wallet Response | [47](47.md) |
161| `30001` | Generic lists | [51](51.md) | 164| `24133` | Nostr Connect | [46](46.md) |
162| `30002` | Relay sets | [51](51.md) | 165| `27235` | HTTP Auth | [98](98.md) |
163| `30003` | Bookmark sets | [51](51.md) | 166| `30000` | Follow sets | [51](51.md) |
164| `30004` | Curation sets | [51](51.md) | 167| `30001` | Generic lists | [51](51.md) |
165| `30005` | Video sets | [51](51.md) | 168| `30002` | Relay sets | [51](51.md) |
166| `30008` | Profile Badges | [58](58.md) | 169| `30003` | Bookmark sets | [51](51.md) |
167| `30009` | Badge Definition | [58](58.md) | 170| `30004` | Curation sets | [51](51.md) |
168| `30015` | Interest sets | [51](51.md) | 171| `30005` | Video sets | [51](51.md) |
169| `30017` | Create or update a stall | [15](15.md) | 172| `30008` | Profile Badges | [58](58.md) |
170| `30018` | Create or update a product | [15](15.md) | 173| `30009` | Badge Definition | [58](58.md) |
171| `30019` | Marketplace UI/UX | [15](15.md) | 174| `30015` | Interest sets | [51](51.md) |
172| `30020` | Product sold as an auction | [15](15.md) | 175| `30017` | Create or update a stall | [15](15.md) |
173| `30023` | Long-form Content | [23](23.md) | 176| `30018` | Create or update a product | [15](15.md) |
174| `30024` | Draft Long-form Content | [23](23.md) | 177| `30019` | Marketplace UI/UX | [15](15.md) |
175| `30030` | Emoji sets | [51](51.md) | 178| `30020` | Product sold as an auction | [15](15.md) |
176| `30063` | Release artifact sets | [51](51.md) | 179| `30023` | Long-form Content | [23](23.md) |
177| `30078` | Application-specific Data | [78](78.md) | 180| `30024` | Draft Long-form Content | [23](23.md) |
178| `30311` | Live Event | [53](53.md) | 181| `30030` | Emoji sets | [51](51.md) |
179| `30315` | User Statuses | [38](38.md) | 182| `30063` | Release artifact sets | [51](51.md) |
180| `30402` | Classified Listing | [99](99.md) | 183| `30078` | Application-specific Data | [78](78.md) |
181| `30403` | Draft Classified Listing | [99](99.md) | 184| `30311` | Live Event | [53](53.md) |
182| `30617` | Repository announcements | [34](34.md) | 185| `30315` | User Statuses | [38](38.md) |
183| `30818` | Wiki article | [54](54.md) | 186| `30402` | Classified Listing | [99](99.md) |
184| `30819` | Redirects | [54](54.md) | 187| `30403` | Draft Classified Listing | [99](99.md) |
185| `31890` | Feed | [NUD: Custom Feeds](https://wikifreedia.xyz/cip-01/97c70a44366a6535c1) | 188| `30617` | Repository announcements | [34](34.md) |
186| `31922` | Date-Based Calendar Event | [52](52.md) | 189| `30618` | Repository state announcements | [34](34.md) |
187| `31923` | Time-Based Calendar Event | [52](52.md) | 190| `30818` | Wiki article | [54](54.md) |
188| `31924` | Calendar | [52](52.md) | 191| `30819` | Redirects | [54](54.md) |
189| `31925` | Calendar Event RSVP | [52](52.md) | 192| `31890` | Feed | [NUD: Custom Feeds][NUD: Custom Feeds] |
190| `31989` | Handler recommendation | [89](89.md) | 193| `31922` | Date-Based Calendar Event | [52](52.md) |
191| `31990` | Handler information | [89](89.md) | 194| `31923` | Time-Based Calendar Event | [52](52.md) |
192| `34235` | Video Event | [71](71.md) | 195| `31924` | Calendar | [52](52.md) |
193| `34236` | Short-form Portrait Video Event | [71](71.md) | 196| `31925` | Calendar Event RSVP | [52](52.md) |
194| `34237` | Video View Event | [71](71.md) | 197| `31989` | Handler recommendation | [89](89.md) |
195| `34550` | Community Definition | [72](72.md) | 198| `31990` | Handler information | [89](89.md) |
196| `39000-9` | Group metadata events | [29](29.md) | 199| `34235` | Video Event | [71](71.md) |
200| `34236` | Short-form Portrait Video Event | [71](71.md) |
201| `34237` | Video View Event | [71](71.md) |
202| `34550` | Community Definition | [72](72.md) |
203| `39000-9` | Group metadata events | [29](29.md) |
197 204
198[NUD: Custom Feeds]: https://wikifreedia.xyz/cip-01/97c70a44366a6535c1 205[NUD: Custom Feeds]: https://wikifreedia.xyz/cip-01/97c70a44366a6535c1
199[nostrocket]: https://github.com/nostrocket/NIPS/blob/main/Problems.md 206[nostrocket]: https://github.com/nostrocket/NIPS/blob/main/Problems.md
@@ -232,16 +239,18 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
232| `p` | pubkey (hex) | relay URL, petname | [01](01.md), [02](02.md) | 239| `p` | pubkey (hex) | relay URL, petname | [01](01.md), [02](02.md) |
233| `a` | coordinates to an event | relay URL | [01](01.md) | 240| `a` | coordinates to an event | relay URL | [01](01.md) |
234| `d` | identifier | -- | [01](01.md) | 241| `d` | identifier | -- | [01](01.md) |
242| `-` | -- | -- | [70](70.md) |
235| `g` | geohash | -- | [52](52.md) | 243| `g` | geohash | -- | [52](52.md) |
236| `i` | identity | proof | [39](39.md) | 244| `h` | group id | -- | [29](29.md) |
245| `i` | external identity | proof, url hint | [39](39.md), [73](73.md) |
237| `k` | kind number (string) | -- | [18](18.md), [25](25.md), [72](72.md) | 246| `k` | kind number (string) | -- | [18](18.md), [25](25.md), [72](72.md) |
238| `l` | label, label namespace | -- | [32](32.md) | 247| `l` | label, label namespace | -- | [32](32.md) |
239| `L` | label namespace | -- | [32](32.md) | 248| `L` | label namespace | -- | [32](32.md) |
240| `m` | MIME type | -- | [94](94.md) | 249| `m` | MIME type | -- | [94](94.md) |
241| `q` | event id (hex) | relay URL | [18](18.md) | 250| `q` | event id (hex) | relay URL | [18](18.md) |
242| `r` | a reference (URL, etc) | petname | [24](24.md) | 251| `r` | a reference (URL, etc) | -- | [24](24.md), [25](25.md) |
243| `r` | relay url | marker | [65](65.md) | 252| `r` | relay url | marker | [65](65.md) |
244| `t` | hashtag | -- | | 253| `t` | hashtag | -- | [24](24.md) |
245| `alt` | summary | -- | [31](31.md) | 254| `alt` | summary | -- | [31](31.md) |
246| `amount` | millisatoshis, stringified | -- | [57](57.md) | 255| `amount` | millisatoshis, stringified | -- | [57](57.md) |
247| `bolt11` | `bolt11` invoice | -- | [57](57.md) | 256| `bolt11` | `bolt11` invoice | -- | [57](57.md) |
@@ -255,11 +264,11 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
255| `encrypted` | -- | -- | [90](90.md) | 264| `encrypted` | -- | -- | [90](90.md) |
256| `expiration` | unix timestamp (string) | -- | [40](40.md) | 265| `expiration` | unix timestamp (string) | -- | [40](40.md) |
257| `goal` | event id (hex) | relay URL | [75](75.md) | 266| `goal` | event id (hex) | relay URL | [75](75.md) |
258| `image` | image URL | dimensions in pixels | [23](23.md), [58](58.md) | 267| `image` | image URL | dimensions in pixels | [23](23.md), [52](52.md), [58](58.md) |
259| `imeta` | inline metadata | -- | [92](92.md) | 268| `imeta` | inline metadata | -- | [92](92.md) |
260| `lnurl` | `bech32` encoded `lnurl` | -- | [57](57.md) | 269| `lnurl` | `bech32` encoded `lnurl` | -- | [57](57.md) |
261| `location` | location string | -- | [52](52.md), [99](99.md) | 270| `location` | location string | -- | [52](52.md), [99](99.md) |
262| `name` | name | -- | [34](34.md), [58](58.md) | 271| `name` | name | -- | [34](34.md), [58](58.md), [72](72.md) |
263| `nonce` | random | difficulty | [13](13.md) | 272| `nonce` | random | difficulty | [13](13.md) |
264| `preimage` | hash of `bolt11` invoice | -- | [57](57.md) | 273| `preimage` | hash of `bolt11` invoice | -- | [57](57.md) |
265| `price` | price | currency, frequency | [99](99.md) | 274| `price` | price | currency, frequency | [99](99.md) |
@@ -269,7 +278,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
269| `relays` | relay list | -- | [57](57.md) | 278| `relays` | relay list | -- | [57](57.md) |
270| `server` | file storage server url | -- | [96](96.md) | 279| `server` | file storage server url | -- | [96](96.md) |
271| `subject` | subject | -- | [14](14.md), [17](17.md) | 280| `subject` | subject | -- | [14](14.md), [17](17.md) |
272| `summary` | article summary | -- | [23](23.md) | 281| `summary` | summary | -- | [23](23.md), [52](52.md) |
273| `thumb` | badge thumbnail | dimensions in pixels | [58](58.md) | 282| `thumb` | badge thumbnail | dimensions in pixels | [58](58.md) |
274| `title` | article title | -- | [23](23.md) | 283| `title` | article title | -- | [23](23.md) |
275| `web` | webpage URL | -- | [34](34.md) | 284| `web` | webpage URL | -- | [34](34.md) |