Files
01.md
02.md
03.md
04.md
05.md
06.md
07.md
08.md
09.md
10.md
11.md
12.md
13.md
14.md
15.md
16.md
17.md
18.md
19.md
20.md
21.md
22.md
23.md
24.md
25.md
26.md
27.md
28.md
29.md
30.md
31.md
32.md
33.md
34.md
35.md
36.md
37.md
38.md
39.md
40.md
42.md
44.md
45.md
46.md
47.md
48.md
49.md
50.md
51.md
52.md
53.md
54.md
55.md
56.md
57.md
58.md
59.md
60.md
61.md
64.md
65.md
68.md
69.md
70.md
71.md
72.md
73.md
75.md
78.md
7D.md
84.md
86.md
88.md
89.md
90.md
92.md
94.md
96.md
98.md
99.md
BREAKING.md
C7.md
README.md
nips/89.md
2024-09-03 20:41:31 +03:30

5.5 KiB

NIP-89

draft optional

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

{
  "kind": 31989,
  "pubkey": <recommender-user-pubkey>,
  "tags": [
    ["d", <supported-event-kind>],
    ["a", "31990:app1-pubkey:<d-identifier>", "wss://relay1", "ios"],
    ["a", "31990:app2-pubkey:<d-identifier>", "wss://relay2", "web"]
  ],
  // other fields...
}

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

{
  "kind": 31990,
  "pubkey": "<application-pubkey>",
  "content": "<optional-kind:0-style-metadata>",
  "tags": [
    ["d", <random-id>],
    ["k", <supported-event-kind>],
    ["web", "https://..../a/<bech32>", "nevent"],
    ["web", "https://..../p/<bech32>", "nprofile"],
    ["web", "https://..../e/<bech32>"],
    ["ios", ".../<bech32>"]
  ],
  // other fields...
}
  • content is an optional 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 of the 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.

Client tag

When publishing events, clients MAY include a client tag. Identifying the client that published the note. This tag is a tuple of name, address identifying a handler event and, a relay hint for finding the handler event. This has privacy implications for users, so clients SHOULD allow users to opt-out of using this tag.

{
  "kind": 1,
  "tags": [
    ["client", "My Client", "31990:app1-pubkey:<d-identifier>", "wss://relay1"]
  ]
  // other fields...
}

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.

{
  "kind": 31989,
  "tags": [
    ["d", "31337"],
    ["a", "31990:1743058db7078661b94aaf4286429d97ee5257d14a86d6bfa54cb0482b876fb0:abcd", <relay-url>, "web"]
  ],
  // other fields...
}

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", <id>, { "kinds": [31989], "#d": ["31337"], "authors": [<user>, <users-contact-list>] }]

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 or querying high-quality restricted relays to avoid directing users to malicious handlers.

["REQ", <id>, { "kinds": [31990], "#k": [<desired-event-kind>], "authors": [...] }]