diff options
| -rw-r--r-- | 01.md | 1 | ||||
| -rw-r--r-- | 09.md | 5 | ||||
| -rw-r--r-- | 11.md | 15 | ||||
| -rw-r--r-- | 18.md | 21 | ||||
| -rw-r--r-- | 98.md | 68 | ||||
| -rw-r--r-- | README.md | 5 |
6 files changed, 105 insertions, 10 deletions
| @@ -110,3 +110,4 @@ A relay may choose to treat different message kinds differently, and it may or m | |||
| 110 | - The `tags` array can store a tag identifier as the first element of each subarray, plus arbitrary information afterward (always as strings). This NIP defines `"p"` — meaning "pubkey", which points to a pubkey of someone that is referred to in the event —, and `"e"` — meaning "event", which points to the id of an event this event is quoting, replying to or referring to somehow. See [NIP-10](10.md) for a detailed description of "e" and "p" tags. | 110 | - The `tags` array can store a tag identifier as the first element of each subarray, plus arbitrary information afterward (always as strings). This NIP defines `"p"` — meaning "pubkey", which points to a pubkey of someone that is referred to in the event —, and `"e"` — meaning "event", which points to the id of an event this event is quoting, replying to or referring to somehow. See [NIP-10](10.md) for a detailed description of "e" and "p" tags. |
| 111 | - The `<recommended relay URL>` item present on the `"e"` and `"p"` tags is an optional (could be set to `""`) URL of a relay the client could attempt to connect to fetch the tagged event or other events from a tagged profile. It MAY be ignored, but it exists to increase censorship resistance and make the spread of relay addresses more seamless across clients. | 111 | - The `<recommended relay URL>` item present on the `"e"` and `"p"` tags is an optional (could be set to `""`) URL of a relay the client could attempt to connect to fetch the tagged event or other events from a tagged profile. It MAY be ignored, but it exists to increase censorship resistance and make the spread of relay addresses more seamless across clients. |
| 112 | - Clients should use the created_at field to judge the age of a metadata event and completely replace older metadata events with newer metadata events regardless of the order in which they arrive. Clients should not merge any filled fields within older metadata events into empty fields of newer metadata events. | 112 | - Clients should use the created_at field to judge the age of a metadata event and completely replace older metadata events with newer metadata events regardless of the order in which they arrive. Clients should not merge any filled fields within older metadata events into empty fields of newer metadata events. |
| 113 | - When a websocket is closed by the relay with a status code 4000 that means the client shouldn't try to connect again. | ||
| @@ -8,7 +8,7 @@ Event Deletion | |||
| 8 | 8 | ||
| 9 | A special event with kind `5`, meaning "deletion" is defined as having a list of one or more `e` tags, each referencing an event the author is requesting to be deleted. | 9 | A special event with kind `5`, meaning "deletion" is defined as having a list of one or more `e` tags, each referencing an event the author is requesting to be deleted. |
| 10 | 10 | ||
| 11 | Each tag entry must contain an "e" event id intended for deletion. | 11 | Each tag entry must contain an "e" event id and/or NIP-33 `a` tags intended for deletion. |
| 12 | 12 | ||
| 13 | The event's `content` field MAY contain a text note describing the reason for the deletion. | 13 | The event's `content` field MAY contain a text note describing the reason for the deletion. |
| 14 | 14 | ||
| @@ -20,7 +20,8 @@ For example: | |||
| 20 | "pubkey": <32-bytes hex-encoded public key of the event creator>, | 20 | "pubkey": <32-bytes hex-encoded public key of the event creator>, |
| 21 | "tags": [ | 21 | "tags": [ |
| 22 | ["e", "dcd59..464a2"], | 22 | ["e", "dcd59..464a2"], |
| 23 | ["e", "968c5..ad7a4"] | 23 | ["e", "968c5..ad7a4"], |
| 24 | ["a", "<kind>:<pubkey>:<d-identifier>"] | ||
| 24 | ], | 25 | ], |
| 25 | "content": "these posts were published by accident", | 26 | "content": "these posts were published by accident", |
| 26 | ...other fields | 27 | ...other fields |
| @@ -255,6 +255,18 @@ Relays that require payments may want to expose their fee schedules. | |||
| 255 | } | 255 | } |
| 256 | ``` | 256 | ``` |
| 257 | 257 | ||
| 258 | ### Icon ### | ||
| 259 | |||
| 260 | A URL pointing to an image to be used as an icon for the relay. Recommended to be squared in shape. | ||
| 261 | |||
| 262 | ```json | ||
| 263 | { | ||
| 264 | ... | ||
| 265 | "icon": "https://nostr.build/i/53866b44135a27d624e99c6165cabd76ac8f72797209700acb189fce75021f47.jpg", | ||
| 266 | ... | ||
| 267 | } | ||
| 268 | ``` | ||
| 269 | |||
| 258 | ### Examples ### | 270 | ### Examples ### |
| 259 | As of 2 May 2023 the following `curl` command provided these results. | 271 | As of 2 May 2023 the following `curl` command provided these results. |
| 260 | 272 | ||
| @@ -281,4 +293,5 @@ As of 2 May 2023 the following `curl` command provided these results. | |||
| 281 | "payment_required":true}, | 293 | "payment_required":true}, |
| 282 | "payments_url":"https://eden.nostr.land/invoices", | 294 | "payments_url":"https://eden.nostr.land/invoices", |
| 283 | "fees":{"admission":[{"amount":5000000,"unit":"msats"}], | 295 | "fees":{"admission":[{"amount":5000000,"unit":"msats"}], |
| 284 | "publication":[]}} | 296 | "publication":[]}}, |
| 297 | "icon": "https://nostr.build/i/53866b44135a27d624e99c6165cabd76ac8f72797209700acb189fce75021f47.jpg" | ||
| @@ -6,11 +6,10 @@ Reposts | |||
| 6 | 6 | ||
| 7 | `draft` `optional` `author:jb55` `author:fiatjaf` `author:arthurfranca` | 7 | `draft` `optional` `author:jb55` `author:fiatjaf` `author:arthurfranca` |
| 8 | 8 | ||
| 9 | A repost is a `kind 6` note that is used to signal to followers | 9 | A repost is a `kind 6` event that is used to signal to followers |
| 10 | that another event is worth reading. | 10 | that a `kind 1` text note is worth reading. |
| 11 | 11 | ||
| 12 | The `content` of a repost event is empty. Optionally, it MAY contain | 12 | The `content` of a repost event is _the stringified JSON of the reposted note_. It MAY also be empty, but that is not recommended. |
| 13 | the stringified JSON of the reposted note event for quick look up. | ||
| 14 | 13 | ||
| 15 | The repost event MUST include an `e` tag with the `id` of the note that is | 14 | The repost event MUST include an `e` tag with the `id` of the note that is |
| 16 | being reposted. That tag MUST include a relay URL as its third entry | 15 | being reposted. That tag MUST include a relay URL as its third entry |
| @@ -21,5 +20,15 @@ reposted. | |||
| 21 | 20 | ||
| 22 | ## Quote Reposts | 21 | ## Quote Reposts |
| 23 | 22 | ||
| 24 | Quote reposts are `kind 1` events with an embedded `e` tag (see [NIP-08](08.md) and [NIP-27](27.md)). | 23 | Quote reposts are `kind 1` events with an embedded `e` tag |
| 25 | Because a quote repost includes an `e` tag, it may show up along replies to the reposted note. | 24 | (see [NIP-08](08.md) and [NIP-27](27.md)). Because a quote repost includes |
| 25 | an `e` tag, it may show up along replies to the reposted note. | ||
| 26 | |||
| 27 | ## Generic Reposts | ||
| 28 | |||
| 29 | Since `kind 6` reposts are reserved for `kind 1` contents, we use `kind 16` | ||
| 30 | as a "generic repost", that can include any kind of event inside other than | ||
| 31 | `kind 1`. | ||
| 32 | |||
| 33 | `kind 16` reposts SHOULD contain a `k` tag with the stringified kind number | ||
| 34 | of the reposted event as its value. | ||
| @@ -0,0 +1,68 @@ | |||
| 1 | NIP-98 | ||
| 2 | ====== | ||
| 3 | |||
| 4 | HTTP Auth | ||
| 5 | ------------------------- | ||
| 6 | |||
| 7 | `draft` `optional` `author:kieran` `author:melvincarvalho` | ||
| 8 | |||
| 9 | This NIP defines an ephemerial event used to authorize requests to HTTP servers using nostr events. | ||
| 10 | |||
| 11 | This is useful for HTTP services which are build for Nostr and deal with Nostr user accounts. | ||
| 12 | |||
| 13 | ## Nostr event | ||
| 14 | |||
| 15 | A `kind 27235` (In reference to [RFC 7235](https://www.rfc-editor.org/rfc/rfc7235)) event is used. | ||
| 16 | |||
| 17 | The `content` SHOULD be empty. | ||
| 18 | |||
| 19 | The following tags are defined as REQUIRED. | ||
| 20 | |||
| 21 | * `u` - absolute URL | ||
| 22 | * `method` - HTTP Request Method | ||
| 23 | |||
| 24 | Example event: | ||
| 25 | ```json | ||
| 26 | { | ||
| 27 | "id": "fe964e758903360f28d8424d092da8494ed207cba823110be3a57dfe4b578734", | ||
| 28 | "pubkey": "63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed", | ||
| 29 | "content": "", | ||
| 30 | "kind": 27235, | ||
| 31 | "created_at": 1682327852, | ||
| 32 | "tags": [ | ||
| 33 | [ | ||
| 34 | "u", | ||
| 35 | "https://api.snort.social/api/v1/n5sp/list" | ||
| 36 | ], | ||
| 37 | [ | ||
| 38 | "method", | ||
| 39 | "GET" | ||
| 40 | ] | ||
| 41 | ], | ||
| 42 | "sig": "5ed9d8ec958bc854f997bdc24ac337d005af372324747efe4a00e24f4c30437ff4dd8308684bed467d9d6be3e5a517bb43b1732cc7d33949a3aaf86705c22184" | ||
| 43 | } | ||
| 44 | ``` | ||
| 45 | |||
| 46 | Servers MUST perform the following checks in order to validate the event: | ||
| 47 | 1. The `kind` MUST be `27235`. | ||
| 48 | 2. The `created_at` MUST be within a reasonable time window (suggestion 60 seconds). | ||
| 49 | 3. The `u` tag MUST be exactly the same as the absolute request URL (including query parameters). | ||
| 50 | 4. The `method` tag MUST be the same HTTP method used for the requested resource. | ||
| 51 | |||
| 52 | When the request contains a body (as in POST/PUT/PATCH methods) clients SHOULD include a SHA256 hash of the request body in a `payload` tag as hex (`["payload", "<sha256-hex>"]`), servers MAY check this to validate that the requested payload is authorized. | ||
| 53 | |||
| 54 | If one of the checks was to fail the server SHOULD respond with a 401 Unauthorized response code. | ||
| 55 | |||
| 56 | All other checks which server MAY do are OPTIONAL, and implementation specific. | ||
| 57 | |||
| 58 | ## Request Flow | ||
| 59 | |||
| 60 | Using the `Authorization` header, the `kind 27235` event MUST be `base64` encoded and use the Authorization scheme `Nostr` | ||
| 61 | |||
| 62 | Example HTTP Authorization header: | ||
| 63 | ``` | ||
| 64 | Authorization: Nostr eyJpZCI6ImZlOTY0ZTc1ODkwMzM2MGYyOGQ4NDI0ZDA5MmRhODQ5NGVkMjA3Y2JhODIzMTEwYmUzYTU3ZGZlNGI1Nzg3MzQiLCJwdWJrZXkiOiI2M2ZlNjMxOGRjNTg1ODNjZmUxNjgxMGY4NmRkMDllMThiZmQ3NmFhYmMyNGEwMDgxY2UyODU2ZjMzMDUwNGVkIiwiY29udGVudCI6IiIsImtpbmQiOjI3MjM1LCJjcmVhdGVkX2F0IjoxNjgyMzI3ODUyLCJ0YWdzIjpbWyJ1cmwiLCJodHRwczovL2FwaS5zbm9ydC5zb2NpYWwvYXBpL3YxL241c3AvbGlzdCJdLFsibWV0aG9kIiwiR0VUIl1dLCJzaWciOiI1ZWQ5ZDhlYzk1OGJjODU0Zjk5N2JkYzI0YWMzMzdkMDA1YWYzNzIzMjQ3NDdlZmU0YTAwZTI0ZjRjMzA0MzdmZjRkZDgzMDg2ODRiZWQ0NjdkOWQ2YmUzZTVhNTE3YmI0M2IxNzMyY2M3ZDMzOTQ5YTNhYWY4NjcwNWMyMjE4NCJ9 | ||
| 65 | ``` | ||
| 66 | |||
| 67 | ## Reference Implementations | ||
| 68 | - C# ASP.NET `AuthenticationHandler` [NostrAuth.cs](https://gist.github.com/v0l/74346ae530896115bfe2504c8cd018d3) \ No newline at end of file | ||
| @@ -65,6 +65,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos | |||
| 65 | - [NIP-78: Application-specific data](78.md) | 65 | - [NIP-78: Application-specific data](78.md) |
| 66 | - [NIP-89: Recommended Application Handlers](89.md) | 66 | - [NIP-89: Recommended Application Handlers](89.md) |
| 67 | - [NIP-94: File Metadata](94.md) | 67 | - [NIP-94: File Metadata](94.md) |
| 68 | - [NIP-98: HTTP Auth](98.md) | ||
| 68 | 69 | ||
| 69 | ## Event Kinds | 70 | ## Event Kinds |
| 70 | 71 | ||
| @@ -76,9 +77,10 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos | |||
| 76 | | `3` | Contacts | [2](02.md) | | 77 | | `3` | Contacts | [2](02.md) | |
| 77 | | `4` | Encrypted Direct Messages | [4](04.md) | | 78 | | `4` | Encrypted Direct Messages | [4](04.md) | |
| 78 | | `5` | Event Deletion | [9](09.md) | | 79 | | `5` | Event Deletion | [9](09.md) | |
| 79 | | `6` | Reposts | [18](18.md) | | 80 | | `6` | Repost | [18](18.md) | |
| 80 | | `7` | Reaction | [25](25.md) | | 81 | | `7` | Reaction | [25](25.md) | |
| 81 | | `8` | Badge Award | [58](58.md) | | 82 | | `8` | Badge Award | [58](58.md) | |
| 83 | | `16` | Generic Repost | [18](18.md) | | ||
| 82 | | `40` | Channel Creation | [28](28.md) | | 84 | | `40` | Channel Creation | [28](28.md) | |
| 83 | | `41` | Channel Metadata | [28](28.md) | | 85 | | `41` | Channel Metadata | [28](28.md) | |
| 84 | | `42` | Channel Message | [28](28.md) | | 86 | | `42` | Channel Message | [28](28.md) | |
| @@ -96,6 +98,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos | |||
| 96 | | `23194` | Wallet Request | [47](47.md) | | 98 | | `23194` | Wallet Request | [47](47.md) | |
| 97 | | `23195` | Wallet Response | [47](47.md) | | 99 | | `23195` | Wallet Response | [47](47.md) | |
| 98 | | `24133` | Nostr Connect | [46](46.md) | | 100 | | `24133` | Nostr Connect | [46](46.md) | |
| 101 | | `27235` | HTTP Auth | [98](98.md) | | ||
| 99 | | `30000` | Categorized People List | [51](51.md) | | 102 | | `30000` | Categorized People List | [51](51.md) | |
| 100 | | `30001` | Categorized Bookmark List | [51](51.md) | | 103 | | `30001` | Categorized Bookmark List | [51](51.md) | |
| 101 | | `30008` | Profile Badges | [58](58.md) | | 104 | | `30008` | Profile Badges | [58](58.md) | |