diff --git a/22.md b/22.md index 2172519e23..5ab7e7321e 100644 --- a/22.md +++ b/22.md @@ -24,6 +24,8 @@ The event `created_at` field is just a unix timestamp and can be set to a time i [Replaceable events](16.md#replaceable-events) can behave rather unexpectedly if the user wrote them - or tried to write them - with a wrong system clock. Persisting an update with a backdated system now would result in the update not getting persisted without a notification and if they did the last update with a forward dated system, they will again fail to do another update with the now correct time. +[Copied events](81.md) are exceptions. They are expected to have `created_at` past date values. + A wide adoption of this NIP could create a better user experience as it would decrease the amount of events that appear wildly out of order or even from impossible dates in the distant past or future. Keep in mind that there is a use case where a user migrates their old posts onto a new relay. If a relay rejects events that were not recently created, it cannot serve this use case. diff --git a/81.md b/81.md new file mode 100644 index 0000000000..dfc394377e --- /dev/null +++ b/81.md @@ -0,0 +1,50 @@ +NIP-81 +====== + +Event Copy +---------- + +`draft` `optional` `author:arthurfranca` + +An event of `kind 1006` is used to copy any event from another author (except other copies). A copy +allows its creator to keep content around even when the original gets deleted. + +The `.content` of a copy event SHOULD be the stringified JSON of the whole original event, +optionally with extra fields inside a `.meta` key. +The `.content` MAY be empty to represent a deleted event. + +The copy event's `created_at` field MUST be identical to the original one to keep same sort order. +A `copied_at` tag MAY be added as the moment of the copy. + +The copy event SHOULD include the following tags so to make them queriable: + +- Capital `I` tag with original event's `id`; +- Capital `P` tag with original event's `pubkey`; +- Capital `K` tag with original event's `kind`; +- All original event's single-letter tags. + +`I`, `P` and `K` tags are reserved. They cannot be used by any other event kind. + +## Use Cases + +It is useful for any case one would benefit for owning someone else's event. + +Clients can request both originals and copies to increase the chance of finding the events +they are interested in. + +# Relay Event Re-publishing + +It enables storing someone else's events while consuming one own event quota, +in case of relays that forbids different author event publishing. +The user can later delete it to free some quota. + +# DM Inbox + +The benefit comes from being able to soft-delete a received DM (by using a copy with empty `.content`), +making it possible to control one own inbox. Received DMs without copies may be considered unread. + +# Group Moderation + +A group admin may soft-delete events by using a copy with an empty content. +It can use a copy's `.meta.moderation.content` to take out curse words from the original content. +Clients should request group messages along with admin copies. diff --git a/README.md b/README.md index 94e945c583..6d068b508a 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos | `42` | Channel Message | [28](28.md) | | `43` | Channel Hide Message | [28](28.md) | | `44` | Channel Mute User | [28](28.md) | +| `1006` | Event Copy | [81](81.md) | | `1063` | File Metadata | [94](94.md) | | `1984` | Reporting | [56](56.md) | | `9734` | Zap Request | [57](57.md) | @@ -149,6 +150,9 @@ When experimenting with kinds, keep in mind the classification introduced by [NI | `p` | pubkey (hex) | relay URL | [1](01.md) | | `r` | a reference (URL, etc) | -- | [12](12.md) | | `t` | hashtag | -- | [12](12.md) | +| `I` | (reserved) copied id | -- | [81](81.md) | +| `P` | (reserved) copied pubkey | -- | [81](81.md) | +| `K` | (reserved) copied kind | -- | [81](81.md) | | `amount` | millisats | -- | [57](57.md) | | `bolt11` | `bolt11` invoice | -- | [57](57.md) | | `challenge` | challenge string | -- | [42](42.md) |