Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nip-64: inbox model #1135

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions 64.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
NIP-64
======

Inbox model
-----------

`draft` `optional`

Suppose **Sarah** wants to subscribe to the notes **Walter** writes.

She must let Walter know she is following him. The first step is to find Walter's _inbox list_:

```jsonc
{
"kind": 10064,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inboxes and outboxes are both just relays in reality. Put another way, an outbox is a relay with a "write" marker, and an inbox is a relay with a "read" marker. So this nip can reuse kind 10002 events from NIP-65.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we gain nothing by conflating two different kinds of relays. Relays specified on kind 10002 are already there and already being used. Relays that implement this NIP would require a little bit of special behavior, so it's better to signal them properly.

Also I think it's very important that users announce that they support this NIP before others start engaging with them through it, having a special kind published serves that purpose.

Copy link
Contributor

@arthurfranca arthurfranca Mar 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's very important that users announce that they support this NIP

After #991 gets merged, you can pick a new relay usage flag to mean "nip64 relay" instead of introducing kind:10064. nip65 regular inbox relays may be enough don't know..nip11 may help client choose to load feed using nip64 while it can default to always send follow intent when user follows someone?

Copy link
Member Author

@fiatjaf fiatjaf Mar 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could use a different tag in kind 10002 if people prefer that, but I honestly thinks it's always better to use a different event kind when the use case and implementation contexts are different. It's not a super strong argument, more like a rule-of-thumb I came up with, same as I said in #686 (comment).

What I don't think we should do is just rely on the "read" relays that already exist in kind 10002, as they were not chosen to be there explicitly to deal with the inbox model specified in this NIP and won't be prepared to handle it.

"pubkey": "<walter>",
"tags": [
["relay", "wss://walter.inbox"]
]
}
```

Now Sarah can publish a `kind:6401` _follow intent_ to `wss://walter.inbox` tagging Walter:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use kind 10 and 11 events? #349

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These kinds are already being used by NIP-29.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

@alexgleason alexgleason Apr 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

6401 is within the reserved DVM Job Result range. 🤦


```jsonc
{
"kind": 6401,
"pubkey": "<sarah>"
"tags": [
["p", "<walter>"],
["relay", "wss://sarah.inbox"],
["relay", "wss://other.inbox"]
]
}
```

Sarah also publishes these to her own inbox relays (`wss://sarah.inbox` and `wss://other.inbox`) so they are aware.

From the Walter side, whenever he is about to publish a note, he downloads all the `kind:6401` events from his inbox relays and sends his note to all the relays he finds in these.

Whenever Sarah's inbox relay receive a note from Walter, they will know that Sarah is following him, so they index that note in a way that it is associated with Sarah. If the relays receive a note from someone else they can simply reject the note.

When Sarah turns on her client she will connect to her inbox relay, perform [NIP-42](42.md) `AUTH` and create a subscription that doesn't specify `"authors"` (for example, `["REQ", "_", {}]`). The relays, aware of who she is and who she is following, can deliver to her just Walter's notes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This breaks how absent authors filter works.

Instead of NIP-42, better to filter like this { "nip64": "<sarah-pubkey>", kinds: [1], ...etc }. The nip64 key clearly asks for relay to change how an absent authors filter should be treated.

It is ok to let anyone see the "feed" as Sarah cause follow list is public.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This introduces unnecessary complexity. A new term to remember, libraries would have to add support for this and everything would be awful.

I don't see any issue with using an empty "authors" and expecting the relay to treat that in a certain way, as long as the relay is carefully chosen to be treated differently by the client. A relay is already allowed to return anything they want as long as it matches the filter, it isn't mandated or expected to always return everything.

There are already other experiments out there of relay that behave differently when AUTHed and when not and I hope to see more.

Also specifying the AUTH stuff from the beginning is nice as it allows for private feeds in cool ways that, although not explicitly specified in this NIP, could be implemented somewhat easily.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I must have missed this entire paragraph. You are suggesting to put the smarts in the relay. I thought Walter would just tag Sarah when he puts her notes into her inbox relay. If the relay really handles the subscriptions as a service without the tagging, then of course this is not synonymous with a NIP-65 inbox relay and it should be specified differently.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there should be any tagging. Walter writes one note, signs it once and sends it to all the relays of people who have previously announced their intent to follow him (and also sends it to his own outbox relays). If he had to write a different note for each I think this would be a cumbersome nightmare.


If Sarah ever decides to stop following Walter, she can send a `kind:6402` _unfollow intent_ to both Walter's relays and her own, so her relay can start rejecting (and maybe delete previous) Walter's notes, and Walter can know to not send her his notes anymore. As an optimization, Walter's inbox relay can just delete Sarah's `kind:6401` upon receiving a `kind:6402`.

```jsonc
{
"kind": 6402,
"pubkey": "<sarah>"
"tags": [
["p", "<walter>"]
]
}
```

---

The approach described in this NIP doesn't replace any of the other models for following people that are already in use in Nostr, and doesn't claim to be strictly superior to the Outbox Model, but just provides an alternative way to do things.

In reality, clients should implement both approaches and can never assume others will implement this.

For example, if Sarah wanted to follow Wesley and he didn't have a `kind:10064` she would have to do the normal "outbox" approach of subscribing to his relays and fetching his notes from there.

In the same vein, if for any reason Sarah noticed that she had stopped receiving notes from Walter for a long time (~7 days) it would make sense for her to go to his relays (obtained from [NIP-65](65.md), [NIP-05](05.md), relay hints or other means) and check if he is publishing to these. In the affirmative case, she would turn Walter into an "outbox follow" instead of an "inbox follow".