NIP-10 规定了 kind 1 笔记如何相互引用形成回复线程。理解这一点对于构建对话视图至关重要。

问题

当有人回复一条笔记时,客户端需要知道:这是回复什么的?对话的根是什么?谁应该被通知?NIP-10 通过 e 标签(事件引用)和 p 标签(公钥提及)回答这些问题。

标记标签(首选)

现代客户端在 e 标签中使用显式标记:

{
  "id": "f9c2e...",
  "pubkey": "a3b9c...",
  "created_at": 1734912345,
  "kind": 1,
  "tags": [
    ["e", "abc123...", "wss://relay.example.com", "root"],
    ["e", "def456...", "wss://relay.example.com", "reply"],
    ["p", "91cf9..."],
    ["p", "14aeb..."]
  ],
  "content": "说得好!我同意。",
  "sig": "b7d3f..."
}

root 标记指向开始线程的原始笔记。reply 标记指向正在回复的特定笔记。如果直接回复根,只使用 root(不需要 reply 标签)。这个区分对于渲染很重要:reply 决定线程视图中的缩进,而 root 将所有回复分组在一起。

线程规则

  • 直接回复根: 一个带有 root 标记的 e 标签
  • 回复一个回复: 两个 e 标签,一个 root 和一个 reply
  • root 在整个线程中保持不变;reply 根据您回复的内容而变化

用于通知的公钥标签

包含应被通知的每个人的 p 标签。至少标记您回复笔记的作者。惯例是也包含来自父事件的所有 p 标签(这样对话中的每个人都保持在循环中),加上您在内容中 @提及的任何用户。

中继提示

ep 标签的第三个位置可以包含一个中继 URL,表示可能在哪里找到该事件或用户的内容。这帮助客户端获取引用的内容,即使它们没有连接到原始中继。

已弃用的位置标签

早期 Nostr 实现从标签位置而不是标记推断含义:第一个 e 标签是根,最后一个是回复,中间的是提及。这种方法已弃用,因为它会产生歧义。如果您看到没有标记的 e 标签,它们可能来自旧客户端。现代实现应始终使用显式标记。

构建线程视图

要显示线程,获取根事件,然后查询所有具有引用该根的 e 标签的事件:

["REQ", "thread", {"kinds": [1], "#e": ["<root-event-id>"]}]

created_at 排序结果,使用 reply 标记构建树结构。reply 指向根的事件是顶级回复;reply 指向另一个回复的事件是嵌套响应。


主要来源:

提及于:

另请参阅: