Compare commits

...

10 Commits

Author SHA1 Message Date
Braydon Fuller ba2379e3b7
Merge beaa4f6971 into 7dec812f99 2025-08-12 22:26:14 +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
Braydon Fuller beaa4f6971 Update specification after second round of implementation. 2024-09-11 09:36:50 -07:00
Braydon Fuller 2a88430155 Simplify and add user metadata attestations. 2024-09-10 07:50:47 -07:00
Braydon Fuller 01bb28afc7 Update specification after first round of implementation. 2024-09-08 15:20:41 -07:00
Braydon 3fffa43f0c Initial commit of Key Migration and Revocation NIP. 2024-08-28 11:35:17 -07:00
9 changed files with 180 additions and 18 deletions

4
03.md
View File

@ -12,8 +12,8 @@ This NIP defines an event with `kind:1040` that can contain an [OpenTimestamps](
{
"kind": 1040
"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:

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
]
}

153
xx.md Normal file
View File

@ -0,0 +1,153 @@
NIP-X
=====
Key Revocation and Migration
------
`draft` `optional`
This NIP defines a protocol for clients and relays to gracefully recovery from a compromised private key.
At a minimum this includes the revocation of a private key. Clients give warning that the key is compromised. Relays and clients reject future events from a revoked key and may delete existing events.
Also defined is a protocol for a user to be able to remember an associated public key for another user. In the event that a private key of the other user is compromised, the user is able to identity who it was and how to go about recovering from the compromise. This includes an ability to remember the original name, NIP-05 identification, website, migration keys and other associated metadata. Client implementations can provide various strategies to help that recovery, starting as simple as displaying that the key has been compromised.
There are two new events introduced:
* [Key Revocation](#key-revocation-event)
* [User Metadata Attestation](#user-metadata-attestation-event)
There is one new optional field (`migration_pubkeys`) for a user's metadata (`kind 0`):
* [Migration Keys](#migration-keys)
## Key Revocation Event
This is a regular event with kind `50`. It will revoke a public key _(it has been compromised)_ and stop future events from the key _(as determined as after the event was received)_. It will also provide a means to inform followers of the compromise and suggest a successor public key to follow.
```js
{
"kind": 50,
"pubkey": "<user-pubkey>",
"tags": [
["successor-key", "<successor-pubkey>"],
["key-revocation"]
],
"content": "<optional-comment>"
}
```
* The `key-revocation` tag MUST be included, once and without a value.
* There MUST NOT be multiple `successor-key` tags or multiple values.
### Event Handling for Clients
For a client, this event is a revocation with a suggestion for a migration to a successor public key. The revocation SHOULD be automatic. The migration, if it is provided, SHOULD NOT be automatic and MAY be presented and verified by the user to accept or reject the migration key change.
#### Key Revocation
* Upon a valid key revocation:
* All events SHOULD display a warning that the event is from a revoked public key.
* A user's profile SHOULD display a warning that the key has been compromised.
* All events of a revoked public key MAY be deleted, this MAY be after a duration of time depending on the client or preferences.
#### Key Migration
* If a user has made a prior _User Metadata Attestation_:
* The user interface MAY display the original name, NIP-05, migration keys and other user metadata that has been attested.
* The user interface MAY provide a means to accept or reject a suggested key migration. This can include using NIP-05, migration keys _(with matching signatures)_ and/or a social graph of those the user follows that are now following the suggested successor public key.
* Upon the user accepting a suggested successor key:
* The _predecessor public key_ SHOULD be unfollowed and the _successor public key_ SHOULD be followed.
* The _predecessor public key_ SHOULD be added to a mute list.
### Event Handling for Relays
For a relay, this event is a key revocation.
#### Key Revocation
* Upon a valid key revocation:
* All future events _(as determined when it was received)_ of a revoked public key MUST be rejected, except for another _Key Revocation Event_. This is to ensure that if a key is compromised and a fraudulent event is made, an honest event can also be made and broadcast.
* All events of a revoked public key MAY be deleted. The time-frame that events are deleted MAY be defined by an agreed upon terms between client and relay.
* For denial-of-service mitigation, a relay MAY require proof-of-work, a small fee or another solution to continue to write _Key Revocation Events_. This MAY be determined by the terms agreed upon by the client and relay.
## User Metadata Attestation Event
This is a parameterized replaceable event with kind `30050`. This is an attestation for another user's metadata (`kind 0`). This will help a user remember what public key is associated with what `display_name`, `nip05`, `website` and other metadata (should that `kind 0` event be compromised in the future). It can also attest to a newly defined `migration_pubkeys` field that could be useful to be able to identify a user. The attestation can be _public_ or _private_.
Public:
```js
{
"kind": 30050,
"pubkey": "<user-pubkey>",
"tags": [
["d", "<pubkey-of-friend>"],
["p", "<pubkey-of-friend>"],
["p", "<optional-predecessor-pubkey-of-friend>"],
["attestation", JSONStringify({
"pubkey": "<pubkey-of-friend>"
"tags": [<attested-to-tags>],
"content": {
"<attested-key>": "<attested-value>",
"<attested-key>": "<attested-value>"
}
})]
],
"content": ""
}
```
Private:
```js
"kind": 30050,
"pubkey": "<user-pubkey>",
"tags": [
["d", "<encrypted-and-hashed-pubkey"]
],
"content": Nip44Encrypt(JSONStringify([
["p", "<pubkey-of-friend>"],
["attestation", JSONStringify({
"pubkey": "<pubkey-of-friend>"
"tags": [<attested-to-tags>],
"content": {
"<attested-key>": "<attested-value>",
"<attested-key>": "<attested-value>"
}
})]
]))
```
* For a _public_ attestation:
* The `d` tag and a `p` tag MUST include a public key for the attested to metadata.
* Another `p` tag SHOULD be included if there was a predecessor public key. This helps to inform other users of a link between the predecessor public and a successor public key.
* The `attestations` tag MUST include JSON stringified copy of the attested to event pubkey, tags and content of the `kind 0` event. It is a partial copy of the `kind 0` event.
* For a _private_ attestation:
* The `d` tag MUST be an encrypted and hashed version of the public key (hex encoding of a sha256 hash of an encrypted, with NIP-44, of the public key).
* The `p`, `metadata` and `attestations` tags, as the same as the public attestation, MUST be JSON stringified and NIP-44 encrypted in the content field.
## Migration Keys
This is a new field on a users metadata (`kind 0`) event with a key of `migration_keys`. Its purpose is to define a set of migration keys that can be used to help migrate to a successor key in the future. The event can assign anywhere from `1` to `n` migration keys. A threshold number of keys (`m` of `n`) can be assigned to verify this event.
The value should be as follows:
```js
[<threshold>, <migration-pubkey-1>, <migration-pubkey-2>]
```
* The array SHOULD be all strings, including the threshold.
* Clients MAY present a user interface to make an attestation, if this field is available on the metadata.
* Clients MAY use hardware devices and NIP-06 seed phrases to store the migration keys.
### Revocation Event Signing
A _Key Revocation Event_ MAY be signed with `m` of `n` of these migration keys. This can help assist the migration process for those that have previously attested to the `migration_keys`.
The following `migration-sigs` tag MAY be included:
```js
{
"kind": 50,
"tags": [
// other tags
["migration-sigs", "<index-0-sig", "<index-1-sig>", "<index-2-sig>"]
]
// other fields
}
```