Compare commits

...

26 Commits

Author SHA1 Message Date
monlovesmango 4639c7b9dc
Merge 118dfe62ee into 7dec812f99 2025-08-12 22:25:16 +00: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
fiatjaf_ 477e3dfd4d
add "mute" OK=false status for no-op ephemeral events (#1965) 2025-07-07 10:50:54 -03:00
fiatjaf 9afca6c4dc nip51: clarify kind:10012 description. 2025-07-03 19:45:38 -03:00
Gamma Markets 4eed6e8368
nip99 e-commerce use case extension (#1784) 2025-07-02 10:47:46 -07:00
Awiteb db3e3bddbe
nip34: change 'defaults' to 'is' in patch revision status description (#1964) 2025-07-02 08:15:12 -03:00
monlovesmango 118dfe62ee
add tag to filter condition
Co-authored-by: arthurfranca <arthur.a.franca@gmail.com>
2024-02-25 17:07:15 -06:00
monlovesmango 7ce58a7499 NIP43 auth delegation 2024-02-24 21:31:38 -06:00
21 changed files with 619 additions and 244 deletions

5
01.md
View File

@ -85,7 +85,7 @@ As a convention, all single-letter (only english alphabet letters: a-z, A-Z) key
### Kinds
Kinds specify how clients should interpret the meaning of each event and the other fields of each event (e.g. an `"r"` tag may have a meaning in an event of kind 1 and an entirely different meaning in an event of kind 10002). Each NIP may define the meaning of a set of kinds that weren't defined elsewhere. [NIP-10](10.md), for instance, specifies the `kind:1` text note for social media applications.
Kinds specify how clients should interpret the meaning of each event and the other fields of each event (e.g. an `"r"` tag may have a meaning in an event of kind 1 and an entirely different meaning in an event of kind 10002). Each NIP may define the meaning of a set of kinds that weren't defined elsewhere. [NIP-10](10.md), for instance, specifies the `kind:1` text note for social media applications.
This NIP defines one basic kind:
@ -170,8 +170,9 @@ This NIP defines no rules for how `NOTICE` messages should be sent or treated.
* `["OK", "b1a649ebe8...", false, "pow: difficulty 26 is less than 30"]`
* `["OK", "b1a649ebe8...", false, "restricted: not allowed to write."]`
* `["OK", "b1a649ebe8...", false, "error: could not connect to the database"]`
* `["OK", "b1a649ebe8...", false, "mute: no one was listening to your ephemeral event and it wasn't handled in any way, it was ignored"]`
- `CLOSED` messages MUST be sent in response to a `REQ` when the relay refuses to fulfill it. It can also be sent when a relay decides to kill a subscription on its side before a client has disconnected or sent a `CLOSE`. This message uses the same pattern of `OK` messages with the machine-readable prefix and human-readable message. Some examples:
* `["CLOSED", "sub1", "unsupported: filter contains unknown elements"]`
* `["CLOSED", "sub1", "error: could not connect to the database"]`
* `["CLOSED", "sub1", "error: shutting down idle subscription"]`
- The standardized machine-readable prefixes for `OK` and `CLOSED` are: `duplicate`, `pow`, `blocked`, `rate-limited`, `invalid`, `restricted`, and `error` for when none of that fits.
- The standardized machine-readable prefixes for `OK` and `CLOSED` are: `duplicate`, `pow`, `blocked`, `rate-limited`, `invalid`, `restricted`, `mute` and `error` for when none of that fits.

4
03.md
View File

@ -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
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
`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
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
`<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
View File

@ -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
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.
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
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.
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 reaction event MAY include a `k` tag with the stringified kind number of the reacted event as its value.

4
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>"]
// 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>"]
@ -163,7 +163,7 @@ Root Patches and Issues have a Status that defaults to 'Open' and can be set by
The most recent Status event (by `created_at` date) from either the issue/patch author or a maintainer is considered valid.
The Status of a patch-revision defaults to either that of the root-patch, or `1632` (_Closed_) if the root-patch's Status is `1631` (_Applied/Merged_) and the patch-revision isn't tagged in the `1631` (_Applied/Merged_) event.
The Status of a patch-revision is to either that of the root-patch, or `1632` (_Closed_) if the root-patch's Status is `1631` (_Applied/Merged_) and the patch-revision isn't tagged in the `1631` (_Applied/Merged_) event.
## Possible things to be added later

160
43.md Normal file
View File

@ -0,0 +1,160 @@
NIP-43
======
Delegated Authentication of Clients to Relays
-----------------------------------
`draft` `optional`
This NIP defines how authentication can be delegated so that a user or client can authenticate with a relay using other keypairs.
## Motivation
A user may want to delegate authentication to another keypair in order to selectively grant access to relay restricted resources. For example,
- A user may want to login to clients with a NostrConnect remote signer over an authenticated relay that requires membership to send ephemeral events
- A user may want to authorize others to access a particular [NIP-71 Restricted Event](https://github.com/nostr-protocol/nips/blob/master/71.md) in exchange for payment or other services
- A user may want to create subscription services to certain kinds of [NIP-71 Restricted Event](https://github.com/nostr-protocol/nips/blob/master/71.md) in exchange for payment or other services
## Terminology
- **delegator**: The user who would like to delegate authentication to another key pair.
- **delegatee**: The alternate key pair the user has delegated authentication to.
## Definitions
### 'auth-delegation' tag
This NIP introduces a new tag: `auth-delegation` which is formatted as follows:
```json
[
"auth-delegation",
<delegator pubkey>,
<delegation conditions>,
<authentication delegation token: 64-byte Schnorr signature of the sha256 hash of the authentication delegation string>
]
```
This tag will only be used on events of kind `22242 - Client Authentication` as defined in [NIP-42 Authentication of Clients to Relays](https://github.com/nostr-protocol/nips/blob/master/42.md). Each `Client Authentication` event MAY contain multiple `auth-delegation` tags to allow for different authentication delegation conditions for a single key pair.
### Authentication Delegation Token
The **authentication delegation token** should be a 64-byte Schnorr signature of the sha256 hash of the following string:
```
nostr|auth-delegation|<pubkey of delegatee>|<delegation conditions>
```
### Delegation Conditions
The delegation conditions define the scope of `REQ` filters the delegatee has been allowed access to by the delgator. The delegation conditions are comprised of an expiration condition, a mode condition, a filter condition, and a relay condition which are concatenated together with `;`.
#### Expiration Condition
The expiration condition is REQUIRED. The authentication delegation token is invalid if the expiration condition is missing. It is denoted as a unix timestamp in seconds.
The timestamp is the time at which this particular authentication delegation token expires and will no longer be valid. The timestamp is to be compared to the relay's current local time and NOT the `created_at` field on events.
#### Mode Condition
The mode condition is OPTIONAL. It indicates whether the delegatee should be fully authenticated as the delegator and granted all access and priveleges that are granted to the delegator. It is denoted by a single integer value:
- `0`: Login - (DEFAULT) delegatee should be fully authenticated as the delegator
- `1`: Restricted Event Permission - delegatee should not be fully authenticated as the delegator and access is limited by the filter condition
If mode condition is set to `0` it is STRONGLY RECOMMENDED that the expiration condition is set to no more than one day in the future.
#### Filter Condition
The filter condition is OPTIONAL and only applies if the mode condition is set to `1`. It defines what a `REQ` sent by a delegatee can filter for within [NIP-71 Restricted Events](https://github.com/nostr-protocol/nips/blob/master/71.md). The filter condition is a JSON stringified filter object as defined in [NIP-01](https://github.com/nostr-protocol/nips/blob/master/01.md), however only the following attributes are valid within the filter condition:
- `"ids"`
- `"kinds"`
- `"since"`
- `"until"`
- `"#<single-letter (a-zA-Z)>"`
The filter condition ALWAYS IMPLICITLY includes the filter criteria `"authors": ["${delegator pubkey}"]`, even if the filter condition is omitted altogether.
Any `REQ` filter sent by the delegatee using an authentication delegation token MUST BE narrower in scope than the filter condition in order for the token to be valid for that `REQ`. In order for an authentication delegation token to be valid for a `REQ` filter, all filter condition attributes must be found within the `REQ` filter. The `REQ` filter is allowed to have additional attributes not contained in the filter condition that add specificity.
#### Relay Condition
The relay condition is OPTIONAL. It defines which relays the authentication delegation token is valid for. It is denoted as an array of relay URL strings. If this condition is ommited it is assumed that the authentication delegation token is valid for all relays.
#### Examples
- `1707409439;;;` // delegatee can query all restricted events published by the delegator on any relay until Feb 08 2024 16:23:59 GMT
- `9999999999;;{"ids": ["123abc"]};["wss://example.com", "wss://example2.com"]` // delegatee can query for event id "123abc" (published by delegator) on relays "wss://example.com" and "wss://example2.com" for forever
- `1707409439;1;;` // delegatee can be fully authenticated as delegator on any relay until Feb 08 2024 16:23:59 GMT
## Application
Delegated authentication allows delegatees to use [NIP-42 Authentication of Clients to Relays](https://github.com/nostr-protocol/nips/blob/master/42.md) with an `auth-delegation` tag to:
- authenticate as or
- gain access to [NIP-71 Restricted Events](https://github.com/nostr-protocol/nips/blob/master/71.md) owned by
the delegator.
The method in which the delegatee obtains the authentication delegation token is not prescribed here and should be detailed in any new specification that employs this NIP. This has been intentionally left unspecified as the range of applications of this NIP are large and may have varying requirements or flows.
When using delegated authentication, the delegatee will respond to authentication challenges with a authentication event that has an additional `auth-delegation` tag. Once verified, the delegatee will be granted access according to the conditions of the authentication delegation token.
If the filter condition is employed in the authentication delegation conditions the relay SHOULD cache the conditioins for the duration of the authenticated session and ensure that all delegatee `REQ` filters fall within the granted access.
## Example
```
# Delegator:
privkey: ee35e8bb71131c02c1d7e73231daa48e9953d329a4b701f7133c8f46dd21139c
pubkey: 8e0d3d3eb2881ec137a11debe736a9086715a8c8beeeda615780064d68bc25dd
# Delegatee:
privkey: 777e4f60b4aa87937e13acc84f7abcc3c93cc035cb4c1e9f7a9086dd78fffce1
pubkey: 477318cfb5427b9cfc66a9fa376150c1ddbc62115ae27cef72417eb959691396
```
Authentication delegation string to grant delegatee (477318cf) permission to authentication as delegator (8e0d3d3e) until Feb 08 2024 16:23:59 GMT.
```json
nostr|auth-delegation|477318cfb5427b9cfc66a9fa376150c1ddbc62115ae27cef72417eb959691396|1707409439;1;;
```
The delegator (8e0d3d3e) then signs a SHA256 hash of the above authentication delegation string, the result of which is the authentication delegation token:
```
22f12761e0d0311c29341b6c58e2ddfb66ef8895bf7c3c1456dcf5a1d4a1b22b4461d53b47142a516c768abd39366a57c24b4045673a979553201b2f41674c68
```
The delegatee (477318cf) can now construct an authentication event on behalf of the delegator (8e0d3d3e). The delegatee then signs the authentication event with its own private key and sends it in an `AUTH` message.
```json
{
"pubkey": "477318cfb5427b9cfc66a9fa376150c1ddbc62115ae27cef72417eb959691396",
"created_at": 1707408434,
"kind": 22242,
"tags": [
["relay", "wss://relay.example.com/"],
["challenge", "challengestringhere"]
[
"auth-delegation",
"8e0d3d3eb2881ec137a11debe736a9086715a8c8beeeda615780064d68bc25dd",
"1707409439;1;;",
"22f12761e0d0311c29341b6c58e2ddfb66ef8895bf7c3c1456dcf5a1d4a1b22b4461d53b47142a516c768abd39366a57c24b4045673a979553201b2f41674c68"
]
],
...
}
```
## Verification
To verify delegated authentication events, relays must ensure:
- all of the requirements in [NIP-42 Authentication Event Verification](https://github.com/nostr-protocol/nips/blob/master/42.md#signed-event-verification) are satisfied
- the expiration condition is in the future
- the relay condition is omitted OR the relay condition contains the relay's URL
- URL normalization techniques can be applied. For most cases just checking if the domain name is correct should be enough.
- validate the authentication delegation token to be the delegator's 64-byte Schnorr signature of the sha256 hash of the authentication delegation token string

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.
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"

2
51.md
View File

@ -32,7 +32,7 @@ For example, _mute list_ can contain the public keys of spammers and bad actors
| Blocked relays | 10006 | relays clients should never connect to | `"relay"` (relay URLs) |
| Search relays | 10007 | relays clients should use when performing search queries | `"relay"` (relay URLs) |
| Simple groups | 10009 | [NIP-29](29.md) groups the user is in | `"group"` ([NIP-29](29.md) group id + relay URL + optional group name), `"r"` for each relay in use |
| Favorite relays | 10012 | user favorite relays and pointers to relay sets | `"relay"` (relay URLs) and `"a"` (kind:30002 relay set) |
| Relay feeds | 10012 | user favorite browsable relays (and relay sets) | `"relay"` (relay URLs) and `"a"` (kind:30002 relay set) |
| Interests | 10015 | topics a user may be interested in and pointers | `"t"` (hashtags) and `"a"` (kind:30015 interest set) |
| Media follows | 10020 | multimedia (photos, short video) follow list | `"p"` (pubkeys -- with optional relay hint and petname) |
| Emojis | 10030 | user preferred emojis and pointers to emoji sets | `"emoji"` (see [NIP-30](30.md)) and `"a"` (kind:30030 emoji set) |

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
* `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
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.
- `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
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\\\"}]\"}" ],
[ "u", "https://stablenut.umint.cash" ],
[ "e", "<nutzapped-event-id>", "<relay-hint>" ],
[ "k", "<nutzapped-kind>"],
[ "p", "e9fbced3a42dcf551486650cc752ab354347dd413b307484e4fd1818ab53f991" ], // recipient of nutzap
]
}

225
66.md
View File

@ -6,137 +6,46 @@ 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": [
"tags": [
["d","wss://some.relay/"],
["n", "clearnet"],
["N", "40"],
@ -144,64 +53,28 @@ _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 ]
]
}
}
```
## `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>",
@ -209,46 +82,18 @@ Monitors **SHOULD** have the following
"created_at": "<created_at [some recent date ...]>",
"signature": "<signature>",
"content": "",
"tags": [
"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.

1
69.md
View File

@ -80,6 +80,7 @@ Currently implemented on the following platforms:
- [Mostro](https://github.com/MostroP2P/mostro)
- [@lnp2pBot](https://github.com/lnp2pBot/bot)
- [Robosats](https://github.com/RoboSats/robosats/pull/1362)
- [Peach Bitcoin](https://github.com/Peach2Peach/peach-nostr-announcer-bot)
## 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
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
{
"kind": 1,
"kind": 1111,
"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...
}
```
## 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
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": [...] }]]
```

2
99.md
View File

@ -8,7 +8,7 @@ Classified Listings
This NIP defines `kind:30402`: an addressable event to describe classified listings that list any arbitrary product, service, or other thing for sale or offer and includes enough structured metadata to make them useful.
The category of classifieds includes a very broad range of physical goods, services, work opportunities, rentals, free giveaways, personals, etc. and is distinct from the more strictly structured marketplaces defined in [NIP-15](15.md) that often sell many units of specific products through very specific channels.
The specification supports a broad range of use cases physical goods, services, work opportunities, rentals, free giveaways, personals, etc. To promote interoperability between clients implementing NIP-99 for e-commerce, you can find the extension proposal [here](https://github.com/GammaMarkets/market-spec/blob/main/spec.md) which standardizes the e-commerce use case while maintaining the specification's lightweight and flexible nature. While [NIP-15](15.md) provides a strictly structured marketplace specification, NIP-99 has emerged as a simpler and more flexible alternative.
The structure of these events is very similar to [NIP-23](23.md) long-form content events.

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-84: Highlights](84.md)
- [NIP-86: Relay Management API](86.md)
- [NIP-87: Ecash Mint Discoverability](87.md)
- [NIP-88: Polls](88.md)
- [NIP-89: Recommended Application Handlers](89.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-98: HTTP Auth](98.md)
- [NIP-99: Classified Listings](99.md)
- [NIP-A0: Voice Messages](A0.md)
- [NIP-B0: Web Bookmarks](B0.md)
- [NIP-B7: Blossom](B7.md)
- [NIP-C0: Code Snippets](C0.md)
- [NIP-C7: Chats](C7.md)
## Event Kinds
| kind | description | NIP |
| ------------- | ------------------------------- | -------------------------------------- |
| `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) |
| `1068` | Poll | [88](88.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) |
| `1337` | Code Snippet | [C0](C0.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) |
| `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) |
@ -198,6 +203,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
| `10063` | User server list | [Blossom][blossom] |
| `10096` | File storage server list | [96](96.md) |
| `10166` | Relay Monitor Announcement | [66](66.md) |
| `10312` | Room Presence | [53](53.md) |
| `13194` | Wallet Info | [47](47.md) |
| `17375` | Cashu Wallet Event | [60](60.md) |
| `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) |
| `30267` | App curation sets | [51](51.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) |
| `30388` | Slide Set | [Corny Chat][cornychat-slideset] |
| `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) |
| `31925` | Calendar Event RSVP | [52](52.md) |
| `31989` | Handler recommendation | [89](89.md) |
| `31990` | Handler information | [89](89.md) | |
| `32267` | Software Application | | |
| `31990` | Handler information | [89](89.md) |
| `32267` | Software Application | |
| `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) |
@ -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
[blossom]: https://github.com/hzrd149/blossom
[Tidal-nostr]: https://wikistr.com/tidal-nostr
[geocaching]: https://nostrhub.io/naddr1qvzqqqrcvypzppscgyy746fhmrt0nq955z6xmf80pkvrat0yq0hpknqtd00z8z68qqgkwet0vdskx6rfdenj6etkv4h8guc6gs5y5
## Message types