Files
amethyst/docs/changelog/v1.19.00.md
Claude ca6327af2d chore: remove mentions of nsec.app, which is gone
Test fixtures and doc examples use neutral hosts (relay.signer.example,
relay.nip46.com); comments and plans list the signers that remain.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DgJn7fqMFnv58kvLC1soen
2026-10-20 16:19:56 +00:00

15 KiB

v1.19.0: A New Login, Remote Signers on Android, Wayland, and Marketplace Cards

Highlights:

  • Redesigns the login and sign-up screens around signers: your signer app or a remote signer first, then the key field, on every platform.
  • Adds NIP-46 remote signer login on Android, and makes it work with Opal and other signers that percent-encode their bunker addresses.
  • Opens gift wraps in parallel for remote-signer accounts: a cold start that waited ~85s using a remote signer for DMs now takes ~20s.
  • Gives the desktop first-class key storage: a status card in Key Backup, a password file when there is no system keyring, and an opt-out.
  • Draws natively on Wayland in every Linux release, with the compositor's own title bar where it has one.
  • Compresses videos on desktop through the system's ffmpeg, with the same quality table as Android.
  • Honors relay rate limits: a relay's rate-limited: back-off now holds and re-sends the refused commands instead of losing them.
  • Adds cards for NIP-15 marketplaces, NIP-85 trust assertions, Trusted Lists, decentralized lists and NIP-29 group metadata.

New Features

Login and Sign-up

  • Redesigns the login, sign-up and remote-signer screens on one shared frame: the logo over a soft glow, rounded fields and buttons, Tor settings as a chip, and a brand-and-card split on windows 840 dp and wider.
  • Shows the same order everywhere: the signer app where one is installed, the remote signer wherever it works, then "or", then the key field.
  • Names and draws the installed signer app ("Login with Amber" and its icon), or says "a signer app" when there are several.
  • Lights up Login once a key is typed, and Create Account once there is a name, and puts the terms checkbox at the top, gating every way in.
  • Puts each error right under what it is about: the key field, the password field, the signer app's button or the remote signer's button.
  • Fits the logged-off screens and the remote-signer dialog on small phones, and keeps the Add New Account bar above the form, not over it.
  • Uses white and frosted cards instead of grey for the login, remote-signer, key-storage and Key Backup surfaces.

Remote Signers (NIP-46)

  • Logs in with a NIP-46 remote signer on Android too: paste a bunker:// or show the nostrconnect:// code.
  • Hands the code to a signer app with Open signer, from an in-app menu when several take it, never to Amethyst itself.
  • Shows the code in a large frame ringed by the logo's colors while it waits, with Copy, Open signer and the relays as pills.
  • Lets you pick the relay your signer uses, or one of your inbox relays, when it can't reach the defaults.
  • Uses relay.nip46.com, nrs.primal.net and bucket.coracle.social, the relays Amber and Opal default to, instead of the old single default relay, which stopped answering.
  • Reads percent-encoded bunker addresses, as Opal writes them, and fails with an error instead of spinning forever.
  • Accepts only an answer that carries the code's secret. Anyone who saw the code could reply first and pose as the signer.
  • Resends the same request on a retry, so a signer that queues requests for approval (Amber) no longer asks twice.
  • Waits five minutes for the signer instead of two, and introduces each platform by its own name and icon.
  • Opens gift wraps, seals and drafts up to 8 at a time ahead of the indexer. With Amber over NIP-46, a desktop cold start opened its 118 wraps in ~20 s instead of ~85 s.
  • Tries remote-signer accounts last when decrypting push notifications, so an offline bunker no longer holds every other account's notifications.

Desktop Key Storage

  • Shows where your keys live in a status card at the top of Key Backup, with Try again when the keychain refuses and Unlock when the key file is locked.
  • Keeps keys in a password-protected NIP-49 file (keys.ncryptsec) when the computer has no system keyring, asking for the password once per launch.
  • Adds "Remember my key on this device": turn it off and the key is asked for at each launch.
  • Adds Save keys to take back this run's "Don't save".
  • Stops rewriting the private key to the macOS Keychain on every settings save, which brought the Keychain password prompt back over and over.
  • Fixes view-only, bunker and signer-app logins failing to load after a restart on Windows and Linux.
  • Fixes the Linux OS keyring in release builds (deb, rpm, AppImage and Flatpak), which always fell back to the password file.
  • Treats KWallet's missing item as absent, so a fresh KWallet no longer shows "Keychain error" on every launch.
  • Upgrades a read-only session when you Unlock, Try again or log in again with the nsec.
  • Reports a key the vault could not keep once per run, instead of on every settings save.
  • Keeps the nostrconnect:// secret out of the logs.

Desktop Video Compression

  • Compresses videos through the system's ffmpeg at the quality slider's level, with Android's resolution and bitrate table, HEVC when asked, and H.264 otherwise.
  • Strips video metadata by remuxing the original when it is the one going up, and asks before uploading if the strip fails.
  • Names the picked video and its target on the slider, such as "High · 4K video → 2160p, 8 Mbps".
  • Hides the H.265 and GIF-to-MP4 switches without ffmpeg, showing an install hint instead.
  • Tells you when an encode was discarded for not being smaller.
  • Finds Homebrew and other package-manager installs of ffmpeg when the app is launched from Finder.

Marketplaces (NIP-15)

  • Adds cards for stalls, products, marketplaces, auctions, bids and bid confirmations, which showed as raw JSON or not at all.
  • Shows a product's gallery, price, stock, stall, specs and a Message seller button that drafts a DM with the listing.
  • Shows an auction's starting bid, its start and end with the merchant's extensions, an Upcoming/Live/Ended badge, and its highest bid and bid count.
  • Reads marketplace events leniently (prices as strings, missing ids, tag form auctions from hash21 and mkauction), and keeps other apps' records on the same kinds out.

Trust and List Cards

  • Adds one card for NIP-85 trusted assertions (30382-30385): what it scores, the rank, hops, every other metric as a tile, timestamps as dates, and the provider.
  • Shows a kind 10040's designated providers, with the services each serves.
  • Adds cards for Trusted Lists (30392-30395) with members best first and their scores.
  • Adds cards for decentralized list headers and items (9998/9999, 39998/39999), loading a header's items while it is on screen, with url, tel and email fields as links.
  • Adds a card for NIP-29 group metadata (39000) that opens the group.
  • Renders hashtags, links and people in bookmark lists and sets, and quotes pinned notes instead of printing raw nevent strings.
  • Pages long rosters (3, then 50 per Show more) and caps chip rows with a "+N more" chip, since event authors decide how many tags a card gets.

Feeds and Cards

  • Adds an info button to each feed filter that explains what it shows, and on the Notifications screen, what it does to notifications.
  • Loads the relay lists of people-list members you don't follow, so list feeds, follow packs and All Follows find their notes.
  • Draws live streams with their summary, start time, viewer count, and a Watch recording button over the cover once ended.
  • Shows a classified's location and a Sold badge, a zap goal's end countdown, a calendar event's own time zone, and a long-form article's reading time and topics.
  • Renders every kind as the thread's main note the way the feed does: RSVPs, calendars, lists, chess, live activities and more drew nothing or plain text there.
  • Resolves NIP-30 custom emoji on reaction notification cards, and draws an untagged :shortcode: reaction as text instead of an empty image.
  • Plays Blossom's .mpga audio files and Podcasting 2.0 trailers.
  • Draws a kind 31337 as a music track only when it has a file to play, and leaves the rest (ad-skip data, game state) out of the feeds.

Performance

  • Makes the outbox's delivery state mutable under its lock: a publish cost O(relays²) in copies, ~3,400 ns per relay at 100 relays, now ~150 ns.
  • Makes a screen's subscription invalidation lock-free: 1.1 ns instead of up to 8,300 ns while an update is running.
  • Returns at once when pruning frees a note that is not a zap.

Improvements and Bug fixes

  • Shows a relay that refused a post with a back-off as retrying while the client waits it out.
  • Stops one relay's hang-up during a publish retry from reconnecting the whole relay pool.
  • Fixes acks from different relays being lost, which kept an event in the outbox and re-sent it on every reconnect.
  • Fixes a forged copy of a note getting the real one dropped as its duplicate, and deleting an addressable's old version removing the current one.
  • Downloads the Web of Trust network in ~10 s and 39 MB instead of minutes and 380 MB: it no longer fetches every deletion the provider signed, and learns of retracted cards over NIP-77.
  • Routes the Web of Trust provider's relays like your own: clearnet by default instead of through Tor.
  • Stops a Web of Trust download on mobile data when it is not allowed, keeps it through list updates, and checkpoints it so an interruption loses less.
  • Fixes the zoom animation for images scrolled partly out of the feed or under the bars, and makes GIFs shrink back into their thumbnail.
  • Fixes tapping a quoted reply in a chat scrolling to the wrong message.
  • Stops the like icon crossfading from an empty heart on every scroll.
  • Stops demoting the threads of audio rooms and video playback, which made audio stutter under load.
  • Stops an audio room's service restarting after the app was killed and holding audio focus and a wake lock for a room that was gone.
  • Stops any app from controlling picture-in-picture video playback.
  • Reads timestamps written in milliseconds as seconds, which made goals and live streams end in "54,000 years".
  • Keeps the Git Repositories search's kind:git chip out of the Namecoin and .bit lookups.
  • Gives a room's name width before its label in Messages, so a Cordn group no longer shows only its coordinator.
  • Follows the testls.space ElectrumX port swap for Namecoin.

Desktop

  • Draws natively on Wayland in every Linux package, with the JetBrains Runtime. Set AMETHYST_X11=1 to stay on XWayland.
  • Uses the compositor's title bar on KDE, sway, Hyprland, COSMIC and niri; GNOME keeps the GTK one.
  • Fixes video playback on Windows, which said "Video playback unavailable" in 1.18.0, and on macOS release builds.
  • Keeps the chart library intact in release builds, which ProGuard broke.
  • Lets the .deb install on Ubuntu 22.04, Debian 12 and their derivatives.
  • Fixes .deb and .rpm installs and removals failing on systems without /usr/share/desktop-directories, and upgrades that removed the menu entry.
  • Requires the system libraries and a font in the .rpm, so minimal Fedora and openSUSE installs launch.
  • Renames the Flatpak app ID to com.vitorpamplona.amethyst.Amethyst, so it doesn't share the Android package's listing in Nostr app stores. See BUILDING.md to move your v1.18.0 data.
  • Fixes the Web of Trust download, which never started on desktop, and keeps Cordn's group state on disk.
  • Drops the image viewer's URL tooltip and click-to-copy; Copy URL stays in its menu.
  • Removes the Intel macOS options from the README: only Apple Silicon is built.

Cli

  • Fixes amy 1.18.0's self-contained bundles crashing on every command with NoClassDefFoundError: java/lang/management/ManagementFactory.
  • Lists relays amy fetch --paginate could not page under unpaged_relays, and warns that the result may be partial.
  • Adds retry_after_ms to rejected_by entries.
  • Fetches all of a search such as include:spam on search.brainstorm.world: amy fetch returned 5,000 of 35,578 events, and amy sync none.

Quartz

  • Implements NIP-01 rate-limit back-offs (nostr-protocol/nips#2498): OkMessage and ClosedMessage carry params and retryAfterMs.
  • Holds a relay's refused commands on its connection (RateLimitGate) and re-sends them when the back-off passes, across reconnects and pool changes, with the subscription's current filters.
  • Adds RateLimiter and RateLimitPolicy for relays, with PolicyResult.Rejected.rateLimited.
  • Pages a NIP-50 search with no words to rank, keeps observer: searches on one page, and carries the search on fetchByIds.
  • Re-asks a page cut short inside its boundary second instead of reporting DRAINED.
  • Fixes a decoder hang on short OK, CLOSED and NEG-ERR frames, a truncated JSON object looping, and a field like jE replacing an event's id.
  • Fixes subscribeAsFlow and fetchAsFlow dropping the newest list on a burst.
  • Fixes QuicReader overflowing on a peer-chosen length, and a bad datagram escaping to the crash handler.
  • Reads NIP-15 marketplace events leniently, with isWellFormed(), AuctionData.endsAt() and AuctionBidSummary.
  • Adds AssertionMetric readers, Trusted List accessors and D-list fieldDeclarations(), displayHints() and listImage(), with tel and email field types.
  • Adds TimeUtils.toUnixSeconds for millisecond timestamps.
  • EmojiUrlTag.decode returns null unless both shortcode and url are present.

Geode

  • Adds a [rate_limits] section for events and REQs per client per minute, answering with the NIP-01 back-off and 429 with Retry-After over NIP-FE. Off by default.
  • Counts an IPv6 client by its /64.
  • Caps WebSocket frames at 1 MiB by default; one header could cost 2 GB.

Build & Documentation

  • Fails the desktop release if ProGuard strips a JNI native method, a D-Bus transport or leaves a stale jar signature.
  • Fails the amy build when its runtime lacks a JDK module its jars use.
  • Self-tests the OS keyring on every packaged desktop build in CI.
  • Speeds up .deb post-processing from 156 s to 51 s.
  • Splits the iOS CI jobs and caches the Kotlin/Native toolchain, so they finish under their timeout.
  • Adds tools/desktop-run to run and screenshot the shared UI headless, and asks agents to look at a UI change before calling it done.
  • Clears the build and lint warnings across modules, and removes 125 unused Android strings and 10 unused drawables.
  • Publishes the Flatpak to Orchard.
  • States that issue bounties are not a promise of payment.
  • Bumps appCode to 464.

Contributors

  • @npub1gcxzte5zlkncx26j68ez60fzkvtkm9e0vrwdcvsjakxf9mu9qewqlfnj5z
  • @npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef
  • @npub1gvv9ahktvavf9qjtrgm62le7gplmmchd5usp5wpfhr85hf79kncqj8xchs

Translations

  • Czech, German, Swedish, and Brazilian Portuguese by @npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef
  • Hindi by @npub1ww6huwu3xye6r05n3qkjeq62wds5pq0jswhl7uc59lchc0n0ns4sdtw5e6
  • Hungarian by @npub1dnvslq0vvrs8d603suykc4harv94yglcxwna9sl2xu8grt2afm3qgfh0tp
  • Polish by @npub16gjyljum0ksrrm28zzvejydgxwfm7xse98zwc4hlgq8epxeuggushqwyrm