mirror of
https://github.com/nostr-protocol/nips.git
synced 2025-12-12 10:08:49 +00:00
Compare commits
1 Commits
cc77619af8
...
djot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
784c88e45b |
2
17.md
2
17.md
@@ -145,7 +145,7 @@ Kind `10050` indicates the user's preferred relays to receive DMs. The event MUS
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
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 recipient’s 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.
|
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.
|
||||||
|
|
||||||
## Relays
|
## Relays
|
||||||
|
|
||||||
|
|||||||
16
18.md
16
18.md
@@ -21,12 +21,18 @@ reposted.
|
|||||||
|
|
||||||
## Quote Reposts
|
## Quote Reposts
|
||||||
|
|
||||||
Mentions to [NIP-21](21.md) entities like `nevent`, `note` and `naddr` on any
|
Quote reposts are `kind 1` events with an embedded `q` tag of the note being
|
||||||
event must be converted into `q` tags. The `q` tag ensures quote reposts are
|
quote reposted. The `q` tag ensures quote reposts are not pulled and included
|
||||||
not pulled and included as replies in threads. It also allows you to easily
|
as replies in threads. It also allows you to easily pull and count all of the
|
||||||
pull and count all of the quotes for a post. The syntax follows
|
quotes for a post.
|
||||||
|
|
||||||
`["q", "<event-id> or <event-address>", "<relay-url>", "<pubkey-if-a-regular-event>"]`
|
`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.
|
||||||
|
|
||||||
## Generic Reposts
|
## Generic Reposts
|
||||||
|
|
||||||
|
|||||||
92
34.md
92
34.md
@@ -10,7 +10,7 @@ This NIP defines all the ways code collaboration using and adjacent to [`git`](h
|
|||||||
|
|
||||||
## Repository announcements
|
## Repository announcements
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
```jsonc
|
```jsonc
|
||||||
{
|
{
|
||||||
@@ -25,7 +25,6 @@ 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
|
["relays", "<relay-url>", ...], // relays that this repository will monitor for patches and issues
|
||||||
["r", "<earliest-unique-commit-id>", "euc"],
|
["r", "<earliest-unique-commit-id>", "euc"],
|
||||||
["maintainers", "<other-recognized-maintainer>", ...],
|
["maintainers", "<other-recognized-maintainer>", ...],
|
||||||
["t","personal-fork"], // optionally indicate author isn't a maintainer
|
|
||||||
["t", "<arbitrary string>"], // hashtags labelling the repository
|
["t", "<arbitrary string>"], // hashtags labelling the repository
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -67,13 +66,9 @@ The `refs` tag can be optionally extended to enable clients to identify how many
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Patches and Pull Requests (PRs)
|
## Patches
|
||||||
|
|
||||||
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 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 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.
|
Patches in a patch set SHOULD include a [NIP-10](10.md) `e` `reply` tag pointing to the previous patch.
|
||||||
|
|
||||||
@@ -108,66 +103,9 @@ 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`.
|
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
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
@@ -187,11 +125,11 @@ Issues may have a `subject` tag, which clients can utilize to display a header.
|
|||||||
|
|
||||||
## Replies
|
## Replies
|
||||||
|
|
||||||
Replies to either a `kind:1621` (_issue_), `kind:1617` (_patch_) or `kind:1618` (_pull request_) event should follow [NIP-22 comment](22.md).
|
Replies to either a `kind:1621` (_issue_) or a `kind:1617` (_patch_) event should follow [NIP-22 comment](22.md).
|
||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
Root Patches, PRs and Issues have a Status that defaults to 'Open' and can be set by issuing Status events.
|
Root Patches and Issues have a Status that defaults to 'Open' and can be set by issuing Status events.
|
||||||
|
|
||||||
```jsonc
|
```jsonc
|
||||||
{
|
{
|
||||||
@@ -201,7 +139,7 @@ Root Patches, PRs and Issues have a Status that defaults to 'Open' and can be se
|
|||||||
"kind": 1633, // Draft
|
"kind": 1633, // Draft
|
||||||
"content": "<markdown text>",
|
"content": "<markdown text>",
|
||||||
"tags": [
|
"tags": [
|
||||||
["e", "<issue-or-PR-or-original-root-patch-id-hex>", "", "root"],
|
["e", "<issue-or-original-root-patch-id-hex>", "", "root"],
|
||||||
["e", "<accepted-revision-root-id-hex>", "", "reply"], // for when revisions applied
|
["e", "<accepted-revision-root-id-hex>", "", "reply"], // for when revisions applied
|
||||||
["p", "<repository-owner>"],
|
["p", "<repository-owner>"],
|
||||||
["p", "<root-event-author>"],
|
["p", "<root-event-author>"],
|
||||||
@@ -227,22 +165,8 @@ 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.
|
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
|
## 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)
|
- inline file comments kind (we probably need one for patches and a different one for merged files)
|
||||||
|
|||||||
39
37.md
39
37.md
@@ -1,57 +1,50 @@
|
|||||||
NIP-37
|
NIP-37
|
||||||
======
|
======
|
||||||
|
|
||||||
Draft Wraps
|
Draft Events
|
||||||
-----------
|
------------
|
||||||
|
|
||||||
`draft` `optional`
|
`draft` `optional`
|
||||||
|
|
||||||
This NIP defines kind `31234` as an encrypted storage for unsigned draft events of any other kind.
|
This NIP defines kind `31234` as a private wrap for drafts of any other event kind.
|
||||||
|
|
||||||
The draft is JSON-stringified, [NIP44-encrypted](44.md) to the signer's public key and placed inside the `.content`.
|
The draft event is JSON-stringified, [NIP44-encrypted](44.md) to the signer's public key and placed inside the `.content` of the event.
|
||||||
|
|
||||||
`k` tags identify the kind of the draft.
|
An additional `k` tag identifies the kind of the draft event.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
{
|
{
|
||||||
"kind": 31234,
|
"kind": 31234,
|
||||||
"tags": [
|
"tags": [
|
||||||
["d", "<identifier>"],
|
["d", "<identifier>"],
|
||||||
["k", "<kind of the draft event>"], // required
|
["k", "<kind of the draft event>"],
|
||||||
["expiration", "now + 90 days"] // recommended
|
["e", "<anchor event event id>", "<relay-url>"],
|
||||||
|
["a", "<anchor event address>", "<relay-url>"],
|
||||||
],
|
],
|
||||||
"content": nip44Encrypt(JSON.stringify(draft_event)),
|
"content": nip44Encrypt(JSON.stringify(draft_event)),
|
||||||
// other fields
|
// other fields
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
A blanked `.content` field signals that the draft has been deleted.
|
A blanked `.content` means this draft has been deleted by a client but relays still have the event.
|
||||||
|
|
||||||
[NIP-40](40.md) `expiration` tags are recommended.
|
Tags `e` and `a` identify one or more anchor events, such as parent events on replies.
|
||||||
|
|
||||||
Clients SHOULD publish kind `31234` events to relays listed on kind `10013` below.
|
|
||||||
|
|
||||||
## Relay List for Private Content
|
## Relay List for Private Content
|
||||||
|
|
||||||
Kind `10013` indicates the user's preferred relays to store private events like Draft Wraps.
|
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.
|
||||||
|
|
||||||
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
|
```js
|
||||||
{
|
{
|
||||||
"kind": 10013,
|
"kind": 10013,
|
||||||
"tags": [],
|
"tags": [],
|
||||||
"content": nip44Encrypt(
|
"content": nip44Encrypt(JSON.stringify([
|
||||||
JSON.stringify(
|
["relay", "wss://myrelay.mydomain.com"]
|
||||||
[
|
]))
|
||||||
["relay", "wss://myrelay.mydomain.com"]
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
//...other fields
|
//...other fields
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
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.
|
Relays listed in this event SHOULD be authed and only allow downloads to events signed by the authed user.
|
||||||
|
|
||||||
Clients MUST publish kind `10013` events to the author's [NIP-65](65.md) `write` relays.
|
Clients SHOULD publish kind `10013` events to the author's [NIP-65](65.md) `write` relays.
|
||||||
|
|||||||
146
43.md
146
43.md
@@ -1,146 +0,0 @@
|
|||||||
NIP-43
|
|
||||||
======
|
|
||||||
|
|
||||||
Relay Access Metadata and Requests
|
|
||||||
----------------------------------
|
|
||||||
|
|
||||||
`draft` `optional`
|
|
||||||
|
|
||||||
This NIP defines a way for relays to advertise membership lists, and for clients to request admission to relays on behalf of users.
|
|
||||||
|
|
||||||
## Membership Lists
|
|
||||||
|
|
||||||
Relays MAY publish a `kind 13534` event which indicates pubkeys that have access to a given relay. This event MUST be signed by the pubkey specified in the `self` field of the relay's [NIP 11](./11.md) document.
|
|
||||||
|
|
||||||
The following tags are required:
|
|
||||||
|
|
||||||
- A [NIP 70](./70.md) `-` tag
|
|
||||||
- A `member` tag containing a hex pubkey should be included for each member
|
|
||||||
|
|
||||||
This list should not be considered exhaustive or authoritative. To determine membership, both a `kind 13534` event by the relay, and a `kind 10010` event by the member should be consulted.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```jsonc
|
|
||||||
{
|
|
||||||
"kind": 13534,
|
|
||||||
"pubkey": "<nip11.self>",
|
|
||||||
"tags": [
|
|
||||||
["-"],
|
|
||||||
["member", "c308e1f882c1f1dff2a43d4294239ddeec04e575f2d1aad1fa21ea7684e61fb5"],
|
|
||||||
["member", "ee1d336e13779e4d4c527b988429d96de16088f958cbf6c074676ac9cfd9c958"]
|
|
||||||
],
|
|
||||||
// ...other fields
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Add User
|
|
||||||
|
|
||||||
Relays MAY publish a `kind 8000` event when a member is added to the relay. This event MUST be signed by the pubkey specified in the `self` field of the relay's [NIP 11](./11.md) document.
|
|
||||||
|
|
||||||
The following tags are required:
|
|
||||||
|
|
||||||
- A [NIP 70](./70.md) `-` tag
|
|
||||||
- A `p` tag indicating the member's hex pubkey
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```jsonc
|
|
||||||
{
|
|
||||||
"kind": 8000,
|
|
||||||
"pubkey": "<nip11.self>",
|
|
||||||
"tags": [
|
|
||||||
["-"],
|
|
||||||
["p", "c308e1f882c1f1dff2a43d4294239ddeec04e575f2d1aad1fa21ea7684e61fb5"]
|
|
||||||
],
|
|
||||||
// ...other fields
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Remove User
|
|
||||||
|
|
||||||
Relays MAY publish a `kind 8001` event when a member is removed from the relay. This event MUST be signed by the pubkey specified in the `self` field of the relay's [NIP 11](./11.md) document.
|
|
||||||
|
|
||||||
The following tags are required:
|
|
||||||
|
|
||||||
- A [NIP 70](./70.md) `-` tag
|
|
||||||
- A `p` tag indicating the member's hex pubkey
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```jsonc
|
|
||||||
{
|
|
||||||
"kind": 8001,
|
|
||||||
"pubkey": "<nip11.self>",
|
|
||||||
"tags": [
|
|
||||||
["-"],
|
|
||||||
["p", "c308e1f882c1f1dff2a43d4294239ddeec04e575f2d1aad1fa21ea7684e61fb5"]
|
|
||||||
],
|
|
||||||
// ...other fields
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Join Request
|
|
||||||
|
|
||||||
A user MAY send a `kind 28934` to a relay in order to request admission. It MUST have a `claim` tag containing an invite code. The event's `created_at` MUST be now, plus or minus a few minutes.
|
|
||||||
|
|
||||||
```jsonc
|
|
||||||
{
|
|
||||||
"kind": 28934,
|
|
||||||
"pubkey": "<user pubkey>",
|
|
||||||
"tags": [
|
|
||||||
["-"],
|
|
||||||
["claim", "<invite code>"]
|
|
||||||
],
|
|
||||||
// ...other fields
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Upon receiving a claim, a relay MUST notify the client as to what the status of the claim is using an `OK` message. Failed claims SHOULD use the same standard `"restricted: "` prefix specified by NIP 42.
|
|
||||||
|
|
||||||
Relays SHOULD update their `kind 13534` member list and MAY publish a `kind 8000` "add member" event.
|
|
||||||
|
|
||||||
Some examples:
|
|
||||||
|
|
||||||
```
|
|
||||||
["OK", <event-id>, false, "restricted: that invite code is expired."]
|
|
||||||
["OK", <event-id>, false, "restricted: that is an invalid invite code."]
|
|
||||||
["OK", <event-id>, true, "duplicate: you are already a member of this relay."]
|
|
||||||
["OK", <event-id>, true, "info: welcome to wss://relay.bunk.skunk!"]
|
|
||||||
```
|
|
||||||
|
|
||||||
## Invite Request
|
|
||||||
|
|
||||||
Users may request a claim string from a relay by making a request for `kind 28935` events. This event MUST be signed by the pubkey specified in the `self` field of the relay's [NIP 11](./11.md) document.
|
|
||||||
|
|
||||||
```jsonc
|
|
||||||
{
|
|
||||||
"kind": 28935,
|
|
||||||
"pubkey": "<nip11.self>",
|
|
||||||
"tags": [
|
|
||||||
["-"],
|
|
||||||
["claim", "<invite code>"],
|
|
||||||
],
|
|
||||||
// ...other fields
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that these events are in the `ephemeral` range, which means relays must explicitly opt-in to this behavior by generating claims on the fly when requested. This allows relays to improve security by issuing a different claim for each request, only issuing claims to certain users, or expiring claims.
|
|
||||||
|
|
||||||
## Leave Request
|
|
||||||
|
|
||||||
A user MAY send a `kind 28936` to a relay in order to request that their access be revoked. The event's `created_at` MUST be now, plus or minus a few minutes. This event MUST include a [NIP 70](./70.md) `-` tag.
|
|
||||||
|
|
||||||
```jsonc
|
|
||||||
{
|
|
||||||
"kind": 28936,
|
|
||||||
"tags": [["-"]],
|
|
||||||
// ...other fields
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Relays SHOULD update their `kind 13534` member list and MAY publish a `kind 8001` "remove member" event.
|
|
||||||
|
|
||||||
## Implementation
|
|
||||||
|
|
||||||
Clients MUST only request `kind 28935` events from and send `kind 28934` events to relays which include this NIP in the `supported_nips` section of its [NIP 11](./11.md) relay information document.
|
|
||||||
22
45.md
22
45.md
@@ -14,17 +14,17 @@ Some queries a client may want to execute against connected relays are prohibiti
|
|||||||
|
|
||||||
## Filters and return values
|
## Filters and return values
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
```
|
```
|
||||||
["COUNT", <query_id>, <filters JSON>...]
|
["COUNT", <subscription_id>, <filters JSON>...]
|
||||||
```
|
```
|
||||||
|
|
||||||
Counts are returned using a `COUNT` response in the form `{"count": <integer>}`. Relays may use probabilistic counts to reduce compute requirements.
|
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>}`.
|
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", <query_id>, {"count": <integer>}]
|
["COUNT", <subscription_id>, {"count": <integer>}]
|
||||||
```
|
```
|
||||||
|
|
||||||
Whenever the relay decides to refuse to fulfill the `COUNT` request, it MUST return a `CLOSED` message.
|
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
|
### Followers count
|
||||||
|
|
||||||
```
|
```
|
||||||
["COUNT", <query_id>, {"kinds": [3], "#p": [<pubkey>]}]
|
["COUNT", <subscription_id>, {"kinds": [3], "#p": [<pubkey>]}]
|
||||||
["COUNT", <query_id>, {"count": 238}]
|
["COUNT", <subscription_id>, {"count": 238}]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Count posts and reactions
|
### Count posts and reactions
|
||||||
|
|
||||||
```
|
```
|
||||||
["COUNT", <query_id>, {"kinds": [1, 7], "authors": [<pubkey>]}]
|
["COUNT", <subscription_id>, {"kinds": [1, 7], "authors": [<pubkey>]}]
|
||||||
["COUNT", <query_id>, {"count": 5}]
|
["COUNT", <subscription_id>, {"count": 5}]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Count posts approximately
|
### Count posts approximately
|
||||||
|
|
||||||
```
|
```
|
||||||
["COUNT", <query_id>, {"kinds": [1]}]
|
["COUNT", <subscription_id>, {"kinds": [1]}]
|
||||||
["COUNT", <query_id>, {"count": 93412452, "approximate": true}]
|
["COUNT", <subscription_id>, {"count": 93412452, "approximate": true}]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Relay refuses to count
|
### Relay refuses to count
|
||||||
|
|
||||||
```
|
```
|
||||||
["COUNT", <query_id>, {"kinds": [1059], "#p": [<pubkey>]}]
|
["COUNT", <subscription_id>, {"kinds": [4], "authors": [<pubkey>], "#p": [<pubkey>]}]
|
||||||
["CLOSED", <query_id>, "auth-required: cannot count other people's DMs"]
|
["CLOSED", <subscription_id>, "auth-required: cannot count other people's DMs"]
|
||||||
```
|
```
|
||||||
|
|||||||
22
54.md
22
54.md
@@ -28,16 +28,18 @@ Articles are identified by lowercase, normalized ascii `d` tags.
|
|||||||
|
|
||||||
## Content
|
## Content
|
||||||
|
|
||||||
The `content` should be Asciidoc with two extra functionalities: **wikilinks** and **nostr:...** links.
|
The `content` should be [Djot](https://djot.net/) with two special functionalities:
|
||||||
|
|
||||||
Unlike normal Asciidoc links `http://example.com[]` that link to external webpages, wikilinks `[[]]` link to other articles in the wiki. In this case, the wiki is the entirety of Nostr. Clicking on a wikilink should cause the client to ask relays for events with `d` tags equal to the target of that wikilink.
|
1. Links can have target URIs in NIP-21 format, like `[bob](nostr:npub1bob4npub4here4qwxek)`.
|
||||||
|
2. When a reference can't be found for a "Reference"-style link should link to the wiki article with that name instead, like a "wikilink". For example:
|
||||||
|
|
||||||
Wikilinks can take these two forms:
|
> a tree is a [vegetable][] that grows big.
|
||||||
|
>
|
||||||
|
> trees are often [green][green color], but they can also be [red][red color] as [bob][] says.
|
||||||
|
>
|
||||||
|
> [bob]: nostr:npub1bob4npub4here4qwxek
|
||||||
|
|
||||||
1. `[[Target Page]]` -- in this case it will link to the page `target-page` (according to `d` tag normalization rules above) and be displayed as `Target Page`;
|
In the article above, "vegetable" will link to the wiki article **"vegetable"** (with a `d` tag set to `"vegetable"`), "green" will link to the article **green color** (with `d` set to `"green-color"`), same for "red". But "bob" will link to the specified npub as in the reference.
|
||||||
2. `[[target page|see this]]` -- in this case it will link to the page `target-page`, but will be displayed as `see this`.
|
|
||||||
|
|
||||||
`nostr:...` links, as per [NIP-21](21.md), should link to profiles or arbitrary Nostr events. Although it is not recommended to link to specific versions of articles -- instead the _wikilink_ syntax should be preferred, since it should be left to the reader and their client to decide what version of any given article they want to read.
|
|
||||||
|
|
||||||
## Optional extra tags
|
## Optional extra tags
|
||||||
|
|
||||||
@@ -87,11 +89,11 @@ This is a stronger signal of trust than a `+` reaction.
|
|||||||
|
|
||||||
This marker is useful when a user edits someone else's entry; if the original author includes the editor's changes and the editor doesn't want to keep/maintain an independent version, the `link` tag could effectively be a considered a "deletion" of the editor's version and putting that pubkey's WoT weight behind the original author's version.
|
This marker is useful when a user edits someone else's entry; if the original author includes the editor's changes and the editor doesn't want to keep/maintain an independent version, the `link` tag could effectively be a considered a "deletion" of the editor's version and putting that pubkey's WoT weight behind the original author's version.
|
||||||
|
|
||||||
## Why Asciidoc?
|
## Why Djot?
|
||||||
|
|
||||||
Wikitext is [garbage](nostr:nevent1qqsqt0gcggry60n72uglhuhypdlmr2dm6swjj69jex5v530gcpazlzsprpmhxue69uhhyetvv9ujumn0wdmksetjv5hxxmmdqy28wumn8ghj7un9d3shjtnyv9kh2uewd9hsygpm7rrrljungc6q0tuh5hj7ue863q73qlheu4vywtzwhx42a7j9n5ueneex) and Markdown is not powerful enough (besides being too freeform and unspecified and prone to generate incompatibilities in the future).
|
Wikitext is unimplementable. Markdown and Asciidoc do not have strict specs. In Markdown every implementation has its own set of special functionalities that would cause conflict and protocol bloat, also it lacks standardized features that are good to have on encyclopaedias: subscript, superscript, description lists, math, comments and custom labeled blocks. Asciidoc, on the other hand, has all features under the sun, but its spec is so huge no one has ever implemented it, not even in JavaScript (the canonical JavaScript library that most people use is transpiled from the original in Ruby).
|
||||||
|
|
||||||
Asciidoc has a strict spec, multiple implementations in many languages, and support for features that are very much necessary in a wiki article, like _sidebars_, _tables_ (with rich markup inside cells), many levels of _headings_, _footnotes_, _superscript_ and _subscript_ markup and _description lists_. It is also arguably easier to read in its plaintext format than Markdown (and certainly much better than Wikitext).
|
Djot is a much faster parser, made by John MacFarlane (the guy behind Pandoc) with years of experience and lessons learned behind him. The spec is well-defined and simple, and has all the features listed above, while also being basically the same as the most basic Markdown.
|
||||||
|
|
||||||
## Appendix 1: Merge requests
|
## Appendix 1: Merge requests
|
||||||
Users can request other users to get their entries merged into someone else's entry by creating a `kind:818` event.
|
Users can request other users to get their entries merged into someone else's entry by creating a `kind:818` event.
|
||||||
|
|||||||
4
55.md
4
55.md
@@ -295,8 +295,6 @@ 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
|
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
|
#### Methods
|
||||||
|
|
||||||
- **get_public_key**
|
- **get_public_key**
|
||||||
@@ -305,7 +303,7 @@ Clients SHOULD save the user pubkey locally and avoid calling the `get_public_ke
|
|||||||
```kotlin
|
```kotlin
|
||||||
val result = context.contentResolver.query(
|
val result = context.contentResolver.query(
|
||||||
Uri.parse("content://com.example.signer.GET_PUBLIC_KEY"),
|
Uri.parse("content://com.example.signer.GET_PUBLIC_KEY"),
|
||||||
listOf(hex_pub_key),
|
listOf("login"),
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null
|
null
|
||||||
|
|||||||
3
59.md
3
59.md
@@ -97,9 +97,6 @@ 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
|
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.
|
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
|
## An Example
|
||||||
|
|
||||||
Let's send a wrapped `kind 1` message between two parties asking "Are you going to the party tonight?"
|
Let's send a wrapped `kind 1` message between two parties asking "Are you going to the party tonight?"
|
||||||
|
|||||||
14
60.md
14
60.md
@@ -22,7 +22,7 @@ This NIP doesn't deal with users' *receiving* money from someone else, it's just
|
|||||||
3. A user has `kind:7376` events that represent the spending history of the wallet -- This history is for informational purposes only and is completely optional.
|
3. A user has `kind:7376` events that represent the spending history of the wallet -- This history is for informational purposes only and is completely optional.
|
||||||
|
|
||||||
### Wallet Event
|
### Wallet Event
|
||||||
```javascript
|
```jsonc
|
||||||
{
|
{
|
||||||
"kind": 17375,
|
"kind": 17375,
|
||||||
"content": nip44_encrypt([
|
"content": nip44_encrypt([
|
||||||
@@ -45,7 +45,7 @@ Token events are used to record unspent proofs.
|
|||||||
|
|
||||||
There can be multiple `kind:7375` events for the same mint, and multiple proofs inside each `kind:7375` event.
|
There can be multiple `kind:7375` events for the same mint, and multiple proofs inside each `kind:7375` event.
|
||||||
|
|
||||||
```javascript
|
```jsonc
|
||||||
{
|
{
|
||||||
"kind": 7375,
|
"kind": 7375,
|
||||||
"content": nip44_encrypt({
|
"content": nip44_encrypt({
|
||||||
@@ -78,7 +78,7 @@ The `kind:5` _delete event_ created in the [NIP-09](09.md) process MUST have a t
|
|||||||
### Spending History Event
|
### Spending History Event
|
||||||
Clients SHOULD publish `kind:7376` events to create a transaction history when their balance changes.
|
Clients SHOULD publish `kind:7376` events to create a transaction history when their balance changes.
|
||||||
|
|
||||||
```javascript
|
```jsonc
|
||||||
{
|
{
|
||||||
"kind": 7376,
|
"kind": 7376,
|
||||||
"content": nip44_encrypt([
|
"content": nip44_encrypt([
|
||||||
@@ -115,7 +115,7 @@ From those relays, the client should fetch wallet and token events.
|
|||||||
|
|
||||||
### Spending token
|
### Spending token
|
||||||
If Alice spends 4 sats from this token event
|
If Alice spends 4 sats from this token event
|
||||||
```javascript
|
```jsonc
|
||||||
{
|
{
|
||||||
"kind": 7375,
|
"kind": 7375,
|
||||||
"id": "event-id-1",
|
"id": "event-id-1",
|
||||||
@@ -134,7 +134,7 @@ If Alice spends 4 sats from this token event
|
|||||||
|
|
||||||
Her client:
|
Her client:
|
||||||
* MUST roll over the unspent proofs:
|
* MUST roll over the unspent proofs:
|
||||||
```javascript
|
```jsonc
|
||||||
{
|
{
|
||||||
"kind": 7375,
|
"kind": 7375,
|
||||||
"id": "event-id-2",
|
"id": "event-id-2",
|
||||||
@@ -153,7 +153,7 @@ Her client:
|
|||||||
* MUST delete event `event-id-1`
|
* MUST delete event `event-id-1`
|
||||||
* SHOULD add the `event-id-1` to the `del` array of deleted token-ids.
|
* SHOULD add the `event-id-1` to the `del` array of deleted token-ids.
|
||||||
* SHOULD create a `kind:7376` event to record the spend
|
* SHOULD create a `kind:7376` event to record the spend
|
||||||
```javascript
|
```jsonc
|
||||||
{
|
{
|
||||||
"kind": 7376,
|
"kind": 7376,
|
||||||
"content": nip44_encrypt([
|
"content": nip44_encrypt([
|
||||||
@@ -171,7 +171,7 @@ When creating a quote at a mint, an event can be used to keep the state of the q
|
|||||||
|
|
||||||
However, application developers SHOULD use local state when possible and only publish this event when it makes sense in the context of their application.
|
However, application developers SHOULD use local state when possible and only publish this event when it makes sense in the context of their application.
|
||||||
|
|
||||||
```javascript
|
```jsonc
|
||||||
{
|
{
|
||||||
"kind": 7374,
|
"kind": 7374,
|
||||||
"content": nip44_encrypt("quote-id"),
|
"content": nip44_encrypt("quote-id"),
|
||||||
|
|||||||
2
66.md
2
66.md
@@ -53,7 +53,7 @@ Example:
|
|||||||
["g", "ww8p1r4t8"],
|
["g", "ww8p1r4t8"],
|
||||||
["l", "en", "ISO-639-1"],
|
["l", "en", "ISO-639-1"],
|
||||||
["t", "nsfw" ],
|
["t", "nsfw" ],
|
||||||
["rtt-open", "234" ]
|
["rtt-open", 234 ]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
12
71.md
12
71.md
@@ -26,11 +26,6 @@ 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.
|
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:
|
Example:
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
@@ -44,8 +39,6 @@ Example:
|
|||||||
"fallback https://myotherserver.com/1080/12345.mp4",
|
"fallback https://myotherserver.com/1080/12345.mp4",
|
||||||
"fallback https://andanotherserver.com/1080/12345.mp4",
|
"fallback https://andanotherserver.com/1080/12345.mp4",
|
||||||
"service nip96",
|
"service nip96",
|
||||||
"bitrate 3000000",
|
|
||||||
"duration 29.223"
|
|
||||||
],
|
],
|
||||||
["imeta",
|
["imeta",
|
||||||
"dim 1280x720",
|
"dim 1280x720",
|
||||||
@@ -57,8 +50,6 @@ Example:
|
|||||||
"fallback https://myotherserver.com/720/12345.mp4",
|
"fallback https://myotherserver.com/720/12345.mp4",
|
||||||
"fallback https://andanotherserver.com/720/12345.mp4",
|
"fallback https://andanotherserver.com/720/12345.mp4",
|
||||||
"service nip96",
|
"service nip96",
|
||||||
"bitrate 2000000",
|
|
||||||
"duration 29.24"
|
|
||||||
],
|
],
|
||||||
["imeta",
|
["imeta",
|
||||||
"dim 1280x720",
|
"dim 1280x720",
|
||||||
@@ -70,7 +61,6 @@ Example:
|
|||||||
"fallback https://myotherserver.com/720/12345.m3u8",
|
"fallback https://myotherserver.com/720/12345.m3u8",
|
||||||
"fallback https://andanotherserver.com/720/12345.m3u8",
|
"fallback https://andanotherserver.com/720/12345.m3u8",
|
||||||
"service nip96",
|
"service nip96",
|
||||||
"duration 29.21"
|
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
@@ -84,6 +74,7 @@ Additionally `service nip96` may be included to allow clients to search the auth
|
|||||||
### Other tags:
|
### Other tags:
|
||||||
* `title` (required) title of the video
|
* `title` (required) title of the video
|
||||||
* `published_at`, for the timestamp in unix seconds (stringified) of the first time the video was published
|
* `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
|
* `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
|
* `content-warning` (optional) warning about content of NSFW video
|
||||||
* `alt` (optional) description for accessibility
|
* `alt` (optional) description for accessibility
|
||||||
@@ -117,6 +108,7 @@ Additionally `service nip96` may be included to allow clients to search the auth
|
|||||||
"service nip96",
|
"service nip96",
|
||||||
],
|
],
|
||||||
|
|
||||||
|
["duration", "<duration of video in seconds>"],
|
||||||
["text-track", "<encoded `kind 6000` event>", "<recommended relay urls>"],
|
["text-track", "<encoded `kind 6000` event>", "<recommended relay urls>"],
|
||||||
["content-warning", "<reason>"],
|
["content-warning", "<reason>"],
|
||||||
["segment", <start>, <end>, "<title>", "<thumbnail URL>"],
|
["segment", <start>, <end>, "<title>", "<thumbnail URL>"],
|
||||||
|
|||||||
@@ -160,8 +160,6 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
|
|||||||
| `1311` | Live Chat Message | [53](53.md) |
|
| `1311` | Live Chat Message | [53](53.md) |
|
||||||
| `1337` | Code Snippet | [C0](C0.md) |
|
| `1337` | Code Snippet | [C0](C0.md) |
|
||||||
| `1617` | Patches | [34](34.md) |
|
| `1617` | Patches | [34](34.md) |
|
||||||
| `1618` | Pull Requests | [34](34.md) |
|
|
||||||
| `1619` | Pull Request Updates | [34](34.md) |
|
|
||||||
| `1621` | Issues | [34](34.md) |
|
| `1621` | Issues | [34](34.md) |
|
||||||
| `1622` | Git Replies (deprecated) | [34](34.md) |
|
| `1622` | Git Replies (deprecated) | [34](34.md) |
|
||||||
| `1630`-`1633` | Status | [34](34.md) |
|
| `1630`-`1633` | Status | [34](34.md) |
|
||||||
@@ -319,7 +317,6 @@ 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` | coordinates to an event | relay URL | [01](01.md) |
|
||||||
| `A` | root address | relay URL | [22](22.md) |
|
| `A` | root address | relay URL | [22](22.md) |
|
||||||
| `c` | commit id | | [34](34.md) |
|
|
||||||
| `d` | identifier | -- | [01](01.md) |
|
| `d` | identifier | -- | [01](01.md) |
|
||||||
| `e` | event id (hex) | relay URL, marker, pubkey (hex) | [01](01.md), [10](10.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) |
|
| `E` | root event id | relay URL | [22](22.md) |
|
||||||
@@ -348,7 +345,6 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
|
|||||||
| `alt` | summary | -- | [31](31.md) |
|
| `alt` | summary | -- | [31](31.md) |
|
||||||
| `amount` | millisatoshis, stringified | -- | [57](57.md) |
|
| `amount` | millisatoshis, stringified | -- | [57](57.md) |
|
||||||
| `bolt11` | `bolt11` invoice | -- | [57](57.md) |
|
| `bolt11` | `bolt11` invoice | -- | [57](57.md) |
|
||||||
| `branch-name` | branch name suggestion | -- | [34](34.md) |
|
|
||||||
| `challenge` | challenge string | -- | [42](42.md) |
|
| `challenge` | challenge string | -- | [42](42.md) |
|
||||||
| `client` | name, address | relay URL | [89](89.md) |
|
| `client` | name, address | relay URL | [89](89.md) |
|
||||||
| `clone` | git clone URL | -- | [34](34.md) |
|
| `clone` | git clone URL | -- | [34](34.md) |
|
||||||
@@ -362,7 +358,6 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
|
|||||||
| `expiration` | unix timestamp (string) | -- | [40](40.md) |
|
| `expiration` | unix timestamp (string) | -- | [40](40.md) |
|
||||||
| `file` | full path (string) | -- | [35](35.md) |
|
| `file` | full path (string) | -- | [35](35.md) |
|
||||||
| `goal` | event id (hex) | relay URL | [75](75.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) |
|
| `HEAD` | `ref: refs/heads/<branch-name>` | | [34](34.md) |
|
||||||
| `image` | image URL | dimensions in pixels | [23](23.md), [52](52.md), [58](58.md) |
|
| `image` | image URL | dimensions in pixels | [23](23.md), [52](52.md), [58](58.md) |
|
||||||
| `imeta` | inline metadata | -- | [92](92.md) |
|
| `imeta` | inline metadata | -- | [92](92.md) |
|
||||||
|
|||||||
Reference in New Issue
Block a user