Join Nostr
2026-10-11 19:05:22 UTC

amethyst on Nostr: #Amethyst v1.18.0: Amethyst Desktop, Web of Trust, Privacy Lock, and a Deck ...

#Amethyst v1.18.0: Amethyst Desktop, Web of Trust, Privacy Lock, and a Deck

Highlights:

- Ships **Amethyst Desktop**: the desktop app now runs the same screens and navigation as Android, and the legacy desktop app is gone.
- Adds a **Web of Trust** network from your NIP-85 provider. Strangers' DMs go
to New Requests, and Curated notifications and replies leave them out.
- Adds a **Privacy lock** for the whole app, your messages or your wallet,
with biometrics on Android and a password on desktop.
- Adds **Custom feeds** built from people, hashtags, kinds and relays, and an
opt-in **Deck** of columns for wide windows.
- Rewrites **web-app signing prompts** to say what each request does, and
stops one stuck prompt from blocking every later signature.
- Lets you **drag the panes** in wide windows, and opens every chat type
beside its list.
- Redesigns **My Fitness** around weekly goals, with streaks, history and
charts.
- Makes the **Messages toggles** stop loading NIP-04 or NIP-17, instead of
only hiding them.
- Renders **NIP-82 software releases** with their app, release notes, and
downloads for your device first.

## New Features

### Privacy Lock

- Adds a Privacy lock settings screen with three switches, all off by default:
lock the entire app, lock messages, lock the wallet. Plus an idle timeout.
- Unlocks with biometrics or the device credential on Android, and with an
app password on desktop.
- Locks you out for 30 s after five wrong passwords, doubling up to
5 minutes, and keeps the lockout across restarts.
- Asks for the credential before a lock is turned off or its timeout made
longer.
- Hides message text in notifications while the messages or app lock is on,
and guards the secret-key backup behind any lock.
- Locks the Marmot and Cordn group screens, drafts, and the payment and mint
top-up screens too.

### Custom Feeds and Deck

- Adds custom feeds: pick people, hashtags, kinds and relays, minus hidden
people and keywords. They show in the Home feed picker under "Your feeds",
with a manage screen and an editor.
- Adds an opt-in Deck (Settings › App › Deck) for windows 1,200 dp and wider,
in place of the notification panel.
- Makes every Deck column any screen, with its own back stack. Columns can be
added, moved, resized, reset and closed, across up to nine workspaces.
- Adds Deck shortcuts on desktop: Ctrl/Cmd+T, +W, +Shift+PageUp/PageDown,
+Alt+1–9 and +Shift+S, plus a Deck menu on macOS.
- Imports the legacy desktop app's feeds, workspaces and lock settings.

### Web of Trust

- Downloads your NIP-85 rank provider's trust cards into a compact index on
the device, and keeps it current with small, cheap updates.
- Treats people below a minimum trust score as strangers. Their DMs go to New
Requests, Curated notifications drop them (in-app and push, zaps exempt),
and their thread replies start collapsed. Follows always pass.
- Adds a Web of Trust settings screen: the network's size over a histogram of
ranks, a minimum-score slider with a live count, and sync status.
- Sets up Brainstorm's GrapeRank with a guided sign-up, or any NIP-85 provider
by its key and relay.
- Reads rank and follower badges from the index, without a subscription per
profile.
- Shows on a profile whether the person is in your network, with their score
or "You follow them". Tapping it opens the Web of Trust settings.
- Collapses runs of public-chat messages from people outside your network
into one "3 messages from outside your network · Show" row, in NIP-28,
live-stream, ephemeral and relay-group chats.
- Orders people search, mentions and people lists by follows, then trust
score, then everyone else.
- Resumes a cut-off trust network download instead of starting over.
- Lets you copy another person's trust view, or enter a provider key with its
tags as chips, under "Set up by hand".
- Opens the provider's website in Amethyst's browser, signed in with this
account.
- Adds the Brainstorm relay to the default search and indexer relays.

### Signing

- Times out a web-app signing prompt after 120 s. A prompt left behind Home
used to block every later request from every web app.
- Brings a pending prompt back when Amethyst returns to the foreground.
- Shows what each request does: the private message inside a seal, the relay
of a relay login, the method and URL of a NIP-98 request, and the verb, file
and server of a Blossom upload or delete.
- Previews a profile edit as the new profile, with "Changes your bio ·
Removes your lightning address" lines.
- Summarizes follow, mute, deletion and report changes in one line, and shows
reports as report cards.
- Asks before signing a report under the Reasonable trust level, and asks
once, not twice, in Paranoid mode.
- Warns when a prompt has been open a minute or more that the app may have
stopped waiting.
- Fixes Connected Apps for web apps: Forget now forgets an app's decisions, a
new trust level takes effect, and an app no longer shows once per account.
A forgotten app could keep signing logins without a prompt.
- Only the buttons and Back decide a prompt now. A tap beside it no longer
denies silently.
- Removes the 40-requests-per-10-seconds limit on Amethyst's own NIP-46
signer for paired apps, and answers their requests in parallel, so busy
clients are no longer refused. Unpaired keys get 10 requests a minute each,
100 in total, and the rest are dropped unanswered.

### Messages

- Turns NIP-04 or NIP-17 loading, paging and subscriptions off when you turn
its toggle off. With NIP-17 off, its rooms, composer and calls are gone, and
the gift-wrap subscription asks only for what Marmot or Concord still need.
- Brings cached messages back when a protocol is turned on again.
- Pages NIP-17 history one round at a time. A quiet chat offers Keep looking
and Stop instead of walking every gift wrap you ever received, and names the
relays that didn't answer.
- Pages NIP-17 history from your DM relay list only, 500 gift wraps at a time.
- Pages history (messages, notifications, Cashu wallet) only for the account
on screen. With several accounts logged in, a NIP-17 group showed only its
last message.
- Keeps pinned conversations in the list when none of their messages is
loaded yet.
- Opens every chat type beside its list on wide screens: Buzz, Marmot, Cordn,
Concord, relay groups and location channels, like DMs.
- Softens the bubble colors: other people's bubbles are lighter in the light
theme, and your own keep the accent's hue without the neon glare.
- Checks the stock Concord relays for invites every 15 minutes instead of
keeping them open.

### Wide Windows

- Lets you drag the splitters between the drawer and the content, the content
and the notification panel, and a chat list and its chat. Widths are saved
per device.
- Opens a note's menu as a dropdown by its ⋮ button, with keyboard navigation
and submenus, instead of a dialog in the middle of the screen.
- Wraps the composer's tools under the text instead of scrolling them
sideways, with hover tooltips.
- Opens the account switcher as a menu from the docked drawer.
- Scrolls the feed with the mouse wheel over the empty gutters beside it.
- Adds a refresh button to the docked notification panel, and shows today's
counts and the 7-day chart in it.
- Opens the drawer from a tab pager only after a 120 dp swipe or a fast
flick, instead of on the first pixel, and keeps wheel and trackpad scrolls
with the pager.
- Puts Navigate before You in the drawer when there is no bottom bar.

### My Fitness

- Redesigns My Fitness around weekly goals: rings for active minutes, workouts
and active days, plus an optional weekly distance, each "on track" or
"behind pace".
- Adds a goal editor. The default is 150 active minutes a week, the WHO
guideline.
- Adds 12 weeks of weekly active time, a 18-week consistency heatmap with
streaks, your busiest days and times, and the activity mix against the
previous four weeks.
- Fetches your own published workouts, instead of only those another screen
had loaded.
- Stops counting fasting, diet and meditation as active time.

### Composer and Uploads

- Adds a custom-emoji picker to the note, comment, DM and public-chat
composers. It inserts your NIP-30 emoji as `:shortcode:`.
- Makes the image quality slider also set a maximum size: 640, 1280 or
1920 px, then uncompressed. Posts start at 1280 px on phones, now at JPEG
quality 85 instead of 75.
- Resizes photos on Android to exactly that size. A 12 MP photo used to go up
at about 2016 px whatever the setting.
- Previews the first image compressed in the upload dialog, with its size and
dimensions next to the original's. Tap it to compare both full screen at
their real resolution, with zoom; tap again to flip between them.
- Deletes the temporary copies a compression leaves behind when the quality
slider moves on before it finishes.
- Tags music uploads with their `format` (m4a, mp3, …), so other clients
know the `.mp4` Blossom returns is audio.
- Adds imeta (hash, size, type, dimensions, blurhash) to images pasted as
links in the note, comment, public message, classified and new group DM
composers, so readers can lay them out before they load. Links without an
image extension count when their preview is an image.
- Waits up to 3 s for a link just pasted before posting, so its imeta goes
out with the post.
- Fetches a pasted link once for its preview card and its imeta.

### Feeds and Cards

- Renders NIP-82 software releases with the app's icon and name, markdown
release notes and OS chips.
- Groups release downloads by OS, with the best match for this device on top,
and splits pre-releases from the latest release.
- Trusts a release only from the app's publisher or its listed maintainers.
- Opens Zapstore apps instead of an empty group chat. Only group content
follows its `h` tag to a NIP-29 group.
- Loads an app's releases on its own page, even when it is opened from a
link, profile or mention.
- Fills bare app cards with their OSes, license and links, renders app
descriptions like a note body with translation, and groups platform chips
by OS.
- Adds cards for Kanban boards and cards, WalletScrutiny verdicts and Mostro
instance terms.
- Adds a CI status badge and runs sheet, and cover notes, to NIP-34 git PRs,
patches and issues.
- Finds Marmot key packages of White Noise users who publish only the legacy
kind 443, so they can be invited.
- Shows the caption above the reactions on video and file cards.
- Plays an audio-only `.mp4` as audio, with its cover, by reading the file's
track list. Blossom serves every M4A upload as `.mp4` / `video/mp4`, so
these showed a black video box. A music track or podcast whose file is a
real music video plays as video instead of inside the waveform strip.
- Shows the cover, title and player of audio tracks, and the player of audio
headers that carry their file in a `url` tag.

## Performance

- Moves blocking and lock-touching work off `Dispatchers.Default`: external
signer calls, proof-of-work mining, relay health saves, cache scans and
cyberspace bag sweeps. One slow job no longer stalls feeds and relay
verification behind it.

## Improvements and Bug fixes

- Shows each relay's median post, query and first-result times, and a
"Slow N×" chip on a relay that lags the others.
- Hides the broadcast banner once your outbox relays accept a post, instead of
waiting for every relay. It can always be dismissed, and an outbox failure
stays with a Retry.
- Stops a dead outbox relay or a dropped connection from showing a post as
failed.
- Counts every connected relay under a job in the always-on notification, and
says "Connected to N relays" instead of "inbox relays".
- Asks before opening a scanned 64-character hex key as a profile, since it
might be a private key.
- Completes multi-part QR codes from the camera and from images, waits for a
tap when several codes are in view, and keeps zoom and torch when the camera
reopens.
- Fixes the wallet invoice QR being clipped in wide windows.
- Converts GIFs to MP4 in comment, public message, classified and edit
composers, which ignored the switch.
- Fixes uploads of keyboard GIFs and stickers failing with a permission error
after the upload dialog had been open a while.
- Makes text fields in embedded web apps behave as in the browser: Enter
sends, cleared fields stay cleared, chips, paste, maxlength, and Next on
forms.
- Fixes the image zoom animation popping to full size instead of growing from
the thumbnail with its rounded corners.
- Fixes a pasted `nevent` to a music track, or any addressable event, showing
twice in search.
- Shows a reaction notification for a reaction to your reply. It was checked
against the thread root's author.
- Shows nested NIP-22 replies in community feeds.
- Fixes zap splits without a relay being saved so that Amethyst and other
clients read them as weight 0. Old splits still load.
- Counts on-chain and BOLT12 zaps toward your zap income only when you are the
payee, and attaches a BOLT12 zap only to the live activity it names.
- Fixes hashtag feeds asking only the first relay.
- Shows "Messages" in the Messages top bar instead of the Amethyst logo.
- Fixes weekday labels on the notification chart after a daylight-saving
change.
- Opens scanned links written in uppercase, and keeps a split nsec in an
image from being listed piece by piece.
- Reports an LNURL server's error as "service unavailable" with its message.
- Stops a bare word in a relay hint turning into a fake relay.
- Fixes a StackOverflowError on reply cycles in threads, and a link detector
that took 27 s on colon-heavy text.
- Fixes a second reaction with the same emoji missing from the reaction
gallery.
- Keeps a feed's subscription when the app comes back right at the end of its
background grace period.
- Opens a chat when you tap its name next to a community label.
- Fixes a crash on videos with side-loaded captions. They now show as
subtitles, and formats no parser reads are left out.
- Fixes padding under the disappearing bars on My Fitness.
- Fixes the call timer showing blank in Polish, and the web-app profile-edit
prompt not naming the changed fields in Polish.
- Shows errors with a severity icon, a selectable message and the stack trace
behind Details. Messages queue instead of replacing each other.
- Moves the navigation to Navigation 3. Tabs keep their scroll position, and
pinned web apps no longer share one saved screen.

## Desktop

- Runs the shared app: the same screens, navigation shell, login, account
switcher and settings as Android. The legacy desktop app is deleted, and its
accounts, feeds, deck and lock settings are imported.
- Gains what the legacy app lacked: zaps and the reactions row, chess, Git
repositories, calendar RSVPs, post editing, markdown with inline media,
Cordn groups, the audio-room list, and crash reports offered on the next
start.
- Drops the hashtag-spam filter, the WoT badge, the live-now bar, the relay
dashboard, the advanced search and the GIF search.
- Adds a 2560 px step to the image quality slider, and starts posts at
1920 px.
- Keeps phone photos upright: compression applies the EXIF orientation, and
the metadata strip keeps that one tag. Photos stored sideways were uploaded
on their side.
- Strips metadata from photos with two EXIF blocks, as some editors save
them. These were uploaded unstripped, GPS location included.
- Keeps the space for images and GIFs without a declared size while they
load, and caches decoded GIF frames so a GIF shown again isn't downloaded or
decoded again.
- Fixes tall photos spilling over the text and reactions around them.
- Draws QR codes with the shared renderer. Long payloads fall back to a lower
error-correction level instead of crashing.
- Plays video like Android: autoplay muted, pause out of view, resume where it
stopped, Android-style controls and a now-playing bar. Encrypted media plays,
and Tor-routed videos stream through Tor.
- Renders music tracks, podcast episodes, audio tracks, audio headers, voice
messages and audio in posts, which drew nothing before, with a waveform
player that seeks on click. Podcast soundbites and chapters jump there.
- Plays audio linked in posts, including audio-only `.mp4`s, in the audio
player instead of the video engine ("Can't play this video").
- Fits portrait videos, preloads the next videos in a feed, and no longer
blinks to black when one starts.
- Zooms photos and videos from their card to full screen and back.
- Redesigns the now-playing bar with thin sliders and hours in long times, and
keeps its stop button in narrow windows.
- Renders PDFs in notes, with a full-window reader that turns pages with the
arrow keys.
- Shows OS notifications with the same title and text as Android, when
previews are on, and skips muted authors.
- Replaces the bare system error box with a crash window that can send the
report to the developers.
- Uses desktop text sizes, a lighter hover, and a menu bar only on macOS. The
title bar blends into the app on macOS.
- Sizes the drawer's text and rows for the desktop, and keeps the photo
viewer's close button clear of the macOS window buttons.
- Opens a notice instead of crashing on screens the desktop doesn't have yet,
and hides their entry points, such as DM calls and the geocache Map tab.
- Drops the media setting's Wi-Fi choice, where it behaved like Always.
- Keeps the top bar on Scheduled posts when there is no post store, instead
of a blank screen.
- Shows a text reply button on voice notes where recording isn't available.
- Brings a background window forward on the first click without pressing what
is under the pointer, and stops hover while scrolling.
- Fixes the pull-to-refresh indicator staying half-pulled after a mouse-wheel
scroll.
- Opens at a larger size and reopens where you left it, and never saves a
window collapsed to a sliver.
- Names the app "Amethyst" in Linux docks and app switchers.
- Only hands http, https and lightning links to the OS.
- Keeps accounts, drafts and settings in the Flatpak across restarts. Every
Flatpak shipped so far lost them.
- Renames the Flatpak app ID to `com.vitorpamplona.amethyst`, on runtime
26.08. Remove the old `com.vitorpamplona.amethyst.Desktop` bundle and log
in again (see `BUILDING.md`).
- Declares GStreamer as a dependency of the Linux `.deb` and `.rpm`.

## Cli

- Adds `amy notes show`, `thread`, `reply`, `quote`, `react` and `repost`,
plus `delete`, `notifications` and `notes feed --hashtag`, on the app's own
routing, tagging and thread code.
- Adds `amy trust setup`, `status`, `sync`, `check` and `copy` for the Web of
Trust network.
- Reports `relay_errors` from `amy fetch`, and fails with `no_relay_served`
when no relay served the request. It used to exit 0 with `count: 0`.
- Streams `amy fetch --paginate --limit 0` with flat memory, and logs every
REQ with `--verbose`.
- Runs every `amy sync` direction through negentropy.
- Answers AUTH in `amy fetch`.
- Refuses reposts and quotes of NIP-29 group content, and sends group content
only to its host relay.
- Shows a zap's sender only when the zap request proves it, so a spoofed
zapper no longer shows.
- Fails interaction verbs with `read_only` on npub-only accounts, filters
`amy notifications --type` at the relay, and applies deletions by address.
- Trims `notes post` text and rewrites bare npub/note words like the composer.
- Keeps amy's data files owner-only on Windows (NTFS ACLs), without eight
warnings per file.

## Quartz

- Makes `fetchAllPages` hold up on production relays: it learns each relay's
limit, drops repeated events, paces throttled relays, and walks each filter
on its own cursor. Multi-filter walks lost most of their events before.
- Fixes `negentropySync` finishing "clean" on relays that truncate their set,
and makes `fetchByIds` public.
- Returns null from `count` at once on relays without NIP-45.
- Fixes a WebSocket dial race that opened two connections per relay, and
REQs sent while a WebSocket was still opening being dropped silently.
- Breaking: `fetchAllPages` drops `DEFAULT_PAGE_SIZE`; `pageSize` is now an
optional cap. Adds `streamAllPagesFromPoolWithHooks` for walks too large to
hold in memory.
- Keeps a relay's CLOSED or connection message in `PagedFetchResult.message`,
and adds an `onRelayResult` callback to `fetchAllPagesFromPool`.
- Adds NIP-85 trust network sync and a compact index.
- Types the event kinds found by a census of 743 relays: Marmot 443, NIP-34
cover notes and NIP-C1 CI, Mostro, RoboSats, Ditto, Zapstore identity
proofs, Kanban, WalletScrutiny, NIP-4E key transfer, private note storage
and more.
- Completes hint providers on 184 kinds and NIP-50 indexing on 72. Existing
stores need `reindexFullTextSearch()`.
- Adds `RelayUrlNormalizer.normalizeHintOrNull`, a strict parser for relay
hints from other clients.
- Names every tag relationship with an accessor, such as `mentions()`,
`quotedEvents()` and `recipient()`.
- Writes the `a` and `f` tags NIP-82 releases require, and adds NIP-82 version
ordering.
- Verifies Zapstore identity proofs (kind 30509) against an APK signing
certificate (RSA, EC, Ed25519) on JVM and Android.
- Reads NIP-4E draft 10044 keys, which were always empty before, and adds
`EncryptionKeyStore`. Parses NIP-69 bonds as decimals.
- Registers `FeedDefinitionEvent` (31890) and `EncryptionKeyListEvent` (10044)
in `EventFactory`, and indexes an emoji pack's public shortcodes instead of
its encrypted content.
- Breaking: adds abstract `BaseRepostEvent.originalAuthorKeys()` and
`ZapReceiptEventInterface.zappedAddresses()`, and `DecoupledCipher` takes an
`EncryptionKeyStore`.
- Shares secp256k1 across every target and one native crypto set across
Apple and Linux, and implements `LargeSoftCache` on iOS.
- Adds a "One-shot Reads" section to `CLIENT.md` (`fetchAll`, `fetchFirst`,
`fetchAllPages`, `count`), switches it to the Maven artifact and the bundled
OkHttp transport, and ships an installable agent skill for projects that
use Quartz (`quartz/agent-skill/`).
- Adds `AudioTrackEvent.title()`, `url()`, `image()` (with `mediaUrl()`,
`coverUrl()`, `displayTitle()`), `AudioHeaderEvent.url()` / `mediaUrl()`,
and a `format` parameter to `MusicTrackEvent.edit`.

## Build & Documentation

- Continues One UI: Navigation 3 with the navigation shell in `commonsUI`,
more screens and ViewModels moved to `commons`/`commonsUI`, a headless
`BaseAccountViewModel` with typed user notices, and feature-based ViewModel
packages.
- Adds plans for iOS and web apps on the shared UI.
- Adds Navigation 3 1.1.2 and Apache PDFBox 3.0.8 (desktop only), both
Apache-2.0, and removes `navigation-compose`.
- Turns on incremental compilation for the KMP modules: a one-line change in
`commons` rebuilds in 9.5 s instead of 38.6 s.
- Builds zxing-cpp reproducibly from any NDK path, from a pinned commit.
- Requires a human to review the diff and test on a device before an AI
contribution becomes a PR.
- Gives Claude Code and Codex the same rules, skills and pre-push checks:
`AGENTS.md` holds the rules, `.agents/skills` links to `.claude/skills`, and
the checks live in `tools/agent-hooks/`. A new check, run before every push
and in CI, keeps them in sync.
- Cuts the agent skills from 33 to 14, each rewritten against the current
code, so the list fits Codex's skill budget.
- Fixes the Compose string-escaping pre-push check, which never blocked a
push.
- Documents Homebrew as autobumped, and verifies the cask instead of
submitting it.
- Bumps `appCode` to 463.

## Contributors

-
-

## Translations

- Czech, German, Swedish, and Brazilian Portuguese by
- Hindi by
- Hungarian by
- Polish by