Commit Graph

1399 Commits

Author SHA1 Message Date
Vitor Pamplona 143d8c30aa Merge branch 'main' into claude/nip86-relay-management-KuTru 2026-03-27 08:17:23 -04:00
Vitor Pamplona 009b5655f9 Merge branch 'main' into claude/add-negentropy-support-PcTpR 2026-03-27 08:15:24 -04:00
Claude c66d63dbb1 feat: add pinned notes support (NIP-51 kind 10001)
Implement pinned notes using NIP-51 kind 10001 event. This allows users
to pin notes to their profile and view pinned notes on other profiles.

- Rewrite PinListEvent from non-standard kind 33888 to NIP-51 kind 10001
  using e tags and BaseReplaceableEvent
- Add PinListState for reactive pin state management
- Add pin/unpin actions to Account, AccountViewModel, and 3-dot menu
- Add Pinned Notes tab to user profile page
- Add Pinned Notes tab to My Bookmarks screen
- Subscribe to kind 10001 in account metadata and profile relay filters

https://claude.ai/code/session_012GQzb2qcGfAcizC6jqZArD
2026-03-27 03:00:49 +00:00
Vitor Pamplona 75a8e461ad 20x Faster Rfc3986Normalizer and way less objects being created. 2026-03-26 19:04:18 -04:00
Vitor Pamplona 7d6f1a539f Merge branch 'main' of https://github.com/vitorpamplona/amethyst
* 'main' of https://github.com/vitorpamplona/amethyst:
  New Crowdin translations by GitHub Action
  update translations: CZ, DE, PT, SE
  fix: restore local WatchAndDisplayNip05Row in ShowUserSuggestionList
  refactor: remove Namecoin label from search results
  feat: show Namecoin label on .bit search results without ViewModel state
  refactor: remove Namecoin label from search results per review
  refactor: simplify .bit search resolution per review feedback
  feat: resolve bare .bit domains and show Namecoin resolution status in UI
  New Crowdin translations by GitHub Action
  New Crowdin translations by GitHub Action
  refactor: rename trustAllCerts → usePinnedTrustStore
  fix: harden TLS for GrapheneOS and security-conscious Android ROMs
  doc: verify .onion ElectrumX cert via Tor, document pinning
  fix: bypass cert pinning for .onion ElectrumX servers
  feat: TOFU cert pinning for custom ElectrumX servers
  feat: add Test Connection diagnostics to Namecoin settings
  fix: pin ElectrumX server certs instead of trust-all TrustManager

# Conflicts:
#	amethyst/src/main/java/com/vitorpamplona/amethyst/AppModules.kt
#	amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt
2026-03-26 11:34:54 -04:00
Vitor Pamplona 44c39b01ea Defers NIP05 Resolver/NamecoinResolver Builder until needed 2026-03-26 11:07:56 -04:00
Vitor Pamplona 276dc6589c Merge pull request #1937 from mstrofnone/fix/samsung-oneui7-namecoin-tls
fix: pin ElectrumX server certs for Samsung One UI 7 (Android 16) compatibility
2026-03-26 09:14:30 -04:00
Claude 2f8e62fda5 feat: implement NIP-86 Relay Management API
Add quartz protocol package for NIP-86 JSON-RPC relay management with
NIP-98 HTTP authorization, and a management UI accessible from the
relay information screen when the relay advertises NIP-86 support.

Quartz (nip86RelayManagement/):
- Nip86Method: all 21 method constants from the spec
- Nip86Request: serializable JSON-RPC request with factory methods
- Nip86Response: response model with typed result parsing helpers
- Nip86Client: builds NIP-98 auth headers, serializes requests,
  parses responses for each result type (pubkeys, events, kinds, IPs)

Amethyst:
- Nip86Retriever: OkHttp-based HTTP executor for NIP-86 calls
- RelayManagementViewModel: state management for all NIP-86 operations
- RelayManagementScreen: tabbed UI (Pubkeys, Events, Kinds, IPs,
  Settings) with add/remove dialogs, moderation queue, and relay
  settings fields
- Route.RelayManagement added to navigation
- "Manage Relay" button shown in RelayInformationScreen top bar when
  relay's supported_nips includes "86"

https://claude.ai/code/session_01QckCAm1T8pJqqmURBiNtaQ
2026-03-26 04:32:43 +00:00
Claude 70baf55e1c feat: add NIP-77 negentropy sync support
Add support for NIP-77 (Negentropy Syncing) protocol messages using
the negentropy-kmp library for efficient set reconciliation between
client and relay.

New files:
- NegOpenCmd, NegMsgCmd, NegCloseCmd: Client-to-relay commands
- NegMsgMessage, NegErrMessage: Relay-to-client messages
- NegentropySession: Client-side reconciliation orchestrator
- NegentropyServerSession: Server-side reconciliation handler
- NegentropyManager: High-level sync manager with listener callbacks

Updated serializers:
- Jackson MessageSerializer/Deserializer for NEG-MSG, NEG-ERR
- Jackson CommandSerializer/Deserializer for NEG-OPEN, NEG-MSG, NEG-CLOSE
- Kotlin MessageKSerializer/CommandKSerializer for all NIP-77 types

Compatible with strfry relay's negentropy implementation via the
negentropy-kmp library which implements the same Protocol V1 spec.

https://claude.ai/code/session_01Dc6W1G1jURAAR9kzyVvk6g
2026-03-26 04:23:32 +00:00
Vitor Pamplona e43047c027 removes warnings 2026-03-25 18:33:03 -04:00
Vitor Pamplona 452d2accc9 Merge pull request #1948 from vitorpamplona/claude/add-web-bookmarks-qYwpU
feat: implement NIP-B0 Web Bookmarking (kind 39701)
2026-03-25 16:06:09 -04:00
Vitor Pamplona c903996cc2 Merge pull request #1939 from vitorpamplona/claude/nip89-client-tag-LZYhd
feat: NIP-89 client tag on all signed events
2026-03-25 15:42:31 -04:00
M 2e02edc333 refactor: rename trustAllCerts → usePinnedTrustStore
The field no longer means 'trust all certificates' — since the Samsung
One UI 7 fix, it means 'use the pinned trust store (hardcoded +
TOFU-pinned certs + system CAs) instead of system-only trust.'

The old name was actively misleading and could cause a future
contributor to interpret the flag literally, potentially reintroducing
the trust-all pattern that Samsung Knox and GrapheneOS reject.

Renamed across all 4 files:
- ElectrumxServer.kt: field definition + updated KDoc
- ElectrumXClient.kt: createSocket() usage + comments
- NamecoinSettings.kt: parseServerString() usage + comments
- NamecoinSettingsTest.kt: test assertions
2026-03-26 06:33:43 +11:00
Claude cbee188ca5 feat: implement NIP-B0 Web Bookmarking (kind 39701)
Add support for NIP-B0 web bookmarks with a complete protocol
implementation in Quartz and a full UI in Amethyst for adding,
editing, browsing, and deleting web bookmarks.

Quartz:
- WebBookmarkEvent (kind 39701) as an addressable event
- Tag builder/parser extensions for title, published_at, hashtags
- Registered in EventFactory

Amethyst:
- WebBookmarksScreen with FAB to add, and per-card edit/delete/open
- WebBookmarkEditDialog for add/edit with URL, title, description, tags
- WebBookmarkFeedFilter querying addressable notes by kind + pubkey
- Account.sendWebBookmark() and Account.deleteWebBookmark()
- LocalCache.consume() for WebBookmarkEvent
- Drawer navigation entry with Language icon
- Route.WebBookmarks and navigation registration

https://claude.ai/code/session_01UzfLJttwuJzovtb8HX5F9n
2026-03-25 19:29:55 +00:00
M 7f451ee7c7 fix: harden TLS for GrapheneOS and security-conscious Android ROMs
Address compatibility and security issues identified by reviewing
GrapheneOS source (hardened Conscrypt, strict TLS enforcement):

1. .onion: prefer pinned factory, fall back to trust-all

   GrapheneOS patches Conscrypt with stricter TLS enforcement that may
   reject no-op X509TrustManagers even for proxied sockets. The .onion
   server's cert is already in PINNED_ELECTRUMX_CERTS (same operator as
   electrumx.testls.space), so we now use cachedPinnedSslFactory() as
   the primary path. onionSslFactory() (trust-all) is kept as a fallback
   on SSLHandshakeException only — this handles cert rotation or unknown
   .onion servers gracefully.

2. TOFU: require explicit user confirmation before pinning

   Previously, Test Connection auto-pinned every cert on success. An
   attacker performing MITM during first test would get their cert
   permanently trusted. Now each new cert triggers an AlertDialog showing
   the full SHA-256 fingerprint. Users must explicitly accept ('Trust')
   or reject each cert — aligning with GrapheneOS's philosophy of
   explicit trust decisions.

3. Clarify trustAllCerts semantics

   The field name is misleading post-refactor: it now means 'use pinned
   trust store' not 'trust all certificates'. Added TODO to rename to
   usePinnedTrustStore and updated inline comments to prevent future
   misinterpretation.

Note: hostname verification on raw SSLSocket is a pre-existing gap
(not introduced by the Samsung fix PR) — SSLSocket.createSocket() uses
the host parameter for SNI only, not hostname verification. A follow-up
should add endpointIdentificationAlgorithm='HTTPS' or fingerprint-based
verification for pinned certs.
2026-03-26 06:26:18 +11:00
Vitor Pamplona fc560d2752 reuse hex methods. 2026-03-25 13:22:02 -04:00
Vitor Pamplona 0d92c86459 Merge branch 'main' into claude/remove-libsodium-dependency-DjtWa 2026-03-25 11:50:07 -04:00
Vitor Pamplona 9e9f6c3164 Completing the transition from NIP-44 architecture specific tests to commontTest 2026-03-25 11:48:37 -04:00
Vitor Pamplona d84d146981 Merge branch 'main' into claude/remove-libsodium-dependency-DjtWa 2026-03-25 11:24:55 -04:00
Vitor Pamplona 617db3613f Re-enables benchmark with native android ChaCha functions 2026-03-25 11:17:17 -04:00
Vitor Pamplona 60a44d25eb Merge branch 'main' of https://github.com/vitorpamplona/amethyst
* '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
2026-03-25 10:55:12 -04:00
Vitor Pamplona 2ffb920f75 Fixes NIP-46 decoding test 2026-03-25 10:51:31 -04:00
Vitor Pamplona f8baf83146 Merge pull request #1941 from vitorpamplona/claude/implement-hyperloglog-nip45-Jai8I
feat: implement NIP-45 HyperLogLog support
2026-03-25 09:34:35 -04:00
Vitor Pamplona d6541e37c3 merge 2026-03-25 08:37:18 -04:00
Vitor Pamplona 7583f7f8e1 Moves some of the nip-44 based tests to commonTest 2026-03-25 08:33:04 -04:00
Nathan Day 92ae288720 Align attestation tags with latest NIP format 2026-03-25 11:30:29 +00:00
Claude 403351610b feat: implement NIP-45 HyperLogLog for probabilistic event counting
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
2026-03-25 03:43:47 +00:00
Claude 36af9e2346 feat: add NIP-89 client tag to all signed events via NostrSignerWithClientTag decorator
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
2026-03-25 03:24:49 +00:00
M a4953f628d doc: verify .onion ElectrumX cert via Tor, document pinning
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.
2026-03-25 12:13:49 +11:00
M 3afe0c9978 fix: bypass cert pinning for .onion ElectrumX servers
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
2026-03-25 12:10:45 +11:00
M b8b51db0b5 feat: TOFU cert pinning for custom ElectrumX servers
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.
2026-03-25 12:05:05 +11:00
Vitor Pamplona f42881a48e v1.06.3 2026-03-24 20:55:04 -04:00
M 49698de99c feat: add Test Connection diagnostics to Namecoin settings
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.
2026-03-25 11:52:05 +11:00
M 15a2d77a0f fix: pin ElectrumX server certs instead of trust-all TrustManager
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)
2026-03-25 11:41:12 +11:00
Vitor Pamplona 1f2e24bc1f v1.06.2 2026-03-24 19:36:30 -04:00
Vitor Pamplona bc9b6dc912 fixes client tags 2026-03-24 19:24:33 -04:00
Vitor Pamplona 8437a819f8 Merge pull request #1909 from KotlinGeekDev/kmp-completeness
Kmp completeness, part 3 - adios, Swift bridge.
2026-03-24 13:38:44 -04:00
Vitor Pamplona cef07a2460 Fixes single label domains with non ascii chars around them 2026-03-24 13:33:14 -04:00
KotlinGeekDev 349781d9be Use uri-reference-kmp in commonMain. Remove platform-specific implementations. 2026-03-24 16:34:13 +01:00
KotlinGeekDev 2933454fb6 Merge branch 'main' of https://github.com/vitorpamplona/amethyst into upstream-main
# Conflicts:
#	quartz/src/iosMain/kotlin/com/vitorpamplona/quartz/utils/URLs.ios.kt
2026-03-24 16:11:04 +01:00
Vitor Pamplona d6d4bdc5e3 avoids duplicating quote tags by key + value 2026-03-24 09:40:02 -04:00
Vitor Pamplona c39eca5172 Add new utility methods 2026-03-24 09:39:09 -04:00
Vitor Pamplona 8c4b2fe62b Makes sure quotes only happen once in events. 2026-03-24 09:30:07 -04:00
Vitor Pamplona 514e90ff17 Fixes non http uris in the references tag 2026-03-24 09:13:48 -04:00
KotlinGeekDev 4c14554263 Merge branch 'vitorpamplona:main' into kmp-completeness 2026-03-24 13:27:40 +01:00
Claude 425fc24bc2 perf: optimize ChaCha20 and XChaCha20-Poly1305 for speed
ChaCha20Core.chaCha20Xor:
- Parse key/nonce once into initial state, reuse across blocks
- XOR at word level (4 bytes at a time) instead of byte-by-byte
- Reuse working IntArray across blocks instead of allocating per block

XChaCha20Poly1305:
- Add hChaCha20FromNonce24 to avoid nonce copyOfRange(0,16) allocation
- Add chaCha20PolyKey to generate only 32 bytes instead of full 64-byte block
- Use single result array instead of ciphertext + tag concatenation

Benchmark (98-byte padded message, JVM):
  Before: encrypt 2286 ns/op, decrypt 2062 ns/op
  After:  encrypt 1544 ns/op, decrypt 341 ns/op

https://claude.ai/code/session_01YHBwqnb3Z7Q7PX31tJ2G3i
2026-03-24 02:35:30 +00:00
Vitor Pamplona 7874893938 v1.06.1 2026-03-23 18:19:42 -04:00
Vitor Pamplona 51fa28f22a no message 2026-03-23 18:16:24 -04:00
Vitor Pamplona e5aeb49a4b Solves some of the crashes of concurrent modification exception 2026-03-23 17:59:14 -04:00
Claude 7ea5557828 test: fix UrlTest to use 今北産業 as the crash input (PR #1907)
https://claude.ai/code/session_013rJ9iYndYVJgpYK2VazxL2
2026-03-23 21:02:41 +00:00