mirror of
https://github.com/nostr-protocol/nips.git
synced 2025-12-08 16:18:50 +00:00
Compare commits
33 Commits
drafts
...
nostrband-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df577ccd11 | ||
|
|
cc3fbab153 | ||
|
|
3f11c00fb9 | ||
|
|
190122fd8d | ||
|
|
0782ebe0bc | ||
|
|
512caf7fcd | ||
|
|
6c62751e57 | ||
|
|
0e3d1cd5d8 | ||
|
|
5b6ca881e2 | ||
|
|
0f376a7aa4 | ||
|
|
d96f6f852a | ||
|
|
76fd221ff1 | ||
|
|
1f8bbbfb50 | ||
|
|
2561566af7 | ||
|
|
c91098af86 | ||
|
|
936befbf9b | ||
|
|
e42aae6184 | ||
|
|
cd09e6c9d8 | ||
|
|
42370a3d30 | ||
|
|
7622cdc9c0 | ||
|
|
b1a3ca4d0a | ||
|
|
ee21566cc4 | ||
|
|
342e5db8c9 | ||
|
|
b88f716eef | ||
|
|
e3911cc9e6 | ||
|
|
2f3b68bb44 | ||
|
|
9acad1c62c | ||
|
|
71ca3f27f3 | ||
|
|
9d4f2b42b4 | ||
|
|
6b4e0f80c2 | ||
|
|
7e150faed4 | ||
|
|
97bf5266d7 | ||
|
|
ed128aef46 |
5
01.md
5
01.md
@@ -85,10 +85,11 @@ As a convention, all single-letter (only english alphabet letters: a-z, A-Z) key
|
||||
|
||||
### Kinds
|
||||
|
||||
Kinds specify how clients should interpret the meaning of each event and the other fields of each event (e.g. an `"r"` tag may have a meaning in an event of kind 1 and an entirely different meaning in an event of kind 10002). Each NIP may define the meaning of a set of kinds that weren't defined elsewhere. This NIP defines two basic kinds:
|
||||
Kinds specify how clients should interpret the meaning of each event and the other fields of each event (e.g. an `"r"` tag may have a meaning in an event of kind 1 and an entirely different meaning in an event of kind 10002). Each NIP may define the meaning of a set of kinds that weren't defined elsewhere. [NIP-10](10.md), for instance, especifies the `kind:1` text note for social media applications.
|
||||
|
||||
This NIP defines one basic kind:
|
||||
|
||||
- `0`: **user metadata**: the `content` is set to a stringified JSON object `{name: <username>, about: <string>, picture: <url, string>}` describing the user who created the event. [Extra metadata fields](24.md#kind-0) may be set. A relay may delete older events once it gets a new one for the same pubkey.
|
||||
- `1`: **text note**: the `content` is set to the **plaintext** content of a note (anything the user wants to say). Content that must be parsed, such as Markdown and HTML, should not be used. Clients should also not parse content as those.
|
||||
|
||||
And also a convention for kind ranges that allow for easier experimentation and flexibility of relay implementation:
|
||||
|
||||
|
||||
16
10.md
16
10.md
@@ -1,14 +1,22 @@
|
||||
NIP-10
|
||||
======
|
||||
|
||||
|
||||
On "e" and "p" tags in Text Events (kind 1)
|
||||
-------------------------------------------
|
||||
Text Notes and Threads
|
||||
----------------------
|
||||
|
||||
`draft` `optional`
|
||||
|
||||
This NIP defines `kind:1` as a simple plaintext note.
|
||||
|
||||
## Abstract
|
||||
This NIP describes how to use "e" and "p" tags in text events, especially those that are replies to other text events. It helps clients thread the replies into a tree rooted at the original event.
|
||||
|
||||
This NIP describes how to use "e" and "p" tags in text events, especially those that are replies to other text events. It helps clients thread the replies into a tree rooted at the original event.
|
||||
|
||||
The `.content` property contains some human-readable text.
|
||||
|
||||
`e` and `p` tags can be used to define note threads, replies and mentions.
|
||||
|
||||
Markup languages such as markdown and HTML SHOULD NOT be used.
|
||||
|
||||
## Marked "e" tags (PREFERRED)
|
||||
`["e", <event-id>, <relay-url>, <marker>, <pubkey>]`
|
||||
|
||||
2
18.md
2
18.md
@@ -10,6 +10,7 @@ A repost is a `kind 6` event that is used to signal to followers
|
||||
that a `kind 1` text note is worth reading.
|
||||
|
||||
The `content` of a repost event is _the stringified JSON of the reposted note_. It MAY also be empty, but that is not recommended.
|
||||
Reposts of [NIP-70](70.md)-protected events SHOULD always have an empty `content`.
|
||||
|
||||
The repost event MUST include an `e` tag with the `id` of the note that is
|
||||
being reposted. That tag MUST include a relay URL as its third entry
|
||||
@@ -41,3 +42,4 @@ as a "generic repost", that can include any kind of event inside other than
|
||||
|
||||
`kind 16` reposts SHOULD contain a `k` tag with the stringified kind number
|
||||
of the reposted event as its value.
|
||||
|
||||
|
||||
33
22.md
33
22.md
@@ -13,6 +13,9 @@ It uses `kind:1111` with plaintext `.content` (no HTML, Markdown, or other forma
|
||||
Comments MUST point to the root scope using uppercase tag names (e.g. `K`, `E`, `A` or `I`)
|
||||
and MUST point to the parent item with lowercase ones (e.g. `k`, `e`, `a` or `i`).
|
||||
|
||||
Comments MUST point to the authors when one is available (i.e. tagging a nostr event). `P` for the root scope
|
||||
and `p` for the author of the parent item.
|
||||
|
||||
```jsonc
|
||||
{
|
||||
kind: 1111,
|
||||
@@ -23,10 +26,16 @@ and MUST point to the parent item with lowercase ones (e.g. `k`, `e`, `a` or `i`
|
||||
// the root item kind
|
||||
["K", "<root kind>"],
|
||||
|
||||
// pubkey of the author of the root scope event
|
||||
["P", "<root-pubkey>", "relay-url-hint"],
|
||||
|
||||
// parent item: event addresses, event ids, or i-tags.
|
||||
["<a, e, i>", "<address, id or i-value>", "<relay or web page hint>", "<parent event's pubkey, if an e tag>"],
|
||||
// parent item kind
|
||||
["k", "<parent comment kind>"]
|
||||
["k", "<parent comment kind>"],
|
||||
|
||||
// parent item pubkey
|
||||
["p", "<parent-pubkey>", "relay-url-hint"]
|
||||
]
|
||||
// other fields
|
||||
}
|
||||
@@ -46,11 +55,8 @@ Their uppercase versions use the same type of values but relate to the root item
|
||||
```
|
||||
|
||||
`p` tags SHOULD be used when mentioning pubkeys in the `.content` with [NIP-21](21.md).
|
||||
If the parent item is an event, a `p` tag set to the parent event's author SHOULD be added.
|
||||
|
||||
```json
|
||||
["p", "<pubkey>", "<relay-url>"]
|
||||
```
|
||||
Comments MUST NOT be used to reply to kind 1 notes. [NIP-10](10.md) should instead be followed.
|
||||
|
||||
## Examples
|
||||
|
||||
@@ -65,13 +71,17 @@ A comment on a blog post looks like this:
|
||||
["A", "30023:3c9849383bdea883b0bd16fece1ed36d37e37cdde3ce43b17ea4e9192ec11289:f9347ca7", "wss://example.relay"],
|
||||
// the root kind
|
||||
["K", "30023"],
|
||||
// author of root event
|
||||
["P", "3c9849383bdea883b0bd16fece1ed36d37e37cdde3ce43b17ea4e9192ec11289", "wss://example.relay"]
|
||||
|
||||
// the parent event address (same as root for top-level comments)
|
||||
["a", "30023:3c9849383bdea883b0bd16fece1ed36d37e37cdde3ce43b17ea4e9192ec11289:f9347ca7", "wss://example.relay"],
|
||||
// when the parent event is replaceable or addressable, also include an `e` tag referencing its id
|
||||
["e", "5b4fc7fed15672fefe65d2426f67197b71ccc82aa0cc8a9e94f683eb78e07651", "wss://example.relay"],
|
||||
// the parent event kind
|
||||
["k", "30023"]
|
||||
["k", "30023"],
|
||||
// author of the parent event
|
||||
["p", "3c9849383bdea883b0bd16fece1ed36d37e37cdde3ce43b17ea4e9192ec11289", "wss://example.relay"]
|
||||
]
|
||||
// other fields
|
||||
}
|
||||
@@ -88,11 +98,14 @@ A comment on a [NIP-94](94.md) file looks like this:
|
||||
["E", "768ac8720cdeb59227cf95e98b66560ef03d8bc9a90d721779e76e68fb42f5e6", "wss://example.relay", "3721e07b079525289877c366ccab47112bdff3d1b44758ca333feb2dbbbbe5bb"],
|
||||
// the root kind
|
||||
["K", "1063"],
|
||||
// author of the root event
|
||||
["P", "3721e07b079525289877c366ccab47112bdff3d1b44758ca333feb2dbbbbe5bb"],
|
||||
|
||||
// the parent event id (same as root for top-level comments)
|
||||
["e", "768ac8720cdeb59227cf95e98b66560ef03d8bc9a90d721779e76e68fb42f5e6", "wss://example.relay", "3721e07b079525289877c366ccab47112bdff3d1b44758ca333feb2dbbbbe5bb"],
|
||||
// the parent kind
|
||||
["k", "1063"]
|
||||
["k", "1063"],
|
||||
["p", "3721e07b079525289877c366ccab47112bdff3d1b44758ca333feb2dbbbbe5bb"]
|
||||
]
|
||||
// other fields
|
||||
}
|
||||
@@ -109,11 +122,13 @@ A reply to a comment looks like this:
|
||||
["E", "768ac8720cdeb59227cf95e98b66560ef03d8bc9a90d721779e76e68fb42f5e6", "wss://example.relay", "fd913cd6fa9edb8405750cd02a8bbe16e158b8676c0e69fdc27436cc4a54cc9a"],
|
||||
// the root kind
|
||||
["K", "1063"],
|
||||
["P", "fd913cd6fa9edb8405750cd02a8bbe16e158b8676c0e69fdc27436cc4a54cc9a"],
|
||||
|
||||
// the parent event
|
||||
["e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36", "wss://example.relay", "93ef2ebaaf9554661f33e79949007900bbc535d239a4c801c33a4d67d3e7f546"],
|
||||
// the parent kind
|
||||
["k", "1111"]
|
||||
["k", "1111"],
|
||||
["p", "93ef2ebaaf9554661f33e79949007900bbc535d239a4c801c33a4d67d3e7f546"]
|
||||
]
|
||||
// other fields
|
||||
}
|
||||
@@ -178,7 +193,9 @@ A reply to a podcast comment:
|
||||
["e", "80c48d992a38f9c445b943a9c9f1010b396676013443765750431a9004bdac05", "wss://example.relay", "252f10c83610ebca1a059c0bae8255eba2f95be4d1d7bcfa89d7248a82d9f111"],
|
||||
// the parent comment kind
|
||||
["k", "1111"]
|
||||
["p", "252f10c83610ebca1a059c0bae8255eba2f95be4d1d7bcfa89d7248a82d9f111"]
|
||||
]
|
||||
// other fields
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
9
28.md
9
28.md
@@ -52,10 +52,17 @@ Clients MAY add additional metadata fields.
|
||||
|
||||
Clients SHOULD use [NIP-10](10.md) marked "e" tags to recommend a relay.
|
||||
|
||||
It is also possible to set the category name using the "t" tag. This category name can be searched and filtered.
|
||||
|
||||
```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>]],
|
||||
"tags": [
|
||||
["e", <channel_create_event_id>, <relay-url>, "root"],
|
||||
["t", <category_name-1>],
|
||||
["t", <category_name-2>],
|
||||
["t", <category_name-3>],
|
||||
],
|
||||
// other fields...
|
||||
}
|
||||
```
|
||||
|
||||
4
32.md
4
32.md
@@ -157,7 +157,7 @@ considered open for public use, and not proprietary. In other words, if there is
|
||||
namespace that fits your use case, use it even if it points to someone else's domain name.
|
||||
|
||||
Vocabularies MAY choose to fully qualify all labels within a namespace (for example,
|
||||
`["l", "com.example.vocabulary:my-label"]`. This may be preferred when defining more
|
||||
`["l", "com.example.vocabulary:my-label"]`). This may be preferred when defining more
|
||||
formal vocabularies that should not be confused with another namespace when querying
|
||||
without an `L` tag. For these vocabularies, all labels SHOULD include the namespace
|
||||
(rather than mixing qualified and unqualified labels).
|
||||
@@ -173,4 +173,4 @@ Appendix: Known Ontologies
|
||||
|
||||
Below is a non-exhaustive list of ontologies currently in widespread use.
|
||||
|
||||
- [social.ontolo.categories](https://ontolo.social/)
|
||||
- [social ontology categories](https://github.com/CLARIAH/awesome-humanities-ontologies)
|
||||
|
||||
12
44.md
12
44.md
@@ -8,11 +8,11 @@ Encrypted Payloads (Versioned)
|
||||
|
||||
The NIP introduces a new data format for keypair-based encryption. This NIP is versioned
|
||||
to allow multiple algorithm choices to exist simultaneously. This format may be used for
|
||||
many things, but MUST be used in the context of a signed event as described in NIP 01.
|
||||
many things, but MUST be used in the context of a signed event as described in NIP-01.
|
||||
|
||||
*Note*: this format DOES NOT define any `kind`s related to a new direct messaging standard,
|
||||
only the encryption required to define one. It SHOULD NOT be used as a drop-in replacement
|
||||
for NIP 04 payloads.
|
||||
for NIP-04 payloads.
|
||||
|
||||
## Versions
|
||||
|
||||
@@ -41,7 +41,7 @@ On its own, messages sent using this scheme have a number of important shortcomi
|
||||
- No post-compromise security: when a key is compromised, it is possible to decrypt all future conversations
|
||||
- No post-quantum security: a powerful quantum computer would be able to decrypt the messages
|
||||
- IP address leak: user IP may be seen by relays and all intermediaries between user and relay
|
||||
- Date leak: `created_at` is public, since it is a part of NIP 01 event
|
||||
- Date leak: `created_at` is public, since it is a part of NIP-01 event
|
||||
- Limited message size leak: padding only partially obscures true message length
|
||||
- No attachments: they are not supported
|
||||
|
||||
@@ -86,7 +86,7 @@ NIP-44 version 2 has the following design characteristics:
|
||||
- Content must be encoded from UTF-8 into byte array
|
||||
- Validate plaintext length. Minimum is 1 byte, maximum is 65535 bytes
|
||||
- Padding format is: `[plaintext_length: u16][plaintext][zero_bytes]`
|
||||
- Padding algorithm is related to powers-of-two, with min padded msg size of 32bytes
|
||||
- Padding algorithm is related to powers-of-two, with min padded msg size of 32 bytes
|
||||
- Plaintext length is encoded in big-endian as first 2 bytes of the padded blob
|
||||
5. Encrypt padded content
|
||||
- Use ChaCha20, with key and nonce from step 3
|
||||
@@ -148,8 +148,8 @@ validation rules, refer to BIP-340.
|
||||
- `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`.
|
||||
- Constants `c`:
|
||||
- `min_plaintext_size` is 1. 1bytes msg is padded to 32bytes.
|
||||
- `max_plaintext_size` is 65535 (64kB - 1). It is padded to 65536bytes.
|
||||
- `min_plaintext_size` is 1. 1 byte msg is padded to 32 bytes.
|
||||
- `max_plaintext_size` is 65535 (64kB - 1). It is padded to 65536 bytes.
|
||||
- Functions
|
||||
- `base64_encode(string)` and `base64_decode(bytes)` are Base64 ([RFC 4648](https://datatracker.ietf.org/doc/html/rfc4648), with padding)
|
||||
- `concat` refers to byte array concatenation
|
||||
|
||||
6
47.md
6
47.md
@@ -107,7 +107,7 @@ The content of notifications is encrypted with [NIP04](https://github.com/nostr-
|
||||
## Nostr Wallet Connect URI
|
||||
**client** discovers **wallet service** by scanning a QR code, handling a deeplink or pasting in a URI.
|
||||
|
||||
The **wallet service** generates this connection URI with protocol `nostr+walletconnect://` and base path it's hex-encoded `pubkey` with the following query string parameters:
|
||||
The **wallet service** generates this connection URI with protocol `nostr+walletconnect://` and base path its hex-encoded `pubkey` with the following query string parameters:
|
||||
|
||||
- `relay` Required. URL of the relay where the **wallet service** is connected and will be listening for events. May be more than one.
|
||||
- `secret` Required. 32-byte randomly generated hex encoded string. The **client** MUST use this to sign events and encrypt payloads when communicating with the **wallet service**.
|
||||
@@ -175,7 +175,7 @@ Request:
|
||||
Response:
|
||||
|
||||
For every invoice in the request, a separate response event is sent. To differentiate between the responses, each
|
||||
response event contains a `d` tag with the id of the invoice it is responding to, if no id was given, then the
|
||||
response event contains a `d` tag with the id of the invoice it is responding to; if no id was given, then the
|
||||
payment hash of the invoice should be used.
|
||||
|
||||
```jsonc
|
||||
@@ -247,7 +247,7 @@ Request:
|
||||
Response:
|
||||
|
||||
For every keysend in the request, a separate response event is sent. To differentiate between the responses, each
|
||||
response event contains an `d` tag with the id of the keysend it is responding to, if no id was given, then the
|
||||
response event contains a `d` tag with the id of the keysend it is responding to; if no id was given, then the
|
||||
pubkey should be used.
|
||||
|
||||
```jsonc
|
||||
|
||||
82
51.md
82
51.md
@@ -20,21 +20,21 @@ Standard lists use normal replaceable events, meaning users may only have a sing
|
||||
|
||||
For 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.
|
||||
|
||||
| name | kind | description | expected tag items |
|
||||
| --- | --- | --- | --- |
|
||||
| Mute list | 10000 | things the user doesn't want to see in their feeds | `"p"` (pubkeys), `"t"` (hashtags), `"word"` (lowercase string), `"e"` (threads) |
|
||||
| Pinned notes | 10001 | events the user intends to showcase in their profile page | `"e"` (kind:1 notes) |
|
||||
| Bookmarks | 10003 | uncategorized, "global" list of things a user wants to save | `"e"` (kind:1 notes), `"a"` (kind:30023 articles), `"t"` (hashtags), `"r"` (URLs) |
|
||||
| Communities | 10004 | [NIP-72](72.md) communities the user belongs to | `"a"` (kind:34550 community definitions) |
|
||||
| Public chats | 10005 | [NIP-28](28.md) chat channels the user is in | `"e"` (kind:40 channel definitions) |
|
||||
| Blocked relays | 10006 | relays clients should never connect to | `"relay"` (relay URLs) |
|
||||
| Search relays | 10007 | relays clients should use when performing search queries | `"relay"` (relay URLs) |
|
||||
| Simple groups | 10009 | [NIP-29](29.md) groups the user is in | `"group"` ([NIP-29](29.md) group id + relay URL + optional group name), `"r"` for each relay in use |
|
||||
| Interests | 10015 | topics a user may be interested in and pointers | `"t"` (hashtags) and `"a"` (kind:30015 interest set) |
|
||||
| Emojis | 10030 | user preferred emojis and pointers to emoji sets | `"emoji"` (see [NIP-30](30.md)) and `"a"` (kind:30030 emoji set) |
|
||||
| DM relays | 10050 | Where to receive [NIP-17](17.md) direct messages | `"relay"` (see [NIP-17](17.md)) |
|
||||
| Good wiki authors | 10101 | [NIP-54](54.md) user recommended wiki authors | `"p"` (pubkeys) |
|
||||
| Good wiki relays | 10102 | [NIP-54](54.md) relays deemed to only host useful articles | `"relay"` (relay URLs) |
|
||||
| name | kind | description | expected tag items |
|
||||
| --- | --- | --- | --- |
|
||||
| Mute list | 10000 | things the user doesn't want to see in their feeds | `"p"` (pubkeys), `"t"` (hashtags), `"word"` (lowercase string), `"e"` (threads) |
|
||||
| Pinned notes | 10001 | events the user intends to showcase in their profile page | `"e"` (kind:1 notes) |
|
||||
| Bookmarks | 10003 | uncategorized, "global" list of things a user wants to save | `"e"` (kind:1 notes), `"a"` (kind:30023 articles), `"t"` (hashtags), `"r"` (URLs) |
|
||||
| Communities | 10004 | [NIP-72](72.md) communities the user belongs to | `"a"` (kind:34550 community definitions) |
|
||||
| Public chats | 10005 | [NIP-28](28.md) chat channels the user is in | `"e"` (kind:40 channel definitions) |
|
||||
| Blocked relays | 10006 | relays clients should never connect to | `"relay"` (relay URLs) |
|
||||
| Search relays | 10007 | relays clients should use when performing search queries | `"relay"` (relay URLs) |
|
||||
| Simple groups | 10009 | [NIP-29](29.md) groups the user is in | `"group"` ([NIP-29](29.md) group id + relay URL + optional group name), `"r"` for each relay in use |
|
||||
| Interests | 10015 | topics a user may be interested in and pointers | `"t"` (hashtags) and `"a"` (kind:30015 interest set) |
|
||||
| Emojis | 10030 | user preferred emojis and pointers to emoji sets | `"emoji"` (see [NIP-30](30.md)) and `"a"` (kind:30030 emoji set) |
|
||||
| DM relays | 10050 | Where to receive [NIP-17](17.md) direct messages | `"relay"` (see [NIP-17](17.md)) |
|
||||
| Good wiki authors | 10101 | [NIP-54](54.md) user recommended wiki authors | `"p"` (pubkeys) |
|
||||
| Good wiki relays | 10102 | [NIP-54](54.md) relays deemed to only host useful articles | `"relay"` (relay URLs) |
|
||||
|
||||
### Sets
|
||||
|
||||
@@ -44,17 +44,18 @@ For example, _relay sets_ can be displayed in a dropdown UI to give users the op
|
||||
|
||||
Aside from their main identifier, the `"d"` tag, sets can optionally have a `"title"`, an `"image"` and a `"description"` tags that can be used to enhance their UI.
|
||||
|
||||
| name | kind | description | expected tag items |
|
||||
| --- | --- | --- | --- |
|
||||
| Follow sets | 30000 | categorized groups of users a client may choose to check out in different circumstances | `"p"` (pubkeys) |
|
||||
| Relay sets | 30002 | user-defined relay groups the user can easily pick and choose from during various operations | `"relay"` (relay URLs) |
|
||||
| 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) |
|
||||
| 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) |
|
||||
| Curation sets | 30005 | groups of videos picked by users as interesting and/or belonging to the same category | `"a"` (kind:34235 videos) |
|
||||
| Kind mute sets | 30007 | mute pubkeys by kinds<br>`"d"` tag MUST be the kind string | `"p"` (pubkeys) |
|
||||
| Interest sets | 30015 | interest topics represented by a bunch of "hashtags" | `"t"` (hashtags) |
|
||||
| Emoji sets | 30030 | categorized emoji groups | `"emoji"` (see [NIP-30](30.md)) |
|
||||
| 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"` |
|
||||
| name | kind | description | expected tag items |
|
||||
| --- | --- | --- | --- |
|
||||
| Follow sets | 30000 | categorized groups of users a client may choose to check out in different circumstances | `"p"` (pubkeys) |
|
||||
| Relay sets | 30002 | user-defined relay groups the user can easily pick and choose from during various operations | `"relay"` (relay URLs) |
|
||||
| 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) |
|
||||
| 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) |
|
||||
| Curation sets | 30005 | groups of videos picked by users as interesting and/or belonging to the same category | `"a"` (kind:34235 videos) |
|
||||
| Kind mute sets | 30007 | mute pubkeys by kinds<br>`"d"` tag MUST be the kind string | `"p"` (pubkeys) |
|
||||
| Interest sets | 30015 | interest topics represented by a bunch of "hashtags" | `"t"` (hashtags) |
|
||||
| Emoji sets | 30030 | categorized emoji groups | `"emoji"` (see [NIP-30](30.md)) |
|
||||
| Release artifact sets | 30063 | group of artifacts of a software release | `"e"` (kind:1063 [file metadata](94.md) events), `"a"` (software application event) |
|
||||
| App curation sets | 30267 | references to multiple software applications | `"a"` (software application event) |
|
||||
|
||||
### Deprecated standard lists
|
||||
|
||||
@@ -117,22 +118,39 @@ Some clients have used these lists in the past, but they should work on transiti
|
||||
"pubkey": "d6dc95542e18b8b7aec2f14610f55c335abebec76f3db9e58c254661d0593a0c",
|
||||
"created_at": 1695327657,
|
||||
"kind": 30063,
|
||||
"content": "Release notes in markdown",
|
||||
"tags": [
|
||||
["d", "ak8dy3v7"],
|
||||
["i", "com.example.app"],
|
||||
["version", "0.0.1"],
|
||||
["title", "Example App"],
|
||||
["image", "http://cdn.site/p/com.example.app/icon.png"],
|
||||
["d", "com.example.app@0.0.1"],
|
||||
["e", "d78ba0d5dce22bfff9db0a9e996c9ef27e2c91051de0c4e1da340e0326b4941e"], // Windows exe
|
||||
["e", "f27e2c91051de0c4e1da0d5dce22bfff9db0a9340e0326b4941ed78bae996c9e"], // MacOS dmg
|
||||
["e", "9d24ddfab95ba3ff7c03fbd07ad011fff245abea431fb4d3787c2d04aad02332"], // Linux AppImage
|
||||
["e", "340e0326b340e0326b4941ed78ba340e0326b4941ed78ba340e0326b49ed78ba"] // PWA
|
||||
["e", "340e0326b340e0326b4941ed78ba340e0326b4941ed78ba340e0326b49ed78ba"], // PWA
|
||||
["a", "32267:d6dc95542e18b8b7aec2f14610f55c335abebec76f3db9e58c254661d0593a0c:com.example.app"] // Reference to parent software application
|
||||
],
|
||||
"content": "Example App is a decentralized marketplace for apps",
|
||||
"sig": "a9a4e2192eede77e6c9d24ddfab95ba3ff7c03fbd07ad011fff245abea431fb4d3787c2d04aad001cb039cb8de91d83ce30e9a94f82ac3c5a2372aa1294a96bd"
|
||||
}
|
||||
```
|
||||
|
||||
### An _app curation set_
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"id": "d8037fa866eb5acd2159960b3ada7284172f7d687b5289cc72a96ca2b431b611",
|
||||
"pubkey": "78ce6faa72264387284e647ba6938995735ec8c7d5c5a65737e55130f026307d",
|
||||
"sig": "c1ce0a04521c020ae7485307cd86285530c1f778766a3fd594d662a73e7c28f307d7cd9a9ab642ae749fce62abbabb3a32facfe8d19a21fba551b60fae863d95",
|
||||
"kind": 30267,
|
||||
"created_at": 1729302793,
|
||||
"content": "My nostr app selection",
|
||||
"tags": [
|
||||
["d", "nostr"],
|
||||
["a", "32267:7579076d9aff0a4cfdefa7e2045f2486c7e5d8bc63bfc6b45397233e1bbfcb19:com.example.app1"],
|
||||
["a", "32267:045f2486c7e5d8bc63bfc6b45397233e1bbfcb197579076d9aff0a4cfdefa7e2:net.example.app2"],
|
||||
["a", "32267:264387284e647ba6938995735ec8c7d5c5a6f026307d78ce6faa725737e55130:pl.code.app3"]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Encryption process pseudocode
|
||||
|
||||
```scala
|
||||
|
||||
2
57.md
2
57.md
@@ -132,7 +132,7 @@ The following should be true of the `zap receipt` event:
|
||||
- `tags` MUST include the `p` tag (zap recipient) AND optional `e` tag from the `zap request` AND optional `a` tag from the `zap request` AND optional `P` tag from the pubkey of the zap request (zap sender).
|
||||
- The `zap receipt` MUST have a `bolt11` tag containing the description hash bolt11 invoice.
|
||||
- The `zap receipt` MUST contain a `description` tag which is the JSON-encoded zap request.
|
||||
- `SHA256(description)` MUST match the description hash in the bolt11 invoice.
|
||||
- `SHA256(description)` SHOULD match the description hash in the bolt11 invoice.
|
||||
- The `zap receipt` MAY contain a `preimage` tag to match against the payment hash of the bolt11 invoice. This isn't really a payment proof, there is no real way to prove that the invoice is real or has been paid. You are trusting the author of the `zap receipt` for the legitimacy of the payment.
|
||||
|
||||
The `zap receipt` is not a proof of payment, all it proves is that some nostr user fetched an invoice. The existence of the `zap receipt` implies the invoice as paid, but it could be a lie given a rogue implementation.
|
||||
|
||||
2
59.md
2
59.md
@@ -53,7 +53,7 @@ without the receiver's or the sender's private key. The only public information
|
||||
}
|
||||
```
|
||||
|
||||
Tags MUST must always be empty in a `kind:13`. The inner event MUST always be unsigned.
|
||||
Tags MUST always be empty in a `kind:13`. The inner event MUST always be unsigned.
|
||||
|
||||
## 3. Gift Wrap Event Kind
|
||||
|
||||
|
||||
2
60.md
2
60.md
@@ -54,7 +54,7 @@ Tags:
|
||||
Any tag, other than the `d` tag, can be [[NIP-44]] encrypted into the `.content` field.
|
||||
|
||||
### Deleting a wallet event
|
||||
Due to PRE being hard to delete, if a user wants to delete a wallet, they should empty the event and keep just the `d` identifier and add a `deleted` tag.
|
||||
Due to addressable event being hard to delete, if a user wants to delete a wallet, they should empty the event and keep just the `d` identifier and add a `deleted` tag.
|
||||
|
||||
## Token Event
|
||||
Token events are used to record the unspent proofs that come from the mint.
|
||||
|
||||
4
61.md
4
61.md
@@ -70,7 +70,7 @@ WIP: Clients SHOULD embed a DLEQ proof in the nutzap event to make it possible t
|
||||
|
||||
* The sender fetches the recipient's `kind:10019`.
|
||||
* The sender mints/swaps ecash on one of the recipient's listed mints.
|
||||
* The sender p2pk locks to the recipient's specified pubkey in their
|
||||
* The sender p2pk locks to the recipient's specified pubkey in their `kind:10019`
|
||||
|
||||
# Receiving nutzaps
|
||||
|
||||
@@ -129,4 +129,4 @@ For this scenarios clients can:
|
||||
* add a `pubkey` tag to the `kind:10019` (indicating which pubkey senders should P2PK to)
|
||||
* store the private key in the `kind:37375` event in the nip44-encrypted `content` field.
|
||||
|
||||
This is to avoid depending on NIP-07/46 adaptations to sign cashu payloads.
|
||||
This is to avoid depending on NIP-07/46 adaptations to sign cashu payloads.
|
||||
|
||||
130
88.md
Normal file
130
88.md
Normal file
@@ -0,0 +1,130 @@
|
||||
# NIP-88
|
||||
|
||||
## Polls
|
||||
|
||||
`draft` `optional`
|
||||
|
||||
This NIP defines the event scheme that describe Polls on nostr.
|
||||
|
||||
## Events
|
||||
|
||||
### Poll Event
|
||||
|
||||
The poll event is defined as a `kind:1068` event.
|
||||
|
||||
- **content** key holds the label for the poll.
|
||||
|
||||
Major tags in the poll event are:
|
||||
|
||||
- **option**: The option tags contain an OptionId(any alphanumeric) field, followed by an option label field.
|
||||
- **relay**: One or multiple tags that the poll is expecting respondents to respond on.
|
||||
- **polltype**: can be "singlechoice" or "multiplechoice". Polls that do not have a polltype should be considered a "singlechoice" poll.
|
||||
- **endsAt**: signifying at which unix timestamp the poll is meant to end.
|
||||
|
||||
Example Event
|
||||
|
||||
```json
|
||||
{
|
||||
"content": "Pineapple on pizza",
|
||||
"created_at": 1719888496,
|
||||
"id": "9d1b6b9562e66f2ecf35eb0a3c2decc736c47fddb13d6fb8f87185a153ea3634",
|
||||
"kind": 1068,
|
||||
"pubkey": "dee45a23c4f1d93f3a2043650c5081e4ac14a778e0acbef03de3768e4f81ac7b",
|
||||
"sig": "7fa93bf3c430eaef784b0dacc217d3cd5eff1c520e7ef5d961381bc0f014dde6286618048d924808e54d1be03f2f2c2f0f8b5c9c2082a4480caf45a565ca9797",
|
||||
"tags": [
|
||||
["option", "qj518h583", "Yay"],
|
||||
["option", "gga6cdnqj", "Nay"],
|
||||
["relay", "<relay url1>"],
|
||||
["relay", "<relay url2>"],
|
||||
["polltype", "singlechoice"],
|
||||
["endsAt", "<unix timestamp in seconds>"]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Responses
|
||||
|
||||
The response event is a `kind:1018` event. It contains an e tag with the poll event it is referencing, followed by one or more response tags.
|
||||
|
||||
- **response** : The tag contains "response" as it's first positional argument followed by the option Id selected.
|
||||
|
||||
The responses are meant to be published to the relays specified in the poll event.
|
||||
|
||||
Example Response Event
|
||||
|
||||
```json
|
||||
{
|
||||
"content": "",
|
||||
"created_at": 1720097117,
|
||||
"id": "60a005e32e9596c3f544a841a9bc4e46d3020ca3650d6a739c95c1568e33f6d8",
|
||||
"kind": 1018,
|
||||
"pubkey": "1bc70a0148b3f316da33fe7e89f23e3e71ac4ff998027ec712b905cd24f6a411",
|
||||
"sig": "30071a633c65db8f3a075c7a8de757fbd8ce65e3607f4ba287fe6d7fbf839a380f94ff4e826fbba593f6faaa13683b7ea9114ade140720ecf4927010ebf3e44f",
|
||||
"tags": [
|
||||
["e", "1fc80cf813f1af33d5a435862b7ef7fb96b47e68a48f1abcadf8081f5a545550"],
|
||||
["response", "gga6cdnqj"],
|
||||
["response", "m3agjsdq1"]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Poll Types
|
||||
|
||||
The polltype setting dictates how multiple response tags are handled in the `kind:1018` event.
|
||||
|
||||
- **polltype: singlechoice**: The first response tag is to be considered the actual response.
|
||||
- **polltype: multiplechoice**: The first response tag pointing to each id is considered the actual response, without considering the order of the response tags.
|
||||
|
||||
### Counting Results
|
||||
|
||||
Results can be queried by fetching `kind:1018` events from the relays specified in the poll.
|
||||
The results displayed should only be 1 vote event per pubkey.
|
||||
In case of multiple events for a pubkey, the event with the largest timestamp within the poll limits should be considered.
|
||||
|
||||
Example for querying polls.
|
||||
|
||||
```ts
|
||||
const fetchVoteEvents = (filterPubkeys: string[]) => {
|
||||
let resultFilter: Filter = {
|
||||
"#e": [pollEvent.id],
|
||||
kinds: [1018],
|
||||
};
|
||||
if (filterPubkeys?.length) {
|
||||
resultFilter.authors = filterPubkeys;
|
||||
}
|
||||
if (pollExpiration) {
|
||||
resultFilter.until = Number(pollExpiration);
|
||||
}
|
||||
pool.subscribeMany(relays, [resultFilter], {
|
||||
onevent: handleResultEvent,
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
Example for maintaining OneVotePerPubkey
|
||||
|
||||
```ts
|
||||
const oneVotePerPubkey = (events: Event[]) => {
|
||||
const eventMap = new Map<string, Event>();
|
||||
|
||||
events.forEach((event) => {
|
||||
if (
|
||||
!eventMap.has(event.pubkey) ||
|
||||
event.created_at > eventMap.get(event.pubkey)!.created_at
|
||||
) {
|
||||
eventMap.set(event.pubkey, event);
|
||||
}
|
||||
});
|
||||
|
||||
return Array.from(eventMap.values());
|
||||
};
|
||||
```
|
||||
|
||||
### Relays
|
||||
|
||||
It is advisable for poll authors to use relays that do not allow backdated events and do not honor kind:5 (delete) requests for vote events in order to maintain the integrity of poll results after the poll has ended.
|
||||
|
||||
### Curation
|
||||
|
||||
The clients may configure fetching results by specific people. This can be achieved by creating `kind:30000` follow sets, and fetching results only from the follow set.
|
||||
Clients can also employ other curation algorithms, like Proof Of Work and Web of Trust scores for result curations.
|
||||
2
94.md
2
94.md
@@ -10,7 +10,7 @@ The purpose of this NIP is to allow an organization and classification of shared
|
||||
|
||||
## Event format
|
||||
|
||||
This NIP specifies the use of the `1063` event type, having in `content` a description of the file content, and a list of tags described below:
|
||||
This NIP specifies the use of the `1063` event kind, having in `content` a description of the file content, and a list of tags described below:
|
||||
|
||||
* `url` the url to download the file
|
||||
* `m` a string indicating the data type of the file. The [MIME types](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types) format must be used, and they should be lowercase.
|
||||
|
||||
23
README.md
23
README.md
@@ -31,7 +31,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
|
||||
- [NIP-07: `window.nostr` capability for web browsers](07.md)
|
||||
- [NIP-08: Handling Mentions](08.md) --- **unrecommended**: deprecated in favor of [NIP-27](27.md)
|
||||
- [NIP-09: Event Deletion Request](09.md)
|
||||
- [NIP-10: Conventions for clients' use of `e` and `p` tags in text events](10.md)
|
||||
- [NIP-10: Text Notes and Threads](10.md)
|
||||
- [NIP-11: Relay Information Document](11.md)
|
||||
- [NIP-13: Proof of Work](13.md)
|
||||
- [NIP-14: Subject tag in text events](14.md)
|
||||
@@ -59,10 +59,10 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
|
||||
- [NIP-39: External Identities in Profiles](39.md)
|
||||
- [NIP-40: Expiration Timestamp](40.md)
|
||||
- [NIP-42: Authentication of clients to relays](42.md)
|
||||
- [NIP-44: Versioned Encryption](44.md)
|
||||
- [NIP-44: Encrypted Payloads (Versioned)](44.md)
|
||||
- [NIP-45: Counting results](45.md)
|
||||
- [NIP-46: Nostr Connect](46.md)
|
||||
- [NIP-47: Wallet Connect](47.md)
|
||||
- [NIP-46: Nostr Remote Signing](46.md)
|
||||
- [NIP-47: Nostr Wallet Connect](47.md)
|
||||
- [NIP-48: Proxy Tags](48.md)
|
||||
- [NIP-49: Private Key Encryption](49.md)
|
||||
- [NIP-50: Search Capability](50.md)
|
||||
@@ -89,6 +89,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
|
||||
- [NIP-78: Application-specific data](78.md)
|
||||
- [NIP-84: Highlights](84.md)
|
||||
- [NIP-86: Relay Management API](86.md)
|
||||
- [NIP-88: Polls](88.md)
|
||||
- [NIP-89: Recommended Application Handlers](89.md)
|
||||
- [NIP-90: Data Vending Machines](90.md)
|
||||
- [NIP-92: Media Attachments](92.md)
|
||||
@@ -104,7 +105,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
|
||||
| kind | description | NIP |
|
||||
| ------------- | ------------------------------- | -------------------------------------- |
|
||||
| `0` | User Metadata | [01](01.md) |
|
||||
| `1` | Short Text Note | [01](01.md) |
|
||||
| `1` | Short Text Note | [10](10.md) |
|
||||
| `2` | Recommend Relay | 01 (deprecated) |
|
||||
| `3` | Follows | [02](02.md) |
|
||||
| `4` | Encrypted Direct Messages | [04](04.md) |
|
||||
@@ -128,11 +129,13 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
|
||||
| `44` | Channel Mute User | [28](28.md) |
|
||||
| `64` | Chess (PGN) | [64](64.md) |
|
||||
| `818` | Merge Requests | [54](54.md) |
|
||||
| `1018` | Poll Response | [88](88.md) |
|
||||
| `1021` | Bid | [15](15.md) |
|
||||
| `1022` | Bid confirmation | [15](15.md) |
|
||||
| `1040` | OpenTimestamps | [03](03.md) |
|
||||
| `1059` | Gift Wrap | [59](59.md) |
|
||||
| `1063` | File Metadata | [94](94.md) |
|
||||
| `1068` | Poll | [88](88.md) |
|
||||
| `1111` | Comment | [22](22.md) |
|
||||
| `1311` | Live Chat Message | [53](53.md) |
|
||||
| `1617` | Patches | [34](34.md) |
|
||||
@@ -170,6 +173,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
|
||||
| `10006` | Blocked relays list | [51](51.md) |
|
||||
| `10007` | Search relays list | [51](51.md) |
|
||||
| `10009` | User groups | [51](51.md), [29](29.md) |
|
||||
| `10013` | Draft relays | [37](37.md) |
|
||||
| `10015` | Interests list | [51](51.md) |
|
||||
| `10019` | Nutzap Mint Recommendation | [61](61.md) |
|
||||
| `10030` | User emoji list | [51](51.md) |
|
||||
@@ -205,6 +209,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
|
||||
| `30041` | Modular Article Content | [NKBIP-01] |
|
||||
| `30063` | Release artifact sets | [51](51.md) |
|
||||
| `30078` | Application-specific Data | [78](78.md) |
|
||||
| `30267` | App curation sets | [51](51.md) |
|
||||
| `30311` | Live Event | [53](53.md) |
|
||||
| `30315` | User Statuses | [38](38.md) |
|
||||
| `30388` | Slide Set | [Corny Chat][cornychat-slideset] |
|
||||
@@ -284,8 +289,8 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
|
||||
| `l` | label, label namespace | -- | [32](32.md) |
|
||||
| `L` | label namespace | -- | [32](32.md) |
|
||||
| `m` | MIME type | -- | [94](94.md) |
|
||||
| `p` | pubkey (hex) | relay URL, petname | [01](01.md), [02](02.md) |
|
||||
| `P` | pubkey (hex) | -- | [57](57.md) |
|
||||
| `p` | pubkey (hex) | relay URL, petname | [01](01.md), [02](02.md), [22](22.md) |
|
||||
| `P` | pubkey (hex) | -- | [22](22.md), [57](57.md) |
|
||||
| `q` | event id (hex) | relay URL, pubkey (hex) | [18](18.md) |
|
||||
| `r` | a reference (URL, etc) | -- | [24](24.md), [25](25.md) |
|
||||
| `r` | relay url | marker | [65](65.md) |
|
||||
@@ -343,9 +348,9 @@ Please update these lists when proposing new NIPs.
|
||||
|
||||
## Is this repository a centralizing factor?
|
||||
|
||||
To promote interoperability, we standards that everybody can follow, and we need them to define a **single way of doing each thing** without ever hurting **backwards-compatibility**, and for that purpose there is no way around getting everybody to agree on the same thing and keep a centralized index of these standards. However the fact that such index exists doesn't hurt the decentralization of Nostr. _At any point the central index can be challenged if it is failing to fulfill the needs of the protocol_ and it can migrate to other places and be maintained by other people.
|
||||
To promote interoperability, we need standards that everybody can follow, and we need them to define a **single way of doing each thing** without ever hurting **backwards-compatibility**, and for that purpose there is no way around getting everybody to agree on the same thing and keep a centralized index of these standards. However the fact that such an index exists doesn't hurt the decentralization of Nostr. _At any point the central index can be challenged if it is failing to fulfill the needs of the protocol_ and it can migrate to other places and be maintained by other people.
|
||||
|
||||
It can even fork into multiple and then some clients would go one way, others would go another way, and some clients would adhere to both competing standards. This would hurt the simplicity, openness and interoperability of Nostr a little, but everything would still work in the short term.
|
||||
It can even fork into multiple versions, and then some clients would go one way, others would go another way, and some clients would adhere to both competing standards. This would hurt the simplicity, openness and interoperability of Nostr a little, but everything would still work in the short term.
|
||||
|
||||
There is a list of notable Nostr software developers who have commit access to this repository, but that exists mostly for practical reasons, as by the nature of the thing we're dealing with the repository owner can revoke membership and rewrite history as they want -- and if these actions are unjustified or perceived as bad or evil the community must react.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user