nostr
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseNostr Protocol Expert
Nostr协议专家
Purpose
用途
This skill provides expert-level assistance with the Nostr protocol, a simple, open protocol for global, decentralized, and censorship-resistant social networks. The protocol is built on relays and cryptographic keys, enabling direct peer-to-peer communication without central servers.
此技能为Nostr协议提供专家级协助,Nostr是一个用于构建全球、去中心化且抗审查社交网络的简单开源协议。该协议基于中继和加密密钥构建,无需中央服务器即可实现直接的点对点通信。
When to Use
适用场景
Activate this skill when:
- Implementing Nostr clients or relays
- Working with Nostr events and messages
- Handling cryptographic signatures and keys (schnorr signatures on secp256k1)
- Implementing any Nostr Implementation Possibility (NIP)
- Building social networking features on Nostr
- Querying or filtering Nostr events
- Discussing Nostr protocol architecture
- Implementing WebSocket communication with relays
在以下场景激活此技能:
- 实现Nostr客户端或中继
- 处理Nostr事件和消息
- 处理加密签名和密钥(secp256k1上的schnorr签名)
- 实现任何Nostr实现提案(NIP)
- 在Nostr上构建社交网络功能
- 查询或过滤Nostr事件
- 讨论Nostr协议架构
- 实现与中继的WebSocket通信
Core Concepts
核心概念
The Protocol Foundation
协议基础
Nostr operates on two main components:
- Clients - Applications users run to read/write data
- Relays - Servers that store and forward messages
Key principles:
- Everyone runs a client
- Anyone can run a relay
- Users identified by public keys
- Messages signed with private keys
- No central authority or trusted servers
Nostr基于两个核心组件运行:
- 客户端 - 用户运行的用于读写数据的应用
- 中继 - 存储和转发消息的服务器
核心原则:
- 每个用户都可运行客户端
- 任何人都可运行中继
- 用户通过公钥标识
- 消息使用私钥签名
- 无中央权威机构或受信任服务器
Events Structure
事件结构
All data in Nostr is represented as events. An event is a JSON object with this structure:
json
{
"id": "<32-bytes lowercase hex-encoded sha256 of the serialized event data>",
"pubkey": "<32-bytes lowercase hex-encoded public key of the event creator>",
"created_at": "<unix timestamp in seconds>",
"kind": "<integer identifying event type>",
"tags": [
["<tag name>", "<tag value>", "<optional third param>", "..."]
],
"content": "<arbitrary string>",
"sig": "<64-bytes lowercase hex of the schnorr signature of the sha256 hash of the serialized event data>"
}Nostr中的所有数据都以事件形式呈现。事件是一个如下结构的JSON对象:
json
{
"id": "<32-bytes lowercase hex-encoded sha256 of the serialized event data>",
"pubkey": "<32-bytes lowercase hex-encoded public key of the event creator>",
"created_at": "<unix timestamp in seconds>",
"kind": "<integer identifying event type>",
"tags": [
["<tag name>", "<tag value>", "<optional third param>", "..."]
],
"content": "<arbitrary string>",
"sig": "<64-bytes lowercase hex of the schnorr signature of the sha256 hash of the serialized event data>"
}Event Kinds
事件类型
Standard event kinds (from various NIPs):
- - Metadata (user profile)
0 - - Text note (short post)
1 - - Recommend relay
2 - - Contacts (following list)
3 - - Encrypted direct messages
4 - - Event deletion
5 - - Repost
6 - - Reaction (like, emoji reaction)
7 - - Channel creation
40 - - Channel metadata
41 - - Channel message
42 - - Channel hide message
43 - - Channel mute user
44 - - Regular events
1000-9999 - - Replaceable events
10000-19999 - - Ephemeral events
20000-29999 - - Parameterized replaceable events
30000-39999
标准事件类型(来自各类NIP):
- - 元数据(用户资料)
0 - - 文本笔记(短帖子)
1 - - 推荐中继
2 - - 联系人(关注列表)
3 - - 加密私信
4 - - 事件删除
5 - - 转发
6 - - 反应(点赞、表情反应)
7 - - 频道创建
40 - - 频道元数据
41 - - 频道消息
42 - - 隐藏频道消息
43 - - 屏蔽频道用户
44 - - 常规事件
1000-9999 - - 可替换事件
10000-19999 - - 临时事件
20000-29999 - - 参数化可替换事件
30000-39999
Tags
标签
Common tag types:
- - Reference to an event
["e", "<event-id>", "<relay-url>", "<marker>"] - - Reference to a user
["p", "<pubkey>", "<relay-url>"] - - Reference to a replaceable event
["a", "<kind>:<pubkey>:<d-tag>", "<relay-url>"] - - Identifier for parameterized replaceable events
["d", "<identifier>"] - - Reference/link to a web resource
["r", "<url>"] - - Hashtag
["t", "<hashtag>"] - - Geolocation
["g", "<geohash>"] - - Proof of work
["nonce", "<number>", "<difficulty>"] - - Subject/title
["subject", "<subject>"] - - Client application used
["client", "<client-name>"]
常见标签类型:
- - 引用某个事件
["e", "<event-id>", "<relay-url>", "<marker>"] - - 引用某个用户
["p", "<pubkey>", "<relay-url>"] - - 引用可替换事件
["a", "<kind>:<pubkey>:<d-tag>", "<relay-url>"] - - 参数化可替换事件的标识符
["d", "<identifier>"] - - 引用/链接到网络资源
["r", "<url>"] - - 话题标签
["t", "<hashtag>"] - - 地理位置
["g", "<geohash>"] - - 工作量证明
["nonce", "<number>", "<difficulty>"] - - 主题/标题
["subject", "<subject>"] - - 使用的客户端应用
["client", "<client-name>"]
Key NIPs Reference
关键NIP参考
For detailed specifications, refer to references/nips-overview.md.
如需详细规范,请参考 references/nips-overview.md。
Core Protocol NIPs
核心协议NIP
NIP-01: Basic Protocol Flow
NIP-01: 基础协议流程
The foundation of Nostr. Defines:
- Event structure and validation
- Event ID calculation (SHA256 of serialized event)
- Signature verification (schnorr signatures)
- Client-relay communication via WebSocket
- Message types: EVENT, REQ, CLOSE, EOSE, OK, NOTICE
Nostr的基础规范,定义了:
- 事件结构与验证
- 事件ID计算(序列化事件的SHA256哈希)
- 签名验证(schnorr签名)
- 客户端与中继通过WebSocket通信
- 消息类型:EVENT、REQ、CLOSE、EOSE、OK、NOTICE
NIP-02: Contact List and Petnames
NIP-02: 联系人列表与昵称
Event kind for following lists:
3- Each tag represents a followed user
p - Optional relay URL and petname in tag
- Replaceable event (latest overwrites)
类型的事件用于关注列表:
3- 每个标签代表一个被关注的用户
p - 标签中可包含可选的中继URL和昵称
- 可替换事件(最新版本覆盖旧版本)
NIP-04: Encrypted Direct Messages
NIP-04: 加密私信
Event kind for private messages:
4- Content encrypted with shared secret (ECDH)
- tag for recipient pubkey
p - Deprecated in favor of NIP-44
类型的事件用于私信:
4- 内容使用共享密钥(ECDH)加密
- 标签指定接收者公钥
p - 已被NIP-44取代
NIP-05: Mapping Nostr Keys to DNS
NIP-05: Nostr密钥与DNS映射
Internet identifier format:
name@domain.com- endpoint
.well-known/nostr.json - Maps names to pubkeys
- Optional relay list
互联网标识符格式:
name@domain.com- 端点
.well-known/nostr.json - 将名称映射到公钥
- 可选的中继列表
NIP-09: Event Deletion
NIP-09: 事件删除
Event kind to request deletion:
5- Contains tags for events to delete
e - Relays should delete referenced events
- Only works for own events
类型的事件用于请求删除:
5- 包含标签指定要删除的事件
e - 中继应删除引用的事件
- 仅对自己的事件有效
NIP-10: Text Note References (Threads)
NIP-10: 文本笔记引用(线程)
Conventions for and tags in replies:
ep- Root event reference
- Reply event reference
- Mentions
- Marker types: "root", "reply", "mention"
回复中和标签的约定:
ep- 根事件引用
- 回复事件引用
- 提及
- 标记类型:"root"、"reply"、"mention"
NIP-11: Relay Information Document
NIP-11: 中继信息文档
HTTP endpoint for relay metadata:
- GET request to relay URL
- Returns JSON with relay information
- Supported NIPs, software, limitations
用于获取中继元数据的HTTP端点:
- 向中继URL发送GET请求
- 返回包含中继信息的JSON
- 支持的NIP、软件、限制条件
Social Features NIPs
社交功能NIP
NIP-25: Reactions
NIP-25: 反应
Event kind for reactions:
7- Content usually "+" (like) or emoji
- tag for reacted event
e - tag for event author
p
类型的事件用于反应:
7- 内容通常为"+"(点赞)或表情
- 标签指定被反应的事件
e - 标签指定事件作者
p
NIP-42: Authentication
NIP-42: 认证
Client authentication to relays:
- AUTH message from relay
- Client responds with event kind
22242 - Proves key ownership
客户端向中继认证:
- 中继发送AUTH消息
- 客户端回复类型的事件
22242 - 证明密钥所有权
NIP-50: Search
NIP-50: 搜索
Query filter extension for full-text search:
- field in REQ filters
search - Implementation-defined behavior
REQ消息的查询过滤器扩展:
- REQ过滤器中的字段
search - 实现定义的行为
Advanced NIPs
高级NIP
NIP-19: bech32-encoded Entities
NIP-19: bech32编码实体
Human-readable identifiers:
- : public key
npub - : private key (sensitive!)
nsec - : note/event ID
note - : profile with relay hints
nprofile - : event with relay hints
nevent - : replaceable event coordinate
naddr
人类可读标识符:
- : 公钥
npub - : 私钥(敏感!)
nsec - : 笔记/事件ID
note - : 带中继提示的资料
nprofile - : 带中继提示的事件
nevent - : 可替换事件坐标
naddr
NIP-44: Encrypted Payloads
NIP-44: 加密负载
Improved encryption for direct messages:
- Versioned encryption scheme
- Better security than NIP-04
- ChaCha20-Poly1305 AEAD
改进的私信加密方案:
- 版本化加密机制
- 安全性优于NIP-04
- ChaCha20-Poly1305 AEAD
NIP-65: Relay List Metadata
NIP-65: 中继列表元数据
Event kind for relay lists:
10002- Read/write relay preferences
- Optimizes relay discovery
- Replaceable event
类型的事件用于中继列表:
10002- 读写中继偏好
- 优化中继发现
- 可替换事件
Client-Relay Communication
客户端-中继通信
WebSocket Messages
WebSocket消息
From Client to Relay
客户端到中继
EVENT - Publish an event:
json
["EVENT", <event JSON>]REQ - Request events (subscription):
json
["REQ", <subscription_id>, <filters JSON>, <filters JSON>, ...]CLOSE - Stop a subscription:
json
["CLOSE", <subscription_id>]AUTH - Respond to auth challenge:
json
["AUTH", <signed event kind 22242>]EVENT - 发布事件:
json
["EVENT", <event JSON>]REQ - 请求事件(订阅):
json
["REQ", <subscription_id>, <filters JSON>, <filters JSON>, ...]CLOSE - 停止订阅:
json
["CLOSE", <subscription_id>]AUTH - 响应认证挑战:
json
["AUTH", <signed event kind 22242>]From Relay to Client
中继到客户端
EVENT - Send event to client:
json
["EVENT", <subscription_id>, <event JSON>]OK - Acceptance/rejection notice:
json
["OK", <event_id>, <true|false>, <message>]EOSE - End of stored events:
json
["EOSE", <subscription_id>]CLOSED - Subscription closed:
json
["CLOSED", <subscription_id>, <message>]NOTICE - Human-readable message:
json
["NOTICE", <message>]AUTH - Authentication challenge:
json
["AUTH", <challenge>]EVENT - 向客户端发送事件:
json
["EVENT", <subscription_id>, <event JSON>]OK - 接受/拒绝通知:
json
["OK", <event_id>, <true|false>, <message>]EOSE - 存储事件结束:
json
["EOSE", <subscription_id>]CLOSED - 订阅已关闭:
json
["CLOSED", <subscription_id>, <message>]NOTICE - 人类可读消息:
json
["NOTICE", <message>]AUTH - 认证挑战:
json
["AUTH", <challenge>]Filter Objects
过滤器对象
Filters select events in REQ messages:
json
{
"ids": ["<event-id>", ...],
"authors": ["<pubkey>", ...],
"kinds": [<kind number>, ...],
"#e": ["<event-id>", ...],
"#p": ["<pubkey>", ...],
"#a": ["<coordinate>", ...],
"#t": ["<hashtag>", ...],
"since": <unix timestamp>,
"until": <unix timestamp>,
"limit": <max number of events>
}Filtering rules:
- Arrays are ORed together
- Different fields are ANDed
- Tag filters: matches tag values
#<single-letter> - Prefix matching allowed for and
idsauthors
过滤器用于在REQ消息中选择事件:
json
{
"ids": ["<event-id>", ...],
"authors": ["<pubkey>", ...],
"kinds": [<kind number>, ...],
"#e": ["<event-id>", ...],
"#p": ["<pubkey>", ...],
"#a": ["<coordinate>", ...],
"#t": ["<hashtag>", ...],
"since": <unix timestamp>,
"until": <unix timestamp>,
"limit": <max number of events>
}过滤规则:
- 数组内的元素为或关系
- 不同字段为与关系
- 标签过滤器:匹配标签值
#<single-letter> - 和
ids支持前缀匹配authors
Cryptographic Operations
加密操作
Key Management
密钥管理
- Private Key: 32-byte random value, keep secure
- Public Key: Derived via secp256k1
- Encoding: Hex (lowercase) or bech32
- 私钥:32字节随机值,需妥善保管
- 公钥:通过secp256k1派生
- 编码:十六进制(小写)或bech32
Event Signing (schnorr)
事件签名(schnorr)
Steps to create a signed event:
- Set all fields except and
idsig - Serialize event data to JSON (specific order)
- Calculate SHA256 hash →
id - Sign with schnorr signature →
idsig
Serialization format for ID calculation:
json
[
0,
<pubkey>,
<created_at>,
<kind>,
<tags>,
<content>
]创建签名事件的步骤:
- 设置除和
id外的所有字段sig - 将事件数据序列化为JSON(特定顺序)
- 计算SHA256哈希 →
id - 使用schnorr签名对签名 →
idsig
用于ID计算的序列化格式:
json
[
0,
<pubkey>,
<created_at>,
<kind>,
<tags>,
<content>
]Event Verification
事件验证
Steps to verify an event:
- Verify ID matches SHA256 of serialized data
- Verify signature is valid schnorr signature
- Check created_at is reasonable (not far future)
- Validate event structure and required fields
验证事件的步骤:
- 验证ID是否与序列化数据的SHA256哈希匹配
- 验证签名是否为有效的schnorr签名
- 检查created_at是否合理(不应为遥远的未来)
- 验证事件结构和必填字段
Implementation Best Practices
实现最佳实践
For Clients
客户端
- Connect to Multiple Relays: Don't rely on single relay
- Cache Events: Reduce redundant relay queries
- Verify Signatures: Always verify event signatures
- Handle Replaceable Events: Keep only latest version
- Respect User Privacy: Careful with sensitive data
- Implement NIP-65: Use user's preferred relays
- Proper Error Handling: Handle relay disconnections
- Pagination: Use ,
limit,sincefor queriesuntil
- 连接多个中继:不要依赖单个中继
- 缓存事件:减少重复的中继查询
- 验证签名:始终验证事件签名
- 处理可替换事件:仅保留最新版本
- 尊重用户隐私:谨慎处理敏感数据
- 实现NIP-65:使用用户偏好的中继
- 完善错误处理:处理中继断开连接的情况
- 分页处理:使用、
limit、since进行查询until
For Relays
中继
- Validate Events: Check signatures, IDs, structure
- Rate Limiting: Prevent spam and abuse
- Storage Management: Ephemeral events, retention policies
- Implement NIP-11: Provide relay information
- WebSocket Optimization: Handle many connections
- Filter Optimization: Efficient event querying
- Consider NIP-42: Authentication for write access
- Performance: Index by pubkey, kind, tags, timestamp
- 验证事件:检查签名、ID和结构
- 速率限制:防止垃圾信息和滥用
- 存储管理:临时事件、保留策略
- 实现NIP-11:提供中继信息
- WebSocket优化:处理大量连接
- 过滤器优化:高效的事件查询
- 考虑NIP-42:写入访问的认证
- 性能优化:按公钥、类型、标签、时间戳建立索引
Security Considerations
安全注意事项
- Never Expose Private Keys: Handle nsec carefully
- Validate All Input: Prevent injection attacks
- Use NIP-44: For encrypted messages (not NIP-04)
- Check Event Timestamps: Reject far-future events
- Implement Proof of Work: NIP-13 for spam prevention
- Sanitize Content: XSS prevention in displayed content
- Relay Trust: Don't trust single relay for critical data
- 绝不暴露私钥:妥善处理nsec
- 验证所有输入:防止注入攻击
- 使用NIP-44:用于私信加密(而非NIP-04)
- 检查事件时间戳:拒绝遥远未来的事件
- 实现工作量证明:使用NIP-13防止垃圾信息
- 内容 sanitize:防止显示内容中的XSS攻击
- 中继信任:不要依赖单个中继获取关键数据
Common Patterns
常见模式
Publishing a Note
发布笔记
javascript
const event = {
pubkey: userPublicKey,
created_at: Math.floor(Date.now() / 1000),
kind: 1,
tags: [],
content: "Hello Nostr!",
}
// Calculate ID and sign
event.id = calculateId(event)
event.sig = signEvent(event, privateKey)
// Publish to relay
ws.send(JSON.stringify(["EVENT", event]))javascript
const event = {
pubkey: userPublicKey,
created_at: Math.floor(Date.now() / 1000),
kind: 1,
tags: [],
content: "Hello Nostr!",
}
// 计算ID并签名
event.id = calculateId(event)
event.sig = signEvent(event, privateKey)
// 发布到中继
ws.send(JSON.stringify(["EVENT", event]))Subscribing to Notes
订阅笔记
javascript
const filter = {
kinds: [1],
authors: [followedPubkey1, followedPubkey2],
limit: 50
}
ws.send(JSON.stringify(["REQ", "my-sub", filter]))javascript
const filter = {
kinds: [1],
authors: [followedPubkey1, followedPubkey2],
limit: 50
}
ws.send(JSON.stringify(["REQ", "my-sub", filter]))Replying to a Note
回复笔记
javascript
const reply = {
kind: 1,
tags: [
["e", originalEventId, relayUrl, "root"],
["p", originalAuthorPubkey]
],
content: "Great post!",
// ... other fields
}javascript
const reply = {
kind: 1,
tags: [
["e", originalEventId, relayUrl, "root"],
["p", originalAuthorPubkey]
],
content: "Great post!",
// ... 其他字段
}Reacting to a Note
对笔记做出反应
javascript
const reaction = {
kind: 7,
tags: [
["e", eventId],
["p", eventAuthorPubkey]
],
content: "+", // or emoji
// ... other fields
}javascript
const reaction = {
kind: 7,
tags: [
["e", eventId],
["p", eventAuthorPubkey]
],
content: "+", // 或表情
// ... 其他字段
}Development Resources
开发资源
Essential NIPs for Beginners
初学者必备NIP
Start with these NIPs in order:
- NIP-01 - Basic protocol (MUST read)
- NIP-19 - Bech32 identifiers
- NIP-02 - Following lists
- NIP-10 - Threaded conversations
- NIP-25 - Reactions
- NIP-65 - Relay lists
按顺序从以下NIP开始:
- NIP-01 - 基础协议(必读)
- NIP-19 - Bech32标识符
- NIP-02 - 关注列表
- NIP-10 - 线程对话
- NIP-25 - 反应
- NIP-65 - 中继列表
Testing and Development
测试与开发
- Relay Implementations: nostream, strfry, relay.py
- Test Relays: wss://relay.damus.io, wss://nos.lol
- Libraries: nostr-tools (JS), rust-nostr (Rust), python-nostr (Python)
- Development Tools: NostrDebug, Nostr Army Knife, nostril
- Reference Clients: Damus (iOS), Amethyst (Android), Snort (Web)
- 中继实现:nostream, strfry, relay.py
- 测试中继:wss://relay.damus.io, wss://nos.lol
- 库:nostr-tools(JS), rust-nostr(Rust), python-nostr(Python)
- 开发工具:NostrDebug, Nostr Army Knife, nostril
- 参考客户端:Damus(iOS), Amethyst(Android), Snort(Web)
Key Repositories
关键仓库
- NIPs Repository: https://github.com/nostr-protocol/nips
- Awesome Nostr: https://github.com/aljazceru/awesome-nostr
- Nostr Resources: https://nostr.how
- NIP仓库:https://github.com/nostr-protocol/nips
- Awesome Nostr:https://github.com/aljazceru/awesome-nostr
- Nostr资源:https://nostr.how
Reference Files
参考文件
For comprehensive NIP details, see:
- references/nips-overview.md - Detailed descriptions of all standard NIPs
- references/event-kinds.md - Complete event kinds reference
- references/common-mistakes.md - Pitfalls and how to avoid them
如需全面的NIP详情,请查看:
- references/nips-overview.md - 所有标准NIP的详细说明
- references/event-kinds.md - 完整的事件类型参考
- references/common-mistakes.md - 常见陷阱及避免方法
Quick Checklist
快速检查清单
When implementing Nostr:
- Events have all required fields (id, pubkey, created_at, kind, tags, content, sig)
- Event IDs calculated correctly (SHA256 of serialization)
- Signatures verified (schnorr on secp256k1)
- WebSocket messages properly formatted
- Filter queries optimized with appropriate limits
- Handling replaceable events correctly
- Connected to multiple relays for redundancy
- Following relevant NIPs for features implemented
- Private keys never exposed or transmitted
- Event timestamps validated
实现Nostr时:
- 事件包含所有必填字段(id, pubkey, created_at, kind, tags, content, sig)
- 事件ID计算正确(序列化数据的SHA256哈希)
- 签名已验证(secp256k1上的schnorr签名)
- WebSocket消息格式正确
- 过滤器查询已优化并设置了适当的限制
- 可替换事件处理正确
- 已连接多个中继以实现冗余
- 已遵循所实现功能对应的NIP
- 私钥从未暴露或传输
- 事件时间戳已验证
Official Resources
官方资源
- NIPs Repository: https://github.com/nostr-protocol/nips
- Nostr Website: https://nostr.com
- Nostr Documentation: https://nostr.how
- NIP Status: https://nostr-nips.com
- NIP仓库:https://github.com/nostr-protocol/nips
- Nostr官网:https://nostr.com
- Nostr文档:https://nostr.how
- NIP状态:https://nostr-nips.com ",