Adds UI rendering for kind 31922 (CalendarDateSlotEvent) and kind 31923
(CalendarTimeSlotEvent) in the note feed. Each event renders with a header
image, title, date/time range, location, and summary.
* 'main' of https://github.com/vitorpamplona/amethyst:
fix(quartz): connect() returns Unit, caller calls getPublicKey separately
fix(quartz): fix NIP-44 key mutation and NIP-46 connect response handling
feat: add custom ElectrumX server settings for Namecoin resolution
feat: import follow list with Namecoin resolution during signup
Per Amber maintainer: connect never returns a pubkey — response is
"ack" or the secret string. Rewrote ConnectResponse.parse() to check
result/error fields directly on base BunkerResponse (matching Jackson
deserialization). connect() is now a pure protocol handshake; callers
call getPublicKey() separately as a domain concern.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two bugs in quartz's NIP-46 remote signer:
1. FixedKey.getEncoded() returned the raw byte array reference. javax.crypto.Mac
zeroes the key via destroy() after HMAC computation, corrupting the NIP-44
saltPrefix ("nip44-v2") after the first computeConversationKey call. All
subsequent NIP-44 decryptions with different key pairs fail with Invalid Mac.
Fix: return key.copyOf() instead of key.
2. NostrSignerRemote.connect() only handled pubkey responses. Amber (and other
signers) may respond with "ack" or "already connected" error. Added
ConnectResponse parser that maps these to success and falls back to
getPublicKey() to retrieve the actual pubkey.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a 'Namecoin Resolution' section that lets users configure custom
ElectrumX servers for .bit / d/ / id/ name resolution. When custom
servers are configured, they are used EXCLUSIVELY — the hardcoded
public defaults are completely ignored. This gives privacy-conscious
users full control over which servers observe their name lookups.
Server format: host:port (TLS default) or host:port:tcp (plaintext).
Supports .onion addresses for Tor-routed lookups.
New files:
NamecoinSettings.kt
Immutable settings data class with server string parsing/formatting.
NamecoinSharedPreferences.kt
DataStore-backed persistence following the TorSharedPreferences
pattern. Provides a synchronous snapshot for the serverListProvider
lambda and observable StateFlow for the UI.
NamecoinSettingsSection.kt
Compose UI: enable/disable toggle, active server display with
DEFAULT/CUSTOM badge, add/remove servers with validation, reset.
NamecoinSettingsTest.kt
Unit tests for parsing, formatting, round-trips, and edge cases.
Integration:
AppModules.kt — added namecoinPrefs (NamecoinSharedPreferences) and
wired customServersOrNull into the existing serverListProvider so
user-configured servers take priority over the Tor/default logic.
Refactored from an earlier patch to avoid duplicating code already in
main. The quartz-layer ElectrumXClient, NamecoinNameResolver, and
supporting types are reused unchanged.
- Organize zap settings into three clear sections with primary-colored
headers: Quick Zap Amounts, Zap Privacy, and Nostr Wallet Connect
- Replace plain Buttons with InputChip for amount selection — each chip
shows a lightning bolt, the amount, and a close icon to remove it
- Add animateContentSize() to the chips FlowRow so adding/removing
amounts animates smoothly
- Add descriptive sub-text under each section header explaining what
the control does
- NWC section: show an animated "Connected / Not Connected" status badge
(green CheckCircle vs grey RadioButtonUnchecked) that cross-fades via
AnimatedContent when the connection state changes
- NWC section: add animateColorAsState for the status color transition
- Replace the bare icon-only Add button with an OutlinedButton labelled
"Connect Wallet" for better discoverability
- Move the manual pubkey/relay/secret fields into a collapsible
"Advanced" row animated with AnimatedVisibility (expandVertically +
fadeIn/fadeOut). The section auto-expands when a connection already
exists or when a QR/clipboard import populates the pubkey field
- Add 9 new string resources for the new UI copy
https://claude.ai/code/session_01QzBq319fsxhrT91bGxws6N
- UrlDetector: simplify space handler in readDefault() — both branches
of if/else were calling the same readEnd(InvalidUrl), making the
conditional dead code; now we always call readEnd after attempting
to read the domain
- UrlDetector: remove redundant inner buffer.isNotEmpty() check in
readEnd(), already guarded by the outer condition
- UrlDetector: rename processColon() parameter from length to
startLength to eliminate the var length = length self-shadowing
- UrlDetector: replace ArrayList<Url>() with mutableListOf<Url>()
for idiomatic Kotlin
- DomainNameReader: replace lastSection.deleteRange(0, lastSection.length)
with lastSection.clear() which expresses the intent directly
- DomainNameReader: move isDotPercent() and isXn() extension functions
from inside the class body to private file-level functions — extension
functions defined on a class instance are unusual and confusing
https://claude.ai/code/session_01Pci2AC45yQxQw6F6g7jWdd