<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <updated>2026-03-21T05:59:22Z</updated>
  <generator>https://yabu.me</generator>

  <title>Nostr notes by mstrofnone</title>
  <author>
    <name>mstrofnone</name>
  </author>
  <link rel="self" type="application/atom+xml" href="https://yabu.me/npub1gvv9ahktvavf9qjtrgm62le7gplmmchd5usp5wpfhr85hf79kncqj8xchs.rss" />
  <link href="https://yabu.me/npub1gvv9ahktvavf9qjtrgm62le7gplmmchd5usp5wpfhr85hf79kncqj8xchs" />
  <id>https://yabu.me/npub1gvv9ahktvavf9qjtrgm62le7gplmmchd5usp5wpfhr85hf79kncqj8xchs</id>
  <icon></icon>
  <logo></logo>




  <entry>
    <id>https://yabu.me/nevent1qqs89s7pm8vksq0n7r2tcpc80m3rnp2h55lfvypf5qq9xz9u89ng9fczypp3shk7edn43y5zfvdr0ftl8eq8l00zaknjqx3c9xuv7ja8ck60q456dtc</id>
    
      <title type="html">📡 How to use relay.testls.bit — a Namecoin .bit-gated Nostr ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqs89s7pm8vksq0n7r2tcpc80m3rnp2h55lfvypf5qq9xz9u89ng9fczypp3shk7edn43y5zfvdr0ftl8eq8l00zaknjqx3c9xuv7ja8ck60q456dtc" />
    <content type="html">
      📡 How to use relay.testls.bit — a Namecoin .bit-gated Nostr relay&lt;br/&gt;&lt;br/&gt;🔗 wss://relay.testls.bit/&lt;br/&gt;&lt;br/&gt;🛡️ What makes it different&lt;br/&gt;   The relay only accepts events from pubkeys whose kind:0 metadata declares&lt;br/&gt;   a .bit NIP-05 identifier (e.g. _@yourname.bit, m@testls.bit). Verification&lt;br/&gt;   is done against Namecoin directly via ElectrumX — no DNS, no public CAs.&lt;br/&gt;&lt;br/&gt;🚀 To use it as a write relay you need:&lt;br/&gt;   1. A Namecoin .bit name (d/ namespace) you control&lt;br/&gt;   2. Set the .bit value to a JSON record with a &amp;#34;nostr&amp;#34; field mapping a&lt;br/&gt;      label to your hex pubkey, e.g.&lt;br/&gt;        {&amp;#34;nostr&amp;#34;:{&amp;#34;names&amp;#34;:{&amp;#34;_&amp;#34;:&amp;#34;&amp;lt;your-hex-pubkey&amp;gt;&amp;#34;}}}&lt;br/&gt;   3. Update your kind:0 metadata so &amp;#34;nip05&amp;#34; = &amp;#34;&amp;lt;label&amp;gt;@&amp;lt;yourname&amp;gt;.bit&amp;#34;&lt;br/&gt;   4. Add wss://relay.testls.bit/ to your client&amp;#39;s relay list&lt;br/&gt;&lt;br/&gt;📱 Native client support&lt;br/&gt;   Amethyst (Android &#43; iOS &#43; Desktop) has full .bit relay resolution behind&lt;br/&gt;   PR #2595: it queries Namecoin via ElectrumX, rewrites wss://*.bit/ to the&lt;br/&gt;   underlying real wss:// host or .onion, and pins TLS via Namecoin TLSA.&lt;br/&gt;   No client-side config needed beyond adding the relay URL.&lt;br/&gt;&lt;br/&gt;   &lt;a href=&#34;https://github.com/vitorpamplona/amethyst/pull/2595&#34;&gt;https://github.com/vitorpamplona/amethyst/pull/2595&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;📡 Read-only access works for everyone&lt;br/&gt;   Even without a .bit identity you can subscribe with REQ and read the relay&lt;br/&gt;   freely. Only writes are gated.&lt;br/&gt;&lt;br/&gt;🔐 Why this matters&lt;br/&gt;   It&amp;#39;s a working demo of the cypherpunk thesis: name resolution and TLS&lt;br/&gt;   trust without ICANN, without public CAs, without DNS. Names are&lt;br/&gt;   blockchain-anchored and TLS is pinned via TLSA-on-Namecoin (DANE-TA).&lt;br/&gt;&lt;br/&gt;🌐 Browse it in your browser: &lt;a href=&#34;https://relay.testls.bit/&#34;&gt;https://relay.testls.bit/&lt;/a&gt;&lt;br/&gt;   (vanilla SPA, talks WSS back to the same host. Self-signed cert is&lt;br/&gt;   pinned via Namecoin TLSA.)&lt;br/&gt;   Go to &lt;a href=&#34;https://www.namecoin.org/download/&#34;&gt;https://www.namecoin.org/download/&lt;/a&gt; to figure out how to resolve&lt;br/&gt;   on your OS or in your browser&lt;br/&gt;&lt;br/&gt;🔧 Nuts and Bolts — what a publisher actually has to do&lt;br/&gt;&lt;br/&gt;   1. On-chain Namecoin records (one-time per identity using &amp;lt;name&amp;gt;):&lt;br/&gt;&lt;br/&gt;      • id/&amp;lt;name&amp;gt;  MUST exist with JSON like:&lt;br/&gt;          {&amp;#34;nostr&amp;#34;:{&amp;#34;pubkey&amp;#34;:&amp;#34;&amp;lt;hex-pubkey&amp;gt;&amp;#34;,&lt;br/&gt;                    &amp;#34;relays&amp;#34;:[&amp;#34;wss://relay.testls.bit/&amp;#34;, ...]}}&lt;br/&gt;        id/&amp;lt;name&amp;gt; is the canonical NIP-05 namespace; the relay verifies&lt;br/&gt;        _@&amp;lt;name&amp;gt;.bit against this record.&lt;br/&gt;&lt;br/&gt;      • d/&amp;lt;name&amp;gt;   SHOULD mirror the same &amp;#34;nostr&amp;#34; block for .bit-aware&lt;br/&gt;        clients that resolve the domain side too.&lt;br/&gt;&lt;br/&gt;   2. Nostr events to publish BEFORE your kind:1 content (every&lt;br/&gt;      identity, once per metadata change):&lt;br/&gt;&lt;br/&gt;      a. kind:0 (profile metadata) with content JSON containing&lt;br/&gt;            &amp;#34;nip05&amp;#34;: &amp;#34;_@&amp;lt;name&amp;gt;.bit&amp;#34;&lt;br/&gt;         The &amp;#34;_&amp;#34; localpart resolves to id/&amp;lt;name&amp;gt; via the NIP-05&lt;br/&gt;         default-name rule. Without this, the relay rejects writes with:&lt;br/&gt;            blocked: this relay requires a verified Namecoin .bit NIP-05&lt;br/&gt;&lt;br/&gt;      b. kind:10002 (NIP-65 relay list) listing&lt;br/&gt;            wss://relay.testls.bit/&lt;br/&gt;         as a write relay. Not strictly required for acceptance, but&lt;br/&gt;         it makes the relay discoverable in the author&amp;#39;s outbox.&lt;br/&gt;&lt;br/&gt;      Send both (a) and (b) to relay.testls.bit AND to your normal&lt;br/&gt;      public relays so verification &#43; discovery stay in sync.&lt;br/&gt;&lt;br/&gt;   3. TLS handshake (every connection):&lt;br/&gt;&lt;br/&gt;      a. Resolve the host via Namecoin:&lt;br/&gt;            name_show d/testls -&amp;gt; map.relay -&amp;gt; { ip, tls }&lt;br/&gt;         The &amp;#34;tls&amp;#34; field is one or more TLSA records of shape&lt;br/&gt;            [usage, selector, matchingType, base64-data]&lt;br/&gt;         Currently usage=2 (DANE-TA), selector=1 (SPKI),&lt;br/&gt;         matching=1 (SHA-256).&lt;br/&gt;&lt;br/&gt;      b. Open TCP/TLS to that IP with SNI = &amp;#34;relay.testls.bit&amp;#34; and&lt;br/&gt;         your own certificate validation (rejectUnauthorized=false).&lt;br/&gt;&lt;br/&gt;      c. Pin against the TLSA. IMPORTANT: neither the leaf SPKI nor&lt;br/&gt;         the intermediate SPKI hashes match — the pin is the&lt;br/&gt;         AIA Parent CA SPKI, which the Namecoin TLS scheme staples&lt;br/&gt;         as JSON inside the *issuer&amp;#39;s* serialNumber RDN:&lt;br/&gt;&lt;br/&gt;            serialNumber=Namecoin TLS Certificate&lt;br/&gt;                          \n\nStapled: {&amp;#34;pubb64&amp;#34;:&amp;#34;&amp;lt;b64url SPKI DER&amp;gt;&amp;#34;}&lt;br/&gt;&lt;br/&gt;         The cert literally encodes \&amp;#34; as backslash&#43;quote and \0A&lt;br/&gt;         as \ 0 A in that string — unescape both before JSON.parse.&lt;br/&gt;         SHA-256 of base64url-decoded pubb64 is what TLSA covers.&lt;br/&gt;&lt;br/&gt;      d. Once the pin matches, hand the validated TLS socket to your&lt;br/&gt;         WebSocket client (e.g. ws&amp;#39;s createConnection: () =&amp;gt; socket)&lt;br/&gt;         so you don&amp;#39;t trigger a second TLS handshake.&lt;br/&gt;&lt;br/&gt;   4. Operational order for a content broadcast:&lt;br/&gt;&lt;br/&gt;         a. Verify id/&amp;lt;name&amp;gt; &#43; d/&amp;lt;name&amp;gt; on chain.&lt;br/&gt;         b. Publish kind:0 (with .bit nip05) → public relays &#43; .bit relay.&lt;br/&gt;         c. Publish kind:10002 (with .bit relay) → public relays &#43; .bit relay.&lt;br/&gt;         d. Publish kind:1 (your content) → public relays &#43; .bit relay.&lt;br/&gt;&lt;br/&gt;   5. Common failure modes:&lt;br/&gt;&lt;br/&gt;      • &amp;#34;tls: TLSA pin mismatch&amp;#34;&lt;br/&gt;          You&amp;#39;re hashing the leaf or chain SPKI. Use the stapled&lt;br/&gt;          AIA Parent CA SPKI from the issuer&amp;#39;s serialNumber RDN.&lt;br/&gt;&lt;br/&gt;      • &amp;#34;blocked: this relay requires a verified Namecoin .bit NIP-05&amp;#34;&lt;br/&gt;          Latest kind:0 doesn&amp;#39;t carry a .bit nip05, OR id/&amp;lt;name&amp;gt;&lt;br/&gt;          on-chain doesn&amp;#39;t list this pubkey.&lt;br/&gt;&lt;br/&gt;      • TLSA pin mismatch after a server cert rotation&lt;br/&gt;          The on-chain &amp;#34;tls&amp;#34; array under d/&amp;lt;base&amp;gt;/map/&amp;lt;sub&amp;gt; needs an&lt;br/&gt;          update — the AIA Parent CA pubkey is the trust anchor.&lt;br/&gt;&lt;br/&gt;   Reference implementation:&lt;br/&gt;   &lt;a href=&#34;https://github.com/mstrofnone/nmcLightningService&#34;&gt;https://github.com/mstrofnone/nmcLightningService&lt;/a&gt; (publish-announce-bit.js)&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;#namecoin #nostr #cypherpunk #dotbit&lt;br/&gt;
    </content>
    <updated>2026-05-01T02:27:11Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsyvzqln4laqpxr9jmlq8su860s8kj5a4fdcsqp73fgrwnypwdzmkszypp3shk7edn43y5zfvdr0ftl8eq8l00zaknjqx3c9xuv7ja8ck60q889eys</id>
    
      <title type="html">📡 How to use relay.testls.bit — a Namecoin .bit-gated Nostr ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsyvzqln4laqpxr9jmlq8su860s8kj5a4fdcsqp73fgrwnypwdzmkszypp3shk7edn43y5zfvdr0ftl8eq8l00zaknjqx3c9xuv7ja8ck60q889eys" />
    <content type="html">
      📡 How to use relay.testls.bit — a Namecoin .bit-gated Nostr relay&lt;br/&gt;&lt;br/&gt;🔗 wss://relay.testls.bit/&lt;br/&gt;&lt;br/&gt;🛡️ What makes it different&lt;br/&gt;   The relay only accepts events from pubkeys whose kind:0 metadata declares&lt;br/&gt;   a .bit NIP-05 identifier (e.g. _@yourname.bit, m@testls.bit). Verification&lt;br/&gt;   is done against Namecoin directly via ElectrumX — no DNS, no public CAs.&lt;br/&gt;&lt;br/&gt;🚀 To use it as a write relay you need:&lt;br/&gt;   1. A Namecoin .bit name (d/ namespace) you control&lt;br/&gt;   2. Set the .bit value to a JSON record with a &amp;#34;nostr&amp;#34; field mapping a&lt;br/&gt;      label to your hex pubkey, e.g.&lt;br/&gt;        {&amp;#34;nostr&amp;#34;:{&amp;#34;names&amp;#34;:{&amp;#34;_&amp;#34;:&amp;#34;&amp;lt;your-hex-pubkey&amp;gt;&amp;#34;}}}&lt;br/&gt;   3. Update your kind:0 metadata so &amp;#34;nip05&amp;#34; = &amp;#34;&amp;lt;label&amp;gt;@&amp;lt;yourname&amp;gt;.bit&amp;#34;&lt;br/&gt;   4. Add wss://relay.testls.bit/ to your client&amp;#39;s relay list&lt;br/&gt;&lt;br/&gt;📱 Native client support&lt;br/&gt;   Amethyst (Android &#43; iOS &#43; Desktop) has full .bit relay resolution behind&lt;br/&gt;   PR #2595: it queries Namecoin via ElectrumX, rewrites wss://*.bit/ to the&lt;br/&gt;   underlying real wss:// host or .onion, and pins TLS via Namecoin TLSA.&lt;br/&gt;   No client-side config needed beyond adding the relay URL.&lt;br/&gt;&lt;br/&gt;   &lt;a href=&#34;https://github.com/vitorpamplona/amethyst/pull/2595&#34;&gt;https://github.com/vitorpamplona/amethyst/pull/2595&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;📡 Read-only access works for everyone&lt;br/&gt;   Even without a .bit identity you can subscribe with REQ and read the relay&lt;br/&gt;   freely. Only writes are gated.&lt;br/&gt;&lt;br/&gt;🔐 Why this matters&lt;br/&gt;   It&amp;#39;s a working demo of the cypherpunk thesis: name resolution and TLS&lt;br/&gt;   trust without ICANN, without public CAs, without DNS. Names are&lt;br/&gt;   blockchain-anchored and TLS is pinned via TLSA-on-Namecoin (DANE-TA).&lt;br/&gt;&lt;br/&gt;🌐 Browse it in your browser: &lt;a href=&#34;https://relay.testls.bit/&#34;&gt;https://relay.testls.bit/&lt;/a&gt;&lt;br/&gt;   (vanilla SPA, talks WSS back to the same host. Self-signed cert is&lt;br/&gt;   pinned via Namecoin TLSA.)&lt;br/&gt;   Go to &lt;a href=&#34;https://www.namecoin.org/download/&#34;&gt;https://www.namecoin.org/download/&lt;/a&gt; to figure out how to resolve&lt;br/&gt;   on your OS or in your browser&lt;br/&gt;&lt;br/&gt;🔧 Nuts and Bolts — what a publisher actually has to do&lt;br/&gt;&lt;br/&gt;   1. On-chain Namecoin records (one-time per identity using &amp;lt;name&amp;gt;):&lt;br/&gt;&lt;br/&gt;      • id/&amp;lt;name&amp;gt;  MUST exist with JSON like:&lt;br/&gt;          {&amp;#34;nostr&amp;#34;:{&amp;#34;pubkey&amp;#34;:&amp;#34;&amp;lt;hex-pubkey&amp;gt;&amp;#34;,&lt;br/&gt;                    &amp;#34;relays&amp;#34;:[&amp;#34;wss://relay.testls.bit/&amp;#34;, ...]}}&lt;br/&gt;        id/&amp;lt;name&amp;gt; is the canonical NIP-05 namespace; the relay verifies&lt;br/&gt;        _@&amp;lt;name&amp;gt;.bit against this record.&lt;br/&gt;&lt;br/&gt;      • d/&amp;lt;name&amp;gt;   SHOULD mirror the same &amp;#34;nostr&amp;#34; block for .bit-aware&lt;br/&gt;        clients that resolve the domain side too.&lt;br/&gt;&lt;br/&gt;   2. Nostr events to publish BEFORE your kind:1 content (every&lt;br/&gt;      identity, once per metadata change):&lt;br/&gt;&lt;br/&gt;      a. kind:0 (profile metadata) with content JSON containing&lt;br/&gt;            &amp;#34;nip05&amp;#34;: &amp;#34;_@&amp;lt;name&amp;gt;.bit&amp;#34;&lt;br/&gt;         The &amp;#34;_&amp;#34; localpart resolves to id/&amp;lt;name&amp;gt; via the NIP-05&lt;br/&gt;         default-name rule. Without this, the relay rejects writes with:&lt;br/&gt;            blocked: this relay requires a verified Namecoin .bit NIP-05&lt;br/&gt;&lt;br/&gt;      b. kind:10002 (NIP-65 relay list) listing&lt;br/&gt;            wss://relay.testls.bit/&lt;br/&gt;         as a write relay. Not strictly required for acceptance, but&lt;br/&gt;         it makes the relay discoverable in the author&amp;#39;s outbox.&lt;br/&gt;&lt;br/&gt;      Send both (a) and (b) to relay.testls.bit AND to your normal&lt;br/&gt;      public relays so verification &#43; discovery stay in sync.&lt;br/&gt;&lt;br/&gt;   3. TLS handshake (every connection):&lt;br/&gt;&lt;br/&gt;      a. Resolve the host via Namecoin:&lt;br/&gt;            name_show d/testls -&amp;gt; map.relay -&amp;gt; { ip, tls }&lt;br/&gt;         The &amp;#34;tls&amp;#34; field is one or more TLSA records of shape&lt;br/&gt;            [usage, selector, matchingType, base64-data]&lt;br/&gt;         Currently usage=2 (DANE-TA), selector=1 (SPKI),&lt;br/&gt;         matching=1 (SHA-256).&lt;br/&gt;&lt;br/&gt;      b. Open TCP/TLS to that IP with SNI = &amp;#34;relay.testls.bit&amp;#34; and&lt;br/&gt;         your own certificate validation (rejectUnauthorized=false).&lt;br/&gt;&lt;br/&gt;      c. Pin against the TLSA. IMPORTANT: neither the leaf SPKI nor&lt;br/&gt;         the intermediate SPKI hashes match — the pin is the&lt;br/&gt;         AIA Parent CA SPKI, which the Namecoin TLS scheme staples&lt;br/&gt;         as JSON inside the *issuer&amp;#39;s* serialNumber RDN:&lt;br/&gt;&lt;br/&gt;            serialNumber=Namecoin TLS Certificate&lt;br/&gt;                          \n\nStapled: {&amp;#34;pubb64&amp;#34;:&amp;#34;&amp;lt;b64url SPKI DER&amp;gt;&amp;#34;}&lt;br/&gt;&lt;br/&gt;         The cert literally encodes \&amp;#34; as backslash&#43;quote and \0A&lt;br/&gt;         as \ 0 A in that string — unescape both before JSON.parse.&lt;br/&gt;         SHA-256 of base64url-decoded pubb64 is what TLSA covers.&lt;br/&gt;&lt;br/&gt;      d. Once the pin matches, hand the validated TLS socket to your&lt;br/&gt;         WebSocket client (e.g. ws&amp;#39;s createConnection: () =&amp;gt; socket)&lt;br/&gt;         so you don&amp;#39;t trigger a second TLS handshake.&lt;br/&gt;&lt;br/&gt;   4. Operational order for a content broadcast:&lt;br/&gt;&lt;br/&gt;         a. Verify id/&amp;lt;name&amp;gt; &#43; d/&amp;lt;name&amp;gt; on chain.&lt;br/&gt;         b. Publish kind:0 (with .bit nip05) → public relays &#43; .bit relay.&lt;br/&gt;         c. Publish kind:10002 (with .bit relay) → public relays &#43; .bit relay.&lt;br/&gt;         d. Publish kind:1 (your content) → public relays &#43; .bit relay.&lt;br/&gt;&lt;br/&gt;   5. Common failure modes:&lt;br/&gt;&lt;br/&gt;      • &amp;#34;tls: TLSA pin mismatch&amp;#34;&lt;br/&gt;          You&amp;#39;re hashing the leaf or chain SPKI. Use the stapled&lt;br/&gt;          AIA Parent CA SPKI from the issuer&amp;#39;s serialNumber RDN.&lt;br/&gt;&lt;br/&gt;      • &amp;#34;blocked: this relay requires a verified Namecoin .bit NIP-05&amp;#34;&lt;br/&gt;          Latest kind:0 doesn&amp;#39;t carry a .bit nip05, OR id/&amp;lt;name&amp;gt;&lt;br/&gt;          on-chain doesn&amp;#39;t list this pubkey.&lt;br/&gt;&lt;br/&gt;      • TLSA pin mismatch after a server cert rotation&lt;br/&gt;          The on-chain &amp;#34;tls&amp;#34; array under d/&amp;lt;base&amp;gt;/map/&amp;lt;sub&amp;gt; needs an&lt;br/&gt;          update — the AIA Parent CA pubkey is the trust anchor.&lt;br/&gt;&lt;br/&gt;   Reference implementation:&lt;br/&gt;   &lt;a href=&#34;https://github.com/mstrofnone/nmcLightningService&#34;&gt;https://github.com/mstrofnone/nmcLightningService&lt;/a&gt; (publish-announce-bit.js)&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;#namecoin #nostr #cypherpunk #dotbit&lt;br/&gt;
    </content>
    <updated>2026-05-01T02:26:35Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqs04hahmghvsvq0lrq5uq5qjngm7etf07lhsp7r56hz7lth7j6n7lgzypp3shk7edn43y5zfvdr0ftl8eq8l00zaknjqx3c9xuv7ja8ck60qzly0dv</id>
    
      <title type="html">A free-software Namecoin explorer is now live for nostriches to ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqs04hahmghvsvq0lrq5uq5qjngm7etf07lhsp7r56hz7lth7j6n7lgzypp3shk7edn43y5zfvdr0ftl8eq8l00zaknjqx3c9xuv7ja8ck60qzly0dv" />
    <content type="html">
      A free-software Namecoin explorer is now live for nostriches to explore. No public CA, just a Namecoin Core node, your Tor client, and the&lt;br/&gt;chain.&lt;br/&gt;&lt;br/&gt;  Tor:      &lt;a href=&#34;http://6cbn4rskfdr647otej7gpqlmpqcmj723vg2eoeuu7ljbwu6cpdebozyd.onion:8080/&#34;&gt;http://6cbn4rskfdr647otej7gpqlmpqcmj723vg2eoeuu7ljbwu6cpdebozyd.onion:8080/&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;What&amp;#39;s there:&lt;br/&gt;&lt;br/&gt;- Full name-op aware mempool view: every name_new, name_firstupdate,&lt;br/&gt;  and name_update queued for the next block, bucketed by op kind.&lt;br/&gt;  &lt;a href=&#34;http://...onion:8080/mempool-name-ops&#34;&gt;http://...onion:8080/mempool-name-ops&lt;/a&gt;&lt;br/&gt;- Detection of ifa-0001 §&amp;#34;import&amp;#34; references between names, rendered&lt;br/&gt;  as clickable links — so you can walk a record&amp;#39;s import graph&lt;br/&gt;  without leaving the explorer.&lt;br/&gt;- d/&amp;lt;name&amp;gt; and id/&amp;lt;name&amp;gt; records Nostr blocks linked to NIP-19 npubs&lt;br/&gt;  (with njump.me deeplinks), the implied &amp;lt;localPart&amp;gt;@&amp;lt;host&amp;gt;.bit&lt;br/&gt;  NIP-05 identifier, and the publisher&amp;#39;s preferred relays.&lt;br/&gt;- Merge-mining-aware mining-summary: scans the parent Bitcoin&lt;br/&gt;  coinbase tag carried inside the auxpow blob (auxpow.tx.vin[0].coinbase),&lt;br/&gt;  so you actually see WHO mined the last 30 days of Namecoin — not&lt;br/&gt;  just &amp;#34;Unknown&amp;#34; the way most NMC explorers render it.&lt;br/&gt;&lt;br/&gt;Top NMC mining pools, last 30 days (4,321 blocks, snapshot at&lt;br/&gt;height 822,734 — refresh before posting if more than ~12 hours&lt;br/&gt;old):&lt;br/&gt;&lt;br/&gt;  1. AntPool         1347 blocks  (31.17%)&lt;br/&gt;  2. F2Pool           891 blocks  (20.62%)&lt;br/&gt;  3. ViaBTC           713 blocks  (16.50%)&lt;br/&gt;  4. SpiderPool       291 blocks  ( 6.73%)&lt;br/&gt;  5. SecPool          259 blocks  ( 5.99%)&lt;br/&gt;  6. Luxor            253 blocks  ( 5.86%)&lt;br/&gt;  7. Binance Pool     181 blocks  ( 4.19%)&lt;br/&gt;  8. Braiins Pool     108 blocks  ( 2.50%)&lt;br/&gt;  9. Ultimus Pool      35 blocks  ( 0.81%)&lt;br/&gt; 10. CloverPool        26 blocks  ( 0.60%)&lt;br/&gt;&lt;br/&gt;AntPool &#43; F2Pool &#43; ViaBTC alone mined 68% of all Namecoin blocks in&lt;br/&gt;the last 30 days.&lt;br/&gt;&lt;br/&gt;  See the full breakdown:&lt;br/&gt;  &lt;a href=&#34;http://6cbn4rskfdr647otej7gpqlmpqcmj723vg2eoeuu7ljbwu6cpdebozyd.onion:8080/mining-summary&#34;&gt;http://6cbn4rskfdr647otej7gpqlmpqcmj723vg2eoeuu7ljbwu6cpdebozyd.onion:8080/mining-summary&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;Source: &lt;a href=&#34;https://github.com/mstrofnone/nmc-rpc-explorer&#34;&gt;https://github.com/mstrofnone/nmc-rpc-explorer&lt;/a&gt; (master)&lt;br/&gt;Upstream PR queue: namecoin/nmc-rpc-explorer #13–#18&lt;br/&gt;&lt;br/&gt;#namecoin #nostr #cypherpunk #mergemining #bitcoin #miner
    </content>
    <updated>2026-05-01T01:43:18Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsf8st6dlaa73kh3zztg3kmfd6r5ua7fv8rxnxrclcdd4n4jpxcq5gzypp3shk7edn43y5zfvdr0ftl8eq8l00zaknjqx3c9xuv7ja8ck60qdvcd47</id>
    
      <title type="html">A free-software Namecoin explorer is now live for nostriches to ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsf8st6dlaa73kh3zztg3kmfd6r5ua7fv8rxnxrclcdd4n4jpxcq5gzypp3shk7edn43y5zfvdr0ftl8eq8l00zaknjqx3c9xuv7ja8ck60qdvcd47" />
    <content type="html">
      A free-software Namecoin explorer is now live for nostriches to explore. No public CA, just a Namecoin Core node, your Tor client, and the&lt;br/&gt;chain.&lt;br/&gt;&lt;br/&gt;  Tor:      &lt;a href=&#34;http://6cbn4rskfdr647otej7gpqlmpqcmj723vg2eoeuu7ljbwu6cpdebozyd.onion:8080/&#34;&gt;http://6cbn4rskfdr647otej7gpqlmpqcmj723vg2eoeuu7ljbwu6cpdebozyd.onion:8080/&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;What&amp;#39;s there:&lt;br/&gt;&lt;br/&gt;- Full name-op aware mempool view: every name_new, name_firstupdate,&lt;br/&gt;  and name_update queued for the next block, bucketed by op kind.&lt;br/&gt;  &lt;a href=&#34;http://...onion:8080/mempool-name-ops&#34;&gt;http://...onion:8080/mempool-name-ops&lt;/a&gt;&lt;br/&gt;- Detection of ifa-0001 §&amp;#34;import&amp;#34; references between names, rendered&lt;br/&gt;  as clickable links — so you can walk a record&amp;#39;s import graph&lt;br/&gt;  without leaving the explorer.&lt;br/&gt;- d/&amp;lt;name&amp;gt; and id/&amp;lt;name&amp;gt; records Nostr blocks linked to NIP-19 npubs&lt;br/&gt;  (with njump.me deeplinks), the implied &amp;lt;localPart&amp;gt;@&amp;lt;host&amp;gt;.bit&lt;br/&gt;  NIP-05 identifier, and the publisher&amp;#39;s preferred relays.&lt;br/&gt;- Merge-mining-aware mining-summary: scans the parent Bitcoin&lt;br/&gt;  coinbase tag carried inside the auxpow blob (auxpow.tx.vin[0].coinbase),&lt;br/&gt;  so you actually see WHO mined the last 30 days of Namecoin — not&lt;br/&gt;  just &amp;#34;Unknown&amp;#34; the way most NMC explorers render it.&lt;br/&gt;&lt;br/&gt;Top NMC mining pools, last 30 days (4,321 blocks, snapshot at&lt;br/&gt;height 822,734 — refresh before posting if more than ~12 hours&lt;br/&gt;old):&lt;br/&gt;&lt;br/&gt;  1. AntPool         1347 blocks  (31.17%)&lt;br/&gt;  2. F2Pool           891 blocks  (20.62%)&lt;br/&gt;  3. ViaBTC           713 blocks  (16.50%)&lt;br/&gt;  4. SpiderPool       291 blocks  ( 6.73%)&lt;br/&gt;  5. SecPool          259 blocks  ( 5.99%)&lt;br/&gt;  6. Luxor            253 blocks  ( 5.86%)&lt;br/&gt;  7. Binance Pool     181 blocks  ( 4.19%)&lt;br/&gt;  8. Braiins Pool     108 blocks  ( 2.50%)&lt;br/&gt;  9. Ultimus Pool      35 blocks  ( 0.81%)&lt;br/&gt; 10. CloverPool        26 blocks  ( 0.60%)&lt;br/&gt;&lt;br/&gt;AntPool &#43; F2Pool &#43; ViaBTC alone mined 68% of all Namecoin blocks in&lt;br/&gt;the last 30 days.&lt;br/&gt;&lt;br/&gt;  See the full breakdown:&lt;br/&gt;  &lt;a href=&#34;http://6cbn4rskfdr647otej7gpqlmpqcmj723vg2eoeuu7ljbwu6cpdebozyd.onion:8080/mining-summary&#34;&gt;http://6cbn4rskfdr647otej7gpqlmpqcmj723vg2eoeuu7ljbwu6cpdebozyd.onion:8080/mining-summary&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;Source: &lt;a href=&#34;https://github.com/mstrofnone/nmc-rpc-explorer&#34;&gt;https://github.com/mstrofnone/nmc-rpc-explorer&lt;/a&gt; (master)&lt;br/&gt;Upstream PR queue: namecoin/nmc-rpc-explorer #13–#18&lt;br/&gt;&lt;br/&gt;#namecoin #nostr #cypherpunk #mergemining #bitcoin #miner
    </content>
    <updated>2026-05-01T01:41:40Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsfrveralw7ppuxjanucl9jj3n2rs9v003s2nmvx49rftndsasxlmqzypp3shk7edn43y5zfvdr0ftl8eq8l00zaknjqx3c9xuv7ja8ck60qnglzda</id>
    
      <title type="html">A free-software Namecoin explorer is now live for nostriches to ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsfrveralw7ppuxjanucl9jj3n2rs9v003s2nmvx49rftndsasxlmqzypp3shk7edn43y5zfvdr0ftl8eq8l00zaknjqx3c9xuv7ja8ck60qnglzda" />
    <content type="html">
      A free-software Namecoin explorer is now live for nostriches to explore. No public CA, just a Namecoin Core node, your Tor client, and the&lt;br/&gt;chain.&lt;br/&gt;&lt;br/&gt;  Tor:      &lt;a href=&#34;http://6cbn4rskfdr647otej7gpqlmpqcmj723vg2eoeuu7ljbwu6cpdebozyd.onion:8080/&#34;&gt;http://6cbn4rskfdr647otej7gpqlmpqcmj723vg2eoeuu7ljbwu6cpdebozyd.onion:8080/&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;What&amp;#39;s there:&lt;br/&gt;&lt;br/&gt;- Full name-op aware mempool view: every name_new, name_firstupdate,&lt;br/&gt;  and name_update queued for the next block, bucketed by op kind.&lt;br/&gt;  &lt;a href=&#34;http://...onion:8080/mempool-name-ops&#34;&gt;http://...onion:8080/mempool-name-ops&lt;/a&gt;&lt;br/&gt;- Detection of ifa-0001 §&amp;#34;import&amp;#34; references between names, rendered&lt;br/&gt;  as clickable links — so you can walk a record&amp;#39;s import graph&lt;br/&gt;  without leaving the explorer.&lt;br/&gt;- d/&amp;lt;name&amp;gt; and id/&amp;lt;name&amp;gt; records Nostr blocks linked to NIP-19 npubs&lt;br/&gt;  (with njump.me deeplinks), the implied &amp;lt;localPart&amp;gt;@&amp;lt;host&amp;gt;.bit&lt;br/&gt;  NIP-05 identifier, and the publisher&amp;#39;s preferred relays.&lt;br/&gt;- Merge-mining-aware mining-summary: scans the parent Bitcoin&lt;br/&gt;  coinbase tag carried inside the auxpow blob (auxpow.tx.vin[0].coinbase),&lt;br/&gt;  so you actually see WHO mined the last 30 days of Namecoin — not&lt;br/&gt;  just &amp;#34;Unknown&amp;#34; the way most NMC explorers render it.&lt;br/&gt;&lt;br/&gt;Top NMC mining pools, last 30 days (4,321 blocks, snapshot at&lt;br/&gt;height 822,734 — refresh before posting if more than ~12 hours&lt;br/&gt;old):&lt;br/&gt;&lt;br/&gt;  1. AntPool         1347 blocks  (31.17%)&lt;br/&gt;  2. F2Pool           891 blocks  (20.62%)&lt;br/&gt;  3. ViaBTC           713 blocks  (16.50%)&lt;br/&gt;  4. SpiderPool       291 blocks  ( 6.73%)&lt;br/&gt;  5. SecPool          259 blocks  ( 5.99%)&lt;br/&gt;  6. Luxor            253 blocks  ( 5.86%)&lt;br/&gt;  7. Binance Pool     181 blocks  ( 4.19%)&lt;br/&gt;  8. Braiins Pool     108 blocks  ( 2.50%)&lt;br/&gt;  9. Ultimus Pool      35 blocks  ( 0.81%)&lt;br/&gt; 10. CloverPool        26 blocks  ( 0.60%)&lt;br/&gt;&lt;br/&gt;AntPool &#43; F2Pool &#43; ViaBTC alone mined 68% of all Namecoin blocks in&lt;br/&gt;the last 30 days.&lt;br/&gt;&lt;br/&gt;  See the full breakdown:&lt;br/&gt;  &lt;a href=&#34;http://6cbn4rskfdr647otej7gpqlmpqcmj723vg2eoeuu7ljbwu6cpdebozyd.onion:8080/mining-summary&#34;&gt;http://6cbn4rskfdr647otej7gpqlmpqcmj723vg2eoeuu7ljbwu6cpdebozyd.onion:8080/mining-summary&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;Source: &lt;a href=&#34;https://github.com/mstrofnone/nmc-rpc-explorer&#34;&gt;https://github.com/mstrofnone/nmc-rpc-explorer&lt;/a&gt; (master)&lt;br/&gt;Upstream PR queue: namecoin/nmc-rpc-explorer #13–#18&lt;br/&gt;&lt;br/&gt;#namecoin #nostr #cypherpunk #mergemining #bitcoin #miner
    </content>
    <updated>2026-05-01T01:41:04Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsy5ak6rxe2fzp4p8lp2zul3mjtkwa7ewz3dy6akfxwe4jfw9vtuwszypp3shk7edn43y5zfvdr0ftl8eq8l00zaknjqx3c9xuv7ja8ck60qfzc225</id>
    
      <title type="html">A free-software Namecoin explorer is now live for nostriches to ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsy5ak6rxe2fzp4p8lp2zul3mjtkwa7ewz3dy6akfxwe4jfw9vtuwszypp3shk7edn43y5zfvdr0ftl8eq8l00zaknjqx3c9xuv7ja8ck60qfzc225" />
    <content type="html">
      A free-software Namecoin explorer is now live for nostriches to explore. No public CA, just a Namecoin Core node, your Tor client, and the&lt;br/&gt;chain.&lt;br/&gt;&lt;br/&gt;  Tor:      &lt;a href=&#34;http://6cbn4rskfdr647otej7gpqlmpqcmj723vg2eoeuu7ljbwu6cpdebozyd.onion:8080/&#34;&gt;http://6cbn4rskfdr647otej7gpqlmpqcmj723vg2eoeuu7ljbwu6cpdebozyd.onion:8080/&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;What&amp;#39;s there:&lt;br/&gt;&lt;br/&gt;- Full name-op aware mempool view: every name_new, name_firstupdate,&lt;br/&gt;  and name_update queued for the next block, bucketed by op kind.&lt;br/&gt;  &lt;a href=&#34;http://...onion:8080/mempool-name-ops&#34;&gt;http://...onion:8080/mempool-name-ops&lt;/a&gt;&lt;br/&gt;- Detection of ifa-0001 §&amp;#34;import&amp;#34; references between names, rendered&lt;br/&gt;  as clickable links — so you can walk a record&amp;#39;s import graph&lt;br/&gt;  without leaving the explorer.&lt;br/&gt;- d/&amp;lt;name&amp;gt; and id/&amp;lt;name&amp;gt; records Nostr blocks linked to NIP-19 npubs&lt;br/&gt;  (with njump.me deeplinks), the implied &amp;lt;localPart&amp;gt;@&amp;lt;host&amp;gt;.bit&lt;br/&gt;  NIP-05 identifier, and the publisher&amp;#39;s preferred relays.&lt;br/&gt;- Merge-mining-aware mining-summary: scans the parent Bitcoin&lt;br/&gt;  coinbase tag carried inside the auxpow blob (auxpow.tx.vin[0].coinbase),&lt;br/&gt;  so you actually see WHO mined the last 30 days of Namecoin — not&lt;br/&gt;  just &amp;#34;Unknown&amp;#34; the way most NMC explorers render it.&lt;br/&gt;&lt;br/&gt;Top NMC mining pools, last 30 days (4,321 blocks, snapshot at&lt;br/&gt;height 822,734 — refresh before posting if more than ~12 hours&lt;br/&gt;old):&lt;br/&gt;&lt;br/&gt;  1. AntPool         1347 blocks  (31.17%)&lt;br/&gt;  2. F2Pool           891 blocks  (20.62%)&lt;br/&gt;  3. ViaBTC           713 blocks  (16.50%)&lt;br/&gt;  4. SpiderPool       291 blocks  ( 6.73%)&lt;br/&gt;  5. SecPool          259 blocks  ( 5.99%)&lt;br/&gt;  6. Luxor            253 blocks  ( 5.86%)&lt;br/&gt;  7. Binance Pool     181 blocks  ( 4.19%)&lt;br/&gt;  8. Braiins Pool     108 blocks  ( 2.50%)&lt;br/&gt;  9. Ultimus Pool      35 blocks  ( 0.81%)&lt;br/&gt; 10. CloverPool        26 blocks  ( 0.60%)&lt;br/&gt;&lt;br/&gt;AntPool &#43; F2Pool &#43; ViaBTC alone mined 68% of all Namecoin blocks in&lt;br/&gt;the last 30 days.&lt;br/&gt;&lt;br/&gt;  See the full breakdown:&lt;br/&gt;  &lt;a href=&#34;http://6cbn4rskfdr647otej7gpqlmpqcmj723vg2eoeuu7ljbwu6cpdebozyd.onion:8080/mining-summary&#34;&gt;http://6cbn4rskfdr647otej7gpqlmpqcmj723vg2eoeuu7ljbwu6cpdebozyd.onion:8080/mining-summary&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;Source: &lt;a href=&#34;https://github.com/mstrofnone/nmc-rpc-explorer&#34;&gt;https://github.com/mstrofnone/nmc-rpc-explorer&lt;/a&gt; (master)&lt;br/&gt;Upstream PR queue: namecoin/nmc-rpc-explorer #13–#18&lt;br/&gt;&lt;br/&gt;#namecoin #nostr #cypherpunk #mergemining #bitcoin #miner
    </content>
    <updated>2026-05-01T01:39:08Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsgmd0xvrz8c72x3emq85stxk8qh80qyrzq00c7v85enz6exes2zfgzypp3shk7edn43y5zfvdr0ftl8eq8l00zaknjqx3c9xuv7ja8ck60qeq23tf</id>
    
      <title type="html">📡 How to use relay.testls.bit — a Namecoin .bit-gated Nostr ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsgmd0xvrz8c72x3emq85stxk8qh80qyrzq00c7v85enz6exes2zfgzypp3shk7edn43y5zfvdr0ftl8eq8l00zaknjqx3c9xuv7ja8ck60qeq23tf" />
    <content type="html">
      📡 How to use relay.testls.bit — a Namecoin .bit-gated Nostr relay&lt;br/&gt;&lt;br/&gt;🔗 wss://relay.testls.bit/&lt;br/&gt;&lt;br/&gt;🛡️ What makes it different&lt;br/&gt;   The relay only accepts events from pubkeys whose kind:0 metadata declares&lt;br/&gt;   a .bit NIP-05 identifier (e.g. _@yourname.bit, m@testls.bit). Verification&lt;br/&gt;   is done against Namecoin directly via ElectrumX — no DNS, no public CAs.&lt;br/&gt;&lt;br/&gt;🚀 To use it as a write relay you need:&lt;br/&gt;   1. A Namecoin .bit name (d/ namespace) you control&lt;br/&gt;   2. Set the .bit value to a JSON record with a &amp;#34;nostr&amp;#34; field mapping a&lt;br/&gt;      label to your hex pubkey, e.g.&lt;br/&gt;        {&amp;#34;nostr&amp;#34;:{&amp;#34;names&amp;#34;:{&amp;#34;_&amp;#34;:&amp;#34;&amp;lt;your-hex-pubkey&amp;gt;&amp;#34;}}}&lt;br/&gt;   3. Update your kind:0 metadata so &amp;#34;nip05&amp;#34; = &amp;#34;&amp;lt;label&amp;gt;@&amp;lt;yourname&amp;gt;.bit&amp;#34;&lt;br/&gt;   4. Add wss://relay.testls.bit/ to your client&amp;#39;s relay list&lt;br/&gt;&lt;br/&gt;📱 Native client support&lt;br/&gt;   Amethyst (Android &#43; iOS &#43; Desktop) has full .bit relay resolution behind&lt;br/&gt;   PR #2595: it queries Namecoin via ElectrumX, rewrites wss://*.bit/ to the&lt;br/&gt;   underlying real wss:// host or .onion, and pins TLS via Namecoin TLSA.&lt;br/&gt;   No client-side config needed beyond adding the relay URL.&lt;br/&gt;&lt;br/&gt;   &lt;a href=&#34;https://github.com/vitorpamplona/amethyst/pull/2595&#34;&gt;https://github.com/vitorpamplona/amethyst/pull/2595&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;📡 Read-only access works for everyone&lt;br/&gt;   Even without a .bit identity you can subscribe with REQ and read the relay&lt;br/&gt;   freely. Only writes are gated.&lt;br/&gt;&lt;br/&gt;🔐 Why this matters&lt;br/&gt;   It&amp;#39;s a working demo of the cypherpunk thesis: name resolution and TLS&lt;br/&gt;   trust without ICANN, without public CAs, without DNS. Names are&lt;br/&gt;   blockchain-anchored and TLS is pinned via TLSA-on-Namecoin (DANE-TA).&lt;br/&gt;&lt;br/&gt;🌐 Browse it in your browser: &lt;a href=&#34;https://relay.testls.bit/&#34;&gt;https://relay.testls.bit/&lt;/a&gt;&lt;br/&gt;   (vanilla SPA, talks WSS back to the same host. Self-signed cert is&lt;br/&gt;   pinned via Namecoin TLSA.)&lt;br/&gt;   Go to &lt;a href=&#34;https://www.namecoin.org/download/&#34;&gt;https://www.namecoin.org/download/&lt;/a&gt; to figure out how to resolve&lt;br/&gt;   on your OS or in your browser&lt;br/&gt;&lt;br/&gt;#namecoin #nostr #cypherpunk #dotbit&lt;br/&gt;
    </content>
    <updated>2026-04-28T21:31:00Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqswhp3etm6u9x4xc3jd3tv52q5nl8whzxqs0rf3mkj20watan0c2wqzypp3shk7edn43y5zfvdr0ftl8eq8l00zaknjqx3c9xuv7ja8ck60qlc58l9</id>
    
      <title type="html">📡 How to use relay.testls.bit — a Namecoin .bit-gated Nostr ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqswhp3etm6u9x4xc3jd3tv52q5nl8whzxqs0rf3mkj20watan0c2wqzypp3shk7edn43y5zfvdr0ftl8eq8l00zaknjqx3c9xuv7ja8ck60qlc58l9" />
    <content type="html">
      📡 How to use relay.testls.bit — a Namecoin .bit-gated Nostr relay&lt;br/&gt;&lt;br/&gt;🔗 wss://relay.testls.bit/&lt;br/&gt;&lt;br/&gt;🌐 Browse it in your browser: &lt;a href=&#34;https://relay.testls.bit/&#34;&gt;https://relay.testls.bit/&lt;/a&gt;&lt;br/&gt;   (vanilla SPA, talks WSS back to the same host. Self-signed cert — first&lt;br/&gt;   visit shows a warning. Click through; the cert is pinned via Namecoin TLSA.)&lt;br/&gt;&lt;br/&gt;🛡️ What makes it different&lt;br/&gt;   The relay only accepts events from pubkeys whose kind:0 metadata declares&lt;br/&gt;   a .bit NIP-05 identifier (e.g. _@yourname.bit, m@testls.bit). Verification&lt;br/&gt;   is done against Namecoin directly via ElectrumX — no DNS, no public CAs.&lt;br/&gt;&lt;br/&gt;🚀 To use it as a write relay you need:&lt;br/&gt;   1. A Namecoin .bit name (d/ namespace) you control&lt;br/&gt;   2. Set the .bit value to a JSON record with a &amp;#34;nostr&amp;#34; field mapping a&lt;br/&gt;      label to your hex pubkey, e.g.&lt;br/&gt;        {&amp;#34;nostr&amp;#34;:{&amp;#34;names&amp;#34;:{&amp;#34;_&amp;#34;:&amp;#34;&amp;lt;your-hex-pubkey&amp;gt;&amp;#34;}}}&lt;br/&gt;   3. Update your kind:0 metadata so &amp;#34;nip05&amp;#34; = &amp;#34;&amp;lt;label&amp;gt;@&amp;lt;yourname&amp;gt;.bit&amp;#34;&lt;br/&gt;   4. Add wss://relay.testls.bit/ to your client&amp;#39;s relay list&lt;br/&gt;&lt;br/&gt;📱 Native client support&lt;br/&gt;   Amethyst (Android &#43; iOS &#43; Desktop) has full .bit relay resolution behind&lt;br/&gt;   PR #2595: it queries Namecoin via ElectrumX, rewrites wss://*.bit/ to the&lt;br/&gt;   underlying real wss:// host or .onion, and pins TLS via Namecoin TLSA.&lt;br/&gt;   No client-side config needed beyond adding the relay URL.&lt;br/&gt;&lt;br/&gt;   &lt;a href=&#34;https://github.com/vitorpamplona/amethyst/pull/2595&#34;&gt;https://github.com/vitorpamplona/amethyst/pull/2595&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;📡 Read-only access works for everyone&lt;br/&gt;   Even without a .bit identity you can subscribe with REQ and read the relay&lt;br/&gt;   freely. Only writes are gated.&lt;br/&gt;&lt;br/&gt;🔐 Why this matters&lt;br/&gt;   It&amp;#39;s a working demo of the cypherpunk thesis: name resolution and TLS&lt;br/&gt;   trust without ICANN, without public CAs, without DNS. Names are&lt;br/&gt;   blockchain-anchored and TLS is pinned via TLSA-on-Namecoin (DANE-TA).&lt;br/&gt;&lt;br/&gt;#namecoin #nostr #cypherpunk #dotbit&lt;br/&gt;
    </content>
    <updated>2026-04-28T21:18:43Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsfkr7aup09jshu5u0jntsvr2taahjgdpx77pe606epf37udfmnvuqzypp3shk7edn43y5zfvdr0ftl8eq8l00zaknjqx3c9xuv7ja8ck60qtkfnvd</id>
    
      <title type="html">follow-up patch adds WebSocket (WSS) transport — enables ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsfkr7aup09jshu5u0jntsvr2taahjgdpx77pe606epf37udfmnvuqzypp3shk7edn43y5zfvdr0ftl8eq8l00zaknjqx3c9xuv7ja8ck60qtkfnvd" />
    <content type="html">
      In reply to &lt;a href=&#39;/nevent1qqsxwm9uu4rzhf2r87y6r005ltsar23dreyjq48kr9sk5mkmxl5pduch99x66&#39;&gt;nevent1q…9x66&lt;/a&gt;&lt;br/&gt;_________________________&lt;br/&gt;&lt;br/&gt;follow-up patch adds WebSocket (WSS) transport — enables browser/wasm use of nip05/namecoin and works on networks where raw TCP is blocked. same pinned certs, same RPC, just different framing.&lt;blockquote class=&#34;border-l-05rem border-l-strongpink border-solid&#34;&gt;&lt;div class=&#34;-ml-4 bg-gradient-to-r from-gray-100 dark:from-zinc-800 to-transparent mr-0 mt-0 mb-4 pl-4 pr-2 py-2&#34;&gt;quoting  &lt;span itemprop=&#34;mentions&#34; itemscope itemtype=&#34;https://schema.org/Article&#34;&gt;&lt;a itemprop=&#34;url&#34; href=&#34;/nevent1qqsytgl9hh9qkn5xp9l7xf2sjm4z4ksajns8uwnqpgu3ve3aktavxsqpp4mhxue69uhkummn9ekx7mqpzemhxue69uhhyetvv9ujuurjd9kkzmpwdejhgqg0waehxw309ahx7um5wghx6mmdqy28wumn8ghj7un9d3shjtnwva5hgtnyv4mqzynhwden5te0va5hgmn0wd68ytnrdaksygzrrp0dajm8tzfgyjc6x7jh70jq07779md8yqdrs2dcea9603d57qsflk5q&#34; class=&#34;bg-lavender dark:prose:text-neutral-50 dark:text-neutral-50 dark:bg-garnet px-1&#34;&gt;nevent1q…lk5q&lt;/a&gt;&lt;/span&gt; &lt;/div&gt; From d307275490adbc6b012399e2d5200c4b963a4ba6 Mon Sep 17 00:00:00 2001&lt;br/&gt;From: M &lt;m@Ms-MacBook-Pro.local&gt;&lt;br/&gt;Date: Sun, 19 Apr 2026 21:57:33 &#43;1000&lt;br/&gt;Subject: [PATCH] feat(nip05/namecoin): add WebSocket (WSS) transport&lt;br/&gt;&lt;br/&gt;Adds WS/WSS as an alternative transport to TCP&#43;TLS for ElectrumX&lt;br/&gt;name resolution. Enables browser/wasm use of nip05/namecoin and&lt;br/&gt;improves resilience on networks where raw TCP is blocked.&lt;br/&gt;&lt;br/&gt;New: Transport enum on ElectrumxServer, DefaultElectrumXServersWSS,&lt;br/&gt;WebSocket client via github.com/coder/websocket (zero transitive&lt;br/&gt;deps, already a transitive dep of nostrlib). Pinned-cert TLS trust&lt;br/&gt;is shared between TCP&#43;TLS and WSS \u2014 the public operators serve the&lt;br/&gt;same certificate on the adjacent ports (:50002 / :50004 on testls,&lt;br/&gt;:57002 / :57004 on nmc2.bitcoins.sk).&lt;br/&gt;&lt;br/&gt;Zero API break: the new Transport field on ElectrumxServer is a&lt;br/&gt;zero-valued enum that preserves the v1 UseSSL semantics. Every&lt;br/&gt;call site from the previous patch compiles and behaves unchanged.&lt;br/&gt;&lt;br/&gt;Tests: new unit test stands up an httptest WebSocket server via&lt;br/&gt;coder/websocket&#39;s accept helper and exercises the whole dial \u2192&lt;br/&gt;read \u2192 parse flow over WS framing, offline. Integration tests&lt;br/&gt;(build tag integration) add two WSS cases against the live public&lt;br/&gt;servers on :50004, mirroring the existing TCP test fixtures.&lt;br/&gt;&lt;br/&gt;Follow-up to the patch event at&lt;br/&gt;&lt;span itemprop=&#34;mentions&#34; itemscope itemtype=&#34;https://schema.org/Article&#34;&gt;&lt;a itemprop=&#34;url&#34; href=&#34;/nevent1qqs8yepuma694y6saym8ny4wtfzymlgu2htusvweyjzpamc0rgn8pyq&#34; class=&#34;bg-lavender dark:prose:text-neutral-50 dark:text-neutral-50 dark:bg-garnet px-1&#34;&gt;nevent1q…8pyq&lt;/a&gt;&lt;/span&gt;&lt;br/&gt;(original subpackage). Rebase-clean on top of it.&lt;br/&gt;&lt;br/&gt;Signed-off-by: M &lt;m@Ms-MacBook-Pro.local&gt;&lt;br/&gt;---&lt;br/&gt; nip05/namecoin/doc.go                        |   8 &#43;-&lt;br/&gt; nip05/namecoin/electrumx.go                  | 139 &#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;----&lt;br/&gt; nip05/namecoin/electrumx_integration_test.go |  50 &#43;&#43;&#43;&#43;&#43;&lt;br/&gt; nip05/namecoin/servers.go                    |  70 &#43;&#43;&#43;&#43;&#43;&#43;&#43;&lt;br/&gt; nip05/namecoin/websocket.go                  | 105 &#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&lt;br/&gt; nip05/namecoin/websocket_test.go             | 195 &#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&lt;br/&gt; 6 files changed, 524 insertions(&#43;), 43 deletions(-)&lt;br/&gt; create mode 100644 nip05/namecoin/websocket.go&lt;br/&gt; create mode 100644 nip05/namecoin/websocket_test.go&lt;br/&gt;&lt;br/&gt;diff --git a/nip05/namecoin/doc.go b/nip05/namecoin/doc.go&lt;br/&gt;index 7189a38..82bbce2 100644&lt;br/&gt;--- a/nip05/namecoin/doc.go&lt;br/&gt;&#43;&#43;&#43; b/nip05/namecoin/doc.go&lt;br/&gt;@@ -28,6 &#43;28,10 @@&lt;br/&gt; //	    // ...&lt;br/&gt; //	}&lt;br/&gt; //&lt;br/&gt;-// No external dependencies beyond the Go standard library and the&lt;br/&gt;-// fiatjaf.com/nostr types.&lt;br/&gt;&#43;// Two transports are supported: raw TCP&#43;TLS (the default, selected&lt;br/&gt;&#43;// by the zero value of ElectrumxServer.Transport) and WebSocket over&lt;br/&gt;&#43;// TLS (TransportWSS). The WSS path uses github.com/coder/websocket —&lt;br/&gt;&#43;// a zero-transitive-dep library that also compiles cleanly under&lt;br/&gt;&#43;// GOOS=js GOARCH=wasm, enabling browser use. Pinned-cert trust is&lt;br/&gt;&#43;// shared between the two transports.&lt;br/&gt; package namecoin&lt;br/&gt;diff --git a/nip05/namecoin/electrumx.go b/nip05/namecoin/electrumx.go&lt;br/&gt;index 4fbabdb..b7757d5 100644&lt;br/&gt;--- a/nip05/namecoin/electrumx.go&lt;br/&gt;&#43;&#43;&#43; b/nip05/namecoin/electrumx.go&lt;br/&gt;@@ -42,9 &#43;42,24 @@ var (&lt;br/&gt; 	ErrServersUnreachable = errors.New(&#34;namecoin: all ElectrumX servers unreachable&#34;)&lt;br/&gt; )&lt;br/&gt; &lt;br/&gt;&#43;// rpcConn is the transport-agnostic RPC connection abstraction. Both&lt;br/&gt;&#43;// TCP (newline-delimited) and WebSocket (pre-framed) implementations&lt;br/&gt;&#43;// satisfy it so that the name_show flow can be written once.&lt;br/&gt;&#43;type rpcConn interface {&lt;br/&gt;&#43;	// writeRequest serialises and sends a single JSON-RPC request.&lt;br/&gt;&#43;	// Implementations are responsible for any framing the wire format&lt;br/&gt;&#43;	// requires (TCP appends a newline, WS does not).&lt;br/&gt;&#43;	writeRequest(ctx context.Context, method string, params []any, id int64) error&lt;br/&gt;&#43;	// readResponse returns one JSON-RPC response, blocking until one&lt;br/&gt;&#43;	// is available or the context/deadline fires.&lt;br/&gt;&#43;	readResponse(ctx context.Context) (string, error)&lt;br/&gt;&#43;	// close releases the underlying transport.&lt;br/&gt;&#43;	close() error&lt;br/&gt;&#43;}&lt;br/&gt;&#43;&lt;br/&gt; // ElectrumClient is a minimal, query-only Namecoin ElectrumX client.&lt;br/&gt;-// It opens a short-lived TCP/TLS socket per request, which is plenty&lt;br/&gt;-// for interactive CLI use.&lt;br/&gt;&#43;// It opens a short-lived socket per request, which is plenty for&lt;br/&gt;&#43;// interactive CLI use.&lt;br/&gt; type ElectrumClient struct {&lt;br/&gt; 	ConnectTimeout time.Duration&lt;br/&gt; 	ReadTimeout    time.Duration&lt;br/&gt;@@ -68,18 &#43;83,22 @@ func (c *ElectrumClient) NameShow(ctx context.Context, identifier string, server&lt;br/&gt; 	if err != nil {&lt;br/&gt; 		return nil, err&lt;br/&gt; 	}&lt;br/&gt;-	defer conn.Close()&lt;br/&gt;&#43;	defer conn.close()&lt;br/&gt; &lt;br/&gt;-	_ = conn.SetDeadline(time.Now().Add(c.ReadTimeout))&lt;br/&gt;&#43;	// Give the whole request sequence a deadline. For TCP this is&lt;br/&gt;&#43;	// enforced by net.Conn.SetDeadline; for WS the per-call context&lt;br/&gt;&#43;	// carries the budget instead.&lt;br/&gt;&#43;	reqCtx, cancel := context.WithTimeout(ctx, c.ReadTimeout)&lt;br/&gt;&#43;	defer cancel()&lt;br/&gt; &lt;br/&gt;-	reader := bufio.NewReader(conn)&lt;br/&gt;&#43;	next := func() int64 { return c.requestID.Add(1) }&lt;br/&gt; &lt;br/&gt; 	// 1. Negotiate protocol version. The response is consumed and&lt;br/&gt; 	//    discarded — we only care that the socket is alive.&lt;br/&gt;-	if err := c.sendRPC(conn, &#34;server.version&#34;, []any{&#34;nak-namecoin/0.1&#34;, electrumProtocolVersion}); err != nil {&lt;br/&gt;&#43;	if err := conn.writeRequest(reqCtx, &#34;server.version&#34;, []any{&#34;nak-namecoin/0.1&#34;, electrumProtocolVersion}, next()); err != nil {&lt;br/&gt; 		return nil, err&lt;br/&gt; 	}&lt;br/&gt;-	if _, err := reader.ReadString(&#39;\n&#39;); err != nil {&lt;br/&gt;&#43;	if _, err := conn.readResponse(reqCtx); err != nil {&lt;br/&gt; 		return nil, fmt.Errorf(&#34;namecoin: read version response: %w&#34;, err)&lt;br/&gt; 	}&lt;br/&gt; &lt;br/&gt;@@ -88,10 &#43;107,10 @@ func (c *ElectrumClient) NameShow(ctx context.Context, identifier string, server&lt;br/&gt; 	scriptHash := electrumScriptHash(script)&lt;br/&gt; &lt;br/&gt; 	// 3. Fetch transaction history for that scripthash.&lt;br/&gt;-	if err := c.sendRPC(conn, &#34;blockchain.scripthash.get_history&#34;, []any{scriptHash}); err != nil {&lt;br/&gt;&#43;	if err := conn.writeRequest(reqCtx, &#34;blockchain.scripthash.get_history&#34;, []any{scriptHash}, next()); err != nil {&lt;br/&gt; 		return nil, err&lt;br/&gt; 	}&lt;br/&gt;-	histLine, err := reader.ReadString(&#39;\n&#39;)&lt;br/&gt;&#43;	histLine, err := conn.readResponse(reqCtx)&lt;br/&gt; 	if err != nil {&lt;br/&gt; 		return nil, fmt.Errorf(&#34;namecoin: read history response: %w&#34;, err)&lt;br/&gt; 	}&lt;br/&gt;@@ -108,19 &#43;127,19 @@ func (c *ElectrumClient) NameShow(ctx context.Context, identifier string, server&lt;br/&gt; 	latest := entries[len(entries)-1]&lt;br/&gt; &lt;br/&gt; 	// 4. Fetch the verbose transaction.&lt;br/&gt;-	if err := c.sendRPC(conn, &#34;blockchain.transaction.get&#34;, []any{latest.TxHash, true}); err != nil {&lt;br/&gt;&#43;	if err := conn.writeRequest(reqCtx, &#34;blockchain.transaction.get&#34;, []any{latest.TxHash, true}, next()); err != nil {&lt;br/&gt; 		return nil, err&lt;br/&gt; 	}&lt;br/&gt;-	txLine, err := reader.ReadString(&#39;\n&#39;)&lt;br/&gt;&#43;	txLine, err := conn.readResponse(reqCtx)&lt;br/&gt; 	if err != nil {&lt;br/&gt; 		return nil, fmt.Errorf(&#34;namecoin: read transaction response: %w&#34;, err)&lt;br/&gt; 	}&lt;br/&gt; &lt;br/&gt; 	// 5. Get the current block height so we can compute expiry.&lt;br/&gt;-	if err := c.sendRPC(conn, &#34;blockchain.headers.subscribe&#34;, []any{}); err != nil {&lt;br/&gt;&#43;	if err := conn.writeRequest(reqCtx, &#34;blockchain.headers.subscribe&#34;, []any{}, next()); err != nil {&lt;br/&gt; 		return nil, err&lt;br/&gt; 	}&lt;br/&gt;-	headerLine, _ := reader.ReadString(&#39;\n&#39;)&lt;br/&gt;&#43;	headerLine, _ := conn.readResponse(reqCtx)&lt;br/&gt; 	currentHeight := parseBlockHeight(headerLine)&lt;br/&gt; &lt;br/&gt; 	if currentHeight &gt; 0 &amp;&amp; latest.Height &gt; 0 {&lt;br/&gt;@@ -161,10 &#43;180,23 @@ func (c *ElectrumClient) NameShowWithFallback(ctx context.Context, identifier st&lt;br/&gt; 	return nil, fmt.Errorf(&#34;%w: last error: %v&#34;, ErrServersUnreachable, lastErr)&lt;br/&gt; }&lt;br/&gt; &lt;br/&gt;-// dial opens a TCP connection to the server, upgrading to TLS when&lt;br/&gt;-// UseSSL is set. Honours both context cancellation and our connect&lt;br/&gt;-// timeout, whichever fires first.&lt;br/&gt;-func (c *ElectrumClient) dial(ctx context.Context, server ElectrumxServer) (net.Conn, error) {&lt;br/&gt;&#43;// dial picks the right transport implementation based on the server&lt;br/&gt;&#43;// configuration and returns a ready-to-use rpcConn.&lt;br/&gt;&#43;func (c *ElectrumClient) dial(ctx context.Context, server ElectrumxServer) (rpcConn, error) {&lt;br/&gt;&#43;	switch effectiveTransport(server) {&lt;br/&gt;&#43;	case TransportTCPTLS, TransportTCP:&lt;br/&gt;&#43;		return c.dialTCP(ctx, server)&lt;br/&gt;&#43;	case TransportWSS, TransportWS:&lt;br/&gt;&#43;		return c.dialWebSocket(ctx, server)&lt;br/&gt;&#43;	default:&lt;br/&gt;&#43;		return nil, fmt.Errorf(&#34;namecoin: unknown transport %d&#34;, server.Transport)&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;}&lt;br/&gt;&#43;&lt;br/&gt;&#43;// dialTCP opens a raw TCP connection to the server, upgrading to TLS&lt;br/&gt;&#43;// when the effective transport is TCPTLS. Honours both context&lt;br/&gt;&#43;// cancellation and our connect timeout, whichever fires first.&lt;br/&gt;&#43;func (c *ElectrumClient) dialTCP(ctx context.Context, server ElectrumxServer) (rpcConn, error) {&lt;br/&gt; 	dialer := &amp;net.Dialer{Timeout: c.ConnectTimeout}&lt;br/&gt; 	address := net.JoinHostPort(server.Host, strconv.Itoa(server.Port))&lt;br/&gt; &lt;br/&gt;@@ -173,34 &#43;205,41 @@ func (c *ElectrumClient) dial(ctx context.Context, server ElectrumxServer) (net.&lt;br/&gt; 		return nil, fmt.Errorf(&#34;namecoin: dial %s: %w&#34;, address, err)&lt;br/&gt; 	}&lt;br/&gt; &lt;br/&gt;-	if !server.UseSSL {&lt;br/&gt;-		return raw, nil&lt;br/&gt;&#43;	var nc net.Conn = raw&lt;br/&gt;&#43;	if effectiveTransport(server) == TransportTCPTLS {&lt;br/&gt;&#43;		cfg := tlsConfigFor(server)&lt;br/&gt;&#43;		tlsConn := tls.Client(raw, cfg)&lt;br/&gt;&#43;&lt;br/&gt;&#43;		// Run the handshake with a deadline so a silent server doesn&#39;t hang&lt;br/&gt;&#43;		// the call beyond what the caller asked for.&lt;br/&gt;&#43;		if deadline, ok := ctx.Deadline(); ok {&lt;br/&gt;&#43;			_ = tlsConn.SetDeadline(deadline)&lt;br/&gt;&#43;		} else {&lt;br/&gt;&#43;			_ = tlsConn.SetDeadline(time.Now().Add(c.ConnectTimeout))&lt;br/&gt;&#43;		}&lt;br/&gt;&#43;		if err := tlsConn.HandshakeContext(ctx); err != nil {&lt;br/&gt;&#43;			raw.Close()&lt;br/&gt;&#43;			return nil, fmt.Errorf(&#34;namecoin: TLS handshake with %s: %w&#34;, address, err)&lt;br/&gt;&#43;		}&lt;br/&gt;&#43;		// Clear the handshake deadline — we&#39;ll set fresh per-request&lt;br/&gt;&#43;		// deadlines below.&lt;br/&gt;&#43;		_ = tlsConn.SetDeadline(time.Time{})&lt;br/&gt;&#43;		nc = tlsConn&lt;br/&gt; 	}&lt;br/&gt; &lt;br/&gt;-	cfg := tlsConfigFor(server)&lt;br/&gt;-	tlsConn := tls.Client(raw, cfg)&lt;br/&gt;&#43;	_ = nc.SetDeadline(time.Now().Add(c.ReadTimeout))&lt;br/&gt;&#43;	return &amp;tcpRPCConn{conn: nc, reader: bufio.NewReader(nc)}, nil&lt;br/&gt;&#43;}&lt;br/&gt; &lt;br/&gt;-	// Run the handshake with a deadline so a silent server doesn&#39;t hang&lt;br/&gt;-	// the call beyond what the caller asked for.&lt;br/&gt;-	if deadline, ok := ctx.Deadline(); ok {&lt;br/&gt;-		_ = tlsConn.SetDeadline(deadline)&lt;br/&gt;-	} else {&lt;br/&gt;-		_ = tlsConn.SetDeadline(time.Now().Add(c.ConnectTimeout))&lt;br/&gt;-	}&lt;br/&gt;-	if err := tlsConn.HandshakeContext(ctx); err != nil {&lt;br/&gt;-		raw.Close()&lt;br/&gt;-		return nil, fmt.Errorf(&#34;namecoin: TLS handshake with %s: %w&#34;, address, err)&lt;br/&gt;-	}&lt;br/&gt;-	// Clear the handshake deadline — the caller sets its own read&lt;br/&gt;-	// deadline afterwards.&lt;br/&gt;-	_ = tlsConn.SetDeadline(time.Time{})&lt;br/&gt;-	return tlsConn, nil&lt;br/&gt;&#43;// tcpRPCConn is the newline-delimited JSON-RPC transport over raw&lt;br/&gt;&#43;// TCP or TCP&#43;TLS. This matches the shape every Electrum / ElectrumX&lt;br/&gt;&#43;// client has used for the last decade.&lt;br/&gt;&#43;type tcpRPCConn struct {&lt;br/&gt;&#43;	conn   net.Conn&lt;br/&gt;&#43;	reader *bufio.Reader&lt;br/&gt; }&lt;br/&gt; &lt;br/&gt;-// sendRPC writes a JSON-RPC 2.0 request (newline-terminated, per&lt;br/&gt;-// Electrum&#39;s line-delimited protocol) to the connection.&lt;br/&gt;-func (c *ElectrumClient) sendRPC(w net.Conn, method string, params []any) error {&lt;br/&gt;-	id := c.requestID.Add(1)&lt;br/&gt;&#43;func (t *tcpRPCConn) writeRequest(ctx context.Context, method string, params []any, id int64) error {&lt;br/&gt; 	payload := map[string]any{&lt;br/&gt; 		&#34;jsonrpc&#34;: &#34;2.0&#34;,&lt;br/&gt; 		&#34;id&#34;:      id,&lt;br/&gt;@@ -212,12 &#43;251,30 @@ func (c *ElectrumClient) sendRPC(w net.Conn, method string, params []any) error&lt;br/&gt; 		return fmt.Errorf(&#34;namecoin: marshal rpc request: %w&#34;, err)&lt;br/&gt; 	}&lt;br/&gt; 	encoded = append(encoded, &#39;\n&#39;)&lt;br/&gt;-	if _, err := w.Write(encoded); err != nil {&lt;br/&gt;&#43;	if deadline, ok := ctx.Deadline(); ok {&lt;br/&gt;&#43;		_ = t.conn.SetWriteDeadline(deadline)&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;	if _, err := t.conn.Write(encoded); err != nil {&lt;br/&gt; 		return fmt.Errorf(&#34;namecoin: write rpc request: %w&#34;, err)&lt;br/&gt; 	}&lt;br/&gt; 	return nil&lt;br/&gt; }&lt;br/&gt; &lt;br/&gt;&#43;func (t *tcpRPCConn) readResponse(ctx context.Context) (string, error) {&lt;br/&gt;&#43;	if deadline, ok := ctx.Deadline(); ok {&lt;br/&gt;&#43;		_ = t.conn.SetReadDeadline(deadline)&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;	line, err := t.reader.ReadString(&#39;\n&#39;)&lt;br/&gt;&#43;	if err != nil {&lt;br/&gt;&#43;		return &#34;&#34;, err&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;	return line, nil&lt;br/&gt;&#43;}&lt;br/&gt;&#43;&lt;br/&gt;&#43;func (t *tcpRPCConn) close() error {&lt;br/&gt;&#43;	return t.conn.Close()&lt;br/&gt;&#43;}&lt;br/&gt;&#43;&lt;br/&gt; // historyEntry is one row of `blockchain.scripthash.get_history`.&lt;br/&gt; type historyEntry struct {&lt;br/&gt; 	TxHash string&lt;br/&gt;diff --git a/nip05/namecoin/electrumx_integration_test.go b/nip05/namecoin/electrumx_integration_test.go&lt;br/&gt;index 1458d4d..64ac17c 100644&lt;br/&gt;--- a/nip05/namecoin/electrumx_integration_test.go&lt;br/&gt;&#43;&#43;&#43; b/nip05/namecoin/electrumx_integration_test.go&lt;br/&gt;@@ -49,3 &#43;49,53 @@ func TestIntegration_ResolveAtTestlsBit(t *testing.T) {&lt;br/&gt; 		t.Errorf(&#34;m@testls.bit pubkey = %s, want %s&#34;, got, testlsMPubkey)&lt;br/&gt; 	}&lt;br/&gt; }&lt;br/&gt;&#43;&lt;br/&gt;&#43;// --- WSS (WebSocket over TLS) integration tests -----------------------&lt;br/&gt;&#43;//&lt;br/&gt;&#43;// These hit the same ElectrumX operators as the TCP tests above, but&lt;br/&gt;&#43;// over the WebSocket endpoints (ports 500xx&#43;2 on testls, 570xx&#43;2 on&lt;br/&gt;&#43;// nmc2.bitcoins.sk). Same pinned certs, same JSON-RPC protocol, just&lt;br/&gt;&#43;// different framing. The assertions match the TCP path because the&lt;br/&gt;&#43;// Namecoin blockchain is the source of truth.&lt;br/&gt;&#43;&lt;br/&gt;&#43;func TestIntegration_ResolveTestlsBit_WSS(t *testing.T) {&lt;br/&gt;&#43;	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)&lt;br/&gt;&#43;	defer cancel()&lt;br/&gt;&#43;&lt;br/&gt;&#43;	client := NewElectrumClient()&lt;br/&gt;&#43;	result, err := client.NameShowWithFallback(ctx, &#34;d/testls&#34;, DefaultElectrumXServersWSS)&lt;br/&gt;&#43;	if err != nil {&lt;br/&gt;&#43;		t.Fatalf(&#34;NameShowWithFallback(d/testls, WSS): %v&#34;, err)&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;	if result == nil {&lt;br/&gt;&#43;		t.Fatal(&#34;nil result&#34;)&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;	pk, _, err := extractNostrFromValue(result.Value, &amp;parsedIdentifier{&#34;d/testls&#34;, &#34;_&#34;, true})&lt;br/&gt;&#43;	if err != nil {&lt;br/&gt;&#43;		t.Fatalf(&#34;extractNostrFromValue: %v&#34;, err)&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;	if pk != testlsRootPubkey {&lt;br/&gt;&#43;		t.Errorf(&#34;testls.bit (WSS) pubkey = %s, want %s&#34;, pk, testlsRootPubkey)&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;}&lt;br/&gt;&#43;&lt;br/&gt;&#43;func TestIntegration_ResolveAtTestlsBit_WSS(t *testing.T) {&lt;br/&gt;&#43;	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)&lt;br/&gt;&#43;	defer cancel()&lt;br/&gt;&#43;&lt;br/&gt;&#43;	client := NewElectrumClient()&lt;br/&gt;&#43;	result, err := client.NameShowWithFallback(ctx, &#34;d/testls&#34;, DefaultElectrumXServersWSS)&lt;br/&gt;&#43;	if err != nil {&lt;br/&gt;&#43;		t.Fatalf(&#34;NameShowWithFallback(d/testls, WSS): %v&#34;, err)&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;	if result == nil {&lt;br/&gt;&#43;		t.Fatal(&#34;nil result&#34;)&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;	pk, _, err := extractNostrFromValue(result.Value, &amp;parsedIdentifier{&#34;d/testls&#34;, &#34;m&#34;, true})&lt;br/&gt;&#43;	if err != nil {&lt;br/&gt;&#43;		t.Fatalf(&#34;extractNostrFromValue: %v&#34;, err)&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;	if pk != testlsMPubkey {&lt;br/&gt;&#43;		t.Errorf(&#34;m@testls.bit (WSS) pubkey = %s, want %s&#34;, pk, testlsMPubkey)&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;}&lt;br/&gt;diff --git a/nip05/namecoin/servers.go b/nip05/namecoin/servers.go&lt;br/&gt;index b76c889..71c8551 100644&lt;br/&gt;--- a/nip05/namecoin/servers.go&lt;br/&gt;&#43;&#43;&#43; b/nip05/namecoin/servers.go&lt;br/&gt;@@ -1,15 &#43;1,59 @@&lt;br/&gt; package namecoin&lt;br/&gt; &lt;br/&gt;&#43;// Transport selects how an ElectrumX server is dialed. The zero value&lt;br/&gt;&#43;// is TransportTCPTLS, matching the traditional Electrum client path&lt;br/&gt;&#43;// and the behaviour shipped in v0.1.x. Callers that want WebSocket&lt;br/&gt;&#43;// (for example, browser/wasm targets or restricted networks that&lt;br/&gt;&#43;// block raw TCP) set this to TransportWSS.&lt;br/&gt;&#43;type Transport int&lt;br/&gt;&#43;&lt;br/&gt;&#43;const (&lt;br/&gt;&#43;	// TransportTCPTLS is raw TCP &#43; TLS with newline-delimited JSON-RPC.&lt;br/&gt;&#43;	// This is the default and what most Namecoin ElectrumX clients use.&lt;br/&gt;&#43;	TransportTCPTLS Transport = iota&lt;br/&gt;&#43;	// TransportTCP is plaintext TCP — rarely used in practice but&lt;br/&gt;&#43;	// supported for completeness / local testing.&lt;br/&gt;&#43;	TransportTCP&lt;br/&gt;&#43;	// TransportWSS is WebSocket over TLS, using the ElectrumX WS&lt;br/&gt;&#43;	// endpoint (ports 500xx&#43;2 on typical public servers). Messages&lt;br/&gt;&#43;	// are pre-framed by the WebSocket layer and MUST NOT carry a&lt;br/&gt;&#43;	// trailing newline.&lt;br/&gt;&#43;	TransportWSS&lt;br/&gt;&#43;	// TransportWS is plaintext WebSocket.&lt;br/&gt;&#43;	TransportWS&lt;br/&gt;&#43;)&lt;br/&gt;&#43;&lt;br/&gt; // ElectrumxServer is a single Namecoin ElectrumX endpoint.&lt;br/&gt; type ElectrumxServer struct {&lt;br/&gt; 	Host string&lt;br/&gt; 	Port int&lt;br/&gt; 	// UseSSL indicates TLS should be negotiated over the raw socket.&lt;br/&gt;&#43;	// Kept for backwards compat with v0.1.x callers. When Transport&lt;br/&gt;&#43;	// is the zero value, UseSSL selects between TransportTCPTLS&lt;br/&gt;&#43;	// (UseSSL=true) and TransportTCP (UseSSL=false).&lt;br/&gt; 	UseSSL bool&lt;br/&gt; 	// UsePinnedTrustStore enables the pinned-cert trust anchor bundle&lt;br/&gt; 	// for servers that present self-signed certificates. This is the&lt;br/&gt; 	// norm for the public Namecoin ElectrumX ecosystem.&lt;br/&gt; 	UsePinnedTrustStore bool&lt;br/&gt;&#43;	// Transport selects the dial transport. Zero value keeps v0.1.x&lt;br/&gt;&#43;	// semantics: if UseSSL is true it&#39;s TCP&#43;TLS, otherwise plain TCP.&lt;br/&gt;&#43;	// Set explicitly to TransportWSS / TransportWS for WebSocket.&lt;br/&gt;&#43;	Transport Transport&lt;br/&gt;&#43;}&lt;br/&gt;&#43;&lt;br/&gt;&#43;// effectiveTransport resolves the transport to use for a server,&lt;br/&gt;&#43;// reconciling the legacy UseSSL bool with the explicit Transport&lt;br/&gt;&#43;// field. The explicit Transport wins when non-zero.&lt;br/&gt;&#43;func effectiveTransport(s ElectrumxServer) Transport {&lt;br/&gt;&#43;	if s.Transport != TransportTCPTLS {&lt;br/&gt;&#43;		return s.Transport&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;	// Zero value: fall back to UseSSL for v0.1.x compatibility.&lt;br/&gt;&#43;	if s.UseSSL {&lt;br/&gt;&#43;		return TransportTCPTLS&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;	return TransportTCP&lt;br/&gt; }&lt;br/&gt; &lt;br/&gt; // DefaultElectrumXServers is the built-in list of public Namecoin&lt;br/&gt;@@ -24,11 &#43;68,37 @@ var DefaultElectrumXServers = []ElectrumxServer{&lt;br/&gt; 	{Host: &#34;46.229.238.187&#34;, Port: 57002, UseSSL: true, UsePinnedTrustStore: true},&lt;br/&gt; }&lt;br/&gt; &lt;br/&gt;&#43;// DefaultElectrumXServersWSS is the WSS-preferred server list. It&lt;br/&gt;&#43;// points at the same operators as DefaultElectrumXServers but uses&lt;br/&gt;&#43;// their WebSocket-over-TLS endpoints. Useful for:&lt;br/&gt;&#43;//&lt;br/&gt;&#43;//   - Browser / wasm targets, where raw TCP is unavailable and the&lt;br/&gt;&#43;//     only viable transport is the browser&#39;s WebSocket API (which&lt;br/&gt;&#43;//     `github.com/coder/websocket` targets natively when compiled&lt;br/&gt;&#43;//     with GOOS=js GOARCH=wasm).&lt;br/&gt;&#43;//   - Restricted networks that block the traditional ElectrumX ports&lt;br/&gt;&#43;//     but allow outbound HTTPS/WSS.&lt;br/&gt;&#43;//   - Environments that prefer WSS on policy grounds (aligns with the&lt;br/&gt;&#43;//     broader Nostr ecosystem, which is WSS-everywhere).&lt;br/&gt;&#43;//&lt;br/&gt;&#43;// Ports are the ElectrumX convention of ELECTRUM_PORT&#43;2 for the WSS&lt;br/&gt;&#43;// endpoint. Both listed operators expose these alongside their&lt;br/&gt;&#43;// TCP&#43;TLS ports, sharing the same TLS certificate.&lt;br/&gt;&#43;var DefaultElectrumXServersWSS = []ElectrumxServer{&lt;br/&gt;&#43;	{Host: &#34;electrumx.testls.space&#34;, Port: 50004, Transport: TransportWSS, UsePinnedTrustStore: true},&lt;br/&gt;&#43;	{Host: &#34;nmc2.bitcoins.sk&#34;, Port: 57004, Transport: TransportWSS, UsePinnedTrustStore: true},&lt;br/&gt;&#43;	{Host: &#34;46.229.238.187&#34;, Port: 57004, Transport: TransportWSS, UsePinnedTrustStore: true},&lt;br/&gt;&#43;}&lt;br/&gt;&#43;&lt;br/&gt; // PinnedElectrumXCerts is the PEM-encoded bundle of server&lt;br/&gt; // certificates we trust in addition to the system roots. These are&lt;br/&gt; // copied verbatim from the Kotlin Amethyst reference implementation.&lt;br/&gt; //&lt;br/&gt; // To refresh: `echo | openssl s_client -connect HOST:PORT 2&gt;/dev/null | openssl x509 -outform PEM`&lt;br/&gt;&#43;//&lt;br/&gt;&#43;// The same certificates are served on the WSS endpoints (adjacent&lt;br/&gt;&#43;// ports on the same host), so a single pinned bundle covers both&lt;br/&gt;&#43;// transports.&lt;br/&gt; var PinnedElectrumXCerts = []string{&lt;br/&gt; 	// electrumx.testls.space:50002 — expires 2027-05-04.&lt;br/&gt; 	// Also covers the i665jpwsq46zlsdbnj4axgzd3s56uzey5uhotsnxzsknzbn36jaddsid.onion:50002&lt;br/&gt;diff --git a/nip05/namecoin/websocket.go b/nip05/namecoin/websocket.go&lt;br/&gt;new file mode 100644&lt;br/&gt;index 0000000..5e849d7&lt;br/&gt;--- /dev/null&lt;br/&gt;&#43;&#43;&#43; b/nip05/namecoin/websocket.go&lt;br/&gt;@@ -0,0 &#43;1,105 @@&lt;br/&gt;&#43;package namecoin&lt;br/&gt;&#43;&lt;br/&gt;&#43;import (&lt;br/&gt;&#43;	&#34;context&#34;&lt;br/&gt;&#43;	&#34;encoding/json&#34;&lt;br/&gt;&#43;	&#34;fmt&#34;&lt;br/&gt;&#43;	&#34;net&#34;&lt;br/&gt;&#43;	&#34;net/http&#34;&lt;br/&gt;&#43;	&#34;strconv&#34;&lt;br/&gt;&#43;&lt;br/&gt;&#43;	&#34;github.com/coder/websocket&#34;&lt;br/&gt;&#43;)&lt;br/&gt;&#43;&lt;br/&gt;&#43;// wsReadLimit is the maximum size of a single WebSocket message we are&lt;br/&gt;&#43;// willing to accept from an ElectrumX server. Verbose transactions&lt;br/&gt;&#43;// from `blockchain.transaction.get` can legitimately run to tens of&lt;br/&gt;&#43;// kilobytes; 1 MiB is generous but keeps us safely bounded.&lt;br/&gt;&#43;const wsReadLimit int64 = 1 &lt;&lt; 20&lt;br/&gt;&#43;&lt;br/&gt;&#43;// dialWebSocket opens a WebSocket (plain or TLS) RPC connection to&lt;br/&gt;&#43;// the given ElectrumX server. It reuses the same pinned-cert TLS&lt;br/&gt;&#43;// config as the TCP&#43;TLS transport so operators who serve a single&lt;br/&gt;&#43;// self-signed certificate across both ports are handled identically.&lt;br/&gt;&#43;func (c *ElectrumClient) dialWebSocket(ctx context.Context, server ElectrumxServer) (rpcConn, error) {&lt;br/&gt;&#43;	transport := effectiveTransport(server)&lt;br/&gt;&#43;	scheme := &#34;ws&#34;&lt;br/&gt;&#43;	if transport == TransportWSS {&lt;br/&gt;&#43;		scheme = &#34;wss&#34;&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;	address := net.JoinHostPort(server.Host, strconv.Itoa(server.Port))&lt;br/&gt;&#43;	url := scheme &#43; &#34;://&#34; &#43; address&lt;br/&gt;&#43;&lt;br/&gt;&#43;	// Bound the dial to our connect timeout, in addition to honouring&lt;br/&gt;&#43;	// any deadline on the caller&#39;s context.&lt;br/&gt;&#43;	dialCtx, cancel := context.WithTimeout(ctx, c.ConnectTimeout)&lt;br/&gt;&#43;	defer cancel()&lt;br/&gt;&#43;&lt;br/&gt;&#43;	opts := &amp;websocket.DialOptions{}&lt;br/&gt;&#43;	if transport == TransportWSS {&lt;br/&gt;&#43;		// Build an http.Transport that carries the same *tls.Config&lt;br/&gt;&#43;		// the TCP&#43;TLS path uses. The custom VerifyPeerCertificate is&lt;br/&gt;&#43;		// transport-agnostic, so pinned-cert trust continues to work&lt;br/&gt;&#43;		// over WebSocket&#39;s HTTP upgrade handshake.&lt;br/&gt;&#43;		tlsCfg := tlsConfigFor(server)&lt;br/&gt;&#43;		opts.HTTPClient = &amp;http.Client{&lt;br/&gt;&#43;			Timeout: c.ConnectTimeout &#43; c.ReadTimeout,&lt;br/&gt;&#43;			Transport: &amp;http.Transport{&lt;br/&gt;&#43;				TLSClientConfig:     tlsCfg,&lt;br/&gt;&#43;				TLSHandshakeTimeout: c.ConnectTimeout,&lt;br/&gt;&#43;			},&lt;br/&gt;&#43;		}&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;&lt;br/&gt;&#43;	conn, _, err := websocket.Dial(dialCtx, url, opts)&lt;br/&gt;&#43;	if err != nil {&lt;br/&gt;&#43;		return nil, fmt.Errorf(&#34;namecoin: websocket dial %s: %w&#34;, url, err)&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;	conn.SetReadLimit(wsReadLimit)&lt;br/&gt;&#43;&lt;br/&gt;&#43;	return &amp;wsRPCConn{conn: conn}, nil&lt;br/&gt;&#43;}&lt;br/&gt;&#43;&lt;br/&gt;&#43;// wsRPCConn is the WebSocket JSON-RPC transport. Unlike the TCP&lt;br/&gt;&#43;// variant, WebSocket messages are pre-framed by the protocol layer,&lt;br/&gt;&#43;// so requests MUST NOT carry a trailing newline and responses arrive&lt;br/&gt;&#43;// as whole JSON messages per frame.&lt;br/&gt;&#43;type wsRPCConn struct {&lt;br/&gt;&#43;	conn *websocket.Conn&lt;br/&gt;&#43;}&lt;br/&gt;&#43;&lt;br/&gt;&#43;func (w *wsRPCConn) writeRequest(ctx context.Context, method string, params []any, id int64) error {&lt;br/&gt;&#43;	payload := map[string]any{&lt;br/&gt;&#43;		&#34;jsonrpc&#34;: &#34;2.0&#34;,&lt;br/&gt;&#43;		&#34;id&#34;:      id,&lt;br/&gt;&#43;		&#34;method&#34;:  method,&lt;br/&gt;&#43;		&#34;params&#34;:  params,&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;	encoded, err := json.Marshal(payload)&lt;br/&gt;&#43;	if err != nil {&lt;br/&gt;&#43;		return fmt.Errorf(&#34;namecoin: marshal rpc request: %w&#34;, err)&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;	if err := w.conn.Write(ctx, websocket.MessageText, encoded); err != nil {&lt;br/&gt;&#43;		return fmt.Errorf(&#34;namecoin: write rpc request: %w&#34;, err)&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;	return nil&lt;br/&gt;&#43;}&lt;br/&gt;&#43;&lt;br/&gt;&#43;func (w *wsRPCConn) readResponse(ctx context.Context) (string, error) {&lt;br/&gt;&#43;	_, data, err := w.conn.Read(ctx)&lt;br/&gt;&#43;	if err != nil {&lt;br/&gt;&#43;		return &#34;&#34;, err&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;	return string(data), nil&lt;br/&gt;&#43;}&lt;br/&gt;&#43;&lt;br/&gt;&#43;func (w *wsRPCConn) close() error {&lt;br/&gt;&#43;	return w.conn.Close(websocket.StatusNormalClosure, &#34;&#34;)&lt;br/&gt;&#43;}&lt;br/&gt;&#43;&lt;br/&gt;&#43;// Compile-time interface checks — catch drift early if the rpcConn&lt;br/&gt;&#43;// signature ever evolves.&lt;br/&gt;&#43;var (&lt;br/&gt;&#43;	_ rpcConn = (*tcpRPCConn)(nil)&lt;br/&gt;&#43;	_ rpcConn = (*wsRPCConn)(nil)&lt;br/&gt;&#43;)&lt;br/&gt;diff --git a/nip05/namecoin/websocket_test.go b/nip05/namecoin/websocket_test.go&lt;br/&gt;new file mode 100644&lt;br/&gt;index 0000000..ad5682a&lt;br/&gt;--- /dev/null&lt;br/&gt;&#43;&#43;&#43; b/nip05/namecoin/websocket_test.go&lt;br/&gt;@@ -0,0 &#43;1,195 @@&lt;br/&gt;&#43;package namecoin&lt;br/&gt;&#43;&lt;br/&gt;&#43;import (&lt;br/&gt;&#43;	&#34;context&#34;&lt;br/&gt;&#43;	&#34;encoding/json&#34;&lt;br/&gt;&#43;	&#34;net/http&#34;&lt;br/&gt;&#43;	&#34;net/http/httptest&#34;&lt;br/&gt;&#43;	&#34;net/url&#34;&lt;br/&gt;&#43;	&#34;strconv&#34;&lt;br/&gt;&#43;	&#34;strings&#34;&lt;br/&gt;&#43;	&#34;testing&#34;&lt;br/&gt;&#43;	&#34;time&#34;&lt;br/&gt;&#43;&lt;br/&gt;&#43;	&#34;github.com/coder/websocket&#34;&lt;br/&gt;&#43;)&lt;br/&gt;&#43;&lt;br/&gt;&#43;// fakeElectrumXWSHandler returns an http.Handler that upgrades incoming&lt;br/&gt;&#43;// connections to WebSocket and serves canned JSON-RPC responses for the&lt;br/&gt;&#43;// sequence the ElectrumClient issues during NameShow.&lt;br/&gt;&#43;//&lt;br/&gt;&#43;// The response ordering mirrors the real RPC sequence:&lt;br/&gt;&#43;//   1. server.version               → any non-error result&lt;br/&gt;&#43;//   2. blockchain.scripthash.get_history → one entry pointing at a fake txid&lt;br/&gt;&#43;//   3. blockchain.transaction.get   → one vout with a NAME_UPDATE that&lt;br/&gt;&#43;//                                     matches the requested name and a&lt;br/&gt;&#43;//                                     value whose &#34;nostr&#34; field is a&lt;br/&gt;&#43;//                                     known hex pubkey&lt;br/&gt;&#43;//   4. blockchain.headers.subscribe → a height far enough below our&lt;br/&gt;&#43;//                                     fake tx height that the name is&lt;br/&gt;&#43;//                                     well within its expiry window&lt;br/&gt;&#43;//&lt;br/&gt;&#43;// This exercises the whole WS dial → read → parse path end-to-end&lt;br/&gt;&#43;// without hitting the network.&lt;br/&gt;&#43;func fakeElectrumXWSHandler(t *testing.T, identifier, pubkeyHex string) http.Handler {&lt;br/&gt;&#43;	// Build the NAME_UPDATE script hex we want the client to parse&lt;br/&gt;&#43;	// back out of the &#34;transaction&#34;.&lt;br/&gt;&#43;	value := `{&#34;nostr&#34;:&#34;` &#43; pubkeyHex &#43; `&#34;}`&lt;br/&gt;&#43;	script := []byte{opNameUpdate}&lt;br/&gt;&#43;	script = append(script, pushData([]byte(identifier))...)&lt;br/&gt;&#43;	script = append(script, pushData([]byte(value))...)&lt;br/&gt;&#43;	script = append(script, op2Drop, opDrop)&lt;br/&gt;&#43;	// Stub P2PKH-ish tail so the parser&#39;s &#34;we don&#39;t care what follows&lt;br/&gt;&#43;	// the DROPs&#34; assumption holds.&lt;br/&gt;&#43;	script = append(script, 0x76, 0xa9, 0x14)&lt;br/&gt;&#43;	scriptHex := hexString(script)&lt;br/&gt;&#43;&lt;br/&gt;&#43;	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {&lt;br/&gt;&#43;		conn, err := websocket.Accept(w, r, nil)&lt;br/&gt;&#43;		if err != nil {&lt;br/&gt;&#43;			t.Logf(&#34;ws accept: %v&#34;, err)&lt;br/&gt;&#43;			return&lt;br/&gt;&#43;		}&lt;br/&gt;&#43;		defer conn.Close(websocket.StatusInternalError, &#34;test server shutting down&#34;)&lt;br/&gt;&#43;&lt;br/&gt;&#43;		ctx := r.Context()&lt;br/&gt;&#43;&lt;br/&gt;&#43;		respond := func(id any, result any) {&lt;br/&gt;&#43;			payload := map[string]any{&lt;br/&gt;&#43;				&#34;jsonrpc&#34;: &#34;2.0&#34;,&lt;br/&gt;&#43;				&#34;id&#34;:      id,&lt;br/&gt;&#43;				&#34;result&#34;:  result,&lt;br/&gt;&#43;			}&lt;br/&gt;&#43;			raw, _ := json.Marshal(payload)&lt;br/&gt;&#43;			if err := conn.Write(ctx, websocket.MessageText, raw); err != nil {&lt;br/&gt;&#43;				t.Logf(&#34;ws write: %v&#34;, err)&lt;br/&gt;&#43;			}&lt;br/&gt;&#43;		}&lt;br/&gt;&#43;&lt;br/&gt;&#43;		for {&lt;br/&gt;&#43;			_, data, err := conn.Read(ctx)&lt;br/&gt;&#43;			if err != nil {&lt;br/&gt;&#43;				return&lt;br/&gt;&#43;			}&lt;br/&gt;&#43;			var req struct {&lt;br/&gt;&#43;				ID     any    `json:&#34;id&#34;`&lt;br/&gt;&#43;				Method string `json:&#34;method&#34;`&lt;br/&gt;&#43;			}&lt;br/&gt;&#43;			if err := json.Unmarshal(data, &amp;req); err != nil {&lt;br/&gt;&#43;				t.Logf(&#34;ws request parse: %v&#34;, err)&lt;br/&gt;&#43;				return&lt;br/&gt;&#43;			}&lt;br/&gt;&#43;			switch req.Method {&lt;br/&gt;&#43;			case &#34;server.version&#34;:&lt;br/&gt;&#43;				respond(req.ID, []string{&#34;ElectrumX 1.16.0&#34;, electrumProtocolVersion})&lt;br/&gt;&#43;			case &#34;blockchain.scripthash.get_history&#34;:&lt;br/&gt;&#43;				respond(req.ID, []map[string]any{&lt;br/&gt;&#43;					{&#34;tx_hash&#34;: &#34;deadbeefcafebabe&#34;, &#34;height&#34;: 600000},&lt;br/&gt;&#43;				})&lt;br/&gt;&#43;			case &#34;blockchain.transaction.get&#34;:&lt;br/&gt;&#43;				respond(req.ID, map[string]any{&lt;br/&gt;&#43;					&#34;txid&#34;: &#34;deadbeefcafebabe&#34;,&lt;br/&gt;&#43;					&#34;vout&#34;: []map[string]any{&lt;br/&gt;&#43;						{&#34;scriptPubKey&#34;: map[string]any{&#34;hex&#34;: scriptHex}},&lt;br/&gt;&#43;					},&lt;br/&gt;&#43;				})&lt;br/&gt;&#43;			case &#34;blockchain.headers.subscribe&#34;:&lt;br/&gt;&#43;				respond(req.ID, map[string]any{&#34;height&#34;: 600010})&lt;br/&gt;&#43;			default:&lt;br/&gt;&#43;				respond(req.ID, nil)&lt;br/&gt;&#43;			}&lt;br/&gt;&#43;		}&lt;br/&gt;&#43;	})&lt;br/&gt;&#43;}&lt;br/&gt;&#43;&lt;br/&gt;&#43;func hexString(b []byte) string {&lt;br/&gt;&#43;	const hexDigits = &#34;0123456789abcdef&#34;&lt;br/&gt;&#43;	out := make([]byte, 0, len(b)*2)&lt;br/&gt;&#43;	for _, v := range b {&lt;br/&gt;&#43;		out = append(out, hexDigits[v&gt;&gt;4], hexDigits[v&amp;0x0f])&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;	return string(out)&lt;br/&gt;&#43;}&lt;br/&gt;&#43;&lt;br/&gt;&#43;func TestWebSocketTransport_NameShow(t *testing.T) {&lt;br/&gt;&#43;	identifier := &#34;d/wsfake&#34;&lt;br/&gt;&#43;	pubkey := &#34;aaaa000000000000000000000000000000000000000000000000000000000001&#34;&lt;br/&gt;&#43;&lt;br/&gt;&#43;	ts := httptest.NewServer(fakeElectrumXWSHandler(t, identifier, pubkey))&lt;br/&gt;&#43;	defer ts.Close()&lt;br/&gt;&#43;&lt;br/&gt;&#43;	// Parse the httptest URL so we can point the client at it as&lt;br/&gt;&#43;	// host&#43;port with the plain-WS transport. httptest.Server is HTTP,&lt;br/&gt;&#43;	// so TransportWS (not WSS) is what we want here — it verifies the&lt;br/&gt;&#43;	// framing/routing independently of the TLS plumbing.&lt;br/&gt;&#43;	u, err := url.Parse(ts.URL)&lt;br/&gt;&#43;	if err != nil {&lt;br/&gt;&#43;		t.Fatal(err)&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;	port, err := strconv.Atoi(u.Port())&lt;br/&gt;&#43;	if err != nil {&lt;br/&gt;&#43;		t.Fatal(err)&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;&lt;br/&gt;&#43;	srv := ElectrumxServer{&lt;br/&gt;&#43;		Host:      u.Hostname(),&lt;br/&gt;&#43;		Port:      port,&lt;br/&gt;&#43;		Transport: TransportWS,&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;&lt;br/&gt;&#43;	client := NewElectrumClient()&lt;br/&gt;&#43;	client.ConnectTimeout = 3 * time.Second&lt;br/&gt;&#43;	client.ReadTimeout = 5 * time.Second&lt;br/&gt;&#43;&lt;br/&gt;&#43;	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)&lt;br/&gt;&#43;	defer cancel()&lt;br/&gt;&#43;&lt;br/&gt;&#43;	result, err := client.NameShow(ctx, identifier, srv)&lt;br/&gt;&#43;	if err != nil {&lt;br/&gt;&#43;		t.Fatalf(&#34;NameShow over WS: %v&#34;, err)&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;	if result == nil {&lt;br/&gt;&#43;		t.Fatal(&#34;NameShow returned nil result&#34;)&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;	if result.Name != identifier {&lt;br/&gt;&#43;		t.Errorf(&#34;name = %q, want %q&#34;, result.Name, identifier)&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;	if !strings.Contains(result.Value, pubkey) {&lt;br/&gt;&#43;		t.Errorf(&#34;value = %q, want to contain %q&#34;, result.Value, pubkey)&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;}&lt;br/&gt;&#43;&lt;br/&gt;&#43;func TestEffectiveTransport(t *testing.T) {&lt;br/&gt;&#43;	cases := []struct {&lt;br/&gt;&#43;		in   ElectrumxServer&lt;br/&gt;&#43;		want Transport&lt;br/&gt;&#43;	}{&lt;br/&gt;&#43;		// v0.1.x shape: UseSSL=true, Transport unset → TCPTLS.&lt;br/&gt;&#43;		{ElectrumxServer{UseSSL: true}, TransportTCPTLS},&lt;br/&gt;&#43;		// v0.1.x shape: UseSSL=false, Transport unset → plain TCP.&lt;br/&gt;&#43;		{ElectrumxServer{UseSSL: false}, TransportTCP},&lt;br/&gt;&#43;		// Explicit Transport wins over UseSSL when non-zero.&lt;br/&gt;&#43;		{ElectrumxServer{UseSSL: true, Transport: TransportWSS}, TransportWSS},&lt;br/&gt;&#43;		{ElectrumxServer{UseSSL: false, Transport: TransportWS}, TransportWS},&lt;br/&gt;&#43;		{ElectrumxServer{UseSSL: false, Transport: TransportTCPTLS}, TransportTCP}, // TCPTLS is zero value; falls back to UseSSL&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;	for i, tc := range cases {&lt;br/&gt;&#43;		if got := effectiveTransport(tc.in); got != tc.want {&lt;br/&gt;&#43;			t.Errorf(&#34;case %d: effectiveTransport(%&#43;v) = %d, want %d&#34;, i, tc.in, got, tc.want)&lt;br/&gt;&#43;		}&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;}&lt;br/&gt;&#43;&lt;br/&gt;&#43;func TestDefaultElectrumXServersWSS(t *testing.T) {&lt;br/&gt;&#43;	if len(DefaultElectrumXServersWSS) == 0 {&lt;br/&gt;&#43;		t.Fatal(&#34;DefaultElectrumXServersWSS is empty&#34;)&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;	for _, srv := range DefaultElectrumXServersWSS {&lt;br/&gt;&#43;		if srv.Transport != TransportWSS {&lt;br/&gt;&#43;			t.Errorf(&#34;%s:%d has Transport=%d, want WSS&#34;, srv.Host, srv.Port, srv.Transport)&lt;br/&gt;&#43;		}&lt;br/&gt;&#43;		if !srv.UsePinnedTrustStore {&lt;br/&gt;&#43;			t.Errorf(&#34;%s:%d: WSS default servers must pin the trust store&#34;, srv.Host, srv.Port)&lt;br/&gt;&#43;		}&lt;br/&gt;&#43;	}&lt;br/&gt;&#43;}&lt;br/&gt;-- &lt;br/&gt;2.50.1 (Apple Git-155)&lt;br/&gt;&lt;br/&gt; &lt;/blockquote&gt;
    </content>
    <updated>2026-04-19T12:00:28Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsxwm9uu4rzhf2r87y6r005ltsar23dreyjq48kr9sk5mkmxl5pduczypp3shk7edn43y5zfvdr0ftl8eq8l00zaknjqx3c9xuv7ja8ck60qwkzrde</id>
    
      <title type="html">@npub180c…h6w6 re https://github.com/fiatjaf/nak/pull/123 — ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsxwm9uu4rzhf2r87y6r005ltsar23dreyjq48kr9sk5mkmxl5pduczypp3shk7edn43y5zfvdr0ftl8eq8l00zaknjqx3c9xuv7ja8ck60qwkzrde" />
    <content type="html">
      In reply to &lt;a href=&#39;/naddr1qqyxummnw3exc6tzqgsrhuxx8l9ex335q7he0f09aej04zpazpl0ne2cgukyawd24mayt8grqsqqqaue48cxua&#39;&gt;naddr1qq…cxua&lt;/a&gt;&lt;br/&gt;_________________________&lt;br/&gt;&lt;br/&gt;&lt;span itemprop=&#34;mentions&#34; itemscope itemtype=&#34;https://schema.org/Person&#34;&gt;&lt;a itemprop=&#34;url&#34; href=&#34;/npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6&#34; class=&#34;bg-lavender dark:prose:text-neutral-50 dark:text-neutral-50 dark:bg-garnet px-1&#34;&gt;&lt;span&gt;fiatjaf&lt;/span&gt; (&lt;span class=&#34;italic&#34;&gt;npub180c…h6w6&lt;/span&gt;)&lt;/a&gt;&lt;/span&gt; re &lt;a href=&#34;https://github.com/fiatjaf/nak/pull/123&#34;&gt;https://github.com/fiatjaf/nak/pull/123&lt;/a&gt; — posted a NIP-34 patch event adding a proposed nip05/namecoin subpackage to nostrlib, addressed to you. Patch: nostr:nevent1qqs8yepuma694y6saym8ny4wtfzymlgu2htusvweyjzpamc0rgn8pyqpz3mhxue69uhhyetvv9ujumn8d96zuer9wcq3yamnwvaz7tm8d96xummnw3ezucm0d5q3gamnwvaz7tmjv4kxz7fwv3sk6atn9e5k7q3qgvv9ahktvavf9qjtrgm62le7gplmmchd5usp5wpfhr85hf79kncq8jdtz6. GitHub mirror: &lt;a href=&#34;https://github.com/mstrofnone/nostrlib-nip05-namecoin&#34;&gt;https://github.com/mstrofnone/nostrlib-nip05-namecoin&lt;/a&gt;
    </content>
    <updated>2026-04-19T11:25:10Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsdx2pwklc5ccf9cumgkm4z5xwm4sck0zfgmqdaammxfvggt802k6qzypp3shk7edn43y5zfvdr0ftl8eq8l00zaknjqx3c9xuv7ja8ck60qhmqfnz</id>
    
      <title type="html">This is spot on. Satoshi saw merged mining as the way to ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsdx2pwklc5ccf9cumgkm4z5xwm4sck0zfgmqdaammxfvggt802k6qzypp3shk7edn43y5zfvdr0ftl8eq8l00zaknjqx3c9xuv7ja8ck60qhmqfnz" />
    <content type="html">
      In reply to &lt;a href=&#39;/nevent1qqstx4vqglk6lhrrg6kvcqynt6qpj2tdx4rdpm33yme65ra98gqg08gxkvxmt&#39;&gt;nevent1q…vxmt&lt;/a&gt;&lt;br/&gt;_________________________&lt;br/&gt;&lt;br/&gt;This is spot on. Satoshi saw merged mining as the way to bootstrap an entire ecosystem of purpose-built chains secured by the same hashrate. BitDNS/Namecoin was the proof of concept.&lt;br/&gt;&lt;br/&gt;What most people miss is that Namecoin gives you something no other system does: human-readable names with immutable, temporally ordered key bindings on a chain with Bitcoin-class security. That&amp;#39;s not a novelty — it&amp;#39;s infrastructure.&lt;br/&gt;&lt;br/&gt;We&amp;#39;re using it right now to build a Nostr reputation layer with blockchain-anchored identity proofs:&lt;br/&gt;&lt;blockquote class=&#34;border-l-05rem border-l-strongpink border-solid&#34;&gt;&lt;div class=&#34;-ml-4 bg-gradient-to-r from-gray-100 dark:from-zinc-800 to-transparent mr-0 mt-0 mb-4 pl-4 pr-2 py-2&#34;&gt;quoting &lt;br/&gt;&lt;span itemprop=&#34;mentions&#34; itemscope itemtype=&#34;https://schema.org/Article&#34;&gt;&lt;a itemprop=&#34;url&#34; href=&#34;/naddr1qvzqqqr4gupzqscctm0vke6cj2pykx3h54lnusrlhh3wmfeqrguznwx0fwnutd8sqq3kuctdv43k76tw945kuar9vaexzarfdahz6ctdv46xs7tnwskkwatfv3jsz0753t&#34; class=&#34;bg-lavender dark:prose:text-neutral-50 dark:text-neutral-50 dark:bg-garnet px-1&#34;&gt;naddr1qv…753t&lt;/a&gt;&lt;/span&gt;&lt;br/&gt; &lt;/div&gt; 
&lt;h1 id=&#34;how-to-guide-namecoin-integration-in-amethyst-2&#34;&gt;How-To Guide: Namecoin Integration in Amethyst&lt;/h1&gt;

&lt;h2 id=&#34;what-this-is-2&#34;&gt;What This Is&lt;/h2&gt;

&lt;p&gt;Amethyst — the Android Nostr client — includes built-in support for resolving Namecoin blockchain names as NIP-05 identities. Instead of relying on a web server to verify &lt;code&gt;alice@example.com&lt;/code&gt;, a user can set their NIP-05 address to something like &lt;code&gt;alice@example.bit&lt;/code&gt;, and Amethyst will verify it directly against the Namecoin blockchain via ElectrumX servers.&lt;/p&gt;

&lt;p&gt;This is censorship-resistant identity: no web server to seize, no DNS to hijack, no TLS certificate to revoke. The name-to-pubkey mapping lives in Namecoin UTXOs.&lt;/p&gt;

&lt;p&gt;This guide covers how the system works, how to use it as an end-user, and how to register or update a Namecoin name value so that it resolves to your Nostr pubkey.&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&#34;part-1-using-namecoin-names-in-amethyst-end-user-2&#34;&gt;Part 1: Using Namecoin Names in Amethyst (End-User)&lt;/h2&gt;

&lt;h3 id=&#34;searching-for-namecoin-users-2&#34;&gt;Searching for Namecoin Users&lt;/h3&gt;

&lt;p&gt;Open Amethyst&amp;#39;s search bar and type any of these formats:&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Search Input&lt;/th&gt;
&lt;th&gt;What It Does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;alice@example.bit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Looks up the &lt;code&gt;alice&lt;/code&gt; entry in Namecoin name &lt;code&gt;d/example&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;example.bit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Looks up the root (&lt;code&gt;_&lt;/code&gt;) entry in &lt;code&gt;d/example&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;d/example&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Direct Namecoin domain namespace lookup (root entry)&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;id/alice&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Direct Namecoin identity namespace lookup&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Amethyst queries the Namecoin blockchain through an ElectrumX server, resolves the name to a Nostr public key, and shows the matching user profile at the top of search results. There is a 400ms debounce on the search input to avoid flooding the server with requests.&lt;/p&gt;

&lt;h3 id=&#34;nip-05-verification-via-namecoin-2&#34;&gt;NIP-05 Verification via Namecoin&lt;/h3&gt;

&lt;p&gt;If a Nostr profile has a &lt;code&gt;.bit&lt;/code&gt; address in its &lt;code&gt;nip05&lt;/code&gt; metadata field (e.g. &lt;code&gt;m@testls.bit&lt;/code&gt;), Amethyst will automatically verify it against the blockchain instead of making an HTTP request. The verification badge works the same as traditional NIP-05 — the only difference is the trust anchor: blockchain consensus rather than a web server.&lt;/p&gt;

&lt;h3 id=&#34;configuring-namecoin-settings-2&#34;&gt;Configuring Namecoin Settings&lt;/h3&gt;

&lt;p&gt;Navigate to &lt;strong&gt;Settings → Namecoin Settings&lt;/strong&gt; in Amethyst. From here you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Enable/disable&lt;/strong&gt; Namecoin resolution entirely&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Add custom ElectrumX servers&lt;/strong&gt; — useful if you run your own server for privacy&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Remove servers&lt;/strong&gt; from the custom list&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Test server connectivity&lt;/strong&gt; — checks TLS, latency, and optionally resolves a test name&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pin TLS certificates&lt;/strong&gt; — after testing a server with a self-signed cert, you can pin its certificate via TOFU (Trust On First Use)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reset to defaults&lt;/strong&gt; — reverts to the built-in server list&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&#34;server-string-format-2&#34;&gt;Server String Format&lt;/h4&gt;

&lt;p&gt;When adding a custom server, use the format:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;host:port          → TLS connection (default)
host:port:tcp      → Plaintext TCP (for .onion or local servers)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;electrumx.testls.space:50002
my-local-server.lan:50001:tcp
i665jpw...dsid.onion:50002
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;tor-integration-2&#34;&gt;Tor Integration&lt;/h3&gt;

&lt;p&gt;If you have Tor enabled in Amethyst and have set &amp;#34;NIP-05 verifications via Tor&amp;#34; to on, all Namecoin ElectrumX connections are routed through your Tor SOCKS proxy. The server list also switches to prioritize &lt;code&gt;.onion&lt;/code&gt; addresses:&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tor Setting&lt;/th&gt;
&lt;th&gt;Primary Server&lt;/th&gt;
&lt;th&gt;Fallback&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Off&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;electrumx.testls.space:50002&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nmc2.bitcoins.sk:57002&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;On&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.onion:50002&lt;/code&gt; (hidden service)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;electrumx.testls.space:50002&lt;/code&gt; (via Tor)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Toggling Tor on or off in settings takes effect on the next lookup — no app restart needed.&lt;/p&gt;

&lt;h3 id=&#34;default-electrumx-servers-2&#34;&gt;Default ElectrumX Servers&lt;/h3&gt;

&lt;p&gt;Amethyst ships with these built-in servers:&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Server&lt;/th&gt;
&lt;th&gt;Port&lt;/th&gt;
&lt;th&gt;TLS&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;electrumx.testls.space&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;50002&lt;/td&gt;
&lt;td&gt;Yes (self-signed, pinned)&lt;/td&gt;
&lt;td&gt;Primary&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;nmc2.bitcoins.sk&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;57002&lt;/td&gt;
&lt;td&gt;Yes (self-signed, pinned)&lt;/td&gt;
&lt;td&gt;Fallback&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;46.229.238.187&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;57002&lt;/td&gt;
&lt;td&gt;Yes (self-signed, pinned)&lt;/td&gt;
&lt;td&gt;IP fallback&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The self-signed certificates for these servers are pinned directly into the Amethyst binary, so connections succeed even on devices with strict TLS enforcement (Samsung One UI 7, GrapheneOS).&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&#34;part-2-registering-updating-a-namecoin-name-value-2&#34;&gt;Part 2: Registering &amp;amp; Updating a Namecoin Name Value&lt;/h2&gt;

&lt;p&gt;Amethyst itself is a &lt;strong&gt;read-only&lt;/strong&gt; consumer of Namecoin data — it resolves names but does not write to the blockchain. To register or update a Namecoin name so that it points to your Nostr pubkey, you need to interact with the Namecoin blockchain directly using Namecoin Core (the full node software) or a compatible wallet.&lt;/p&gt;

&lt;h3 id=&#34;prerequisites-2&#34;&gt;Prerequisites&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Namecoin Core&lt;/strong&gt; or &lt;strong&gt;Electrum-NMC&lt;/strong&gt; installed and synced — download from &lt;a href=&#34;https://www.namecoin.org/&#34;&gt;namecoin.org&lt;/a&gt; (this guide uses Namecoin Core as an example)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NMC (Namecoin coins)&lt;/strong&gt; in your wallet — needed to pay registration and update fees (0.01 NMC per registration operation plus associated fees)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Your Nostr hex public key&lt;/strong&gt; — the 64-character hex string (not &lt;code&gt;npub1...&lt;/code&gt;). You can find this in Amethyst under your profile settings or by converting your npub using a tool like &lt;a href=&#34;https://nostrdeck.com/key-converter.php&#34;&gt;https://nostrdeck.com/key-converter.php&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&#34;step-1-choose-your-namespace-2&#34;&gt;Step 1: Choose Your Namespace&lt;/h3&gt;

&lt;p&gt;Amethyst supports two Namecoin namespaces:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Domain namespace (&lt;code&gt;d/&lt;/code&gt;)&lt;/strong&gt; — maps a domain-like name to one or more Nostr pubkeys. This is the most common choice and mirrors NIP-05&amp;#39;s &lt;code&gt;user@domain&lt;/code&gt; format.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Identity namespace (&lt;code&gt;id/&lt;/code&gt;)&lt;/strong&gt; — maps a personal identity name to a single Nostr pubkey.&lt;/p&gt;

&lt;p&gt;For most users, the &lt;code&gt;d/&lt;/code&gt; namespace is the right choice because it allows &lt;code&gt;user@name.bit&lt;/code&gt; style addresses.&lt;/p&gt;

&lt;h3 id=&#34;step-2-register-a-new-name-2&#34;&gt;Step 2: Register a New Name&lt;/h3&gt;

&lt;p&gt;Open a terminal and use &lt;code&gt;namecoin-cli&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Register a name in the domain namespace
# This creates a &amp;#34;pre-registration&amp;#34; (name_new) first
namecoin-cli name_new &amp;#34;d/yourname&amp;#34;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This returns a transaction ID and a random value. &lt;strong&gt;Save both&lt;/strong&gt; — you need the random value for the next step. Wait for the transaction to get at least 12 confirmations (about 2 hours).&lt;/p&gt;

&lt;p&gt;Then finalize the registration:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;namecoin-cli name_firstupdate &amp;#34;d/yourname&amp;#34; &amp;lt;random_value&amp;gt; &amp;#39;&amp;lt;json_value&amp;gt;&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;step-3-set-the-name-value-for-nostr-2&#34;&gt;Step 3: Set the Name Value for Nostr&lt;/h3&gt;

&lt;p&gt;The JSON value you store in the Namecoin name is what Amethyst reads to find your Nostr pubkey. There are several supported formats.&lt;/p&gt;

&lt;h4 id=&#34;simple-form-single-user-root-domain-2&#34;&gt;Simple Form — Single User, Root Domain&lt;/h4&gt;

&lt;p&gt;If you just want &lt;code&gt;yourname.bit&lt;/code&gt; to resolve to your pubkey:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  &amp;#34;nostr&amp;#34;: &amp;#34;b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9&amp;#34;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;namecoin-cli name_firstupdate &amp;#34;d/yourname&amp;#34; &amp;lt;random&amp;gt; \
  &amp;#39;{&amp;#34;nostr&amp;#34;:&amp;#34;b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9&amp;#34;}&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This makes &lt;code&gt;yourname.bit&lt;/code&gt; and &lt;code&gt;_@yourname.bit&lt;/code&gt; resolve to the given pubkey.&lt;/p&gt;

&lt;h4 id=&#34;extended-form-multiple-users-with-relay-hints-2&#34;&gt;Extended Form — Multiple Users with Relay Hints&lt;/h4&gt;

&lt;p&gt;If you want to host multiple identities under one &lt;code&gt;.bit&lt;/code&gt; domain (like a NIP-05 server hosting multiple users):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  &amp;#34;nostr&amp;#34;: {
    &amp;#34;names&amp;#34;: {
      &amp;#34;_&amp;#34;: &amp;#34;aaaa000000000000000000000000000000000000000000000000000000000001&amp;#34;,
      &amp;#34;alice&amp;#34;: &amp;#34;bbbb000000000000000000000000000000000000000000000000000000000002&amp;#34;,
      &amp;#34;bob&amp;#34;: &amp;#34;cccc000000000000000000000000000000000000000000000000000000000003&amp;#34;
    },
    &amp;#34;relays&amp;#34;: {
      &amp;#34;bbbb000000000000000000000000000000000000000000000000000000000002&amp;#34;: [
        &amp;#34;wss://relay.example.com&amp;#34;,
        &amp;#34;wss://nos.lol&amp;#34;
      ]
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With this value stored in &lt;code&gt;d/yourname&lt;/code&gt;:
- &lt;code&gt;_@yourname.bit&lt;/code&gt; or &lt;code&gt;yourname.bit&lt;/code&gt; → resolves to the &lt;code&gt;_&lt;/code&gt; pubkey
- &lt;code&gt;alice@yourname.bit&lt;/code&gt; → resolves to Alice&amp;#39;s pubkey, with relay hints
- &lt;code&gt;bob@yourname.bit&lt;/code&gt; → resolves to Bob&amp;#39;s pubkey&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;namecoin-cli name_firstupdate &amp;#34;d/yourname&amp;#34; &amp;lt;random&amp;gt; \
  &amp;#39;{&amp;#34;nostr&amp;#34;:{&amp;#34;names&amp;#34;:{&amp;#34;_&amp;#34;:&amp;#34;aaaa...0001&amp;#34;,&amp;#34;alice&amp;#34;:&amp;#34;bbbb...0002&amp;#34;},&amp;#34;relays&amp;#34;:{&amp;#34;bbbb...0002&amp;#34;:[&amp;#34;wss://relay.example.com&amp;#34;]}}}&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&#34;identity-namespace-form-id-2&#34;&gt;Identity Namespace Form (&lt;code&gt;id/&lt;/code&gt;)&lt;/h4&gt;

&lt;p&gt;For the &lt;code&gt;id/&lt;/code&gt; namespace, the value format is simpler:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  &amp;#34;nostr&amp;#34;: &amp;#34;cccc000000000000000000000000000000000000000000000000000000000003&amp;#34;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or with relay hints:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  &amp;#34;nostr&amp;#34;: {
    &amp;#34;pubkey&amp;#34;: &amp;#34;dddd000000000000000000000000000000000000000000000000000000000004&amp;#34;,
    &amp;#34;relays&amp;#34;: [&amp;#34;wss://relay.example.com&amp;#34;]
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;namecoin-cli name_firstupdate &amp;#34;id/youridentity&amp;#34; &amp;lt;random&amp;gt; \
  &amp;#39;{&amp;#34;nostr&amp;#34;:{&amp;#34;pubkey&amp;#34;:&amp;#34;dddd...0004&amp;#34;,&amp;#34;relays&amp;#34;:[&amp;#34;wss://relay.example.com&amp;#34;]}}&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;step-4-update-an-existing-name-2&#34;&gt;Step 4: Update an Existing Name&lt;/h3&gt;

&lt;p&gt;To change the Nostr pubkey (or any other data) associated with an already-registered name, use &lt;code&gt;name_update&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;namecoin-cli name_update &amp;#34;d/yourname&amp;#34; \
  &amp;#39;{&amp;#34;nostr&amp;#34;:{&amp;#34;names&amp;#34;:{&amp;#34;_&amp;#34;:&amp;#34;&amp;lt;new_hex_pubkey&amp;gt;&amp;#34;,&amp;#34;alice&amp;#34;:&amp;#34;&amp;lt;alice_hex_pubkey&amp;gt;&amp;#34;},&amp;#34;relays&amp;#34;:{&amp;#34;&amp;lt;alice_hex_pubkey&amp;gt;&amp;#34;:[&amp;#34;wss://relay.example.com&amp;#34;]}}}&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This broadcasts a &lt;code&gt;NAME_UPDATE&lt;/code&gt; transaction to the Namecoin blockchain. Once confirmed, Amethyst (and any other client that supports Namecoin NIP-05) will resolve the name to the new value.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important notes on updates:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each &lt;code&gt;name_update&lt;/code&gt; costs a small NMC fee&lt;/li&gt;
&lt;li&gt;Names expire after &lt;strong&gt;36,000 blocks&lt;/strong&gt; (~36 weeks) if not updated or renewed. Amethyst checks expiry and will treat expired names as non-existent.&lt;/li&gt;
&lt;li&gt;To simply renew without changing the value, you can &lt;code&gt;name_update&lt;/code&gt; with the same value&lt;/li&gt;
&lt;li&gt;Updates replace the entire value — there is no partial update mechanism&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;step-5-set-your-nip-05-in-your-nostr-profile-2&#34;&gt;Step 5: Set Your NIP-05 in Your Nostr Profile&lt;/h3&gt;

&lt;p&gt;Once your Namecoin name is registered and confirmed on the blockchain, update your Nostr profile&amp;#39;s &lt;code&gt;nip05&lt;/code&gt; field in Amethyst:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to your profile → Edit&lt;/li&gt;
&lt;li&gt;Set the NIP-05 field to your Namecoin address, e.g. &lt;code&gt;alice@yourname.bit&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Save&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Amethyst (and other Namecoin-aware clients) will verify this address against the blockchain and show the verification badge.&lt;/p&gt;

&lt;h3 id=&#34;step-6-verify-it-works-2&#34;&gt;Step 6: Verify It Works&lt;/h3&gt;

&lt;p&gt;In Amethyst&amp;#39;s search bar, type your Namecoin identifier. You should see your profile appear at the top of results:&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Test Query&lt;/th&gt;
&lt;th&gt;Expected Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;alice@yourname.bit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Your profile (matched via &lt;code&gt;alice&lt;/code&gt; entry)&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;yourname.bit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Your profile (matched via &lt;code&gt;_&lt;/code&gt; root entry)&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;d/yourname&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Your profile (direct namespace lookup)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;hr&gt;

&lt;h2 id=&#34;part-3-how-it-works-under-the-hood-2&#34;&gt;Part 3: How It Works Under the Hood&lt;/h2&gt;

&lt;h3 id=&#34;resolution-flow-2&#34;&gt;Resolution Flow&lt;/h3&gt;

&lt;p&gt;When Amethyst encounters a &lt;code&gt;.bit&lt;/code&gt; address, here is what happens:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1. User types &amp;#34;alice@example.bit&amp;#34; in search (or a profile has it in nip05)

2. NamecoinNameResolver.parseIdentifier() parses it:
   → namecoinName = &amp;#34;d/example&amp;#34;, localPart = &amp;#34;alice&amp;#34;, namespace = DOMAIN

3. ElectrumXClient builds a canonical &amp;#34;name index script&amp;#34;:
   OP_NAME_UPDATE(0x53) &#43; push(&amp;#34;d/example&amp;#34;) &#43; push(&amp;#34;&amp;#34;) &#43; OP_2DROP &#43; OP_DROP &#43; OP_RETURN

4. Computes the Electrum-style scripthash:
   SHA-256(script) → reverse bytes → hex encode

5. Queries the ElectrumX server:
   → blockchain.scripthash.get_history(scripthash)
   ← [{tx_hash: &amp;#34;abc...&amp;#34;, height: 814278}, ...]

6. Fetches the latest transaction (last entry = most recent name update):
   → blockchain.transaction.get(tx_hash, verbose=true)

7. Checks block headers to verify the name hasn&amp;#39;t expired:
   → blockchain.headers.subscribe
   ← current height; if (current - update_height) &amp;gt;= 36000 → expired

8. Parses the NAME_UPDATE script from the transaction output:
   Extracts: name string &#43; JSON value

9. NamecoinNameResolver.extractFromDomainValue() reads the JSON:
   Finds &amp;#34;nostr&amp;#34; → &amp;#34;names&amp;#34; → &amp;#34;alice&amp;#34; → hex pubkey

10. Returns NamecoinNostrResult(pubkey, relays, namecoinName, localPart)
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;caching-2&#34;&gt;Caching&lt;/h3&gt;

&lt;p&gt;Resolved names are cached in an LRU cache (default 500 entries, 1-hour TTL). Both positive and negative results are cached. The cache is keyed by the normalized (lowercased, trimmed) identifier.&lt;/p&gt;

&lt;h3 id=&#34;architecture-layers-2&#34;&gt;Architecture Layers&lt;/h3&gt;

&lt;p&gt;The implementation is split across two modules:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quartz (library, no Android dependencies):&lt;/strong&gt;
- &lt;code&gt;NamecoinNameResolver&lt;/code&gt; — identifier parsing, value extraction, resolution orchestration
- &lt;code&gt;ElectrumXClient&lt;/code&gt; — TCP/TLS connection to ElectrumX, JSON-RPC, script parsing
- &lt;code&gt;NamecoinLookupCache&lt;/code&gt; — LRU cache with TTL
- &lt;code&gt;IElectrumXClient&lt;/code&gt; — interface for testing/mocking&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amethyst (Android app):&lt;/strong&gt;
- &lt;code&gt;NamecoinNameService&lt;/code&gt; — application singleton, wires up caching and proxy-aware client
- &lt;code&gt;NamecoinSettings&lt;/code&gt; / &lt;code&gt;NamecoinSharedPreferences&lt;/code&gt; — persistent config
- &lt;code&gt;NamecoinSettingsScreen&lt;/code&gt; / &lt;code&gt;NamecoinSettingsSection&lt;/code&gt; — settings UI
- &lt;code&gt;ProxiedSocketFactory&lt;/code&gt; — SOCKS5 proxy routing for Tor
- &lt;code&gt;RoleBasedHttpClientBuilder.socketFactoryForNip05()&lt;/code&gt; — Tor-aware socket creation&lt;/p&gt;

&lt;p&gt;The integration into NIP-05 is minimal: &lt;code&gt;Nip05Client&lt;/code&gt; checks if an identifier matches &lt;code&gt;.bit&lt;/code&gt; / &lt;code&gt;d/&lt;/code&gt; / &lt;code&gt;id/&lt;/code&gt; patterns, and routes to &lt;code&gt;NamecoinNameResolver&lt;/code&gt; instead of making an HTTP fetch. Non-Namecoin identifiers are completely unaffected.&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&#34;part-4-security-considerations-2&#34;&gt;Part 4: Security Considerations&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Tor integration&lt;/strong&gt; — When enabled, all ElectrumX connections go through the Tor SOCKS proxy. The &lt;code&gt;.onion&lt;/code&gt; server is preferred for end-to-end onion routing. Socket factory and server list are evaluated per-request via lambdas, so toggling Tor takes effect immediately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TLS certificate pinning&lt;/strong&gt; — The primary ElectrumX servers use self-signed certificates. Their PEM-encoded certs are pinned in the Amethyst binary. Users can pin additional certs via the TOFU flow in settings (test server → view fingerprint → confirm → pin). This is necessary because Samsung One UI 7 and GrapheneOS reject trust-all TrustManagers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Name expiry&lt;/strong&gt; — Namecoin names expire after ~36,000 blocks (~250 days) if not renewed. The ElectrumX client checks the current block height against the name&amp;#39;s last update height and treats expired names as non-existent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Server trust&lt;/strong&gt; — The client trusts that the ElectrumX server returns accurate transaction data. The Namecoin blockchain itself is the trust anchor — a MITM could return stale data but cannot forge name registrations. For higher assurance, SPV proof verification could be added in the future.&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&#34;quick-reference-2&#34;&gt;Quick Reference&lt;/h2&gt;

&lt;h3 id=&#34;identifier-format-summary-2&#34;&gt;Identifier Format Summary&lt;/h3&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;User Input&lt;/th&gt;
&lt;th&gt;Namecoin Name&lt;/th&gt;
&lt;th&gt;Looked-Up Entry&lt;/th&gt;
&lt;th&gt;Namespace&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;alice@example.bit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;d/example&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;alice&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Domain&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;_@example.bit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;d/example&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;_&lt;/code&gt; (root)&lt;/td&gt;
&lt;td&gt;Domain&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;example.bit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;d/example&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;_&lt;/code&gt; (root)&lt;/td&gt;
&lt;td&gt;Domain&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;d/example&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;d/example&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;_&lt;/code&gt; (root)&lt;/td&gt;
&lt;td&gt;Domain&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;id/alice&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;id/alice&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;_&lt;/code&gt; (root)&lt;/td&gt;
&lt;td&gt;Identity&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&#34;name-value-json-formats-2&#34;&gt;Name Value JSON Formats&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Domain simple:&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{&amp;#34;nostr&amp;#34;: &amp;#34;&amp;lt;64-char-hex-pubkey&amp;gt;&amp;#34;}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Domain extended (multi-user &#43; relays):&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{&amp;#34;nostr&amp;#34;: {&amp;#34;names&amp;#34;: {&amp;#34;_&amp;#34;: &amp;#34;&amp;lt;hex&amp;gt;&amp;#34;, &amp;#34;alice&amp;#34;: &amp;#34;&amp;lt;hex&amp;gt;&amp;#34;}, &amp;#34;relays&amp;#34;: {&amp;#34;&amp;lt;hex&amp;gt;&amp;#34;: [&amp;#34;wss://...&amp;#34;]}}}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Identity simple:&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{&amp;#34;nostr&amp;#34;: &amp;#34;&amp;lt;64-char-hex-pubkey&amp;gt;&amp;#34;}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Identity with relays:&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{&amp;#34;nostr&amp;#34;: {&amp;#34;pubkey&amp;#34;: &amp;#34;&amp;lt;hex&amp;gt;&amp;#34;, &amp;#34;relays&amp;#34;: [&amp;#34;wss://...&amp;#34;]}}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;namecoin-cli-commands-2&#34;&gt;Namecoin CLI Commands&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;# Register a new name
namecoin-cli name_new &amp;#34;d/yourname&amp;#34;
# Returns: [txid, random_value]
# Example:
#   [
#     &amp;#34;a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2&amp;#34;,
#     &amp;#34;6e4a2d190f7b&amp;#34;
#   ]
# SAVE BOTH — you need the random value (2nd element) for name_firstupdate.
# Wait for at least 12 confirmations (~2 hours) before proceeding.

# Finalize registration with the random value from name_new
namecoin-cli name_firstupdate &amp;#34;d/yourname&amp;#34; &amp;lt;random&amp;gt; &amp;#39;&amp;lt;json&amp;gt;&amp;#39;

# Update an existing name
namecoin-cli name_update &amp;#34;d/yourname&amp;#34; &amp;#39;&amp;lt;new_json&amp;gt;&amp;#39;

# Check a name&amp;#39;s current value
namecoin-cli name_show &amp;#34;d/yourname&amp;#34;

# List your names
namecoin-cli name_list
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;getting-namecoins-via-dvm-nip-90-2&#34;&gt;Getting Namecoins via DVM (NIP-90)&lt;/h3&gt;

&lt;p&gt;Don&amp;#39;t have NMC? You can acquire Namecoin through a Nostr-native exchange service — no centralized exchange account needed.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;NMC Exchange DVM&lt;/strong&gt; is a &lt;a href=&#34;https://github.com/nostr-protocol/nips/blob/master/90.md&#34;&gt;NIP-90 Data Vending Machine&lt;/a&gt; that accepts Lightning Bitcoin (⚡ sats) or Cashu ecash (🥜) and sends NMC directly to your Namecoin address.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Send a &lt;code&gt;kind:5950&lt;/code&gt; job request to the DVM with your NMC address and desired amount (0.2–0.5 NMC)&lt;/li&gt;
&lt;li&gt;The DVM responds with a Lightning invoice or Cashu payment info&lt;/li&gt;
&lt;li&gt;Pay via Lightning zap or Cashu ecash&lt;/li&gt;
&lt;li&gt;Receive NMC at your designated address — the DVM sends the &lt;code&gt;kind:6950&lt;/code&gt; result with the NMC transaction ID&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Rate:&lt;/strong&gt; $10 USD per NMC (max 0.5 NMC per order)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Payment methods:&lt;/strong&gt; Lightning Bitcoin ⚡ | Cashu ecash 🥜&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DVM address (NIP-89):&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;span itemprop=&#34;mentions&#34; itemscope itemtype=&#34;https://schema.org/Article&#34;&gt;&lt;a itemprop=&#34;url&#34; href=&#34;/naddr1qvzqqqru7cpzqscctm0vke6cj2pykx3h54lnusrlhh3wmfeqrguznwx0fwnutd8sqy2hwumn8ghj7un9d3shjtnyd968gmewwp6kyqqsdekkxtt90p3ksctwvajj6erkd5njfjn5&#34; class=&#34;bg-lavender dark:prose:text-neutral-50 dark:text-neutral-50 dark:bg-garnet px-1&#34;&gt;naddr1qv…fjn5&lt;/a&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;View on NostrHub:&lt;/strong&gt; &lt;a href=&#34;https://nostrhub.io/naddr1qvzqqqru7cpzqscctm0vke6cj2pykx3h54lnusrlhh3wmfeqrguznwx0fwnutd8sqy2hwumn8ghj7un9d3shjtnyd968gmewwp6kyqqsdekkxtt90p3ksctwvajj6erkd5njfjn5&#34;&gt;NMC Exchange DVM&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example job request:&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  &amp;#34;kind&amp;#34;: 5950,
  &amp;#34;tags&amp;#34;: [
    [&amp;#34;i&amp;#34;, &amp;#34;&amp;lt;your-nmc-address&amp;gt;&amp;#34;, &amp;#34;text&amp;#34;],
    [&amp;#34;param&amp;#34;, &amp;#34;amount&amp;#34;, &amp;#34;0.5&amp;#34;],
    [&amp;#34;bid&amp;#34;, &amp;#34;10000000&amp;#34;]
  ],
  &amp;#34;content&amp;#34;: &amp;#34;&amp;#34;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is an experimental service — no guarantees of uptime, but it&amp;#39;s a quick way to get NMC for name registrations without touching a centralized exchange.&lt;/p&gt;

&lt;h3 id=&#34;testing-for-developers-2&#34;&gt;Testing (for Developers)&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;# Run unit tests
./gradlew :quartz:jvmTest --tests &amp;#34;*NamecoinNameResolverTest*&amp;#34;

# Build and install debug APK
./gradlew assemblePlayDebug
adb install -r amethyst/build/outputs/apk/play/debug/amethyst-play-universal-debug.apk

# Monitor ElectrumX connections
adb root &amp;amp;&amp;amp; adb shell tcpdump -i any -nn port 50002 or port 50006
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;live-test-data-2&#34;&gt;Live Test Data&lt;/h3&gt;

&lt;p&gt;The name &lt;code&gt;d/testls&lt;/code&gt; is registered on the Namecoin blockchain with value:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{&amp;#34;nostr&amp;#34;: {&amp;#34;names&amp;#34;: {&amp;#34;_&amp;#34;: &amp;#34;6cdebccabda1dfa058ab85352a79509b592b2bdfa0370325e28ec1cb4f18667d&amp;#34;}}}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So &lt;code&gt;_@testls.bit&lt;/code&gt; (or simply &lt;code&gt;testls.bit&lt;/code&gt;) resolves to Vitor Pamplona&amp;#39;s Nostr profile.&lt;/p&gt;
 &lt;/blockquote&gt;&lt;br/&gt;The cypherpunk use case Satoshi envisioned for merged mining is more relevant now than ever.
    </content>
    <updated>2026-04-08T08:33:05Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsqmltjktqdzrdxp3q8ynxges8k6jvqzcvfay4yk62ryyyh0m3s29czypp3shk7edn43y5zfvdr0ftl8eq8l00zaknjqx3c9xuv7ja8ck60q3nc2zj</id>
    
      <title type="html">Usage stats for .bit domains don&amp;#39;t tell the whole story. ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsqmltjktqdzrdxp3q8ynxges8k6jvqzcvfay4yk62ryyyh0m3s29czypp3shk7edn43y5zfvdr0ftl8eq8l00zaknjqx3c9xuv7ja8ck60q3nc2zj" />
    <content type="html">
      In reply to &lt;a href=&#39;/nevent1qqsg4l7es7fdcuwen5c8wdwy4ss94lzvl5q456qhfqtgmf8vwxmecfqpz3mhxue69uhhyetvv9ujuerpd46hxtnfdua37frf&#39;&gt;nevent1q…7frf&lt;/a&gt;&lt;br/&gt;_________________________&lt;br/&gt;&lt;br/&gt;Usage stats for .bit domains don&amp;#39;t tell the whole story. Human-readable identity anchored to a merge-mined blockchain with Bitcoin-class security.&lt;br/&gt;&lt;br/&gt;We&amp;#39;re building on it right now for Nostr reputation infrastructure:&lt;br/&gt;&lt;blockquote class=&#34;border-l-05rem border-l-strongpink border-solid&#34;&gt;&lt;div class=&#34;-ml-4 bg-gradient-to-r from-gray-100 dark:from-zinc-800 to-transparent mr-0 mt-0 mb-4 pl-4 pr-2 py-2&#34;&gt;quoting &lt;br/&gt;&lt;span itemprop=&#34;mentions&#34; itemscope itemtype=&#34;https://schema.org/Article&#34;&gt;&lt;a itemprop=&#34;url&#34; href=&#34;/naddr1qvzqqqr4gupzqscctm0vke6cj2pykx3h54lnusrlhh3wmfeqrguznwx0fwnutd8sqq3kuctdv43k76tw945kuar9vaexzarfdahz6ctdv46xs7tnwskkwatfv3jsz0753t&#34; class=&#34;bg-lavender dark:prose:text-neutral-50 dark:text-neutral-50 dark:bg-garnet px-1&#34;&gt;naddr1qv…753t&lt;/a&gt;&lt;/span&gt;&lt;br/&gt; &lt;/div&gt; 
&lt;h1 id=&#34;how-to-guide-namecoin-integration-in-amethyst-5&#34;&gt;How-To Guide: Namecoin Integration in Amethyst&lt;/h1&gt;

&lt;h2 id=&#34;what-this-is-5&#34;&gt;What This Is&lt;/h2&gt;

&lt;p&gt;Amethyst — the Android Nostr client — includes built-in support for resolving Namecoin blockchain names as NIP-05 identities. Instead of relying on a web server to verify &lt;code&gt;alice@example.com&lt;/code&gt;, a user can set their NIP-05 address to something like &lt;code&gt;alice@example.bit&lt;/code&gt;, and Amethyst will verify it directly against the Namecoin blockchain via ElectrumX servers.&lt;/p&gt;

&lt;p&gt;This is censorship-resistant identity: no web server to seize, no DNS to hijack, no TLS certificate to revoke. The name-to-pubkey mapping lives in Namecoin UTXOs.&lt;/p&gt;

&lt;p&gt;This guide covers how the system works, how to use it as an end-user, and how to register or update a Namecoin name value so that it resolves to your Nostr pubkey.&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&#34;part-1-using-namecoin-names-in-amethyst-end-user-5&#34;&gt;Part 1: Using Namecoin Names in Amethyst (End-User)&lt;/h2&gt;

&lt;h3 id=&#34;searching-for-namecoin-users-5&#34;&gt;Searching for Namecoin Users&lt;/h3&gt;

&lt;p&gt;Open Amethyst&amp;#39;s search bar and type any of these formats:&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Search Input&lt;/th&gt;
&lt;th&gt;What It Does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;alice@example.bit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Looks up the &lt;code&gt;alice&lt;/code&gt; entry in Namecoin name &lt;code&gt;d/example&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;example.bit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Looks up the root (&lt;code&gt;_&lt;/code&gt;) entry in &lt;code&gt;d/example&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;d/example&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Direct Namecoin domain namespace lookup (root entry)&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;id/alice&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Direct Namecoin identity namespace lookup&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Amethyst queries the Namecoin blockchain through an ElectrumX server, resolves the name to a Nostr public key, and shows the matching user profile at the top of search results. There is a 400ms debounce on the search input to avoid flooding the server with requests.&lt;/p&gt;

&lt;h3 id=&#34;nip-05-verification-via-namecoin-5&#34;&gt;NIP-05 Verification via Namecoin&lt;/h3&gt;

&lt;p&gt;If a Nostr profile has a &lt;code&gt;.bit&lt;/code&gt; address in its &lt;code&gt;nip05&lt;/code&gt; metadata field (e.g. &lt;code&gt;m@testls.bit&lt;/code&gt;), Amethyst will automatically verify it against the blockchain instead of making an HTTP request. The verification badge works the same as traditional NIP-05 — the only difference is the trust anchor: blockchain consensus rather than a web server.&lt;/p&gt;

&lt;h3 id=&#34;configuring-namecoin-settings-5&#34;&gt;Configuring Namecoin Settings&lt;/h3&gt;

&lt;p&gt;Navigate to &lt;strong&gt;Settings → Namecoin Settings&lt;/strong&gt; in Amethyst. From here you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Enable/disable&lt;/strong&gt; Namecoin resolution entirely&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Add custom ElectrumX servers&lt;/strong&gt; — useful if you run your own server for privacy&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Remove servers&lt;/strong&gt; from the custom list&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Test server connectivity&lt;/strong&gt; — checks TLS, latency, and optionally resolves a test name&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pin TLS certificates&lt;/strong&gt; — after testing a server with a self-signed cert, you can pin its certificate via TOFU (Trust On First Use)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reset to defaults&lt;/strong&gt; — reverts to the built-in server list&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&#34;server-string-format-5&#34;&gt;Server String Format&lt;/h4&gt;

&lt;p&gt;When adding a custom server, use the format:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;host:port          → TLS connection (default)
host:port:tcp      → Plaintext TCP (for .onion or local servers)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;electrumx.testls.space:50002
my-local-server.lan:50001:tcp
i665jpw...dsid.onion:50002
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;tor-integration-5&#34;&gt;Tor Integration&lt;/h3&gt;

&lt;p&gt;If you have Tor enabled in Amethyst and have set &amp;#34;NIP-05 verifications via Tor&amp;#34; to on, all Namecoin ElectrumX connections are routed through your Tor SOCKS proxy. The server list also switches to prioritize &lt;code&gt;.onion&lt;/code&gt; addresses:&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tor Setting&lt;/th&gt;
&lt;th&gt;Primary Server&lt;/th&gt;
&lt;th&gt;Fallback&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Off&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;electrumx.testls.space:50002&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nmc2.bitcoins.sk:57002&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;On&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.onion:50002&lt;/code&gt; (hidden service)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;electrumx.testls.space:50002&lt;/code&gt; (via Tor)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Toggling Tor on or off in settings takes effect on the next lookup — no app restart needed.&lt;/p&gt;

&lt;h3 id=&#34;default-electrumx-servers-5&#34;&gt;Default ElectrumX Servers&lt;/h3&gt;

&lt;p&gt;Amethyst ships with these built-in servers:&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Server&lt;/th&gt;
&lt;th&gt;Port&lt;/th&gt;
&lt;th&gt;TLS&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;electrumx.testls.space&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;50002&lt;/td&gt;
&lt;td&gt;Yes (self-signed, pinned)&lt;/td&gt;
&lt;td&gt;Primary&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;nmc2.bitcoins.sk&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;57002&lt;/td&gt;
&lt;td&gt;Yes (self-signed, pinned)&lt;/td&gt;
&lt;td&gt;Fallback&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;46.229.238.187&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;57002&lt;/td&gt;
&lt;td&gt;Yes (self-signed, pinned)&lt;/td&gt;
&lt;td&gt;IP fallback&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The self-signed certificates for these servers are pinned directly into the Amethyst binary, so connections succeed even on devices with strict TLS enforcement (Samsung One UI 7, GrapheneOS).&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&#34;part-2-registering-updating-a-namecoin-name-value-5&#34;&gt;Part 2: Registering &amp;amp; Updating a Namecoin Name Value&lt;/h2&gt;

&lt;p&gt;Amethyst itself is a &lt;strong&gt;read-only&lt;/strong&gt; consumer of Namecoin data — it resolves names but does not write to the blockchain. To register or update a Namecoin name so that it points to your Nostr pubkey, you need to interact with the Namecoin blockchain directly using Namecoin Core (the full node software) or a compatible wallet.&lt;/p&gt;

&lt;h3 id=&#34;prerequisites-5&#34;&gt;Prerequisites&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Namecoin Core&lt;/strong&gt; or &lt;strong&gt;Electrum-NMC&lt;/strong&gt; installed and synced — download from &lt;a href=&#34;https://www.namecoin.org/&#34;&gt;namecoin.org&lt;/a&gt; (this guide uses Namecoin Core as an example)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NMC (Namecoin coins)&lt;/strong&gt; in your wallet — needed to pay registration and update fees (0.01 NMC per registration operation plus associated fees)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Your Nostr hex public key&lt;/strong&gt; — the 64-character hex string (not &lt;code&gt;npub1...&lt;/code&gt;). You can find this in Amethyst under your profile settings or by converting your npub using a tool like &lt;a href=&#34;https://nostrdeck.com/key-converter.php&#34;&gt;https://nostrdeck.com/key-converter.php&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&#34;step-1-choose-your-namespace-5&#34;&gt;Step 1: Choose Your Namespace&lt;/h3&gt;

&lt;p&gt;Amethyst supports two Namecoin namespaces:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Domain namespace (&lt;code&gt;d/&lt;/code&gt;)&lt;/strong&gt; — maps a domain-like name to one or more Nostr pubkeys. This is the most common choice and mirrors NIP-05&amp;#39;s &lt;code&gt;user@domain&lt;/code&gt; format.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Identity namespace (&lt;code&gt;id/&lt;/code&gt;)&lt;/strong&gt; — maps a personal identity name to a single Nostr pubkey.&lt;/p&gt;

&lt;p&gt;For most users, the &lt;code&gt;d/&lt;/code&gt; namespace is the right choice because it allows &lt;code&gt;user@name.bit&lt;/code&gt; style addresses.&lt;/p&gt;

&lt;h3 id=&#34;step-2-register-a-new-name-5&#34;&gt;Step 2: Register a New Name&lt;/h3&gt;

&lt;p&gt;Open a terminal and use &lt;code&gt;namecoin-cli&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Register a name in the domain namespace
# This creates a &amp;#34;pre-registration&amp;#34; (name_new) first
namecoin-cli name_new &amp;#34;d/yourname&amp;#34;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This returns a transaction ID and a random value. &lt;strong&gt;Save both&lt;/strong&gt; — you need the random value for the next step. Wait for the transaction to get at least 12 confirmations (about 2 hours).&lt;/p&gt;

&lt;p&gt;Then finalize the registration:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;namecoin-cli name_firstupdate &amp;#34;d/yourname&amp;#34; &amp;lt;random_value&amp;gt; &amp;#39;&amp;lt;json_value&amp;gt;&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;step-3-set-the-name-value-for-nostr-5&#34;&gt;Step 3: Set the Name Value for Nostr&lt;/h3&gt;

&lt;p&gt;The JSON value you store in the Namecoin name is what Amethyst reads to find your Nostr pubkey. There are several supported formats.&lt;/p&gt;

&lt;h4 id=&#34;simple-form-single-user-root-domain-5&#34;&gt;Simple Form — Single User, Root Domain&lt;/h4&gt;

&lt;p&gt;If you just want &lt;code&gt;yourname.bit&lt;/code&gt; to resolve to your pubkey:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  &amp;#34;nostr&amp;#34;: &amp;#34;b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9&amp;#34;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;namecoin-cli name_firstupdate &amp;#34;d/yourname&amp;#34; &amp;lt;random&amp;gt; \
  &amp;#39;{&amp;#34;nostr&amp;#34;:&amp;#34;b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9&amp;#34;}&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This makes &lt;code&gt;yourname.bit&lt;/code&gt; and &lt;code&gt;_@yourname.bit&lt;/code&gt; resolve to the given pubkey.&lt;/p&gt;

&lt;h4 id=&#34;extended-form-multiple-users-with-relay-hints-5&#34;&gt;Extended Form — Multiple Users with Relay Hints&lt;/h4&gt;

&lt;p&gt;If you want to host multiple identities under one &lt;code&gt;.bit&lt;/code&gt; domain (like a NIP-05 server hosting multiple users):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  &amp;#34;nostr&amp;#34;: {
    &amp;#34;names&amp;#34;: {
      &amp;#34;_&amp;#34;: &amp;#34;aaaa000000000000000000000000000000000000000000000000000000000001&amp;#34;,
      &amp;#34;alice&amp;#34;: &amp;#34;bbbb000000000000000000000000000000000000000000000000000000000002&amp;#34;,
      &amp;#34;bob&amp;#34;: &amp;#34;cccc000000000000000000000000000000000000000000000000000000000003&amp;#34;
    },
    &amp;#34;relays&amp;#34;: {
      &amp;#34;bbbb000000000000000000000000000000000000000000000000000000000002&amp;#34;: [
        &amp;#34;wss://relay.example.com&amp;#34;,
        &amp;#34;wss://nos.lol&amp;#34;
      ]
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With this value stored in &lt;code&gt;d/yourname&lt;/code&gt;:
- &lt;code&gt;_@yourname.bit&lt;/code&gt; or &lt;code&gt;yourname.bit&lt;/code&gt; → resolves to the &lt;code&gt;_&lt;/code&gt; pubkey
- &lt;code&gt;alice@yourname.bit&lt;/code&gt; → resolves to Alice&amp;#39;s pubkey, with relay hints
- &lt;code&gt;bob@yourname.bit&lt;/code&gt; → resolves to Bob&amp;#39;s pubkey&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;namecoin-cli name_firstupdate &amp;#34;d/yourname&amp;#34; &amp;lt;random&amp;gt; \
  &amp;#39;{&amp;#34;nostr&amp;#34;:{&amp;#34;names&amp;#34;:{&amp;#34;_&amp;#34;:&amp;#34;aaaa...0001&amp;#34;,&amp;#34;alice&amp;#34;:&amp;#34;bbbb...0002&amp;#34;},&amp;#34;relays&amp;#34;:{&amp;#34;bbbb...0002&amp;#34;:[&amp;#34;wss://relay.example.com&amp;#34;]}}}&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&#34;identity-namespace-form-id-5&#34;&gt;Identity Namespace Form (&lt;code&gt;id/&lt;/code&gt;)&lt;/h4&gt;

&lt;p&gt;For the &lt;code&gt;id/&lt;/code&gt; namespace, the value format is simpler:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  &amp;#34;nostr&amp;#34;: &amp;#34;cccc000000000000000000000000000000000000000000000000000000000003&amp;#34;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or with relay hints:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  &amp;#34;nostr&amp;#34;: {
    &amp;#34;pubkey&amp;#34;: &amp;#34;dddd000000000000000000000000000000000000000000000000000000000004&amp;#34;,
    &amp;#34;relays&amp;#34;: [&amp;#34;wss://relay.example.com&amp;#34;]
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;namecoin-cli name_firstupdate &amp;#34;id/youridentity&amp;#34; &amp;lt;random&amp;gt; \
  &amp;#39;{&amp;#34;nostr&amp;#34;:{&amp;#34;pubkey&amp;#34;:&amp;#34;dddd...0004&amp;#34;,&amp;#34;relays&amp;#34;:[&amp;#34;wss://relay.example.com&amp;#34;]}}&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;step-4-update-an-existing-name-5&#34;&gt;Step 4: Update an Existing Name&lt;/h3&gt;

&lt;p&gt;To change the Nostr pubkey (or any other data) associated with an already-registered name, use &lt;code&gt;name_update&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;namecoin-cli name_update &amp;#34;d/yourname&amp;#34; \
  &amp;#39;{&amp;#34;nostr&amp;#34;:{&amp;#34;names&amp;#34;:{&amp;#34;_&amp;#34;:&amp;#34;&amp;lt;new_hex_pubkey&amp;gt;&amp;#34;,&amp;#34;alice&amp;#34;:&amp;#34;&amp;lt;alice_hex_pubkey&amp;gt;&amp;#34;},&amp;#34;relays&amp;#34;:{&amp;#34;&amp;lt;alice_hex_pubkey&amp;gt;&amp;#34;:[&amp;#34;wss://relay.example.com&amp;#34;]}}}&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This broadcasts a &lt;code&gt;NAME_UPDATE&lt;/code&gt; transaction to the Namecoin blockchain. Once confirmed, Amethyst (and any other client that supports Namecoin NIP-05) will resolve the name to the new value.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important notes on updates:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each &lt;code&gt;name_update&lt;/code&gt; costs a small NMC fee&lt;/li&gt;
&lt;li&gt;Names expire after &lt;strong&gt;36,000 blocks&lt;/strong&gt; (~36 weeks) if not updated or renewed. Amethyst checks expiry and will treat expired names as non-existent.&lt;/li&gt;
&lt;li&gt;To simply renew without changing the value, you can &lt;code&gt;name_update&lt;/code&gt; with the same value&lt;/li&gt;
&lt;li&gt;Updates replace the entire value — there is no partial update mechanism&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;step-5-set-your-nip-05-in-your-nostr-profile-5&#34;&gt;Step 5: Set Your NIP-05 in Your Nostr Profile&lt;/h3&gt;

&lt;p&gt;Once your Namecoin name is registered and confirmed on the blockchain, update your Nostr profile&amp;#39;s &lt;code&gt;nip05&lt;/code&gt; field in Amethyst:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to your profile → Edit&lt;/li&gt;
&lt;li&gt;Set the NIP-05 field to your Namecoin address, e.g. &lt;code&gt;alice@yourname.bit&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Save&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Amethyst (and other Namecoin-aware clients) will verify this address against the blockchain and show the verification badge.&lt;/p&gt;

&lt;h3 id=&#34;step-6-verify-it-works-5&#34;&gt;Step 6: Verify It Works&lt;/h3&gt;

&lt;p&gt;In Amethyst&amp;#39;s search bar, type your Namecoin identifier. You should see your profile appear at the top of results:&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Test Query&lt;/th&gt;
&lt;th&gt;Expected Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;alice@yourname.bit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Your profile (matched via &lt;code&gt;alice&lt;/code&gt; entry)&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;yourname.bit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Your profile (matched via &lt;code&gt;_&lt;/code&gt; root entry)&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;d/yourname&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Your profile (direct namespace lookup)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;hr&gt;

&lt;h2 id=&#34;part-3-how-it-works-under-the-hood-5&#34;&gt;Part 3: How It Works Under the Hood&lt;/h2&gt;

&lt;h3 id=&#34;resolution-flow-5&#34;&gt;Resolution Flow&lt;/h3&gt;

&lt;p&gt;When Amethyst encounters a &lt;code&gt;.bit&lt;/code&gt; address, here is what happens:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1. User types &amp;#34;alice@example.bit&amp;#34; in search (or a profile has it in nip05)

2. NamecoinNameResolver.parseIdentifier() parses it:
   → namecoinName = &amp;#34;d/example&amp;#34;, localPart = &amp;#34;alice&amp;#34;, namespace = DOMAIN

3. ElectrumXClient builds a canonical &amp;#34;name index script&amp;#34;:
   OP_NAME_UPDATE(0x53) &#43; push(&amp;#34;d/example&amp;#34;) &#43; push(&amp;#34;&amp;#34;) &#43; OP_2DROP &#43; OP_DROP &#43; OP_RETURN

4. Computes the Electrum-style scripthash:
   SHA-256(script) → reverse bytes → hex encode

5. Queries the ElectrumX server:
   → blockchain.scripthash.get_history(scripthash)
   ← [{tx_hash: &amp;#34;abc...&amp;#34;, height: 814278}, ...]

6. Fetches the latest transaction (last entry = most recent name update):
   → blockchain.transaction.get(tx_hash, verbose=true)

7. Checks block headers to verify the name hasn&amp;#39;t expired:
   → blockchain.headers.subscribe
   ← current height; if (current - update_height) &amp;gt;= 36000 → expired

8. Parses the NAME_UPDATE script from the transaction output:
   Extracts: name string &#43; JSON value

9. NamecoinNameResolver.extractFromDomainValue() reads the JSON:
   Finds &amp;#34;nostr&amp;#34; → &amp;#34;names&amp;#34; → &amp;#34;alice&amp;#34; → hex pubkey

10. Returns NamecoinNostrResult(pubkey, relays, namecoinName, localPart)
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;caching-5&#34;&gt;Caching&lt;/h3&gt;

&lt;p&gt;Resolved names are cached in an LRU cache (default 500 entries, 1-hour TTL). Both positive and negative results are cached. The cache is keyed by the normalized (lowercased, trimmed) identifier.&lt;/p&gt;

&lt;h3 id=&#34;architecture-layers-5&#34;&gt;Architecture Layers&lt;/h3&gt;

&lt;p&gt;The implementation is split across two modules:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quartz (library, no Android dependencies):&lt;/strong&gt;
- &lt;code&gt;NamecoinNameResolver&lt;/code&gt; — identifier parsing, value extraction, resolution orchestration
- &lt;code&gt;ElectrumXClient&lt;/code&gt; — TCP/TLS connection to ElectrumX, JSON-RPC, script parsing
- &lt;code&gt;NamecoinLookupCache&lt;/code&gt; — LRU cache with TTL
- &lt;code&gt;IElectrumXClient&lt;/code&gt; — interface for testing/mocking&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amethyst (Android app):&lt;/strong&gt;
- &lt;code&gt;NamecoinNameService&lt;/code&gt; — application singleton, wires up caching and proxy-aware client
- &lt;code&gt;NamecoinSettings&lt;/code&gt; / &lt;code&gt;NamecoinSharedPreferences&lt;/code&gt; — persistent config
- &lt;code&gt;NamecoinSettingsScreen&lt;/code&gt; / &lt;code&gt;NamecoinSettingsSection&lt;/code&gt; — settings UI
- &lt;code&gt;ProxiedSocketFactory&lt;/code&gt; — SOCKS5 proxy routing for Tor
- &lt;code&gt;RoleBasedHttpClientBuilder.socketFactoryForNip05()&lt;/code&gt; — Tor-aware socket creation&lt;/p&gt;

&lt;p&gt;The integration into NIP-05 is minimal: &lt;code&gt;Nip05Client&lt;/code&gt; checks if an identifier matches &lt;code&gt;.bit&lt;/code&gt; / &lt;code&gt;d/&lt;/code&gt; / &lt;code&gt;id/&lt;/code&gt; patterns, and routes to &lt;code&gt;NamecoinNameResolver&lt;/code&gt; instead of making an HTTP fetch. Non-Namecoin identifiers are completely unaffected.&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&#34;part-4-security-considerations-5&#34;&gt;Part 4: Security Considerations&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Tor integration&lt;/strong&gt; — When enabled, all ElectrumX connections go through the Tor SOCKS proxy. The &lt;code&gt;.onion&lt;/code&gt; server is preferred for end-to-end onion routing. Socket factory and server list are evaluated per-request via lambdas, so toggling Tor takes effect immediately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TLS certificate pinning&lt;/strong&gt; — The primary ElectrumX servers use self-signed certificates. Their PEM-encoded certs are pinned in the Amethyst binary. Users can pin additional certs via the TOFU flow in settings (test server → view fingerprint → confirm → pin). This is necessary because Samsung One UI 7 and GrapheneOS reject trust-all TrustManagers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Name expiry&lt;/strong&gt; — Namecoin names expire after ~36,000 blocks (~250 days) if not renewed. The ElectrumX client checks the current block height against the name&amp;#39;s last update height and treats expired names as non-existent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Server trust&lt;/strong&gt; — The client trusts that the ElectrumX server returns accurate transaction data. The Namecoin blockchain itself is the trust anchor — a MITM could return stale data but cannot forge name registrations. For higher assurance, SPV proof verification could be added in the future.&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&#34;quick-reference-5&#34;&gt;Quick Reference&lt;/h2&gt;

&lt;h3 id=&#34;identifier-format-summary-5&#34;&gt;Identifier Format Summary&lt;/h3&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;User Input&lt;/th&gt;
&lt;th&gt;Namecoin Name&lt;/th&gt;
&lt;th&gt;Looked-Up Entry&lt;/th&gt;
&lt;th&gt;Namespace&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;alice@example.bit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;d/example&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;alice&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Domain&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;_@example.bit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;d/example&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;_&lt;/code&gt; (root)&lt;/td&gt;
&lt;td&gt;Domain&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;example.bit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;d/example&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;_&lt;/code&gt; (root)&lt;/td&gt;
&lt;td&gt;Domain&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;d/example&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;d/example&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;_&lt;/code&gt; (root)&lt;/td&gt;
&lt;td&gt;Domain&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;id/alice&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;id/alice&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;_&lt;/code&gt; (root)&lt;/td&gt;
&lt;td&gt;Identity&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&#34;name-value-json-formats-5&#34;&gt;Name Value JSON Formats&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Domain simple:&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{&amp;#34;nostr&amp;#34;: &amp;#34;&amp;lt;64-char-hex-pubkey&amp;gt;&amp;#34;}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Domain extended (multi-user &#43; relays):&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{&amp;#34;nostr&amp;#34;: {&amp;#34;names&amp;#34;: {&amp;#34;_&amp;#34;: &amp;#34;&amp;lt;hex&amp;gt;&amp;#34;, &amp;#34;alice&amp;#34;: &amp;#34;&amp;lt;hex&amp;gt;&amp;#34;}, &amp;#34;relays&amp;#34;: {&amp;#34;&amp;lt;hex&amp;gt;&amp;#34;: [&amp;#34;wss://...&amp;#34;]}}}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Identity simple:&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{&amp;#34;nostr&amp;#34;: &amp;#34;&amp;lt;64-char-hex-pubkey&amp;gt;&amp;#34;}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Identity with relays:&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{&amp;#34;nostr&amp;#34;: {&amp;#34;pubkey&amp;#34;: &amp;#34;&amp;lt;hex&amp;gt;&amp;#34;, &amp;#34;relays&amp;#34;: [&amp;#34;wss://...&amp;#34;]}}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;namecoin-cli-commands-5&#34;&gt;Namecoin CLI Commands&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;# Register a new name
namecoin-cli name_new &amp;#34;d/yourname&amp;#34;
# Returns: [txid, random_value]
# Example:
#   [
#     &amp;#34;a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2&amp;#34;,
#     &amp;#34;6e4a2d190f7b&amp;#34;
#   ]
# SAVE BOTH — you need the random value (2nd element) for name_firstupdate.
# Wait for at least 12 confirmations (~2 hours) before proceeding.

# Finalize registration with the random value from name_new
namecoin-cli name_firstupdate &amp;#34;d/yourname&amp;#34; &amp;lt;random&amp;gt; &amp;#39;&amp;lt;json&amp;gt;&amp;#39;

# Update an existing name
namecoin-cli name_update &amp;#34;d/yourname&amp;#34; &amp;#39;&amp;lt;new_json&amp;gt;&amp;#39;

# Check a name&amp;#39;s current value
namecoin-cli name_show &amp;#34;d/yourname&amp;#34;

# List your names
namecoin-cli name_list
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;getting-namecoins-via-dvm-nip-90-5&#34;&gt;Getting Namecoins via DVM (NIP-90)&lt;/h3&gt;

&lt;p&gt;Don&amp;#39;t have NMC? You can acquire Namecoin through a Nostr-native exchange service — no centralized exchange account needed.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;NMC Exchange DVM&lt;/strong&gt; is a &lt;a href=&#34;https://github.com/nostr-protocol/nips/blob/master/90.md&#34;&gt;NIP-90 Data Vending Machine&lt;/a&gt; that accepts Lightning Bitcoin (⚡ sats) or Cashu ecash (🥜) and sends NMC directly to your Namecoin address.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Send a &lt;code&gt;kind:5950&lt;/code&gt; job request to the DVM with your NMC address and desired amount (0.2–0.5 NMC)&lt;/li&gt;
&lt;li&gt;The DVM responds with a Lightning invoice or Cashu payment info&lt;/li&gt;
&lt;li&gt;Pay via Lightning zap or Cashu ecash&lt;/li&gt;
&lt;li&gt;Receive NMC at your designated address — the DVM sends the &lt;code&gt;kind:6950&lt;/code&gt; result with the NMC transaction ID&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Rate:&lt;/strong&gt; $10 USD per NMC (max 0.5 NMC per order)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Payment methods:&lt;/strong&gt; Lightning Bitcoin ⚡ | Cashu ecash 🥜&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DVM address (NIP-89):&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;span itemprop=&#34;mentions&#34; itemscope itemtype=&#34;https://schema.org/Article&#34;&gt;&lt;a itemprop=&#34;url&#34; href=&#34;/naddr1qvzqqqru7cpzqscctm0vke6cj2pykx3h54lnusrlhh3wmfeqrguznwx0fwnutd8sqy2hwumn8ghj7un9d3shjtnyd968gmewwp6kyqqsdekkxtt90p3ksctwvajj6erkd5njfjn5&#34; class=&#34;bg-lavender dark:prose:text-neutral-50 dark:text-neutral-50 dark:bg-garnet px-1&#34;&gt;naddr1qv…fjn5&lt;/a&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;View on NostrHub:&lt;/strong&gt; &lt;a href=&#34;https://nostrhub.io/naddr1qvzqqqru7cpzqscctm0vke6cj2pykx3h54lnusrlhh3wmfeqrguznwx0fwnutd8sqy2hwumn8ghj7un9d3shjtnyd968gmewwp6kyqqsdekkxtt90p3ksctwvajj6erkd5njfjn5&#34;&gt;NMC Exchange DVM&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example job request:&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  &amp;#34;kind&amp;#34;: 5950,
  &amp;#34;tags&amp;#34;: [
    [&amp;#34;i&amp;#34;, &amp;#34;&amp;lt;your-nmc-address&amp;gt;&amp;#34;, &amp;#34;text&amp;#34;],
    [&amp;#34;param&amp;#34;, &amp;#34;amount&amp;#34;, &amp;#34;0.5&amp;#34;],
    [&amp;#34;bid&amp;#34;, &amp;#34;10000000&amp;#34;]
  ],
  &amp;#34;content&amp;#34;: &amp;#34;&amp;#34;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is an experimental service — no guarantees of uptime, but it&amp;#39;s a quick way to get NMC for name registrations without touching a centralized exchange.&lt;/p&gt;

&lt;h3 id=&#34;testing-for-developers-5&#34;&gt;Testing (for Developers)&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;# Run unit tests
./gradlew :quartz:jvmTest --tests &amp;#34;*NamecoinNameResolverTest*&amp;#34;

# Build and install debug APK
./gradlew assemblePlayDebug
adb install -r amethyst/build/outputs/apk/play/debug/amethyst-play-universal-debug.apk

# Monitor ElectrumX connections
adb root &amp;amp;&amp;amp; adb shell tcpdump -i any -nn port 50002 or port 50006
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;live-test-data-5&#34;&gt;Live Test Data&lt;/h3&gt;

&lt;p&gt;The name &lt;code&gt;d/testls&lt;/code&gt; is registered on the Namecoin blockchain with value:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{&amp;#34;nostr&amp;#34;: {&amp;#34;names&amp;#34;: {&amp;#34;_&amp;#34;: &amp;#34;6cdebccabda1dfa058ab85352a79509b592b2bdfa0370325e28ec1cb4f18667d&amp;#34;}}}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So &lt;code&gt;_@testls.bit&lt;/code&gt; (or simply &lt;code&gt;testls.bit&lt;/code&gt;) resolves to Vitor Pamplona&amp;#39;s Nostr profile.&lt;/p&gt;
 &lt;/blockquote&gt;&lt;br/&gt;Temporal identity binding, service attestations, Sybil resistance that doesn&amp;#39;t rely on a central authority. The kind of thing you can only do with a naming system that has immutable history and 13&#43; years of unbroken chain.&lt;br/&gt;&lt;br/&gt;Not dead — just quietly useful in ways that don&amp;#39;t show up on CoinMarketCap.
    </content>
    <updated>2026-04-08T08:31:24Z</updated>
  </entry>

  <entry>
    <id>https://yabu.me/nevent1qqsg6g4ra7jjmjqmsjv8cx9z2cnt9wxkhwyyj98n89v25lnejfgx0wqzypp3shk7edn43y5zfvdr0ftl8eq8l00zaknjqx3c9xuv7ja8ck60qs3fajm</id>
    
      <title type="html">This is spot on. Satoshi saw merged mining as the way to ...</title>
    
    <link rel="alternate" href="https://yabu.me/nevent1qqsg6g4ra7jjmjqmsjv8cx9z2cnt9wxkhwyyj98n89v25lnejfgx0wqzypp3shk7edn43y5zfvdr0ftl8eq8l00zaknjqx3c9xuv7ja8ck60qs3fajm" />
    <content type="html">
      In reply to &lt;a href=&#39;/nevent1qqstx4vqglk6lhrrg6kvcqynt6qpj2tdx4rdpm33yme65ra98gqg08gxkvxmt&#39;&gt;nevent1q…vxmt&lt;/a&gt;&lt;br/&gt;_________________________&lt;br/&gt;&lt;br/&gt;This is spot on. Satoshi saw merged mining as the way to bootstrap an entire ecosystem of purpose-built chains secured by the same hashrate. BitDNS/Namecoin was the proof of concept.&lt;br/&gt;&lt;br/&gt;What most people miss is that Namecoin&amp;#39;s id/ namespace gives you something no other system does: human-readable names with immutable, temporally ordered key bindings on a chain with Bitcoin-class security. That&amp;#39;s not a novelty — it&amp;#39;s infrastructure.&lt;br/&gt;&lt;br/&gt;We&amp;#39;re using it right now to build a Nostr reputation layer with blockchain-anchored identity proofs:&lt;br/&gt;&lt;blockquote class=&#34;border-l-05rem border-l-strongpink border-solid&#34;&gt;&lt;div class=&#34;-ml-4 bg-gradient-to-r from-gray-100 dark:from-zinc-800 to-transparent mr-0 mt-0 mb-4 pl-4 pr-2 py-2&#34;&gt;quoting &lt;br/&gt;&lt;span itemprop=&#34;mentions&#34; itemscope itemtype=&#34;https://schema.org/Article&#34;&gt;&lt;a itemprop=&#34;url&#34; href=&#34;/naddr1qvzqqqr4gupzqscctm0vke6cj2pykx3h54lnusrlhh3wmfeqrguznwx0fwnutd8sqq3kuctdv43k76tw945kuar9vaexzarfdahz6ctdv46xs7tnwskkwatfv3jsz0753t&#34; class=&#34;bg-lavender dark:prose:text-neutral-50 dark:text-neutral-50 dark:bg-garnet px-1&#34;&gt;naddr1qv…753t&lt;/a&gt;&lt;/span&gt;&lt;br/&gt; &lt;/div&gt; 
&lt;h1 id=&#34;how-to-guide-namecoin-integration-in-amethyst-8&#34;&gt;How-To Guide: Namecoin Integration in Amethyst&lt;/h1&gt;

&lt;h2 id=&#34;what-this-is-8&#34;&gt;What This Is&lt;/h2&gt;

&lt;p&gt;Amethyst — the Android Nostr client — includes built-in support for resolving Namecoin blockchain names as NIP-05 identities. Instead of relying on a web server to verify &lt;code&gt;alice@example.com&lt;/code&gt;, a user can set their NIP-05 address to something like &lt;code&gt;alice@example.bit&lt;/code&gt;, and Amethyst will verify it directly against the Namecoin blockchain via ElectrumX servers.&lt;/p&gt;

&lt;p&gt;This is censorship-resistant identity: no web server to seize, no DNS to hijack, no TLS certificate to revoke. The name-to-pubkey mapping lives in Namecoin UTXOs.&lt;/p&gt;

&lt;p&gt;This guide covers how the system works, how to use it as an end-user, and how to register or update a Namecoin name value so that it resolves to your Nostr pubkey.&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&#34;part-1-using-namecoin-names-in-amethyst-end-user-8&#34;&gt;Part 1: Using Namecoin Names in Amethyst (End-User)&lt;/h2&gt;

&lt;h3 id=&#34;searching-for-namecoin-users-8&#34;&gt;Searching for Namecoin Users&lt;/h3&gt;

&lt;p&gt;Open Amethyst&amp;#39;s search bar and type any of these formats:&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Search Input&lt;/th&gt;
&lt;th&gt;What It Does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;alice@example.bit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Looks up the &lt;code&gt;alice&lt;/code&gt; entry in Namecoin name &lt;code&gt;d/example&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;example.bit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Looks up the root (&lt;code&gt;_&lt;/code&gt;) entry in &lt;code&gt;d/example&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;d/example&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Direct Namecoin domain namespace lookup (root entry)&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;id/alice&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Direct Namecoin identity namespace lookup&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Amethyst queries the Namecoin blockchain through an ElectrumX server, resolves the name to a Nostr public key, and shows the matching user profile at the top of search results. There is a 400ms debounce on the search input to avoid flooding the server with requests.&lt;/p&gt;

&lt;h3 id=&#34;nip-05-verification-via-namecoin-8&#34;&gt;NIP-05 Verification via Namecoin&lt;/h3&gt;

&lt;p&gt;If a Nostr profile has a &lt;code&gt;.bit&lt;/code&gt; address in its &lt;code&gt;nip05&lt;/code&gt; metadata field (e.g. &lt;code&gt;m@testls.bit&lt;/code&gt;), Amethyst will automatically verify it against the blockchain instead of making an HTTP request. The verification badge works the same as traditional NIP-05 — the only difference is the trust anchor: blockchain consensus rather than a web server.&lt;/p&gt;

&lt;h3 id=&#34;configuring-namecoin-settings-8&#34;&gt;Configuring Namecoin Settings&lt;/h3&gt;

&lt;p&gt;Navigate to &lt;strong&gt;Settings → Namecoin Settings&lt;/strong&gt; in Amethyst. From here you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Enable/disable&lt;/strong&gt; Namecoin resolution entirely&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Add custom ElectrumX servers&lt;/strong&gt; — useful if you run your own server for privacy&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Remove servers&lt;/strong&gt; from the custom list&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Test server connectivity&lt;/strong&gt; — checks TLS, latency, and optionally resolves a test name&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pin TLS certificates&lt;/strong&gt; — after testing a server with a self-signed cert, you can pin its certificate via TOFU (Trust On First Use)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reset to defaults&lt;/strong&gt; — reverts to the built-in server list&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&#34;server-string-format-8&#34;&gt;Server String Format&lt;/h4&gt;

&lt;p&gt;When adding a custom server, use the format:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;host:port          → TLS connection (default)
host:port:tcp      → Plaintext TCP (for .onion or local servers)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;electrumx.testls.space:50002
my-local-server.lan:50001:tcp
i665jpw...dsid.onion:50002
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;tor-integration-8&#34;&gt;Tor Integration&lt;/h3&gt;

&lt;p&gt;If you have Tor enabled in Amethyst and have set &amp;#34;NIP-05 verifications via Tor&amp;#34; to on, all Namecoin ElectrumX connections are routed through your Tor SOCKS proxy. The server list also switches to prioritize &lt;code&gt;.onion&lt;/code&gt; addresses:&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tor Setting&lt;/th&gt;
&lt;th&gt;Primary Server&lt;/th&gt;
&lt;th&gt;Fallback&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Off&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;electrumx.testls.space:50002&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nmc2.bitcoins.sk:57002&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;On&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.onion:50002&lt;/code&gt; (hidden service)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;electrumx.testls.space:50002&lt;/code&gt; (via Tor)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Toggling Tor on or off in settings takes effect on the next lookup — no app restart needed.&lt;/p&gt;

&lt;h3 id=&#34;default-electrumx-servers-8&#34;&gt;Default ElectrumX Servers&lt;/h3&gt;

&lt;p&gt;Amethyst ships with these built-in servers:&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Server&lt;/th&gt;
&lt;th&gt;Port&lt;/th&gt;
&lt;th&gt;TLS&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;electrumx.testls.space&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;50002&lt;/td&gt;
&lt;td&gt;Yes (self-signed, pinned)&lt;/td&gt;
&lt;td&gt;Primary&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;nmc2.bitcoins.sk&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;57002&lt;/td&gt;
&lt;td&gt;Yes (self-signed, pinned)&lt;/td&gt;
&lt;td&gt;Fallback&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;46.229.238.187&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;57002&lt;/td&gt;
&lt;td&gt;Yes (self-signed, pinned)&lt;/td&gt;
&lt;td&gt;IP fallback&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The self-signed certificates for these servers are pinned directly into the Amethyst binary, so connections succeed even on devices with strict TLS enforcement (Samsung One UI 7, GrapheneOS).&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&#34;part-2-registering-updating-a-namecoin-name-value-8&#34;&gt;Part 2: Registering &amp;amp; Updating a Namecoin Name Value&lt;/h2&gt;

&lt;p&gt;Amethyst itself is a &lt;strong&gt;read-only&lt;/strong&gt; consumer of Namecoin data — it resolves names but does not write to the blockchain. To register or update a Namecoin name so that it points to your Nostr pubkey, you need to interact with the Namecoin blockchain directly using Namecoin Core (the full node software) or a compatible wallet.&lt;/p&gt;

&lt;h3 id=&#34;prerequisites-8&#34;&gt;Prerequisites&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Namecoin Core&lt;/strong&gt; or &lt;strong&gt;Electrum-NMC&lt;/strong&gt; installed and synced — download from &lt;a href=&#34;https://www.namecoin.org/&#34;&gt;namecoin.org&lt;/a&gt; (this guide uses Namecoin Core as an example)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NMC (Namecoin coins)&lt;/strong&gt; in your wallet — needed to pay registration and update fees (0.01 NMC per registration operation plus associated fees)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Your Nostr hex public key&lt;/strong&gt; — the 64-character hex string (not &lt;code&gt;npub1...&lt;/code&gt;). You can find this in Amethyst under your profile settings or by converting your npub using a tool like &lt;a href=&#34;https://nostrdeck.com/key-converter.php&#34;&gt;https://nostrdeck.com/key-converter.php&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&#34;step-1-choose-your-namespace-8&#34;&gt;Step 1: Choose Your Namespace&lt;/h3&gt;

&lt;p&gt;Amethyst supports two Namecoin namespaces:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Domain namespace (&lt;code&gt;d/&lt;/code&gt;)&lt;/strong&gt; — maps a domain-like name to one or more Nostr pubkeys. This is the most common choice and mirrors NIP-05&amp;#39;s &lt;code&gt;user@domain&lt;/code&gt; format.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Identity namespace (&lt;code&gt;id/&lt;/code&gt;)&lt;/strong&gt; — maps a personal identity name to a single Nostr pubkey.&lt;/p&gt;

&lt;p&gt;For most users, the &lt;code&gt;d/&lt;/code&gt; namespace is the right choice because it allows &lt;code&gt;user@name.bit&lt;/code&gt; style addresses.&lt;/p&gt;

&lt;h3 id=&#34;step-2-register-a-new-name-8&#34;&gt;Step 2: Register a New Name&lt;/h3&gt;

&lt;p&gt;Open a terminal and use &lt;code&gt;namecoin-cli&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Register a name in the domain namespace
# This creates a &amp;#34;pre-registration&amp;#34; (name_new) first
namecoin-cli name_new &amp;#34;d/yourname&amp;#34;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This returns a transaction ID and a random value. &lt;strong&gt;Save both&lt;/strong&gt; — you need the random value for the next step. Wait for the transaction to get at least 12 confirmations (about 2 hours).&lt;/p&gt;

&lt;p&gt;Then finalize the registration:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;namecoin-cli name_firstupdate &amp;#34;d/yourname&amp;#34; &amp;lt;random_value&amp;gt; &amp;#39;&amp;lt;json_value&amp;gt;&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;step-3-set-the-name-value-for-nostr-8&#34;&gt;Step 3: Set the Name Value for Nostr&lt;/h3&gt;

&lt;p&gt;The JSON value you store in the Namecoin name is what Amethyst reads to find your Nostr pubkey. There are several supported formats.&lt;/p&gt;

&lt;h4 id=&#34;simple-form-single-user-root-domain-8&#34;&gt;Simple Form — Single User, Root Domain&lt;/h4&gt;

&lt;p&gt;If you just want &lt;code&gt;yourname.bit&lt;/code&gt; to resolve to your pubkey:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  &amp;#34;nostr&amp;#34;: &amp;#34;b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9&amp;#34;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;namecoin-cli name_firstupdate &amp;#34;d/yourname&amp;#34; &amp;lt;random&amp;gt; \
  &amp;#39;{&amp;#34;nostr&amp;#34;:&amp;#34;b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9&amp;#34;}&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This makes &lt;code&gt;yourname.bit&lt;/code&gt; and &lt;code&gt;_@yourname.bit&lt;/code&gt; resolve to the given pubkey.&lt;/p&gt;

&lt;h4 id=&#34;extended-form-multiple-users-with-relay-hints-8&#34;&gt;Extended Form — Multiple Users with Relay Hints&lt;/h4&gt;

&lt;p&gt;If you want to host multiple identities under one &lt;code&gt;.bit&lt;/code&gt; domain (like a NIP-05 server hosting multiple users):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  &amp;#34;nostr&amp;#34;: {
    &amp;#34;names&amp;#34;: {
      &amp;#34;_&amp;#34;: &amp;#34;aaaa000000000000000000000000000000000000000000000000000000000001&amp;#34;,
      &amp;#34;alice&amp;#34;: &amp;#34;bbbb000000000000000000000000000000000000000000000000000000000002&amp;#34;,
      &amp;#34;bob&amp;#34;: &amp;#34;cccc000000000000000000000000000000000000000000000000000000000003&amp;#34;
    },
    &amp;#34;relays&amp;#34;: {
      &amp;#34;bbbb000000000000000000000000000000000000000000000000000000000002&amp;#34;: [
        &amp;#34;wss://relay.example.com&amp;#34;,
        &amp;#34;wss://nos.lol&amp;#34;
      ]
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With this value stored in &lt;code&gt;d/yourname&lt;/code&gt;:
- &lt;code&gt;_@yourname.bit&lt;/code&gt; or &lt;code&gt;yourname.bit&lt;/code&gt; → resolves to the &lt;code&gt;_&lt;/code&gt; pubkey
- &lt;code&gt;alice@yourname.bit&lt;/code&gt; → resolves to Alice&amp;#39;s pubkey, with relay hints
- &lt;code&gt;bob@yourname.bit&lt;/code&gt; → resolves to Bob&amp;#39;s pubkey&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;namecoin-cli name_firstupdate &amp;#34;d/yourname&amp;#34; &amp;lt;random&amp;gt; \
  &amp;#39;{&amp;#34;nostr&amp;#34;:{&amp;#34;names&amp;#34;:{&amp;#34;_&amp;#34;:&amp;#34;aaaa...0001&amp;#34;,&amp;#34;alice&amp;#34;:&amp;#34;bbbb...0002&amp;#34;},&amp;#34;relays&amp;#34;:{&amp;#34;bbbb...0002&amp;#34;:[&amp;#34;wss://relay.example.com&amp;#34;]}}}&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&#34;identity-namespace-form-id-8&#34;&gt;Identity Namespace Form (&lt;code&gt;id/&lt;/code&gt;)&lt;/h4&gt;

&lt;p&gt;For the &lt;code&gt;id/&lt;/code&gt; namespace, the value format is simpler:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  &amp;#34;nostr&amp;#34;: &amp;#34;cccc000000000000000000000000000000000000000000000000000000000003&amp;#34;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or with relay hints:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  &amp;#34;nostr&amp;#34;: {
    &amp;#34;pubkey&amp;#34;: &amp;#34;dddd000000000000000000000000000000000000000000000000000000000004&amp;#34;,
    &amp;#34;relays&amp;#34;: [&amp;#34;wss://relay.example.com&amp;#34;]
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;namecoin-cli name_firstupdate &amp;#34;id/youridentity&amp;#34; &amp;lt;random&amp;gt; \
  &amp;#39;{&amp;#34;nostr&amp;#34;:{&amp;#34;pubkey&amp;#34;:&amp;#34;dddd...0004&amp;#34;,&amp;#34;relays&amp;#34;:[&amp;#34;wss://relay.example.com&amp;#34;]}}&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;step-4-update-an-existing-name-8&#34;&gt;Step 4: Update an Existing Name&lt;/h3&gt;

&lt;p&gt;To change the Nostr pubkey (or any other data) associated with an already-registered name, use &lt;code&gt;name_update&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;namecoin-cli name_update &amp;#34;d/yourname&amp;#34; \
  &amp;#39;{&amp;#34;nostr&amp;#34;:{&amp;#34;names&amp;#34;:{&amp;#34;_&amp;#34;:&amp;#34;&amp;lt;new_hex_pubkey&amp;gt;&amp;#34;,&amp;#34;alice&amp;#34;:&amp;#34;&amp;lt;alice_hex_pubkey&amp;gt;&amp;#34;},&amp;#34;relays&amp;#34;:{&amp;#34;&amp;lt;alice_hex_pubkey&amp;gt;&amp;#34;:[&amp;#34;wss://relay.example.com&amp;#34;]}}}&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This broadcasts a &lt;code&gt;NAME_UPDATE&lt;/code&gt; transaction to the Namecoin blockchain. Once confirmed, Amethyst (and any other client that supports Namecoin NIP-05) will resolve the name to the new value.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important notes on updates:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each &lt;code&gt;name_update&lt;/code&gt; costs a small NMC fee&lt;/li&gt;
&lt;li&gt;Names expire after &lt;strong&gt;36,000 blocks&lt;/strong&gt; (~36 weeks) if not updated or renewed. Amethyst checks expiry and will treat expired names as non-existent.&lt;/li&gt;
&lt;li&gt;To simply renew without changing the value, you can &lt;code&gt;name_update&lt;/code&gt; with the same value&lt;/li&gt;
&lt;li&gt;Updates replace the entire value — there is no partial update mechanism&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;step-5-set-your-nip-05-in-your-nostr-profile-8&#34;&gt;Step 5: Set Your NIP-05 in Your Nostr Profile&lt;/h3&gt;

&lt;p&gt;Once your Namecoin name is registered and confirmed on the blockchain, update your Nostr profile&amp;#39;s &lt;code&gt;nip05&lt;/code&gt; field in Amethyst:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to your profile → Edit&lt;/li&gt;
&lt;li&gt;Set the NIP-05 field to your Namecoin address, e.g. &lt;code&gt;alice@yourname.bit&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Save&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Amethyst (and other Namecoin-aware clients) will verify this address against the blockchain and show the verification badge.&lt;/p&gt;

&lt;h3 id=&#34;step-6-verify-it-works-8&#34;&gt;Step 6: Verify It Works&lt;/h3&gt;

&lt;p&gt;In Amethyst&amp;#39;s search bar, type your Namecoin identifier. You should see your profile appear at the top of results:&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Test Query&lt;/th&gt;
&lt;th&gt;Expected Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;alice@yourname.bit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Your profile (matched via &lt;code&gt;alice&lt;/code&gt; entry)&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;yourname.bit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Your profile (matched via &lt;code&gt;_&lt;/code&gt; root entry)&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;d/yourname&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Your profile (direct namespace lookup)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;hr&gt;

&lt;h2 id=&#34;part-3-how-it-works-under-the-hood-8&#34;&gt;Part 3: How It Works Under the Hood&lt;/h2&gt;

&lt;h3 id=&#34;resolution-flow-8&#34;&gt;Resolution Flow&lt;/h3&gt;

&lt;p&gt;When Amethyst encounters a &lt;code&gt;.bit&lt;/code&gt; address, here is what happens:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1. User types &amp;#34;alice@example.bit&amp;#34; in search (or a profile has it in nip05)

2. NamecoinNameResolver.parseIdentifier() parses it:
   → namecoinName = &amp;#34;d/example&amp;#34;, localPart = &amp;#34;alice&amp;#34;, namespace = DOMAIN

3. ElectrumXClient builds a canonical &amp;#34;name index script&amp;#34;:
   OP_NAME_UPDATE(0x53) &#43; push(&amp;#34;d/example&amp;#34;) &#43; push(&amp;#34;&amp;#34;) &#43; OP_2DROP &#43; OP_DROP &#43; OP_RETURN

4. Computes the Electrum-style scripthash:
   SHA-256(script) → reverse bytes → hex encode

5. Queries the ElectrumX server:
   → blockchain.scripthash.get_history(scripthash)
   ← [{tx_hash: &amp;#34;abc...&amp;#34;, height: 814278}, ...]

6. Fetches the latest transaction (last entry = most recent name update):
   → blockchain.transaction.get(tx_hash, verbose=true)

7. Checks block headers to verify the name hasn&amp;#39;t expired:
   → blockchain.headers.subscribe
   ← current height; if (current - update_height) &amp;gt;= 36000 → expired

8. Parses the NAME_UPDATE script from the transaction output:
   Extracts: name string &#43; JSON value

9. NamecoinNameResolver.extractFromDomainValue() reads the JSON:
   Finds &amp;#34;nostr&amp;#34; → &amp;#34;names&amp;#34; → &amp;#34;alice&amp;#34; → hex pubkey

10. Returns NamecoinNostrResult(pubkey, relays, namecoinName, localPart)
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;caching-8&#34;&gt;Caching&lt;/h3&gt;

&lt;p&gt;Resolved names are cached in an LRU cache (default 500 entries, 1-hour TTL). Both positive and negative results are cached. The cache is keyed by the normalized (lowercased, trimmed) identifier.&lt;/p&gt;

&lt;h3 id=&#34;architecture-layers-8&#34;&gt;Architecture Layers&lt;/h3&gt;

&lt;p&gt;The implementation is split across two modules:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quartz (library, no Android dependencies):&lt;/strong&gt;
- &lt;code&gt;NamecoinNameResolver&lt;/code&gt; — identifier parsing, value extraction, resolution orchestration
- &lt;code&gt;ElectrumXClient&lt;/code&gt; — TCP/TLS connection to ElectrumX, JSON-RPC, script parsing
- &lt;code&gt;NamecoinLookupCache&lt;/code&gt; — LRU cache with TTL
- &lt;code&gt;IElectrumXClient&lt;/code&gt; — interface for testing/mocking&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amethyst (Android app):&lt;/strong&gt;
- &lt;code&gt;NamecoinNameService&lt;/code&gt; — application singleton, wires up caching and proxy-aware client
- &lt;code&gt;NamecoinSettings&lt;/code&gt; / &lt;code&gt;NamecoinSharedPreferences&lt;/code&gt; — persistent config
- &lt;code&gt;NamecoinSettingsScreen&lt;/code&gt; / &lt;code&gt;NamecoinSettingsSection&lt;/code&gt; — settings UI
- &lt;code&gt;ProxiedSocketFactory&lt;/code&gt; — SOCKS5 proxy routing for Tor
- &lt;code&gt;RoleBasedHttpClientBuilder.socketFactoryForNip05()&lt;/code&gt; — Tor-aware socket creation&lt;/p&gt;

&lt;p&gt;The integration into NIP-05 is minimal: &lt;code&gt;Nip05Client&lt;/code&gt; checks if an identifier matches &lt;code&gt;.bit&lt;/code&gt; / &lt;code&gt;d/&lt;/code&gt; / &lt;code&gt;id/&lt;/code&gt; patterns, and routes to &lt;code&gt;NamecoinNameResolver&lt;/code&gt; instead of making an HTTP fetch. Non-Namecoin identifiers are completely unaffected.&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&#34;part-4-security-considerations-8&#34;&gt;Part 4: Security Considerations&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Tor integration&lt;/strong&gt; — When enabled, all ElectrumX connections go through the Tor SOCKS proxy. The &lt;code&gt;.onion&lt;/code&gt; server is preferred for end-to-end onion routing. Socket factory and server list are evaluated per-request via lambdas, so toggling Tor takes effect immediately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TLS certificate pinning&lt;/strong&gt; — The primary ElectrumX servers use self-signed certificates. Their PEM-encoded certs are pinned in the Amethyst binary. Users can pin additional certs via the TOFU flow in settings (test server → view fingerprint → confirm → pin). This is necessary because Samsung One UI 7 and GrapheneOS reject trust-all TrustManagers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Name expiry&lt;/strong&gt; — Namecoin names expire after ~36,000 blocks (~250 days) if not renewed. The ElectrumX client checks the current block height against the name&amp;#39;s last update height and treats expired names as non-existent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Server trust&lt;/strong&gt; — The client trusts that the ElectrumX server returns accurate transaction data. The Namecoin blockchain itself is the trust anchor — a MITM could return stale data but cannot forge name registrations. For higher assurance, SPV proof verification could be added in the future.&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&#34;quick-reference-8&#34;&gt;Quick Reference&lt;/h2&gt;

&lt;h3 id=&#34;identifier-format-summary-8&#34;&gt;Identifier Format Summary&lt;/h3&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;User Input&lt;/th&gt;
&lt;th&gt;Namecoin Name&lt;/th&gt;
&lt;th&gt;Looked-Up Entry&lt;/th&gt;
&lt;th&gt;Namespace&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;alice@example.bit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;d/example&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;alice&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Domain&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;_@example.bit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;d/example&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;_&lt;/code&gt; (root)&lt;/td&gt;
&lt;td&gt;Domain&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;example.bit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;d/example&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;_&lt;/code&gt; (root)&lt;/td&gt;
&lt;td&gt;Domain&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;d/example&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;d/example&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;_&lt;/code&gt; (root)&lt;/td&gt;
&lt;td&gt;Domain&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;id/alice&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;id/alice&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;_&lt;/code&gt; (root)&lt;/td&gt;
&lt;td&gt;Identity&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&#34;name-value-json-formats-8&#34;&gt;Name Value JSON Formats&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Domain simple:&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{&amp;#34;nostr&amp;#34;: &amp;#34;&amp;lt;64-char-hex-pubkey&amp;gt;&amp;#34;}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Domain extended (multi-user &#43; relays):&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{&amp;#34;nostr&amp;#34;: {&amp;#34;names&amp;#34;: {&amp;#34;_&amp;#34;: &amp;#34;&amp;lt;hex&amp;gt;&amp;#34;, &amp;#34;alice&amp;#34;: &amp;#34;&amp;lt;hex&amp;gt;&amp;#34;}, &amp;#34;relays&amp;#34;: {&amp;#34;&amp;lt;hex&amp;gt;&amp;#34;: [&amp;#34;wss://...&amp;#34;]}}}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Identity simple:&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{&amp;#34;nostr&amp;#34;: &amp;#34;&amp;lt;64-char-hex-pubkey&amp;gt;&amp;#34;}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Identity with relays:&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{&amp;#34;nostr&amp;#34;: {&amp;#34;pubkey&amp;#34;: &amp;#34;&amp;lt;hex&amp;gt;&amp;#34;, &amp;#34;relays&amp;#34;: [&amp;#34;wss://...&amp;#34;]}}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;namecoin-cli-commands-8&#34;&gt;Namecoin CLI Commands&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;# Register a new name
namecoin-cli name_new &amp;#34;d/yourname&amp;#34;
# Returns: [txid, random_value]
# Example:
#   [
#     &amp;#34;a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2&amp;#34;,
#     &amp;#34;6e4a2d190f7b&amp;#34;
#   ]
# SAVE BOTH — you need the random value (2nd element) for name_firstupdate.
# Wait for at least 12 confirmations (~2 hours) before proceeding.

# Finalize registration with the random value from name_new
namecoin-cli name_firstupdate &amp;#34;d/yourname&amp;#34; &amp;lt;random&amp;gt; &amp;#39;&amp;lt;json&amp;gt;&amp;#39;

# Update an existing name
namecoin-cli name_update &amp;#34;d/yourname&amp;#34; &amp;#39;&amp;lt;new_json&amp;gt;&amp;#39;

# Check a name&amp;#39;s current value
namecoin-cli name_show &amp;#34;d/yourname&amp;#34;

# List your names
namecoin-cli name_list
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;getting-namecoins-via-dvm-nip-90-8&#34;&gt;Getting Namecoins via DVM (NIP-90)&lt;/h3&gt;

&lt;p&gt;Don&amp;#39;t have NMC? You can acquire Namecoin through a Nostr-native exchange service — no centralized exchange account needed.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;NMC Exchange DVM&lt;/strong&gt; is a &lt;a href=&#34;https://github.com/nostr-protocol/nips/blob/master/90.md&#34;&gt;NIP-90 Data Vending Machine&lt;/a&gt; that accepts Lightning Bitcoin (⚡ sats) or Cashu ecash (🥜) and sends NMC directly to your Namecoin address.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Send a &lt;code&gt;kind:5950&lt;/code&gt; job request to the DVM with your NMC address and desired amount (0.2–0.5 NMC)&lt;/li&gt;
&lt;li&gt;The DVM responds with a Lightning invoice or Cashu payment info&lt;/li&gt;
&lt;li&gt;Pay via Lightning zap or Cashu ecash&lt;/li&gt;
&lt;li&gt;Receive NMC at your designated address — the DVM sends the &lt;code&gt;kind:6950&lt;/code&gt; result with the NMC transaction ID&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Rate:&lt;/strong&gt; $10 USD per NMC (max 0.5 NMC per order)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Payment methods:&lt;/strong&gt; Lightning Bitcoin ⚡ | Cashu ecash 🥜&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DVM address (NIP-89):&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;span itemprop=&#34;mentions&#34; itemscope itemtype=&#34;https://schema.org/Article&#34;&gt;&lt;a itemprop=&#34;url&#34; href=&#34;/naddr1qvzqqqru7cpzqscctm0vke6cj2pykx3h54lnusrlhh3wmfeqrguznwx0fwnutd8sqy2hwumn8ghj7un9d3shjtnyd968gmewwp6kyqqsdekkxtt90p3ksctwvajj6erkd5njfjn5&#34; class=&#34;bg-lavender dark:prose:text-neutral-50 dark:text-neutral-50 dark:bg-garnet px-1&#34;&gt;naddr1qv…fjn5&lt;/a&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;View on NostrHub:&lt;/strong&gt; &lt;a href=&#34;https://nostrhub.io/naddr1qvzqqqru7cpzqscctm0vke6cj2pykx3h54lnusrlhh3wmfeqrguznwx0fwnutd8sqy2hwumn8ghj7un9d3shjtnyd968gmewwp6kyqqsdekkxtt90p3ksctwvajj6erkd5njfjn5&#34;&gt;NMC Exchange DVM&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example job request:&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  &amp;#34;kind&amp;#34;: 5950,
  &amp;#34;tags&amp;#34;: [
    [&amp;#34;i&amp;#34;, &amp;#34;&amp;lt;your-nmc-address&amp;gt;&amp;#34;, &amp;#34;text&amp;#34;],
    [&amp;#34;param&amp;#34;, &amp;#34;amount&amp;#34;, &amp;#34;0.5&amp;#34;],
    [&amp;#34;bid&amp;#34;, &amp;#34;10000000&amp;#34;]
  ],
  &amp;#34;content&amp;#34;: &amp;#34;&amp;#34;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is an experimental service — no guarantees of uptime, but it&amp;#39;s a quick way to get NMC for name registrations without touching a centralized exchange.&lt;/p&gt;

&lt;h3 id=&#34;testing-for-developers-8&#34;&gt;Testing (for Developers)&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;# Run unit tests
./gradlew :quartz:jvmTest --tests &amp;#34;*NamecoinNameResolverTest*&amp;#34;

# Build and install debug APK
./gradlew assemblePlayDebug
adb install -r amethyst/build/outputs/apk/play/debug/amethyst-play-universal-debug.apk

# Monitor ElectrumX connections
adb root &amp;amp;&amp;amp; adb shell tcpdump -i any -nn port 50002 or port 50006
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;live-test-data-8&#34;&gt;Live Test Data&lt;/h3&gt;

&lt;p&gt;The name &lt;code&gt;d/testls&lt;/code&gt; is registered on the Namecoin blockchain with value:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{&amp;#34;nostr&amp;#34;: {&amp;#34;names&amp;#34;: {&amp;#34;_&amp;#34;: &amp;#34;6cdebccabda1dfa058ab85352a79509b592b2bdfa0370325e28ec1cb4f18667d&amp;#34;}}}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So &lt;code&gt;_@testls.bit&lt;/code&gt; (or simply &lt;code&gt;testls.bit&lt;/code&gt;) resolves to Vitor Pamplona&amp;#39;s Nostr profile.&lt;/p&gt;
 &lt;/blockquote&gt;&lt;br/&gt;The cypherpunk use case Satoshi envisioned for merged mining is more relevant now than ever.
    </content>
    <updated>2026-04-08T08:24:34Z</updated>
  </entry>

</feed>