Nostr Compassへようこそ。Nostrの週刊ガイドです。

今週の内容: Amethystが、ピン留めノート、NIP-86経由のrelay管理、NIP-62 Request to Vanishサポートを備えたv1.07.0を出荷しました。NIP-5A(静的ウェブサイト)がNIPsリポジトリへマージされ、Blossomストレージを使ってNostrキーペア配下でサイトをホストする方法を定義しました。Flotillaは、voice rooms、email/password login、proof-of-work DMを含むv1.7.0を出荷しました。White Noisev2026.3.23でrelay churnを修正し、nospeakはサインアップ不要の暗号化メッセンジャーとして1.0.0を開始しました。Nymchatgroup chats向けにMarmotを採用し、Calendar by Form*はプライベートカレンダーリストとICS importを備えたv1.0.0へ到達し、Ambermnemonic recoveryとNIP-42 relay auth whitelistを追加し、Marmot specはKeyPackagesをアドレス可能イベントへ移してMIP-05 push notification形式を厳格化しました。

ニュース

Amethystがピン留めノート、relay管理、Request to Vanishを出荷

AmethystはvitorpamplonaがメンテナンスするAndroidクライアントで、3日間に6リリース、v1.07.0からv1.07.5までを出荷しました。目玉機能群は6つのプロトコルサーフェスにまたがっています。ピン留めノート、専用ポールフィード画面、relayへ完全なイベント削除を求めるNIP-62(Request to Vanish)サポート、クライアント内からのNIP-86(Relay Management API)、relay情報画面内のNIP-66(Relay Discovery and Liveness Monitoring)評価、そしてNIP-43(Relay Access Metadata and Requests)のメンバー情報表示です。

NIP-86はrelayオペレーター向けのJSON-RPCインターフェースを定義し、pubkeyのBAN、pubkeyの許可、BANユーザー一覧の取得といった管理コマンドを標準化API経由でクライアントから送れるようにします。Amethystはこれをrelay管理UIに直接公開したため、自分のrelayを運用するユーザーは、投稿に使うのと同じクライアントから運用管理もできるようになりました。PR #2039は、BANおよび許可pubkeyの旧来のhex入力ダイアログを、対話型のユーザー検索ダイアログへ置き換えています。

v1.07.2ではGIF keyboard uploadsが追加され、旧Amberバージョンがrejectedフィールドに空文字列を返していたために起きていた署名リグレッションも修正されました(PR #2042)。v1.07.5では画像アップロード時クラッシュが修正されています。同週前半のv1.06.2v1.06.3では、単一選択と複数選択ポールの切り替え、動画プログレスバーのdrag-to-seek、匿名投稿の改善が入っていました。

NIP-5Aがマージ、Nostrに静的ウェブサイトをもたらす

NIP-5A(静的ウェブサイト)がPR #1538経由でマージされ、Nostrキーペア配下で静的ウェブサイトをホストする方法を定義しました。仕様は2つのイベントkindを使います。kind 15128はpubkeyごとに1つのroot site用、kind 35128dタグで識別されるnamed site用です。各manifestはURL pathをSHA256 hashへ対応づけ、実ファイルが置かれているBlossomストレージホストを指すserverタグをオプションで持てます。

ホスティングモデルは次のように動きます。サイト作者が静的サイトをビルドし、ファイルを1つまたは複数のBlossomサーバーへアップロードし、その後にpathとcontent hashの対応表を持つ署名済みmanifestイベントを公開します。ホストサーバーはWebリクエストを受けると、subdomainから作者のpubkeyを解決し、作者のNIP-65 relay listからmanifestを取得し、対応するblobをBlossomからダウンロードして配信します。更新manifestに署名できるのはその鍵だけなので、サイトの制御権は作者の側に残ります。NIP-5Aを理解するサーバーならどれでも同じmanifestから同じサイトを配信できるため、ホストサーバー自体は置き換え可能です。

この仕様はすでに存在していたインフラの上に乗っています。lezによるNIP-5Aのreference host実装nsiteと、hzrd149による管理UInsite-managerは、NIPがマージされる前から稼働していました。今回のマージにより、イベントkindとURL解決ルールが公式化され、2つ目3つ目の実装にとって安定したターゲットが生まれました。

White Noiseがrelay churnを修正し、クライアント制御を拡張

White NoiseMarmotプロトコル上のプライベートメッセンジャーで、3月25日にv2026.3.23を出荷しました。主な作業はrelay安定性です。relay list publishはquorum logicを使い、残りをバックグラウンドで再試行するようになったため、ログインはすべてのrelay-list publish完了を待たずに先へ進めるようになりました。単発のfetchとpublishは長寿命poolに残留せず、スコープ付きの一時relay sessionを使います。復元されたsessionは起動後にgroup refresh pathを回復し、アプリはPR #495PR #502を通じてrelay diagnosticsとrelay state inspectionを公開しました。

同じリリースでは会話の振る舞いも変わりました。PR #468qタグとnostr:nevent参照を使うNIP-C7 reply threadingを追加し、PR #471PR #512が削除メッセージを静かに消すのではなく削除済みプレースホルダーとして見せるようにし、PR #478NIP-44(暗号化ペイロード)を使った匿名バグレポートフローを入れ、PR #486がクライアント内サポートチャットを追加しました。ユーザー向けメッセージ制御も同期間に入り、PR #532はchat archive、PR #541は期間指定可能なmute/unmute、PR #535はnotification settingsを追加しています。PR #539はpush登録の準備作業で、iOSではAPNs登録、AndroidではPlay Services検出を配線し、その上に登録処理を積める状態にしました。バックエンド側ではMDKがMIP-05 push notification primitivesとnotification request builderを追加し(PR #235PR #238)、whitenoise-rsはpush notification登録の永続化(PR #688)、バックグラウンドタスクキャンセル修正(PR #696)、起動時のkey package回復(PR #693)を追加しました。

Nostr VPNがv0.3.0に到達し、roster syncとinvite v2を追加

先週のローンチ記事に続き、Nostr relayをシグナリングに、WireGuardを暗号化トンネルに使うP2P VPNのnostr-vpnは高速なリリースペースを維持し、v0.3.3まで進みました。このバージョン更新では2つの破壊的変更が入っています。invite formatがv2へ移行し(0.3.0はv1 inviteをまだimportできますが、旧ビルドはv2 inviteをimportできません)、シグナリングプロトコルにadmin署名付きroster syncが追加されました。バージョンが混在するpeer同士でもmesh層では接続できますが、古いpeerはroster同期には参加しません。

roster syncの追加は、managed networkへの移行の始まりです。admin nodeが全peerにmembership変更をpushできるようになり、meshへのデバイス追加や削除のたびに各peerが手動で設定を更新する必要がなくなります。同週のv0.2.xリリース群は具体的なデプロイ問題を修正しており、v0.2.22からv0.2.28ではWindows service管理、Android build scripts、LAN pairing flowの改善が入っています。

nospeakが1.0プライベートメッセンジャーとしてローンチ

nospeakはNostr上のプライベートメッセンジャーで、3月27日に1.0.0を出荷しました。プロジェクトは1対1会話、グループ会話、連絡先管理、self-hostableアーキテクチャを含みます。1対1チャットはNIP-17(プライベートダイレクトメッセージ)を使い、これはNIP-59(Gift Wrap)とNIP-44(暗号化ペイロード)を組み合わせることで、relayから送信者を隠します。メディアについては、ファイルはBlossomサーバーへアップロードされる前にクライアント側でAES-256-GCM暗号化されます。このリリースはself-hosting向けcontainer imageとしても配布されています。

Flotilla v1.7.0がvoice roomsとemail loginを追加

Flotillaは、hodlbodによるDiscord風NIP-29(Relay-based Groups)クライアントで、「relays as groups」モデルを中心に構築されています。3月30日と31日にv1.7.0およびv1.7.1を出荷しました。目玉機能はmplorentzによるvoice roomsです。ユーザーはグループchannel内でvoice callへ参加できるようになり、join dialog(PR #109)ではaudio input deviceの選択と、音声通話に参加するかテキストチャットだけを見るかを選べます。このダイアログは前段のUX問題を解決します。以前はvoice対応roomへ入ると、メッセージ閲覧や設定確認だけが目的でもマイクが強制的に有効化されていました。

同じリリースには、Nostr鍵ベース認証の代替となるemail/password login、DMへのproof-of-work、DM編集、再設計されたrelay onboardingとsettings、supported_nips経由のBlossomサポート検出、改善されたnotification badges、Android push notification fallback、Androidでのfile upload修正も入っています。v1.7.1ではoffline signer使用時のpomade registration fallbackも修正されました。

hodlbodは同時にzooid relay向けのhosting managerおよびdashboardであるCaravelも構築しており、初期開発だけで今週40コミットを記録しています。

NymchatがMarmotベースのgroup chatsを出荷

Nymchat(NYM、Nostr Ynstant Messengerとしても知られます)はBitchatとbridgeされたエフェメラルチャットクライアントで、すべての新しいグループチャットがMarmotプロトコルを使うMLS暗号化メッセージングへ移行したと発表しました。この統合では、key packages、welcome messages、group messagesにそれぞれkinds 443444445を使い、forward secrecy、post-compromise security、metadata leakageゼロを提供します。受信者がMLSを使えない場合、Nymchatは従来のNIP-17(プライベートダイレクトメッセージ)ベースのgroup chat pathにフォールバックします。こちらもエンドツーエンド暗号化ですが、MLSのratchet-tree特性は持ちません。

今週のv3.55およびv3.56系列は、新規デバイスでの読み込み、leave動作、notification routing、未読badge countといったgroup chatの境界ケースに集中していました。同じサイクルでは、エスケープされていないHTMLに起因するXSS脆弱性の修正と、user nicknameにも拡張されたkeyword/phrase blockingも入りました。これによりNymchatは、White NoiseOpenChatに続くもう1つのMarmotクライアントとなり、同じプロトコル上でMLS暗号化group messagesを交換できるアプリ群を広げています。

リリース

Calendar by Form* v1.0.0

Calendar by Form*NIP-52(カレンダーイベント)上に構築された分散カレンダーアプリで、3月29日にv1.0.0へ到達しました。このリリースは、暗号化Nostrイベント(kind 32123)とNIP-44(暗号化ペイロード)の自己暗号化を使うprivate calendar listsを追加し、relayへそのグルーピングを明かさずにイベントを私的コレクションへ整理できるようにします。同じリリースでは、他アプリからカレンダーデータを取り込むICS intent handlingと、ユーザー間でイベントを共有するinvitation requestsも追加されました。

Amber v5.0.2 から v5.0.4

AmberNIP-55(Android署名アプリケーション)署名者アプリで、3つのポイントリリース、v5.0.2v5.0.3v5.0.4を出荷しました。最も目に見える追加は、raw nsecやncryptsec文字列を要求せず、BIP39 seed phraseからsignerを復元できるmnemonic recovery phrase login(PR #358)です。PR #357NIP-42 relay auth whitelistを追加し、どのrelayがclient authenticationを要求できるかをユーザーが制限できるようにしました。PR #353はdecrypt permission向けのencryption scope選択を追加し、包括的権限ではなくNIP-04専用あるいはNIP-44専用のdecrypt accessを付与できるようにしています。v5.0.4では、scoped encrypt/decrypt permissionsが拒否処理に正しく反映されないバグが修正され、複数のbunker request受信時の性能も改善されました。

Aegis v0.4.0

Aegisはクロスプラットフォーム署名者で、3月26日にv0.4.0を出荷しました。このリリースではSettingsにFullおよびSelective authorization modesが追加され、複数のQRスキャン問題も修正されています。追随するコミットd4f799f3313af93b214e4e4f40b6では、この方向をさらに進め、batch select controls、再利用可能なbatch selection stats、set-all-groups selection APIs、app permissionsページ上のpermission別使用統計を追加しています。

Schemata v0.2.7 から v0.3.0

SchemataはNostrイベントkind検証用のJSON Schema定義群で、v0.2.7からv0.3.0まで4リリース、21件のマージ済みPRを出しました。v0.3.0では、relay URL、hex ID、MIME type、BOLT-11文字列にわたるpattern consistency修正(PR #126)、relay URL patternの集中管理(PR #117)、NIP-19 bech32 base type schema(PR #118)、kind 777 spellイベントの検証(PR #125)が入りました。release pipelineは各リリース時にNostrへkind 1 noteも公開するようになり(PR #120)、プロジェクト自身が検証対象のプロトコルを通じて自らを告知します。Schemataは、canonicalなJS/TSパッケージ以外に、Rust、Go、Python、Kotlin、Java、Swift、Dart、PHP、C#/.NET、C++、Ruby、Cの計12超の言語をサポートするようになりました。

Schemataと並行して、チームはschemata-codegenも公開しました。これは同じ検証問題に対して別アプローチを取る実験的コードジェネレーターです。Schemataのvalidator packagesがJSON Schema runtime dependencyを必要とするのに対し、schemata-codegenはschemaをtyped tag tuples、kind interfaces、runtime validatorsといったネイティブ言語構造へ直接移植することで、実行時にvalidator libraryを不要にします。codegen-vs-validators比較は、どちらのアプローチがどの場面に適するかを文書化しています。

BigBrotr v6.5.0 から v6.5.4

BigBrotrはrelay分析プラットフォームで、v6.5.0からv6.5.4まで5リリースを出荷しました。v6.5.0では、parse_relay_url() factory functionによるrelay URL validationの集中化、URL length checking、path sanitizationが入りました。monitoring基盤にも修正があり、announcementイベントはNIP-52にならったgeohash location tagsを含むようになり、期限のなかったGeo/Net NIP-66 metadata testsにはtimeout protectionが追加され、無期限ハングを防いでいます。PR #410はPostgreSQLを16から18へ上げており、async I/O subsystemとWAL throughput改善がrelay analytics pipelineに入っています。

Vertex Lab relayがNIP-50プロフィール検索を追加

Vertex Labnpub.worldVertex Web of Trust engineを手がけるチームで、wss://relay.vertexlab.ioがプロフィールクエリ向けにNIP-50(検索)をサポートしたと発表しました。NIP-50は標準Nostr REQ filterにsearchフィールドを拡張し、relayがindexを持つ場合にクライアントが全文検索クエリを送れるようにします。Web of Trustデータも提供するrelayにプロフィール検索が入ることで、relay.vertexlab.ioへ接続するクライアントは別検索サービスなしに名前や説明からユーザーを発見できます。

Hashtree v0.2.17 と v0.2.18がWebRTCメッシュとIris Desktopを出荷

Hashtreeはmmalmiによる、Merkle rootをNostrへ公開するcontent-addressed blob storage systemで、3月31日にv0.2.17v0.2.18を出荷しました。この2リリースは30コミットのスプリントを締めくくるもので、3つの機能が加わっています。1つ目はhashtree-webrtc crate(v0.2.18でhashtree-networkへ改名)によるWebRTCベースのP2P blob配布で、Rust CLI、simulation harness、TypeScript clientにまたがる統一mesh signalingを追加します。2つ目はrelease pipelineがWindows artifacts(CLI zipとIris installer)をビルドするようになったことで、macOS、Linux、Windowsのクロスプラットフォーム対応が整いました。3つ目は、両リリースがIris Desktop 0.1.0、すなわちmmalmiのNostr social clientを、AppImage、.deb、Windows installer assetとしてhashtree CLIと一緒に同梱していることです。HashtreeはNewsletter #10で、filesystemベースのBlossom互換ストアとして初めて取り上げました。今回のWebRTC層は、中央集権的Blossomサーバーに依存しないP2P content distributionへの第一歩です。

Nostr Mail Client v0.7.0 から v0.7.2

Nostr Mail ClientはNostrアイデンティティ上に構築されたFlutter製メール風クライアントで、3日間でv0.7.0v0.7.1v0.7.2を出荷しました。見えるプロダクト作業はオンボーディング(PR #9)とプロフィール編集(PR #10)に集中しており、Nostrをメールボックスとして提示しようとするクライアントにとって基本的な部品です。後続のポイントリリースはこの作業を新しいAndroidおよびLinuxビルドへパッケージしました。

Wisp v0.14.0 から v0.16.1

WispはAndroid Nostrクライアントで、今週さらにv0.14.0-betaからv0.16.3-betaまで13リリースを出しました。作業内容には、NIP-17 rumor JSON修正(PR #385)、gallery cards上のrepost badges(PR #383)、展開可能なreaction details(PR #382)、永続emoji sets(PR #381)、video autoplay controls(PR #380)が含まれます。最新のv0.16.3-betaでは、ハイフンを含むcustom emoji shortcodeと欠落emoji tagsも修正されています。

Primal Android 3.0.17

Primal Androidは3月24日に3.0.17を出荷しました。PR #1000はWalletExceptionの型をNWC response内のerror codeへ対応付け、NIP-47クライアントに汎用エラーではなく構造化された障害情報を返します。PR #995はpoll zap votesがTop Zapsとして見えてしまう問題を修正し、PR #998はwallet未設定時に残高とaction buttonsを非表示にします。

OpenChat v0.2.4 から v0.3.0

OpenChatMarmotスタック上に構築されたAvaloniaベースのチャットクライアントで、4日間でv0.2.4からv0.3.0まで6リリースを出荷しました。commit logは、「Marmotが動く」から「誰かが日常的に使える」までの隙間を埋めていくクライアントの過程を示しています。NIP-42 relay authenticationが入り、それに続いてduplicate event filteringを持つrelay picker UIも入りました。voice messagesはpause、resume、seek、時間表示を獲得しました。signer pathも強化され、更新されたNIP-46 URI formatによってAmber接続が修正され、WebSocketはrequest送信前に自動再接続するようになり、replayed responseを検査することでduplicate Amber requestsも捕捉されます。ストレージ面では、LinuxとmacOSにAES-256-GCM secure storageとfile-backed keysが入り、user metadata fetchはNIP-65 relay discoveryを使ってローカルデータベースにキャッシュされるようになりました。

Igloo Signer 1.1

IglooはFROSTRプロジェクトによるiOS向けFROST threshold signerで、3月28日にv1.1を出荷しました。FROST(Flexible Round-Optimized Schnorr Threshold)署名は、署名者のグループが共同で1つのNostrキーペアを制御し、単一の当事者が完全な秘密鍵を保持しないまま、t-of-n参加者でイベント署名できるようにします。Iglooは、Nostr向けにこのアプローチを実装した最初期のモバイル実装の1つです。

nak v0.19.3 と v0.19.4

fiatjafのコマンドラインNostrツールキットnakが、3月26日と30日にv0.19.3v0.19.4を出荷しました。どちらのリリースもpanic条件を修正しています。PR #118strings.Splitstrings.Cutへ置き換え、潜在的なout-of-bounds accessを防ぎます。PR #119はcurl flag parsingでも同種のpanicを防ぎます。

Flora v0.3.0

Floraは、Nostr上で分散スクリーン録画と共有を行うChrome拡張で、v0.3.0を出荷しました。このリリースは、public、unlisted、private modeを備えたprivate encrypted video sharingを追加します。private録画はAES-256-GCMで暗号化され、NIP-17(プライベートダイレクトメッセージ)経由で受信者に渡されるため、録画は平文のままサーバーに触れません。

YakiHonne Mobile 2.0.3

YakiHonneはモバイルNostrクライアントで、relay reviewsとjoin requests、拡張されたnested replies、ノートのauto-translation、NWC multi-relay supportを含む2.0.3を出荷しました。

プロジェクトアップデート

Zap Cookingがzap pollsとBranta支払い検証を追加

Zap Cookingはレシピおよびcontentプラットフォームで、今週11件のPRをマージしました。焦点はinteractive contentとpayment flowsです。PR #277はkind 6969のzap pollsを追加し、ユーザーはsatsを送って投票し、プロフィール画像付きで投票者一覧を見られるようになりました。PR #274は投票インターフェースがフィード内で自然に見えるようpoll UXを再設計しています。

PR #276はSend Payment flowにcamera-based QR scanningを追加し、送信先が正当かどうかを送信前に確認する検証サービスBrantaを統合しました。Brantaは送信前に支払い先をphishing、address swaps、man-in-the-middle interceptionに対して検査します。Zap Cookingでの実装では、Brantaにより検証されたplatform nameとlogoが支払いフロー内に直接表示され、Branta対応QRコードはbranta_idbranta_secretパラメータを持てるため、walletはスキャンされたコード自体から送信先を検証できます。

diVineが統一検索の基盤を敷き、動画配信を強化

diVineは短尺動画クライアントで、今週は検索、feed navigation、playback recovery、upload behaviorの強化に取り組みました。PR #2540は、Videos、People、Tagsのグループ化セクションを持つ統一検索画面の基礎を敷きます。PR #2623は、profile feeds、inbox、notifications、discover lists、classic vines、search、composable grid feedsにわたるpaginationを共通pagination controllerへ移すことで全体を強化しました。

動画配信にも具体的な修正がいくつか入りました。PR #2643はDivineホスト由来の派生ソースを順番に再試行し、それでもだめならraw blobへフォールバックしてからplayback errorを出すようにし、1つのソースの一時障害で即座に再生失敗にならないようにします。PR #2634はcapability probingが一時的に失敗してもresumable uploadをDivine所有パスに維持し、短時間のネットワーク障害でuploadが壊れることを減らします。PR #2637はsensitive-content gateも変更し、実際のwarning labelsがある動画のみをハードゲートし、単に作者が付けたcontent warning labelだけではゲートしないようにしました。

Shopstrがカスタムstorefrontを追加し、Milk Marketが引き続きマーケットプレイス作業を進める

ShopstrはNostrベースのマーケットプレイスで、PR #245をマージしてcustom storefrontsを追加しました。これにより、売り手はすべてのlistingが同じ汎用表示に押し込まれるのではなく、より独自性のあるhome surfaceを持てます。

Milk Marketは牛乳に特化した専用マーケットプレイスで、storefront最適化(PR #18)、account recovery(PR #17)、beef splits(PR #15)、MCP tool typing fixes(PR #16)を継続しています。

Notedeckが効果音を追加し、Android向けupdater pathを拡張

NotedeckはDamusチームによるデスクトップクライアントで、rodioを使ったUI interaction soundsを含むsound effects subsystemを追加するPR #1412と、CLI title flagや折りたたみ可能なsession foldersを含むAgentium更新を入れるPR #1399をマージしました。オープンなPR #1417は、Android上でNostr/Zapstore経由のAPK self-updateを提案しており、Newsletter #14で扱ったNotedeckのNostrネイティブupdater作業をさらに先へ進めています。

Nostriaがrepost relay hintsとNIP-98整合を追加

Nostriaは、kind 6およびkind 16イベントのrepost e tagsへNIP-18(Reposts)relay hintsを追加するPR #583、Brainstorm HTTP auth(kind 27235)をNIP-98(HTTP認証)の必須タグへ合わせるPR #582、Schemata schema validation testsを追加するPR #576をマージしました。NIP-98の変更により、Nostriaは他クライアントと同じHTTP auth形式で外部サービスへ認証できるようになります。

Nostr-Docがデスクトップパッケージングとoffline-first作業を追加

Nostr-DocはForm*による共同編集ツールで、今週はパッケージングとエディター作業が活発でした。commit fcdc00aがデスクトップアプリを追加し、commit 3977a8eがネイティブアプリ作業を始め、commit 413a030がアプリをoffline-first挙動へ近づけています。エディター側ではcommit 1855ce8がCtrl+S保存、保存警告、link preview修正、strikethrough描画修正を追加しました。

rust-nostrがNIP-21解析を最適化し、relay側NIP-62サポートを追加

rust-nostrは8件のPRをマージしました。最も注目すべきは、NIP-21 URI解析を標準bech32解析性能に合わせる形でPublicKey::parse内で最適化するPR #1308です。以前はNIP-21 URIの解析にraw bech32 keysの約2倍の時間がかかっていました。加えて、このプロジェクトにはmemory、LMDB、SQLite、database test backendsそれぞれへrelay固有のNIP-62(Request to Vanish)サポートを追加する4つのオープンPRもあります(PR #1315PR #1316PR #1317PR #1318)。

nostr-toolsがbunker relay制御を追加し、NIP-47 multi-relay parsingを修正

nostr-toolsは、manual relay management向けにBunkerSignerParamsへskipSwitchRelaysを追加するPR #530と、仕様が許す複数relayに対応するためNIP-47(Nostr Wallet Connect)接続文字列解析を修正するPR #529をマージしました。

NostrabilityがSherlock audit dataを統合し、Schemata overviewを公開

NostrabilityはNostrクライアント向け相互運用性trackerで、14件のPRをマージしました。PR #306はdashboardへSherlock scan statisticsを統合しています。SherlockはNostrabilityの自動監査ツールで、Nostrクライアントへ接続し、公開されたイベントを取得し、各イベントをSchemata JSON Schema定義に照らして検証し、仕様違反を検出します。dashboardは現在、クライアントごとのschema fail rateを表示し(PR #315)、開発者が自分のクライアントがどのイベントkindを誤っているかを確認できるようにしています。PR #323はNostr publish workflowも刷新し、release announcementを、先行CIステップにキャンセルされない別jobとして実行するようにしました。

elsatは3月30日に、Schemata for nostr devsも公開しました。ここではschemata、schemata-codegen、Sherlockがどう組み合わさるかが説明され、現時点のカバレッジ数、65 NIPsにまたがる179のevent kind schema、154のtag schema、13のprotocol messages、310のsample eventsが示されています。

Nalgorithmがdigest生成とローカルscore cachingを追加

Nalgorithmは新しいrelevance-ranked Nostr feedプロジェクトで、今週public developmentを開始しました。commit cf6c501は、followからpostを取得し、ユーザー定義のpreference promptに照らしてscore付けする初期Webアプリを構築します。commit 8e931b6はトップランク投稿をspoken-word summaryへ変換するCLI digest toolを追加し、commit 4cb9c63はfile-based score cachingとrecent likesからのincremental learned-prompt evolutionを追加しました。commit c2edfb8は失敗したbatchのfallback scoresをキャッシュしないようにもしており、一時的なscoring failureでpost rankが恒久的に平坦化されることを防いでいます。

TENEXがRAG vector storeとtargeted MCP startupを追加

TENEXは、AIエージェントをTelegram経由でNostr channelへ接続するNostrネイティブのagent frameworkで、今週7件のPRをマージしました。PR #101はSQLite-vec、LanceDB、Qdrant backendsを持つpluggable vector store abstractionを追加し、特定のvector databaseに縛られないretrieval-augmented generationをエージェントへ提供します。PR #102はMCP startupをtargeted化し、最初の実行時に全MCPサーバーを起動する代わりに、エージェントが実際に使うtoolsを持つサーバーだけを起動するようにしました。PR #100send_message toolを追加し、Telegram channel bindingを持つagentが、受信メッセージに応答するだけでなく自発的にメッセージをpushできるようにします。PR #106.git/HEADを直接読むことで、subprocess起動に伴って発生していた9GBのBun/JSCメモリ事前確保を回避しました。

Dart NDKがAmber signerを移し、Alby Go 1-clickを追加

Dart NDKはFlutter向けNostr development kitで、11件のPRをマージしました。PR #525はAmber signer supportをndk_flutter packageへ移し、PR #552はsample appにAlby Goのone-click wallet connectionを追加します。PR #502はCLI向けinstall.sh scriptを追加し、PR #523はnative asset handlingを優先してRust verifier dependencyを削除しました。

Protocol and Spec Work

MarmotがKeyPackagesをアドレス可能イベントへ移し、push notificationsを厳格化

Marmot specificationは、プロトコルが鍵素材とgroup membershipを扱う方法を変える4件のPRをマージしました。PR #54はKeyPackageイベントを通常のkind:443からdタグ付きのアドレス可能kind:30443へ移行し、鍵ローテーション時にNIP-09イベント削除を使う必要をなくします。アドレス可能イベントは上書き更新されるため、rotationが自己完結します。PR #57は非adminユーザーによるSelfRemove proposals(自発的なgroup離脱)コミットを許可し、PR #62はadminがSelfRemoveを使う前にadmin statusを relinquish することを要求し、高権限を保持したまま消えることを防ぎます。

PR #61MIP-05 push notification formatも厳格化し、single-blob base64 encoding、versioning、token wire format、x-only key使用法を明示しました。その結果、spec、client libraries、app backendsの間でtoken blobsとx-only keysに対して1つの定義済みwire representationが得られます。これらのspec変更の実装は今週White Noiseスタックへ入り、上のWhite Noise v2026.3.23セクションで取り上げました。

NIPアップデート

NIPsリポジトリへの最近の変更:

マージ済み:

  • NIP-5A: 静的ウェブサイトPR #1538):Blossomストレージを使い、Nostrキーペア配下で静的ウェブサイトをホストするためのkind 15128(root site)およびkind 35128(named site)manifestイベントを定義します。詳しくは下のディープダイブを参照してください。

  • NIP-30(カスタム絵文字): shortcodeでハイフンを許可PR #2297):shortcode記述がハイフンを含められるよう更新されました。ハイフン入りshortcodeは実際にはNIP導入当初から使われており、今回の仕様変更は現在の利用実態を文書化するものです。

オープンPRとディスカッション:

  • NIP-C1: Agent TUI MessagesPR #2295):暗号化DM経由でagentが対話的UI要素を送るための構造化メッセージ形式を提案しています。typed textbuttonscardtable payloadsを含みます。ドラフトは既存のNIP-17およびNIP-04ダイレクトメッセージcontent内にJSONとして収め、新しいイベントkindは定義せず、button responsesには単純なcallback文字列形式を使います。

  • NIP-95: Hybrid Peer-to-Peer Relay ProtocolPR #2293):relayが権威を保ちつつ、最近のイベントをWebRTC経由でP2P配布する調整役にもなるハイブリッドrelayモデルを提案します。ドラフトではPEER_REGISTERPEER_REQUESTPEER_OFFERなどのrelay messageを導入し、安定したクライアントがSuper Peersとして振る舞い、relayがseed node兼fallbackとなります。

  • NIP-B9: Zap Poll EventsPR #2284):NIP-88(Polls)が無料ポールをカバーした後、古いNIP-69 zap-poll案を再始動する提案です。ドラフトはkind 6969のpoll定義とkind 9734のzapsを投票として使い、経済的Sybil耐性を持つ有料ポーリングシステムにします。無料の1鍵1票ポールを補完します。

  • NIP-AD: Super ZapPR #2289):relayのpubkeyやクライアントのpubkeyへ送られたzapsを、特化したプロモーションノートとして表示する慣例を提案しています。relayオペレーターやクライアントはlud16付きプロフィールを公開し、そのreceiptを取得し、zap description内の埋め込みcontentを抽出し、必要に応じて最小sats閾値でspamを抑制します。

  • NIP-XX: Agent Reputation AttestationsPR #2285):Nostrエージェントに対する構造化reputation attestations向けのparameterized replaceable eventとしてkind 30085を提案しています。ドラフトは単一のグローバルスコアを避け、reputationを観測者依存とし、古いattestationが薄れていくtemporal decayを追加し、証拠要件付きnegative ratingsをサポートし、より良いSybil耐性に向けた単純weighted scoringとgraph-diversity scoringの両方を概説します。

  • NIP-XX: Paid API Service AnnouncementsPR #2291):有料HTTP APIsを広告するためのkind 31402アドレス可能イベントを提案し、発見はNostr、支払いはHTTP 402処理を使います。ドラフトはtags-first設計なので、relayはJSON contentを解析せずに支払い方法、価格、能力でfilterできます。また任意でrequest/response schemaも許可し、クライアントやagentが呼び出しを自動生成できるようにします。

  • NIP-XX: SplitSigを使うLNURL-authからの鍵導出PR #2294):LNURL-authのECDSA署名とクライアント側ランダムnonceを組み合わせてNostrキーペアを導出する提案です。導出式はnsec = SHA256(ecdsa_signature || nonce)です。サーバーはECDSA署名(LNURL-auth handshakeに内在)を見ますがnonceは見ず、ブラウザはnonceを生成しますが署名は制御しません。どちらの断片だけでもnsecは導出できません。狙いは、同じLightning walletがデバイス間で同じNostr鍵を生み、walletがrecovery anchorとなり、どのサーバーも秘密鍵を再構築できないことです。

  • NIP-55: rejected fieldの文書化PR #2290):intentベース署名者レスポンスのrejectedフィールドを文書化し、Amethyst v1.07.xの修正が回避しなければならなかった挙動を正式化します。

NIPディープダイブ: NIP-5A(静的ウェブサイト)

NIP-5Aは、署名済みイベントを配信されるWebページへ変えるために、2つのイベントkindと既存blob storageインフラを使って、Nostrキーペア配下で静的ウェブサイトをホストする方法を定義します。仕様は3月25日にPR #1538経由でマージされました。

このモデルでは、pubkeyごとに1つのroot site用にkind 15128dタグで識別されるnamed sites用にkind 35128を使います。各manifestは絶対URL pathをSHA256 hashへマッピングします。以下はroot site manifestの例です。

{
  "id": "5324d695ed7abf7cdd2a48deb881c93b7f4e43de702989bbfb55a1b97b35a3de",
  "pubkey": "266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5",
  "created_at": 1743465600,
  "kind": 15128,
  "tags": [
    ["path", "/index.html", "186ea5fd14e88fd1ac49351759e7ab906fa94892002b60bf7f5a428f28ca1c99"],
    ["path", "/about.html", "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456"],
    ["path", "/favicon.ico", "fedcba0987654321fedcba0987654321fedcba0987654321fedcba0987654321"],
    ["server", "https://blossom.primal.net"],
    ["title", "My Nostr Site"],
    ["description", "A static website hosted on Nostr"],
    ["source", "https://github.com/lez/nsite"]
  ],
  "content": "",
  "sig": "f4e4a9e785f70e9fcaa855d769438fea10781e84cd889e3fcb823774f83d094cf2c05d5a3ac4aebc1227a4ebc3d56867286c15a6df92d55045658bb428fd5fb5"
}

配信フローは3段階です。ホストサーバーがHTTP requestを受け取り、subdomainから著者のpubkeyを抽出します(root sitesならnpub、named sitesならbase36エンコードpubkey)。次に、著者のrelay listをNIP-65経由で取得し、site manifestを問い合わせます。manifestが見つかると、サーバーは要求されたpathをcontent hashへ解決し、server tagsに列挙されたBlossomサーバーから対応blobをダウンロードして返します。

DNS subdomain formatは厳密に指定されています。root sitesは標準npubをsubdomainに使います。named sitesは、生のpubkeyの50文字base36 encodingに続けてdタグ値を1つのDNS labelに収めます。DNS labelは63文字制限があり、base36 encodingは常に50文字を使うため、dタグは13文字に制限されます。仕様はさらに、dタグが^[a-z0-9-]{1,13}$に一致し、ハイフンで終わらないことを要求しており、DNS解決の曖昧さを防ぎます。

content hashを使うことで、同じサイトを異なるhost serversから配信でき、file integrityもサーバーを信用せずに検証できます。host serverはファイルを自前で保存する必要がありません。manifest内hashを使って必要時にBlossomから取得するだけです。つまり、作者が何を配信するかを制御し、Blossom serverが生ファイルを保持し、host serverは両者を接続するだけです。この3要素はそれぞれ独立に交換可能です。

既存実装には、manifestを解決してファイルを配信するhost servernsiteと、manifestの構築と公開を行うUInsite-managerがあります。仕様にはサイトのsource code repositoryへのリンク用sourceタグも追加され、別途PR #2286でマージされたREADME更新では、kind 1512835128の両方がNIP kind indexへ登録されました。

NIPディープダイブ: NIP-62(Request to Vanish)

NIP-62は、要求したpubkeyからのすべてのイベントをrelayが削除するよう求めるkind 62イベントを定義します。仕様の動機は法的なものです。忘れられる権利のある法域では、標準化され署名された削除要求があれば、relayオペレーターは行動すべき明確なシグナルを得られます。

{
  "id": "a7b8c9d0e1f23456789012345678901234567890abcdef1234567890abcdef12",
  "pubkey": "f1e2d3c4b5a697887766554433221100ffeeddccbbaa99887766554433221100",
  "created_at": 1743465600,
  "kind": 62,
  "tags": [
    ["relay", "wss://relay.example.com"]
  ],
  "content": "Requesting deletion of all events from this relay.",
  "sig": "11aa22bb33cc44dd55ee66ff77889900aabbccddeeff0011223344556677889911aa22bb33cc44dd55ee66ff77889900aabbccddeeff00112233445566778899"
}

この仕様は、targeted vanish requestとglobal vanish requestを分けています。targeted requestは、どのrelayが対応すべきかを示す具体的なrelayタグを含みます。global requestは、relayタグ値として文字列ALL_RELAYSを使い、そのイベントを見るすべてのrelayに対して、そのpubkey由来のすべてのイベント削除を求めます。準拠するrelayは、削除済みイベントが再びrelayへ再放送されないことも保証しなければならず、削除はstickyである必要があります。

NIP-62は、範囲と意図の両面でNIP-09(イベント削除)を超えます。NIP-09は個別イベントを削除でき、relayは準拠してもしなくてもよい仕様です。NIP-62はすべての削除を要求し、仕様はURLがタグ付けされたrelayに対してMUST準拠を求めています。さらに、要求pubkeyをp-tagしたNIP-59(Gift Wrap)イベントも削除するようrelayに求めているため、受信DMもユーザー自身のイベントと一緒に消されます。NIP-62 vanish requestに対してNIP-09削除イベントを公開しても効果はありません。いったんvanishした後で、vanish request自体を削除してun-vanishすることはできません。

今週、Amethyst v1.07.0はクライアント側のNIP-62サポートを出荷し、ユーザーがアプリからvanish requestを開始できるようにしました。relay側では、rust-nostrが、memory、LMDB、SQLite、database test backendsそれぞれにNIP-62を追加する4つのオープンPRを抱えています(PR #1315PR #1316PR #1317PR #1318)。クライアントサポートとrelayサポートが同じ週に進んでいるわけです。

この設計は実務的な緊張も生みます。Nostrの価値提案には検閲耐性が含まれ、relayは公開を妨げるべきではありません。一方でNIP-62は、特定pubkeyからの再公開をrelayがMUST防ぐケースを導入します。両者が両立するのは、この要求が自己指向だからです。あなたが求めているのは他人のイベント削除ではなく、自分自身のイベント削除です。検閲耐性は、明示的にオプトアウトした本人以外についてはそのまま保たれます。


今週は以上です。何か作っているものや共有したいニュースがあれば、NIP-17(プライベートダイレクトメッセージ)DMでご連絡ください。Nostr上でもお待ちしています。