Compare commits

...

9 Commits

Author SHA1 Message Date
alltheseas
520b901629 NIP-17: Clarify client event publishing instructions (#2097) 2025-10-28 10:49:19 -04:00
alltheseas
bcaad2957d Enhance metadata/timestamp protection guidance in NIP-59 (#2095) 2025-10-27 10:56:47 -07:00
DanConwayDev
6e6b9877b3 NIP-34: add PR and PR update events (#1966) 2025-10-16 12:08:48 -05:00
Vitor Pamplona
3f79b7fde2 NIP-18: Normalize its q tags with the definition on NIP-22 (#1746) 2025-10-16 04:44:37 -07:00
Kieran
a3c5554e34 Add duration & bitrate to NIP-71 (#1723)
Co-authored-by: Vitor Pamplona <vitor@vitorpamplona.com>
2025-10-15 16:15:27 -04:00
Vitor Pamplona
7b24bf803f NIP-37: Improving Draft events (#2016) 2025-10-15 16:09:36 -04:00
greenart7c3
d54c426709 [NIP 55] - Instructions on how to use the get_public_key method with content resolver (#2086) 2025-10-13 11:21:07 -07:00
Sandwich
179e421011 nip66: tags shouldn't have integers (#2085) 2025-10-13 05:26:14 -07:00
Vitor Pamplona
74681c3c14 NIP-45 is not a subscription. Changing to query id to reduce confusion. (#2083) 2025-10-08 17:43:37 -05:00
10 changed files with 146 additions and 51 deletions

2
17.md
View File

@@ -145,7 +145,7 @@ Kind `10050` indicates the user's preferred relays to receive DMs. The event MUS
}
```
Clients SHOULD publish kind `14` events to the `10050`-listed relays. If that is not found that indicates the user is not ready to receive messages under this NIP and clients shouldn't try.
Clients SHOULD publish the gift-wrapped kind 1059 events that contain the sealed kind 14 (text) or kind 15 (file) rumors to the relays listed in the recipients kind 10050 event. If that is not found that indicates the user is not ready to receive messages under this NIP and clients shouldn't try.
## Relays

16
18.md
View File

@@ -21,18 +21,12 @@ reposted.
## Quote Reposts
Quote reposts are `kind 1` events with an embedded `q` tag of the note being
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.
Mentions to [NIP-21](21.md) entities like `nevent`, `note` and `naddr` on any
event must be converted into `q` tags. 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. The syntax follows
`q` tags should follow the same conventions as NIP 10 `e` tags, with the exception
of the `mark` argument.
`["q", <event-id>, <relay-url>, <pubkey>]`
Quote reposts MUST include the [NIP-21](21.md) `nevent`, `note`, or `naddr` of the
event in the content.
`["q", "<event-id> or <event-address>", "<relay-url>", "<pubkey-if-a-regular-event>"]`
## Generic Reposts

92
34.md
View File

@@ -10,7 +10,7 @@ This NIP defines all the ways code collaboration using and adjacent to [`git`](h
## Repository announcements
Git repositories are hosted in Git-enabled servers, but their existence can be announced using Nostr events, as well as their willingness to receive patches, bug reports and comments in general.
Git repositories are hosted in Git-enabled servers, but their existence can be announced using Nostr events. By doing so the author asserts themselves as a maintainer and expresses a willingness to receive patches, bug reports and comments in general, unless `t` tag `personal-fork` is included.
```jsonc
{
@@ -25,6 +25,7 @@ Git repositories are hosted in Git-enabled servers, but their existence can be a
["relays", "<relay-url>", ...], // relays that this repository will monitor for patches and issues
["r", "<earliest-unique-commit-id>", "euc"],
["maintainers", "<other-recognized-maintainer>", ...],
["t","personal-fork"], // optionally indicate author isn't a maintainer
["t", "<arbitrary string>"], // hashtags labelling the repository
]
}
@@ -66,9 +67,13 @@ The `refs` tag can be optionally extended to enable clients to identify how many
}
```
## Patches
## Patches and Pull Requests (PRs)
Patches can be sent by anyone to any repository. Patches to a specific repository SHOULD be sent to the relays specified in that repository's announcement event's `"relays"` tag. Patch events SHOULD include an `a` tag pointing to that repository's announcement address.
Patches and PRs can be sent by anyone to any repository. Patches and PRs to a specific repository SHOULD be sent to the relays specified in that repository's announcement event's `"relays"` tag. Patch and PR events SHOULD include an `a` tag pointing to that repository's announcement address.
Patches SHOULD be used if each event is under 60kb, otherwise PRs SHOULD be used.
### Patches
Patches in a patch set SHOULD include a [NIP-10](10.md) `e` `reply` tag pointing to the previous patch.
@@ -103,9 +108,66 @@ The first patch revision in a patch revision SHOULD include a [NIP-10](10.md) `e
The first patch in a series MAY be a cover letter in the format produced by `git format-patch`.
### Pull Requests
The PR or PR update tip SHOULD be successfully pushed to `refs/nostr/<[PR|PR-Update]-event-id>` in all repositories listed in its `clone` tag before the event is signed.
An attempt SHOULD be made to push this ref to all repositories listed in the repository's announcement event's `"clone"` tag, for which their is reason to believe the user might have write access. This includes each [grasp server](https://njump.me/naddr1qvzqqqrhnypzpgqgmmc409hm4xsdd74sf68a2uyf9pwel4g9mfdg8l5244t6x4jdqy28wumn8ghj7un9d3shjtnwva5hgtnyv4mqqpt8wfshxuqlnvh8x) which can be identified using this method: `clone` tag includes `[http|https]://<grasp-path>/<valid-npub>/<string>.git` and `relays` tag includes `[ws/wss]://<grasp-path>`.
Clients MAY fallback to creating a 'personal-fork' `repository announcement` listing other grasp servers, e.g. from the `User grasp list`, for the purpose of serving the specified commit(s).
```jsonc
{
"kind": 1618,
"content": "<markdown text>",
"tags": [
["a", "30617:<base-repo-owner-pubkey>:<base-repo-id>"],
["r", "<earliest-unique-commit-id-of-repo>"] // so clients can subscribe to all PRs sent to a local git repo
["p", "<repository-owner>"],
["p", "<other-user>"], // optionally send the PR to another user to bring it to their attention
["subject", "<PR-subject>"],
["t", "<PR-label>"], // optional
["t", "<another-PR-label>"], // optional
["c", "<current-commit-id>"], // tip of the PR branch
["clone", "<clone-url>", ...], // at least one git clone url where commit can be downloaded
["branch-name", "<branch-name>"], // optional recommended branch name
["e", "<root-patch-event-id>"], // optionally indicate PR is a revision of an existing patch, which should be closed
["merge-base", "<commit-id>"], // optional: the most recent common ancestor with the target branch
]
}
```
### Pull Request Updates
A PR Update changes the tip of a referenced PR event.
```jsonc
{
"kind": 1619,
"content": "",
"tags": [
["a", "30617:<base-repo-owner-pubkey>:<base-repo-id>"],
["r", "<earliest-unique-commit-id-of-repo>"] // so clients can subscribe to all PRs sent to a local git repo
["p", "<repository-owner>"],
["p", "<other-user>"], // optionally send the PR to another user to bring it to their attention
// NIP-22 tags
["E", "<pull-request-event-id>"],
["P", "<pull-request-author>"],
["c", "<current-commit-id>"], // updated tip of PR
["clone", "<clone-url>", ...], // at least one git clone url where commit can be downloaded
["merge-base", "<commit-id>"], // optional: the most recent common ancestor with the target branch
]
}
```
## Issues
Issues are Markdown text that is just human-readable conversational threads related to the repository: bug reports, feature requests, questions or comments of any kind. Like patches, these SHOULD be sent to the relays specified in that repository's announcement event's `"relays"` tag.
Issues are Markdown text that is just human-readable conversational threads related to the repository: bug reports, feature requests, questions or comments of any kind. Like patches, these SHOULD be sent to the relays specified in that repository's announcement event's `"relays"` tag.
Issues may have a `subject` tag, which clients can utilize to display a header. Additionally, one or more `t` tags may be included to provide labels for the issue.
@@ -125,11 +187,11 @@ Issues may have a `subject` tag, which clients can utilize to display a header.
## Replies
Replies to either a `kind:1621` (_issue_) or a `kind:1617` (_patch_) event should follow [NIP-22 comment](22.md).
Replies to either a `kind:1621` (_issue_), `kind:1617` (_patch_) or `kind:1618` (_pull request_) event should follow [NIP-22 comment](22.md).
## Status
Root Patches and Issues have a Status that defaults to 'Open' and can be set by issuing Status events.
Root Patches, PRs and Issues have a Status that defaults to 'Open' and can be set by issuing Status events.
```jsonc
{
@@ -139,7 +201,7 @@ Root Patches and Issues have a Status that defaults to 'Open' and can be set by
"kind": 1633, // Draft
"content": "<markdown text>",
"tags": [
["e", "<issue-or-original-root-patch-id-hex>", "", "root"],
["e", "<issue-or-PR-or-original-root-patch-id-hex>", "", "root"],
["e", "<accepted-revision-root-id-hex>", "", "reply"], // for when revisions applied
["p", "<repository-owner>"],
["p", "<root-event-author>"],
@@ -165,8 +227,22 @@ The most recent Status event (by `created_at` date) from either the issue/patch
The Status of a patch-revision is to either that of the root-patch, or `1632` (_Closed_) if the root-patch's Status is `1631` (_Applied/Merged_) and the patch-revision isn't tagged in the `1631` (_Applied/Merged_) event.
## User grasp list
List of [grasp servers](https://njump.me/naddr1qvzqqqrhnypzpgqgmmc409hm4xsdd74sf68a2uyf9pwel4g9mfdg8l5244t6x4jdqy28wumn8ghj7un9d3shjtnwva5hgtnyv4mqqpt8wfshxuqlnvh8x) the user generally wishes to use for NIP-34 related activity. It is similar in function to the NIP-65 relay list and NIP-B7 blossom list.
The event SHOULD include a list of `g` tags with grasp service websocket URLs in order of preference.
```jsonc
{
"kind": 10317,
"content": "",
"tags": [
["g", "<grasp-service-websocket-url>"], // zero or more grasp sever urls
]
}
```
## Possible things to be added later
- "branch merge" kind (specifying a URL from where to fetch the branch to be merged)
- inline file comments kind (we probably need one for patches and a different one for merged files)

39
37.md
View File

@@ -1,50 +1,57 @@
NIP-37
======
Draft Events
------------
Draft Wraps
-----------
`draft` `optional`
This NIP defines kind `31234` as a private wrap for drafts of any other event kind.
This NIP defines kind `31234` as an encrypted storage for unsigned draft events of any other kind.
The draft event is JSON-stringified, [NIP44-encrypted](44.md) to the signer's public key and placed inside the `.content` of the event.
The draft is JSON-stringified, [NIP44-encrypted](44.md) to the signer's public key and placed inside the `.content`.
An additional `k` tag identifies the kind of the draft event.
`k` tags identify the kind of the draft.
```js
{
"kind": 31234,
"tags": [
["d", "<identifier>"],
["k", "<kind of the draft event>"],
["e", "<anchor event event id>", "<relay-url>"],
["a", "<anchor event address>", "<relay-url>"],
["k", "<kind of the draft event>"], // required
["expiration", "now + 90 days"] // recommended
],
"content": nip44Encrypt(JSON.stringify(draft_event)),
// other fields
}
```
A blanked `.content` means this draft has been deleted by a client but relays still have the event.
A blanked `.content` field signals that the draft has been deleted.
Tags `e` and `a` identify one or more anchor events, such as parent events on replies.
[NIP-40](40.md) `expiration` tags are recommended.
Clients SHOULD publish kind `31234` events to relays listed on kind `10013` below.
## Relay List for Private Content
Kind `10013` indicates the user's preferred relays to store private events like Drafts. The event MUST include a list of `relay` URLs in private tags. Private tags are JSON Stringified, NIP-44-encrypted to the signer's keys and placed inside the .content of the event.
Kind `10013` indicates the user's preferred relays to store private events like Draft Wraps.
The event MUST include a list of `relay` URLs in private tags. Private tags are JSON Stringified, [NIP44-encrypted](44.md) to the signer's keys and placed inside the .content of the event.
```js
{
"kind": 10013,
"tags": [],
"content": nip44Encrypt(JSON.stringify([
["relay", "wss://myrelay.mydomain.com"]
]))
"content": nip44Encrypt(
JSON.stringify(
[
["relay", "wss://myrelay.mydomain.com"]
]
)
)
//...other fields
}
```
Relays listed in this event SHOULD be authed and only allow downloads to events signed by the authed user.
It's recommended that Private Storage relays SHOULD be [NIP-42](42.md)-authed and only allow downloads of events signed by the authed user.
Clients SHOULD publish kind `10013` events to the author's [NIP-65](65.md) `write` relays.
Clients MUST publish kind `10013` events to the author's [NIP-65](65.md) `write` relays.

22
45.md
View File

@@ -14,17 +14,17 @@ Some queries a client may want to execute against connected relays are prohibiti
## Filters and return values
This NIP defines the verb `COUNT`, which accepts a subscription id and filters as specified in [NIP 01](01.md) for the verb `REQ`. Multiple filters are OR'd together and aggregated into a single count result.
This NIP defines the verb `COUNT`, which accepts a query id and filters as specified in [NIP 01](01.md) for the verb `REQ`. Multiple filters are OR'd together and aggregated into a single count result.
```
["COUNT", <subscription_id>, <filters JSON>...]
["COUNT", <query_id>, <filters JSON>...]
```
Counts are returned using a `COUNT` response in the form `{"count": <integer>}`. Relays may use probabilistic counts to reduce compute requirements.
In case a relay uses probabilistic counts, it MAY indicate it in the response with `approximate` key i.e. `{"count": <integer>, "approximate": <true|false>}`.
```
["COUNT", <subscription_id>, {"count": <integer>}]
["COUNT", <query_id>, {"count": <integer>}]
```
Whenever the relay decides to refuse to fulfill the `COUNT` request, it MUST return a `CLOSED` message.
@@ -34,27 +34,27 @@ Whenever the relay decides to refuse to fulfill the `COUNT` request, it MUST ret
### Followers count
```
["COUNT", <subscription_id>, {"kinds": [3], "#p": [<pubkey>]}]
["COUNT", <subscription_id>, {"count": 238}]
["COUNT", <query_id>, {"kinds": [3], "#p": [<pubkey>]}]
["COUNT", <query_id>, {"count": 238}]
```
### Count posts and reactions
```
["COUNT", <subscription_id>, {"kinds": [1, 7], "authors": [<pubkey>]}]
["COUNT", <subscription_id>, {"count": 5}]
["COUNT", <query_id>, {"kinds": [1, 7], "authors": [<pubkey>]}]
["COUNT", <query_id>, {"count": 5}]
```
### Count posts approximately
```
["COUNT", <subscription_id>, {"kinds": [1]}]
["COUNT", <subscription_id>, {"count": 93412452, "approximate": true}]
["COUNT", <query_id>, {"kinds": [1]}]
["COUNT", <query_id>, {"count": 93412452, "approximate": true}]
```
### Relay refuses to count
```
["COUNT", <subscription_id>, {"kinds": [4], "authors": [<pubkey>], "#p": [<pubkey>]}]
["CLOSED", <subscription_id>, "auth-required: cannot count other people's DMs"]
["COUNT", <query_id>, {"kinds": [1059], "#p": [<pubkey>]}]
["CLOSED", <query_id>, "auth-required: cannot count other people's DMs"]
```

4
55.md
View File

@@ -295,6 +295,8 @@ For the other types Signer Application returns the column "result"
If the user chose to always reject the event, signer application will return the column "rejected" and you should not open signer application
Clients SHOULD save the user pubkey locally and avoid calling the `get_public_key` after the user is logged in to the Client
#### Methods
- **get_public_key**
@@ -303,7 +305,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.GET_PUBLIC_KEY"),
listOf("login"),
listOf(hex_pub_key),
null,
null,
null

3
59.md
View File

@@ -97,6 +97,9 @@ To protect recipient metadata, relays SHOULD only serve `kind 1059` events inten
When possible, clients should only send wrapped events to `read` relays for the recipient that implement
AUTH, and refuse to serve wrapped events to non-recipients.
When adding expiration tags to both `seal` and `gift wrap` layers, implementations SHOULD use independent random timestamps for each layer. Using different `created_at` values increases timing variance and helps protect against metadata correlation attacks.
## An Example
Let's send a wrapped `kind 1` message between two parties asking "Are you going to the party tonight?"

2
66.md
View File

@@ -53,7 +53,7 @@ Example:
["g", "ww8p1r4t8"],
["l", "en", "ISO-639-1"],
["t", "nsfw" ],
["rtt-open", 234 ]
["rtt-open", "234" ]
]
}
```

12
71.md
View File

@@ -26,6 +26,11 @@ The primary source of video information is the `imeta` tags which is defined in
Each `imeta` tag can be used to specify a variant of the video by the `dim` & `m` properties.
This NIP defines the following additional `imeta` properties aside form those listen in [NIP-92](92.md) & [NIP-94](94.md):
* `duration` (recommended) the duration of the video/audio in seconds (floating point number)
* `bitrate` (recommended) the average bitrate of the video/audio in bits/sec
Example:
```json
[
@@ -39,6 +44,8 @@ Example:
"fallback https://myotherserver.com/1080/12345.mp4",
"fallback https://andanotherserver.com/1080/12345.mp4",
"service nip96",
"bitrate 3000000",
"duration 29.223"
],
["imeta",
"dim 1280x720",
@@ -50,6 +57,8 @@ Example:
"fallback https://myotherserver.com/720/12345.mp4",
"fallback https://andanotherserver.com/720/12345.mp4",
"service nip96",
"bitrate 2000000",
"duration 29.24"
],
["imeta",
"dim 1280x720",
@@ -61,6 +70,7 @@ Example:
"fallback https://myotherserver.com/720/12345.m3u8",
"fallback https://andanotherserver.com/720/12345.m3u8",
"service nip96",
"duration 29.21"
],
]
```
@@ -74,7 +84,6 @@ Additionally `service nip96` may be included to allow clients to search the auth
### 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
* `duration` (optional) video duration in seconds
* `text-track` (optional, repeated) link to WebVTT file for video, type of supplementary information (captions/subtitles/chapters/metadata), optional language code
* `content-warning` (optional) warning about content of NSFW video
* `alt` (optional) description for accessibility
@@ -108,7 +117,6 @@ Additionally `service nip96` may be included to allow clients to search the auth
"service nip96",
],
["duration", "<duration of video in seconds>"],
["text-track", "<encoded `kind 6000` event>", "<recommended relay urls>"],
["content-warning", "<reason>"],
["segment", <start>, <end>, "<title>", "<thumbnail URL>"],

View File

@@ -160,6 +160,8 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
| `1311` | Live Chat Message | [53](53.md) |
| `1337` | Code Snippet | [C0](C0.md) |
| `1617` | Patches | [34](34.md) |
| `1618` | Pull Requests | [34](34.md) |
| `1619` | Pull Request Updates | [34](34.md) |
| `1621` | Issues | [34](34.md) |
| `1622` | Git Replies (deprecated) | [34](34.md) |
| `1630`-`1633` | Status | [34](34.md) |
@@ -317,6 +319,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
| ----------------- | ------------------------------------ | ------------------------------- | -------------------------------------------------- |
| `a` | coordinates to an event | relay URL | [01](01.md) |
| `A` | root address | relay URL | [22](22.md) |
| `c` | commit id | | [34](34.md) |
| `d` | identifier | -- | [01](01.md) |
| `e` | event id (hex) | relay URL, marker, pubkey (hex) | [01](01.md), [10](10.md) |
| `E` | root event id | relay URL | [22](22.md) |
@@ -345,6 +348,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
| `alt` | summary | -- | [31](31.md) |
| `amount` | millisatoshis, stringified | -- | [57](57.md) |
| `bolt11` | `bolt11` invoice | -- | [57](57.md) |
| `branch-name` | branch name suggestion | -- | [34](34.md) |
| `challenge` | challenge string | -- | [42](42.md) |
| `client` | name, address | relay URL | [89](89.md) |
| `clone` | git clone URL | -- | [34](34.md) |
@@ -358,6 +362,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
| `expiration` | unix timestamp (string) | -- | [40](40.md) |
| `file` | full path (string) | -- | [35](35.md) |
| `goal` | event id (hex) | relay URL | [75](75.md) |
| `merge-base` | commit id | | [34](34.md) |
| `HEAD` | `ref: refs/heads/<branch-name>` | | [34](34.md) |
| `image` | image URL | dimensions in pixels | [23](23.md), [52](52.md), [58](58.md) |
| `imeta` | inline metadata | -- | [92](92.md) |