Many updates to 0A

This commit is contained in:
Mike Dilger 2025-01-03 09:08:50 +13:00
parent 1d1d76d13b
commit 4dc79e2687
No known key found for this signature in database
GPG Key ID: 47581A78D4329BA4

117
0A.md
View File

@ -4,16 +4,21 @@ NIP-0A
Follow List v2
--------------
An event with kind `103` means "follow list" which communicates the set of profiles
(represented by public keys) that the author is currently following.
An addressable event with kind `33000` means "follow list" which communicates the set of profiles (represented by public keys) that the author is currently following.
The term "following" is left undefined, see ["Uses"](#uses).
The public keys followed are specified in "p" tags.
Additional "np" tags are present only to help with synchronization as described below.
A "d" tag is specified to indicate the client (or possibly client installation) that created the event. This helps prevent cross-client clobbers.
The `.content` is not used.
## Tags
## Event Tags
### p tags
Each profile followed is reprsented in a "p" tag as follows:
@ -26,12 +31,11 @@ Where
* `pubkey` is the hex encoded public key of the profile
* `relay` is an optional relay where the `pubkey` is known to post, or an empty string
* `petname` is an optional petname that the author uses for the contact, or an empty string
* `timestamp` is the time when the entry was added
* `timestamp` is required and is the time when the entry was added to the list
## Removal of entries
### np tags
Entries are not removed. Instead they are converted into "np" entries and their
timestamp is updated to time they are considered removed.
"p" tag entries are not removed. Instead they are converted into "np" entries and their timestamp is updated to time that they were considered removed.
```
["np", <pubkey>, <relay>, <petname>, <timestamp2>]
@ -39,42 +43,93 @@ timestamp is updated to time they are considered removed.
Pubkeys MUST only be listed once in either a "p" tag or an "np" tag.
`p` means the person is counted as a contact. `np` means they are not counted as a contact
but the entry serves to help remember when they were removed so that conflicts can be
resolved.
`p` means the person is counted as a contact. `np` means they are not counted as a contact but the entry serves to help remember when they were removed so that conflicts can be resolved.
Note that `np` is not searchable on relays.
All contacts should be listed. These events are complete lists, they are not change sets.
## Updates and Publishing
## Owner Handling
### Ownership (your own list)
When you add a person, you find their entry and make sure the tag is "p" and not "np" and then you
update the timestamp to the current time. If missing, you create the entry.
When you add a person, you find their entry and make sure the tag is "p" and not "np" and then you update the timestamp to the current time. If missing, you create the entry.
When you remove a person, you find their entry and make sure the tag is "np" and not "p" and then
you update the timestamp to the current time. If missing, you create the entry.
When you remove a person, you find their entry and make sure the tag is "np" and not "p" and then you update the timestamp to the current time. If missing, you create the entry.
When you receive your own contact list (presumably created by a different client), you merge it
with your local one and if the data has changed you publish the result. See
[Merge Operation](#merge-operation) below.
When you receive your own follow list, you merge it with your local one and if the data has changed you publish the result. See [Merge Operation](#merge-operation) below. This resolves forks.
## Observers
Clients MUST read the latest follow list from a relay and merge it before writing a newer follow list to minimize the chance of clobbering.
A client that does not store any data can simply accept the latest contact list as probably
up to date.
### Observation (other people's lists)
Clients that do store data can instead choose to merge newer contact lists with the data they
already hold for the person's contacts that was created from previous events. The benefit of
doing this is only slight.
When dealing with other people's follow lists, nothing special needs to be done. These events are complete lists not change sets. The latest event represents the entire set of contacts. Clients do not need to search for and merge multiple events.
## Merge Operation
### Merge Operation
The merge operation is as follows: On a tag-by-tag basis, if only one event has a line for a pubkey, you accept that line. If both events have a line for that pubkey, you take the line with the largest timestamp.
### Relay to use
These events are published to the author's outbox relays. They do not need to be delivered to the inboxes of all the people tagged.
### Interaction with kind=3 events
Clients supporting this NIP should consider these newer events to supercede any kind-3 events by the same author. For their own user's follow list, they should NOT try to merge in data from updated kind-3 events. However if there is no kind-33000 event available, they may migrate from the latest kind-3 event to the first kind-33000 event.
Clients supporting this NIP should also publish kind-3 events that reflect the latest follow list whenever they publish kind-33000 events.
## Uses
### Feed Generation
Clients may use this list to generate feeds including only (or prefentially) these authors.
### Follow list backup
If one believes a relay will store their events for sufficient time, they can use this kind-33000 event to backup their following list and recover on a different device.
### Profile discovery and context augmentation
A client may rely on the kind-33000 event to display a list of followed people by profiles one is browsing; make lists of suggestions on who to follow based on the follow lists of other people one might be following or browsing; or show the data in other contexts.
### Relay sharing
A client may publish a follow list with good relays for each of their follows so other clients may use these to update their internal relay lists if needed, increasing censorship-resistance.
### Petname scheme
The data from these follow lists can be used by clients to construct local ["petname"](http://www.skyhunter.com/marcs/petnames/IntroPetNames.html) tables derived from other people's follow lists. This alleviates the need for global human-readable names. For example:
A user has an internal follow list that says
```json
[
["p", "21df6d143fb96c2ec9d63726bf9edc71", "", "erin"]
]
```
And receives two follow lists, one from `21df6d143fb96c2ec9d63726bf9edc71` that says
```json
[
["p", "a8bb3d884d5d90b413d9891fe4c4e46d", "", "david"]
]
```
and another from `a8bb3d884d5d90b413d9891fe4c4e46d` that says
```json
[
["p", "f57f54057d2a7af0efecc8b0b66f5708", "", "frank"]
]
```
When the user sees `21df6d143fb96c2ec9d63726bf9edc71` the client can show _erin_ instead;
When the user sees `a8bb3d884d5d90b413d9891fe4c4e46d` the client can show _david.erin_ instead;
When the user sees `f57f54057d2a7af0efecc8b0b66f5708` the client can show _frank.david.erin_ instead.
The merge operation is as follows: On a tag-by-tag basis, if only one event has a line for a pubkey,
you accept that line. If both events have a line for that pubkey, you take the line with the largest
timestamp.
## Rationale
This is functionally implements a Last-Write-Wins Element Set, which is a conflict-free replicated
data set with eventual consistency.
This functionally implements a Last-Write-Wins Element Set, which is a conflict-free replicated data set with eventual consistency.
We use replaceable events so that superceded events can be erased by relays. This brings back a per-relay clobbering issue, and so we use addressable events to limit such clobbering.