Keynctr/docs/NIP-05.md
Avi 045fa47476 Add NIP-05 identifiers: store, publish, GUI modal, CLI helpers
- Store an optional nip05 on each profile; publish it in kind 0 metadata
- set-nip05 CLI (+ validation, lower-casing, clear) and nip05-file helper
  that prints the .well-known/nostr.json document for a domain
- Profiles screen: NIP-05 button, handle shown on cards, Nip05Modal with
  client-side validation and Remove action
- Fix Modal stealing focus from autoFocus inputs one frame after open
2026-08-23 21:59:11 -05:00

2.4 KiB

NIP-05 identifiers in Keynectr

A NIP-05 identifier is a human-readable Nostr address that looks like an email address — for example boo@l484.com. When a profile has one, clients such as Iris, Yakihonne, Amethyst and snort show the handle instead of a raw npub1… key, and users can find and tag you by typing it.

NIP-05 has two halves. Keynectr does the first half; you do the second half once on your own domain.

1. Publish it from Keynectr (the app side)

  • GUI: Profiles → NIP-05 button → enter name@domain.com → Save & publish. The identifier is stored with the profile and published to your enabled relays as part of your kind 0 metadata.
  • CLI:
    B=~/Projects/Nostr_Keynctr/target/release/keynectr
    $B set-nip05 <npub> boo@l484.com   # set + publish
    $B set-nip05 <npub> clear          # remove + publish the removal
    
  • The special form _@domain.com claims the bare domain itself (the whole domain shows as your handle).

2. Serve .well-known/nostr.json (the domain side)

Clients verify a NIP-05 claim by fetching:

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

That file must live on the domain in the identifier — publishing alone is not enough. Keynectr prints the exact document to serve:

$B nip05-file <npub> boo@l484.com

which outputs something like:

{
  "names": {
    "boo": "3bf0c6…(64-char hex public key)"
  },
  "relays": {
    "3bf0c6…": ["wss://nos.lol", "wss://relay.primal.net"]
  }
}

Serve it at https://<domain>/.well-known/nostr.json with:

  • Content-Type: application/json (or application/json; charset=utf-8)
  • CORS header Access-Control-Allow-Origin: * (clients fetch it from browsers)

nginx example

location = /.well-known/nostr.json {
    include snippets/cors.conf;           # or add_header Access-Control-Allow-Origin *;
    default_type application/json;
    root /var/www/static;
}

Then place the printed document at /var/www/static/.well-known/nostr.json. Regenerate it if you switch profiles or change your relay list.

Notes

  • The identifier is lower-cased when stored; validation matches NIP-05's limited character set (a-z, 0-9, -, _; _ for the bare domain).
  • Clients cache profiles aggressively — hard-refresh after changing anything.
  • Without the well-known file, most clients will not display the handle even though the metadata was published successfully.