From 867c8bb334b0d9bb22a6af5c16ce6d186852af5a Mon Sep 17 00:00:00 2001 From: Pablo Fernandez Date: Wed, 7 Jun 2023 21:56:17 +0200 Subject: [PATCH] NIP-89: Recommended Application Handlers (#530) --- 89.md | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 89.md diff --git a/89.md b/89.md new file mode 100644 index 00000000..5eee3b8e --- /dev/null +++ b/89.md @@ -0,0 +1,116 @@ +NIP-89 +====== + +Recommended Application Handlers +-------------------------------- + +`draft` `optional` `author:pablof7z` + +This NIP describes `kind:31989` and `kind:31990`: a way to discover applications that can handle unknown event-kinds. + +## Rationale +Nostr's discoverability and transparent event interaction is one of its most interesting/novel mechanics. +This NIP provides a simple way for clients to discover applications that handle events of a specific kind to ensure smooth cross-client and cross-kind interactions. + +### Parties involved +There are three actors to this workflow: + +* application that handles a specific event kind (note that an application doesn't necessarily need to be a distinct entity and it could just be the same pubkey as user A) + * Publishes `kind:31990`, detailing how apps should redirect to it +* user A, who recommends an app that handles a specific event kind + * Publishes `kind:31989` +* user B, who seeks a recommendation for an app that handles a specific event kind + * Queries for `kind:31989` and, based on results, queries for `kind:31990` + +# Events + +## Recommendation event +```json +{ + "kind": 31989, + "pubkey": , + "tags": [ + [ "d", ], + [ "a", "31990:app1-pubkey:", "wss://relay1", "ios" ], + [ "a", "31990:app2-pubkey:", "wss://relay2", "web" ] + ] +} +``` + +The `d` tag in `kind:31989` is the supported event kind this event is recommending. + +Multiple `a` tags can appear on the same `kind:31989`. + +The second value of the tag SHOULD be a relay hint. +The third value of the tag SHOULD be the platform where this recommendation might apply. + +## Handler information +```json +{ + "kind": 31990, + "pubkey": , + "content": "", + "tags": [ + [ "d", ], + [ "k", ], + [ "web", "https://..../a/", "nevent" ], + [ "web", "https://..../p/", "nprofile" ], + [ "web", "https://..../e/" ], + [ "ios", ".../" ] + ] +} +``` + +* `content` is an optional `set_metadata`-like stringified JSON object, as described in NIP-01. This content is useful when the pubkey creating the `kind:31990` is not an application. If `content` is empty, the `kind:0` of the pubkey should be used to display application information (e.g. name, picture, web, LUD16, etc.) + +* `k` tags' value is the event kind that is supported by this `kind:31990`. +Using a `k` tag(s) (instead of having the kind onf the NIP-33 `d` tag) provides: + * Multiple `k` tags can exist in the same event if the application supports more than one event kind and their handler URLs are the same. + * The same pubkey can have multiple events with different apps that handle the same event kind. + +* `bech32` in a URL MUST be replaced by clients with the NIP-19-encoded entity that should be loaded by the application. + +Multiple tags might be registered by the app, following NIP-19 nomenclature as the second value of the array. + +A tag without a second value in the array SHOULD be considered a generic handler for any NIP-19 entity that is not handled by a different tag. + +# User flow +A user A who uses a non-`kind:1`-centric nostr app could choose to announce/recommend a certain kind-handler application. + +When user B sees an unknown event kind, e.g. in a social-media centric nostr client, the client would allow user B to interact with the unknown-kind event (e.g. tapping on it). + +The client MIGHT query for the user's and the user's follows handler. + +# Example + +## User A recommends a `kind:31337`-handler +User A might be a user of Zapstr, a `kind:31337`-centric client (tracks). Using Zapstr, user A publishes an event recommending Zapstr as a `kind:31337`-handler. + +```json +{ + "kind": 31989, + "tags": [ + [ "d", "31337" ], + [ "a", "31990:1743058db7078661b94aaf4286429d97ee5257d14a86d6bfa54cb0482b876fb0:abcd", , "web" ] + ] +} +``` + +## User B interacts with a `kind:31337`-handler +User B might see in their timeline an event referring to a `kind:31337` event +(e.g. a `kind:1` tagging a `kind:31337`). + +User B's client, not knowing how to handle a `kind:31337` might display the event +using its `alt` tag (as described in NIP-31). When the user clicks on the event, +the application queries for a handler for this `kind`: + +`["REQ", , '[{ "kinds": [31989], "#d": ["31337"], 'authors': [, ] }]']` + +User B, who follows User A, sees that `kind:31989` event and fetches the `a`-tagged event for the app and handler information. + +User B's client sees the application's `kind:31990` which includes the information to redirect the user to the relevant URL with the desired entity replaced in the URL. + +## Alternative query bypassing `kind:31989` +Alternatively, users might choose to query directly for `kind:31990` for an event kind. Clients SHOULD be careful doing this and use spam-prevention mechanisms to avoid directing users to malicious handlers. + +`["REQ", , '[{ "kinds": [31990], "#k": [], 'authors': [...] }]']` \ No newline at end of file