nips/0A.md
Mike Dilger a58e71bcab
more
2025-01-03 09:20:22 +13:00

5.8 KiB

NIP-0A

Synchronized Contact List

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

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.

Event Tags

p tags

Each profile followed is reprsented in a "p" tag as follows:

    ["p", <pubkey>, <relay>, <petname>, <timestamp>]

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 required and is the time when the entry was added to the list

np tags

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

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.

Note that np is not searchable on relays.

Updates and Publishing

Ownership (your own list)

When you add a person, you find their entry and if it is an "np", you change it to a "p" and update the timestamp to the current time. If missing, you create the "p" entry.

When you remove a person, you find their entry and if it is a "p", you change it to a "np" and update the timestamp to the current time. If missing, you create the "np" entry.

When you receive your own follow list, you merge it with any previous data you had. If the result changes the previous data you had, then you generate a new kind 33000 event and publish it. See Merge Operation below. This resolves forks.

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.

Observation (other people's lists)

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

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 shouldn't be delivered to the inboxes of all the people tagged.

Interaction with kind=3 events

This section is still being worked out

Ideas:

  • 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, if a kind-3 event is found that is newer than the newest kind-33000 event, clients can choose what to do about that (this is not an easy situation to resolve).
  • If there is no kind-33000 event available, clients should migrate data 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" 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

[
  ["p", "21df6d143fb96c2ec9d63726bf9edc71", "", "erin"]
]

And receives two follow lists, one from 21df6d143fb96c2ec9d63726bf9edc71 that says

[
  ["p", "a8bb3d884d5d90b413d9891fe4c4e46d", "", "david"]
]

and another from a8bb3d884d5d90b413d9891fe4c4e46d that says

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

Rationale

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.