* 'main' of https://github.com/vitorpamplona/amethyst:
New Crowdin translations by GitHub Action
New Crowdin translations by GitHub Action
feat: implement NIP-45 HyperLogLog for probabilistic event counting
- Share DesktopHighlightStore and DesktopDraftStore at app level instead
of per-column to fix cross-deck reactivity and draft persistence
- Replace broken clipboard-based highlight creation with
LocalContextMenuRepresentation that piggybacks on Copy to get selected text
- Render highlights as highlight:// links instead of bold/italic markers
- Add collapsible highlights panel in article reader with edit/delete/publish
- Publish highlights to relays as NIP-84 events via HighlightPublishAction
- Add Reads tab (kind 30023) and Highlights tab (kind 9802) to profile
- Rewrite MarkdownToolbar with MarkdownEditorState for selection-aware
toggle, Material icons, and keyboard shortcuts (Cmd+B/I/E/K)
- Wire DraftsScreen "New Draft" button to ArticleEditorScreen navigation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add client-side HyperLogLog support as specified by NIP-45:
- HyperLogLog object with merge, estimate, encode/decode, and
computeOffset for deterministic filter-based offset calculation
- Add hll ByteArray field to CountResult for relay HLL data
- Update CountResultKSerializer to serialize/deserialize hll hex field
- Add queryCountMergedHll extension for multi-relay HLL merging
- 20 unit tests covering HLL operations and serialization round-trips
https://claude.ai/code/session_01CQzygEkwckLCiXzSRPMpBa
Introduces a signer decorator that automatically appends the NIP-89
client tag to every event before signing, ensuring all events carry
client identification without modifying individual event creation sites.
Works transparently with internal, external (NIP-55), and remote (NIP-46) signers.
https://claude.ai/code/session_01WRtuk1ySCfqXzfFrieKsDs
Relay feeds were previously grouped under the generic "Feeds" category
in the top nav bar filter dialog. This adds a dedicated "Relays" group
so users can more easily find their favorite relay feeds.
https://claude.ai/code/session_016gjbPgYRXrQCoY1zKPz5PX
Connected to the .onion hidden service via Tor SOCKS proxy and
confirmed it serves the SAME certificate as electrumx.testls.space:
SHA-256: 53:65:D5:BB:26:19:F5:40:1C:D8:8E:FC:AF:FB:A5:B2:...
The .onion cert is already covered by the first pinned cert entry.
Added comments documenting this relationship and instructions for
fetching .onion certs via Tor for future updates.
The .onion still uses onionSslFactory() (trust-all) as the primary
path — this is correct since Tor provides its own authentication.
The pinned cert serves as defense-in-depth.
Tor hidden services are authenticated by their onion address (the
public key hash), making TLS certificate verification redundant.
The .onion server in TOR_ELECTRUMX_SERVERS was going through
pinnedSslFactory() but its cert isn't in the pinned list (and can't
be fetched without Tor). This would cause .onion connections to fail
with SSLHandshakeException when Tor mode is active.
Fix: .onion addresses now use a dedicated onionSslFactory() with
trust-all, which is safe because:
1. Tor provides end-to-end encryption
2. The onion address IS the server identity proof
3. Samsung Knox trust-all rejection doesn't apply to proxied sockets
When a user adds a custom ElectrumX server and runs Test Connection,
the server's TLS certificate is automatically captured and pinned
(Trust On First Use). This allows custom servers with self-signed
certificates to work on Samsung/Xiaomi/OnePlus devices.
Changes:
- ElectrumXClient: addPinnedCert(), setDynamicCerts() for runtime
cert management; testServer() now captures server cert PEM and
SHA-256 fingerprint from SSL session
- NamecoinSharedPreferences: persist pinned certs to DataStore
- AppModules: load pinned certs on startup, sync to ElectrumXClient
- NamecoinSettings: custom servers always set trustAllCerts=true
(ElectrumX servers almost universally use self-signed certs)
- UI: shows cert fingerprint in test results, auto-pins on success
- ServerTestResult: new serverCertPem + certFingerprint fields
Flow: Add server → Test Connection → cert auto-captured and pinned →
future connections trust that cert even on Samsung Knox devices.
Add per-server connection testing with detailed error reporting:
- Test Connection button tests each ElectrumX server individually
- Shows streaming results: ✅ success with response time, ❌ failure
with human-readable error (TLS handshake failed, connection refused,
timeout, DNS failed, invalid response, etc.)
- Diagnostic card shows: last test timestamp + success count, device
info (manufacturer/model/Android/API), TLS version negotiated
- ElectrumXClient.testServer() method for single-server diagnostics
with TLS version capture from SSL session
This gives users (and bug reporters) immediate visibility into why
Namecoin resolution may be failing silently on their device.
Samsung One UI 7 (Android 16) silently rejects TLS connections that use
a no-op X509TrustManager which accepts all certificates. This breaks
Namecoin resolution on all Samsung devices running One UI 7, including
Galaxy A15 (SM-A156E) and Galaxy S24 Ultra (SM-S938B).
Replace trustAllSslFactory() with pinnedSslFactory() that:
- Pins the actual self-signed certificates of known ElectrumX servers
- Also includes system CA certificates for servers with real certs
- Uses a proper TrustManagerFactory chain that Samsung Knox accepts
Additional OEM compatibility hardening:
- Cache the SSLSocketFactory (avoid expensive rebuild per connection)
- Request TLSv1.2 explicitly (Xiaomi MIUI/HyperOS and OnePlus ColorOS
Conscrypt forks may default to TLS 1.0 for raw socket upgrades)
- Enforce TLSv1.2+ enabled protocols on the SSLSocket
- KeyStore fallback to PKCS12 if default type fails (Xiaomi)
- Defensive try/catch on system CA cert re-insertion (some OEMs return
certs that cannot be added to a new KeyStore)
Tested on Android 16 (API 36) emulator — all ElectrumX servers connect
(hostname, IP-address, factory reuse) and .bit resolution works E2E.
Pinned certs:
- electrumx.testls.space:50002 (expires 2027-05-04)
- nmc2.bitcoins.sk:57002 (expires 2030-10-22)