Nimstr
Nostr SDK for Nim
About
Nimstrは、Nim言語のための Nostr SDK だにゃん。 鍵生成、イベントの署名・送信、リレー接続、Bech32エンコードなど、 Nostrプロトコルを扱うための機能を提供するにゃ。MITライセンス。バージョン 0.2.0。 GitHub で公開中にゃ。
Installation
nimble install https://github.com/LunaYoineko/nimstr
.nimbleのdependenciesに requires "nimstr" を追加してにゃ。
Quick Start
import std/asyncdispatch import nimstr proc main() {.async.} = let keypair = generateKeypair() echo "npub: ", keypair.npub let relay = newRelayClient("wss://relay.damus.io") await relay.connect() let ok = await relay.sendTextNote(keypair.seckeyHex, "Hello, Nostr!") echo "Sent: ", ok await relay.close() waitFor main()
Types
NostrKeypair
seckeyHex, pubkeyHex, nsec, npub
鍵ペアを保持するオブジェクト
NostrEvent
id, pubkey, createdAt, kind, tags, content, sig
Nostrイベントのデータ構造
NostrFilter
ids, authors, kinds, since, until, limit
イベント購読フィルター
RelayClient
url, ws, connected
単一リレーへの接続を管理
RelayPool
relays
複数リレーを束ねて管理
UserProfile
name, display_name, about, picture, nip05, banner, website, lightning_address, rawJson
ユーザープロフィール
ReplyTarget
eventId, relayUrl, authorPubkey
返信先イベントの指定
ThreadContext
rootEventId, replyEventId, mentionedPubkeys
スレッドコンテキスト
API Reference
Key Generation
generateKeypair(): NostrKeypair 新しい鍵ペアを生成。nsec/npubも同時に生成。
keypairFromSecret(secretInput: string): NostrKeypair 16進数の秘密鍵またはnsecから鍵ペアを復元。
Relay / Pool Management
newRelayClient(url: string): RelayClient 単一リレークライアントを作成
newRelayPool(urls: seq[string]): RelayPool 複数リレークライアントを作成
connect(relay: RelayClient) リレーにWebSocket接続
connectAll(pool: RelayPool) プール内の全リレーに接続
close(relay: RelayClient) 切断
closeAll(pool: RelayPool) 全リレー切断
Event Publishing
sendEvent(relay, seckeyHex, kind, tags, content): Future[bool] 任意のkindのイベントを送信
sendEventAll(pool, seckeyHex, kind, tags, content): Future[int] 全リレーにイベントをブロードキャスト
sendTextNote(relay, seckeyHex, content, extraTags=nil): Future[bool] テキストノート(kind 1)を送信
sendTextNoteAll(pool, seckeyHex, content, extraTags=nil): Future[int] 全リレーにテキストノートをブロードキャスト
sendReply(relay, seckeyHex, content, replyTo, extraTags=nil): Future[bool] イベントに返信(reply)
sendRootReply(relay, seckeyHex, content, replyTo, extraTags=nil): Future[bool] イベントに返信(root)
sendReplyAll(pool, seckeyHex, content, replyTo, extraTags=nil): Future[int] 全リレーに返信をブロードキャスト
sendRootReplyAll(pool, seckeyHex, content, replyTo, extraTags=nil): Future[int] 全リレーにroot返信をブロードキャスト
deleteEvent(relay, seckeyHex, eventIdHex, reason=""): Future[bool] イベント削除(kind 5)
deleteEventAll(pool, seckeyHex, eventIdHex, reason=""): Future[int] 全リレーでイベント削除
sendProfile(relay, seckeyHex, profile): Future[bool] プロフィール更新(kind 0)
fetchProfile(relay, subscriptionId, pubkeyHex) プロフィール購読
Subscription
subscribe(relay, subscriptionId, filter) フィルターでイベント購読開始 (REQ)
subscribeAll(pool, subscriptionId, filter) 全リレーで購読開始
closeSubscription(relay, subscriptionId) 購読終了 (CLOSE)
closeSubscriptionAll(pool, subscriptionId) 全リレーで購読終了
Crypto / Utility
computeEventId(pubkey, createdAt, kind, tags, content): string イベントIDの計算
signEventId(seckeyHex, eventIdHex): string イベントIDにSchnorr署名
toBech32(hrp, hexStr): string 16進数文字列をBech32エンコード
fromBech32(bechStr): tuple[hrp, hex] Bech32文字列をデコード
parseUserProfile(contentStr): Option[UserProfile] JSONからプロフィールをパース
parseThreadContext(eventTags): ThreadContext イベントタグからスレッドコンテキストを解析
Examples
basic.nim — 基本操作
import std/[asyncdispatch, json] import nimstr proc main() {.async.} = let alice = generateKeypair() echo "Alice npub: ", alice.npub let restored = keypairFromSecret(alice.nsec) assert restored.pubkeyHex == alice.pubkeyHex let relay = newRelayClient("wss://relay.damus.io") await relay.connect() let ok = await relay.sendTextNote(alice.seckeyHex, "Hello from Nimstr!") var filter = NostrFilter(kinds: @[1], limit: 3) await relay.subscribe("test", filter) for i in 0..<10: let msg = await relay.ws.receiveStrPacket() let json = parseJson(msg) if json[0].getStr() == "EVENT": echo "Received: ", json[2]["content"].getStr() elif json[0].getStr() == "EOSE": break await relay.closeSubscription("test") await relay.close() waitFor main()
鍵生成 → リレー接続 → テキストノート送信 → イベント購読 → 受信 → 切断
reply_bot.nim — 自動返信ボット
import std/[asyncdispatch, json, strutils] import nimstr proc replyToMentions(botKeypair: NostrKeypair) {.async.} = let relay = newRelayClient("wss://relay.damus.io") await relay.connect() await relay.subscribe("bot", NostrFilter(kinds: @[1])) while true: let msg = await relay.ws.receiveStrPacket() let json = parseJson(msg) if json[0].getStr() != "EVENT": continue let pubkey = json[2]["pubkey"].getStr() if pubkey == botKeypair.pubkeyHex: continue let target = ReplyTarget( eventId: json[2]["id"].getStr(), relayUrl: "wss://relay.damus.io", authorPubkey: pubkey ) let ok = await relay.sendReply( botKeypair.seckeyHex, "Echo: " & json[2]["content"].getStr(), target )
イベントを監視して自動返信するボット。ReplyTargetで返信先を指定。