Implements a pure-Kotlin (commonMain) parser for the BUD-10 blossom: URI
scheme, which allows sharing blob references with discovery hints.
Format: blossom:<sha256>.<ext>[?xs=<server>&as=<pubkey>&sz=<bytes>]
- BlossomUri data class holds sha256, extension, servers (xs), authors (as), size (sz)
- BlossomUri.parse() returns null for non-blossom URIs or invalid SHA-256
- Supports repeated xs/as params (multiple servers and authors)
- Percent-encodes server URLs on serialisation; decodes on parse
- BlossomUri.toUriString() round-trips back to a canonical URI
- Includes commonTest coverage for all parsing cases
https://claude.ai/code/session_01T4jyLbkNWd3f7i6MwsBcD4
- Add contentWarningReason() helper to TagArrayExt and EventExt for reading the reason from existing events
- Add contentWarningDescription state to ShortNotePostViewModel, wired into event building and draft load/save/reset
- Update ContentSensitivityExplainer to accept description state and render an OutlinedTextField for user input
- Pass description state from ShortNotePostScreen to ContentSensitivityExplainer
- Add "Reason (optional)" placeholder string resource
https://claude.ai/code/session_01P2nkYdNiWXiAcfMPTRTVEW
* 'main' of https://github.com/vitorpamplona/amethyst:
New Crowdin translations by GitHub Action
fix: resolve conflicts with upstream PR #1789 merge
fix(desktop): remove noisy debug logs and silence SLF4J warnings
feat(desktop): add bunker heartbeat indicator to sidebar navigation
fix(desktop): verify user pubkey via get_public_key after nostrconnect login
fix(desktop): address code review findings for NIP-46 bunker login
feat(desktop): add nostrconnect:// login flow for QR-based signer pairing
revert: remove QR code scanning from login
feat(desktop): webcam QR scanning via ffmpeg for bunker login
feat(desktop): add webcam QR code scanning for bunker login
feat(desktop): add QR code scanning for bunker login
fix(desktop): clear stored credentials on logout
feat(desktop): update login hints to mention bunker:// option
fix(desktop): simplify settings logout to just a button
feat(desktop): add logout option to menu bar and settings
test: add NIP-46 test suite for desktop, quartz, and fix pre-existing chess test errors
feat(desktop): add NIP-46 remote signer (bunker://) login
The nostrconnect flow was trusting params[0] from the signer's connect
message as the user's pubkey. Some signers (e.g. nsec.app) don't put
the actual user pubkey there, causing all relay subscriptions to query
the wrong identity — contact lists, profiles, and DMs all returned empty.
Now calls remoteSigner.getPublicKey() after the handshake to get the
verified pubkey from the signer. Also stabilizes FeedScreen relay
subscriptions with distinctUntilChanged() and adds relay.primal.net
to defaults.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds client-initiated NIP-46 (nostrconnect://) flow so users can pair
with a remote signer (e.g. Amber) by scanning a QR code instead of
manually copying a bunker:// URI.
Changes:
- Fix RemoteSignerManager to decrypt NIP-44 content before parsing
- Add CoroutineScope to NostrSignerRemote for async event callbacks
- Add loginWithNostrConnect() to AccountManager with 120s timeout
- Add QrCodeCanvas composable using ZXing for QR generation
- Add "Connect" tab to LoginCard showing QR + copyable URI + waiting state
- Wire nostrconnect flow through LoginScreen
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
- 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
* 'main' of https://github.com/vitorpamplona/amethyst: (35 commits)
New Crowdin translations by GitHub Action
fix chess tests
Replace subsequent checks with '!isNullOrEmpty()' call
use forEach: no intermediate list created.
Use filterIsInstance to avoid dual iteration
Lambda argument should be moved out of parentheses
replace null checks with Elvis
merge call chain with flatMap (slight performance improvement)
New Crowdin translations by GitHub Action
New Crowdin translations by GitHub Action
update cz, pt, de, sv
was this meant to be withContext?
add names to boolean params
remove unused imports
Explicit type arguments can be inferred
remove redundant modifiers
correct package name
If-Null return/break/... foldable to '?:'
Declaration has type inferred from a platform call, which can lead to unchecked nullability issues. Specify type explicitly as nullable or non-nullable.
Declaration has type inferred from a platform call, which can lead to unchecked nullability issues. Specify type explicitly as nullable or non-nullable.
...
# Conflicts:
# amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/ReactionsSettingsScreen.kt