Join Nostr
2026-05-01 02:27:11 UTC

mstrofnone on Nostr: 📡 How to use relay.testls.bit — a Namecoin .bit-gated Nostr relay 🔗 ...

📡 How to use relay.testls.bit — a Namecoin .bit-gated Nostr relay

🔗 wss://relay.testls.bit/

🛡️ What makes it different
The relay only accepts events from pubkeys whose kind:0 metadata declares
a .bit NIP-05 identifier (e.g. _@yourname.bit, m@testls.bit). Verification
is done against Namecoin directly via ElectrumX — no DNS, no public CAs.

🚀 To use it as a write relay you need:
1. A Namecoin .bit name (d/ namespace) you control
2. Set the .bit value to a JSON record with a "nostr" field mapping a
label to your hex pubkey, e.g.
{"nostr":{"names":{"_":"<your-hex-pubkey>"}}}
3. Update your kind:0 metadata so "nip05" = "<label>@<yourname>.bit"
4. Add wss://relay.testls.bit/ to your client's relay list

📱 Native client support
Amethyst (Android + iOS + Desktop) has full .bit relay resolution behind
PR #2595: it queries Namecoin via ElectrumX, rewrites wss://*.bit/ to the
underlying real wss:// host or .onion, and pins TLS via Namecoin TLSA.
No client-side config needed beyond adding the relay URL.

https://github.com/vitorpamplona/amethyst/pull/2595

📡 Read-only access works for everyone
Even without a .bit identity you can subscribe with REQ and read the relay
freely. Only writes are gated.

🔐 Why this matters
It's a working demo of the cypherpunk thesis: name resolution and TLS
trust without ICANN, without public CAs, without DNS. Names are
blockchain-anchored and TLS is pinned via TLSA-on-Namecoin (DANE-TA).

🌐 Browse it in your browser: https://relay.testls.bit/
(vanilla SPA, talks WSS back to the same host. Self-signed cert is
pinned via Namecoin TLSA.)
Go to https://www.namecoin.org/download/ to figure out how to resolve
on your OS or in your browser

🔧 Nuts and Bolts — what a publisher actually has to do

1. On-chain Namecoin records (one-time per identity using <name>):

• id/<name> MUST exist with JSON like:
{"nostr":{"pubkey":"<hex-pubkey>",
"relays":["wss://relay.testls.bit/", ...]}}
id/<name> is the canonical NIP-05 namespace; the relay verifies
_@<name>.bit against this record.

• d/<name> SHOULD mirror the same "nostr" block for .bit-aware
clients that resolve the domain side too.

2. Nostr events to publish BEFORE your kind:1 content (every
identity, once per metadata change):

a. kind:0 (profile metadata) with content JSON containing
"nip05": "_@<name>.bit"
The "_" localpart resolves to id/<name> via the NIP-05
default-name rule. Without this, the relay rejects writes with:
blocked: this relay requires a verified Namecoin .bit NIP-05

b. kind:10002 (NIP-65 relay list) listing
wss://relay.testls.bit/
as a write relay. Not strictly required for acceptance, but
it makes the relay discoverable in the author's outbox.

Send both (a) and (b) to relay.testls.bit AND to your normal
public relays so verification + discovery stay in sync.

3. TLS handshake (every connection):

a. Resolve the host via Namecoin:
name_show d/testls -> map.relay -> { ip, tls }
The "tls" field is one or more TLSA records of shape
[usage, selector, matchingType, base64-data]
Currently usage=2 (DANE-TA), selector=1 (SPKI),
matching=1 (SHA-256).

b. Open TCP/TLS to that IP with SNI = "relay.testls.bit" and
your own certificate validation (rejectUnauthorized=false).

c. Pin against the TLSA. IMPORTANT: neither the leaf SPKI nor
the intermediate SPKI hashes match — the pin is the
AIA Parent CA SPKI, which the Namecoin TLS scheme staples
as JSON inside the *issuer's* serialNumber RDN:

serialNumber=Namecoin TLS Certificate
\n\nStapled: {"pubb64":"<b64url SPKI DER>"}

The cert literally encodes \" as backslash+quote and \0A
as \ 0 A in that string — unescape both before JSON.parse.
SHA-256 of base64url-decoded pubb64 is what TLSA covers.

d. Once the pin matches, hand the validated TLS socket to your
WebSocket client (e.g. ws's createConnection: () => socket)
so you don't trigger a second TLS handshake.

4. Operational order for a content broadcast:

a. Verify id/<name> + d/<name> on chain.
b. Publish kind:0 (with .bit nip05) → public relays + .bit relay.
c. Publish kind:10002 (with .bit relay) → public relays + .bit relay.
d. Publish kind:1 (your content) → public relays + .bit relay.

5. Common failure modes:

• "tls: TLSA pin mismatch"
You're hashing the leaf or chain SPKI. Use the stapled
AIA Parent CA SPKI from the issuer's serialNumber RDN.

• "blocked: this relay requires a verified Namecoin .bit NIP-05"
Latest kind:0 doesn't carry a .bit nip05, OR id/<name>
on-chain doesn't list this pubkey.

• TLSA pin mismatch after a server cert rotation
The on-chain "tls" array under d/<base>/map/<sub> needs an
update — the AIA Parent CA pubkey is the trust anchor.

Reference implementation:
https://github.com/mstrofnone/nmcLightningService (publish-announce-bit.js)


#namecoin #nostr #cypherpunk #dotbit