Skip to content

feat(namecoin): resolve .bit NIP-05 identifiers via Namecoin ElectrumX#2128

Open
mstrofnone wants to merge 1 commit into
SnowCait:mainfrom
mstrofnone:feat/namecoin-bit-nip05
Open

feat(namecoin): resolve .bit NIP-05 identifiers via Namecoin ElectrumX#2128
mstrofnone wants to merge 1 commit into
SnowCait:mainfrom
mstrofnone:feat/namecoin-bit-nip05

Conversation

@mstrofnone
Copy link
Copy Markdown

Summary

Adds optional Namecoin .bit verification: NIP-05 addresses ending in .bit (and the d/<name> / id/<name> shorthands) are resolved over the Namecoin blockchain instead of HTTPS, giving users a DNS-free alternative for identity verification. Everything else still flows through nostr-tools exactly as today.

Why

.bit is a censorship-resistant naming layer (Namecoin, since 2011). For a calm reader-oriented client like nostter, this lands as a one-line suffix check in the existing NIP-05 path — no new UI noise, no new badges, no new top-level components. The existing verified checkmark either lights up for a .bit address or it doesn't, same as for a .com address.

Scope

  • One module: src/lib/namecoin/ (cache + WSS ElectrumX client + ifa-0001 value parser + tests).
  • One hook: src/lib/Nip05.ts wraps nostr-tools queryProfile. .bit shapes route to the Namecoin resolver; everything else falls through unchanged.
  • Two existing call sites updated to use the wrapper (NostrAddress.svelte and the [slug=npub] slug-overwrite path).
  • No new top-level UI elements.
  • Falls back silently on resolver failure (transport error, missing nostr field, expired name).

Wire format

Same wire format used in Amethyst (Kotlin), Nostur (Swift), dart-nostr (merged), and the in-review PRs against nostrudel, jumble, and nostr-tools:

  • d/<domain> records: read nostr.names[<local-part>] (with _ as the root entry), with optional nostr.relays map keyed by pubkey.
  • id/<name> records: read nostr.pubkey plus optional flat nostr.relays array.
  • Shorthand "nostr": "<hex>" accepted as the root entry of a d/ record.

See the N1 NIP draft for the formal definition.

Try it

  • _@mstrofnone.bit resolves to the same pubkey as the existing mstrofnone npub on the Namecoin chain.
  • mstrofnone.bit (the bare shorthand) does the same.

Footprint

+1012 / -8 across 10 files (most of that is the WSS client + tests). The two existing Svelte components each get a 2-line import-swap; everything else is new code under src/lib/namecoin/.

Tests & checks

  • 21 new vitest tests for the parser + mock-socket resolver path.
  • Full suite: 103/103 pass.
  • Prettier + ESLint clean for new files.
  • svelte-check: zero regressions (11 pre-existing errors, same count before and after; none introduced by this change).

Server pool note

The shipped default list is the 4-of-6 browser-WSS subset of Amethyst's DEFAULT_ELECTRUMX_SERVERS. Two of Amethyst's entries are bare IPs that browsers refuse over WSS (no IP-SAN cert), so they're deliberately omitted here. This is documented inline in electrumx.ts. Of the four shipped servers, electrum.nmc.ethicnology.com is the most browser-friendly today (Let's Encrypt-fronted); the other three serve self-signed certs and will only succeed once the user has TOFU-trusted them. The calm-failure UX means this is fine: .bit verification is optional, and if every server fails the checkmark just stays dark.

Adds optional Namecoin .bit verification to the existing NIP-05 path.
Identifiers ending in .bit (and the d/<name> / id/<name> shorthands)
are routed to a small browser-WSS ElectrumX client instead of HTTPS,
giving users a DNS-free option for identity verification.

Wire format follows the parallel ports in Amethyst (Kotlin), Nostur
(Swift), nostr-tools PR SnowCait#533 / Jumble PR SnowCait#774 / nostrudel PR SnowCait#352
(JS), and dart-nostr PR SnowCait#44 (Dart, merged). Domain names use
"nostr.names[<local>]" with optional "nostr.relays" map; identity
names (id/) use "nostr.pubkey" + array relays; the shorthand
"nostr": "<hex>" form is accepted for root entries.

- Module: src/lib/namecoin/ (cache + electrumx + parser + tests).
- Single hook: src/lib/Nip05.ts wraps nostr-tools queryProfile,
  routing .bit identifiers and falling through for everything else.
- Two call sites updated: NostrAddress.svelte (profile NIP-05 row)
  and the npub route slug-overwrite path.
- No new top-level UI: the existing verified checkmark either lights
  up or stays dark, no extra badges or noise.
- Browser-WSS pool is the 4-of-6 subset of amethyst's
  DEFAULT_ELECTRUMX_SERVERS that operators expose over WSS. Bare-IP
  amethyst entries are deliberately skipped (no IP-SAN cert path in
  browsers). Documented in a comment in electrumx.ts.
- 21 new unit tests, all passing; full suite stays at 103/103.

Try it: `_@mstrofnone.bit` resolves to the same pubkey as the
existing mstrofnone npub.
@mstrofnone mstrofnone requested a review from SnowCait as a code owner May 19, 2026 13:51
@SnowCait
Copy link
Copy Markdown
Owner

I know nothing about Namecoin, so I cannot judge whether I should implement a specification that does not exist in NIP-05. Also, I cannot verify your code.
I am very sorry, but I will have to reconsider this after it has been merged into the NIPs and reflected in nostr-tools.

@mstrofnone
Copy link
Copy Markdown
Author

sure @SnowCait that seems very reasonable

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants