Compare commits
11 Commits
d24b54fe85
...
5e362efce2
Author | SHA1 | Date |
---|---|---|
|
5e362efce2 | |
|
7dec812f99 | |
|
739f3c5263 | |
|
8830525250 | |
|
b224b0ecb8 | |
|
ce130e504a | |
|
0b45265a93 | |
|
e33f5cd38f | |
|
0595d438aa | |
|
f30a43bd37 | |
|
faba3f016d |
4
03.md
4
03.md
|
@ -12,8 +12,8 @@ This NIP defines an event with `kind:1040` that can contain an [OpenTimestamps](
|
|||
{
|
||||
"kind": 1040
|
||||
"tags": [
|
||||
["e", <event-id>, <relay-url>],
|
||||
["alt", "opentimestamps attestation"]
|
||||
["e", <target-event-id>, <relay-url>],
|
||||
["k", "<target-event-kind>"]
|
||||
],
|
||||
"content": <base64-encoded OTS file data>
|
||||
}
|
||||
|
|
3
18.md
3
18.md
|
@ -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
|
||||
`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.
|
||||
|
||||
|
|
2
21.md
2
21.md
|
@ -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
|
||||
|
||||
`<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>
|
||||
|
|
8
22.md
8
22.md
|
@ -143,13 +143,13 @@ A comment on a website's url looks like this:
|
|||
"tags": [
|
||||
// referencing the root url
|
||||
["I", "https://abc.com/articles/1"],
|
||||
// the root "kind": for an url, the kind is its domain
|
||||
["K", "https://abc.com"],
|
||||
// the root "kind": for an url
|
||||
["K", "web"],
|
||||
|
||||
// the parent reference (same as root for top-level comments)
|
||||
["i", "https://abc.com/articles/1"],
|
||||
// the parent "kind": for an url, the kind is its domain
|
||||
["k", "https://abc.com"]
|
||||
// the parent "kind": for an url
|
||||
["k", "web"]
|
||||
]
|
||||
// other fields
|
||||
}
|
||||
|
|
13
24.md
13
24.md
|
@ -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.
|
||||
|
||||
kind 0
|
||||
======
|
||||
### kind 0
|
||||
|
||||
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.
|
||||
- `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:
|
||||
|
||||
- `displayName`: use `display_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:
|
||||
|
||||
### 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.
|
||||
|
||||
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:
|
||||
|
||||
|
|
2
34.md
2
34.md
|
@ -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>"]
|
||||
|
||||
// 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
|
||||
["merge-commit", "<merge-commit-id>"]
|
||||
["r", "<merge-commit-id>"]
|
||||
|
|
153
47.md
153
47.md
|
@ -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.
|
||||
|
||||
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
|
||||
|
||||
There are four event kinds:
|
||||
|
||||
- `NIP-47 info event`: 13194
|
||||
- `NIP-47 request`: 23194
|
||||
- `NIP-47 response`: 23195
|
||||
- `NIP-47 notification event`: 23196
|
||||
- `NIP-47 notification event`: 23197 (23196 for backwards compatibility with NIP-04)
|
||||
|
||||
### 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`.
|
||||
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
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:
|
||||
```jsonc
|
||||
**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
|
||||
`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
|
||||
"params": { // params, object
|
||||
"invoice": "lnbc50n1..." // command-related data
|
||||
}
|
||||
"kind" 23194,
|
||||
"tags": [
|
||||
["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:
|
||||
```jsonc
|
||||
Example response:
|
||||
|
||||
```js
|
||||
{
|
||||
"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
|
||||
}
|
||||
"kind" 23195,
|
||||
"tags": [
|
||||
["p", "03..." ] // public key of the requesting client app
|
||||
["e", "1234"] // id of the request event this is responding to
|
||||
// ...
|
||||
],
|
||||
"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
|
||||
|
||||
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
|
||||
{
|
||||
|
@ -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
|
||||
- `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.
|
||||
- `UNAUTHORIZED`: This public key has no wallet connected.
|
||||
- `INTERNAL`: An internal error.
|
||||
- `UNSUPPORTED_ENCRYPTION`: The encryption type of the request is not supported by the wallet service.
|
||||
- `OTHER`: Other error.
|
||||
|
||||
## Nostr Wallet Connect URI
|
||||
|
@ -295,6 +335,7 @@ Response:
|
|||
"result_type": "make_invoice",
|
||||
"result": {
|
||||
"type": "incoming", // "incoming" for invoices, "outgoing" for payments
|
||||
"state": "pending",
|
||||
"invoice": "string", // encoded invoice, optional
|
||||
"description": "string", // invoice's description, optional
|
||||
"description_hash": "string", // invoice's description hash, optional
|
||||
|
@ -328,6 +369,7 @@ Response:
|
|||
"result_type": "lookup_invoice",
|
||||
"result": {
|
||||
"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
|
||||
"description": "string", // invoice's description, optional
|
||||
"description_hash": "string", // invoice's description hash, optional
|
||||
|
@ -376,6 +418,7 @@ Response:
|
|||
"transactions": [
|
||||
{
|
||||
"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
|
||||
"description": "string", // invoice's description, optional
|
||||
"description_hash": "string", // invoice's description hash, optional
|
||||
|
@ -452,6 +495,7 @@ Notification:
|
|||
"notification_type": "payment_received",
|
||||
"notification": {
|
||||
"type": "incoming",
|
||||
"state": "settled",
|
||||
"invoice": "string", // encoded invoice
|
||||
"description": "string", // invoice's description, optional
|
||||
"description_hash": "string", // invoice's description hash, optional
|
||||
|
@ -477,6 +521,7 @@ Notification:
|
|||
"notification_type": "payment_sent",
|
||||
"notification": {
|
||||
"type": "outgoing",
|
||||
"state": "settled",
|
||||
"invoice": "string", // encoded invoice
|
||||
"description": "string", // invoice's description, 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.
|
||||
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
|
||||
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,
|
||||
"kind": 13194,
|
||||
"tags": [
|
||||
[ "encryption", "nip44_v2 nip04" ],
|
||||
[
|
||||
"notifications",
|
||||
"payment_received payment_sent"
|
||||
|
|
9
52.md
9
52.md
|
@ -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
|
||||
* `t` (optional, repeated) hashtag to categorize calendar event
|
||||
* `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:
|
||||
|
||||
|
@ -32,6 +33,12 @@ The following tags are deprecated:
|
|||
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
* `d` (required) universally unique identifier. Generated by the client creating the calendar.
|
||||
|
|
5
57.md
5
57.md
|
@ -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.
|
||||
- `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:
|
||||
|
||||
|
@ -49,7 +50,8 @@ Example:
|
|||
["amount", "21000"],
|
||||
["lnurl", "lnurl1dp68gurn8ghj7um5v93kketj9ehx2amn9uh8wetvdskkkmn0wahz7mrww4excup0dajx2mrv92x9xp"],
|
||||
["p", "04c915daefee38317fa734444acee390a8269fe5810b2241e5e6dd343dfbecc9"],
|
||||
["e", "9ae37aa68f48645127299e9453eb5d908a0cbb6058ff340d528ed4d37c8994fb"]
|
||||
["e", "9ae37aa68f48645127299e9453eb5d908a0cbb6058ff340d528ed4d37c8994fb"],
|
||||
["k", "1"]
|
||||
],
|
||||
"pubkey": "97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322",
|
||||
"created_at": 1679673265,
|
||||
|
@ -151,6 +153,7 @@ Example `zap receipt`:
|
|||
["p", "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245"],
|
||||
["P", "97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322"],
|
||||
["e", "3624762a1274dd9636e0c552b53086d70bc88c165bc4dc0f9e836a1eaf86c3b8"],
|
||||
["k", "1"],
|
||||
["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\"]]}"],
|
||||
["preimage", "5d006d2cf1e73c7148e7519a4c68adc81642ce0e25a432b2434c99f97344c15f"]
|
||||
|
|
1
61.md
1
61.md
|
@ -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\\\"}]\"}" ],
|
||||
[ "u", "https://stablenut.umint.cash" ],
|
||||
[ "e", "<nutzapped-event-id>", "<relay-hint>" ],
|
||||
[ "k", "<nutzapped-kind>"],
|
||||
[ "p", "e9fbced3a42dcf551486650cc752ab354347dd413b307484e4fd1818ab53f991" ], // recipient of nutzap
|
||||
]
|
||||
}
|
||||
|
|
217
66.md
217
66.md
|
@ -6,135 +6,44 @@ Relay Discovery and Liveness Monitoring
|
|||
|
||||
`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
|
||||
{
|
||||
"kind": 30166,
|
||||
"created_at": 1722173222,
|
||||
"content": "{}",
|
||||
"tags": [
|
||||
[ "d", "wss://somerelay.abc/" ]
|
||||
],
|
||||
"pubkey": "<pubkey>",
|
||||
"sig": "<signature>",
|
||||
"id": "<eventid>"
|
||||
}
|
||||
```
|
||||
`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.
|
||||
|
||||
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
|
||||
`NIP-66` defines two (2) event kinds, `30166` and `10166`
|
||||
`content` MAY include the stringified JSON of the relay's NIP-11 informational document.
|
||||
|
||||
| kind | name | description |
|
||||
|-------|----------------------------|-----------------------------------------------------------------------------------------|
|
||||
| [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_ |
|
||||
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.
|
||||
|
||||
## Ontology
|
||||
- `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.
|
||||
Other tags include:
|
||||
|
||||
## `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
|
||||
`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.
|
||||
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"]]`.
|
||||
|
||||
### Purpose
|
||||
Discovery of relays over nostr.
|
||||
Example:
|
||||
|
||||
### 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
|
||||
{
|
||||
"id": "<eventid>",
|
||||
"pubkey": "<monitor's pubkey>",
|
||||
"created_at": "<created_at [some recent date ...]>",
|
||||
"signature": "<signature>",
|
||||
"content": "{}",
|
||||
"content": "<optional nip 11 document>",
|
||||
"kind": 30166,
|
||||
"tags": [
|
||||
["d","wss://some.relay/"],
|
||||
|
@ -144,7 +53,6 @@ _Relay was online, and you can filter on a number of different tags_
|
|||
["R", "!payment"],
|
||||
["R", "auth"],
|
||||
["g", "ww8p1r4t8"],
|
||||
["p", "somehexkey..."],
|
||||
["l", "en", "ISO-639-1"],
|
||||
["t", "nsfw" ],
|
||||
["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
|
||||
`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.
|
||||
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.
|
||||
|
||||
### Purpose
|
||||
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.
|
||||
Tags include:
|
||||
|
||||
### 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
|
||||
{
|
||||
"id": "<eventid>",
|
||||
|
@ -210,45 +83,17 @@ Monitors **SHOULD** have the following
|
|||
"signature": "<signature>",
|
||||
"content": "",
|
||||
"tags": [
|
||||
|
||||
[ "timeout", "open", "5000" ],
|
||||
[ "timeout", "read", "3000" ],
|
||||
[ "timeout", "write", "3000" ],
|
||||
[ "timeout", "nip11", "3000" ],
|
||||
|
||||
[ "frequency", "3600" ],
|
||||
|
||||
[ "c", "ws" ],
|
||||
[ "c", "nip11" ],
|
||||
[ "c", "ssl" ],
|
||||
[ "c", "dns" ],
|
||||
[ "c", "geo" ]
|
||||
|
||||
[ "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.
|
||||
|
|
|
@ -175,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) |
|
||||
| `7375` | Cashu Wallet Tokens | [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) |
|
||||
| `9041` | Zap Goal | [75](75.md) |
|
||||
| `9321` | Nutzap | [61](61.md) |
|
||||
|
@ -258,6 +260,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
|
|||
| `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) |
|
||||
| `39000-9` | Group metadata events | [29](29.md) |
|
||||
| `39089` | Starter packs | [51](51.md) |
|
||||
|
@ -275,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
|
||||
[blossom]: https://github.com/hzrd149/blossom
|
||||
[Tidal-nostr]: https://wikistr.com/tidal-nostr
|
||||
[geocaching]: https://nostrhub.io/naddr1qvzqqqrcvypzppscgyy746fhmrt0nq955z6xmf80pkvrat0yq0hpknqtd00z8z68qqgkwet0vdskx6rfdenj6etkv4h8guc6gs5y5
|
||||
|
||||
## Message types
|
||||
|
||||
|
|
Loading…
Reference in New Issue