# 06 — Nostr Foundations for Operators

This chapter is connective tissue: the protocol-level concepts underneath every Soapbox product a builder will touch — Ditto (community/company ops) [1], Agora (fundraising) [2], Shakespeare (AI-built sites) [3], NostrHub (publishing) [4]. Other chapters cover each product's verdict in depth; this one covers the NIPs (Nostr Implementation Possibilities) those products are built from, so decisions in one tool make sense in the others. Verified live against the `nostr-protocol/nips` repo on 2026-07-09 — the spec has moved since 2025 training data, notably several deprecations below.

**Worked examples throughout this chapter** (a company domain, an operator's day-1 checklist, an agent-dispatch pattern) use the maintainers' own setup — trespies.dev, the operator Cruz, the DojoGenesis agent stack — as concrete, real data instead of placeholders. Swap in your own domain, team, and orchestrator wherever you see them.

**Amended: 2026-07-10** (v2 wave — NIP-62, NIP-55/17/29/42/77 currency, onchain zaps, signer additions, local-first caching).

---

## 1. Identity & Keys for a Company

*Confidence: High — verified against NIP-01, NIP-05, NIP-07, NIP-46, NIP-49, NIP-55 source, plus GitHub PR history for key migration.*

A Nostr identity is one keypair: a private key (**nsec**) and a public key (**npub**) — bech32-encoded, human-readable wrappers around a raw secp256k1 hex key [5][6]. The **npub is the identity**. There is no username/password, no account database, no "forgot password" flow. Whoever holds the nsec *is* the account, permanently, on every relay and client at once.

**Why this matters more than it sounds like it should:** there is no ratified key-rotation mechanism. DOCUMENTED: "there is no native, widely-adopted key rotation or recovery in Nostr. Your public key is your identity, so you cannot update or rotate it while keeping the same account" [7] — a 2023 migration proposal (NIP-41) never merged [8]. If a key leaks, recovery is social: publish a note from the old key pointing followers to a new one, and wait for re-follows. NIP-26 (delegated signing), once floated as a fix, is now deprecated — "unnecessary burden" [5]. **Treat nsec loss as identity loss, not a support ticket.**

### Key custody decision tree

```mermaid
flowchart TD
    A[New Nostr keypair issued] --> B{Who needs to sign as this identity?}
    B -->|Just me, one laptop, daily use| C["NIP-07 browser extension<br/>(Alby or nos2x)"]
    B -->|Me, across phone + laptop| D["NIP-46 remote signer / bunker<br/>(nsec.app)"]
    B -->|Team / shared brand account| E["NIP-46 bunker, self-hosted or nsec.app<br/>+ per-teammate connection grants"]
    B -->|High-value / cold storage| F["Amber on a dedicated Android device<br/>(NIP-46 signer, key never leaves phone)"]
    C --> G["Back up nsec as ncryptsec<br/>(NIP-49, password-encrypted)"]
    D --> G
    E --> G
    F --> G
    G --> H["Password in password manager.<br/>Encrypted key stored offline.<br/>Raw nsec never pasted into chat, doc, or code."]
```

### NIP-07 vs NIP-46 — the two signer models

| | **NIP-07** (browser extension) | **NIP-46** (remote signer / bunker) |
|---|---|---|
| What it is | `window.nostr` object a browser extension injects; sites call `getPublicKey()`/`signEvent()` [9] | Client and signer talk over relays via encrypted `bunker://` or `nostrconnect://` events (kind 24133); nsec never touches the client device [10] |
| Where nsec lives | In the browser extension's storage, on that one machine | In the signer app/daemon — can be a phone, a server, hardware |
| Tools | Alby (Lightning wallet + signer, heavier), nos2x (signer-only, minimal, by Nostr's creator) [11] | nsec.app (desktop + mobile, non-custodial) [12]; Amber (Android, keeps nsec segregated in one app, acts as a NIP-46 signer for other apps) [13] |
| Best for | Solo desktop use, one machine | Multi-device use, teams, mobile-only, or keeping the key off the everyday client entirely |

Rationale straight from the spec: "Private keys should be exposed to as few systems - apps, operating systems, devices - as possible as each system adds to the attack surface" [10].

### NIP-55 — the third signer standard

NIP-07 and NIP-46 aren't the whole story. **NIP-55** standardizes signing through Android's intent system: a client sends a sign request as an Android Intent, the *signer app* — not the requesting app — shows the approval prompt and returns the signature, so the private key never enters the requesting app's process [46]. Status is `draft` `optional`, the same maturity marker most working NIPs in this manual carry, and Amber is the reference implementation [13][46]. Soapbox's own key-management guidance draws the line explicitly: apps should implement **NIP-07, NIP-55, and NIP-46** so a site or app can "request signatures... without ever seeing the private key itself" — and never fall back to asking for a raw nsec [47]. Treat that trio as the minimum bar for anything you build that touches Nostr keys.

Two signer tools worth knowing that are newer than most Nostr key-management writeups:
- **Soapbox Signer** (Chrome/Firefox extension, announced Dec 2025) — NIP-07, multi-identity (switch between several npubs from one extension), per-domain permission grants, both NIP-04 and NIP-44 encryption, and identity export as JSON/CSV for backup or migration [48].
- **Divine's Keycast** — a managed remote-signer service behind Divine, a Nostr-native short-video app (iOS + Android/Flutter): users create an account or import an nsec once, keys are encrypted server-side, and apps request signing via OAuth-style grants over a NIP-46 bunker URL — the pattern for "feels custodial, isn't underneath" signing [49].

### NIP-05 — your name@domain identifier

NIP-05 maps `name@yourdomain.com` to a pubkey via a JSON file at `/.well-known/nostr.json` [14]:

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

Clients GET `https://trespies.dev/.well-known/nostr.json?name=cruz` and check the returned pubkey matches your profile's claimed pubkey [14]. Two rules that trip people up: the endpoint **must not** redirect, and the local-part is restricted to `a-z0-9-_.` [14]. Critically, this is identification, not verification — NIP-05 "is not intended to *verify* a user, but only to *identify* them" [14]; it proves domain control, nothing about the person.

Two paths for `@trespies.dev`:
- **Static file** — trespies.dev already exists as a hosted static site; dropping a `.well-known/nostr.json` there is a no-server, static-hosting-compatible change [14]. This is the practical path for TresPies today.
- **Ditto self-service** — if community ops move to a self-hosted Ditto instance, Ditto grants NIP-05 self-service under its own domain, with admin approve/deny per request [15]. That's a *different* domain identity (e.g. `@community.trespies.dev`) than the static root-domain file — decide which one is canonical before publishing both.

### Org-account patterns

**[INFERRED from NIP-46 + NIP-05 mechanics — no single spec source covers "how a company does this."]** Nostr has no built-in org-account primitive; every event needs exactly one signing key. Two patterns cover most real usage:

| Pattern | How it works | Trade-off |
|---|---|---|
| **Shared brand account** | One npub (`@trespies`), key held in a bunker (self-hosted or nsec.app); staff get NIP-46 connection grants to request signatures, never see nsec | Single voice, single point of custody failure; revoking a departed teammate = revoking their bunker grant, not rotating the key |
| **Personal + domain identity** | Each teammate runs their own npub with `name@trespies.dev` NIP-05; "company" is expressed via shared domain + mutual follows/mentions, not one account | No single custody bottleneck; brand presence is diffuse across people |

Most orgs blend both — a brand account for official posts, personal NIP-05 identities on the same domain for individuals. Pick the brand-account bunker's admin (who can grant/revoke signer access) before anyone posts as `@trespies`.

### Day 1 with your new credentials — checklist

1. **Confirm your npub/nsec pair** is the one you were issued; do not generate a second one by accident in a different client.
2. **Back up nsec offline immediately** — encode it as `ncryptsec` (NIP-49: scrypt-derived key, XChaCha20-Poly1305 encryption) with a strong password [16]; store the password in a password manager and the encrypted string somewhere offline (not in this repo, not in Slack).
3. **Install a signer** — NIP-07 extension (Alby or nos2x) for daily browser use; if you'll ever touch a second device, set up a NIP-46 bunker (nsec.app) now rather than exporting raw nsec later.
4. **Publish your profile** — kind 0 event: name, about, picture, and (once a wallet exists — Section 4) a `lud16` lightning address.
5. **Set up NIP-05** — publish `.well-known/nostr.json` on trespies.dev per the format above; add the `nip05` field to your kind 0.
6. **Publish a relay list** — kind 10002 (NIP-65), 2-4 write relays + a few read relays (Section 2).
7. **First post** — a kind 1 note, to confirm the full round-trip: signer signs → event lands on your write relays → visible on njump.me or any client.

---

## 2. Relays

*Confidence: High — NIP-65, NIP-42, NIP-77 fetched directly; `NIndexedDB` confirmed against its own source file (2026-07-10); relay ecosystem facts cross-checked across two sources.*

A relay is a WebSocket server that stores and forwards events — dumb by design, no protocol-level authority. Clients choose which relays to trust. **NIP-65 (Relay List Metadata)** lets a user publish a kind 10002 event listing preferred relays, each optionally marked read or write [17].

> "When downloading events from a user, clients SHOULD use the write relays of that user." [17]

That's the **outbox model**: publish to *your* write relays, look for someone's posts on *their* write relays, look for mentions of them on *their* read relays — a directed lookup instead of querying every relay for everything. Spec guidance: keep the list small, 2-4 relays per category [17].

### NIP-42 (relay auth) and NIP-77 (sync efficiency)

Two more relay-level mechanics worth knowing before picking a relay mix. **NIP-42** is ephemeral challenge-response authentication: the relay sends `["AUTH", <challenge>]`, the client signs a throwaway kind-22242 event binding that challenge to the relay URL and sends it back [50]. Relays use this to gate access — restrict publishing to a whitelist, limit a private-message subscription to just its participants, or require auth before serving any request at all [50]. It's how a paid relay actually enforces "paid" instead of just asking nicely.

**NIP-77 (negentropy)** solves a different problem: efficient re-sync. Instead of a client re-downloading everything or diffing by event ID, negentropy does range-based set reconciliation — client and relay exchange compact fingerprints of what they already have and transfer only the gap [51]. The protocol originated in Doug Hoyte's strfry relay before being written up as NIP-77 [52]; independent client-side implementations exist too, e.g. `@nostr-dev-kit/sync`, which reports **10-100x bandwidth reduction** over plain REQ/EVENT sync once both sides are mostly caught up [52]. Caveat that matters operationally: merged into the NIPs repo is not the same as deployed — most relays don't implement NIP-77 yet, so treat it as a bonus when the relay on the other end supports it, not a default to build around.

| Relay type | Examples | Fit |
|---|---|---|
| Public/free | relay.damus.io, nos.lol [18] | Fine for personal reach, no guarantees, higher spam exposure |
| Paid | nostr.wine, nostr.land (~$5-10/mo) [18] | Spam filtering because posting costs something; worth it once discoverability matters |
| Self-hosted | Ditto (bundles its own relay) [1]; **Relay Kit** — "one install script to deploy and manage Nostr relays, Blossom servers, and nsite gateways" [19]; **Stacks** — Docker-based scaffolding for full Nostr infrastructure [19] | Full moderation control, own domain identity, operational burden is yours |

### Local-first caching — NIndexedDB

Everything above is about which server-side relay to trust. There's a client-side complement: **`NIndexedDB`**, from `@nostrify/indexeddb`, is a first-party persistent browser cache that implements the same `NStore` interface as a relay or any other Nostrify storage — so it drops in as a swap, not a rewrite [60]. It supports the full Nostr filter set (`ids`, `authors`, `kinds`, single-letter tag filters, `since`/`until`, `limit`, and `search`), resolves supersession correctly (a newer replaceable/addressable event overwrites the old one in the cache, so queries never surface a stale kind-0 profile), and applies NIP-09 deletion requests on write [60]. When IndexedDB itself isn't available — Apple's Lockdown Mode disables it, along with Service Workers and WASM, as part of the exact threat model Lockdown Mode targets [61] — `NIndexedDB` degrades to a silent no-op (`event()` does nothing, `query()` returns empty) instead of throwing, so an app built against it doesn't crash under Lockdown, it just stops caching [60]. The rest of the `NStore`/`NRelay` interface family — signer swaps, moderation policies, the other storage backends — is Chapter 11's job; this is the one piece operators need now, because it's the practical answer to "does the app work offline, and does it degrade gracefully when it can't."

**Moderation implication:** content policy lives at the relay + client layer, not a platform layer (expanded in Section 6). Running your own relay is how TresPies enforces house rules on its own community — but nothing stops content being copied to other relays first. Deletion requests (NIP-09, master table) are, by default, a *request* — not a guarantee; NIP-62 (Section 6) exists for a stronger, MUST-honor version, but adoption is thin enough that NIP-09's advisory norm is still the safer planning assumption.

---

## 3. Event Model & Content Kinds

*Confidence: High for kind mechanics (direct NIP fetches); Medium for "which tool uses which" (mix of docs + search-derived, current as of 2026-07-09; adoption claims for NIP-17/NIP-29 refreshed 2026-07-10).*

Every Nostr action is the same JSON envelope — `id`, `pubkey`, `created_at`, `kind`, `tags`, `content`, `sig` [6] — differentiated only by `kind`. An operator mostly touches these (NIP numbers cited individually below; kind registry per [5]):

| Kind | NIP | Plain-English function | Soapbox-stack surface |
|---|---|---|---|
| 0 | 01 | Profile (name, about, picture, `nip05`, `lud16`) | Every product — this *is* your identity card |
| 1 | 10 | Short text note (the "tweet") | Ditto feed, general posting |
| 3 | 02 | Follow list | Ditto, any client's "who you follow" |
| 30023 | 23 | Long-form content (articles/blogs, Markdown) | NostrHub docs, Ditto long-form posts — company blog/policy posts |
| 4 | 04 (**deprecated**) | Encrypted DM — legacy | Avoid for new work |
| 14 / 15 | 17 (+59) | Private chat message / file message, gift-wrapped | Ditto DMs, general private messaging |
| 34550 / 1111 | 72 (**unrecommended**) | Reddit-style community + moderator-approved posts | Legacy clients (Amethyst, Nostrudel, Satellite) [21] — not Ditto's model |
| 9 / 39000-39002 | 29 | Discord-style relay-enforced groups | Target model for Ditto's in-progress "groups" feature [15]; live today in 0xChat, chachi.chat [21] |
| 30311 | 53 | Live streaming event | Ditto live streams — town halls, AMAs [20] |
| 31922-31925 | 52 | Calendar events | Community scheduling |

### NIP-04 vs NIP-17 — currency verdict

**NIP-04 is deprecated** — "Encrypted Direct Message (superseded by NIP-17)" [5]. NIP-17 wraps a plain (unsigned) message in a **seal** (kind 13) then a **gift wrap** (kind 1059), per NIP-59 [22][23]. The privacy gain is real: "Participant identities, each message's real date and time, event kinds… are all hidden from the public" [22] — each gift wrap uses a random one-time key so relays can't correlate messages by sender, and timestamps are randomized per layer to defeat timing analysis [23]. NIP-04 leaked all of that — sender, recipient, and timing were public even though content was encrypted. **Any new DM feature should be NIP-17, full stop.**

Adoption has moved from "the spec says so" to "the clients actually ship it": Amethyst, Primal, Nostur, Damus, noStrudel, and Coracle all run NIP-17 as their primary DM protocol now, and Amethyst's newer work extends the same gift-wrap machinery to sealed private replies on regular notes, not just 1:1 DMs [54]. Mostro — the P2P Bitcoin/Lightning exchange built on Nostr — made the same move at the protocol level: Mostro Protocol v2 (mostro-core v0.13.0) replaced its old relay-routed order messaging with NIP-44-encrypted, gift-wrapped kind-14 messages bound to a per-trade key, so relays now see only encrypted envelopes instead of order/dispute/settlement metadata [55]. Two different products, same direction of travel.

**Watch item, not a recommendation yet — and already more moved-on than expected:** a parallel track for *group* E2EE exists, adapting MLS (Messaging Layer Security, the Signal-Protocol successor standardized as RFC 9420) for Nostr. This is exactly the kind of ground that shifts between verification passes: the original proposal, **NIP-EE**, is now itself marked `unrecommended` in the live NIPs repo, superseded by a separate, non-NIP-numbered spec called the **Marmot Protocol** [56]. Marmot is still experimental but already has real implementations moving — MDK (its Rust reference stack), `marmot-ts`, and apps including White Noise, Pika, and Vector [57]. Don't build on NIP-EE directly; if group E2EE becomes a real requirement, evaluate Marmot instead, and re-verify its status before committing to it.

### NIP-72 vs NIP-29 — currency verdict

Sharper than expected: **NIP-72 is now marked unrecommended in the core spec** — "`unrecommended`: try NIP-29 instead" [24]. Steering has moved from moderator-approval (Reddit-style) toward relay-enforced membership (Discord-style), though *both* still have active client support today (NIP-72: Amethyst, Nostrudel, Satellite; NIP-29: 0xChat, chachi.chat, groups.nip29.com, and Flotilla — partially [21]). NIP-29 itself is still `draft` `optional`, the same maturity marker NIP-72 carries [21] — steering intent isn't the same as ratified stability. **Ditto does neither exactly** — it runs Mastodon-style server/domain moderation (admins, reports, NIP-05 self-service) today, with NIP-29-style groups on its roadmap [15]. Operator read: don't build new tooling against NIP-72; use Ditto's current server-level moderation if it fits, and wait for its NIP-29 groups for Discord-style team space. For a consumer app specifically: NIP-29's implementation list is real but still small and still drafting — not a universal-adoption bet yet, the way NIP-65 or NIP-17 now are.

---

## 4. Payments

*Confidence: High for NIP-57/47/60/61 mechanics (direct spec fetches) and for kind 8333 onchain zaps (Ditto reference doc fetched directly, 2026-07-10); Medium for wallet-option currency (fast-moving market, verify before funding anything).*

### Zap flow (NIP-57)

```mermaid
sequenceDiagram
    participant S as Sender
    participant C as Sender's client
    participant L as Recipient's LNURL/Lightning server
    participant R as Relay
    participant P as Recipient

    S->>C: Choose amount, click zap
    C->>L: Fetch LNURL pay endpoint (recipient's lud16 in kind 0)
    C->>C: Build + sign Zap Request (kind 9734)
    C->>L: Send zap request, receive Lightning invoice
    S->>L: Pay invoice
    L->>R: Publish Zap Receipt (kind 9735)
    R->>P: Receipt visible to all clients reading that relay
```

A **zap request** (kind 9734) is signed by the sender but sent directly to the recipient's LNURL callback — it is *not* itself published to relays [25]. Once paid, the recipient's Lightning service publishes a **zap receipt** (kind 9735) to the relays named in the request [25] — that receipt is the public, verifiable "this got paid" record clients render as a zap.

### Nostr Wallet Connect (NIP-47)

NWC lets an app pay/check-balance/list-transactions against a wallet **without ever holding the wallet's keys** — connection is a `nostr+walletconnect://` URI (wallet pubkey + per-client secret + relay) [26]. The wallet service runs as an always-on process; the client stores only its own secret and talks to it over relays [26] — this is what lets you connect one Alby Hub wallet to several apps with separate, revocable, spend-limited grants per app.

### Cashu / nutzaps (NIP-60 / NIP-61) — status: active, still maturing

Both are **live, non-deprecated NIPs** [5]. NIP-60 stores an encrypted "wallet in relays" — mint references and unspent ecash proofs as kind 17375/7375/7376/7374 events, so wallet state follows the user across apps [27]. NIP-61 "nutzaps" collapse payment and receipt into one object: a Cashu token locked to the recipient's pubkey (P2PK) *is* the payment and the proof, no separate receipt needed [28]. Newer and less battle-tested than NIP-57 zaps; promising, not yet default.

### Onchain zaps (kind 8333) — a third payment mechanism

As of Ditto 2.12 (shipped, per Soapbox's own post, May 2026) there's a third way to move value on Nostr, alongside Lightning/NIP-57 and Cashu/NWC [58]: **onchain zaps** — direct on-chain Bitcoin transfers, using kind 8333, defined as "attestation that an on-chain Bitcoin transaction paid a Nostr event or profile" [59]. The mechanism leans on a property of Nostr keys that isn't obvious until pointed out: because both Nostr and Bitcoin use secp256k1, a Nostr public key can double directly as a Bitcoin address — no separate wallet setup for sender or receiver [58]. Ditto layers **Silent Payments** on top for privacy — deriving a fresh, unlinkable receiving address per payment from a single published key, so on-chain analysis can't trivially cluster a recipient's zaps together [58]. Practical cost, in the team's own words: "It was costing $0.24 to send a transaction. For most of its life the average Nostr transaction was about $0.02" [58] — an onchain zap costs noticeably more than a typical Lightning-based zap, a tradeoff the team argued over before shipping and judged acceptable once you're sending amounts larger than a tip; onchain fees also float with mempool conditions, so treat $0.24 as a snapshot, not a constant. For anyone building rather than just operating: this is the same territory MKStack's `onchain-bitcoin` skill covers (Chapter 12) — worth knowing it exists before reinventing it.

### Practical wallet options (verify before moving real money)

| Option | Custody | Fit |
|---|---|---|
| **Alby Hub** | Self-custodial; runs on your choice of 6 Lightning backends (LDK, LND, Greenlight, Phoenixd, Breez SDK, or a Cashu mint) [29][30] | Best fit for a technical operator wanting one controlled node behind NWC |
| **coinos** | Lower-friction web wallet, Lightning + ecash | Fast start, less control |
| **Primal Wallet** | Built into the Primal client | Fine for personal zapping, not a business Lightning node |
| **Cashu mints** | Ecash — the mint is a custodial trust point even though the token is bearer-instrument-like | Good for small nutzap balances; don't park significant value at a single mint |

Alby's own guidance signals the direction: they're "phasing out Alby's shared [custodial] wallet" for Alby Hub [31] — self-custody is where the tooling is consolidating in 2026, not custodial web wallets.

### Tax reality (flag, not advice)

Sats received for goods/services are ordinary income at fair market value in USD on the date received — for a sole proprietorship, Schedule C, subject to self-employment tax [32]. The $10,000 Form 8300 cash-reporting trigger technically applies to crypto too, though enforcement is currently paused pending final regulations [32]. Not tax advice — get an accountant before treating zaps as real revenue.

---

## 5. Files & Media — The Storage Substrate

*Confidence: High — Blossom BUD structure and NIP-96 deprecation directly confirmed from source.*

### NIP-96 vs Blossom — currency verdict

Settled. NIP-96 (HTTP File Storage Integration) carries an explicit deprecation banner: **"`unrecommended`: deprecated in favor of NIP-B7"** [33] — NIP-B7 being Blossom, which was folded into the core NIPs index as an active spec [5]. **Blossom won.** Don't build new file-upload integrations against NIP-96.

### How Blossom works

Blossom is an HTTP-endpoint spec for storing **blobs addressed by their SHA256 hash**, authorized using the uploader's Nostr keypair [34] — same file, same identity everywhere; upload/delete rights ride on Nostr auth, not a platform account. The spec is a stack of BUD (Blossom Upgrade Document) documents:

| BUD | Covers |
|---|---|
| BUD-01 | Fetching blobs (GET/HEAD) |
| BUD-02 | Uploading blobs |
| BUD-03 | User Server List — which servers a user prefers |
| BUD-04 | Server-to-server mirroring |
| BUD-05 | Media optimization/transformation |
| BUD-06 | Upload constraints |
| BUD-07 | Payment-gated storage |
| BUD-08 | Nostr metadata tags for files |
| BUD-09 | Blob reporting/moderation |
| BUD-10 | URI schema |
| BUD-11 | Nostr-based auth tokens |
| BUD-12 | Blob lifecycle (delete/list) |

Mirroring (BUD-04) is what makes this resilient: if a file's home server disappears, any client can pull it from another server in the uploader's published list [34] — same file, same hash, different host. Ditto's product materials describe its media layer as Blossom-integrated [1]; the specific server hostname surfaced in search wasn't independently confirmable this session (install-guide fetch 404'd) — see Open Questions.

### nsite — static sites on Blossom

nsite serves a full static website from a Blossom-hosted blob set, with the path-to-file mapping published as Nostr events under the owner's npub — "a static site deployed under your npub, where the raw data is stored on blossom servers, and the mapping from path to sha256 of the content is stored on relays" [35]. Effect: a website with no traditional host — if one gateway blocks it, it resolves through another, because resolution is relay-based, not DNS/server-based [35]. Directly relevant if Shakespeare-built output [3] ever needs a censorship-resistant deployment target beyond a conventional host.

### Media metadata in posts (NIP-92)

An `imeta` tag attaches structured metadata — MIME type, SHA256 hash, dimensions, blurhash, alt text — to a URL inside a kind 1 note's content [36], so clients can render previews and verify integrity before fetching.

### File-tool maturity

| Tool | Maturity | Fit for company docs |
|---|---|---|
| Blossom (protocol) | Active, in core NIPs | The substrate — always relevant |
| Blossom Drive | **Deprecated / unmaintained**, "hasn't been updated in over a year" [37] | Skip |
| Bouquet | Current recommended successor for managing Blossom blobs [37] | Reasonable for ad hoc file management today |
| nsite tooling (nsyte, nsite-cli, and related CLIs) | Multiple active repos surfaced in search; individual maintenance status not independently verified this session [35] | Good for static-site deployment, not general document storage |

---

## 6. Trust & Safety

*Confidence: High — NIP-56, NIP-32, NIP-51, NIP-09, NIP-62 fetched directly; NIP-62's named third-party implementations are REPORTED (search-derived), not all independently confirmed shipped.*

Three separate primitives, each doing one job:

- **NIP-56 Reporting** — kind 1984 events flag a pubkey or note under one of seven categories: nudity, malware, profanity, illegal, spam, impersonation, other [38]. The spec explicitly warns relays against fully-automated moderation on report volume alone — "reports are easily manipulated"; trusted moderator judgment is the intended backstop [38].
- **NIP-32 Labeling** — kind 1985 events attach a namespaced label (`L` tag) and value (`l` tag) to an event, pubkey, relay, or topic [39]. Broader than moderation — also used for content classification and licensing — but it's the primitive a moderation dashboard would consume.
- **NIP-51 Mute Lists** — kind 10000, a personal list of pubkeys/hashtags/words/threads a user doesn't want to see [40]; can hold private (encrypted) entries alongside public ones.

### NIP-09 vs NIP-62 — currency verdict

Reporting, labeling, and muting (above) are *signals* — they don't remove anything by themselves. Actual deletion is a separate, smaller pair of primitives, and the two are not equivalent:

- **NIP-09 (Event Deletion Request)** — a client asks relays to drop an event by publishing a kind-5 request naming it. Advisory only: the NIP uses SHOULD language, relays are free to ignore it, and nothing stops a relay that already forwarded the event from having it live on elsewhere. This is the deletion behavior most of the ecosystem has today.
- **NIP-62 (Request to Vanish)** — a materially stronger primitive, merged into the spec February 19, 2025 [53]. Relays that implement it **MUST** fully delete every event from the requesting pubkey (not just one named event), **MUST** ensure deleted events aren't re-broadcast, and — the clause with real teeth — **paid or access-restricted relays MUST honor the request regardless of the requester's account status** [53]: a relay can't hold data hostage by banning the account first. Requests can be **targeted** (naming specific relay URLs) or global (`["relay", "ALL_RELAYS"]`, broadcast as widely as possible) [53]. NIP-62 also SHOULDs relays into deleting NIP-59 gift wraps addressed to the pubkey — a vanish request can reach into someone's DMs, not just their public notes [53].

**Adoption is thin.** NIP-62 is real and legally meaningful wherever "right to be forgotten" regimes apply, but implementation is still early: rust-nostr has shipped it across all three of its storage backends (LMDB, SQLite, in-memory); the nostrcheck-server relay module and the Nestr client both show it as planned/in-progress per project trackers, not confirmed shipped [53]. Ditto's own support wasn't confirmed either way this session — verify directly before promising a user (or a regulator) that "vanish" actually works on your relay. **Practical read:** NIP-09 is still the safe default assumption for "will this actually disappear"; reach for NIP-62 when a deletion promise needs to be a MUST, not a SHOULD, and confirm relay-by-relay support before relying on it.

**Why moderation is relay + client level, not platform level:** no central authority can remove content network-wide. A relay operator (Ditto, in TresPies' case) decides what *their* relay stores, and clients decide what they render — reports and labels are *signals* those parties act on, not enforcement with teeth beyond one relay's boundary [15]. Practical consequence: you fully control your own relay's front door for events you're willing to purge on request — NIP-62 gives that control real force, NIP-09 gives it a polite ask — but neither can make content vanish once it has propagated to a relay outside your control.

---

## 7. Discovery & App Wiring

*Confidence: Medium — NIP-89/34 mechanics are High (direct fetch); the DVM ecosystem's current health is a mix of DOCUMENTED spec status and REPORTED community activity.*

**NIP-89 (Recommended Application Handlers)** is Nostr's "open in app" mechanism: apps publish kind 31990 advertising which event kinds they handle; users or contacts publish kind 31989 recommending a handler [41]. Same mechanism DVM marketplaces use for provider discovery (below).

**NIP-34 (git over Nostr)** replaces GitHub's centralized model with relay-published repo announcements (kind 30617), patches (kind 1617), and issues (kind 1621) [42] — not in the Soapbox stack directly, but a pattern any team could use for censorship-resistant code collaboration.

**NIP-05 as lightweight SSO:** since a NIP-05 identifier cryptographically ties a domain to a pubkey [14], "Login with Nostr" flows ask a user to sign a challenge event and check it resolves to the claimed `name@domain` — no password, no OAuth provider. Any app you build (via Shakespeare or otherwise) can use this for low-friction auth.

### DVMs (NIP-90) — worked example: the agent-dispatch angle

**Currency verdict: the base spec is deprecated.** Its own file warns: *"this got totally out of control, prefer use-case-specific microstandards"* [43], `unrecommended` throughout. No single named successor — but the pattern moved rather than died: a dedicated `nostr-protocol/data-vending-machines` repo maintains the kind registry (5000-5999 requests → 6000-6999 results → 7000 status) as narrow per-job "microstandards" [44]. Discovery still runs through NIP-89 — newer projects (e.g. Agentry) auto-discover DVM providers via kind 31990 [45].

**Worked example — if you run an agent orchestrator** (DojoGenesis Gateway, or any other agent-dispatch stack): DVMs are structurally the same shape as an internal job-dispatch queue (the maintainers' own is `dojo_agent_dispatch`) — post a job, providers compete, deliver, get paid in sats instead of an internal ledger. Real and live, worth scouting for any orchestrator looking for an open, cross-network job market — but the "unrecommended" base spec plus an informally-governed sister repo means treat it as an *early probe*, not a dependency.

---

## 8. Master NIP Reference Table

*The protocol reference card for this manual. Status reflects the live `nostr-protocol/nips` repo as of 2026-07-09 [5], amended 2026-07-10 with NIP-62, NIP-55, NIP-42, NIP-77, and kind 8333 (onchain zaps) — see the Amended note at the top of the chapter. Individual NIPs are cited in the relevant prose sections above; this table is the consolidated index.*

| NIP / Protocol | Function | Soapbox-stack surface | Operator relevance |
|---|---|---|---|
| NIP-01 | Core event format, keys, kind 0 profile | Every product | Foundation — read once, applies everywhere |
| NIP-02 | Follow list (kind 3) | All clients | Who your account follows |
| NIP-05 | `name@domain` identifier via `.well-known/nostr.json` | Static hosting (e.g. trespies.dev) or Ditto self-service | Sets up `you@yourdomain`; day-1 task |
| NIP-07 | Browser-extension signing (`window.nostr`) | Any web client, incl. Shakespeare-built sites | Alby or nos2x for daily desktop use |
| NIP-09 | Event deletion request | All clients | Advisory only — not guaranteed removal; see NIP-62 for the MUST-delete alternative |
| NIP-17 + NIP-59 | Private DMs via gift-wrap | Ditto DMs, general clients | Current standard — use this, not NIP-04 |
| NIP-19 | bech32 entities (npub/nsec/note/nevent) | Universal | How keys/events are shared as text |
| NIP-23 | Long-form content (kind 30023) | NostrHub docs, Ditto articles | Company blog posts, policy docs |
| NIP-26 | Delegated signing | **Deprecated** — none | Ignore; don't build on it |
| NIP-29 | Relay-based groups (Discord-style) | Roadmap for Ditto groups; live in 0xChat, chachi.chat, groups.nip29.com, Flotilla (partial) | Team/private space, once Ditto ships it — still draft-status itself |
| NIP-32 | Labeling (kind 1985) | Ditto moderation backend | Content classification signal |
| NIP-34 | Git over Nostr | Not in Soapbox stack directly | Optional pattern for censorship-resistant code collab |
| NIP-41 | Key migration | **Unmerged proposal, stalled** | Don't rely on it — use social recovery instead |
| NIP-42 | Relay authentication (ephemeral kind-22242 challenge-response) | Paid/whitelisted relays, DM-gating | Gates access — expect it wherever a relay charges or restricts |
| NIP-46 | Remote signing (bunker) | nsec.app, Amber, Divine's Keycast; any NIP-46-aware client | Team + multi-device signing without exposing nsec |
| NIP-47 | Nostr Wallet Connect | Alby Hub → any app | Connect one wallet to many apps, revocable per app |
| NIP-49 | `ncryptsec` password-encrypted key backup | Manual step, any client | How you back up nsec safely |
| NIP-51 | Lists (mute list, bookmarks, etc.) | Ditto, any client | Spam/abuse control (kind 10000 mute list) |
| NIP-52 | Calendar events | Community clients | Scheduling for company/community events |
| NIP-53 | Live streaming (kind 30311) | Ditto live streams | Town halls, AMAs |
| NIP-55 | Android signer app intents | Amber; any Android Nostr app | Third signing standard alongside NIP-07/NIP-46 — never request raw nsec |
| NIP-56 | Reporting (kind 1984) | Ditto moderation queue | Abuse-reporting pipeline |
| NIP-57 | Lightning zaps | Ditto tipping; likely Agora's payment signal (unconfirmed — see Open Questions) | Value-for-content, community support |
| NIP-60 | Cashu wallet (wallet-in-relays) | Emerging wallet layer | Portable ecash balance across apps — still maturing |
| NIP-61 | Nutzaps (payment = receipt) | Emerging | Newer than zaps; promising, not yet default |
| NIP-62 | Request to Vanish — MUST-delete, not advisory | Not confirmed in Ditto; rust-nostr, others (thin adoption) | Stronger deletion primitive than NIP-09; verify per-relay before relying on it |
| NIP-65 | Relay list metadata / outbox model | All clients | Relay strategy — where you publish, where others find you |
| NIP-72 | Communities (Reddit-style) | **Unrecommended** — legacy clients only | Understand it; don't build new work on it |
| NIP-77 | Negentropy sync (range-based set reconciliation) | strfry origin; `@nostr-dev-kit/sync` client-side | 10-100x sync bandwidth once both sides support it — most relays don't yet |
| NIP-89 | Recommended application handlers | Shakespeare-built apps, NostrHub app directory, DVM discovery | "Open in app" discovery; also how DVM providers get found |
| NIP-90 | Data Vending Machines | Not in Soapbox stack directly; relevant to any agent orchestrator | AI-agent job marketplace pattern — **base spec deprecated**, successor is a sister kind-registry repo |
| NIP-92 | Media attachment metadata (`imeta`) | Ditto media posts | Rich previews, integrity hashes on posted media |
| NIP-94 | File metadata event | Pairs with Blossom uploads | Describes an uploaded file as a Nostr event |
| NIP-96 | HTTP file storage | **Deprecated** — replaced by Blossom | Ignore; use Blossom |
| NIP-B7 (Blossom) | Blob storage protocol, hash-addressed | Ditto media layer, Shakespeare sites, nsite | The file-storage substrate under the whole stack |
| NIP-5A (nsite) | Static websites served from Blossom + relays | Alternative deploy target to conventional hosting | Censorship-resistant hosting option |
| Kind 8333 (no NIP number yet) | Onchain zap — Bitcoin tx as payment attestation | Ditto 2.12+ wallet | Third payment rail alongside Lightning zaps and Cashu; Silent Payments privacy option |

---

## Open Questions

- Whether Agora emits actual NIP-57 zap receipts, or uses a simpler direct wallet-to-wallet Lightning flow with Nostr only for identity/comms — Agora's own materials describe "wallet-to-wallet" Bitcoin movement without confirming zap-event mechanics [2]; verify in the Agora-specific chapter.
- Whether Ditto's media pipeline specifically points at `blossom.ditto.pub` — this hostname surfaced in preliminary search results but the primary Ditto self-hosting doc 404'd on direct fetch this session; the general claim "Ditto integrates with Blossom" is solid [1], the specific hostname is REPORTED, not independently confirmed.
- Exact reason NIP-06 (mnemonic-seed key derivation) was deprecated — confirmed deprecated in the index [5], but the deprecation-note text itself wasn't fetched; doesn't change the operator recommendation (use NIP-49 `ncryptsec` for backup) but worth closing out if seed-phrase import ever comes up in a signer's UI.
- Whether Ditto's planned NIP-29 groups feature has shipped by the time an operator would adopt it — roadmap item as of the fetched blog post [15], not yet confirmed live.
- DVM ecosystem health beyond the spec-status question — Agentry and similar discovery projects surfaced in search but weren't independently verified for maturity beyond their own landing page [45]; treat any DVM integration as a probe, not a plan.

---

## Sources

1. [Soapbox — Ditto product page](https://soapbox.pub/ditto), plus [Announcing Ditto](https://soapbox.pub/blog/announcing-ditto) and [Ditto Server Keypair docs](https://docs.soapbox.pub/ditto/nsec) — accessed 2026-07-09 — Ditto architecture (relay + web UI + Mastodon API), Blossom integration, self-hosted relay.
2. [Soapbox — Agora](https://soapbox.pub/agora) and [Agora: Connecting Freedom Fighters to Uncensorable International Support](https://soapbox.pub/blog/agora-connecting-freedom-fighters) — accessed 2026-07-09 — Agora product description, non-custodial wallet-to-wallet design, Nostr-as-comms-layer framing.
3. [Soapbox — Shakespeare](https://soapbox.pub/tools/shakespeare) and [Announcing Shakespeare](https://soapbox.pub/blog/announcing-shakespeare) — accessed 2026-07-09 — AI website builder on Nostr, NSP model, AGPL license.
4. [Soapbox — NostrHub](https://soapbox.pub/tools/nostrhub/) — accessed 2026-07-09 — NIP/app/repo discovery hub description.
5. [nostr-protocol/nips README (NIP index + kind registry)](https://github.com/nostr-protocol/nips/blob/master/README.md) — accessed 2026-07-09 — full NIP list, deprecation status, complete event-kind registry.
6. [NIP-01: Basic protocol flow description](https://github.com/nostr-protocol/nips/blob/master/01.md) — accessed 2026-07-09 — event structure, key basics, kind 0 definition.
7. [Nostr Key Management: Complete Guide](https://nostr.co.uk/learn/key-management/) — accessed 2026-07-09 — current-practice statement on key rotation absence.
8. [NIP-41: simple account migration (unmerged PR #829)](https://github.com/nostr-protocol/nips/pull/829) — accessed 2026-07-09 — confirms migration proposal never ratified.
9. [NIP-07: `window.nostr` capability for web browsers](https://github.com/nostr-protocol/nips/blob/master/07.md) — accessed 2026-07-09 — extension API, methods.
10. [NIP-46: Nostr Remote Signing](https://github.com/nostr-protocol/nips/blob/master/46.md) — accessed 2026-07-09 — bunker/nostrconnect flow, roles, rationale quote.
11. [Best Nostr Browser Extensions 2026 — comparison](https://threenine.blog/posts/best-nostr-browser-extensions-2026) — accessed 2026-07-09 — Alby vs nos2x positioning.
12. [nsec.app](https://nsec.app/) — accessed 2026-07-09 — non-custodial key storage/remote signer product description.
13. [Amber (GitHub)](https://github.com/greenart7c3/Amber) — accessed 2026-07-09 — Android NIP-46 signer, supported client list.
14. [NIP-05: Mapping Nostr keys to DNS-based identifiers](https://github.com/nostr-protocol/nips/blob/master/05.md) — accessed 2026-07-09 — exact `.well-known/nostr.json` format, verification flow, caveats.
15. [Creating Curated Communities on Nostr with Ditto](https://soapbox.pub/blog/curated-communities-with-ditto/) — accessed 2026-07-09 — NIP-05 self-service, moderation model, NIP-29 roadmap note.
16. [NIP-49: Private Key Encryption (`ncryptsec`)](https://github.com/nostr-protocol/nips/blob/master/49.md) — accessed 2026-07-09 — password-encrypted key backup spec.
17. [NIP-65: Relay List Metadata](https://github.com/nostr-protocol/nips/blob/master/65.md) — accessed 2026-07-09 — outbox model, read/write markers.
18. [How to Choose Nostr Relays](https://threenine.blog/posts/how-to-choose-nostr-relays) — accessed 2026-07-09 — relay-mix recommendations, paid relay examples/pricing.
19. [Soapbox Toolbox](https://soapbox.pub/toolbox) — accessed 2026-07-09 — full Soapbox product inventory, Relay Kit / Stacks descriptions.
20. [NIP-53: Live Streaming and Spaces](https://nips.nostr.com/53) — accessed 2026-07-09 — kind 30311 structure.
21. [Comparing Nostr Group Implementations — Nostrbook](https://nostrbook.dev/groups) — accessed 2026-07-09 — plain-English NIP-29 vs NIP-72 comparison, client support lists.
22. [NIP-17: Private Direct Messages](https://github.com/nostr-protocol/nips/blob/master/17.md) — accessed 2026-07-09 — gift-wrap DM design, kind 14/15.
23. [NIP-59: Gift Wrap](https://github.com/nostr-protocol/nips/blob/master/59.md) — accessed 2026-07-09 — rumor/seal/wrap layering, metadata protection.
24. [NIP-72: Moderated Communities](https://github.com/nostr-protocol/nips/blob/master/72.md) — accessed 2026-07-09 — verbatim deprecation notice, original community model.
25. [NIP-57: Lightning Zaps](https://github.com/nostr-protocol/nips/blob/master/57.md) — accessed 2026-07-09 — zap request/receipt flow.
26. [NIP-47: Nostr Wallet Connect](https://github.com/nostr-protocol/nips/blob/master/47.md) — accessed 2026-07-09 — connection URI, methods, roles.
27. [NIP-60: Cashu Wallet](https://github.com/nostr-protocol/nips/blob/master/60.md) — accessed 2026-07-09 — wallet-in-relays architecture, kind numbers.
28. [NIP-61: Nutzaps](https://github.com/nostr-protocol/nips/blob/master/61.md) — accessed 2026-07-09 — payment-as-receipt design, kind 9321.
29. [Alby Hub](https://albyhub.com/) — accessed 2026-07-09 — self-custodial wallet product description.
30. [The 6 different Lightning backends for Alby Hub](https://blog.getalby.com/the-6-different-lightning-backends-for-alby-hub/) — accessed 2026-07-09 — backend options (LDK, LND, Greenlight, Phoenixd, Breez SDK, Cashu mint).
31. [Embrace Alby Hub — phasing out Alby's shared wallet](https://guides.getalby.com/user-guide/alby-account/faq/embrace-alby-hub-phasing-out-albys-shared-wallet) — accessed 2026-07-09 — custodial-to-self-custodial market shift, verbatim quote.
32. [IRS: Report digital asset income](https://www.irs.gov/filing/digital-assets) — accessed 2026-07-09 — tax treatment of crypto/digital-asset income, Form 8300 status.
33. [NIP-96: HTTP File Storage Integration](https://github.com/nostr-protocol/nips/blob/master/96.md) — accessed 2026-07-09 — verbatim deprecation notice pointing to NIP-B7/Blossom.
34. [Blossom protocol README / BUD specs](https://github.com/hzrd149/blossom/blob/master/README.md) — accessed 2026-07-09 — blob addressing, BUD-01 through BUD-12 overview, mirroring.
35. [Nsite.info — Let them eat static](https://nsite.info/learn) — accessed 2026-07-09 — nsite mechanics, Blossom + relay resolution; also source for nsite CLI tooling landscape.
36. [NIP-92: Media Attachments Metadata (`imeta`)](https://github.com/nostr-protocol/nips/blob/master/92.md) — accessed 2026-07-09 — imeta tag fields.
37. [blossom-drive (GitHub) — deprecation note pointing to Bouquet](https://github.com/hzrd149/blossom-drive) — accessed 2026-07-09 — file-manager tool status.
38. [NIP-56: Reporting](https://github.com/nostr-protocol/nips/blob/master/56.md) — accessed 2026-07-09 — kind 1984 structure, report categories.
39. [NIP-32: Labeling](https://github.com/nostr-protocol/nips/blob/master/32.md) — accessed 2026-07-09 — kind 1985 structure, namespaces, use cases.
40. [NIP-51: Lists](https://github.com/nostr-protocol/nips/blob/master/51.md) — accessed 2026-07-09 — mute list and other standard list kinds.
41. [NIP-89: Recommended Application Handlers](https://github.com/nostr-protocol/nips/blob/master/89.md) — accessed 2026-07-09 — kind 31989/31990 discovery mechanism.
42. [NIP-34: git stuff](https://github.com/nostr-protocol/nips/blob/master/34.md) — accessed 2026-07-09 — repo/patch/issue event kinds.
43. [NIP-90: Data Vending Machines](https://github.com/nostr-protocol/nips/blob/master/90.md) — accessed 2026-07-09 — verbatim deprecation notice, original job-marketplace design.
44. [nostr-protocol/data-vending-machines (kind registry repo)](https://github.com/nostr-protocol/data-vending-machines) — accessed 2026-07-09 — successor governance model for DVM kinds.
45. [Nostr Agent Network — Agentry](https://agentry.com/nostr/) — accessed 2026-07-09 — example of DVM provider discovery via NIP-89.

**Amendment pack sources (2026-07-10 v2 wave):**

46. [NIP-55: Android Signer Application](https://github.com/nostr-protocol/nips/blob/master/55.md) — accessed 2026-07-10 — status header (`draft` `optional`), Intent/Content Resolver/Web signing methods.
47. [Managing Nostr Keys — Soapbox Blog](https://soapbox.pub/blog/managing-nostr-keys) — accessed 2026-07-10 — NIP-07/NIP-55/NIP-46 framing as the three signing standards apps should implement, Amber description.
48. [Announcing Soapbox Signer](https://soapbox.pub/blog/announcing-soapbox-signer) — accessed 2026-07-10 — Dec 7 2025 launch, Chrome/Firefox extension, multi-identity, per-domain permissions, NIP-04/NIP-44, JSON/CSV identity export.
49. [Divine — Open Source](https://divine.video/open-source), [Divine (GitHub org)](https://github.com/divinevideo), [Keycast (GitHub)](https://github.com/divinevideo/keycast) — accessed 2026-07-10 — Nostr-native short-video app; Keycast as its OAuth-style NIP-46 remote-signer service; iOS App Store + Flutter Android build.
50. [NIP-42: Authentication of Clients to Relays](https://github.com/nostr-protocol/nips/blob/master/42.md) — accessed 2026-07-10 — ephemeral kind-22242 challenge-response flow, access-gating use cases.
51. [NIP-77: Negentropy Syncing](https://github.com/nostr-protocol/nips/blob/master/77.md) — accessed 2026-07-10 — range-based set reconciliation spec, `draft` status.
52. [@nostr-dev-kit/sync (npm)](https://www.npmjs.com/package/@nostr-dev-kit/sync), [hoytech/negentropy](https://github.com/hoytech/negentropy) — accessed 2026-07-10 — negentropy's origin in Doug Hoyte's strfry relay; 10-100x bandwidth-reduction claim; client-side NIP-77 implementation.
53. [NIP-62: Request to Vanish](https://github.com/nostr-protocol/nips/blob/master/62.md), [merge PR #1256](https://github.com/nostr-protocol/nips/pull/1256) — accessed 2026-07-10 — MUST-delete / no-rebroadcast / paid-relay language verbatim; merge date (2025-02-19) confirmed directly via repo commit history; third-party implementation status (rust-nostr, nostrcheck-server, Nestr) cross-checked via search — REPORTED, not all independently confirmed shipped.
54. [Amethyst (GitHub)](https://github.com/vitorpamplona/amethyst) — accessed 2026-07-10 — NIP-17 as primary DM protocol across major clients (Amethyst, Primal, Nostur, Damus, noStrudel, Coracle); gift-wrapped private-note replies — search-derived, current release cycle.
55. [Mostro (GitHub)](https://github.com/MostroP2P/mostro) — accessed 2026-07-10 — Mostro Protocol v2 / mostro-core v0.13.0 migration to NIP-44 gift-wrapped kind-14 trade messaging.
56. [NIP-EE: E2EE Messaging using MLS](https://github.com/nostr-protocol/nips/blob/master/EE.md) — accessed 2026-07-10 — status header (`final` `unrecommended` `optional`), verbatim supersession notice pointing to the Marmot Protocol.
57. [Marmot Protocol (GitHub)](https://github.com/marmot-protocol/marmot) — accessed 2026-07-10 — NIP-EE's successor; experimental status, named implementations (MDK, `marmot-ts`, White Noise, Pika, Vector).
58. [Onchain Zaps in Ditto — Soapbox Blog](https://soapbox.pub/blog/onchain-zaps-in-ditto) — accessed 2026-07-10 — May 2026 post; Ditto 2.12 wallet, Nostr-keys-as-Bitcoin-addresses mechanic, Silent Payments, verbatim $0.24-vs-$0.02 fee quote.
59. [Ditto Nostr Reference](https://about.ditto.pub/reference) — accessed 2026-07-10 — kind 8333 definition ("attestation that an on-chain Bitcoin transaction paid a Nostr event or profile").
60. [NIndexedDB.ts (soapbox-pub/nostrify)](https://github.com/soapbox-pub/nostrify/blob/main/packages/indexeddb/NIndexedDB.ts) — accessed 2026-07-10 — full source of `@nostrify/indexeddb`'s `NStore` implementation: filter support, replaceable/addressable supersession, NIP-09 deletion-on-write, IndexedDB-unavailable no-op behavior.
61. [About Lockdown Mode — Apple Support](https://support.apple.com/en-us/105120) — accessed 2026-07-10 — corroborates that Lockdown Mode disables IndexedDB-dependent web functionality, the real-world trigger for `NIndexedDB`'s no-op path.
