nips/116.md
2024-05-28 14:11:24 +03:00

2.8 KiB

NIP-116

Event paths

Description

Event kind 30079 denotes an event defined by its event path rather than its event kind.

The event directory path is included in the event path, specified in the event's d tag. For example, an event path might be user/profile/name, where user/profile is the directory path.

Relays should parse the event directory from the event path d tag and index the event by it. Relays should support "directory listing" of kind 30079 events using the #f filter, such as {"#f": ["user/profile"]}.

For backward compatibility, the event directory should also be saved in the event's f tag (for "folder"), which is already indexed by some relay implementations, and can be queried using the #f filter.

Event content must be a JSON-encoded value. An empty object {} signifies that the entry at the event path is itself a directory. For example, when saving user/profile/name: Bob, you should also save user/profile: {} so the subdirectory can be listed under user.

In directory names, slashes should be escaped with a double slash.

Example

Event

{
    "tags": [
        ["d", "user/profile/name"],
        ["f", "user/profile"]
    ],
    "content": "\"Bob\"",
    "kind": 30079,
    ...
}

Query

{
    "#f": ["user/profile"],
    "authors": ["[pubkey]"]
}

Motivation

To make Nostr an "everything app," we need a sustainable way to support new kinds of applications. Browsing Nostr data by human-readable nested directories and paths rather than obscure event kind numbers makes the data more manageable.

Numeric event kinds are not sustainable for the infinite number of potential applications. With numeric event kinds, developers need to find an unused number for each new application and announce it somewhere, which is cumbersome and not scalable.

Directories can also replace monolithic list events like follow lists or profile details. You can update a single directory entry such as user/profile/name or groups/follows/[pubkey] without causing an overwrite of the whole profile or follow list when your client is out-of-sync with the most recent list version, as often happens on Nostr.

Using d-tagged replaceable events for reactions, such as {tags: [["d", "reactions/[eventId]"]], content: "\"👍\"", kind: 30079, ...} would make un-reacting trivial: just publish a new event with the same d tag and an empty content. Toggling a reaction on and off would not cause a flurry of new reaction & delete events that all need to be persisted.

Implementations

  • Relays that support tag-replaceable events and indexing by arbitrary tags (in this case f) already support this feature.
  • IrisDB client side library: treelike data structure with subscribable nodes.