diff options
| -rw-r--r-- | 01.md | 20 | ||||
| -rw-r--r-- | 07.md | 14 | ||||
| -rw-r--r-- | 24.md | 1 | ||||
| -rw-r--r-- | 52.md | 34 | ||||
| -rw-r--r-- | 94.md | 4 | ||||
| -rw-r--r-- | README.md | 4 |
6 files changed, 45 insertions, 32 deletions
| @@ -29,7 +29,7 @@ The only object type that exists is the `event`, which has the following format | |||
| 29 | } | 29 | } |
| 30 | ``` | 30 | ``` |
| 31 | 31 | ||
| 32 | To obtain the `event.id`, we `sha256` the serialized event. The serialization is done over the UTF-8 JSON-serialized string (with no white space or line breaks between the fields) of the following structure: | 32 | To obtain the `event.id`, we `sha256` the serialized event. The serialization is done over the UTF-8 JSON-serialized string (which is described below) of the following structure: |
| 33 | 33 | ||
| 34 | ``` | 34 | ``` |
| 35 | [ | 35 | [ |
| @@ -42,6 +42,18 @@ To obtain the `event.id`, we `sha256` the serialized event. The serialization is | |||
| 42 | ] | 42 | ] |
| 43 | ``` | 43 | ``` |
| 44 | 44 | ||
| 45 | To prevent implementation differences from creating a different event ID for the same event, the following rules MUST be followed while serializing: | ||
| 46 | - No whitespace, line breaks or other unnecessary formatting should be included in the output JSON. | ||
| 47 | - No characters except the following should be escaped, and instead should be included verbatim: | ||
| 48 | - A line break, `0x0A`, as `\n` | ||
| 49 | - A double quote, `0x22`, as `\"` | ||
| 50 | - A backslash, `0x5C`, as `\\` | ||
| 51 | - A carriage return, `0x0D`, as `\r` | ||
| 52 | - A tab character, `0x09`, as `\t` | ||
| 53 | - A backspace, `0x08`, as `\b` | ||
| 54 | - A form feed, `0x0C`, as `\f` | ||
| 55 | - UTF-8 should be used for encoding. | ||
| 56 | |||
| 45 | ### Tags | 57 | ### Tags |
| 46 | 58 | ||
| 47 | Each tag is an array of strings of arbitrary size, with some conventions around them. Take a look at the example below: | 59 | Each tag is an array of strings of arbitrary size, with some conventions around them. Take a look at the example below: |
| @@ -101,12 +113,12 @@ Relays expose a websocket endpoint to which clients can connect. Clients SHOULD | |||
| 101 | Clients can send 3 types of messages, which must be JSON arrays, according to the following patterns: | 113 | Clients can send 3 types of messages, which must be JSON arrays, according to the following patterns: |
| 102 | 114 | ||
| 103 | * `["EVENT", <event JSON as defined above>]`, used to publish events. | 115 | * `["EVENT", <event JSON as defined above>]`, used to publish events. |
| 104 | * `["REQ", <subscription_id>, <filters JSON>, ...]`, used to request events and subscribe to new updates. | 116 | * `["REQ", <subscription_id>, <filters1>, <filters2>, ...]`, used to request events and subscribe to new updates. |
| 105 | * `["CLOSE", <subscription_id>]`, used to stop previous subscriptions. | 117 | * `["CLOSE", <subscription_id>]`, used to stop previous subscriptions. |
| 106 | 118 | ||
| 107 | `<subscription_id>` is an arbitrary, non-empty string of max length 64 chars, that should be used to represent a subscription. Relays should manage `<subscription_id>`s independently for each WebSocket connection; even if `<subscription_id>`s are the same string, they should be treated as different subscriptions for different connections. | 119 | `<subscription_id>` is an arbitrary, non-empty string of max length 64 chars. It represents a subscription per connection. Relays MUST manage `<subscription_id>`s independently for each WebSocket connection. `<subscription_id>`s are not guarantueed to be globally unique. |
| 108 | 120 | ||
| 109 | `<filters>` is a JSON object that determines what events will be sent in that subscription, it can have the following attributes: | 121 | `<filtersX>` is a JSON object that determines what events will be sent in that subscription, it can have the following attributes: |
| 110 | 122 | ||
| 111 | ```json | 123 | ```json |
| 112 | { | 124 | { |
| @@ -24,16 +24,4 @@ async window.nostr.nip04.decrypt(pubkey, ciphertext): string // takes ciphertext | |||
| 24 | 24 | ||
| 25 | ### Implementation | 25 | ### Implementation |
| 26 | 26 | ||
| 27 | - [horse](https://github.com/fiatjaf/horse) (Chrome and derivatives) | 27 | See https://github.com/aljazceru/awesome-nostr#nip-07-browser-extensions. |
| 28 | - [nos2x](https://github.com/fiatjaf/nos2x) (Chrome and derivatives) | ||
| 29 | - [Alby](https://getalby.com) (Chrome and derivatives, Firefox) | ||
| 30 | - [Blockcore](https://www.blockcore.net/wallet) (Chrome and derivatives) | ||
| 31 | - [nos2x-fox](https://diegogurpegui.com/nos2x-fox/) (Firefox) | ||
| 32 | - [Flamingo](https://www.getflamingo.org/) (Chrome and derivatives) | ||
| 33 | - [AKA Profiles](https://github.com/neilck/aka-extension) (Chrome, stores multiple keys) | ||
| 34 | - [TokenPocket](https://www.tokenpocket.pro/) (Android, IOS, Chrome and derivatives) | ||
| 35 | - [Nostrmo](https://github.com/haorendashu/nostrmo_faq#download) (Android, IOS) | ||
| 36 | - [Spring Browser](https://spring.site) (Android) | ||
| 37 | - [nodestr](https://github.com/lightning-digital-entertainment/nodestr) (NodeJS polyfill) | ||
| 38 | - [Nostore](https://apps.apple.com/us/app/nostore/id1666553677) (Safari on iOS/MacOS) | ||
| 39 | - [OneKey](https://onekey.so/) (Android, IOS, Chrome and derivatives) | ||
| @@ -39,3 +39,4 @@ tags | |||
| 39 | These tags may be present in multiple event kinds. Whenever a different meaning is not specified by some more specific NIP, they have the following meanings: | 39 | These tags may be present in multiple event kinds. Whenever a different meaning is not specified by some more specific NIP, they have the following meanings: |
| 40 | 40 | ||
| 41 | - `r`: a web URL the event is referring to in some way | 41 | - `r`: a web URL the event is referring to in some way |
| 42 | - `title`: title of the event | ||
| @@ -22,19 +22,22 @@ This kind of calendar event starts on a date and ends before a different date in | |||
| 22 | 22 | ||
| 23 | The format uses a parameterized replaceable event kind `31922`. | 23 | The format uses a parameterized replaceable event kind `31922`. |
| 24 | 24 | ||
| 25 | The `.content` of these events is optional and should be a detailed description of the calendar event. | 25 | The `.content` of these events should be a detailed description of the calendar event. It is required but can be an empty string. |
| 26 | 26 | ||
| 27 | The list of tags are as follows: | 27 | The list of tags are as follows: |
| 28 | * `d` (required) universally unique identifier (UUID). Generated by the client creating the calendar event. | 28 | * `d` (required) universally unique identifier (UUID). Generated by the client creating the calendar event. |
| 29 | * `name` (required) name of the calendar event | 29 | * `title` (required) title of the calendar event |
| 30 | * `start` (required) inclusive start date in ISO 8601 format (YYYY-MM-DD). Must be less than `end`, if it exists. | 30 | * `start` (required) inclusive start date in ISO 8601 format (YYYY-MM-DD). Must be less than `end`, if it exists. |
| 31 | * `end` (optional) exclusive end date in ISO 8601 format (YYYY-MM-DD). If omitted, the calendar event ends on the same date as `start`. | 31 | * `end` (optional) exclusive end date in ISO 8601 format (YYYY-MM-DD). If omitted, the calendar event ends on the same date as `start`. |
| 32 | * `location` (optional) location of the calendar event. e.g. address, GPS coordinates, meeting room name, link to video call | 32 | * `location` (optional, repeated) location of the calendar event. e.g. address, GPS coordinates, meeting room name, link to video call |
| 33 | * `g` (optional) [geohash](https://en.wikipedia.org/wiki/Geohash) to associate calendar event with a searchable physical location | 33 | * `g` (optional) [geohash](https://en.wikipedia.org/wiki/Geohash) to associate calendar event with a searchable physical location |
| 34 | * `p` (optional, repeated) 32-bytes hex pubkey of a participant, optional recommended relay URL, and participant's role in the meeting | 34 | * `p` (optional, repeated) 32-bytes hex pubkey of a participant, optional recommended relay URL, and participant's role in the meeting |
| 35 | * `t` (optional, repeated) hashtag to categorize calendar event | 35 | * `t` (optional, repeated) hashtag to categorize calendar event |
| 36 | * `r` (optional, repeated) references / links to web pages, documents, video calls, recorded videos, etc. | 36 | * `r` (optional, repeated) references / links to web pages, documents, video calls, recorded videos, etc. |
| 37 | 37 | ||
| 38 | The following tags are deprecated: | ||
| 39 | * `name` name of the calendar event. Use only if `title` is not available. | ||
| 40 | |||
| 38 | ```json | 41 | ```json |
| 39 | { | 42 | { |
| 40 | "id": <32-bytes lowercase hex-encoded SHA-256 of the the serialized event data>, | 43 | "id": <32-bytes lowercase hex-encoded SHA-256 of the the serialized event data>, |
| @@ -45,7 +48,7 @@ The list of tags are as follows: | |||
| 45 | "tags": [ | 48 | "tags": [ |
| 46 | ["d", "<UUID>"], | 49 | ["d", "<UUID>"], |
| 47 | 50 | ||
| 48 | ["name", "<name of calendar event>"], | 51 | ["title", "<title of calendar event>"], |
| 49 | 52 | ||
| 50 | // Dates | 53 | // Dates |
| 51 | ["start", "<YYYY-MM-DD>"], | 54 | ["start", "<YYYY-MM-DD>"], |
| @@ -78,21 +81,24 @@ This kind of calendar event spans between a start time and end time. | |||
| 78 | 81 | ||
| 79 | The format uses a parameterized replaceable event kind `31923`. | 82 | The format uses a parameterized replaceable event kind `31923`. |
| 80 | 83 | ||
| 81 | The `.content` of these events is optional and should be a detailed description of the calendar event. | 84 | The `.content` of these events should be a detailed description of the calendar event. It is required but can be an empty string. |
| 82 | 85 | ||
| 83 | The list of tags are as follows: | 86 | The list of tags are as follows: |
| 84 | * `d` (required) universally unique identifier (UUID). Generated by the client creating the calendar event. | 87 | * `d` (required) universally unique identifier (UUID). Generated by the client creating the calendar event. |
| 85 | * `name` (required) name of the calendar event | 88 | * `title` (required) title of the calendar event |
| 86 | * `start` (required) inclusive start Unix timestamp in seconds. Must be less than `end`, if it exists. | 89 | * `start` (required) inclusive start Unix timestamp in seconds. Must be less than `end`, if it exists. |
| 87 | * `end` (optional) exclusive end Unix timestamp in seconds. If omitted, the calendar event ends instantaneously. | 90 | * `end` (optional) exclusive end Unix timestamp in seconds. If omitted, the calendar event ends instantaneously. |
| 88 | * `start_tzid` (optional) time zone of the start timestamp, as defined by the IANA Time Zone Database. e.g., `America/Costa_Rica` | 91 | * `start_tzid` (optional) time zone of the start timestamp, as defined by the IANA Time Zone Database. e.g., `America/Costa_Rica` |
| 89 | * `end_tzid` (optional) time zone of the end timestamp, as defined by the IANA Time Zone Database. e.g., `America/Costa_Rica`. If omitted and `start_tzid` is provided, the time zone of the end timestamp is the same as the start timestamp. | 92 | * `end_tzid` (optional) time zone of the end timestamp, as defined by the IANA Time Zone Database. e.g., `America/Costa_Rica`. If omitted and `start_tzid` is provided, the time zone of the end timestamp is the same as the start timestamp. |
| 90 | * `location` (optional) location of the calendar event. e.g. address, GPS coordinates, meeting room name, link to video call | 93 | * `location` (optional, repeated) location of the calendar event. e.g. address, GPS coordinates, meeting room name, link to video call |
| 91 | * `g` (optional) [geohash](https://en.wikipedia.org/wiki/Geohash) to associate calendar event with a searchable physical location | 94 | * `g` (optional) [geohash](https://en.wikipedia.org/wiki/Geohash) to associate calendar event with a searchable physical location |
| 92 | * `p` (optional, repeated) 32-bytes hex pubkey of a participant, optional recommended relay URL, and participant's role in the meeting | 95 | * `p` (optional, repeated) 32-bytes hex pubkey of a participant, optional recommended relay URL, and participant's role in the meeting |
| 93 | * `t` (optional, repeated) hashtag to categorize calendar event | 96 | * `t` (optional, repeated) hashtag to categorize calendar event |
| 94 | * `r` (optional, repeated) references / links to web pages, documents, video calls, recorded videos, etc. | 97 | * `r` (optional, repeated) references / links to web pages, documents, video calls, recorded videos, etc. |
| 95 | 98 | ||
| 99 | The following tags are deprecated: | ||
| 100 | * `name` name of the calendar event. Use only if `title` is not available. | ||
| 101 | |||
| 96 | ```json | 102 | ```json |
| 97 | { | 103 | { |
| 98 | "id": <32-bytes lowercase hex-encoded SHA-256 of the the serialized event data>, | 104 | "id": <32-bytes lowercase hex-encoded SHA-256 of the the serialized event data>, |
| @@ -103,7 +109,7 @@ The list of tags are as follows: | |||
| 103 | "tags": [ | 109 | "tags": [ |
| 104 | ["d", "<UUID>"], | 110 | ["d", "<UUID>"], |
| 105 | 111 | ||
| 106 | ["name", "<name of calendar event>"], | 112 | ["title", "<title of calendar event>"], |
| 107 | 113 | ||
| 108 | // Timestamps | 114 | // Timestamps |
| 109 | ["start", "<Unix timestamp in seconds>"], | 115 | ["start", "<Unix timestamp in seconds>"], |
| @@ -137,15 +143,23 @@ A calendar is a collection of calendar events, represented as a custom replaceab | |||
| 137 | 143 | ||
| 138 | ### Format | 144 | ### Format |
| 139 | 145 | ||
| 146 | The `.content` of these events should be a detailed description of the calendar. It is required but can be an empty string. | ||
| 147 | |||
| 140 | The format uses a custom replaceable list of kind `31924` with a list of tags as described below: | 148 | The format uses a custom replaceable list of kind `31924` with a list of tags as described below: |
| 141 | * `d` (required) calendar name | 149 | * `d` (required) universally unique identifier. Generated by the client creating the calendar. |
| 150 | * `title` (required) calendar title | ||
| 142 | * `a` (repeated) reference tag to kind `31922` or `31923` calendar event being responded to | 151 | * `a` (repeated) reference tag to kind `31922` or `31923` calendar event being responded to |
| 143 | 152 | ||
| 144 | ```json | 153 | ```json |
| 145 | { | 154 | { |
| 155 | "id": <32-bytes lowercase hex-encoded SHA-256 of the the serialized event data>, | ||
| 156 | "pubkey": <32-bytes lowercase hex-encoded public key of the event creator>, | ||
| 157 | "created_at": <Unix timestamp in seconds>, | ||
| 146 | "kind": 31924, | 158 | "kind": 31924, |
| 159 | "content": "<description of calendar>", | ||
| 147 | "tags": [ | 160 | "tags": [ |
| 148 | ["d", "<calendar name>"], | 161 | ["d", "<UUID>"], |
| 162 | ["title", "<calendar title>"], | ||
| 149 | ["a", "<31922 or 31923>:<calendar event author pubkey>:<d-identifier of calendar event>", "<optional relay url>"], | 163 | ["a", "<31922 or 31923>:<calendar event author pubkey>:<d-identifier of calendar event>", "<optional relay url>"], |
| 150 | ["a", "<31922 or 31923>:<calendar event author pubkey>:<d-identifier of calendar event>", "<optional relay url>"] | 164 | ["a", "<31922 or 31923>:<calendar event author pubkey>:<d-identifier of calendar event>", "<optional relay url>"] |
| 151 | ] | 165 | ] |
| @@ -6,7 +6,7 @@ File Metadata | |||
| 6 | 6 | ||
| 7 | `draft` `optional` | 7 | `draft` `optional` |
| 8 | 8 | ||
| 9 | The purpose of this NIP is to allow an organization and classification of shared files. So that relays can filter and organize in any way that is of interest. With that, multiple types of filesharing clients can be created. NIP-94 support is not expected to be implemented by "social" clients that deal with kind:1 notes or by longform clients that deal with kind:30023 articles. | 9 | The purpose of this NIP is to allow an organization and classification of shared files. So that relays can filter and organize in any way that is of interest. With that, multiple types of filesharing clients can be created. NIP-94 support is not expected to be implemented by "social" clients that deal with `kind:1` notes or by longform clients that deal with `kind:30023` articles. |
| 10 | 10 | ||
| 11 | ## Event format | 11 | ## Event format |
| 12 | 12 | ||
| @@ -14,7 +14,6 @@ This NIP specifies the use of the `1063` event type, having in `content` a descr | |||
| 14 | 14 | ||
| 15 | * `url` the url to download the file | 15 | * `url` the url to download the file |
| 16 | * `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. | 16 | * `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. |
| 17 | * `"aes-256-gcm"` (optional) key and nonce for AES-GCM encryption with tagSize always 128bits | ||
| 18 | * `x` containing the SHA-256 hexencoded string of the file. | 17 | * `x` containing the SHA-256 hexencoded string of the file. |
| 19 | * `size` (optional) size of file in bytes | 18 | * `size` (optional) size of file in bytes |
| 20 | * `dim` (optional) size of file in pixels in the form `<width>x<height>` | 19 | * `dim` (optional) size of file in pixels in the form `<width>x<height>` |
| @@ -31,7 +30,6 @@ This NIP specifies the use of the `1063` event type, having in `content` a descr | |||
| 31 | "kind": 1063, | 30 | "kind": 1063, |
| 32 | "tags": [ | 31 | "tags": [ |
| 33 | ["url",<string with URI of file>], | 32 | ["url",<string with URI of file>], |
| 34 | ["aes-256-gcm",<key>, <iv>], | ||
| 35 | ["m", <MIME type>], | 33 | ["m", <MIME type>], |
| 36 | ["x",<Hash SHA-256>], | 34 | ["x",<Hash SHA-256>], |
| 37 | ["size", <size of file in bytes>], | 35 | ["size", <size of file in bytes>], |
| @@ -77,10 +77,10 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos | |||
| 77 | 77 | ||
| 78 | ## Event Kinds | 78 | ## Event Kinds |
| 79 | | kind | description | NIP | | 79 | | kind | description | NIP | |
| 80 | | ------------- | -------------------------- | ----------- | | 80 | | ------------- | -------------------------- | ------------------------ | |
| 81 | | `0` | Metadata | [01](01.md) | | 81 | | `0` | Metadata | [01](01.md) | |
| 82 | | `1` | Short Text Note | [01](01.md) | | 82 | | `1` | Short Text Note | [01](01.md) | |
| 83 | | `2` | Recommend Relay | 01 (before 2023-08-13) | | 83 | | `2` | Recommend Relay | 01 (deprecated) | |
| 84 | | `3` | Follows | [02](02.md) | | 84 | | `3` | Follows | [02](02.md) | |
| 85 | | `4` | Encrypted Direct Messages | [04](04.md) | | 85 | | `4` | Encrypted Direct Messages | [04](04.md) | |
| 86 | | `5` | Event Deletion | [09](09.md) | | 86 | | `5` | Event Deletion | [09](09.md) | |