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