NIP-10: 텍스트 노트 스레딩
NIP-10은 kind 1 노트가 서로 참조하여 답글 스레드를 형성하는 방법을 지정합니다. 대화 뷰를 구축하는 데 이해가 필수적입니다.
문제
누군가 노트에 답글을 달 때 클라이언트는 알아야 합니다: 무엇에 대한 답글인가? 대화의 루트는 무엇인가? 누구에게 알려야 하는가? NIP-10은 e 태그(이벤트 참조)와 p 태그(pubkey 멘션)를 통해 이러한 질문에 답합니다.
마킹된 태그 (권장)
현대 클라이언트는 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태그 하나 - 답글에 대한 답글:
root하나와reply하나로 두 개의e태그 root는 스레드 전체에서 일정하게 유지됩니다;reply는 응답하는 대상에 따라 변경됩니다
알림을 위한 Pubkey 태그
알림을 받아야 하는 모든 사람에 대해 p 태그를 포함합니다. 최소한 답글하는 노트의 작성자를 태그하세요. 관례적으로 부모 이벤트의 모든 p 태그도 포함합니다(대화의 모든 사람이 계속 알 수 있도록), 그리고 콘텐츠에서 @멘션하는 모든 사용자도 포함합니다.
릴레이 힌트
e 및 p 태그의 세 번째 위치에는 해당 이벤트나 사용자의 콘텐츠를 찾을 수 있는 릴레이 URL이 포함될 수 있습니다. 이는 클라이언트가 원래 릴레이에 연결되어 있지 않아도 참조된 콘텐츠를 가져오는 데 도움이 됩니다.
더 이상 사용되지 않는 위치 기반 태그
초기 Nostr 구현은 마커가 아닌 태그 위치에서 의미를 유추했습니다: 첫 번째 e 태그가 루트, 마지막이 답글, 중간이 멘션이었습니다. 이 접근 방식은 모호성을 만들기 때문에 더 이상 사용되지 않습니다. 마커 없는 e 태그가 보이면 오래된 클라이언트에서 온 것일 가능성이 높습니다. 현대 구현은 항상 명시적 마커를 사용해야 합니다.
스레드 뷰 구축
스레드를 표시하려면 루트 이벤트를 가져온 다음 해당 루트를 참조하는 e 태그가 있는 모든 이벤트를 쿼리합니다:
["REQ", "thread", {"kinds": [1], "#e": ["<root-event-id>"]}]
created_at으로 결과를 정렬하고 reply 마커를 사용하여 트리 구조를 구축합니다. reply가 루트를 가리키는 이벤트는 최상위 답글입니다; reply가 다른 답글을 가리키는 이벤트는 중첩된 응답입니다.
주요 출처:
언급된 곳:
참고: