Compare commits

..

23 Commits

Author SHA1 Message Date
fiatjaf
594c33bed0 rename "claim"=>"code", get rid of kind 9006 (just use 9000), add a paragraph explaining moderation. 2024-10-21 13:45:51 -03:00
fiatjaf
765daceaa1 remove invites, simplify group metadata edits, rework fine-grained "permissions" into unspecified "roles". 2024-09-18 22:27:03 -03:00
fiatjaf
e61651ac06 nip29: make @staab happier. 2024-09-13 08:39:47 -03:00
Zig Blathazar
37a02e817b custom emojis in reactions (#1492) 2024-09-12 10:15:47 -03:00
hodlbod
8a427ea6d6 Merge pull request #1488 from kehiy/md
make *.md linguist detectable.
2024-09-11 06:24:31 -07:00
kehiy
d8ab9849b3 make *.md linguist detectable. 2024-09-11 13:17:16 +03:30
hodlbod
97a42449a8 Merge pull request #1487 from ZigBalthazar/patch-1
Update 10.md
2024-09-10 14:19:48 -07:00
Zig Blathazar
c343175a32 Update 10.md 2024-09-10 23:37:36 +03:30
Jon Staab
e7eb776288 Revert example code update 2024-09-09 17:41:57 -03:00
Asai Toshiya
7edd3d23a9 README: update kinds table 2024-09-10 00:32:25 +09:00
hodlbod
c02b161d9e Merge pull request #1477 from kehiy/jsonc
format(all): JSON formatting
2024-09-03 13:56:56 -07:00
K
c8dc1eadff Update 96.md 2024-09-03 23:47:11 +03:30
kehiy
e6552476aa format(all): json formatting 2024-09-03 20:41:31 +03:30
fiatjaf
378dfaa5db nip54: remove markdown leftovers. 2024-09-03 14:07:46 -03:00
Vitor Pamplona
a928d11fb5 Merge pull request #1466 from paulmillr/patch-2
nip44: clarify ecdh hashing
2024-09-03 08:37:21 -04:00
kehiy
b4a2561df7 style: fix header styles in same format 2024-09-02 22:51:48 -03:00
Silberengel
14ec14dac9 Missing events added to README, including NKBIP-01 and NKBIP-02 (#1464)
* Missing events added to README, including NKBIP-01 and NKBIP-02

* Just format

* kind conflict resolved, 2nd blossom kind added

* Revert "kind conflict resolved, 2nd blossom kind added"

This reverts commit 5a8ecc0c27.

* formatting changes merged, kind conflict resolved, 2nd blossom kind added

* relay reviews

---------

Co-authored-by: Asai Toshiya <to.asai.60@gmail.com>
Co-authored-by: fiatjaf_ <fiatjaf@gmail.com>
2024-09-02 22:51:07 -03:00
Paul Miller
be17e5dcd9 Clarify function name in libsecp256k1 2024-09-01 16:13:12 +02:00
Paul Miller
1002104ece nip44: clarify ecdh hashing 2024-09-01 00:44:30 +02:00
hodlbod
24e97c2539 Merge pull request #1333 from coracle-social/clarify-nip01
Clarify what happens when a duplicate subscription is sent, remove CLOSED on duplicate subscription
2024-08-31 06:45:41 -07:00
hodlbod
8184749f5b Merge pull request #1455 from dtonon/nip05-note
NIP-05: add identification vs verification note
2024-08-29 08:30:02 -07:00
dtonon
da34c57e99 NIP-05: add identification vs verification note 2024-08-29 16:37:02 +02:00
Jon Staab
f6b08429a2 Clarify what happens when a duplicate subscription is sent, remove CLOSED on duplicate subscription 2024-06-27 17:00:16 -07:00
48 changed files with 419 additions and 306 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
*.md linguist-detectable

3
01.md
View File

@@ -131,7 +131,7 @@ Clients can send 3 types of messages, which must be JSON arrays, according to th
}
```
Upon receiving a `REQ` message, the relay SHOULD query its internal database and return events that match the filter, then store that filter and send again all future events it receives to that same websocket until the websocket is closed. The `CLOSE` event is received with the same `<subscription_id>` or a new `REQ` is sent using the same `<subscription_id>`, in which case relay MUST overwrite the previous subscription.
Upon receiving a `REQ` message, the relay SHOULD return events that match the filter. Any new events it receives SHOULD be sent to that same websocket until the connection is closed, a `CLOSE` event is received with the same `<subscription_id>`, or a new `REQ` is sent using the same `<subscription_id>` (in which case a new subscription is created, replacing the old one).
Filter attributes containing lists (`ids`, `authors`, `kinds` and tag filters like `#e`) are JSON arrays with one or more values. At least one of the arrays' values must match the relevant field in an event for the condition to be considered a match. For scalar event attributes such as `authors` and `kind`, the attribute from the event must be contained in the filter list. In the case of tag attributes such as `#e`, for which an event may have multiple values, the event and filter condition values must have at least one item in common.
@@ -169,7 +169,6 @@ This NIP defines no rules for how `NOTICE` messages should be sent or treated.
* `["OK", "b1a649ebe8...", false, "pow: difficulty 26 is less than 30"]`
* `["OK", "b1a649ebe8...", false, "error: could not connect to the database"]`
- `CLOSED` messages MUST be sent in response to a `REQ` when the relay refuses to fulfill it. It can also be sent when a relay decides to kill a subscription on its side before a client has disconnected or sent a `CLOSE`. This message uses the same pattern of `OK` messages with the machine-readable prefix and human-readable message. Some examples:
* `["CLOSED", "sub1", "duplicate: sub1 already opened"]`
* `["CLOSED", "sub1", "unsupported: filter contains unknown elements"]`
* `["CLOSED", "sub1", "error: could not connect to the database"]`
* `["CLOSED", "sub1", "error: shutting down idle subscription"]`

4
02.md
View File

@@ -14,7 +14,7 @@ The `.content` is not used.
For example:
```json
```jsonc
{
"kind": 3,
"tags": [
@@ -23,7 +23,7 @@ For example:
["p", "612ae..e610f", "ws://carolrelay.com/ws", "carol"]
],
"content": "",
...other fields
// other fields...
}
```

17
05.md
View File

@@ -16,12 +16,12 @@ The result should be a JSON document object with a key `"names"` that should the
If a client sees an event like this:
```json
```jsonc
{
"pubkey": "b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9",
"kind": 0,
"content": "{\"name\": \"bob\", \"nip05\": \"bob@example.com\"}"
...
// other fields...
}
```
@@ -58,6 +58,15 @@ A client may implement support for finding users' public keys from _internet ide
## Notes
### Identification, not verification
The 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.
Exceptions 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.
### User discovery implementation suggestion
A 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.
### Clients must always follow public keys, not NIP-05 addresses
For example, if after finding that `bob@bob.com` has the public key `abc...def`, the user clicks a button to follow that profile, the client must keep a primary reference to `abc...def`, not `bob@bob.com`. If, for any reason, the address `https://bob.com/.well-known/nostr.json?name=bob` starts returning the public key `1d2...e3f` at any time in the future, the client must not replace `abc...def` in his list of followed profiles for the user (but it should stop displaying "bob@bob.com" for that user, as that will have become an invalid `"nip05"` property).
@@ -66,10 +75,6 @@ For example, if after finding that `bob@bob.com` has the public key `abc...def`,
Keys 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.
### User Discovery implementation suggestion
A client can also use this to allow users to search other profiles. If a client has a search box or something like that, a user may be able to type "bob@example.com" there and the client would recognize that and do the proper queries to obtain a pubkey and suggest that to the user.
### Showing just the domain as an identifier
Clients may treat the identifier `_@domain` as the "root" identifier, and choose to display it as just the `<domain>`. For example, if Bob owns `bob.com`, he may not want an identifier like `bob@bob.com` as that is redundant. Instead, Bob can use the identifier `_@bob.com` and expect Nostr clients to show and treat that as just `bob.com` for all purposes.

6
09.md
View File

@@ -2,7 +2,7 @@ NIP-09
======
Event Deletion Request
--------------
----------------------
`draft` `optional`
@@ -12,7 +12,7 @@ The event's `content` field MAY contain a text note describing the reason for th
For example:
```
```jsonc
{
"kind": 5,
"pubkey": <32-bytes hex-encoded public key of the event creator>,
@@ -24,7 +24,7 @@ For example:
["k", "30023"]
],
"content": "these posts were published by accident",
...other fields
// other fields...
}
```

6
10.md
View File

@@ -2,8 +2,8 @@ NIP-10
======
On "e" and "p" tags in Text Events (kind 1).
--------------------------------------------
On "e" and "p" tags in Text Events (kind 1)
-------------------------------------------
`draft` `optional`
@@ -43,7 +43,7 @@ They are citing from this event. `root-id` and `reply-id` are as above.
Where:
* `<event-id>` is the id of the event being referenced.
* `<relay-url>` is the URL of a recommended relay associated with the reference. Clients SHOULD add a valid `<relay-URL>` field, but may instead leave it as `""`.
* `<relay-url>` is the URL of a recommended relay associated with the reference. Clients SHOULD add a valid `<relay-url>` field, but may instead leave it as `""`.
* `<marker>` is optional and if present is one of `"reply"`, `"root"`, or `"mention"`.
* `<pubkey>` is optional, SHOULD be the pubkey of the author of the referenced event

32
11.md
View File

@@ -2,7 +2,7 @@ NIP-11
======
Relay Information Document
---------------------------
--------------------------
`draft` `optional`
@@ -66,7 +66,7 @@ These are limitations imposed by the relay on clients. Your client
should expect that requests which exceed these *practical* limitations
are rejected or fail immediately.
```json
```jsonc
{
"limitation": {
"max_message_length": 16384,
@@ -83,7 +83,7 @@ are rejected or fail immediately.
"created_at_lower_limit": 31536000,
"created_at_upper_limit": 3
},
...
// other fields...
}
```
@@ -146,14 +146,15 @@ Retention times are given in seconds, with `null` indicating infinity.
If zero is provided, this means the event will not be stored at
all, and preferably an error will be provided when those are received.
```json
```jsonc
{
"retention": [
{"kinds": [0, 1, [5, 7], [40, 49]], "time": 3600},
{"kinds": [[40000, 49999]], "time": 100},
{"kinds": [[30000, 39999]], "count": 1000},
{"time": 3600, "count": 10000}
]
],
// other fields...
}
```
@@ -172,7 +173,7 @@ There is no need to specify retention times for _ephemeral events_ since they ar
### Content Limitations
Some relays may be governed by the arbitrary laws of a nation state. This
may limit what content can be stored in cleartext on those relays. All
may limit what content can be stored in clear-text on those relays. All
clients are encouraged to use encryption to work around this limitation.
It is not possible to describe the limitations of each country's laws
@@ -183,13 +184,13 @@ countries' laws might end up being enforced on them, and then
indirectly on their users' content.
Users should be able to avoid relays in countries they don't like,
and/or select relays in more favourable zones. Exposing this
and/or select relays in more favorable zones. Exposing this
flexibility is up to the client software.
```json
```jsonc
{
"relay_countries": [ "CA", "US" ],
...
// other fields...
}
```
@@ -208,12 +209,12 @@ local community. This would encourage users to follow the global
feed on that relay, in addition to their usual individual follows.
To support this goal, relays MAY specify some of the following values.
```json
```jsonc
{
"language_tags": ["en", "en-419"],
"tags": ["sfw-only", "bitcoin-only", "anime"],
"posting_policy": "https://example.com/posting-policy.html",
...
// other fields...
}
```
@@ -260,10 +261,10 @@ Relays that require payments may want to expose their fee schedules.
A URL pointing to an image to be used as an icon for the relay. Recommended to be squared in shape.
```json
```jsonc
{
"icon": "https://nostr.build/i/53866b44135a27d624e99c6165cabd76ac8f72797209700acb189fce75021f47.jpg",
...
// other fields...
}
```
@@ -271,9 +272,11 @@ A URL pointing to an image to be used as an icon for the relay. Recommended to b
As of 2 May 2023 the following command provided these results:
```bash
$ curl -H "Accept: application/nostr+json" https://eden.nostr.land | jq
```
~> curl -H "Accept: application/nostr+json" https://eden.nostr.land | jq
```json
{
"description": "nostr.land family of relays (us-or-01)",
"name": "nostr.land",
@@ -312,3 +315,4 @@ As of 2 May 2023 the following command provided these results:
]
},
}
```

45
13.md
View File

@@ -48,37 +48,30 @@ Validating
Here is some reference C code for calculating the difficulty (aka number of leading zero bits) in a nostr event id:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int zero_bits(unsigned char b)
{
int n = 0;
int countLeadingZeroes(const char *hex) {
int count = 0;
if (b == 0)
return 8;
for (int i = 0; i < strlen(hex); i++) {
int nibble = (int)strtol((char[]){hex[i], '\0'}, NULL, 16);
if (nibble == 0) {
count += 4;
} else {
count += __builtin_clz(nibble) - 28;
break;
}
}
while (b >>= 1)
n++;
return count;
return 7-n;
}
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <hex_string>\n", argv[0]);
return 1;
}
const char *hex_string = argv[1];
int result = countLeadingZeroes(hex_string);
printf("Leading zeroes in hex string %s: %d\n", hex_string, result);
return 0;
/* find the number of leading zero bits in a hash */
int count_leading_zero_bits(unsigned char *hash)
{
int bits, total, i;
for (i = 0, total = 0; i < 32; i++) {
bits = zero_bits(hash[i]);
total += bits;
if (bits != 8)
break;
}
return total;
}
```

19
15.md
View File

@@ -73,10 +73,10 @@ Fields that are not self-explanatory:
**Event Tags**
```json
```jsonc
{
"tags": [["d", <string, id of stall]],
...
// other fields...
}
```
- the `d` tag is required, its value MUST be the same as the stall `id`.
@@ -124,12 +124,12 @@ Fields that are not self-explanatory:
**Event Tags**
```json
```jsonc
"tags": [
["d", <string, id of product],
["t", <string (optional), product category],
["t", <string (optional), product category],
...
// other fields...
],
...
```
@@ -158,7 +158,7 @@ The below JSON goes in content of [NIP-04](04.md).
"type": 0,
"name": <string (optional), ???>,
"address": <string (optional), for physical goods an address should be provided>,
"message": "<string (optional), message for merchant>,
"message": <string (optional), message for merchant>,
"contact": {
"nostr": <32-bytes hex of a pubkey>,
"phone": <string (optional), if the customer wants to be contacted by phone>,
@@ -237,7 +237,7 @@ Create a customized user experience using the `naddr` from [NIP-19](19.md#sharea
**Event Content**
```json
```jsonc
{
"name": <string (optional), market name>,
"about": <string (optional), market description>,
@@ -248,7 +248,7 @@ Create a customized user experience using the `naddr` from [NIP-19](19.md#sharea
"darkMode": <bool, true/false>
},
"merchants": [array of pubkeys (optional)],
...
// other fields...
}
```
@@ -290,10 +290,11 @@ This event leverages naddr to enable comprehensive customization and sharing of
### Event `1021`: Bid
```json
```jsonc
{
"content": <int, amount of sats>,
"tags": [["e", <event ID of the auction to bid on>]],
// other fields...
}
```
@@ -335,4 +336,4 @@ Customer support is handled over whatever communication method was specified. If
## Additional
Standard data models can be found <a href="https://raw.githubusercontent.com/lnbits/nostrmarket/main/models.py">here</a>
Standard data models can be found [here](https://raw.githubusercontent.com/lnbits/nostrmarket/main/models.py)

15
17.md
View File

@@ -12,18 +12,18 @@ This NIP defines an encrypted direct messaging scheme using [NIP-44](44.md) encr
Kind `14` is a chat message. `p` tags identify one or more receivers of the message.
```js
```jsonc
{
"id": "<usual hash>",
  "pubkey": "<sender-pubkey>",
"created_at": now(),
"created_at": "<current-time>",
  "kind": 14,
  "tags": [
    ["p", "<receiver-1-pubkey>", "<relay-url>"],
    ["p", "<receiver-2-pubkey>", "<relay-url>"],
    ["e", "<kind-14-id>", "<relay-url>", "reply"] // if this is a reply
["subject", "<conversation-title>"],
    ...
    // rest of tags...
  ],
  "content": "<message-in-plain-text>",
}
@@ -86,7 +86,7 @@ Clients CAN offer disappearing messages by setting an `expiration` tag in the gi
Kind `10050` indicates the user's preferred relays to receive DMs. The event MUST include a list of `relay` tags with relay URIs.
```js
```jsonc
{
"kind": 10050,
"tags": [
@@ -94,7 +94,7 @@ Kind `10050` indicates the user's preferred relays to receive DMs. The event MUS
["relay", "wss://myrelay.nostr1.com"],
],
"content": "",
//...other fields
// other fields...
}
```
@@ -123,11 +123,6 @@ This NIP offers the following privacy and security features:
The main limitation of this approach is having to send a separate encrypted event to each receiver. Group chats with more than 100 participants should find a more suitable messaging scheme.
## NIP-19 entity
To create an `nchat` link:
- `kind`: `17`
- `special`: one or more pubkeys concatenated
## Implementation
Clients implementing this NIP should by default only connect to the set of relays found in their `kind:10050` list. From that they should be able to load all messages both sent and received as well as get new live updates, making it for a very simple and lightweight implementation that should be fast.

3
19.md
View File

@@ -36,7 +36,6 @@ These are the possible bech32 prefixes with `TLV`:
- `nevent`: a nostr event
- `naddr`: a nostr _replaceable event_ coordinate
- `nrelay`: a nostr relay (deprecated)
- `nchat`: a nostr chat conversation
These possible standardized `TLV` types are indicated here:
@@ -45,7 +44,6 @@ These possible standardized `TLV` types are indicated here:
- for `nprofile` it will be the 32 bytes of the profile public key
- for `nevent` it will be the 32 bytes of the event id
- for `naddr`, it is the identifier (the `"d"` tag) of the event being referenced. For normal replaceable events use an empty string.
- for `nchat`, see chat nip for details.
- `1`: `relay`
- for `nprofile`, `nevent` and `naddr`, _optionally_, a relay in which the entity (profile or event) is more likely to be found, encoded as ascii
- this may be included multiple times
@@ -55,7 +53,6 @@ These possible standardized `TLV` types are indicated here:
- `3`: `kind`
- for `naddr`, the 32-bit unsigned integer of the kind, big-endian
- for `nevent`, _optionally_, the 32-bit unsigned integer of the kind, big-endian
- for `nchat`, the NIP number of the chat.
## Examples

8
25.md
View File

@@ -57,14 +57,14 @@ Reactions to a website
If 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.
```json
```jsonc
{
"kind": 17,
"content": "⭐",
"tags": [
["r", "https://example.com/"]
],
...other fields
// other fields...
}
```
@@ -79,14 +79,14 @@ The client may specify a custom emoji ([NIP-30](30.md)) `:shortcode:` in the
reaction content. The client should refer to the emoji tag and render the
content as an emoji if shortcode is specified.
```json
```jsonc
{
"kind": 7,
"content": ":soapbox:",
"tags": [
["emoji", "soapbox", "https://gleasonator.com/emoji/Gleasonator/soapbox.png"]
],
...other fields
// other fields...
}
```

2
26.md
View File

@@ -2,7 +2,7 @@ NIP-26
=======
Delegated Event Signing
-----
-----------------------
`draft` `optional`

31
28.md
View File

@@ -25,10 +25,10 @@ Create a public chat channel.
In the channel creation `content` field, Client SHOULD include basic channel metadata (`name`, `about`, `picture` and `relays` as specified in kind 41).
```json
```jsonc
{
"content": "{\"name\": \"Demo Channel\", \"about\": \"A test channel.\", \"picture\": \"https://placekitten.com/200/200\", \"relays\": [\"wss://nos.lol\", \"wss://nostr.mom\"]}",
...
// other fields...
}
```
@@ -52,11 +52,11 @@ Clients MAY add additional metadata fields.
Clients SHOULD use [NIP-10](10.md) marked "e" tags to recommend a relay.
```json
```jsonc
{
"content": "{\"name\": \"Updated Demo Channel\", \"about\": \"Updating a test channel.\", \"picture\": \"https://placekitten.com/201/201\", \"relays\": [\"wss://nos.lol\", \"wss://nostr.mom\"]}",
"tags": [["e", <channel_create_event_id>, <relay-url>]],
...
// other fields...
}
```
@@ -71,26 +71,26 @@ Clients SHOULD append [NIP-10](10.md) "p" tags to replies.
Root message:
```json
```jsonc
{
"content": <string>,
"tags": [["e", <kind_40_event_id>, <relay-url>, "root"]],
...
// other fields...
}
```
Reply to another message:
```json
```jsonc
{
"content": <string>,
"tags": [
["e", <kind_40_event_id>, <relay-url>, "root"],
["e", <kind_42_event_id>, <relay-url>, "reply"],
["p", <pubkey>, <relay-url>],
...
// rest of tags...
],
...
// other fields...
}
```
@@ -107,11 +107,11 @@ Clients MAY hide event 42s for other users other than the user who sent the even
(For example, if three users 'hide' an event giving a reason that includes the word 'pornography', a Nostr client that is an iOS app may choose to hide that message for all iOS clients.)
```json
```jsonc
{
"content": "{\"reason\": \"Dick pic\"}",
"tags": [["e", <kind_42_event_id>]],
...
// other fields...
}
```
@@ -125,19 +125,14 @@ Clients SHOULD hide event 42s shown to a given user, if there is an event 44 fro
Clients MAY hide event 42s for users other than the user who sent the event 44.
```json
```jsonc
{
"content": "{\"reason\": \"Posting dick pics\"}",
"tags": [["p", <pubkey>]],
...
// other fields...
}
```
## NIP-19 entity
To create an `nchat` link:
- `kind`: `28`
- `special`: `id` from `kind: 40`
## Relay recommendations
Clients SHOULD use the relay URLs of the metadata events.

174
29.md
View File

@@ -22,6 +22,12 @@ Relays are supposed to generate the events that describe group metadata and grou
A group may be identified by a string in the format `<host>'<group-id>`. For example, a group with _id_ `abcdef` hosted at the relay `wss://groups.nostr.com` would be identified by the string `groups.nostr.com'abcdef`.
Group identifiers must be strings restricted to the characters `a-z0-9-_`.
When encountering just the `<host>` without the `'<group-id>`, clients can choose to connect to the group with id `_`, which is a special top-level group dedicated to relay-local discussions.
Group identifiers in most cases should be random or pseudo-random, as that mitigates message replay confusiong and ensures they can be migrated or forked to other relays easily without risking conflicting with other groups using the same id in these new relays. This isn't a hard rule, as, for example, in `unmanaged` and/or ephemeral relays groups might not want to migrate ever, so they might not care about this. Notably, the `_` relay-local group isn't expected to be migrated ever.
## The `h` tag
Events sent by users to groups (chat messages, text notes, moderation events etc) must have an `h` tag with the value set to the group _id_.
@@ -36,20 +42,42 @@ This is a hack to prevent messages from being broadcasted to external relays tha
Relays should prevent late publication (messages published now with a timestamp from days or even hours ago) unless they are open to receive a group forked or moved from another relay.
## Group management
Groups can have any number of users with elevated access. These users are identified by role labels which are arbitrarily defined by the relays (see also the description of `kind:39003`). What each role is capable of not defined in this NIP either, it's a relay policy that can vary. Roles can be assigned by other users (as long as they have the capability to add roles) by publishing a `kind:9000` event with that user's pubkey in a `p` tag and the roles afterwards (even if the user is already a group member a `kind:9000` can be issued and the user roles must just be updated).
The roles supported by the group as to having some special privilege assigned to them should be accessible on the event `kind:39003`, but the relay may also accept other role names, arbitrarily defined by clients, and just not do anything with them.
Users with any roles that have any privilege can be considered _admins_ in a broad sense and be returned in the `kind:39001` event for a group.
## Unmanaged groups
Unmanaged groups are impromptu groups that can be used in any public relay unaware of NIP-29 specifics. They piggyback on relays' natural white/blacklists (or lack of) but aside from that are not actively managed and won't have any admins, group state or metadata events.
In `unmanaged` groups, everybody is considered to be a member.
Unmanaged groups can transition to managed groups, in that case the relay master key just has to publish moderation events setting the state of all groups and start enforcing the rules they choose to.
## Event definitions
These are the events expected to be found in NIP-29 groups.
### Normal user-created events
These events generally can be sent by all members of a group and they require the `h` tag to be present so they're attached to a specific group.
- *text root note* (`kind:11`)
This is the basic unit of a "microblog" root text note sent to a group.
```js
```jsonc
"kind": 11,
"content": "hello my friends lovers of pizza",
"tags": [
["h", "<group-id>"],
["previous", "<event-id-first-chars>", "<event-id-first-chars>", ...]
["previous", "<event-id-first-chars>", "<event-id-first-chars>", /*...*/]
]
...
// other fields...
```
- *threaded text reply* (`kind:12`)
@@ -63,14 +91,14 @@ This is the basic unit of a "microblog" reply note sent to a group. It's the sam
This is the basic unit of a _chat message_ sent to a group.
```js
```jsonc
"kind": 9,
"content": "hello my friends lovers of pizza",
"tags": [
["h", "<group-id>"],
["previous", "<event-id-first-chars>", "<event-id-first-chars>", ...]
["previous", "<event-id-first-chars>", "<event-id-first-chars>", /*...*/]
]
...
// other fields...
```
- *chat message threaded reply* (`kind:10`)
@@ -79,25 +107,36 @@ Similar to `kind:12`, this is the basic unit of a chat message sent to a group.
`kind:10` SHOULD use NIP-10 markers, just like `kind:12`.
- other events:
Groups may also accept other events, like long-form articles, calendar, livestream, market announcements and so on. These should be as defined in their respective NIPs, with the addition of the `h` tag.
### User-related group management events
These are events that can be sent my user to manage their situation in a group, they also require the `h` tag.
- *join request* (`kind:9021`)
Any user can send one of these events to the relay in order to be automatically or manually added to the group. If the group is `open` the relay will automatically issue a `kind:9000` in response adding this user. Otherwise group admins may choose to query for these requests and act upon them.
```js
```json
{
"kind": 9021,
"content": "optional reason",
"tags": [
["h", "<group-id>"]
["h", "<group-id>"],
["code", "<optional-invite-code>"]
]
}
```
The optional `code` tag may be used by the relay to preauthorize acceptances in `closed` groups, together with the `kind:9009` `create-invite` moderation event.
- *leave request* (`kind:9022`)
Any 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.
```js
```json
{
"kind": 9022,
"content": "optional reason",
@@ -107,34 +146,41 @@ Any user can send one of these events to the relay in order to be automatically
}
```
### Group state -- or moderation
These are events expected to be sent by the relay master key or by group admins -- and relays should reject them if they don't come from an authorized admin. They also require the `h` tag.
- *moderation events* (`kinds:9000-9020`) (optional)
Clients 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.
Clients 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 based on its role and the relay's internal policy (see also the description of `kind:39003`).
```js
```json
{
"kind": 90xx,
"content": "optional reason",
"tags": [
["h", "<group-id>"],
["previous", ...]
["previous", /*...*/]
]
}
```
Each moderation action uses a different kind and requires different arguments, which are given as tags. These are defined in the following table:
| kind | name | tags |
| --- | --- | --- |
| 9000 | `add-user` | `p` (pubkey hex) |
| 9001 | `remove-user` | `p` (pubkey hex) |
| 9002 | `edit-metadata` | `name`, `about`, `picture` (string) |
| 9003 | `add-permission` | `p` (pubkey), `permission` (name) |
| 9004 | `remove-permission` | `p` (pubkey), `permission` (name) |
| 9005 | `delete-event` | `e` (id hex) |
| 9006 | `edit-group-status` | `public` or `private`, `open` or `closed` |
| 9007 | `create-group` | |
| 9008 | `delete-group` | |
| kind | name | tags |
| --- | --- | --- |
| 9000 | `add-user` | `p` with pubkey hex and optional roles |
| 9001 | `remove-user` | `p` with pubkey hex |
| 9002 | `edit-metadata` | fields from `kind:39000` to be modified |
| 9005 | `delete-event` | |
| 9007 | `create-group` | |
| 9008 | `delete-group` | |
It's expected that the group state (of who is an allowed member or not, who is an admin and with which permission or not, what are the group name and picture etc) can be fully reconstructed from the canonical sequence of these events.
### Group metadata events
These events contain the group id in a `d` tag instead of the `h` tag. They MUST be created by the relay master key only and a single instance of each (or none) should exist at all times for each group. They are merely informative but should reflect the latest group state (as it was changed by moderation events over time).
- *group metadata* (`kind:39000`) (optional)
@@ -142,7 +188,9 @@ This event defines the metadata for the group -- basically how clients should di
If the group is forked and hosted in multiple relays, there will be multiple versions of this event in each different relay and so on.
```js
When this event is not found, clients may still connect to the group, but treat it as having a different status, `unmanaged`,
```jsonc
{
"kind": 39000,
"content": "",
@@ -154,7 +202,7 @@ If the group is forked and hosted in multiple relays, there will be multiple ver
["public"], // or ["private"]
["open"] // or ["closed"]
]
...
// other fields...
}
```
@@ -162,41 +210,29 @@ If the group is forked and hosted in multiple relays, there will be multiple ver
- *group admins* (`kind:39001`) (optional)
Similar to the group metadata, this event is supposed to be generated by relays that host the group.
Each admin is listed along with one or more roles. These roles SHOULD have a correspondence with the roles supported by the relay, as advertised by the `kind:39003` event.
Each admin gets a label that is only used for display purposes, and a list of permissions it has are listed afterwards. These permissions can inform client building UI, but ultimately are evaluated by the relay in order to become effective.
The list of capabilities, as defined by this NIP, for now, is the following:
- `add-user`
- `edit-metadata`
- `delete-event`
- `remove-user`
- `add-permission`
- `remove-permission`
- `edit-group-status`
- `delete-group`
```js
```jsonc
{
"kind": 39001,
"content": "list of admins for the pizza lovers group",
"tags": [
["d", "<group-id>"],
["p", "<pubkey1-as-hex>", "ceo", "add-user", "edit-metadata", "delete-event", "remove-user"],
["p", "<pubkey2-as-hex>", "secretary", "add-user", "delete-event"]
]
...
["p", "<pubkey1-as-hex>", "ceo"],
["p", "<pubkey2-as-hex>", "secretary", "gardener"],
// other pubkeys...
],
// other fields...
}
```
- *group members* (`kind:39002`) (optional)
Similar to *group admins*, this event is supposed to be generated by relays that host the group.
It's a list of pubkeys that are members of the group. Relays might choose to not to publish this information, to restrict what pubkeys can fetch it or to only display a subset of the members in it.
It's a NIP-51-like list of pubkeys that are members of the group. Relays might choose to not to publish this information or to restrict what pubkeys can fetch it.
Clients should not assume this will always be present or that it will contain a full list of members.
```json
```jsonc
{
"kind": 39002,
"content": "list of members for the pizza lovers group",
@@ -205,10 +241,48 @@ It's a NIP-51-like list of pubkeys that are members of the group. Relays might c
["p", "<admin1>"],
["p", "<member-pubkey1>"],
["p", "<member-pubkey2>"],
]
// other pubkeys...
],
// other fields...
}
```
## Storing the list of groups a user belongs to
- *group roles* (`kind:39003`) (optional)
A definition for kind `10009` was included in [NIP-51](51.md) that allows clients to store the list of groups a user wants to remember being in.
This is an event that MAY be published by the relay informing users and clients about what are the roles supported by this relay according to its internal logic.
For example, a relay may choose to support the roles `"admin"` and `"moderator"`, in which the `"admin"` will be allowed to edit the group metadata, delete messages and remove users from the group, while the `"moderator"` can only delete messages (or the relay may choose to call these roles `"ceo"` and `"secretary"` instead, the exact role name is not relevant).
The process through which the relay decides what roles to support and how to handle moderation events internally based on them is specific to each relay and not specified here.
```jsonc
{
"kind": 39003,
"content": "list of roles supported by this group",
"tags": [
["d", "<group-id>"],
["role", "<role-name>", "<optional-description>"],
["role", "<role-name>", "<optional-description>"],
// other roles...
],
// other fields...
}
```
## Implementation quirks
### Checking your own membership in a group
The latest of either `kind:9000` or `kind:9001` events present in a group should tell a user that they are currently members of the group or if they were removed. In case none of these exist the user is assumed to not be a member of the group -- unless the group is `unmanaged`, in which case the user is assumed to be a member.
### Adding yourself to a group
When a group is `open`, anyone can send a `kind:9021` event to it in order to be added, then expect a `kind:9000` event to be emitted confirming that the user was added. The same happens with `closed` groups, except in that case a user may only send a `kind:9021` if it has an invite code.
### Storing your list of groups
A definition for `kind:10009` was included in [NIP-51](51.md) that allows clients to store the list of groups a user wants to remember being in.
### Using `unmanaged` relays
To prevent event leakage, replay and confusion, when using `unmanaged` relays, clients should include the [NIP-70](70.md) `-` tag, as just the `previous` tag won't be checked by other `unmanaged` relays.

16
30.md
View File

@@ -54,3 +54,19 @@ In kind 1 events, the `content` should be emojified.
"created_at": 1682630000
}
```
### Kind 7 events
In kind 7 events, the `content` should be emojified.
```json
{
"kind": 7,
"content": ":dezh:",
"tags": [
["emoji", "dezh", "https://raw.githubusercontent.com/dezh-tech/brand-assets/main/dezh/logo/black-normal.svg"]
],
"pubkey": "79c2cae114ea28a981e7559b4fe7854a473521a8d22a66bbab9fa248eb820ff6",
"created_at": 1682630000
}
```

28
32.md
View File

@@ -2,7 +2,7 @@ NIP-32
======
Labeling
---------
--------
`draft` `optional`
@@ -57,7 +57,7 @@ Example events
A suggestion that multiple pubkeys be associated with the `permies` topic.
```json
```jsonc
{
"kind": 1985,
"tags": [
@@ -66,13 +66,13 @@ A suggestion that multiple pubkeys be associated with the `permies` topic.
["p", <pubkey1>, <relay_url>],
["p", <pubkey2>, <relay_url>]
],
...
// other fields...
}
```
A report flagging violence toward a human being as defined by ontology.example.com.
```json
```jsonc
{
"kind": 1985,
"tags": [
@@ -81,13 +81,13 @@ A report flagging violence toward a human being as defined by ontology.example.c
["p", <pubkey1>, <relay_url>],
["p", <pubkey2>, <relay_url>]
],
...
// other fields...
}
```
A moderation suggestion for a chat event.
```json
```jsonc
{
"kind": 1985,
"tags": [
@@ -95,13 +95,13 @@ A moderation suggestion for a chat event.
["l", "approve", "nip28.moderation"],
["e", <kind40_event_id>, <relay_url>]
],
...
// other fields...
}
```
Assignment of a license to an event.
```json
```jsonc
{
"kind": 1985,
"tags": [
@@ -109,14 +109,14 @@ Assignment of a license to an event.
["l", "MIT", "license"],
["e", <event_id>, <relay_url>]
],
...
// other fields...
}
```
Publishers can self-label by adding `l` tags to their own non-1985 events. In this case, the kind 1 event's author
is labeling their note as being related to Milan, Italy using ISO 3166-2.
```json
```jsonc
{
"kind": 1,
"tags": [
@@ -124,13 +124,13 @@ is labeling their note as being related to Milan, Italy using ISO 3166-2.
["l", "IT-MI", "ISO-3166-2"]
],
"content": "It's beautiful here in Milan!",
...
// other fields...
}
```
Author is labeling their note language as English using ISO-639-1.
```json
```jsonc
{
"kind": 1,
"tags": [
@@ -138,7 +138,7 @@ Author is labeling their note language as English using ISO-639-1.
["l", "en", "ISO-639-1"]
],
"content": "English text",
...
// other fields...
}
```
@@ -169,7 +169,7 @@ be handled in some other way.
Appendix: Known Ontologies
-------------------------
--------------------------
Below is a non-exhaustive list of ontologies currently in widespread use.

7
34.md
View File

@@ -106,7 +106,7 @@ The first patch in a series MAY be a cover letter in the format produced by `git
Issues are Markdown text that is just human-readable conversational threads related to the repository: bug reports, feature requests, questions or comments of any kind. Like patches, these SHOULD be sent to the relays specified in that repository's announcement event's `"relays"` tag.
```jsonc
```json
{
"kind": 1621,
"content": "<markdown text>",
@@ -132,8 +132,9 @@ Replies are also Markdown text. The difference is that they MUST be issued as re
// other "e" and "p" tags should be applied here when necessary, following the threading rules of NIP-10
["p", "<patch-author-pubkey-hex>", "", "mention"],
["e", "<previous-reply-id-hex>", "", "reply"],
// ...
]
// rest of tags...
],
// other fields...
}
```

4
35.md
View File

@@ -2,7 +2,7 @@ NIP-35
======
Torrents
-----------
--------
`draft` `optional`
@@ -37,7 +37,7 @@ A second level prefix should be included where the database supports multiple me
In some cases the url mapping isnt direct, mapping the url in general is out of scope for this NIP, the section above is only a guide so that implementers have enough information to succsesfully map the url if they wish.
```jsonc
```json
{
"kind": 2003,
"content": "<long-description-pre-formatted>",

6
38.md
View File

@@ -3,7 +3,7 @@ NIP-38
======
User Statuses
--------------
-------------
`draft` `optional`
@@ -17,7 +17,7 @@ A special event with `kind:30315` "User Status" is defined as an *optionally exp
For example:
```js
```json
{
"kind": 30315,
"content": "Sign up for nostrasia!",
@@ -26,7 +26,9 @@ For example:
["r", "https://nostr.world"]
],
}
```
```json
{
"kind": 30315,
"content": "Intergalatic - Beastie Boys",

5
39.md
View File

@@ -13,7 +13,8 @@ Nostr protocol users may have other online identities such as usernames, profile
## `i` tag on a metadata event
A new optional `i` tag is introduced for `kind 0` metadata event defined in [NIP-01](01.md):
```json
```jsonc
{
"id": <id>,
"pubkey": <pubkey>,
@@ -23,7 +24,7 @@ A new optional `i` tag is introduced for `kind 0` metadata event defined in [NIP
["i", "mastodon:bitcoinhackers.org/@semisol", "109775066355589974"]
["i", "telegram:1087295469", "nostrdirectory/770"]
],
...
// other fields...
}
```

8
42.md
View File

@@ -22,13 +22,13 @@ A relay may want to require clients to authenticate to access restricted resourc
This NIP defines a new message, `AUTH`, which relays CAN send when they support authentication and clients can send to relays when they want to authenticate. When sent by relays the message has the following form:
```json
```
["AUTH", <challenge-string>]
```
And, when sent by clients, the following form:
```json
```
["AUTH", <signed-event-json>]
```
@@ -38,14 +38,14 @@ And, when sent by clients, the following form:
The signed event is an ephemeral event not meant to be published or queried, it must be of `kind: 22242` and it should have at least two tags, one for the relay URL and one for the challenge string as received from the relay. Relays MUST exclude `kind: 22242` events from being broadcasted to any client. `created_at` should be the current time. Example:
```json
```jsonc
{
"kind": 22242,
"tags": [
["relay", "wss://relay.example.com/"],
["challenge", "challengestringhere"]
],
...
// other fields...
}
```

4
44.md
View File

@@ -1,5 +1,5 @@
NIP-44
=====
======
Encrypted Payloads (Versioned)
------------------------------
@@ -142,6 +142,8 @@ validation rules, refer to BIP-340.
The operation produces a shared point, and we encode the shared point's 32-byte x coordinate, using method
`bytes(P)` from BIP340. Private and public keys must be validated as per BIP340: pubkey must be a valid,
on-curve point, and private key must be a scalar in range `[1, secp256k1_order - 1]`.
NIP44 doesn't do hashing of the output: keep this in mind, because some libraries hash it using sha256.
As an example, in libsecp256k1, unhashed version is available in `secp256k1_ec_pubkey_tweak_mul`
- Operators
- `x[i:j]`, where `x` is a byte array and `i, j <= 0` returns a `(j - i)`-byte array with a copy of the
`i`-th byte (inclusive) to the `j`-th byte (exclusive) of `x`.

2
45.md
View File

@@ -2,7 +2,7 @@ NIP-45
======
Event Counts
--------------
------------
`draft` `optional`

8
46.md
View File

@@ -1,4 +1,8 @@
# NIP-46 - Nostr Remote Signing
NIP-46
======
Nostr Remote Signing
--------------------
## Rationale
@@ -90,7 +94,7 @@ nostrconnect://<local-keypair-pubkey>?relay=<wss://relay-to-connect-on>&metadata
## Request Events `kind: 24133`
```json
```jsonc
{
"id": <id>,
"kind": 24133,

10
47.md
View File

@@ -173,7 +173,7 @@ Request:
"amount": 123, // invoice amount in msats, required
"pubkey": "03...", // payee pubkey, required
"preimage": "0123456789abcdef...", // preimage of the payment, optional
"tlv_records: [ // tlv records, optional
"tlv_records": [ // tlv records, optional
{
"type": 5482373484, // tlv type
"value": "0123456789abcdef" // hex encoded tlv value
@@ -208,7 +208,7 @@ Request:
"method": "multi_pay_keysend",
"params": {
"keysends": [
{"id": "4c5b24a351", pubkey": "03...", "amount": 123},
{"id": "4c5b24a351", "pubkey": "03...", "amount": 123},
{"id": "3da52c32a1", "pubkey": "02...", "amount": 567, "preimage": "abc123..", "tlv_records": [{"type": 696969, "value": "77616c5f6872444873305242454d353736"}]},
],
}
@@ -358,8 +358,7 @@ Request:
```jsonc
{
"method": "get_balance",
"params": {
}
"params": {}
}
```
@@ -379,8 +378,7 @@ Request:
```jsonc
{
"method": "get_info",
"params": {
}
"params": {}
}
```

4
50.md
View File

@@ -15,9 +15,9 @@ extensible framework for performing such queries.
## `search` filter field
A new `search` field is introduced for `REQ` messages from clients:
```json
```jsonc
{
...
// other fields on filter object...
"search": <string>
}
```

2
51.md
View File

@@ -111,7 +111,7 @@ Some clients have used these lists in the past, but they should work on transiti
### A _release artifact set_ of an Example App
```json
```jsonc
{
"id": "567b41fc9060c758c4216fe5f8d3df7c57daad7ae757fa4606f0c39d4dd220ef",
"pubkey": "d6dc95542e18b8b7aec2f14610f55c335abebec76f3db9e58c254661d0593a0c",

10
53.md
View File

@@ -16,7 +16,7 @@ A special event with `kind:30311` "Live Event" is defined as an _addressable eve
For example:
```json
```jsonc
{
"kind": 30311,
"tags": [
@@ -35,10 +35,10 @@ For example:
["p", "91cf9..4e5ca", "wss://provider1.com/", "Host", "<proof>"],
["p", "14aeb..8dad4", "wss://provider2.com/nostr", "Speaker"],
["p", "612ae..e610f", "ws://provider3.com/ws", "Participant"],
["relays", "wss://one.com", "wss://two.com", ...]
["relays", "wss://one.com", "wss://two.com", /*...*/]
],
"content": "",
...
// other fields...
}
```
@@ -64,14 +64,14 @@ This feature is important to avoid malicious event owners adding large account h
Event `kind:1311` is live chat's channel message. Clients MUST include the `a` tag of the activity with a `root` marker. Other Kind-1 tags such as `reply` and `mention` can also be used.
```json
```jsonc
{
"kind": 1311,
"tags": [
["a", "30311:<Community event author pubkey>:<d-identifier of the community>", "<Optional relay url>", "root"],
],
"content": "Zaps to live streams is beautiful.",
...
// other fields...
}
```

28
54.md
View File

@@ -6,12 +6,12 @@ Wiki
`draft` `optional`
This 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.
This NIP defines `kind:30818` (an _addressable event_) for 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.
Articles are identified by lowercase, normalized ascii `d` tags.
### Articles
```jsonc
```json
{
"content": "A wiki is a hypertext publication collaboratively edited and managed by its own audience.",
"tags": [
@@ -26,21 +26,25 @@ Articles are identified by lowercase, normalized ascii `d` tags.
- Any non-letter character MUST be converted to a `-`.
- All letters MUST be converted to lowercase.
### Content rules
### Content
The content should be Asciidoc, following the same rules as of [NIP-23](23.md), although it takes some extra (optional) metadata tags:
The `content` should be Asciidoc with two extra functionalities: **wikilinks** and **nostr:...** links.
- `title`: for when the display title should be different from the `d` tag.
- `summary`: for display in lists.
- `a` and `e`: for referencing the original event a wiki article was forked from.
One 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.
Unlike normal Asciidoc links `http://example.com[]` that link to external 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.
Wikilinks can take these two forms:
1. `[[Target Page]]` -- in this case it will link to the page `target-page` (according to `d` tag normalization rules above) and be displayed as `Target Page`;
2. `[[target page|see this]]` -- in this case it will link to the page `target-page`, but will be displayed as `see this`.
`nostr:...` links, as per [NIP-21](21.md), should link to profiles or arbitrary Nostr events. Although it is not recommended to link to specific versions of articles -- instead the _wikilink_ syntax should be preferred, since it should be left to the reader and their client to decide what version of any given article they want to read.
### Optional extra tags
- `title`: for when the display title should be different from the `d` tag.
- `summary`: for display in lists.
- `a` and `e`: for referencing the original event a wiki article was forked from.
### Merge Requests
Event `kind:818` represents a request to merge from a forked article into the source. It is directed to a pubkey and references the original article and the modified event.
@@ -96,13 +100,13 @@ Asciidoc has a strict spec, multiple implementations in many languages, and supp
# Appendix 1: Merge requests
Users can request other users to get their entries merged into someone else's entry by creating a `kind:818` event.
```jsonc
```json
{
"content": "I added information about how to make hot ice-creams",
"kind": 818,
"tags": [
[ "a", "30818:<destination-pubkey>:hot-ice-creams", "<relay-url>" ],
[ "e", "<version-against-which-the-modification-was-made>", "<relay-url>' ],
[ "e", "<version-against-which-the-modification-was-made>", "<relay-url>" ],
[ "p", "<destination-pubkey>" ],
[ "e", "<version-to-be-merged>", "<relay-url>", "source" ]
]
@@ -114,4 +118,4 @@ Users can request other users to get their entries merged into someone else's en
`e` tag: optional version of the article in which this modifications is based
`e` tag with `source` marker: the ID of the event that should be merged. This event id MUST be of a `kind:30818` as defined in this NIP.
The destination-pubkey (the pubkey being requested to merge something into their article can create [[NIP-25]] reactions that tag the `kind:818` event with `+` or `-`
The destination-pubkey is the pubkey being requested to merge something into their article can create [[NIP-25]] reactions that tag the `kind:818` event with `+` or `-`

6
55.md
View File

@@ -1,6 +1,8 @@
# NIP-55
NIP-55
======
## Android Signer Application
Android Signer Application
--------------------------
`draft` `optional`

12
56.md
View File

@@ -41,7 +41,7 @@ further qualification and querying.
Example events
--------------
```json
```jsonc
{
"kind": 1984,
"tags": [
@@ -50,9 +50,11 @@ Example events
["l", "NS-nud", "social.nos.ontology"]
],
"content": "",
...
// other fields...
}
```
```jsonc
{
"kind": 1984,
"tags": [
@@ -60,16 +62,18 @@ Example events
["p", <pubkey>]
],
"content": "He's insulting the king!",
...
// other fields...
}
```
```jsonc
{
"kind": 1984,
"tags": [
["p", <impersonator pubkey>, "impersonation"]
],
"content": "Profile is impersonating nostr:<victim bech32 pubkey>",
...
// other fields...
}
```

2
57.md
View File

@@ -171,7 +171,7 @@ A client can retrieve `zap receipt`s on events and pubkeys using a NIP-01 filter
When an event includes one or more `zap` tags, clients wishing to zap it SHOULD calculate the lnurl pay request based on the tags value instead of the event author's profile field. The tag's second argument is the `hex` string of the receiver's pub key and the third argument is the relay to download the receiver's metadata (Kind-0). An optional fourth parameter specifies the weight (a generalization of a percentage) assigned to the respective receiver. Clients should parse all weights, calculate a sum, and then a percentage to each receiver. If weights are not present, CLIENTS should equally divide the zap amount to all receivers. If weights are only partially present, receivers without a weight should not be zapped (`weight = 0`).
```js
```jsonc
{
"tags": [
[ "zap", "82341f882b6eabcd2ba7f1ef90aad961cf074af15b9ef44a09f9d2a8fbfbe6a2", "wss://nostr.oxtr.dev", "1" ], // 25%

12
58.md
View File

@@ -74,7 +74,7 @@ Clients SHOULD attempt to render the most appropriate badge thumbnail according
### Example of a Badge Definition event
```json
```jsonc
{
"pubkey": "alice",
"kind": 30009,
@@ -85,13 +85,13 @@ Clients SHOULD attempt to render the most appropriate badge thumbnail according
["image", "https://nostr.academy/awards/bravery.png", "1024x1024"],
["thumb", "https://nostr.academy/awards/bravery_256x256.png", "256x256"]
],
...
// other fields...
}
```
### Example of Badge Award event
```json
```jsonc
{
"id": "<badge award event id>",
"kind": 8,
@@ -101,14 +101,14 @@ Clients SHOULD attempt to render the most appropriate badge thumbnail according
["p", "bob", "wss://relay"],
["p", "charlie", "wss://relay"]
],
...
// other fields...
}
```
### Example of a Profile Badges event
Honorable Bob The Brave:
```json
```jsonc
{
"kind": 30008,
"pubkey": "bob",
@@ -119,6 +119,6 @@ Honorable Bob The Brave:
["a", "30009:alice:honor"],
["e", "<honor badge award event id>", "wss://nostr.academy"]
],
...
// other fields...
}
```

4
59.md
View File

@@ -41,7 +41,7 @@ A `seal` is a `kind:13` event that wraps a `rumor` with the sender's regular key
to a receiver's pubkey but there is no `p` tag pointing to the receiver. There is no way to know who the rumor is for
without the receiver's or the sender's private key. The only public information in this event is who is signing it.
```js
```json
{
"id": "<id>",
"pubkey": "<real author's pubkey>",
@@ -60,7 +60,7 @@ Tags MUST must always be empty in a `kind:13`. The inner event MUST always be un
A `gift wrap` event is a `kind:1059` event that wraps any other event. `tags` SHOULD include any information
needed to route the event to its intended recipient, including the recipient's `p` tag or [NIP-13](13.md) proof of work.
```js
```json
{
"id": "<id>",
"pubkey": "<random, one-time-use pubkey>",

14
64.md
View File

@@ -2,7 +2,7 @@ NIP-64
======
Chess (Portable Game Notation)
-----
------------------------------
`draft` `optional`
@@ -16,23 +16,23 @@ The `.content` of these notes is a string representing a [PGN-database][pgn_form
### Notes
```json
```jsonc
{
"kind": 64,
"content": "1. e4 *",
...
// other fields...
}
```
```json
```jsonc
{
"kind": 64,
"tags": [
["alt", "Fischer vs. Spassky in Belgrade on 1992-11-04 (F/S Return Match, Round 29)"],
...
// rest of tags...
],
"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"
...
"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",
// other fields...
}
```

4
65.md
View File

@@ -12,7 +12,7 @@ The event MUST include a list of `r` tags with relay URIs and a `read` or `write
The `.content` is not used.
```json
```jsonc
{
"kind": 10002,
"tags": [
@@ -22,7 +22,7 @@ The `.content` is not used.
["r", "wss://nostr-relay.example.com", "read"]
],
"content": "",
...other fields
// other fields...
}
```

4
71.md
View File

@@ -2,7 +2,7 @@ NIP-71
======
Video Events
---------------
------------
`draft` `optional`
@@ -42,7 +42,7 @@ The list of tags are as follows:
* `p` (optional, repeated) 32-bytes hex pubkey of a participant in the video, optional recommended relay URL
* `r` (optional, repeated) references / links to web pages
```json
```jsonc
{
"id": <32-bytes lowercase hex-encoded SHA-256 of the the serialized event data>,
"pubkey": <32-bytes lowercase hex-encoded public key of the event creator>,

6
72.md
View File

@@ -35,7 +35,7 @@ The goal of this NIP is to enable public communities. It defines the replaceable
["relay", "<relay where to send and receive approvals>", "approvals"],
["relay", "<relay where to post requests to and fetch approvals from>"]
],
...
// other fields...
}
```
@@ -50,7 +50,7 @@ Any Nostr event can be posted to a community. Clients MUST add one or more commu
["a", "34550:<community event author pubkey>:<community-d-identifier>", "<optional-relay-url>"],
],
"content": "hello world",
// ...
// other fields...
}
```
@@ -75,7 +75,7 @@ Moderators MAY request deletion of their approval of a post at any time using [N
["k", "<post-request-kind>"]
],
"content": "<the full approved event, JSON-encoded>",
// ...
// other fields...
}
```

2
73.md
View File

@@ -2,7 +2,7 @@ NIP-73
======
External Content IDs
-------------------------
--------------------
`draft` `optional`

20
75.md
View File

@@ -21,15 +21,16 @@ The following tags are defined as REQUIRED.
Example event:
```json
```jsonc
{
"kind": 9041,
"tags": [
["relays", "wss://alicerelay.example.com", "wss://bobrelay.example.com", ...],
["relays", "wss://alicerelay.example.com", "wss://bobrelay.example.com", /*...*/],
["amount", "210000"],
],
"content": "Nostrasia travel expenses",
...
// other fields...
}
```
The following tags are OPTIONAL.
@@ -38,18 +39,18 @@ The following tags are OPTIONAL.
- `image` - an image for the goal
- `summary` - a brief description
```json
```jsonc
{
"kind": 9041,
"tags": [
["relays", "wss://alicerelay.example.com", "wss://bobrelay.example.com", ...],
["relays", "wss://alicerelay.example.com", "wss://bobrelay.example.com", /*...*/],
["amount", "210000"],
["closed_at", "<unix timestamp in seconds>"],
["image", "<image URL>"],
["summary", "<description of the goal>"],
],
"content": "Nostrasia travel expenses",
...
// other fields...
}
```
@@ -59,15 +60,14 @@ The goal MAY include multiple beneficiary pubkeys by specifying [`zap` tags](57.
Addressable events can link to a goal by using a `goal` tag specifying the event id and an optional relay hint.
```json
```jsonc
{
...
"kind": 3xxxx,
"tags": [
...
["goal", "<event id>", "<Relay URL (optional)>"],
// rest of tags...
],
...
// other fields...
}
```

4
84.md
View File

@@ -26,14 +26,14 @@ useful when highlighting non-nostr content for which the client might be able to
(e.g. prompting the user or reading a `<meta name="nostr:nprofile1..." />` tag on the document). A role MAY be included as the
last value of the tag.
```json
```jsonc
{
"tags": [
["p", "<pubkey-hex>", "<relay-url>", "author"],
["p", "<pubkey-hex>", "<relay-url>", "author"],
["p", "<pubkey-hex>", "<relay-url>", "editor"]
],
...
// other fields...
}
```

22
89.md
View File

@@ -27,7 +27,7 @@ There are three actors to this workflow:
## Events
### Recommendation event
```json
```jsonc
{
"kind": 31989,
"pubkey": <recommender-user-pubkey>,
@@ -35,7 +35,8 @@ There are three actors to this workflow:
["d", <supported-event-kind>],
["a", "31990:app1-pubkey:<d-identifier>", "wss://relay1", "ios"],
["a", "31990:app2-pubkey:<d-identifier>", "wss://relay2", "web"]
]
],
// other fields...
}
```
@@ -47,7 +48,7 @@ The second value of the tag SHOULD be a relay hint.
The third value of the tag SHOULD be the platform where this recommendation might apply.
## Handler information
```json
```jsonc
{
"kind": 31990,
"pubkey": "<application-pubkey>",
@@ -59,7 +60,8 @@ The third value of the tag SHOULD be the platform where this recommendation migh
["web", "https://..../p/<bech32>", "nprofile"],
["web", "https://..../e/<bech32>"],
["ios", ".../<bech32>"]
]
],
// other fields...
}
```
@@ -77,13 +79,13 @@ A tag without a second value in the array SHOULD be considered a generic handler
# Client tag
When publishing events, clients MAY include a `client` tag. Identifying the client that published the note. This tag is a tuple of `name`, `address` identifying a handler event and, a relay `hint` for finding the handler event. This has privacy implications for users, so clients SHOULD allow users to opt-out of using this tag.
```json
```jsonc
{
"kind": 1,
"tags": [
["client", "My Client", "31990:app1-pubkey:<d-identifier>", "wss://relay1"]
]
...
// other fields...
}
```
@@ -99,14 +101,14 @@ The client MIGHT query for the user's and the user's follows handler.
### User A recommends a `kind:31337`-handler
User A might be a user of Zapstr, a `kind:31337`-centric client (tracks). Using Zapstr, user A publishes an event recommending Zapstr as a `kind:31337`-handler.
```json
```jsonc
{
"kind": 31989,
"tags": [
["d", "31337"],
["a", "31990:1743058db7078661b94aaf4286429d97ee5257d14a86d6bfa54cb0482b876fb0:abcd", <relay-url>, "web"]
],
...
// other fields...
}
```
@@ -115,7 +117,7 @@ User B might see in their timeline an event referring to a `kind:31337` event (e
User B's client, not knowing how to handle a `kind:31337` might display the event using its `alt` tag (as described in NIP-31). When the user clicks on the event, the application queries for a handler for this `kind`:
```json
```
["REQ", <id>, { "kinds": [31989], "#d": ["31337"], "authors": [<user>, <users-contact-list>] }]
```
@@ -126,6 +128,6 @@ User B's client sees the application's `kind:31990` which includes the informati
### Alternative query bypassing `kind:31989`
Alternatively, users might choose to query directly for `kind:31990` for an event kind. Clients SHOULD be careful doing this and use spam-prevention mechanisms or querying high-quality restricted relays to avoid directing users to malicious handlers.
```json
```
["REQ", <id>, { "kinds": [31990], "#k": [<desired-event-kind>], "authors": [...] }]
```

26
90.md
View File

@@ -36,7 +36,7 @@ There are two actors in the workflow described in this NIP:
## Job request (`kind:5000-5999`)
A request to process data, published by a customer. This event signals that a customer is interested in receiving the result of some kind of compute.
```json
```jsonc
{
"kind": 5xxx, // kind in 5000-5999 range
"content": "",
@@ -46,7 +46,8 @@ A request to process data, published by a customer. This event signals that a cu
[ "relays", "wss://..." ],
[ "bid", "<msat-amount>" ],
[ "t", "bitcoin" ]
]
],
// other fields...
}
```
@@ -81,19 +82,18 @@ If the user wants to keep the input parameters a secret, they can encrypt the `i
["param", "top-p", "0.7"],
["param", "frequency_penalty", "1"]
]
```
This param data will be encrypted and added to the `content` field and `p` tag should be present
```json
```jsonc
{
"content": "BE2Y4xvS6HIY7TozIgbEl3sAHkdZoXyLRRkZv4fLPh3R7LtviLKAJM5qpkC7D6VtMbgIt4iNcMpLtpo...",
"tags": [
["p", "04f74530a6ede6b24731b976b8e78fb449ea61f40ff10e3d869a3030c4edc91f"],
["encrypted"]
],
...
// other fields...
}
```
@@ -102,7 +102,7 @@ This param data will be encrypted and added to the `content` field and `p` tag s
Service providers publish job results, providing the output of the job result. They should tag the original job request event id as well as the customer's pubkey.
```json
```jsonc
{
"pubkey": "<service-provider pubkey>",
"content": "<payload>",
@@ -114,7 +114,7 @@ Service providers publish job results, providing the output of the job result. T
["p", "<customer's-pubkey>"],
["amount", "requested-payment-amount", "<optional-bolt11>"]
],
...
// other fields...
}
```
@@ -127,7 +127,7 @@ Service providers publish job results, providing the output of the job result. T
If the request has encrypted params, then output should be encrypted and placed in `content` field. If the output is encrypted, then avoid including `i` tag with input-data as clear text.
Add a tag encrypted to mark the output content as `encrypted`
```json
```jsonc
{
"pubkey": "<service-provider pubkey>",
"content": "<encrypted payload>",
@@ -139,7 +139,7 @@ Add a tag encrypted to mark the output content as `encrypted`
["amount", "requested-payment-amount", "<optional-bolt11>"],
["encrypted"]
],
...
// other fields...
}
```
@@ -147,7 +147,7 @@ Add a tag encrypted to mark the output content as `encrypted`
Service providers can give feedback about a job back to the customer.
```json
```jsonc
{
"kind": 7000,
"content": "<empty-or-payload>",
@@ -157,7 +157,7 @@ Service providers can give feedback about a job back to the customer.
["e", "<job-request-id>", "<relay-hint>"],
["p", "<customer's-pubkey>"],
],
...
// other fields...
}
```
@@ -211,7 +211,7 @@ This gives a higher level of flexibility to service providers (which sophisticat
# Appendix 2: Service provider discoverability
Service Providers MAY use NIP-89 announcements to advertise their support for job kinds:
```js
```jsonc
{
"kind": 31990,
"pubkey": "<pubkey>",
@@ -223,7 +223,7 @@ Service Providers MAY use NIP-89 announcements to advertise their support for jo
["k", "5005"], // e.g. translation
["t", "bitcoin"] // e.g. optionally advertises it specializes in bitcoin audio transcription that won't confuse "Drivechains" with "Ridechains"
],
...
// other fields...
}
```

4
94.md
View File

@@ -27,7 +27,7 @@ This NIP specifies the use of the `1063` event type, having in `content` a descr
* `alt` (optional) description for accessibility
* `fallback` (optional) zero or more fallback file sources in case `url` fails
```json
```jsonc
{
"kind": 1063,
"tags": [
@@ -46,7 +46,7 @@ This NIP specifies the use of the `1063` event type, having in `content` a descr
["alt", <description>]
],
"content": "<caption>",
...
// other fields...
}
```

59
96.md
View File

@@ -1,6 +1,8 @@
# NIP-96
NIP-96
======
## HTTP File Storage Integration
HTTP File Storage Integration
-----------------------------
`draft` `optional`
@@ -17,7 +19,7 @@ will not have to learn anything about nostr relays.
File storage servers wishing to be accessible by nostr users should opt-in by making available an https route at `/.well-known/nostr/nip96.json` with `api_url`:
```js
```jsonc
{
// Required
// File upload and deletion are served from this url
@@ -57,7 +59,7 @@ File storage servers wishing to be accessible by nostr users should opt-in by ma
"file_expiration": [14, 90],
"media_transformations": {
"image": [
'resizing'
"resizing"
]
}
}
@@ -125,14 +127,14 @@ The `server` MUST link the user's `pubkey` string as the owner of the file so to
The upload response is a json object as follows:
```js
```jsonc
{
// "success" if successful or "error" if not
status: "success",
"status": "success",
// Free text success, failure or info message
message: "Upload successful.",
"message": "Upload successful.",
// Optional. See "Delayed Processing" section
processing_url: "...",
"processing_url": "...",
// This uses the NIP-94 event format but DO NOT need
// to fill some fields like "id", "pubkey", "created_at" and "sig"
//
@@ -141,9 +143,9 @@ The upload response is a json object as follows:
// and, optionally, all file metadata the server wants to make available
//
// nip94_event field is absent if unsuccessful upload
nip94_event: {
"nip94_event2": {
// Required tags: "url" and "ox"
tags: [
"tags": [
// Can be same from /.well-known/nostr/nip96.json's "download_url" field
// (or "api_url" field if "download_url" is absent or empty) with appended
// original file hash.
@@ -164,12 +166,12 @@ The upload response is a json object as follows:
// The server can but does not need to store this value.
["x", "543244319525d9d08dd69cb716a18158a249b7b3b3ec4bbde5435543acb34443"],
// Optional. Recommended for helping clients to easily know file type before downloading it.
["m", "image/png"]
["m", "image/png"],
// Optional. Recommended for helping clients to reserve an adequate UI space to show the file before downloading it.
["dim", "800x600"]
// ... other optional NIP-94 tags
],
content: ""
"content": ""
},
// ... other custom fields (please consider adding them to this NIP or to NIP-94 tags)
}
@@ -200,12 +202,12 @@ the file processing is done.
If the processing isn't done, the server should reply at the `processing_url` url with **200 OK** and the following JSON:
```
```jsonc
{
// It should be "processing". If "error" it would mean the processing failed.
status: "processing",
message: "Processing. Please check again later for updated status.",
percentage: 15 // Processing percentage. An integer between 0 and 100.
"status": "processing",
"message": "Processing. Please check again later for updated status.",
"percentage": 15 // Processing percentage. An integer between 0 and 100.
}
```
@@ -268,10 +270,10 @@ in the same file hash).
The successful response is a 200 OK one with just basic JSON fields:
```
```json
{
status: "success",
message: "File deleted."
"status": "success",
"message": "File deleted."
}
```
@@ -285,7 +287,7 @@ Returns a list of files linked to the authenticated users pubkey.
Example Response:
```js
```jsonc
{
"count": 1, // server page size, eg. max(1, min(server_max_page_size, arg_count))
"total": 1, // total number of files
@@ -293,17 +295,16 @@ Example Response:
"files": [
{
"tags": [
["ox": "719171db19525d9d08dd69cb716a18158a249b7b3b3ec4bbdec5698dca104b7b"],
["x": "5d2899290e0e69bcd809949ee516a4a1597205390878f780c098707a7f18e3df"],
["ox", "719171db19525d9d08dd69cb716a18158a249b7b3b3ec4bbdec5698dca104b7b"],
["x", "5d2899290e0e69bcd809949ee516a4a1597205390878f780c098707a7f18e3df"],
["size", "123456"],
["alt", "a meme that makes you laugh"],
["expiration", "1715691139"],
// ...other metadata
]
],
"content": "haha funny meme", // caption
"created_at": 1715691130 // upload timestamp
},
...
}
]
}
```
@@ -322,14 +323,14 @@ Note: HTTP File Storage Server developers may skip this section. This is meant f
A File Server Preference event is a kind 10096 replaceable event meant to select one or more servers the user wants
to upload files to. Servers are listed as `server` tags:
```js
{
// ...
```json
{.
"kind": 10096,
"content": "",
"tags": [
["server", "https://file.server.one"],
["server", "https://file.server.two"]
]
],
// other fields...
}
```

2
99.md
View File

@@ -54,7 +54,7 @@ Other standard tags that might be useful.
## Example Event
```json
```jsonc
{
"kind": 30402,
"created_at": 1675642635,

View File

@@ -131,6 +131,8 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
| `1971` | Problem Tracker | [nostrocket][nostrocket] |
| `1984` | Reporting | [56](56.md) |
| `1985` | Label | [32](32.md) |
| `1986` | Relay reviews | |
| `1987` | AI Embeddings / Vector lists | [NKBIP-02] |
| `2003` | Torrent | [35](35.md) |
| `2004` | Torrent Comment | [35](35.md) |
| `2022` | Coinjoin Pool | [joinstr][joinstr] |
@@ -140,6 +142,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
| `7000` | Job Feedback | [90](90.md) |
| `9000`-`9030` | Group Control Events | [29](29.md) |
| `9041` | Zap Goal | [75](75.md) |
| `9467` | Tidal login | [Tidal-nostr] |
| `9734` | Zap Request | [57](57.md) |
| `9735` | Zap | [57](57.md) |
| `9802` | Highlights | [84](84.md) |
@@ -155,6 +158,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
| `10015` | Interests list | [51](51.md) |
| `10030` | User emoji list | [51](51.md) |
| `10050` | Relay list to receive DMs | [51](51.md), [17](17.md) |
| `10063` | User server list | [blossom] |
| `10096` | File storage server list | [96](96.md) |
| `13194` | Wallet Info | [47](47.md) |
| `21000` | Lightning Pub RPC | [Lightning.Pub][lnpub] |
@@ -162,6 +166,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
| `23194` | Wallet Request | [47](47.md) |
| `23195` | Wallet Response | [47](47.md) |
| `24133` | Nostr Connect | [46](46.md) |
| `24242` | Blobs stored on mediaservers | [blossom] |
| `27235` | HTTP Auth | [98](98.md) |
| `30000` | Follow sets | [51](51.md) |
| `30001` | Generic lists | [51](51.md) |
@@ -169,6 +174,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
| `30003` | Bookmark sets | [51](51.md) |
| `30004` | Curation sets | [51](51.md) |
| `30005` | Video sets | [51](51.md) |
| `30007` | Kind mute sets | [51](51.md) |
| `30008` | Profile Badges | [58](58.md) |
| `30009` | Badge Definition | [58](58.md) |
| `30015` | Interest sets | [51](51.md) |
@@ -179,6 +185,8 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
| `30023` | Long-form Content | [23](23.md) |
| `30024` | Draft Long-form Content | [23](23.md) |
| `30030` | Emoji sets | [51](51.md) |
| `30040` | Modular Article Header | [NKBIP-01] |
| `30041` | Modular Article Content | [NKBIP-01] |
| `30063` | Release artifact sets | [51](51.md) |
| `30078` | Application-specific Data | [78](78.md) |
| `30311` | Live Event | [53](53.md) |
@@ -202,10 +210,14 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
| `34550` | Community Definition | [72](72.md) |
| `39000-9` | Group metadata events | [29](29.md) |
[NUD: Custom Feeds]: https://wikifreedia.xyz/cip-01/97c70a44366a6535c1
[NUD: Custom Feeds]: https://wikifreedia.xyz/cip-01/
[nostrocket]: https://github.com/nostrocket/NIPS/blob/main/Problems.md
[lnpub]: https://github.com/shocknet/Lightning.Pub/blob/master/proto/autogenerated/client.md
[joinstr]: https://gitlab.com/1440000bytes/joinstr/-/blob/main/NIP.md
[NKBIP-01]: https://wikistr.com/nkbip-01
[NKBIP-02]: https://wikistr.com/nkbip-02
[Blossom]: https://wikistr.com/blossom
[Tidal-nostr]: https://wikistr.com/tidal-nostr
## Message types