From f5a22ce6e689aacab551eaaf00f832f43e8d816c Mon Sep 17 00:00:00 2001 From: Mike Dilger Date: Sun, 8 Dec 2024 09:47:54 +1300 Subject: [PATCH] Further detail after discussion and thought --- 0A.md | 62 ++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 13 deletions(-) diff --git a/0A.md b/0A.md index f41f901..d55fdba 100644 --- a/0A.md +++ b/0A.md @@ -4,26 +4,62 @@ NIP-0A Contact List v2 --------------- -This is an early draft, I'll flesh out details after discussion. +This is an early draft, I'm still working out the details. -Event tags would look like this: +## Events and Tags + +Events have tags like this for each contact: ``` - ["contact", "", "in", ""] - ["contact", "", "out", ""] + ["p", , , , ] + ["np", , , , ] ``` -Note that they are not 'p' tags, they don't need delivery to the person's INBOX. -But maybe they should be searchable to people can count their "followers". +`p` means the person is counted as a contact. `np` means they are not counted as a contact, but +we are just remembering when they were removed. Note that `np` is not searchable on relays. -When you add a person, you find their entry and change the last two fields to "in" and the current timestamp. +All contacts in the stated range should be listed. These events are complete lists, they are +not change sets. -When you remove a person, you find their entry and change the last two fields to "out" and the current timestamp. +## Owner Handling -When merging two events, you accept the entry with the largest timestamp. +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. -Note that we have to keep the "out" entries in case we later get an "in" entry dated earlier, we can -ignore such an add. +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. -This is functionally implements a Last-Write-Wins Element Set, which is a conflict-free replicated data set -with eventual consistency. +When you receive your own contact list (presumably created by a different client), you merge it +with your local one and publish the result. See [Merge Operation](#merge-operation) below. + +## Observers + +A client that does not store any data can simply accept the latest contact list. + +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. + +## 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. + +## Possible Splitting (TBD) + +There are four kinds (to be assigned): + + kind1 - all contacts whose public keys end with '0' - '3' + kind2 - all contacts whose public keys end with '4' - '7' + kind3 - all contacts whose public keys end with '8' - 'b' + kind4 - all contacts whose public keys end with 'c' - 'f' + +NOTE: We could actually continue to use kind3, as the 'timestamp' is additional and would +be ignored by current software, as would the 'np' tags. However that wouldn't allow splitting the +list into four chunks. + +## Rationale + +This is functionally implements a Last-Write-Wins Element Set, which is a conflict-free replicated +data set with eventual consistency.