diff --git a/18.md b/18.md index 27c5915a..41c94424 100644 --- a/18.md +++ b/18.md @@ -25,6 +25,14 @@ quote reposted. The `q` tag ensures quote reposts are not pulled and included as replies in threads. It also allows you to easily pull and count all of the quotes for a post. +`q` tags should follow the same conventions as NIP 10 `e` tags, with the exception +of the `mark` argument. + +`["q", , , ]` + +Quote reposts MUST include the [NIP-21](21.md) `nevent`, `note`, or `naddr` of the +event in the content. + ## Generic Reposts Since `kind 6` reposts are reserved for `kind 1` contents, we use `kind 16` diff --git a/23.md b/23.md index 720f6d61..e5e85ff9 100644 --- a/23.md +++ b/23.md @@ -20,7 +20,7 @@ The `.content` of these events should be a string text in Markdown syntax. To ma ### Metadata -For the date of the last update the `.created_at` field should be used, for "tags"/"hashtags" (i.e. topics about which the event might be of relevance) the `t` tag should be used, as per NIP-12. +For the date of the last update the `.created_at` field should be used, for "tags"/"hashtags" (i.e. topics about which the event might be of relevance) the `t` tag should be used. Other metadata fields can be added as tags to the event as necessary. Here we standardize 4 that may be useful, although they remain strictly optional: diff --git a/55.md b/55.md index c0ee9579..d78bc8ca 100644 --- a/55.md +++ b/55.md @@ -101,10 +101,10 @@ launcher.launch(intent) context.startActivity(intent) ``` - result: - - If the user approved intent it will return the **npub** in the signature field + - If the user approved intent it will return the **pubkey** in the signature field ```kotlin - val npub = intent.data?.getStringExtra("signature") + val pubkey = intent.data?.getStringExtra("signature") // The package name of the signer application val packageName = intent.data?.getStringExtra("package") ``` @@ -118,8 +118,8 @@ launcher.launch(intent) intent.putExtra("type", "sign_event") // To handle results when not waiting between intents intent.putExtra("id", event.id) - // Send the current logged in user npub - intent.putExtra("current_user", npub) + // Send the current logged in user pubkey + intent.putExtra("current_user", pubkey) context.startActivity(intent) ``` @@ -142,10 +142,10 @@ launcher.launch(intent) intent.putExtra("type", "nip04_encrypt") // to control the result in your application in case you are not waiting the result before sending another intent intent.putExtra("id", "some_id") - // Send the current logged in user npub - intent.putExtra("current_user", account.keyPair.pubKey.toNpub()) - // Send the hex pubKey that will be used for encrypting the data - intent.putExtra("pubKey", pubKey) + // Send the current logged in user pubkey + intent.putExtra("current_user", account.keyPair.pubkey) + // Send the hex pubkey that will be used for encrypting the data + intent.putExtra("pubkey", pubkey) context.startActivity(intent) ``` @@ -167,10 +167,10 @@ launcher.launch(intent) intent.putExtra("type", "nip44_encrypt") // to control the result in your application in case you are not waiting the result before sending another intent intent.putExtra("id", "some_id") - // Send the current logged in user npub - intent.putExtra("current_user", account.keyPair.pubKey.toNpub()) - // Send the hex pubKey that will be used for encrypting the data - intent.putExtra("pubKey", pubKey) + // Send the current logged in user pubkey + intent.putExtra("current_user", account.keyPair.pubkey) + // Send the hex pubkey that will be used for encrypting the data + intent.putExtra("pubkey", pubkey) context.startActivity(intent) ``` @@ -192,10 +192,10 @@ launcher.launch(intent) intent.putExtra("type", "nip04_decrypt") // to control the result in your application in case you are not waiting the result before sending another intent intent.putExtra("id", "some_id") - // Send the current logged in user npub - intent.putExtra("current_user", account.keyPair.pubKey.toNpub()) - // Send the hex pubKey that will be used for decrypting the data - intent.putExtra("pubKey", pubKey) + // Send the current logged in user pubkey + intent.putExtra("current_user", account.keyPair.pubkey) + // Send the hex pubkey that will be used for decrypting the data + intent.putExtra("pubkey", pubkey) context.startActivity(intent) ``` @@ -217,10 +217,10 @@ launcher.launch(intent) intent.putExtra("type", "nip04_decrypt") // to control the result in your application in case you are not waiting the result before sending another intent intent.putExtra("id", "some_id") - // Send the current logged in user npub - intent.putExtra("current_user", account.keyPair.pubKey.toNpub()) - // Send the hex pubKey that will be used for decrypting the data - intent.putExtra("pubKey", pubKey) + // Send the current logged in user pubkey + intent.putExtra("current_user", account.keyPair.pubkey) + // Send the hex pubkey that will be used for decrypting the data + intent.putExtra("pubkey", pubkey) context.startActivity(intent) ``` @@ -233,6 +233,29 @@ launcher.launch(intent) val id = intent.data?.getStringExtra("id") ``` +- **get_relays** + - params: + + ```kotlin + val intent = Intent(Intent.ACTION_VIEW, Uri.parse("nostrsigner:")) + intent.`package` = "com.example.signer" + intent.putExtra("type", "get_relays") + // to control the result in your application in case you are not waiting the result before sending another intent + intent.putExtra("id", "some_id") + // Send the current logged in user pubkey + intent.putExtra("current_user", account.keyPair.pubkey) + + context.startActivity(intent) + ``` + - result: + - If the user approved intent it will return the **signature** and **id** fields + + ```kotlin + val relayJsonText = intent.data?.getStringExtra("signature") + // the id you sent + val id = intent.data?.getStringExtra("id") + ``` + - **decrypt_zap_event** - params: @@ -242,8 +265,8 @@ launcher.launch(intent) intent.putExtra("type", "decrypt_zap_event") // to control the result in your application in case you are not waiting the result before sending another intent intent.putExtra("id", "some_id") - // Send the current logged in user npub - intent.putExtra("current_user", account.keyPair.pubKey.toNpub()) + // Send the current logged in user pubkey + intent.putExtra("current_user", account.keyPair.pubkey) context.startActivity(intent) ``` - result: @@ -259,7 +282,7 @@ launcher.launch(intent) To get the result back from Signer Application you should use contentResolver.query in Kotlin. If you are using another framework check the documentation of your framework or a third party library to get the result. -If the user did not check the "remember my choice" option, the npub is not in Signer Application or the signer type is not recognized the `contentResolver` will return null +If the user did not check the "remember my choice" option, the pubkey is not in Signer Application or the signer type is not recognized the `contentResolver` will return null For the SIGN_EVENT type Signer Application returns two columns "signature" and "event". The column event is the signed event json @@ -282,7 +305,7 @@ If the user chose to always reject the event, signer application will return the ) ``` - result: - - Will return the **npub** in the signature column + - Will return the **pubkey** in the signature column ```kotlin if (result == null) return @@ -290,7 +313,7 @@ If the user chose to always reject the event, signer application will return the if (result.moveToFirst()) { val index = it.getColumnIndex("signature") if (index < 0) return - val npub = it.getString(index) + val pubkey = it.getString(index) } ``` @@ -300,7 +323,7 @@ If the user chose to always reject the event, signer application will return the ```kotlin val result = context.contentResolver.query( Uri.parse("content://com.example.signer.SIGN_EVENT"), - listOf("$eventJson", "", "${logged_in_user_npub}"), + listOf("$eventJson", "", "${logged_in_user_pubkey}"), null, null, null @@ -326,7 +349,7 @@ If the user chose to always reject the event, signer application will return the ```kotlin val result = context.contentResolver.query( Uri.parse("content://com.example.signer.NIP04_ENCRYPT"), - listOf("$plainText", "${hex_pub_key}", "${logged_in_user_npub}"), + listOf("$plainText", "${hex_pub_key}", "${logged_in_user_pubkey}"), null, null, null @@ -350,7 +373,7 @@ If the user chose to always reject the event, signer application will return the ```kotlin val result = context.contentResolver.query( Uri.parse("content://com.example.signer.NIP44_ENCRYPT"), - listOf("$plainText", "${hex_pub_key}", "${logged_in_user_npub}"), + listOf("$plainText", "${hex_pub_key}", "${logged_in_user_pubkey}"), null, null, null @@ -374,7 +397,7 @@ If the user chose to always reject the event, signer application will return the ```kotlin val result = context.contentResolver.query( Uri.parse("content://com.example.signer.NIP04_DECRYPT"), - listOf("$encryptedText", "${hex_pub_key}", "${logged_in_user_npub}"), + listOf("$encryptedText", "${hex_pub_key}", "${logged_in_user_pubkey}"), null, null, null @@ -398,7 +421,7 @@ If the user chose to always reject the event, signer application will return the ```kotlin val result = context.contentResolver.query( Uri.parse("content://com.example.signer.NIP44_DECRYPT"), - listOf("$encryptedText", "${hex_pub_key}", "${logged_in_user_npub}"), + listOf("$encryptedText", "${hex_pub_key}", "${logged_in_user_pubkey}"), null, null, null @@ -416,13 +439,37 @@ If the user chose to always reject the event, signer application will return the } ``` +- **get_relays** + - params: + + ```kotlin + val result = context.contentResolver.query( + Uri.parse("content://com.example.signer.GET_RELAYS"), + listOf("${logged_in_user_pubkey}"), + null, + null, + null + ) + ``` + - result: + - Will return the **signature** column + + ```kotlin + if (result == null) return + + if (result.moveToFirst()) { + val index = it.getColumnIndex("signature") + val relayJsonText = it.getString(index) + } + ``` + - **decrypt_zap_event** - params: ```kotlin val result = context.contentResolver.query( Uri.parse("content://com.example.signer.DECRYPT_ZAP_EVENT"), - listOf("$eventJson", "", "${logged_in_user_npub}"), + listOf("$eventJson", "", "${logged_in_user_pubkey}"), null, null, null @@ -472,28 +519,35 @@ Android intents and browser urls have limitations, so if you are using the `retu - params: ```js - window.href = `nostrsigner:${plainText}?pubKey=${hex_pub_key}&compressionType=none&returnType=signature&type=nip04_encrypt&callbackUrl=https://example.com/?event=`; + window.href = `nostrsigner:${plainText}?pubkey=${hex_pub_key}&compressionType=none&returnType=signature&type=nip04_encrypt&callbackUrl=https://example.com/?event=`; ``` - **nip44_encrypt** - params: ```js - window.href = `nostrsigner:${plainText}?pubKey=${hex_pub_key}&compressionType=none&returnType=signature&type=nip44_encrypt&callbackUrl=https://example.com/?event=`; + window.href = `nostrsigner:${plainText}?pubkey=${hex_pub_key}&compressionType=none&returnType=signature&type=nip44_encrypt&callbackUrl=https://example.com/?event=`; ``` - **nip04_decrypt** - params: ```js - window.href = `nostrsigner:${encryptedText}?pubKey=${hex_pub_key}&compressionType=none&returnType=signature&type=nip04_decrypt&callbackUrl=https://example.com/?event=`; + window.href = `nostrsigner:${encryptedText}?pubkey=${hex_pub_key}&compressionType=none&returnType=signature&type=nip04_decrypt&callbackUrl=https://example.com/?event=`; ``` - **nip44_decrypt** - params: ```js - window.href = `nostrsigner:${encryptedText}?pubKey=${hex_pub_key}&compressionType=none&returnType=signature&type=nip44_decrypt&callbackUrl=https://example.com/?event=`; + window.href = `nostrsigner:${encryptedText}?pubkey=${hex_pub_key}&compressionType=none&returnType=signature&type=nip44_decrypt&callbackUrl=https://example.com/?event=`; + ``` + +- **get_relays** + - params: + + ```js + window.href = `nostrsigner:?compressionType=none&returnType=signature&type=get_relays&callbackUrl=https://example.com/?event=`; ``` - **decrypt_zap_event** diff --git a/71.md b/71.md index dd813e93..5edd7c60 100644 --- a/71.md +++ b/71.md @@ -20,21 +20,60 @@ The format uses an _addressable event_ kind `34235` for horizontal videos and `3 The `.content` of these events is a summary or description on the video content. -The list of tags are as follows: -* `d` (required) universally unique identifier (UUID). Generated by the client creating the video event. -* `url` (required) the url to the video 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. +The primary source of video information is the `imeta` tags which is defined in [NIP-92](92.md) + +Each `imeta` tag can be used to specify a variant of the video by the `dim` & `m` properties. + +Example: +```json +[ + ["imeta", + "dim 1920x1080", + "url https://myvideo.com/1080/12345.mp4", + "x 3093509d1e0bc604ff60cb9286f4cd7c781553bc8991937befaacfdc28ec5cdc", + "m video/mp4", + "image https://myvideo.com/1080/12345.jpg", + "image https://myotherserver.com/1080/12345.jpg", + "fallback https://myotherserver.com/1080/12345.mp4", + "fallback https://andanotherserver.com/1080/12345.mp4", + "service nip96", + ], + ["imeta", + "dim 1280x720", + "url https://myvideo.com/720/12345.mp4", + "x e1d4f808dae475ed32fb23ce52ef8ac82e3cc760702fca10d62d382d2da3697d", + "m video/mp4", + "image https://myvideo.com/720/12345.jpg", + "image https://myotherserver.com/720/12345.jpg", + "fallback https://myotherserver.com/720/12345.mp4", + "fallback https://andanotherserver.com/720/12345.mp4", + "service nip96", + ], + ["imeta", + "dim 1280x720", + "url https://myvideo.com/720/12345.m3u8", + "x 704e720af2697f5d6a198ad377789d462054b6e8d790f8a3903afbc1e044014f", + "m application/x-mpegURL", + "image https://myvideo.com/720/12345.jpg", + "image https://myotherserver.com/720/12345.jpg", + "fallback https://myotherserver.com/720/12345.m3u8", + "fallback https://andanotherserver.com/720/12345.m3u8", + "service nip96", + ], +] +``` + +Where `url` is the primary server url and `fallback` are other servers hosting the same file, both `url` and `fallback` should be weighted equally and clients are recommended to use any of the provided video urls. + +The `image` tag contains a preview image (at the same resolution). Multiple `image` tags may be used to specify fallback copies in the same way `fallback` is used for `url`. + +Additionally `service nip96` may be included to allow clients to search the authors NIP-96 server list to find the file using the hash. + +### Other tags: * `title` (required) title of the video -* `"published_at"`, for the timestamp in unix seconds (stringified) of the first time the video was published -* `x` containing the SHA-256 hexencoded string of the file. -* `size` (optional) size of file in bytes -* `dim` (optional) size of file in pixels in the form `x` +* `published_at`, for the timestamp in unix seconds (stringified) of the first time the video was published * `duration` (optional) video duration in seconds -* `magnet` (optional) URI to magnet file -* `i` (optional) torrent infohash * `text-track` (optional, repeated) link to WebVTT file for video, type of supplementary information (captions/subtitles/chapters/metadata), optional language code -* `thumb` (optional) url of thumbnail with same aspect ratio -* `image` (optional) url of preview image with same dimensions * `content-warning` (optional) warning about content of NSFW video * `alt` (optional) description for accessibility * `segment` (optional, repeated) start timestamp in format `HH:MM:SS.sss`, end timestamp in format `HH:MM:SS.sss`, chapter/segment title, chapter thumbnail-url @@ -53,19 +92,23 @@ The list of tags are as follows: ["d", ""], ["title", ""], - ["thumb", "<thumbnail image for video>"], ["published_at", "<unix timestamp>"], ["alt", <description>], // Video Data - ["url",<string with URI of file>], - ["m", <MIME type>], - ["x",<Hash SHA-256>], - ["size", <size of file in bytes>], + ["imeta", + "dim 1920x1080", + "url https://myvideo.com/1080/12345.mp4", + "x 3093509d1e0bc604ff60cb9286f4cd7c781553bc8991937befaacfdc28ec5cdc", + "m video/mp4", + "image https://myvideo.com/1080/12345.jpg", + "image https://myotherserver.com/1080/12345.jpg", + "fallback https://myotherserver.com/1080/12345.mp4", + "fallback https://andanotherserver.com/1080/12345.mp4", + "service nip96", + ], + ["duration", <duration of video in seconds>], - ["dim", <size of file in pixels>], - ["magnet",<magnet URI> ], - ["i",<torrent infohash>], ["text-track", "<encoded `kind 6000` event>", "<recommended relay urls>"], ["content-warning", "<reason>"], ["segment", <start>, <end>, "<title>", "<thumbnail URL>"], @@ -83,36 +126,4 @@ The list of tags are as follows: ["r", "<url>"] ] } -``` - -## Video View - -A video event view is a response to a video event to track a user's view or progress viewing the video. - -### Format - -The format uses an _addressable event_ kind `34237`. - -The `.content` of these events is optional and could be a free-form note that acts like a bookmark for the user. - -The list of tags are as follows: -* `a` (required) reference tag to kind `34235` or `34236` video event being viewed -* `d` (required) same as `a` reference tag value -* `viewed` (optional, repeated) timestamp of the user's start time in seconds, timestamp of the user's end time in seconds - - -```json -{ - "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>, - "created_at": <Unix timestamp in seconds>, - "kind": 34237, - "content": "<note>", - "tags": [ - ["a", "<34235 | 34236>:<video event author pubkey>:<d-identifier of video event>", "<optional relay url>"], - ["e", "<event-id", "<relay-url>"] - ["d", "<34235 | 34236>:<video event author pubkey>:<d-identifier of video event>"], - ["viewed", <start>, <end>], - ] -} -``` +``` \ No newline at end of file diff --git a/94.md b/94.md index a057cb2d..021cc4c3 100644 --- a/94.md +++ b/94.md @@ -26,6 +26,7 @@ This NIP specifies the use of the `1063` event type, having in `content` a descr * `summary` (optional) text excerpt * `alt` (optional) description for accessibility * `fallback` (optional) zero or more fallback file sources in case `url` fails +* `service` (optional) service type which is serving the file (eg. [NIP-96](96.md)) ```jsonc { @@ -33,15 +34,15 @@ This NIP specifies the use of the `1063` event type, having in `content` a descr "tags": [ ["url",<string with URI of file>], ["m", <MIME type>], - ["x",<Hash SHA-256>], - ["ox",<Hash SHA-256>], + ["x", <Hash SHA-256>], + ["ox", <Hash SHA-256>], ["size", <size of file in bytes>], ["dim", <size of file in pixels>], - ["magnet",<magnet URI> ], - ["i",<torrent infohash>], + ["magnet", <magnet URI> ], + ["i", <torrent infohash>], ["blurhash", <value>], - ["thumb", <string with thumbnail URI>], - ["image", <string with preview URI>], + ["thumb", <string with thumbnail URI>, <Hash SHA-256>], + ["image", <string with preview URI>, <Hash SHA-256>], ["summary", <excerpt>], ["alt", <description>] ], diff --git a/99.md b/99.md index e2ffc3b8..724ce5f5 100644 --- a/99.md +++ b/99.md @@ -26,7 +26,7 @@ The `.pubkey` field of these events are treated as the party creating the listin ### Metadata -- For "tags"/"hashtags" (i.e. categories or keywords of relevance for the listing) the `"t"` event tag should be used, as per [NIP-12](12.md). +- For "tags"/"hashtags" (i.e. categories or keywords of relevance for the listing) the `"t"` event tag should be used. - For images, whether included in the markdown content or not, clients SHOULD use `image` tags as described in [NIP-58](58.md). This allows clients to display images in carousel format more easily. The following tags, used for structured metadata, are standardized and SHOULD be included. Other tags may be added as necessary. diff --git a/BREAKING.md b/BREAKING.md index 83b104b6..aba5b835 100644 --- a/BREAKING.md +++ b/BREAKING.md @@ -5,6 +5,7 @@ reverse chronological order. | Date | Commit | NIP | Change | | ----------- | --------- | -------- | ------ | +| 2024-10-07 | [7bb8997b](https://github.com/nostr-protocol/nips/commit/7bb8997b) | [NIP-55](55.md) | some fields and passing data were changed | | 2024-08-18 | [3aff37bd](https://github.com/nostr-protocol/nips/commit/3aff37bd) | [NIP-54](54.md) | content should be Asciidoc | | 2024-07-31 | [3ea2f1a4](https://github.com/nostr-protocol/nips/commit/3ea2f1a4) | [NIP-45](45.md) | [444ad28d](https://github.com/nostr-protocol/nips/commit/444ad28d) was reverted | | 2024-07-30 | [444ad28d](https://github.com/nostr-protocol/nips/commit/444ad28d) | [NIP-45](45.md) | NIP-45 was deprecated | diff --git a/README.md b/README.md index e5e31c68..9566dff6 100644 --- a/README.md +++ b/README.md @@ -191,12 +191,14 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos | `30078` | Application-specific Data | [78](78.md) | | `30311` | Live Event | [53](53.md) | | `30315` | User Statuses | [38](38.md) | +| `30388` | Slide Set | [Corny Chat][cornychat-slideset] | | `30402` | Classified Listing | [99](99.md) | | `30403` | Draft Classified Listing | [99](99.md) | | `30617` | Repository announcements | [34](34.md) | | `30618` | Repository state announcements | [34](34.md) | | `30818` | Wiki article | [54](54.md) | | `30819` | Redirects | [54](54.md) | +| `31388` | Link Set | [Corny Chat][cornychat-linkset] | | `31890` | Feed | [NUD: Custom Feeds][NUD: Custom Feeds] | | `31922` | Date-Based Calendar Event | [52](52.md) | | `31923` | Time-Based Calendar Event | [52](52.md) | @@ -213,6 +215,8 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos [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 +[cornychat-slideset]: https://cornychat.com/datatypes#kind30388slideset +[cornychat-linkset]: https://cornychat.com/datatypes#kind31388linkset [joinstr]: https://gitlab.com/1440000bytes/joinstr/-/blob/main/NIP.md [NKBIP-01]: https://wikistr.com/nkbip-01 [NKBIP-02]: https://wikistr.com/nkbip-02 @@ -259,7 +263,7 @@ 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) | -| `q` | event id (hex) | relay URL | [18](18.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) | | `t` | hashtag | -- | [24](24.md), [34](34.md) |