Nostr リレー開発
Nostr リレーの開発に必要な情報の調査。
要件
- WebSocket が動くサーバー
- NIP の実装 (wss)
- 認証
- NIP-42
- pubkey ホワイトリスト
- p タグに含まれる場合も許可
- pubkey ホワイトリスト
- NIP-42
- レートリミット
- メンテナンスモード
- スパム対策
- タグが大量に含まれる場合は弾く
- kind 3, NIP-51 が弾かれてしまうのでなし
- タグが大量に含まれる場合は弾く
- NIP-11 の実装 (https, application/nostr+json)
- フロントエンド (https)
- トップページ
- 利用規約
- ステータスページ
- ダッシュボード(管理画面)
- スパム報告一覧
- BAN
- データ削除
- ブロック
- pubkey
- IP アドレス
- テスト
- あるといいかも?
- Webhook
- プッシュ通知
NIP
- NIP-01 Basic protocol flow description
- (NIP-04 Encrypted Direct Message)
- NIP-09 Event Deletion Request
- NIP-11 Relay Information Document
- (NIP-13 Proof of Work)
- (NIP-17 Private Direct Messages)
- (NIP-26 Delegated Event Signing)
- (NIP-29 Relay-based Groups)
- (NIP-40 Expiration Timestamp)
- NIP-42 Authentication of clients to relays
- (NIP-45 Event Counts)
- (NIP-50 Search Capability)
- (NIP-59 Gift Wrap)
- NIP-62 Request to Vanish
- (NIP-66 Relay Discovery and Liveness Monitoring)
- NIP-70 Protected Events
クライアントから送られてくるメッセージとリレーが返すメッセージ
- EVENT
- OK
- NOTICE
- REQ
- フィルターのパース、SQL 化
- EVENT
- EOSE
- CLOSED
- NOTICE
- CLOSE
- NOTICE
- AUTH
- AUTH
- リレーから先に送信
- 接続時または特定の EVENT/REQ に対して
- リレーから先に送信
- OK
- CLOSED
- AUTH
規約
利用規約およびプライバシーポリシーに同意して登録する。
登録した時点で利用規約およびプライバシーポリシーに同意したものとみなします。
利用規約
このサービスは現状のまま提供され、いかなる種類の保証も行いません。また管理者は一切の責任を負わないものとします。
管理者の都合でデータの削除やアクセスの制限を行うことがあります。
違法行為はもちろんスパムなどの迷惑行為も禁止します。
プライバシーポリシー
送信されたデータおよび送信元の情報(IP アドレスなど)を保存します。
送信されたデータは公開されます。暗号化されている場合は暗号化された状態のまま公開されます。
送信元の情報は公開されませんが必要に応じて警察などへ提供される場合があります。
英語
Agree to the Terms of Service and Privacy Policy and register.
By registering, you are deemed to have agreed to the Terms of Service and Privacy Policy.
Terms of Service
This service is provided as is without warranty of any kind. The administrator does not take any responsibility.
The administrator may delete data or restrict access at their discretion.
In addition to illegal activities, nuisance activities such as spam are also prohibited.
Privacy Policy
Transmitted data and sender information (such as the IP address) will be stored.
Transmitted data will be made public. If encrypted, it will be made public in its encrypted state.
Sender information will not be made public, but may be provided to the police, etc. if necessary.
参考
ルーティング
-
example.com
-
/
: トップページ- リレーの説明
- 登録
- 利用規約、プライバシーポリシー
- ユーザー数などの情報
-
/
+Accept: application/nostr+json
: NIP-11 -
/
(wss): WebSocket -
/register
: ユーザー登録
-
-
status.example.com
-
/
: ステータス
-
-
portal.example.com
-
/
: 管理画面
-
Hono
npm create hono@latest
Cloudflare
データベース設計
要件
REQ フィルターは可変のため事前に TL を構築することができない。
DB 全体からデータを効率よく取得する必要がある。
メタデータ
- IP アドレス
- 受信日時
- 登録情報
選定
Durable Objects SQL Storage, D1, KV, TimescaleDB, その他から選択。
D1 + KV にするのが良さそう。後々他の選択肢も選べるようになるとベター。
Durable Objects は GUI がないのでデータ見るときに大変そう。
設計
D1 にすべてを保存すると容量(上限 10GB)的に厳しいのとおそらく肥大化したときにパフォーマンスが出ない。
イベントは KV (上限なし)に保存しつつ REQ に必要なデータだけ D1 に保存するのが良さそう。
id
, pubkey
などの SHA256 データは CHAR(64)
ではなく BINARY(32)
で保存した方がよさそう。
events
KV
- id => event
D1
[events]
- id BLOB (32 bytes)
- pubkey BLOB (32 bytes)
- kind INTEGER
- tags TEXT
- created_at INTEGER
[tags をテーブル分ける場合]
- id BLOB
- name TEXT
- value TEXT
- created_at INTEGER
SELECT id FROM tags WHERE name = ? AND value = ?;
SELECT * FROM events WHERE pubkey = ?
AND id IN (SELECT id FROM tags WHERE name = ? AND value = ?) -- #t
AND id IN (SELECT id FROM tags WHERE name = ? AND value = ?) -- #p
SELECT * FROM events WHERE pubkey = ?
INNER JOIN tags ON events.id = tags.id AND name = ? AND value = ? -- #t
INNER JOIN tags ON events.id = tags.id AND name = ? AND value = ? -- #p
connections
KV or D1
- connection_id TEXT (challenge を使える?)
- ip_address
- pubkey
registrations
KV or D1
- pubkey
Cloudflare D1