# nostr-tools > Free Nostr developer tools at https://nostr-tools.com. Convert npub, nsec, note, nevent, nprofile and naddr identifiers, resolve NIP-05 names, generate and encrypt keys, create, sign, verify, fetch and rebroadcast events. The web tools run entirely in the browser and keys never leave it. An MCP server exposes the same operations to AI agents. The site is a JavaScript single page app, so fetching a tool URL returns an empty shell. Use the markdown links below, `https://nostr-tools.com/llms-full.txt`, or the MCP server. ## MCP server Agents can call the tools directly instead of driving the UI. The server speaks the Model Context Protocol over Streamable HTTP, is stateless and needs no auth. - Endpoint: https://nostr-tools.com/mcp - Server card: https://nostr-tools.com/.well-known/mcp.json - Claude Code: `claude mcp add --transport http nostr-tools https://nostr-tools.com/mcp` - Any client config: `{ "mcpServers": { "nostr-tools": { "type": "http", "url": "https://nostr-tools.com/mcp" } } }` Tools: decode_nostr_identifier, encode_nostr_identifier, resolve_nip05, get_profile, get_relay_list, fetch_events, verify_event, compute_event_id, publish_event, get_relay_info, generate_keypair, lookup_nip, describe_event_kind, read_guide. No MCP tool accepts a secret key (nsec or hex). Sign events locally or with a NIP-07/NIP-46 signer, then pass the signed event to `verify_event` or `publish_event`. ## Default relays - wss://relay.damus.io - wss://nos.lol - wss://relay.primal.net - wss://relay.snort.social - wss://nostr.wine - wss://relay.nostr.net - wss://offchain.pub - wss://nostr.mom - wss://nostr.oxtr.dev - wss://nostr.bitcoiner.social - wss://nostr-pub.wellorder.net - wss://eden.nostr.land # Tools ## Identifier converter > Decode any npub, nevent, naddr, nostr: link or NIP-05 name. Build pointers with relay hints. URL: https://nostr-tools.com/nip19-converter ### Specs - NIP-05: DNS identifiers. Maps keys to user@domain names via a well known JSON file. - NIP-19: Bech32 entities. npub, nsec, note, nprofile, nevent and naddr encodings. - NIP-21: nostr: URI scheme. Links that open identifiers in any Nostr client. ### For AI agents The web page runs entirely in the browser and needs JavaScript. Agents can do the same work through the MCP server at `https://nostr-tools.com/mcp` with these tools: `decode_nostr_identifier`, `encode_nostr_identifier`, `resolve_nip05`. ## Key generator > Create a keypair, import an existing key, or lock it behind a password as an ncryptsec. URL: https://nostr-tools.com/key-generator ### Specs - NIP-01: Basic protocol. Events, signatures, filters and the relay message flow. - NIP-19: Bech32 entities. npub, nsec, note, nprofile, nevent and naddr encodings. - NIP-49: Encrypted secret keys. Password protected ncryptsec keys using scrypt. ### For AI agents The web page runs entirely in the browser and needs JavaScript. Agents can do the same work through the MCP server at `https://nostr-tools.com/mcp` with these tools: `generate_keypair`. ## Event creator > Compose any kind, add tags, and sign with a local key or your browser extension. URL: https://nostr-tools.com/event-creator ### Specs - NIP-01: Basic protocol. Events, signatures, filters and the relay message flow. - NIP-07: Browser signer. The window.nostr interface exposed by signing extensions. ### For AI agents The web page runs entirely in the browser and needs JavaScript. Agents can do the same work through the MCP server at `https://nostr-tools.com/mcp` with these tools: `compute_event_id`. ## Event verifier > Check structure, recompute the id and validate the Schnorr signature, step by step. URL: https://nostr-tools.com/event-verifier ### Specs - NIP-01: Basic protocol. Events, signatures, filters and the relay message flow. ### For AI agents The web page runs entirely in the browser and needs JavaScript. Agents can do the same work through the MCP server at `https://nostr-tools.com/mcp` with these tools: `verify_event`. ## Event fetcher > Stream events from relays by author, id, address or NIP-05 name as they arrive. URL: https://nostr-tools.com/event-fetcher ### Specs - NIP-01: Basic protocol. Events, signatures, filters and the relay message flow. - NIP-05: DNS identifiers. Maps keys to user@domain names via a well known JSON file. - NIP-19: Bech32 entities. npub, nsec, note, nprofile, nevent and naddr encodings. ### For AI agents The web page runs entirely in the browser and needs JavaScript. Agents can do the same work through the MCP server at `https://nostr-tools.com/mcp` with these tools: `fetch_events`, `get_profile`, `get_relay_list`. ## Event republisher > Rebroadcast a signed event to a dozen relays and see each relay reply live. URL: https://nostr-tools.com/event-republisher ### Specs - NIP-01: Basic protocol. Events, signatures, filters and the relay message flow. - NIP-65: Relay list. Kind 10002 read and write relay preferences. ### For AI agents The web page runs entirely in the browser and needs JavaScript. Agents can do the same work through the MCP server at `https://nostr-tools.com/mcp` with these tools: `publish_event`, `get_relay_info`. ## NIPs reference > The Nostr Implementation Possibilities that the nostr-tools library implements, with the module to import for each. URL: https://nostr-tools.com/nips-reference | NIP | Title | Description | nostr-tools module | | --- | --- | --- | --- | | NIP-01 | Basic protocol | Events, signatures, filters and the relay message flow. | `nostr-tools/pure` | | NIP-02 | Follow list | Kind 3 contact lists with optional petnames. | | | NIP-04 | Encrypted DMs (legacy) | The original direct message encryption. Superseded by NIP-17 and NIP-44. | `nostr-tools/nip04` | | NIP-05 | DNS identifiers | Maps keys to user@domain names via a well known JSON file. | `nostr-tools/nip05` | | NIP-07 | Browser signer | The window.nostr interface exposed by signing extensions. | `nostr-tools/nip07` | | NIP-09 | Event deletion | Kind 5 requests asking relays to drop earlier events. | | | NIP-10 | Reply threading | Root and reply markers on e tags for threaded notes. | `nostr-tools/nip10` | | NIP-11 | Relay information | A JSON document describing a relay, its limits and supported NIPs. | `nostr-tools/nip11` | | NIP-13 | Proof of work | Leading zero bits on event ids as a spam deterrent. | `nostr-tools/nip13` | | NIP-17 | Private DMs | Gift wrapped direct messages that hide sender and timing. | `nostr-tools/nip17` | | NIP-18 | Reposts | Kind 6 and kind 16 reposts of other events. | `nostr-tools/nip18` | | NIP-19 | Bech32 entities | npub, nsec, note, nprofile, nevent and naddr encodings. | `nostr-tools/nip19` | | NIP-21 | nostr: URI scheme | Links that open identifiers in any Nostr client. | `nostr-tools/nip21` | | NIP-22 | Comments | Kind 1111 comments on any event or external resource. | `nostr-tools/nip22` | | NIP-23 | Long form content | Kind 30023 Markdown articles. | | | NIP-25 | Reactions | Kind 7 likes and emoji reactions. | `nostr-tools/nip25` | | NIP-27 | Text references | Inline nostr: mentions inside note content. | `nostr-tools/nip27` | | NIP-28 | Public chat | Channels built from kinds 40 to 44. | `nostr-tools/nip28` | | NIP-29 | Relay based groups | Groups moderated by the relay that hosts them. | `nostr-tools/nip29` | | NIP-42 | Relay auth | Clients prove key ownership to a relay with a signed challenge. | `nostr-tools/nip42` | | NIP-44 | Versioned encryption | The audited payload encryption used by modern DMs. | `nostr-tools/nip44` | | NIP-46 | Remote signing | Bunkers that hold keys and sign over Nostr Connect. | `nostr-tools/nip46` | | NIP-47 | Wallet Connect | Lightning wallets controlled over Nostr events. | `nostr-tools/nip47` | | NIP-49 | Encrypted secret keys | Password protected ncryptsec keys using scrypt. | `nostr-tools/nip49` | | NIP-57 | Zaps | Lightning payments receipted as Nostr events. | `nostr-tools/nip57` | | NIP-59 | Gift wrap | Seals and wraps that hide event metadata. | `nostr-tools/nip59` | | NIP-65 | Relay list | Kind 10002 read and write relay preferences. | | | NIP-77 | Negentropy sync | Efficient set reconciliation between client and relay. | `nostr-tools/nip77` | | NIP-98 | HTTP auth | Signed events used as HTTP Authorization headers. | `nostr-tools/nip98` | # Guides ## npub to hex converter > Paste an npub to get the 64 character hex public key, or paste hex to get the npub. Works with nprofile and nostr: links too, all in your browser. URL: https://nostr-tools.com/npub-to-hex ### What the converter does An npub and a hex pubkey are the same 32 bytes written two ways. Clients show the npub because it is harder to mistype, while relays, filters and raw events always use hex. This page switches between the two instantly. - Paste an `npub1…` string to get the hex key that relays and REQ filters expect. - Paste a 64 character hex key to get the npub you can share or search in a client. - Paste an `nprofile1…` or a `nostr:` link to get the hex key plus any relay hints it carries. ### How npub encoding works NIP-19 encodes keys with bech32, the same scheme Bitcoin uses for addresses. The human readable prefix `npub` is followed by the separator `1`, the key data in a 32 letter alphabet, and a six character checksum. A complete npub is always 63 characters long. *Same key, two formats* ``` npub npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6 hex 3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d ``` The checksum is why a typo in an npub fails loudly instead of pointing at a stranger. Hex has no checksum, so a single wrong character silently becomes a different, valid looking key. ### Doing it in code With the nostr-tools library the conversion is one call each way. `decode` also handles nsec, note, nevent and naddr, so check the returned `type` before using the data. *TypeScript* ```ts import { nip19 } from 'nostr-tools' const { type, data } = nip19.decode('npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6') // type === 'npub', data is the hex pubkey const npub = nip19.npubEncode('3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d') ``` ### FAQ **Is converting an npub to hex safe?** Yes. An npub is your public key, meant to be shared. Converting it reveals nothing new, and this page does the work in your browser without sending anything to a server. **Why do relays use hex instead of npub?** NIP-01 defines events and filters with lowercase hex. The npub format from NIP-19 exists only for display and copy paste between people, so it never appears inside an event. **Can I paste an nprofile instead of an npub?** Yes. An nprofile holds the same pubkey plus relay hints. The converter shows the hex key and lists every relay in the hint. **Why does my npub fail to decode?** Usually a character was lost when copying, or the string has a nostr: prefix, a trailing space or a line break. The bech32 checksum rejects any change, which protects you from using the wrong key. **Does an npub ever change?** No. It is derived from your keypair. Changing it means creating a new key, and followers would have to find you again. **Is the hex key the same as the note id?** No. A note or nevent decodes to an event id, which is also 64 hex characters but identifies an event, not a person. The converter labels which one you pasted. ### Related tools - [Identifier converter](https://nostr-tools.com/nip19-converter): Decode any npub, nevent, naddr, nostr: link or NIP-05 name. Build pointers with relay hints. - [Event fetcher](https://nostr-tools.com/event-fetcher): Stream events from relays by author, id, address or NIP-05 name as they arrive. - [Key generator](https://nostr-tools.com/key-generator): Create a keypair, import an existing key, or lock it behind a password as an ncryptsec. ## Get your npub from an nsec > Derive your Nostr public key from a secret key. Paste an nsec or hex secret to see the npub and hex pubkey, computed locally in your browser. URL: https://nostr-tools.com/nsec-to-npub ### Before you paste a secret key Your nsec controls your identity. Anyone who sees it can post as you, forever. The math on this page runs in your browser and nothing is sent anywhere, but any website you type a secret into is still exposed to your installed browser extensions. - Use a throwaway key when you are only testing. - For your main identity, prefer a signer extension or a NIP-46 bunker so the key never touches a web page. - If you need to store the key, lock it as an `ncryptsec` with a password using the key generator. ### How the npub is derived A Nostr secret key is a 32 byte number. Multiplying the secp256k1 generator point by that number gives a point on the curve, and the 32 byte x coordinate of that point is your public key. The step is easy forwards and practically impossible to reverse, which is why sharing the npub is safe. *TypeScript* ```ts import { nip19, getPublicKey } from 'nostr-tools' const { data: sk } = nip19.decode('nsec1…') // Uint8Array const pubkey = getPublicKey(sk) // hex const npub = nip19.npubEncode(pubkey) ``` ### If the result is not the npub you expected - The nsec may belong to a different account. Many clients create a fresh key on first launch. - An `ncryptsec1…` string is encrypted. Unlock it with its password in the key generator first. - A 12 or 24 word phrase is a NIP-06 mnemonic, not an nsec. It must be derived into a key by a client that supports NIP-06. ### FAQ **Can someone get my nsec from my npub?** No. Deriving the public key is a one way operation on the secp256k1 curve. Recovering the secret from it would take longer than the age of the universe with current computers. **Is this page sending my nsec anywhere?** No. Decoding and derivation run in JavaScript in this tab with the nostr-tools library. There are no analytics and no backend for keys. You can disconnect from the internet and it still works. **What is the difference between nsec and hex secret keys?** They are the same 32 bytes. nsec is the NIP-19 bech32 form with a checksum, and hex is the raw form some libraries and tools expect. The converter accepts either. **I lost my nsec. Can I recover it from my npub?** No. Without a backup of the nsec, an ncryptsec plus its password, or a seed phrase, the key is gone and you will need a new identity. **Where do clients store my nsec?** Mobile apps usually keep it in the system keychain. Web clients often hold it in local storage, which is why a signer extension or remote signer is the safer choice on the web. **Should I rotate my key if I pasted it somewhere?** If you pasted it into a site or app you do not fully trust, yes. Nostr has no password reset, so treat an exposed nsec as compromised. ### Related tools - [Key generator](https://nostr-tools.com/key-generator): Create a keypair, import an existing key, or lock it behind a password as an ncryptsec. - [Identifier converter](https://nostr-tools.com/nip19-converter): Decode any npub, nevent, naddr, nostr: link or NIP-05 name. Build pointers with relay hints. - [Event creator](https://nostr-tools.com/event-creator): Compose any kind, add tags, and sign with a local key or your browser extension. ## What is Nostr? A plain guide to the protocol > Nostr is an open protocol for social apps built on keys, signed events and relays. Learn how the pieces fit together and try them in your browser. URL: https://nostr-tools.com/what-is-nostr ### Nostr in one paragraph Nostr stands for Notes and Other Stuff Transmitted by Relays. You have a keypair instead of an account. Everything you do, from a post to a like to a profile update, is a small JSON event signed with your key. You send events to relays, which are simple servers that store and forward them, and anyone can read them back from any relay that has them. ### The three building blocks | Piece | What it is | Why it matters | | --- | --- | --- | | Keys | A secret key (nsec) and the public key derived from it (npub) | Your identity belongs to you, not to a server | | Events | Signed JSON objects with a kind, tags and content | Anyone can verify who wrote what | | Relays | WebSocket servers that accept and return events | No single operator can delete you everywhere | ### What a Nostr event looks like Every event has the same seven fields. The `kind` number says what the event is: kind 0 is a profile, kind 1 is a short note, kind 7 is a reaction. Clients only need to understand the kinds they care about. *A kind 1 note* ``` { "id": "338aac49de56cae77ef321cdd36d57f5ca38d16fc4a2365290b06fe471f00985", "pubkey": "f869ffc482e56dc216b8bb57dbea7de7ed61539c346d64ea3ff750049c6a94e0", "created_at": 1730000000, "kind": 1, "tags": [["t", "nostr"]], "content": "Hello from the open web", "sig": "8693a8fe2a1d92f3867549cd7075f3bb17987961db58666310ed72a62fdd3d3d95d8af566d683324516bbf96426978e0035ac0a9c5c73e87d949fad95e36b441" } ``` ### How Nostr differs from other social networks - No sign up. Generating a keypair takes milliseconds and needs no email or phone number. - Portable followers. Your follow list is an event you own, so any client can load it. - Many apps, one identity. Damus, Primal, Amethyst, Coracle and dozens more all read the same events. - Beyond social. Long form articles, marketplaces, Lightning wallets and chat all run on the same event format. ### Getting started 1. Generate a keypair and back up the nsec somewhere safe, ideally as a password protected ncryptsec. 2. Install a client, or a signer extension like Alby or nos2x if you use web clients. 3. Set a profile, follow a few people and add three to five relays you trust. 4. Optionally verify a name like you@yourdomain.com with NIP-05. ### FAQ **Who owns Nostr?** Nobody. It is an open protocol, like email. The specifications, called NIPs, are developed in public on GitHub and anyone can build a client or run a relay. **Is Nostr a blockchain?** No. There is no chain, token or consensus. Events are stored by ordinary servers. Nostr is popular with Bitcoin users because Lightning zaps are built in, but it does not need Bitcoin to work. **Can posts on Nostr be deleted?** You can publish a kind 5 deletion request and most relays will honor it, but copies may survive on relays that ignore it. Treat anything you publish as permanent. **Is Nostr private?** Public notes are public. Direct messages use NIP-17 encryption, which hides the content and the sender from relays. Your IP address is visible to the relays you connect to. **What happens if a relay bans me?** Your events stay on every other relay. Clients read from several relays at once, so one relay dropping you has little effect. **How do I move to another Nostr app?** Log in to the new app with the same key, ideally through a signer. Your profile, follows and posts come with you because they are events tied to your key. ### Related tools - [Key generator](https://nostr-tools.com/key-generator): Create a keypair, import an existing key, or lock it behind a password as an ncryptsec. - [Identifier converter](https://nostr-tools.com/nip19-converter): Decode any npub, nevent, naddr, nostr: link or NIP-05 name. Build pointers with relay hints. - [NIPs reference](https://nostr-tools.com/nips-reference): The specs nostr-tools implements, with the module name to import for each one. ## Nostr relay list and how to choose relays > A list of reliable public Nostr relays checked in October 2026, what read and write relays mean, and how to test whether a relay accepts your events. URL: https://nostr-tools.com/nostr-relays ### Public relays that answered in October 2026 These are the relays nostr-tools uses by default. Each one accepted connections when we last checked. Relays come and go, so test before you rely on one. | Relay | Use | | --- | --- | | wss://relay.damus.io | Read and write | | wss://nos.lol | Read and write | | wss://relay.primal.net | Read and write | | wss://relay.snort.social | Read and write | | wss://nostr.wine | Read and write | | wss://relay.nostr.net | Read and write | | wss://offchain.pub | Write | | wss://nostr.mom | Write | | wss://nostr.oxtr.dev | Write | | wss://nostr.bitcoiner.social | Write | | wss://nostr-pub.wellorder.net | Write | | wss://eden.nostr.land | Write | Some relays, such as `nostr.wine` and `eden.nostr.land`, only accept events from paying members. A rejection from them is expected if you have not subscribed. ### Read relays and write relays NIP-65 lets you publish a kind 10002 event listing the relays you write to and the relays you read from. Other clients use it to find your posts and to deliver replies and mentions to you. This outbox model is why you do not need to be on every relay. *Kind 10002 relay list* ``` { "kind": 10002, "tags": [ ["r", "wss://relay.damus.io"], ["r", "wss://nos.lol"], ["r", "wss://relay.primal.net", "read"], ["r", "wss://nostr.wine", "write"] ], "content": "" } ``` ### How to choose relays - Use three to six relays. More slows clients down and adds little reach. - Mix one or two large public relays with one smaller or paid relay that has less spam. - Pick relays geographically close to you for faster reads. - Check each relay with the republisher. It shows accepted, duplicate or the exact rejection reason. - Publish a kind 10002 list so other clients know where to find you. ### Why a relay rejects an event | Reply prefix | Meaning | | --- | --- | | `blocked:` | The relay does not accept your pubkey or this kind | | `rate-limited:` | You sent too much too quickly | | `auth-required:` | The relay wants a NIP-42 login first | | `pow:` | The event needs NIP-13 proof of work | | `invalid:` | The id or signature does not verify | | `restricted:` | Members only, usually a paid relay | ### FAQ **How many relays should I use?** Three to six is plenty for most people. The outbox model in NIP-65 lets clients find you without everyone sharing the same relays. **Are paid relays worth it?** For many people, yes. Paid relays filter most spam and tend to have better uptime. Keep at least one free relay in your list so non members can still read you. **Can I run my own relay?** Yes. strfry, nostr-rs-relay and khatru are popular implementations. A personal relay is a good backup of everything you publish. **Why do my old posts disappear?** Free relays often prune old events to save space. Rebroadcast important events to a relay you trust using the event republisher. **What does wss:// mean?** It is a secure WebSocket address. Relays speak a small JSON message protocol over WebSockets, defined in NIP-01. **How do I see what a relay supports?** Fetch its NIP-11 document by requesting the relay URL over HTTPS with the header Accept: application/nostr+json. It lists limits, fees and supported NIPs. ### Related tools - [Event republisher](https://nostr-tools.com/event-republisher): Rebroadcast a signed event to a dozen relays and see each relay reply live. - [Event fetcher](https://nostr-tools.com/event-fetcher): Stream events from relays by author, id, address or NIP-05 name as they arrive. - [Event creator](https://nostr-tools.com/event-creator): Compose any kind, add tags, and sign with a local key or your browser extension. ## NIP-05 verification setup guide > Set up NIP-05 so your Nostr profile shows you@yourdomain.com. Copy the nostr.json template, fix CORS and test the lookup in your browser. URL: https://nostr-tools.com/nip-05-verification ### What NIP-05 gives you NIP-05 links your public key to a name on a domain you control, like `alice@example.com`. Clients show it on your profile and let people find you by typing it. It proves you control the domain, not who you are, which makes it most useful for organizations and people with their own site. ### Set it up in four steps 1. Get your hex pubkey. Paste your npub into the converter above if you only have the npub. 2. Create a file at `/.well-known/nostr.json` on your domain with the template below. 3. Serve it with the header `Access-Control-Allow-Origin: *` so web clients can read it. 4. Set the `nip05` field in your profile to `name@yourdomain.com` and save. */.well-known/nostr.json* ```json { "names": { "alice": "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d", "_": "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d" }, "relays": { "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d": ["wss://relay.damus.io", "wss://nos.lol"] } } ``` The `_` name is special. It lets you use the bare domain, so `_@example.com` displays as `example.com`. The `relays` object is optional and tells clients where to find you. ### Common problems | Symptom | Fix | | --- | --- | | Works with curl, fails in web clients | Add the CORS header `Access-Control-Allow-Origin: *` | | Never verifies | Use the hex pubkey in nostr.json, not the npub | | Redirects to www | Clients must not follow redirects. Serve the file on the exact domain | | Name fails, other names work | Names are lowercase. Use `alice`, not `Alice` | | Static host hides the file | Some hosts skip dot folders. Add an explicit route for `.well-known` | ### FAQ **Is NIP-05 the same as a blue check?** No. It only proves the domain owner listed your key. A name on a big shared domain says little about you, while a name on your own company domain says a lot. **Do I need my own domain?** No. Many services offer free or paid names on their domain. Owning the domain means nobody can take the name away. **How do I test my NIP-05 setup?** Paste the name into the identifier converter. It fetches nostr.json from your domain and shows the pubkey and relays it finds, or the exact error. **Can I add several people to one domain?** Yes. Add one entry per person under names. Servers can also answer dynamically using the name query parameter. **What if I change my key?** Update the hex pubkey in nostr.json. Clients check the file again and the old key stops verifying. **Why does my client show a warning on my name?** The client fetched nostr.json and the pubkey did not match, or the request failed. Check CORS, redirects and that the hex key is correct. ### Related tools - [Identifier converter](https://nostr-tools.com/nip19-converter): Decode any npub, nevent, naddr, nostr: link or NIP-05 name. Build pointers with relay hints. - [Event fetcher](https://nostr-tools.com/event-fetcher): Stream events from relays by author, id, address or NIP-05 name as they arrive. - [Key generator](https://nostr-tools.com/key-generator): Create a keypair, import an existing key, or lock it behind a password as an ncryptsec. ## Nostr event kinds list > A reference of Nostr event kinds: what kind 0, 1, 3, 7, 10002, 30023 and others mean, which NIP defines them and how replaceable kinds work. URL: https://nostr-tools.com/nostr-event-kinds ### Common kinds | Kind | Name | NIP | | --- | --- | --- | | 0 | User metadata (profile) | NIP-01 | | 1 | Short text note | NIP-01 | | 3 | Follow list | NIP-02 | | 4 | Encrypted direct message (legacy) | NIP-04 | | 5 | Deletion request | NIP-09 | | 6 | Repost | NIP-18 | | 7 | Reaction | NIP-25 | | 13 | Seal | NIP-59 | | 14 | Private chat message | NIP-17 | | 16 | Generic repost | NIP-18 | | 1059 | Gift wrap | NIP-59 | | 1111 | Comment | NIP-22 | | 9734 | Zap request | NIP-57 | | 9735 | Zap receipt | NIP-57 | | 10000 | Mute list | NIP-51 | | 10002 | Relay list metadata | NIP-65 | | 22242 | Relay authentication | NIP-42 | | 24133 | Nostr Connect | NIP-46 | | 30023 | Long form article | NIP-23 | ### Kind ranges and how relays store them The number itself tells a relay how to store an event. This is defined in NIP-01 and applies even to kinds the relay has never seen. | Range | Class | Storage rule | | --- | --- | --- | | 1000 to 9999, plus 1, 2, 4 to 44 | Regular | Every event is kept | | 10000 to 19999, plus 0 and 3 | Replaceable | Only the latest per pubkey and kind | | 20000 to 29999 | Ephemeral | Forwarded to subscribers, never stored | | 30000 to 39999 | Addressable | Only the latest per pubkey, kind and `d` tag | ### Addressable events and naddr Addressable events like articles are identified by kind, author and the `d` tag rather than by id, because editing them creates a new id. An `naddr` link encodes those three values, so it keeps pointing at the newest version. *Coordinate inside an a tag* ``` ["a", "30023:3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d:nostr-tools-guide"] ``` ### FAQ **What is kind 1 in Nostr?** Kind 1 is a short text note, the equivalent of a tweet. It is what most clients show in the home feed. **What is kind 0?** Kind 0 is your profile. Its content is JSON with fields like name, about, picture and nip05. It is replaceable, so only the newest one counts. **Can I invent my own kind?** Yes. Pick an unused number in the right range for how you want relays to store it, and ideally propose it as a NIP so other apps can support it. **Why did my edit to a profile not show up?** Replaceable events are compared by created_at. If the new event has an older timestamp than the one the relay holds, the relay keeps the old one. **What is the difference between kind 6 and kind 16?** Kind 6 reposts a kind 1 note. Kind 16 is the generic repost for any other kind and includes a k tag naming the reposted kind. **Where is the full list of kinds?** The README of the NIPs repository on GitHub keeps the canonical list, including kinds from drafts. ### Related tools - [Event creator](https://nostr-tools.com/event-creator): Compose any kind, add tags, and sign with a local key or your browser extension. - [Event fetcher](https://nostr-tools.com/event-fetcher): Stream events from relays by author, id, address or NIP-05 name as they arrive. - [NIPs reference](https://nostr-tools.com/nips-reference): The specs nostr-tools implements, with the module name to import for each one. ## How Nostr event ids and signatures work > Learn how a Nostr event id is hashed and signed with Schnorr, why verification fails, and check any event step by step in your browser. URL: https://nostr-tools.com/nostr-event-signature ### Step 1: serialize the event The id is computed from a JSON array of six values in a fixed order. The JSON is written as UTF8 with no whitespace between tokens. *Serialization* ``` [0, , , , , ] ``` ### Step 2: hash it into the id The SHA256 of that string, written as 64 lowercase hex characters, is the event `id`. Change one character of content, one tag or the timestamp and the id changes completely. ### Step 3: sign the id The id is signed with a BIP340 Schnorr signature over secp256k1, using the secret key that matches `pubkey`. The 64 byte result, in hex, is the `sig` field. Anyone can check it with the pubkey alone. *TypeScript* ```ts import { finalizeEvent, verifyEvent } from 'nostr-tools/pure' const event = finalizeEvent({ kind: 1, created_at: Math.floor(Date.now() / 1000), tags: [], content: 'hi' }, sk) verifyEvent(event) // true ``` ### Why verification fails | Cause | What to check | | --- | --- | | Content edited after signing | Any change needs a new id and signature | | Escaping differences | Line breaks and unicode must be serialized exactly as NIP-01 says | | created_at as a string | It must be an integer number of seconds | | Uppercase hex | pubkey, id and sig must be lowercase | | Wrong key | The sig was made with a key other than the one in pubkey | The event verifier on this site shows each check separately, so you can see whether the structure, the id or the signature is the part that fails. ### FAQ **Why does a relay say invalid: bad signature?** The relay recomputed the id or checked the sig and it did not match. Paste the event into the verifier to see which step fails. **Can I change an event after it is signed?** No. Any change produces a different id, which invalidates the signature. Create and sign a new event instead. **Why Schnorr and not ECDSA?** BIP340 Schnorr signatures are smaller, simpler to verify and use 32 byte public keys, the same scheme Bitcoin Taproot uses. **Does the signature cover the tags?** Yes. Tags are part of the serialized array, so adding or removing a tag after signing breaks verification. **Who checks signatures, relays or clients?** Both should. Relays check before storing, and careful clients check again before showing an event, since a relay could serve forged data. **Can I verify an event without a secret key?** Yes. Verification needs only the event itself. The pubkey inside it is all the verifier uses. ### Related tools - [Event verifier](https://nostr-tools.com/event-verifier): Check structure, recompute the id and validate the Schnorr signature, step by step. - [Event creator](https://nostr-tools.com/event-creator): Compose any kind, add tags, and sign with a local key or your browser extension. - [Event republisher](https://nostr-tools.com/event-republisher): Rebroadcast a signed event to a dozen relays and see each relay reply live.