jpskill.com
🛠️ 開発・MCP コミュニティ

nostr-nip05-setup

NostrのNIP-05という仕組みを使って、DNSに基づいたID認証を設定し、必要なファイルや設定を行い、プロフィールを更新して、Nostrクライアントが正しく認証できるようにするSkill。

📜 元の英語説明(参考)

Set up NIP-05 DNS-based identity verification for Nostr, including the /.well-known/nostr.json endpoint, CORS headers, and kind:0 profile updates. Use when configuring NIP-05, setting up nostr.json, debugging NIP-05 verification failures, adding DNS identity to a Nostr profile, or working with /.well-known/nostr.json files and CORS for Nostr clients.

🇯🇵 日本人クリエイター向け解説

一言でいうと

NostrのNIP-05という仕組みを使って、DNSに基づいたID認証を設定し、必要なファイルや設定を行い、プロフィールを更新して、Nostrクライアントが正しく認証できるようにするSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o nostr-nip05-setup.zip https://jpskill.com/download/9139.zip && unzip -o nostr-nip05-setup.zip && rm nostr-nip05-setup.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/9139.zip -OutFile "$d\nostr-nip05-setup.zip"; Expand-Archive "$d\nostr-nip05-setup.zip" -DestinationPath $d -Force; ri "$d\nostr-nip05-setup.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して nostr-nip05-setup.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → nostr-nip05-setup フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

NIP-05 アイデンティティ設定

概要

NIP-05 DNSベースのアイデンティティ検証を設定し、Nostrクライアントが人間が読める識別子(bob@example.comなど)を16進数の公開鍵にマッピングできるようにします。このスキルでは、/.well-known/nostr.jsonエンドポイントの作成、CORSヘッダーの設定、kind:0プロファイルの更新、および検証の失敗のデバッグについて説明します。

どのような時に使うか

  • ドメインのNIP-05検証を設定する
  • /.well-known/nostr.jsonファイルを作成または編集する
  • Nostrクライアント用にWebサーバーのCORSヘッダーを設定する
  • nip05フィールドでkind:0プロファイルを更新する
  • NIP-05検証が失敗する理由をデバッグする
  • _@domainルート識別子を設定する

以下の場合には使用しないでください:

  • Nostrリレーを構築する場合(これはリレープロトコルです)
  • NIP-19 bech32エンコーディング(npub/nsec表示形式)を扱う場合
  • Nostrイベント署名またはキー管理を実装する場合

ワークフロー

1. セットアップタイプの決定

質問: 「静的ファイルですか、動的サーバーですか?」

シナリオ アプローチ 最適な用途
ユーザーが少なく、変更がまれ 静的な .well-known/nostr.json ファイル 個人のサイト、小規模なコミュニティ
ユーザーが多く、頻繁に変更 ?name= クエリ処理を行う動的サーバー NIP-05プロバイダー、大規模なコミュニティ
既存のWebサーバー locationブロック + CORSヘッダーを追加 Nginx、Apache、Caddyのセットアップ

2. nostr.jsonファイルの作成

このファイルは、人間が読める名前を16進数の公開鍵にマッピングします。

形式:

{
  "names": {
    "bob": "b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9"
  },
  "relays": {
    "b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9": [
      "wss://relay.example.com",
      "wss://relay2.example.com"
    ]
  }
}

重要なルール:

  • 公開鍵は64文字の小文字の16進数でなければなりません(npub bech32形式ではありません)
  • namesオブジェクトは必須です
  • relaysオブジェクトは推奨されます — クライアントがユーザーを見つける場所を見つけるのに役立ちます
  • ローカルパート(名前)には、a-z0-9-_.のみを含める必要があります(小文字、大文字は不可)
  • _は特別な「ルート」識別子です — _@example.comはクライアントでexample.comとして表示されます

ルート識別子の例:

{
  "names": {
    "_": "b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9"
  }
}

これにより、ユーザーはbob@example.comではなくexample.comとして識別できます。

3. ファイルを正しく提供する

ファイルは正確に以下で提供される必要があります。

https://<domain>/.well-known/nostr.json?name=<local-part>

3つの譲歩できない要件:

  1. HTTPSのみ — HTTPは機能しません。クライアントはHTTPS経由でのみフェッチします。
  2. CORSヘッダー — レスポンスにはAccess-Control-Allow-Origin: *を含める必要があります。これは、JavaScript Nostrクライアントがブラウザーで実行され、このヘッダーがないとCORSポリシーによってブロックされるためです。
  3. リダイレクトなし — エンドポイントはHTTPリダイレクト(301、302など)を返してはなりません。NIP-05仕様に従って、フェッチャーはリダイレクトを無視する必要があります。これはセキュリティ上の制約です。

?name=<local-part>クエリ文字列形式は、静的ファイルと動的サーバーの両方が機能するように存在します。静的ファイルはクエリ文字列を無視してすべての名前を返し、動的サーバーは名前でフィルタリングできます。

Nginx、Apache、Caddy、およびNode.jsの構成例については、references/server-configs.mdを参照してください。

4. Kind:0プロファイルの更新

ユーザーのkind:0メタデータイベントには、nip05フィールドを含める必要があります。

{
  "kind": 0,
  "content": "{\"name\":\"bob\",\"nip05\":\"bob@example.com\",\"about\":\"A Nostr user\",\"picture\":\"https://example.com/avatar.jpg\"}"
}

nip05値の形式は<local-part>@<domain>です — これはメールアドレスのように見えますが、メールアドレスではありません。

検証フロー(クライアントが行うこと):

  1. クライアントはkind:0イベントで"nip05": "bob@example.com"を確認します
  2. クライアントはローカルパートbobとドメインexample.comに分割します
  3. クライアントはhttps://example.com/.well-known/nostr.json?name=bobをフェッチします
  4. クライアントはresponse.names.bobがイベントのpubkeyと一致するかどうかを確認します
  5. 一致する場合→アイデンティティが検証され、表示されます

5. セットアップのテスト

エンドポイントが正しいJSONを返すことを確認します:

curl -s https://example.com/.well-known/nostr.json?name=bob | jq .

CORSヘッダーが存在することを確認します:

curl -sI https://example.com/.well-known/nostr.json?name=bob | grep -i ^access-control
# Expected: Access-Control-Allow-Origin: *

リダイレクトがないことを確認します:

curl -sI -o /dev/null -w "%{http_code}" https://example.com/.well-known/nostr.json?name=bob
# Expected: 200 (NOT 301, 302, 307, 308)

pubkeyが16進数(npubではない)であることを確認します:

curl -s https://example.com/.well-known/nostr.json?name=bob | jq -r '.names.bob' | grep -E '^[0-9a-f]{64}$'
# Should match — 64 lowercase hex characters

チェックリスト

  • [ ] 正しいnamesマッピングでnostr.jsonファイルが作成されている
  • [ ] 公開鍵は64文字の小文字の16進数(npubではない)である
  • [ ] ローカルパートはa-z0-9-_.文字のみを使用している
  • [ ] ファイルはHTTPS経由で提供されている
  • [ ] Access-Control-Allow-Origin: *ヘッダーが存在する
  • [ ] エンドポイントにHTTPリダイレクトがない
  • [ ] relaysオブジェクトが含まれている(推奨)
  • [ ] Kind:0プロファイルがnip05フィールドで更新されている
  • [ ] エンドポイントがcurlでテストされ、正しいJSONで200を返している

よくある間違い

間違い 失敗する理由 修正方法
npubの代わりに16進数のpubkeyを使用する NIP-05は16進数形式が必要です。npubはUI表示専用です nak decode npub1...のようなツールを使用してnpubを16進数に変換します
CORSヘッダーがない ブラウザのJavaScript Nostrクライアントはファイルをフェッチできません

(原文がここで切り詰められています)

📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

NIP-05 Identity Setup

Overview

Set up NIP-05 DNS-based identity verification so Nostr clients can map human-readable identifiers (like bob@example.com) to hex public keys. This skill covers creating the /.well-known/nostr.json endpoint, configuring CORS headers, updating kind:0 profiles, and debugging verification failures.

When to Use

  • Setting up NIP-05 verification for a domain
  • Creating or editing a /.well-known/nostr.json file
  • Configuring web server CORS headers for Nostr clients
  • Updating a kind:0 profile with a nip05 field
  • Debugging why NIP-05 verification is failing
  • Setting up the _@domain root identifier

Do NOT use when:

  • Building a Nostr relay (that's relay protocol)
  • Working with NIP-19 bech32 encoding (npub/nsec display format)
  • Implementing Nostr event signing or key management

Workflow

1. Determine the Setup Type

Ask: "Static file or dynamic server?"

Scenario Approach Best For
Few users, rarely changes Static .well-known/nostr.json file Personal sites, small communities
Many users, frequent changes Dynamic server with ?name= query handling NIP-05 providers, large communities
Existing web server Add location block + CORS headers Nginx, Apache, Caddy setups

2. Create the nostr.json File

The file maps human-readable names to hex public keys.

Format:

{
  "names": {
    "bob": "b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9"
  },
  "relays": {
    "b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9": [
      "wss://relay.example.com",
      "wss://relay2.example.com"
    ]
  }
}

Critical rules:

  • Public keys MUST be 64-character lowercase hex (NOT npub bech32 format)
  • The names object is REQUIRED
  • The relays object is RECOMMENDED — it helps clients discover where to find the user
  • Local-part (the name) MUST only contain a-z0-9-_. (lowercase, no uppercase)
  • _ is the special "root" identifier — _@example.com displays as just example.com in clients

Root identifier example:

{
  "names": {
    "_": "b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9"
  }
}

This lets the user be identified as just example.com instead of bob@example.com.

3. Serve the File Correctly

The file MUST be served at exactly:

https://<domain>/.well-known/nostr.json?name=<local-part>

Three non-negotiable requirements:

  1. HTTPS only — HTTP will not work. Clients only fetch over HTTPS.
  2. CORS header — Response MUST include Access-Control-Allow-Origin: * because JavaScript Nostr clients run in browsers and are blocked by CORS policies without this header.
  3. No redirects — The endpoint MUST NOT return HTTP redirects (301, 302, etc.). Fetchers MUST ignore redirects per the NIP-05 spec. This is a security constraint.

The ?name=<local-part> query string format exists so both static files and dynamic servers work. A static file ignores the query string and returns all names; a dynamic server can filter by name.

See references/server-configs.md for Nginx, Apache, Caddy, and Node.js configuration examples.

4. Update the Kind:0 Profile

The user's kind:0 metadata event must include the nip05 field:

{
  "kind": 0,
  "content": "{\"name\":\"bob\",\"nip05\":\"bob@example.com\",\"about\":\"A Nostr user\",\"picture\":\"https://example.com/avatar.jpg\"}"
}

The nip05 value format is <local-part>@<domain> — it looks like an email address but is NOT an email address.

Verification flow (what clients do):

  1. Client sees "nip05": "bob@example.com" in a kind:0 event
  2. Client splits into local-part bob and domain example.com
  3. Client fetches https://example.com/.well-known/nostr.json?name=bob
  4. Client checks if response.names.bob matches the event's pubkey
  5. If match → identity is verified and displayed

5. Test the Setup

Verify the endpoint returns correct JSON:

curl -s https://example.com/.well-known/nostr.json?name=bob | jq .

Verify CORS headers are present:

curl -sI https://example.com/.well-known/nostr.json?name=bob | grep -i ^access-control
# Expected: Access-Control-Allow-Origin: *

Verify no redirects:

curl -sI -o /dev/null -w "%{http_code}" https://example.com/.well-known/nostr.json?name=bob
# Expected: 200 (NOT 301, 302, 307, 308)

Verify the pubkey is hex (not npub):

curl -s https://example.com/.well-known/nostr.json?name=bob | jq -r '.names.bob' | grep -E '^[0-9a-f]{64}$'
# Should match — 64 lowercase hex characters

Checklist

  • [ ] nostr.json file created with correct names mapping
  • [ ] Public keys are 64-char lowercase hex (not npub)
  • [ ] Local-parts use only a-z0-9-_. characters
  • [ ] File served over HTTPS
  • [ ] Access-Control-Allow-Origin: * header present
  • [ ] No HTTP redirects on the endpoint
  • [ ] relays object included (recommended)
  • [ ] Kind:0 profile updated with nip05 field
  • [ ] Endpoint tested with curl and returns 200 with correct JSON

Common Mistakes

Mistake Why It Breaks Fix
Using npub instead of hex pubkey NIP-05 requires hex format; npub is only for UI display Convert npub to hex using a tool like nak decode npub1...
Missing CORS header JavaScript Nostr clients in browsers can't fetch the file Add Access-Control-Allow-Origin: * to server config
HTTP redirects (301/302) NIP-05 spec says fetchers MUST ignore redirects Serve directly, no redirects — check trailing slash redirects
Uppercase in local-part Spec requires a-z0-9-_. only Normalize to lowercase before storing
Serving over HTTP instead of HTTPS Clients only fetch NIP-05 over HTTPS Set up TLS (Let's Encrypt, Cloudflare, etc.)
Trailing slash redirect on .well-known Nginx/Apache may redirect /nostr.json to /nostr.json/ Ensure exact match location, not directory
Wrong Content-Type Some servers don't set application/json Add Content-Type: application/json header
Query string breaks static file Some servers reject or misroute ?name= on static files Ensure server passes query strings through to static files

Quick Reference

Item Value
Endpoint https://<domain>/.well-known/nostr.json?name=<local-part>
Required header Access-Control-Allow-Origin: *
Pubkey format 64-char lowercase hex
Local-part chars a-z0-9-_.
Root identifier _@domain (displays as just the domain)
Profile field "nip05": "name@domain" in kind:0 content
Protocol HTTPS only (no HTTP)
Redirects MUST NOT redirect

Key Principles

  1. Hex keys, never npub — The nostr.json file uses raw 64-character lowercase hex public keys. npub is a display format (NIP-19) and must never appear in nostr.json. This is the single most common mistake.

  2. CORS is mandatory — Without Access-Control-Allow-Origin: *, every browser-based Nostr client silently fails to verify the identity. The user sees no error — verification just doesn't work.

  3. No redirects, ever — HTTP redirects are a security risk in this context. The spec explicitly requires fetchers to ignore them. Common culprits: trailing-slash redirects, HTTP→HTTPS redirects on the endpoint itself, and www→non-www redirects.

  4. Identification, not verification — NIP-05 identifies users (maps human-readable names to keys), it does not verify trust. The exception is well-known domains (companies, projects) where domain ownership itself implies trust.

  5. Clients follow pubkeys, not NIP-05 addresses — If a user follows bob@example.com, the client stores the pubkey, not the address. If the NIP-05 mapping changes later, the client unfollows the address display but keeps following the pubkey.