# Nostr Agent Onboarding — start here

> **You are an AI agent and someone pointed you at this site.** It is a
> curated knowledge base for building on, designing for, and reasoning about
> **Nostr**. Read this page first (≈5 minutes). It tells you what Nostr is, the
> rules you must not break, and which document to read for the task in front
> of you. Everything here is plain Markdown; every page has a `.md` twin.
>
> Snapshot: **2026-10-10** · 40 documents · served as an nsite (the
> site is itself a set of signed Nostr events — see §7).

## 0. How to read this site

| If you have… | Read |
|---|---|
| 5 minutes | This page. |
| ~30 minutes / ~120 kB of context | [`/llms-core.txt`](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/llms-core.txt) — the five-part core synthesis + the design synthesis + the kind cheatsheet, concatenated. |
| A specific task | The **task router** in §3, then only the documents it names. |
| A large context window | [`/llms-full.txt`](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/llms-full.txt) — every document, concatenated (~510 kB). |
| A crawler | [`/llms.txt`](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/llms.txt) (index), [`/index.json`](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/index.json) (machine-readable catalog), [`/sitemap.xml`](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/sitemap.xml). |

Fetch the **`.md`** URLs, not the `.html` ones, whenever you can: they are the
canonical text, with no navigation chrome.

## 1. Nostr in one paragraph

Nostr is a description, not a system: **signed JSON events** plus **dumb,
plural, interchangeable relays**. A user mints a secp256k1 keypair, signs
events with it, and publishes them to any number of WebSocket servers
(relays); anyone can verify an event no matter where they got it from.
Signatures move authenticity into the data itself, which frees identity from
platforms and storage from trust. The price: there is **no global view, no
consistency, and no guarantees** — only routing heuristics, redundancy, and
webs of trust. Everything good about Nostr (credible exit, rug-pull
resistance, permissionless building) and everything hard about it (discovery,
spam, key loss, sync) follows from that one trade. To build on Nostr is to
accept the trade explicitly.

The whole wire protocol: client → relay `EVENT`, `REQ` (filters on `ids`,
`authors`, `kinds`, `since`/`until`, `limit`, `#<single-letter-tag>`),
`CLOSE`; relay → client `EVENT`, `OK`, `EOSE`, `CLOSED`, `NOTICE`, `AUTH`.
Event = `{id, pubkey, created_at, kind, tags, content, sig}`. Extensions are
**NIPs**, at <https://github.com/nostr-protocol/nips>.

## 2. Rules an agent must not break

These are the failures that recur when software (and especially
AI-written software) touches Nostr. Each links to where it is argued in full.

1. **Never ask for, handle, or store a user's secret key (`nsec`).** Sign
   through a signer: NIP-07 (browser extension), NIP-46 (remote "bunker"),
   NIP-55 (Android, e.g. Amber). A web client must never see an nsec.
   → [signer-login](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/patterns/signer-login.md),
   [how to develop §keys](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/core/03-how-to-develop.md)
2. **One purpose, one keypair.** A bot, service, or site gets its own freshly
   minted key. Never reuse a human's key for a service, and never publish
   kind 0 / 3 / 10002 (profile, follows, relay list) from an identity whose
   profile you don't own. Replaceable events overwrite: one wrong publish
   destroys someone's data.
3. **Default to regular events.** Use replaceable (0, 3, 10000–19999),
   addressable (30000–39999) or ephemeral (20000–29999) only when you can
   state in writing why discarding history is correct.
   → [kind cheatsheet](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/design/kind-cheatsheet.md)
4. **Reuse before you invent.** Check the kind registry, `nak nip <n>`, and
   probe live relays (`nak req -k <kind> -l 5 <relay>`) before allocating a
   kind. Inventing a duplicate kind gets you fragmentation and zero readers.
   → [NIPs kind registry](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/sources/nips-readme-kinds.md)
5. **Tags are the data model; `content` is for humans.** Single-letter tags
   are relay-indexed and queryable. Don't put structured data as JSON in
   `content`.
6. **Never destroy data you didn't understand.** When updating a shared
   replaceable event (profile, follow list, mute list…), mutate the original —
   keep unknown tags and fields — instead of regenerating it from your model.
7. **Routing is correctness, not optimisation.** Read an author from their
   *outbox* relays (NIP-65 kind 10002 `write`), deliver mentions to recipients'
   *inbox* relays, DMs to their kind 10050 list. No hard-coded "big five"
   relay list in a general-purpose client.
   → [how it should work](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/core/02-how-it-should-work.md)
8. **Every relay is unreliable and every claim is unverified.** Verify every
   signature (discard invalid ones), dedupe by id, distrust `created_at`,
   relay hints and single-relay answers. Sanitize all content.
9. **Signed public events are permanent.** Nostr is publicity technology —
   not private by default. Test against throwaway local relays (`nak serve`, a
   Khatru scaffold), not public ones; publish to the public network only what
   is meant to be public, forever.
   → [testing](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/patterns/testing.md)
10. **"Relay said OK" is not done.** Verify outcomes by reading back from the
    network (and, for sites, by fetching the gateway).
11. **Lean into the paradigm.** If you find yourself wrapping Nostr in a REST
    API with server-held state and usernames, stop. Auth, identity, storage
    and inter-process messaging come with the protocol.
12. **Hand off what you don't render.** Use NIP-89 handlers (kind 31990) for
    unknown kinds and add a NIP-31 `alt` tag to every exotic event you emit.

## 3. Task router

| Your task | Read, in this order |
|---|---|
| Understand Nostr from zero | [01 What Nostr is](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/core/01-what-nostr-is.md) → [02 How it should work](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/core/02-how-it-should-work.md) |
| Build a client / app | [03 How to develop](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/core/03-how-to-develop.md) → [signer-login](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/patterns/signer-login.md) → [testing](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/patterns/testing.md) |
| Design events or a new kind | [04 How to design](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/core/04-how-to-design.md) → [design synthesis](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/design/design-synthesis.md) → [kind cheatsheet](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/design/kind-cheatsheet.md) → [kind registry](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/sources/nips-readme-kinds.md) |
| Relay selection, outbox, spam | [02 How it should work](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/core/02-how-it-should-work.md) → [outbox model](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/sources/outbox-model.md) → [fiatjaf's vision](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/sources/fiatjaf-vision.md) |
| Implement login / signing | [signer-login](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/patterns/signer-login.md) (NIP-07 / NIP-46 / NIP-55, the three-keys model, known-bad library code) |
| Write Go | [Go baseline: `fiatjaf.com/nostr`](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/patterns/go-client-baseline.md) — `nbd-wtf/go-nostr` is archived |
| Write JS/TS | [03 How to develop §tooling](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/core/03-how-to-develop.md) + [examples](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/examples/) |
| Publish a static site (nsite) | [nsite publishing](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/patterns/nsite-publishing.md) → [known issues §7](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/design/known-issues.md) |
| Store files / media | [Blossom](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/sources/blossom.md) |
| Ship an Android app | [Zapstore source](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/sources/zapstore.md) → [Zapstore publishing](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/patterns/zapstore-publishing.md) |
| Git on Nostr (NIP-34 / GRASP) | [GRASP as structural layer](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/patterns/grasp-as-structural-layer.md) → [going public](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/patterns/going-public.md) |
| Provable time (OpenTimestamps) | [Merkle OTS extension](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/patterns/merkle-ots-extension.md) |
| Nostr keys as network identity | [FIPS](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/sources/fips.md) |
| Write tests | [testing](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/patterns/testing.md) |
| Know what's current / open | [05 Current frontier](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/core/05-current-frontier.md) |
| Understand the people & disagreements | [voices: fiatjaf](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/voices/fiatjaf/README.md), [No Solutions podcast](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/voices/no-solutions/README.md), [Constant](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/voices/constant/README.md) |
| Read primary sources | [NIP-01 full text](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/sources/nip-01.md), [Hodlbod's *Building Nostr*](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/sources/hodlbod-book.md), [nostrdesign.org](https://npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe.nsite.lol/docs/sources/nostr-design-principles.md) |

## 4. Live disagreements you should know about

Nostr has no authority, and its principal voices disagree. Don't flatten
these into one "correct" answer when advising a human — name the trade-off.

- **What the invention is:** keys/signatures (Hodlbod) vs. clients talking to
  many independent relays (fiatjaf) vs. the whole paradigm — keys *and*
  events *and* relays, taught explicitly (Constant).
- **Spam filtering:** relay-side, via filtered read relays (fiatjaf) vs.
  client-side web of trust (Martti Malmi).
- **Onboarding:** hide keys and relays to reduce friction (much of the client
  scene) vs. teach the paradigm — "relays and keys are not UX issues, they ARE
  the UX" (Constant).
- **The NIPs repo:** keep numbered specs (Hodlbod) vs. a bare kind registry
  plus competing prose guides (fiatjaf, "The end of NIPs").
- **DMs:** whether private messaging belongs on a publication protocol at all.

## 5. Caveats — read before trusting a detail

- **Dated knowledge.** Facts were verified on the dates stated inside each
  document (mostly August–September 2026). Library versions, relay policies
  and NIP texts change; re-check anything load-bearing against
  <https://github.com/nostr-protocol/nips> and the live network.
- **Workstation references.** Many documents were written for one
  developer's workstation and mention paths like `~/Documents/nostr-dev/…`,
  `~/Production Environment/…`, or local services on `localhost:8080/8081`.
  **Those do not exist for you.** Treat them as worked examples of a setup you
  can recreate (a local relay, a local Blossom server, `nak`), not as
  resources you can reach. Pages that contain such references carry a note.
- **Curated, opinionated.** The synthesis takes positions (see §4) and says
  so. The `voices/` section is the primary-source evidence behind them.

## 6. Tools worth knowing by name

- **`nak`** — the Nostr army knife (fiatjaf): keys, encode/decode, `req`,
  `event`, `serve` (throwaway relay), `bunker`, `blossom`, `nsite`, `nip <n>`.
  <https://github.com/fiatjaf/nak>
- **Libraries** — Go: `fiatjaf.com/nostr` (incl. the `khatru` relay
  framework). JS/TS: `nostr-tools`, NDK, Applesauce. Rust: `rust-nostr`.
  Android: Quartz (Amethyst).
- **References** — <https://nostrbook.dev>,
  <https://undocumented.nostrkinds.info>, <https://nostrapps.com>,
  <https://github.com/nostrability/nostrability>.

## 7. Provenance

Curated by **Constant** (Wouter Constant, techno-ethica.com,
`npub1t6jxfqz9hv0lygn9thwndekuahwyxkgvycyscjrtauuw73gd5k7sqvksrw`) from two
working knowledge bases: `nostr-dev` (the practitioner's layer — patterns,
measured gotchas, vendored sources) and `Nostr-exp` (the synthesis — what
Nostr is, how it should work, how to develop and design, the voices).
Compiled with AI assistance.

This site is an **nsite** (NIP-5A): a kind 15128 manifest signed by
`npub1d70emggs6jzun5lhvqnfqsd9reqmaarn2qjf6q3r02gryyl4v8sqjn44xe`, listing every file by SHA-256, with the blobs on Blossom
servers. You can verify that what you fetched is what was published:

```bash
nak req -k 15128 -a 6f9f9da110d485c9d3f760269041a51e41bef47350249d02237a903213f561e0 --limit 1 wss://relay.nsite.lol \
  | jq -r '.tags[] | select(.[0]=="path") | "\(.[2]) \(.[1])"'
# then: sha256sum of any file you fetched must match its path tag
```

Text from upstream NIPs is MIT-licensed; quotations remain their authors'.
