入門
NIP-11 中繼器資訊
深入了解 Nostr 中繼器的資訊文件,發現中繼器功能、限制和政策。
10 分鐘
什麼是 NIP-11?
NIP-11 定義了中繼器資訊文件(Relay Information Document),讓客戶端可以 發現中繼器的功能、限制和政策。透過 HTTP GET 請求中繼器的 WebSocket URL, 並設定 Accept: application/nostr+json 標頭即可獲取。
用途: 客戶端可以根據中繼器資訊決定是否連接、顯示中繼器名稱和描述、 了解支援的 NIP、檢查限制條件等。
獲取方式
# 使用 curl 獲取中繼器資訊
curl -H "Accept: application/nostr+json" https://relay.damus.io/
# 注意:
# - 將 wss:// 改為 https://
# - 必須設定 Accept 標頭
# - 返回 JSON 格式 文件結構
{
"name": "relay.example.com",
"description": "A fast and reliable Nostr relay",
"pubkey": "admin-pubkey-hex",
"contact": "[email protected]",
"supported_nips": [1, 2, 4, 9, 11, 12, 15, 16, 20, 22, 33, 40],
"software": "git+https://github.com/...",
"version": "1.0.0",
"limitation": {
"max_message_length": 16384,
"max_subscriptions": 20,
"max_filters": 100,
"max_limit": 5000,
"max_subid_length": 100,
"max_event_tags": 100,
"max_content_length": 8196,
"min_pow_difficulty": 0,
"auth_required": false,
"payment_required": false,
"restricted_writes": false,
"created_at_lower_limit": 31536000,
"created_at_upper_limit": 3600
},
"relay_countries": ["US", "CA"],
"language_tags": ["en", "zh"],
"tags": ["sfw-only", "bitcoin"],
"posting_policy": "https://example.com/policy",
"payments_url": "https://example.com/pay",
"fees": {
"admission": [{ "amount": 1000000, "unit": "msats" }],
"subscription": [{ "amount": 5000000, "unit": "msats", "period": 2592000 }],
"publication": [{ "kinds": [4], "amount": 100, "unit": "msats" }]
},
"icon": "https://example.com/icon.png"
} 欄位說明
基本資訊
| 欄位 | 類型 | 說明 |
|---|---|---|
| name | string | 中繼器名稱 |
| description | string | 中繼器描述 |
| pubkey | string | 管理員公鑰(hex) |
| contact | string | 聯絡方式(email 等) |
| supported_nips | number[] | 支援的 NIP 列表 |
| software | string | 軟體專案 URL |
| version | string | 軟體版本 |
限制(limitation)
| 欄位 | 說明 |
|---|---|
| max_message_length | 最大 WebSocket 訊息長度(bytes) |
| max_subscriptions | 每個連接最大訂閱數 |
| max_filters | 每個訂閱最大過濾器數 |
| max_limit | 過濾器中 limit 的最大值 |
| auth_required | 是否需要 NIP-42 認證 |
| payment_required | 是否需要付費 |
程式碼範例
獲取中繼器資訊
async function getRelayInfo(relayUrl) {
// 將 wss:// 轉換為 https://
const httpUrl = relayUrl
.replace('wss://', 'https://')
.replace('ws://', 'http://')
try {
const response = await fetch(httpUrl, {
headers: {
'Accept': 'application/nostr+json'
}
})
if (!response.ok) {
throw new Error(`HTTP ${response.status}`)
}
return await response.json()
} catch (error) {
console.error('無法獲取中繼器資訊:', error)
return null
}
}
// 使用
const info = await getRelayInfo('wss://relay.damus.io')
console.log('中繼器:', info.name)
console.log('支援 NIP:', info.supported_nips) 檢查功能支援
function supportsNip(relayInfo, nipNumber) {
return relayInfo?.supported_nips?.includes(nipNumber) ?? false
}
function checkRelayCapabilities(relayInfo) {
return {
hasSearch: supportsNip(relayInfo, 50),
hasAuth: supportsNip(relayInfo, 42),
hasNip04: supportsNip(relayInfo, 4),
hasNip44: supportsNip(relayInfo, 44),
hasDeletion: supportsNip(relayInfo, 9),
hasZaps: supportsNip(relayInfo, 57),
maxLimit: relayInfo?.limitation?.max_limit ?? 100,
requiresAuth: relayInfo?.limitation?.auth_required ?? false,
requiresPayment: relayInfo?.limitation?.payment_required ?? false
}
}
// 使用
const caps = checkRelayCapabilities(info)
if (caps.hasSearch) {
console.log('此中繼器支援搜尋功能')
} 批量檢查中繼器
async function findRelaysWithFeature(relayUrls, nipNumber) {
const results = await Promise.all(
relayUrls.map(async (url) => {
const info = await getRelayInfo(url)
return {
url,
info,
supported: supportsNip(info, nipNumber)
}
})
)
return results.filter(r => r.supported)
}
// 找出支援搜尋(NIP-50)的中繼器
const relays = [
'wss://relay.damus.io',
'wss://nos.lol',
'wss://relay.nostr.band'
]
const searchRelays = await findRelaysWithFeature(relays, 50)
console.log('支援搜尋的中繼器:', searchRelays.map(r => r.url)) 常見中繼器軟體
strfry
高效能中繼器
C++nostr-rs-relay
Rust 實作
Rustnostream
Node.js 中繼器
TypeScriptrelay
Go 語言實作
Gonostr-relay
Python 中繼器
Pythonknostr
Kotlin 實作
Kotlin客戶端使用建議
推薦做法
- • 連接前先獲取資訊
- • 快取中繼器資訊
- • 顯示名稱和圖示
- • 遵守限制條件
注意事項
- • 資訊文件可能不存在
- • 資訊可能過時
- • 設定合理的超時
- • 處理 CORS 問題
提示: 中繼器資訊文件是可選的,不是所有中繼器都會提供。 客戶端應該能夠在沒有資訊文件的情況下正常工作。
已複製連結