Compare commits

...

21 Commits

Author SHA1 Message Date
hodlbod b9b262e037
Merge 4e78007e6b into 7dec812f99 2025-08-12 14:16:09 +02:00
Awiteb 7dec812f99
nip22: fix example type for external URL (#2011) 2025-08-11 17:26:05 -04:00
Yoji Shidara 739f3c5263
NIP-24: Fix heading levels (#2009) 2025-08-11 19:37:53 +09:00
Yoji Shidara 8830525250
NIP-21: Fix markup issue by closing backtick (#2008) 2025-08-11 19:35:36 +09:00
fiatjaf_ b224b0ecb8
include missing "k" tag in some reactions (#2001) 2025-08-04 17:31:37 -03:00
G!l ce130e504a
NIP-52: Add collaborative calendar event request (#1970) 2025-08-04 20:28:18 +00:00
hodlbod 0b45265a93
Clean up nip 66 (#1986)
Co-authored-by: Jon Staab <shtaab@gmail.com>
2025-08-04 15:47:20 +00:00
hodlbod e33f5cd38f
Add geocaching kinds (#1977)
Co-authored-by: Jon Staab <shtaab@gmail.com>
2025-08-01 19:39:33 +00:00
Adithya Vardhan 0595d438aa
NIP-47: add state to transactions (#1933) 2025-07-31 09:26:27 -04:00
Jeremy Klein f30a43bd37
[NWC] Add an encryption tag to negotiate upgrading to NIP44. (#1780)
Co-authored-by: Roland <33993199+rolznz@users.noreply.github.com>
2025-07-31 09:21:18 -04:00
DanConwayDev faba3f016d
NIP-34: `mention` marker ~> `q` tag NIP-10 update (#1998) 2025-07-31 08:43:14 -04:00
AsaiToshiya e6de76f76b
remove duplicate kind (#1995) 2025-07-29 15:28:29 -03:00
reis aefad1876b
nip25: remove duplicate (#1993) 2025-07-29 08:42:47 -03:00
Fabian 4984b057c2
Update audio format and waveform recommendation for NIP-A0: Voice Messages (#1990) 2025-07-27 16:23:50 -03:00
AsaiToshiya 9be455bf57
fix A0 nip number 2025-07-24 23:04:12 +09:00
Fabian e50f37a527
NIP-A0: Voice Messages (#1984) 2025-07-23 17:31:55 -03:00
AsaiToshiya 074b8eeb01
add kinds 10312, 30312 and 30313 (from nip53) 2025-07-19 01:17:44 +09:00
benthecarman 1afb6da049
NIP-87: Ecash Mint Discoverability (#1110)
Co-authored-by: Pablo Fernandez <pfer@me.com>
2025-07-16 12:13:09 +01:00
Giovanni d306f6b3f8
add peach bitcoin nip-69 implementation (#1961) 2025-07-12 18:04:35 +01:00
Alex Gleason 82fffa0580
NIP-72: use kind 1111 events for text notes (#1953) 2025-07-11 00:58:51 -04:00
Jonathan Staab 4e78007e6b Add NIP 43 for joining relays using a claim 2024-10-16 10:43:45 -07:00
18 changed files with 519 additions and 239 deletions

4
03.md
View File

@ -12,8 +12,8 @@ This NIP defines an event with `kind:1040` that can contain an [OpenTimestamps](
{ {
"kind": 1040 "kind": 1040
"tags": [ "tags": [
["e", <event-id>, <relay-url>], ["e", <target-event-id>, <relay-url>],
["alt", "opentimestamps attestation"] ["k", "<target-event-kind>"]
], ],
"content": <base64-encoded OTS file data> "content": <base64-encoded OTS file data>
} }

3
18.md
View File

@ -40,6 +40,5 @@ Since `kind 6` reposts are reserved for `kind 1` contents, we use `kind 16`
as a "generic repost", that can include any kind of event inside other than as a "generic repost", that can include any kind of event inside other than
`kind 1`. `kind 1`.
`kind 16` reposts SHOULD contain a `k` tag with the stringified kind number `kind 16` reposts SHOULD contain a `"k"` tag with the stringified kind number
of the reposted event as its value. of the reposted event as its value.

2
21.md
View File

@ -21,7 +21,7 @@ The identifiers that come after are expected to be the same as those defined in
### Linking HTML pages to Nostr entities ### Linking HTML pages to Nostr entities
`<link>` tags with `rel="alternate"` can be used to associate webpages to Nostr events, in cases where the same content is served via the two mediums (for example, a web server that exposes Markdown articles both as HTML pages and as `kind:30023' events served under itself as a relay or through some other relay). For example: `<link>` tags with `rel="alternate"` can be used to associate webpages to Nostr events, in cases where the same content is served via the two mediums (for example, a web server that exposes Markdown articles both as HTML pages and as `kind:30023` events served under itself as a relay or through some other relay). For example:
``` ```
<head> <head>

8
22.md
View File

@ -143,13 +143,13 @@ A comment on a website's url looks like this:
"tags": [ "tags": [
// referencing the root url // referencing the root url
["I", "https://abc.com/articles/1"], ["I", "https://abc.com/articles/1"],
// the root "kind": for an url, the kind is its domain // the root "kind": for an url
["K", "https://abc.com"], ["K", "web"],
// the parent reference (same as root for top-level comments) // the parent reference (same as root for top-level comments)
["i", "https://abc.com/articles/1"], ["i", "https://abc.com/articles/1"],
// the parent "kind": for an url, the kind is its domain // the parent "kind": for an url
["k", "https://abc.com"] ["k", "web"]
] ]
// other fields // other fields
} }

13
24.md
View File

@ -8,8 +8,7 @@ Extra metadata fields and tags
This NIP keeps track of extra optional fields that can added to events which are not defined anywhere else but have become _de facto_ standards and other minor implementation possibilities that do not deserve their own NIP and do not have a place in other NIPs. This NIP keeps track of extra optional fields that can added to events which are not defined anywhere else but have become _de facto_ standards and other minor implementation possibilities that do not deserve their own NIP and do not have a place in other NIPs.
kind 0 ### kind 0
======
These are extra fields not specified in NIP-01 that may be present in the stringified JSON of metadata events: These are extra fields not specified in NIP-01 that may be present in the stringified JSON of metadata events:
@ -19,24 +18,22 @@ These are extra fields not specified in NIP-01 that may be present in the string
- `bot`: a boolean to clarify that the content is entirely or partially the result of automation, such as with chatbots or newsfeeds. - `bot`: a boolean to clarify that the content is entirely or partially the result of automation, such as with chatbots or newsfeeds.
- `birthday`: an object representing the author's birth date. The format is { "year": number, "month": number, "day": number }. Each field MAY be omitted. - `birthday`: an object representing the author's birth date. The format is { "year": number, "month": number, "day": number }. Each field MAY be omitted.
### Deprecated fields #### Deprecated fields
These are fields that should be ignored or removed when found in the wild: These are fields that should be ignored or removed when found in the wild:
- `displayName`: use `display_name` instead. - `displayName`: use `display_name` instead.
- `username`: use `name` instead. - `username`: use `name` instead.
kind 3 ### kind 3
======
These are extra fields not specified in NIP-02 that may be present in the stringified JSON of follow events: These are extra fields not specified in NIP-02 that may be present in the stringified JSON of follow events:
### Deprecated fields #### Deprecated fields
- `{<relay-url>: {"read": <true|false>, "write": <true|false>}, ...}`: an object of relays used by a user to read/write. [NIP-65](65.md) should be used instead. - `{<relay-url>: {"read": <true|false>, "write": <true|false>}, ...}`: an object of relays used by a user to read/write. [NIP-65](65.md) should be used instead.
tags ### tags
====
These tags may be present in multiple event kinds. Whenever a different meaning is not specified by some more specific NIP, they have the following meanings: These tags may be present in multiple event kinds. Whenever a different meaning is not specified by some more specific NIP, they have the following meanings:

2
25.md
View File

@ -26,8 +26,6 @@ There SHOULD be a `p` tag set to the `pubkey` of the event being reacted to. If
If the event being reacted to is an addressable event, an `a` SHOULD be included together with the `e` tag, it must be set to the coordinates (`kind:pubkey:d-tag`) of the event being reacted to. If the event being reacted to is an addressable event, an `a` SHOULD be included together with the `e` tag, it must be set to the coordinates (`kind:pubkey:d-tag`) of the event being reacted to.
The reaction SHOULD include a `k` tag with the stringified kind number of the reacted event as its value.
The `e` and `a` tags SHOULD include relay and pubkey hints. The `p` tags SHOULD include relay hints. The `e` and `a` tags SHOULD include relay and pubkey hints. The `p` tags SHOULD include relay hints.
The reaction event MAY include a `k` tag with the stringified kind number of the reacted event as its value. The reaction event MAY include a `k` tag with the stringified kind number of the reacted event as its value.

2
34.md
View File

@ -150,7 +150,7 @@ Root Patches and Issues have a Status that defaults to 'Open' and can be set by
["r", "<earliest-unique-commit-id-of-repo>"] ["r", "<earliest-unique-commit-id-of-repo>"]
// optional for `1631` status // optional for `1631` status
["e", "<applied-or-merged-patch-event-id>", "", "mention"], // for each ["q", "<applied-or-merged-patch-event-id>", "<relay-url>", "<pubkey>"], // for each
// when merged // when merged
["merge-commit", "<merge-commit-id>"] ["merge-commit", "<merge-commit-id>"]
["r", "<merge-commit-id>"] ["r", "<merge-commit-id>"]

66
43.md Normal file
View File

@ -0,0 +1,66 @@
NIP-43
======
Relay Access Requests
---------------------
`draft` `optional`
This NIP defines a way for clients to request admission to relays enforcing
authentication as defined in NIP 42 by signing an ephemeral event.
## Join Request
This NIP defines kind `28934` events which are intended to allow clients to
request admission to a relay. It MUST have a `claim` tag containing an invite
code.
The event's `created_at` MUST be now, plus or minus a few minutes. Clients MAY
send a claim at any time, but MUST check for relay support via NIP 11. This is
to avoid non-compliant relays broadcasting invites to subscribers.
This event should be sent to a relay using the standard `EVENT` verb.
```jsonc
{
"kind": 28934,
"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.
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, "claim-ignored: You are already a member of this relay."]
["OK", <event-id>, true, "claim-accepted: 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. These events MUST NOT be considered valid unless signed by the same pubkey
as exists in the relay's NIP 11 document.
```jsonc
{
"kind": 28935,
"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.

153
47.md
View File

@ -28,15 +28,16 @@ Fundamentally NWC is communication between a **client** and **wallet service** b
4. Once the payment is complete the **wallet service** will send an encrypted `response` (kind 23195) to the **user** over the relay(s) in the URI. 4. Once the payment is complete the **wallet service** will send an encrypted `response` (kind 23195) to the **user** over the relay(s) in the URI.
5. The **wallet service** may send encrypted notifications (kind 23196) of wallet events (such as a received payment) to the **client**. 5. The **wallet service** may send encrypted notifications (kind 23197 or 23196) of wallet events (such as a received payment) to the **client**.
## Events ## Events
There are four event kinds: There are four event kinds:
- `NIP-47 info event`: 13194 - `NIP-47 info event`: 13194
- `NIP-47 request`: 23194 - `NIP-47 request`: 23194
- `NIP-47 response`: 23195 - `NIP-47 response`: 23195
- `NIP-47 notification event`: 23196 - `NIP-47 notification event`: 23197 (23196 for backwards compatibility with NIP-04)
### Info Event ### Info Event
@ -46,34 +47,71 @@ The content should be a plaintext string with the supported capabilities space-s
If the **wallet service** supports notifications, the info event SHOULD contain a `notifications` tag with the supported notification types space-separated, eg. `payment_received payment_sent`. If the **wallet service** supports notifications, the info event SHOULD contain a `notifications` tag with the supported notification types space-separated, eg. `payment_received payment_sent`.
It should also contain supported encryption modes as described in the [Encryption](#encryption) section. For example:
```jsonc
{
"kind": 13194,
"tags": [
["encryption", "nip44_v2 nip04"], // List of supported encryption schemes as described in the Encryption section.
["notifications", "payment_received payment_sent"]
// ...
],
"content": "pay_invoice get_balance make_invoice lookup_invoice list_transactions get_info notifications",
// ...
}
```
### Request and Response Events ### Request and Response Events
Both the request and response events SHOULD contain one `p` tag, containing the public key of the **wallet service** if this is a request, and the public key of the **client** if this is a response. The response event SHOULD contain an `e` tag with the id of the request event it is responding to. Both the request and response events SHOULD contain one `p` tag, containing the public key of the **wallet service** if this is a request, and the public key of the **client** if this is a response. The response event SHOULD contain an `e` tag with the id of the request event it is responding to.
Optionally, a request can have an `expiration` tag that has a unix timestamp in seconds. If the request is received after this timestamp, it should be ignored. Optionally, a request can have an `expiration` tag that has a unix timestamp in seconds. If the request is received after this timestamp, it should be ignored.
The content of requests and responses is encrypted with [NIP04](04.md), and is a JSON-RPCish object with a semi-fixed structure: The content of requests and responses is encrypted with [NIP44](44.md), and is a JSON-RPCish object with a semi-fixed structure.
Request: **Important note for backwards-compatibility:** The initial version of the protocol used [NIP04](04.md). If a **wallet service** or client app does not include the `encryption` tag in the
```jsonc `info` or request events, it should be assumed that the connection is using NIP04 for encryption. See the [Encryption](#encryption) section for more information.
Example request:
```js
{ {
"method": "pay_invoice", // method, string "kind" 23194,
"params": { // params, object "tags": [
"invoice": "lnbc50n1..." // command-related data ["encryption", "nip44_v2"],
} ["p", "03..." ] // public key of the wallet service.
// ...
],
"content": nip44_encrypt({ // Encryption type corresponds to the `encryption` tag.
"method": "pay_invoice", // method, string
"params": { // params, object
"invoice": "lnbc50n1..." // command-related data
}
}),
} }
``` ```
Response: Example response:
```jsonc
```js
{ {
"result_type": "pay_invoice", //indicates the structure of the result field "kind" 23195,
"error": { //object, non-null in case of error "tags": [
"code": "UNAUTHORIZED", //string error code, see below ["p", "03..." ] // public key of the requesting client app
"message": "human readable error message" ["e", "1234"] // id of the request event this is responding to
}, // ...
"result": { // result, object. null in case of error. ],
"preimage": "0123456789abcdef..." // command-related data "content": nip44_encrypt({ // Encrypted using the scheme requested by the client.
} "result_type": "pay_invoice", //indicates the structure of the result field
"error": { //object, non-null in case of error
"code": "UNAUTHORIZED", //string error code, see below
"message": "human readable error message"
},
"result": { // result, object. null in case of error.
"preimage": "0123456789abcdef..." // command-related data
}
})
// ...
} }
``` ```
@ -83,9 +121,9 @@ If the command was successful, the `error` field must be null.
### Notification Events ### Notification Events
The notification event SHOULD contain one `p` tag, the public key of the **client**. The notification event is a kind 23197 event SHOULD contain one `p` tag, the public key of the **client**.
The content of notifications is encrypted with [NIP04](04.md), and is a JSON-RPCish object with a semi-fixed structure: The content of notifications is encrypted with [NIP44](44.md) (or NIP-04 for legacy client apps), and is a JSON-RPCish object with a semi-fixed structure:
```jsonc ```jsonc
{ {
@ -96,6 +134,7 @@ The content of notifications is encrypted with [NIP04](04.md), and is a JSON-RPC
} }
``` ```
_Note on backwards-compatibility:_ If a **wallet service** supports both nip44 and nip04 for legacy client apps, it should publish both notification events for each notification - kind 23196 encrypted with NIP-04, and kind 23197 encrypted with NIP-44. It is up to the **client** to decide which event to listen to based on its supported encryption and declared supported encryption schemes of the **wallet service** in the `info` event.
### Error codes ### Error codes
- `RATE_LIMITED`: The client is sending commands too fast. It should retry in a few seconds. - `RATE_LIMITED`: The client is sending commands too fast. It should retry in a few seconds.
@ -105,6 +144,7 @@ The content of notifications is encrypted with [NIP04](04.md), and is a JSON-RPC
- `RESTRICTED`: This public key is not allowed to do this operation. - `RESTRICTED`: This public key is not allowed to do this operation.
- `UNAUTHORIZED`: This public key has no wallet connected. - `UNAUTHORIZED`: This public key has no wallet connected.
- `INTERNAL`: An internal error. - `INTERNAL`: An internal error.
- `UNSUPPORTED_ENCRYPTION`: The encryption type of the request is not supported by the wallet service.
- `OTHER`: Other error. - `OTHER`: Other error.
## Nostr Wallet Connect URI ## Nostr Wallet Connect URI
@ -295,6 +335,7 @@ Response:
"result_type": "make_invoice", "result_type": "make_invoice",
"result": { "result": {
"type": "incoming", // "incoming" for invoices, "outgoing" for payments "type": "incoming", // "incoming" for invoices, "outgoing" for payments
"state": "pending",
"invoice": "string", // encoded invoice, optional "invoice": "string", // encoded invoice, optional
"description": "string", // invoice's description, optional "description": "string", // invoice's description, optional
"description_hash": "string", // invoice's description hash, optional "description_hash": "string", // invoice's description hash, optional
@ -328,6 +369,7 @@ Response:
"result_type": "lookup_invoice", "result_type": "lookup_invoice",
"result": { "result": {
"type": "incoming", // "incoming" for invoices, "outgoing" for payments "type": "incoming", // "incoming" for invoices, "outgoing" for payments
"state": "pending", // can be "pending", "settled", "expired" (for invoices) or "failed" (for payments)
"invoice": "string", // encoded invoice, optional "invoice": "string", // encoded invoice, optional
"description": "string", // invoice's description, optional "description": "string", // invoice's description, optional
"description_hash": "string", // invoice's description hash, optional "description_hash": "string", // invoice's description hash, optional
@ -376,6 +418,7 @@ Response:
"transactions": [ "transactions": [
{ {
"type": "incoming", // "incoming" for invoices, "outgoing" for payments "type": "incoming", // "incoming" for invoices, "outgoing" for payments
"state": "pending", // can be "pending", "settled", "expired" (for invoices) or "failed" (for payments)
"invoice": "string", // encoded invoice, optional "invoice": "string", // encoded invoice, optional
"description": "string", // invoice's description, optional "description": "string", // invoice's description, optional
"description_hash": "string", // invoice's description hash, optional "description_hash": "string", // invoice's description hash, optional
@ -452,6 +495,7 @@ Notification:
"notification_type": "payment_received", "notification_type": "payment_received",
"notification": { "notification": {
"type": "incoming", "type": "incoming",
"state": "settled",
"invoice": "string", // encoded invoice "invoice": "string", // encoded invoice
"description": "string", // invoice's description, optional "description": "string", // invoice's description, optional
"description_hash": "string", // invoice's description hash, optional "description_hash": "string", // invoice's description hash, optional
@ -477,6 +521,7 @@ Notification:
"notification_type": "payment_sent", "notification_type": "payment_sent",
"notification": { "notification": {
"type": "outgoing", "type": "outgoing",
"state": "settled",
"invoice": "string", // encoded invoice "invoice": "string", // encoded invoice
"description": "string", // invoice's description, optional "description": "string", // invoice's description, optional
"description_hash": "string", // invoice's description hash, optional "description_hash": "string", // invoice's description hash, optional
@ -499,6 +544,71 @@ Notification:
2. **wallet service** verifies that the author's key is authorized to perform the payment, decrypts the payload and sends the payment. 2. **wallet service** verifies that the author's key is authorized to perform the payment, decrypts the payload and sends the payment.
3. **wallet service** responds to the event by sending an event with kind `23195` and content being a response either containing an error message or a preimage. 3. **wallet service** responds to the event by sending an event with kind `23195` and content being a response either containing an error message or a preimage.
## Encryption
The initial version of NWC used [NIP-04](04.md) for encryption which has been deprecated and replaced by [NIP-44](44.md). NIP-44 should always be preferred for encryption, but there may be legacy cases
where the **wallet service** or **client** has not yet migrated to NIP-44. The **wallet service** and **client** should negotiate the encryption method to use based on the `encryption` tag in the `info` event.
The encryption tag can contain either `nip44_v2` or `nip04`. The absence of this tag implies that the wallet only supports `nip04`.
| Encryption code | Use | Notes |
|-----------------|----------------------|---------------------------------------------------------|
| `nip44_v2` | NIP-44 | Required |
| `nip04` | NIP-04 | Deprecated and only here for backward compatibility |
| `<not present>` | NIP-04 | Deprecated and only here for backward compatibility |
The negotiation works as follows.
1. The **wallet service** includes an `encryption` tag in the `info` event. This tag contains a space-separated list of encryption schemes that the **wallet service** supports (eg. `nip44_v2 nip04`)
2. The **client application** includes an `encryption` tag in each request event. This tag contains the encryption scheme which should be used for the request. The **client application** should always prefer nip44 if supported by the **wallet service**.
### Info event
First, the **wallet service** adds an `encryption` tag to its `info` event containing a space-separated list of encryption schemes it supports. For example,
if a wallet service supports nip44, but also allows backwards-compatibility to nip04 client applications, its `encryption` tag in the `info` event might look something like:
```jsonc
{
"kind": 13194,
"tags": [
["encryption", "nip44_v2 nip04"],
// ...
],
"content": "pay_invoice get_balance make_invoice lookup_invoice list_transactions get_info",
// ...
}
```
When a **client application** establishes a connection, it should read the info event and look for the `encryption` tag.
**Absence of this tag implies that the wallet only supports nip04.**
If the `encryption` tag is present, the **client application** will choose optimal encryption supported by both itself, and the **wallet service**, which should always be nip44 if possible.
### Request events
When a **client application** sends a request event, it should include a `encryption` tag with the encryption scheme it is using. The scheme MUST be supported by the **wallet service** as indicated by the info event.
For example, if the client application supports nip44, the request event might look like:
```jsonc
{
"kind": 23194,
"tags": [
["encryption", "nip44_v2"],
// ...
],
// ...
}
```
If the **wallet service** does not support the specified encryption scheme, it will return an `UNSUPPORTED_ENCRYPTION` error. Absence of the `encryption` tag indicates use of nip04 for encryption.
### Notification events
As described above in the [Notifications](#notifications) section, if a **wallet service** supports both nip04 and nip44, it should publish two notification events for each notification - kind 23196 encrypted with NIP-04, and kind 23197 encrypted with NIP-44. If the **wallet service** only supports nip44, it should only publish kind 23197 events.
The **client** should check the `encryption` tag in the `info` event to determine which encryption schemes the **wallet service** supports, and listen to the appropriate notification event.
## Using a dedicated relay ## Using a dedicated relay
This NIP does not specify any requirements on the type of relays used. However, if the user is using a custodial service it might make sense to use a relay that is hosted by the custodial service. The relay may then enforce authentication to prevent metadata leaks. Not depending on a 3rd party relay would also improve reliability in this case. This NIP does not specify any requirements on the type of relays used. However, if the user is using a custodial service it might make sense to use a relay that is hosted by the custodial service. The relay may then enforce authentication to prevent metadata leaks. Not depending on a 3rd party relay would also improve reliability in this case.
@ -513,6 +623,7 @@ This NIP does not specify any requirements on the type of relays used. However,
"created_at": 1713883677, "created_at": 1713883677,
"kind": 13194, "kind": 13194,
"tags": [ "tags": [
[ "encryption", "nip44_v2 nip04" ],
[ [
"notifications", "notifications",
"payment_received payment_sent" "payment_received payment_sent"

9
52.md
View File

@ -25,6 +25,7 @@ These tags are common to both types of calendar events:
* `p` (optional, repeated) 32-bytes hex pubkey of a participant, optional recommended relay URL, and participant's role in the meeting * `p` (optional, repeated) 32-bytes hex pubkey of a participant, optional recommended relay URL, and participant's role in the meeting
* `t` (optional, repeated) hashtag to categorize calendar event * `t` (optional, repeated) hashtag to categorize calendar event
* `r` (optional, repeated) references / links to web pages, documents, video calls, recorded videos, etc. * `r` (optional, repeated) references / links to web pages, documents, video calls, recorded videos, etc.
* `a` (repeated) reference tag to kind `31924` calendar event requesting to be included in Calendar
The following tags are deprecated: The following tags are deprecated:
@ -32,6 +33,12 @@ The following tags are deprecated:
Calendar events are _not_ required to be part of a [calendar](#calendar). Calendar events are _not_ required to be part of a [calendar](#calendar).
## Collaborative Calendar Event Requests
Calendar events can include an `a` tag referencing a calendar (kind 31924) to request addition to that calendar. When a calendar event includes such a reference, clients should interpret this as a request to add the event to the referenced calendar by referencing it with an `a` tag.
This enables collaborative calendar management where multiple users can contribute events to calendars they do not own, subject to the calendar owner's approval.
### Date-Based Calendar Event ### Date-Based Calendar Event
This kind of calendar event starts on a date and ends before a different date in the future. Its use is appropriate for all-day or multi-day events where time and time zone hold no significance. e.g., anniversary, public holidays, vacation days. This kind of calendar event starts on a date and ends before a different date in the future. Its use is appropriate for all-day or multi-day events where time and time zone hold no significance. e.g., anniversary, public holidays, vacation days.
@ -125,6 +132,8 @@ Aside from the common tags, this also takes the following tags:
A calendar is a collection of calendar events, represented as a custom _addressable list_ event using kind `31924`. A user can have multiple calendars. One may create a calendar to segment calendar events for specific purposes. e.g., personal, work, travel, meetups, and conferences. A calendar is a collection of calendar events, represented as a custom _addressable list_ event using kind `31924`. A user can have multiple calendars. One may create a calendar to segment calendar events for specific purposes. e.g., personal, work, travel, meetups, and conferences.
Calendars can accept event requests from other users. When calendar events reference a calendar via an `a` tag, this represents a request for inclusion.
The `.content` of these events should be a detailed description of the calendar. It is required but can be an empty string. The `.content` of these events should be a detailed description of the calendar. It is required but can be an empty string.
* `d` (required) universally unique identifier. Generated by the client creating the calendar. * `d` (required) universally unique identifier. Generated by the client creating the calendar.

5
57.md
View File

@ -37,6 +37,7 @@ In addition, the event MAY include the following tags:
- `e` is an optional hex-encoded event id. Clients MUST include this if zapping an event rather than a person. - `e` is an optional hex-encoded event id. Clients MUST include this if zapping an event rather than a person.
- `a` is an optional event coordinate that allows tipping addressable events such as NIP-23 long-form notes. - `a` is an optional event coordinate that allows tipping addressable events such as NIP-23 long-form notes.
- `k` is the stringified kind of the target event.
Example: Example:
@ -49,7 +50,8 @@ Example:
["amount", "21000"], ["amount", "21000"],
["lnurl", "lnurl1dp68gurn8ghj7um5v93kketj9ehx2amn9uh8wetvdskkkmn0wahz7mrww4excup0dajx2mrv92x9xp"], ["lnurl", "lnurl1dp68gurn8ghj7um5v93kketj9ehx2amn9uh8wetvdskkkmn0wahz7mrww4excup0dajx2mrv92x9xp"],
["p", "04c915daefee38317fa734444acee390a8269fe5810b2241e5e6dd343dfbecc9"], ["p", "04c915daefee38317fa734444acee390a8269fe5810b2241e5e6dd343dfbecc9"],
["e", "9ae37aa68f48645127299e9453eb5d908a0cbb6058ff340d528ed4d37c8994fb"] ["e", "9ae37aa68f48645127299e9453eb5d908a0cbb6058ff340d528ed4d37c8994fb"],
["k", "1"]
], ],
"pubkey": "97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322", "pubkey": "97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322",
"created_at": 1679673265, "created_at": 1679673265,
@ -151,6 +153,7 @@ Example `zap receipt`:
["p", "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245"], ["p", "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245"],
["P", "97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322"], ["P", "97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322"],
["e", "3624762a1274dd9636e0c552b53086d70bc88c165bc4dc0f9e836a1eaf86c3b8"], ["e", "3624762a1274dd9636e0c552b53086d70bc88c165bc4dc0f9e836a1eaf86c3b8"],
["k", "1"],
["bolt11", "lnbc10u1p3unwfusp5t9r3yymhpfqculx78u027lxspgxcr2n2987mx2j55nnfs95nxnzqpp5jmrh92pfld78spqs78v9euf2385t83uvpwk9ldrlvf6ch7tpascqhp5zvkrmemgth3tufcvflmzjzfvjt023nazlhljz2n9hattj4f8jq8qxqyjw5qcqpjrzjqtc4fc44feggv7065fqe5m4ytjarg3repr5j9el35xhmtfexc42yczarjuqqfzqqqqqqqqlgqqqqqqgq9q9qxpqysgq079nkq507a5tw7xgttmj4u990j7wfggtrasah5gd4ywfr2pjcn29383tphp4t48gquelz9z78p4cq7ml3nrrphw5w6eckhjwmhezhnqpy6gyf0"], ["bolt11", "lnbc10u1p3unwfusp5t9r3yymhpfqculx78u027lxspgxcr2n2987mx2j55nnfs95nxnzqpp5jmrh92pfld78spqs78v9euf2385t83uvpwk9ldrlvf6ch7tpascqhp5zvkrmemgth3tufcvflmzjzfvjt023nazlhljz2n9hattj4f8jq8qxqyjw5qcqpjrzjqtc4fc44feggv7065fqe5m4ytjarg3repr5j9el35xhmtfexc42yczarjuqqfzqqqqqqqqlgqqqqqqgq9q9qxpqysgq079nkq507a5tw7xgttmj4u990j7wfggtrasah5gd4ywfr2pjcn29383tphp4t48gquelz9z78p4cq7ml3nrrphw5w6eckhjwmhezhnqpy6gyf0"],
["description", "{\"pubkey\":\"97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322\",\"content\":\"\",\"id\":\"d9cc14d50fcb8c27539aacf776882942c1a11ea4472f8cdec1dea82fab66279d\",\"created_at\":1674164539,\"sig\":\"77127f636577e9029276be060332ea565deaf89ff215a494ccff16ae3f757065e2bc59b2e8c113dd407917a010b3abd36c8d7ad84c0e3ab7dab3a0b0caa9835d\",\"kind\":9734,\"tags\":[[\"e\",\"3624762a1274dd9636e0c552b53086d70bc88c165bc4dc0f9e836a1eaf86c3b8\"],[\"p\",\"32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245\"],[\"relays\",\"wss://relay.damus.io\",\"wss://nostr-relay.wlvs.space\",\"wss://nostr.fmt.wiz.biz\",\"wss://relay.nostr.bg\",\"wss://nostr.oxtr.dev\",\"wss://nostr.v0l.io\",\"wss://brb.io\",\"wss://nostr.bitcoiner.social\",\"ws://monad.jb55.com:8080\",\"wss://relay.snort.social\"]]}"], ["description", "{\"pubkey\":\"97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322\",\"content\":\"\",\"id\":\"d9cc14d50fcb8c27539aacf776882942c1a11ea4472f8cdec1dea82fab66279d\",\"created_at\":1674164539,\"sig\":\"77127f636577e9029276be060332ea565deaf89ff215a494ccff16ae3f757065e2bc59b2e8c113dd407917a010b3abd36c8d7ad84c0e3ab7dab3a0b0caa9835d\",\"kind\":9734,\"tags\":[[\"e\",\"3624762a1274dd9636e0c552b53086d70bc88c165bc4dc0f9e836a1eaf86c3b8\"],[\"p\",\"32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245\"],[\"relays\",\"wss://relay.damus.io\",\"wss://nostr-relay.wlvs.space\",\"wss://nostr.fmt.wiz.biz\",\"wss://relay.nostr.bg\",\"wss://nostr.oxtr.dev\",\"wss://nostr.v0l.io\",\"wss://brb.io\",\"wss://nostr.bitcoiner.social\",\"ws://monad.jb55.com:8080\",\"wss://relay.snort.social\"]]}"],
["preimage", "5d006d2cf1e73c7148e7519a4c68adc81642ce0e25a432b2434c99f97344c15f"] ["preimage", "5d006d2cf1e73c7148e7519a4c68adc81642ce0e25a432b2434c99f97344c15f"]

1
61.md
View File

@ -53,6 +53,7 @@ Clients MUST prefix the public key they P2PK-lock with `"02"` (for nostr<>cashu
[ "proof", "{\"amount\":1,\"C\":\"02277c66191736eb72fce9d975d08e3191f8f96afb73ab1eec37e4465683066d3f\",\"id\":\"000a93d6f8a1d2c4\",\"secret\":\"[\\\"P2PK\\\",{\\\"nonce\\\":\\\"b00bdd0467b0090a25bdf2d2f0d45ac4e355c482c1418350f273a04fedaaee83\\\",\\\"data\\\":\\\"02eaee8939e3565e48cc62967e2fde9d8e2a4b3ec0081f29eceff5c64ef10ac1ed\\\"}]\"}" ], [ "proof", "{\"amount\":1,\"C\":\"02277c66191736eb72fce9d975d08e3191f8f96afb73ab1eec37e4465683066d3f\",\"id\":\"000a93d6f8a1d2c4\",\"secret\":\"[\\\"P2PK\\\",{\\\"nonce\\\":\\\"b00bdd0467b0090a25bdf2d2f0d45ac4e355c482c1418350f273a04fedaaee83\\\",\\\"data\\\":\\\"02eaee8939e3565e48cc62967e2fde9d8e2a4b3ec0081f29eceff5c64ef10ac1ed\\\"}]\"}" ],
[ "u", "https://stablenut.umint.cash" ], [ "u", "https://stablenut.umint.cash" ],
[ "e", "<nutzapped-event-id>", "<relay-hint>" ], [ "e", "<nutzapped-event-id>", "<relay-hint>" ],
[ "k", "<nutzapped-kind>"],
[ "p", "e9fbced3a42dcf551486650cc752ab354347dd413b307484e4fd1818ab53f991" ], // recipient of nutzap [ "p", "e9fbced3a42dcf551486650cc752ab354347dd413b307484e4fd1818ab53f991" ], // recipient of nutzap
] ]
} }

217
66.md
View File

@ -6,135 +6,44 @@ Relay Discovery and Liveness Monitoring
`draft` `optional` `draft` `optional`
You want to find relays. You may want to discover relays based on criteria that's up to date. You may even want to ensure that you have a complete dataset. You probably want to filter relays based on their reported liveness. This NIP defines events for relay discovery and the announcement of relay monitors.
In its purest form: ## Relay Discovery Events
```json `30166` relay discovery events document relay characteristics inferred either from a relay's [NIP 11](https://github.com/nostr-protocol/nips/blob/master/11.md) document, or via probing.
{
"kind": 30166,
"created_at": 1722173222,
"content": "{}",
"tags": [
[ "d", "wss://somerelay.abc/" ]
],
"pubkey": "<pubkey>",
"sig": "<signature>",
"id": "<eventid>"
}
```
This event signals that the relay at `wss://somerelay.abc/` was reported "online" by `<pubkey>` at timestamp `1722173222`. This event **MAY** be extended upon to include more information. Information corresponding to field in a relay's NIP 11 document MAY contradict actual values if monitors find that a different policy is implemented than is advertised.
## Kinds `content` MAY include the stringified JSON of the relay's NIP-11 informational document.
`NIP-66` defines two (2) event kinds, `30166` and `10166`
| kind | name | description | The only required tag is the `d` tag, which MUST be set to the relay's [normalized](https://datatracker.ietf.org/doc/html/rfc3986#section-6) URL. For relays not accessible via URL, a hex-encoded pubkey MAY be used instead.
|-------|----------------------------|-----------------------------------------------------------------------------------------|
| [30166](#k30166) | Relay Discovery | An addressable event that is published by a monitor when a relay is online |
| [10166](#k10166) | Relay Monitor Announcement | An RE that stores data that signals the intent of a pubkey to monitor relays and publish `30166` events at a regular _frequency_ |
## Ontology Other tags include:
- `Relay Operator`: someone who operates a relay
- `Monitor`: A pubkey that monitors relays and publishes `30166` events at the frequency specified in their `10166` event.
- `Ad-hoc Monitor`: A pubkey that monitors relays and publishes `30166` events at an irregular frequency.
- `Monitor Service`: A group or individual that monitors relays using one or more `Monitors`.
- `Check`: a specific data point that is tested or aggregated by a monitor.
## `30166`: "Relay Discovery" <a id="k30166"></a> - `rtt-open` - The relay's open round-trip time in milliseconds.
- `rtt-read` - The relay's read round-trip time in milliseconds.
- `rtt-write` - The relay's write round-trip time in milliseconds.
- `n` - The relay's network type. SHOULD be one of `clearnet`, `tor`, `i2p`, `loki`
- `T` - The relay type. Enumerated [relay type](https://github.com/nostr-protocol/nips/issues/1282) formatted as `PascalCase`, e.g. `PrivateInbox`
- `N` - NIPs supported by the relay
- `R` - Keys corresponding to requirements per [NIP 11](https://github.com/nostr-protocol/nips/blob/master/11.md)'s `limitations` array, including `auth`, `writes`, `pow`, and `payment`. False values should be specified using a `!` prefix, for example `!auth`.
- `t` - A topic associated with this relay
- `k` - An event kind accepted by the relay
- `!k` - An event kind not accepted by the relay
- `g` - A [NIP-52](https://github.com/nostr-protocol/nips/blob/master/52.md) geohash
- `l` - A language tag
### Summary Tags with more than one value should be repeated, rather than putting all values in a single tag, for example `[["t", "cats"], ["t", "dogs"]]`, rather than `[["t", "cats", "dogs"]]`.
`30166` is a `NIP-33` addressable event, referred to as a "Relay Discovery" event. These events are optimized with a small footprint for protocol-level relay Discovery.
### Purpose Example:
Discovery of relays over nostr.
### Schema
#### Content
`30166` content fields **SHOULD** include the stringified JSON of the relay's NIP-11 informational document. This data **MAY** be provided for informational purposes only.
#### `created_at`
The `created_at` field in a NIP-66 event should reflect the time when the relay liveness (and potentially other data points) was checked.
#### `tags`
##### Meta Tags (unindexed)
- `rtt-open` The relay's open **round-trip time** in milliseconds.
- `rtt-read` The relay's read **round-trip time** in milliseconds.
- `rtt-write` The relay's write **round-trip time** in milliseconds.
_Other `rtt` values **MAY** be present. This NIP should be updated if there is value found in more `rtt` values._
##### Single Letter Tags (indexed)
- `d` The relay URL/URI. The `#d` tag **must** be included in the `event.tags[]` array. Index position `1` **must** be the relay websocket URL/URI. If a URL it **SHOULD** be [normalized](https://datatracker.ietf.org/doc/html/rfc3986#section-6). For relays not accessible via conventional means but rather by an npub/pubkey, an npub/pubkey **MAY** be used in place of a URL.
```json
[ "d", "wss://somerelay.abc/"]
```
- `n`: Network
```json
[ "n", "clearnet" ]
```
- `T`: Relay Type. Enumerated [relay type](https://github.com/nostr-protocol/nips/issues/1282) formatted as `PascalCase`
```json
["T", "PrivateInbox" ]
```
- `N`: Supported Nips _From NIP-11 "Informational Document" `nip11.supported_nips[]`_
```json
[ "N", "42" ]
```
- `R`: Requirements _NIP-11 "Informational Document" `nip11.limitations.payment_required`, `nip11.limitations.auth_required` and/or any other boolean value within `nip11.limitations[]` that is added in the future_
```json
[ "R", "payment" ],
[ "R", "auth" ],
```
Since the nostr protocol does not currently support filtering on whether an indexed tag **is** or **is not** set, to make "public" and "no auth" relays discoverable requires a `!` flag
```json
[ "R", "!payment" ], //no payment required, is public
[ "R", "!auth" ], //no authentication required
```
- `t`: "Topics" _From NIP-11 "Informational Document" `nip11.tags[]`_
```json
[ "t", "nsfw" ]
```
- `k`: Accepted/Blocked Kinds [`NIP-22`]
```json
[ "k", "0" ],
[ "k", "3" ],
[ "k", "10002" ]
```
or for blocked kinds
```json
[ "k", "!0" ]
[ "k", "!3" ],
[ "k", "!10002" ]
```
- `g`: `NIP-52` `g` tags (geohash)
```json
[ "g", "9r1652whz" ]
```
- `30166` **MAY** be extended with global tags defined by other NIPs that do no collide with locally defined indices, including but not limited to: `p`, `t`, `e`, `a`, `i` and `l/L`.
#### Robust Example of a `30166` Event
_Relay was online, and you can filter on a number of different tags_
```json ```json
{ {
"id": "<eventid>", "id": "<eventid>",
"pubkey": "<monitor's pubkey>", "pubkey": "<monitor's pubkey>",
"created_at": "<created_at [some recent date ...]>", "created_at": "<created_at [some recent date ...]>",
"signature": "<signature>", "signature": "<signature>",
"content": "{}", "content": "<optional nip 11 document>",
"kind": 30166, "kind": 30166,
"tags": [ "tags": [
["d","wss://some.relay/"], ["d","wss://some.relay/"],
@ -144,7 +53,6 @@ _Relay was online, and you can filter on a number of different tags_
["R", "!payment"], ["R", "!payment"],
["R", "auth"], ["R", "auth"],
["g", "ww8p1r4t8"], ["g", "ww8p1r4t8"],
["p", "somehexkey..."],
["l", "en", "ISO-639-1"], ["l", "en", "ISO-639-1"],
["t", "nsfw" ], ["t", "nsfw" ],
["rtt-open", 234 ] ["rtt-open", 234 ]
@ -152,56 +60,21 @@ _Relay was online, and you can filter on a number of different tags_
} }
``` ```
## `10166`: "Relay Monitor Announcement" Events <a id="k10166"></a> ## Relay Monitor Announcements
### Summary Kind `10166` relay monitor announcements advertise the author's intent to publish `30166` events. This event is optional and is intended for monitors who intend to provide monitoring services at a regular and predictable frequency.
`10166` is a replacable event herein referred to as "Relay Monitor Announcement" events. These events contain information about a publisher's intent to monitor and publish data as `30166` events. This event is optional and is intended for monitors who intend to provide monitoring services at a regular and predictable frequency.
### Purpose Tags include:
To provide a directory of monitors, their intent to publish, their criteria and parameters of monitoring activities. Absence of this event implies the monitor is ad-hoc and does not publish events at a predictable frequency, and relies on mechanisms to infer data integrity, such as web-of-trust.
### Schema - `frequency` - The frequency in seconds at which the monitor publishes events.
- `timeout` (optional) - The timeout values for various checks conducted by a monitor. Index `1` is the monitor's timeout in milliseconds. Index `2` describes what test the timeout is used for. If no index `2` is provided, it is inferred that the timeout provided applies to all tests.
- `c` - a lowercase string describing the checks conducted by a monitor. Examples include `open`, `read`, `write`, `auth`, `nip11`, `dns`, and `geo`.
- `g` - [NIP-52](https://github.com/nostr-protocol/nips/blob/master/11.md) geohash tag
#### Standard Tags Monitors SHOULD also publish a `kind 0` profile and a `kind 10002` relay selections event.
- `frequency` The frequency **in seconds** at which the monitor publishes events. A string-integer at index `1` represents the expected frequency the monitor will publish `30166` events. There should only be `1` frequency per monitor. Example:
```json
[ "frequency", "3600" ]
```
- `timeout` (optional) The timeout values for various checks conducted by a monitor. Index `1` is the monitor's timeout in milliseconds. Index `2` describes what test the timeout is used for. If no index `2` is provided, it is inferred that the timeout provided applies to all tests. These values can assist relay operators in understanding data signaled by the monitor in _Relay Discovery Events_.
```json
[ "timeout", "2000", "open" ],
[ "timeout", "2000", "read" ],
[ "timeout", "3000", "write" ],
[ "timeout", "2000", "nip11" ],
[ "timeout", "4000", "ssl" ]
```
#### Indexed Tags
- `c` "Checks" **SHOULD** be a lowercase string describing the check(s) conducted by a monitor. Due to the rapidly evolving nature of relays, enumeration is organic and not strictly defined. But examples of some checks could be websocket `open/read/write/auth`, `nip11` checks, `dns` and `geo` checks, and and any other checks the monitor may deem useful.. Other checks **MAY** be included. New types of checks **SHOULD** be added to this NIP as they are needed.
```json
[ "c", "ws" ],
[ "c", "nip11" ],
[ "c", "dns" ],
[ "c", "geo" ],
[ "c", "ssl" ],
```
- `g`: `NIP-52` `g` tags (geohash)
```json
[ "g", "9r1652whz" ]
```
- Any other globally defined indexable tags **MAY** be included as found necessary.
### Other Requirements
Monitors **SHOULD** have the following
- A published `0` (NIP-1) event
- A published `10002` (NIP-65) event that defines the relays the monitor publishes to.
### Robust Example of a `10166` Event
```json ```json
{ {
"id": "<eventid>", "id": "<eventid>",
@ -210,45 +83,17 @@ Monitors **SHOULD** have the following
"signature": "<signature>", "signature": "<signature>",
"content": "", "content": "",
"tags": [ "tags": [
[ "timeout", "open", "5000" ], [ "timeout", "open", "5000" ],
[ "timeout", "read", "3000" ], [ "timeout", "read", "3000" ],
[ "timeout", "write", "3000" ], [ "timeout", "write", "3000" ],
[ "timeout", "nip11", "3000" ], [ "timeout", "nip11", "3000" ],
[ "frequency", "3600" ], [ "frequency", "3600" ],
[ "c", "ws" ], [ "c", "ws" ],
[ "c", "nip11" ], [ "c", "nip11" ],
[ "c", "ssl" ], [ "c", "ssl" ],
[ "c", "dns" ], [ "c", "dns" ],
[ "c", "geo" ] [ "c", "geo" ]
[ "g", "ww8p1r4t8" ] [ "g", "ww8p1r4t8" ]
] ]
} }
``` ```
## Methodology
### Monitors
1. A _Relay Monitor_ checks the liveness and potentially other attributes of a relay.
2. _Relay Monitor_ publishes a kind `30166` note when a relay it is monitoring is online. If the monitor has a `10166` event, events should be published at the frequency defined in their `10166` note.
_Any pubkey that publishes `30166` events **SHOULD** at a minimum be checking that the relay is available by websocket and behaves like a relay_
### Clients
1. In most cases, a client **SHOULD** filter on `30166` events using either a statically or dynamically defined monitor's `pubkey` and a `created_at` value respective of the monitor's published `frequency`. If the monitor has no stated frequency, other mechanisms should be employed to determine data integrity.
2. _Relay Liveness_ is subjectively determined by the client, starting with the `frequency` value of a monitor.
3. The liveness of a _Relay Monitor_ can be subjectively determined by detecting whether the _Relay Monitor_ has published events with respect to `frequency` value of any particular monitor.
4. The reliability and trustworthiness of a _Relay Monitor_ could be established via web-of-trust, reviews or similar mechanisms.
## Risk Mitigation
- When a client implements `NIP-66` events, the client should have a fallback if `NIP-66` events cannot be located.
- A `Monitor` or `Ad-hoc Monitor` may publish erroneous `30166` events, intentionally or otherwise. Therefor, it's important to program defensively to limit the impact of such events. This can be achieved with web-of-trust, reviews, fallbacks and/or data-aggregation for example.

1
69.md
View File

@ -80,6 +80,7 @@ Currently implemented on the following platforms:
- [Mostro](https://github.com/MostroP2P/mostro) - [Mostro](https://github.com/MostroP2P/mostro)
- [@lnp2pBot](https://github.com/lnp2pBot/bot) - [@lnp2pBot](https://github.com/lnp2pBot/bot)
- [Robosats](https://github.com/RoboSats/robosats/pull/1362) - [Robosats](https://github.com/RoboSats/robosats/pull/1362)
- [Peach Bitcoin](https://github.com/Peach2Peach/peach-nostr-announcer-bot)
## References ## References

44
72.md
View File

@ -41,19 +41,55 @@ The goal of this NIP is to enable public communities. It defines the replaceable
# Posting to a community # Posting to a community
Any Nostr event can be posted to a community. Clients MUST add one or more community `a` tags, each with a recommended relay. [NIP-22](NIP-22) kind 1111 events SHOULD be used for text notes posted to a community, with the `A` tag always scoped to the community definition.
## Top-level posts
For top-level posts, the uppercase and lowercase NIP-22 tags should both refer to the community definition itself.
```jsonc ```jsonc
{ {
"kind": 1, "kind": 1111,
"tags": [ "tags": [
["a", "34550:<community event author pubkey>:<community-d-identifier>", "<optional-relay-url>"], ["A", "34550:<community-author-pubkey>:<community-d-identifier>", "<optional-relay-url>"],
["a", "34550:<community-author-pubkey>:<community-d-identifier>", "<optional-relay-url>"],
["P", "<community-author-pubkey>", "<optional-relay-url>"],
["p", "<community-author-pubkey>", "<optional-relay-url>"],
["K", "34550"],
["k", "34550"],
], ],
"content": "hello world", "content": "Hi everyone. It's great to be here!",
// other fields... // other fields...
} }
``` ```
## Nested replies
For nested replies, the uppercase tags should still refer to the community definition, while the lowercase tags should refer to the parent post or reply.
```jsonc
{
"kind": 1111,
"tags": [
// community definition itself
["A", "34550:<community-author-pubkey>:<community-d-identifier>", "<optional-relay-url>"],
["P", "<community-author-pubkey>", "<optional-relay-url>"],
["K", "34550"],
// parent post or reply
["e", "<parent-event-id>", "<optional-relay-url>"],
["p", "<parent-event-author-pubkey>", "<optional-relay-url>"],
["k", "<parent-event-kind>"] // most likely "1111"
],
"content": "Agreed! Welcome everyone!",
// other fields...
}
```
## Backwards compatibility note
Previously kind 1 events were used for posts in communities, with an "a" tag pointing to the community. For backwards compatibility, clients MAY still query for kind 1 events, but SHOULD NOT use them for new posts. Instead, clients SHOULD use kind 1111 events with the `A` and `a` tags as described above.
# Moderation # Moderation
Anyone may issue an approval event to express their opinion that a post is appropriate for a community. Clients MAY choose which approval events to honor, but SHOULD at least use ones published by the group's defined moderators. Anyone may issue an approval event to express their opinion that a post is appropriate for a community. Clients MAY choose which approval events to honor, but SHOULD at least use ones published by the group's defined moderators.

142
87.md Normal file
View File

@ -0,0 +1,142 @@
NIP-87
======
Ecash Mint Discoverability
--------------------------------
`draft` `optional`
This NIP describes `kind:38173`, `kind:38172` and `kind:38000`: a way to discover ecash mints, their capabilities, and people who recommend them.
## Rationale
Nostr's discoverability and transparent event interaction is one of its most interesting/novel mechanics.
This NIP provides a simple way for users to discover ecash mints recommended by other users and to interact with them.
### Parties involved
There are three actors to this workflow:
* An ecash mint operator, announces their mint and its capabilities.
* Publishes `kind:38173` or `kind:38172`, detailing how to connect to it and its capabilities.
* user A, who recommends an ecash mint
* Publishes `kind:38000`
* user B, who seeks a recommendation for an ecash mint
* Queries for `kind:38000` and, based on results, queries for `kind:38173`/`kind:38172`
## Events
### Recommendation event
```json
{
"kind": 38000,
"pubkey": <recommender-user-pubkey>,
"tags": [
["k", "38173"],
["d", "<d-identifier>"],
["u", <recommended-fedimint-invite-code>],
["a", "38173:fedimint-pubkey:<d-identifier>", "wss://relay1"]
],
"content": "I trust this mint with my life"
}
```
The recommendation event is a parameterized-replacable event so that a user can change edit their recommendation without creating a new event.
The `d` tag in `kind:38000` is the `kind:38173`/`kind:38172` event identifier this event is recommending, if no event exists, the `d` tag can still be calculated from the mint's pubkey/id.
The `k` tag is the kind number that corresponds to the event kind that the user is recommending, in this case `kind:38173` for fedimints and `kind:38172` for cashu mints.
Optional `u` tags can be added to give a recommend way to connect to the mint.
The value of the tag is the URL or invite code of the ecash mint.
Multiple `u` tags can appear on the same `kind:38000`.
`a` tags are used to point to the `kind:38173`/`kind:38172` event of the ecash mint.
The first value of the tag is the `kind:38173`/`kind:38172` event identifier, the second value of the tag is a relay hint.
This is used to correctly point to the mint's `kind:38173`/`kind:38172` event in case there are duplicates claiming to be the same mint.
The content can be used to give a review.
## Ecash Mint Information
Cashu mints SHOULD publish `kind:38172` events to announce their capabilities and how to connect to them.
For cashu mints, the `u` tag SHOULD be the URL to the cashu mint and it should list the nuts that the cashu mint supports.
The `d` tag SHOULD be the mint's pubkey (found when querying `/v1/info`), this way users can query by pubkey and find the mint announcement.
An `n` tag SHOULD be added to signify the network the cashu mint is on (either `mainnet`, `testnet`, `signet`, or `regtest`)
```json
{
"kind": 38172,
"pubkey": "<application-pubkey>",
"content": "<optional-kind:0-style-metadata>",
"tags": [
["d", <cashu mint pubkey>],
["u", "https://cashu.example.com"],
["nuts", "1,2,3,4,5,6,7"],
["n", "mainnet"]
]
}
```
Fedimints SHOULD publish `kind:38173` events to announce their capabilities and how to connect to them.
For fedimints, it should list all known fedimint invite codes in `u` tags and it should list the modules it supports.
The `d` tag SHOULD be the federation id, this way users can query by federation id and find the fedimint announcement.
An `n` tag SHOULD be added to signify the network the fedimint is on (either `mainnet`, `testnet`, `signet`, or `regtest`)
```json
{
"kind": 38173,
"pubkey": "<application-pubkey>",
"content": "<optional-kind:0-style-metadata>",
"tags": [
["d", <federation-id>],
["u", "fed11abc.."],
["u", "fed11xyz.."],
["modules", "lightning,wallet,mint"],
["n", "signet"]
]
}
```
* `content` is an optional `metadata`-like stringified JSON object, as described in NIP-01. This content is useful when the pubkey creating the `kind:38173` is not a normal user. If `content` is empty, the `kind:0` of the pubkey should be used to display mint information (e.g. name, picture, web, LUD16, etc.)
## Example
### User A recommends some mints
User A might be a user of a cashu mint. Using a client, user A publishes an event recommending the cashu mint they use.
```json
{
"kind": 38000,
"tags": [
["u", "fed11abc..", "fedimint"],
["u", "https://cashu.example.com", "cashu"],
["a", "38173:fedimint-pubkey:<d-identifier>", "wss://relay1", "fedimint"],
["a", "38172:cashu-mint-pubkey:<d-identifier>", "wss://relay2", "cashu"]
],
...
}
```
### User B finds a mint
User B wants to use an ecash wallet, they need to find a mint.
User B's wallet client queries for `kind:38000` events, looking for recommendations for ecash mints.
```json
["REQ", <id>, [{ "kinds": [38000], "authors": [<user>, <users-contact-list>], "#k": ["38173"] }]]
```
User B, who follows User A, sees that `kind:38000` event and tries to connect to the corresponding mints.
### Alternative query bypassing `kind:38000`
Alternatively, users might choose to query directly for `kind:38173` for an event kind. Clients SHOULD be careful doing this and use spam-prevention mechanisms or querying high-quality restricted relays to avoid directing users to malicious handlers.
```json
["REQ", <id>, [{ "kinds": [38173], "authors": [...] }]]
```

60
A0.md Normal file
View File

@ -0,0 +1,60 @@
NIP-A0
======
Voice Messages
-----------
**Status:** Draft
This NIP defines new events `kind: 1222` for root messages and `kind: 1244` for reply messages to be used for short voice messages, typically up to 60 seconds in length.
## Specification
### Event Kind `1222` and Kind `1244`
The `kind: 1222` event is defined as follows:
- `content`: MUST be a URL pointing directly to an audio file.
- The audio file SHOULD be in `audio/mp4` (.m4a) format using AAC or Opus encoding. Clients MAY support other common audio formats like `audio/ogg`, `audio/webm`, or `audio/mpeg` (mp3), but `audio/mp4` is recommended for broad compatibility and efficiency.
- The audio duration SHOULD be no longer than 60 seconds. Clients publishing `kind: 1222` events SHOULD enforce this limit or provide a clear warning to the user if exceeded.
- `tags`:
- Tags MAY be included as per other NIPs (e.g., `t` for hashtags, `g` for geohash, etc.).
The `kind: 1244` event is defined as follows:
- To be used for replies, `kind: 1244` events MUST follow the structure of `NIP-22`.
- `content`: MUST be a URL pointing directly to an audio file.
- The audio file SHOULD be in `audio/mp4` (.m4a) format using AAC or Opus encoding. Clients MAY support other common audio formats like `audio/ogg`, `audio/webm`, or `audio/mpeg` (mp3), but `audio/mp4` is recommended for broad compatibility and efficiency.
- The audio duration SHOULD be no longer than 60 seconds. Clients publishing `kind: 1222` events SHOULD enforce this limit or provide a clear warning to the user if exceeded.
- `tags`:
- Tags MAY be included as per other NIPs (e.g., `t` for hashtags, `g` for geohash, etc.).
## Visual representation with `imeta` (NIP-92) tag (optional)
The following imeta (NIP-92) tags MAY be included so clients can render a visual preview without having to download the audio file first:
- `waveform`: amplitude values over time, space separated full integers, less than 100 values should be enough to render a nice visual
- `duration`: audio length in seconds
## Examples
### Root Voice Message Example
```json
{
"content": "https://blossom.primal.net/5fe7df0e46ee6b14b5a8b8b92939e84e3ca5e3950eb630299742325d5ed9891b.mp4",
"created_at": 1752501052,
"id": "...",
"kind": 1222,
"pubkey": "...",
"sig": "...",
"tags": [
[
"imeta",
"url https://blossom.primal.net/5fe7df0e46ee6b14b5a8b8b92939e84e3ca5e3950eb630299742325d5ed9891b.mp4",
"waveform 0 7 35 8 100 100 49 8 4 16 8 10 7 2 20 10 100 100 100 100 100 100 15 100 100 100 25 60 5 4 3 1 0 100 100 15 100 29 88 0 33 11 39 100 100 19 4 100 42 35 5 0 1 5 0 0 11 38 100 94 17 11 44 58 5 100 100 100 55 14 72 100 100 57 6 1 14 2 16 100 100 40 16 100 100 6 32 14 13 41 36 16 14 6 3 0 1 2 1 6 0",
"duration 8"
]
]
}

View File

@ -93,6 +93,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
- [NIP-7D: Threads](7D.md) - [NIP-7D: Threads](7D.md)
- [NIP-84: Highlights](84.md) - [NIP-84: Highlights](84.md)
- [NIP-86: Relay Management API](86.md) - [NIP-86: Relay Management API](86.md)
- [NIP-87: Ecash Mint Discoverability](87.md)
- [NIP-88: Polls](88.md) - [NIP-88: Polls](88.md)
- [NIP-89: Recommended Application Handlers](89.md) - [NIP-89: Recommended Application Handlers](89.md)
- [NIP-90: Data Vending Machines](90.md) - [NIP-90: Data Vending Machines](90.md)
@ -101,13 +102,13 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
- [NIP-96: HTTP File Storage Integration](96.md) - [NIP-96: HTTP File Storage Integration](96.md)
- [NIP-98: HTTP Auth](98.md) - [NIP-98: HTTP Auth](98.md)
- [NIP-99: Classified Listings](99.md) - [NIP-99: Classified Listings](99.md)
- [NIP-A0: Voice Messages](A0.md)
- [NIP-B0: Web Bookmarks](B0.md) - [NIP-B0: Web Bookmarks](B0.md)
- [NIP-B7: Blossom](B7.md) - [NIP-B7: Blossom](B7.md)
- [NIP-C0: Code Snippets](C0.md) - [NIP-C0: Code Snippets](C0.md)
- [NIP-C7: Chats](C7.md) - [NIP-C7: Chats](C7.md)
## Event Kinds ## Event Kinds
| kind | description | NIP | | kind | description | NIP |
| ------------- | ------------------------------- | -------------------------------------- | | ------------- | ------------------------------- | -------------------------------------- |
| `0` | User Metadata | [01](01.md) | | `0` | User Metadata | [01](01.md) |
@ -151,6 +152,8 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
| `1063` | File Metadata | [94](94.md) | | `1063` | File Metadata | [94](94.md) |
| `1068` | Poll | [88](88.md) | | `1068` | Poll | [88](88.md) |
| `1111` | Comment | [22](22.md) | | `1111` | Comment | [22](22.md) |
| `1222` | Voice Message | [A0](A0.md) |
| `1244` | Voice Message Comment | [A0](A0.md) |
| `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) |
@ -172,6 +175,8 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
| `7374` | Reserved Cashu Wallet Tokens | [60](60.md) | | `7374` | Reserved Cashu Wallet Tokens | [60](60.md) |
| `7375` | Cashu Wallet Tokens | [60](60.md) | | `7375` | Cashu Wallet Tokens | [60](60.md) |
| `7376` | Cashu Wallet History | [60](60.md) | | `7376` | Cashu Wallet History | [60](60.md) |
| `7516` | Geocache log | [geocaching](geocaching) |
| `7517` | Geocache proof of find | [geocaching](geocaching) |
| `9000`-`9030` | Group Control Events | [29](29.md) | | `9000`-`9030` | Group Control Events | [29](29.md) |
| `9041` | Zap Goal | [75](75.md) | | `9041` | Zap Goal | [75](75.md) |
| `9321` | Nutzap | [61](61.md) | | `9321` | Nutzap | [61](61.md) |
@ -198,6 +203,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
| `10063` | User server list | [Blossom][blossom] | | `10063` | User server list | [Blossom][blossom] |
| `10096` | File storage server list | [96](96.md) | | `10096` | File storage server list | [96](96.md) |
| `10166` | Relay Monitor Announcement | [66](66.md) | | `10166` | Relay Monitor Announcement | [66](66.md) |
| `10312` | Room Presence | [53](53.md) |
| `13194` | Wallet Info | [47](47.md) | | `13194` | Wallet Info | [47](47.md) |
| `17375` | Cashu Wallet Event | [60](60.md) | | `17375` | Cashu Wallet Event | [60](60.md) |
| `21000` | Lightning Pub RPC | [Lightning.Pub][lnpub] | | `21000` | Lightning Pub RPC | [Lightning.Pub][lnpub] |
@ -231,6 +237,8 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
| `30166` | Relay Discovery | [66](66.md) | | `30166` | Relay Discovery | [66](66.md) |
| `30267` | App curation sets | [51](51.md) | | `30267` | App curation sets | [51](51.md) |
| `30311` | Live Event | [53](53.md) | | `30311` | Live Event | [53](53.md) |
| `30312` | Interactive Room | [53](53.md) |
| `30313` | Conference Event | [53](53.md) |
| `30315` | User Statuses | [38](38.md) | | `30315` | User Statuses | [38](38.md) |
| `30388` | Slide Set | [Corny Chat][cornychat-slideset] | | `30388` | Slide Set | [Corny Chat][cornychat-slideset] |
| `30402` | Classified Listing | [99](99.md) | | `30402` | Classified Listing | [99](99.md) |
@ -247,9 +255,12 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
| `31924` | Calendar | [52](52.md) | | `31924` | Calendar | [52](52.md) |
| `31925` | Calendar Event RSVP | [52](52.md) | | `31925` | Calendar Event RSVP | [52](52.md) |
| `31989` | Handler recommendation | [89](89.md) | | `31989` | Handler recommendation | [89](89.md) |
| `31990` | Handler information | [89](89.md) | | | `31990` | Handler information | [89](89.md) |
| `32267` | Software Application | | | | `32267` | Software Application | |
| `34550` | Community Definition | [72](72.md) | | `34550` | Community Definition | [72](72.md) |
| `38172` | Cashu Mint Announcement | [87](87.md) |
| `38173` | Fedimint Announcement | [87](87.md) |
| `37516` | Geocache listing | [geocaching](geocaching) |
| `38383` | Peer-to-peer Order events | [69](69.md) | | `38383` | Peer-to-peer Order events | [69](69.md) |
| `39000-9` | Group metadata events | [29](29.md) | | `39000-9` | Group metadata events | [29](29.md) |
| `39089` | Starter packs | [51](51.md) | | `39089` | Starter packs | [51](51.md) |
@ -267,6 +278,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
[NKBIP-03]: https://wikistr.com/nkbip-03*fd208ee8c8f283780a9552896e4823cc9dc6bfd442063889577106940fd927c1 [NKBIP-03]: https://wikistr.com/nkbip-03*fd208ee8c8f283780a9552896e4823cc9dc6bfd442063889577106940fd927c1
[blossom]: https://github.com/hzrd149/blossom [blossom]: https://github.com/hzrd149/blossom
[Tidal-nostr]: https://wikistr.com/tidal-nostr [Tidal-nostr]: https://wikistr.com/tidal-nostr
[geocaching]: https://nostrhub.io/naddr1qvzqqqrcvypzppscgyy746fhmrt0nq955z6xmf80pkvrat0yq0hpknqtd00z8z68qqgkwet0vdskx6rfdenj6etkv4h8guc6gs5y5
## Message types ## Message types