# v1.17.0: Cordn, Geocaching, a New QR Scanner, and One UI

Highlights:

- Adds **Cordn** group chats: MLS groups over an MCP coordinator, with the
  full chat experience, device migration and encrypted backups.
- Adds **Geocaching** (NIP-CC): a hub, a map, hunts, and QR-verified finds.
- Rebuilds the **QR scanner** on CameraX + zxing-cpp. It reads off-axis, blurry
  and low-contrast codes the old one could not.
- Brings **Concord** up to spec: pins, Direct Invites, private channels with key
  rotation, disappearing messages, kick and dissolve.
- Brings the **in-app browser** close to an installed Chrome PWA, with a new
  omnibox and a search-engine setting.
- Shows **Ultra HDR** photos, plays **audio posts** as cards with
  picture-in-picture, and shares what you listen to as **Now Playing**.
- Asks before another app's version of your **backed-up lists** drops items.
- Moves ~200 screens into shared UI on the way to **one UI** for Android and
  Desktop.

## New Features

### Cordn

- Adds Cordn group chats to the Messages inbox, beside DMs, Marmot and Concord.
  Messages never enter the event cache, so they are never searchable.
- Builds the chat on the shared components: bubbles, gestures, reactions,
  quoted replies, day and unread dividers, and the rich text renderer.
- Adds replies, reactions, edits, deletions and pins, interoperable with the
  reference client. Pins sit in a one-line carousel above the chat.
- Uses the shared composer: @-mentions, emoji shortcodes, GIF keyboard and paste.
- Adds encrypted attachments over Blossom and encrypted voice notes, with the
  shared upload dialog and media viewer.
- Keeps drafts, unread counts and messages on disk, so rooms no longer open
  empty after a relaunch.
- Redesigns New group as four steps: name, people, coordinator, and who can
  add and remove. Shows how many of your people each coordinator can reach.
- Invites the whole roster in one commit, so one failed invite cannot fork the
  group. People without a key package get a share link instead.
- Finds coordinators from their ContextVM announcements and names them by
  profile, instead of asking for a 64-character key.
- Adds member management: add by name, npub or NIP-05, remove, rename, and admin
  mode. Enforces admin rights like the reference client.
- Adds a metadata-exposure card explaining what each coordinator can learn.
- Shares groups as `cordn1…` links and QR codes, and adds an invitations screen
  with Join and Decline.
- Adds join requests, coordinator health and management, and a key-package
  screen that keeps your pool topped up.
- Adds device migration: the old phone shows a handoff code, the new phone scans
  it and restores every group with its history. Keys are never in the code.
- Adds encrypted backup and restore of groups and their messages.
- Groups all Cordn settings under one entry, and adds Cordn Groups to the drawer
  and the bottom-bar catalog.

### Geocaching (NIP-CC)

- Renders geocache listings and found logs as cards, with a photo hero, map
  inset, rating, distance and badges.
- Adds a Geocaches hub (Nearby, Map, Hunts, Finds, Mine), cache details with
  their log thread, and composers for caches, hunts and logs.
- Verifies a find by scanning the cache's QR code. The secret signs once and is
  never stored.
- Hides hints behind a tap, and detects whether each was written in plaintext
  or ROT13.
- Sorts Nearby by distance only when you ask.
- Opens caches and hunts from feeds, notifications, `naddr` links, QR scans and
  search.

### QR Codes

- Rebuilds the scanner on CameraX + zxing-cpp, with autofocus, tap-to-focus,
  pinch zoom and a torch. The old decoder read 31 of 48 test codes.
- Lets you pick when several codes are in frame or in a picture, and reassembles
  multi-part codes.
- Reads codes from the gallery, the clipboard and the share sheet, and adds a
  "Scan QR code" launcher shortcut.
- Explains a code it cannot open instead of closing, and keeps private keys off
  the result screen and out of the logs.
- Keeps the screen bright while showing your own QR code.

### Concord

- Adds pinned messages, with a pin badge in the channel header and
  jump-to-message.
- Adds Direct Invites: invite by npub, and accept or decline from the hub,
  Notifications or Messages.
- Adds Public and Private community modes. A ban in a Private community rotates
  the keys.
- Adds private channels, with Make private, Make public and Rotate key.
- Adds disappearing messages, with a timer from 1 day to 1 year.
- Adds cooperative Kick and community dissolution.
- Moves the Community List to the fragmented kind 33302, migrating the old list.
- Lets you edit your own thread replies and retract a reaction by tapping it
  again.
- Shows the community description at the top of the channel list.

### Marmot

- Adds editing your own messages, compatible with White Noise edits.
- Detects a group this device has fallen out of sync with, and offers a Reset
  that keeps history.
- Names unnamed groups after their members, and hides names on bubbles in
  two-person groups, like DMs.
- Commits a member's leave automatically when you are an admin.
- Applies White Noise admin deletions.
- Adds Marmot Groups to the drawer, and makes the list read like the DM list.
- Warns when another device of yours is receiving your invites, and offers to
  move them here.

### Buzz

- Brings Buzz to parity with upstream: artifacts, huddle liveness, team catalog,
  projects and thread windows.
- Writes channel messages as kind 9, as Buzz's own clients do, and lets you edit
  them.
- Labels agents as "Agent · managed by Alice", and tells apart members with the
  same name.

### Browser

- Brings the in-app browser close to an installed Chrome PWA: new windows,
  Tor-aware downloads, fullscreen, find in page, text size, desktop site and
  crash recovery.
- Redraws every browser surface with one shared pill.
- Reworks the address field into an omnibox with paste-and-go and completions.
- Adds a search-engine setting: DuckDuckGo, Brave, Startpage, Mojeek, Qwant,
  Ecosia, Kagi, Google or Bing.
- Adds per-site camera, microphone and location permissions, with "Only this
  time".
- Adds "Add to Home screen". Shortcuts open in Amethyst and wait for Tor.
- Shows page alerts and prompts, which used to be silently cancelled.
- Replaces the WebView error page with a readable one, with Try again and Try
  without Tor.
- Asks before every download, with the real name, size and source, and blocks
  files pretending to be another type.

### Media

- Shows Ultra HDR photos in HDR, capped at 2x in the feed.
- Plays audio files in posts as a waveform or cover card, with
  picture-in-picture.
- Shares what you are listening to as a NIP-38 music status, from Amethyst,
  other apps or desktop players. Off by default.
- Adds captions to NIP-71 videos, with a CC toggle in the player.
- Shows video credits, and checks collaborators who accepted.
- Plays divine.video's adaptive HLS streams.
- Adds Cast on Android 17, and names the format a receiver refuses.

### Backups

- Asks before another app's version of your follows, mutes, relays, profile,
  wallets or settings drops items you backed up.
- Shows a card on Home for each conflict, with one-tap Accept.
- Adds a review screen per conflict that lists every removed, added and changed
  entry.
- Keeps open conflicts across restarts, and closes them when the other app puts
  the items back.

### Key Backup

- Shows the nsec as a numbered, grouped grid you can copy onto paper. It hides
  again when the app goes to the background.
- Adds a confirm-then-encrypt flow for the ncryptsec backup.
- Requires passwords of at least 12 characters for new ncryptsecs. Old ones
  still open.
- Accepts hand-typed keys at login, with uppercase letters, spaces or dashes.

### Profiles

- Reads NIP-92 `imeta` for profile pictures and banners, trying the declared
  fallback URLs when the main one fails.
- Shows the banner's blurhash while it loads.
- Publishes an `imeta` for freshly uploaded pictures and banners, on Android and
  Desktop.

### Signing

- Shows a relay login (kind 22242) as a login card in signing prompts, naming
  each relay exactly as signed. Odd-looking addresses get a "check before
  signing" warning.
- Makes the event preview in signing prompts read-only, so you can no longer
  react, zap, vote or RSVP on an event that does not exist yet.

### Notifications

- Shows DMs, Marmot groups and Buzz rooms as Android conversations, with
  per-chat priority and launcher shortcuts.
- Shows inline-reply progress, with a Retry that keeps your text.

### Calendar

- Shows follows' "Going" RSVPs on Home, with a toggle in Settings.
- Adds a "Friends going" lens of upcoming events your list attends.

### Feeds and Lists

- Renders 3D Simple Nostr Objects, shards and cyberspace avatars, with a
  full-screen viewer.
- Opens cyberspace region bags, showing how long the search will take.
- Renders every NIP-51 list kind as a card, instead of encrypted text.
- Adds favorite follow sets: star any follow set to use it as a feed.
- Shows prediction markets and ballots as their own cards, and hides kind-38000
  spam.
- Shows Zapstore app curation sets, NIP-34 git status events and video curation
  lists as cards.
- Shows a compact link preview for pages without an OpenGraph image.
- Shows follow-list petnames as a display-name fallback.
- Adds Cash App, Nano, Revolut, silent payments and BIP-353 payment targets.

### Messages

- Redesigns the Messages list: unread drives emphasis, and previews show @Name or
  "Photo" instead of raw links.
- Redesigns the chat screen: softer bubbles, clock times and the avatar outside
  the bubble.
- Shows sent messages immediately with a sending state, and retries a failed
  send on tap.
- Plays voice messages and encrypted audio in the waveform player.
- Shows a DM rename as "Alice renamed the conversation".

### Uploads

- Falls back through your Blossom servers when an upload fails. The signer is
  asked once.
- Shows why an upload failed, and lets you remove a failed attachment.

### Relays

- Adds an event allow list, roles and claims to relay management (NIP-86).
- Detects when a NIP-29 group has moved to another relay, and supports group
  banners and `a` pins.

### Android

- Enables ARM Memory Tagging on supporting devices to catch native memory bugs.

## Performance

- Loads My Fitness progressively instead of behind a 2–3s spinner.
- Cuts the DEX from 31.1 MB to 29.9 MB by dropping kotlin-reflect.
- Confirms a Marmot group change at the first relay that accepts it, so creating
  a group no longer waits for the slowest relay.
- Stops the Marmot key-package lookup shortly after the first package arrives, so
  adding a member no longer takes most of a minute.
- Stops rewriting the whole Marmot message log and group state on every send.
- Removes a duplicate encryption on every Marmot send.
- Loads cached Blossom images straight from disk, also offline.
- Remembers missing Blossom files for 30s, so videos no longer stall 10s per
  retry.
- Makes the audio visualizer smooth: 46 frames a second instead of 5.
- Speeds up the 3D renderer 4x and cuts its GC from 51% of a core to 7.7%.
- Speeds up the event cache's list observers 1.3–4x.
- Stops calendar screens rescanning the cache on every event.
- Stops the fullscreen image dialog recomposing on every frame of a swipe.
- Stops rebuilding Notifications and Messages on every Concord update.

## Improvements and Bug fixes

- Shows Tor status in the drawer. The icon hides when Tor is off and opens Tor
  settings on tap.
- Fixes devices stuck on "Loading account" forever because they reject the
  AES/GCM/PKCS7Padding cipher.
- Fixes encrypted stores that could write but not read back.
- Moves settings and account data from SharedPreferences to DataStore, and keys
  off the deprecated androidx.security. Old files stay for downgrades.
- Fixes Tor never working on 32-bit ARM and x86 devices, which shipped without
  the Tor library.
- Fixes notifications opening on a black screen after a cold start.
- Opens DM and private reply notifications in their conversation, under the
  right account.
- Fixes kind-5 deletions matching any author: one user could hide another's
  note.
- Decrypts private zaps for the zapped user, showing the real zapper.
- Fixes zap goals reading only 0% or 100%.
- Saves Cashu counters before using them, so a crash cannot lock funds at the
  mint.
- Keeps proof-of-work posts mining in the background, and saves the draft first.
- Fetches your own profile and lists from inbox relays when you have no write
  relays.
- Fits subscriptions under a relay's filter cap instead of losing the whole REQ.
- Keeps a subscription alive when a relay refuses one kind by name.
- Splits large profile requests, so relays that cap results do not leave authors
  unnamed.
- Fixes quoted notes stuck on "Loading quoted note...".
- Sends calendar RSVPs to the host's and every invitee's inbox relays.
- Keeps the calendar's view and scroll when you come back to it, and stops
  appointments flickering.
- Fixes Marmot groups forking on relay echoes, simultaneous commits, and
  commits that leave you alone.
- Sends Marmot reactions and deletions inside the group, so White Noise sees
  them.
- Fixes Concord messages being invisible in Accordion and other applesauce
  clients.
- Fixes Concord joins: channels show at once, and failures are reported.
- Keeps a private channel's old keys, so history survives a rotation.
- Lets a banned Concord member return when re-invited after an unban.
- Fixes Direct Invites that never arrived.
- Fixes Buzz Desktop interop: uploads, mentions, profile, and relay refusal
  reasons.
- Shows Buzz Join only to non-members and Leave only to members.
- Keeps browser pages on Tor whenever any surface uses Tor, and fails closed
  when Tor cannot be applied.
- Keeps NIP-07 replies with the page that asked, and holds signing and payments
  from tabs you are not looking at.
- Brings back black browser tabs and restores the page after Android reclaims
  memory.
- Stops deleting a private DM from publishing a public NIP-09.
- Fixes NIP-49 rejecting some valid keys and crashing on very high scrypt costs.
- Plays videos from a local Blossom cache over Tor, and falls back to the server
  when the cache is closed.
- Restores YouTube link previews.
- Stops the keyboard staying up after leaving a text field.
- Keeps the bottom bar on every pinnable tab.
- Returns a tablet rail tap to that tab's root.
- Makes all floating action buttons circular.
- Fixes amounts rounding wrongly, such as 12,500 showing as "12k".
- Fixes "100%%" in relay uptime labels.
- Fixes NWC notifications for wallets on the new NIP-47 extensions spec.
- Shows the bunker's error when a NIP-46 signer refuses.
- Encrypts every private relay entry, including ones other clients left in
  plain text.
- Uses plurals for counts, so Czech and Polish read correctly.
- Fixes two release-only crashes on launch in the minified build.

## Desktop

- Stops offline users being stuck on "Connecting to Tor...": after 10s it offers
  a regular connection.
- Reads now-playing from Linux MPRIS, macOS Spotify and Music, and Windows media
  controls.
- Shows names and avatars for thread replies, and stops holding every note in
  memory.
- Shows the nsec in the hand-copyable grid, and requires 12-character passwords.
- Uses the shared report dialog, which now also mutes the author.
- Renames the AppImage to `amethyst-desktop-<ver>-<arch>.AppImage`.

## Cli

- Adds `amy cordn` for refs, exposure, coordinators, key packages, groups,
  invites, sending, `watch` and `migrate`.
- Adds `amy sno` to validate 3D objects and avatar proof of work.
- Adds `amy cyberspace`, which matches the reference cyberspace-cli.
- Adds `amy concord` pins, invites, private channels, kick, dissolve and timer.
- Adds `amy admin` commands for NIP-86 allow lists, roles and claims.
- Adds `amy relaygroup pin/unpin` and joins from invite links.
- Catches up correctly on Marmot groups after being offline.
- Accepts hand-copied keys in `amy login` and `amy key decrypt`.

## Quartz

- Adds ContextVM (MCP over Nostr) with all 12 CEPs, and the Cordn protocol.
- Moves the MLS engine to `quartz/mls/`, shared by Marmot and Cordn, with
  several RFC 9420 interop fixes.
- Adds NIP-CC geocaching, Simple Nostr Objects, cyberspace region bags and
  Tapestry Decentralized Lists.
- Adds NIP-FE relay commands over HTTP, with a client and a server.
- Adds NIP-67 EOSE completeness hints and a NIP-43 membership engine.
- Follows the latest NIP-29, NIP-47, NIP-51, NIP-86 and NIP-A3.
- Fixes NIP-44 padding above 16 MB and rejects non-canonical lengths.
- Fixes NIP-49 to check the AEAD tag and zero derived keys.
- Fixes NIP-88 rejecting every spec-conformant `polltype` tag.
- Fixes NIP-62 vanish requests for relays without a trailing slash.
- Stops page limits truncating NIP-77 negentropy reconciles.
- Answers a superseded replaceable with `OK false replaced:`.
- Indexes every natural-language tag on Decentralized Lists, so authors and
  subjects become searchable, while skipping URLs and ids. Indexed text drops
  from 105 MB to 75 MB on 1.5M events. Existing databases need
  `reindexFullTextSearch()`.
- Makes local search match a searchable kind only by what it indexes, so local
  and store search agree.
- Adds typed diffs between versions of replaceable events.
- Fixes many tag readers and bounds checks on hostile tags.
- Renames event classes to their NIP names, keeping deprecated aliases.
- Breaking: removes `ForkTag`. Use `experimental.forks.parseForkedAddress`.
- Fixes iOS ConcurrentModificationException crashes in LargeCache.

## Geode

- Serves NIP-FE relay commands over HTTP, with limits, CORS and NIP-98 sign-in.
- Adds NIP-43 membership: members-only writes, invites and roles.

## Build & Documentation

- Enables R8 obfuscation, and publishes mapping files with each release.
- Adds `scripts/retrace.sh` to deobfuscate a crash report in one command.
- Checks at release time that every reflected class survived R8.
- Builds Arti and zxing-cpp reproducibly for all four ABIs.
- Moves 1,906 strings to shared Compose resources.
- Moves the event cache, Account, AccountViewModel and most screens into
  `commons`/`commonsUI`. 204 of 252 screens are now shared.
- Makes `./gradlew test` run every KMP module's JVM tests: 11,690 instead of
  3,567.
- Updates AGP to 9.4.1, Gradle to 9.8.0, Compose Multiplatform to 1.12.1, Ktor
  to 3.6.0, Coil to 3.6.3 and zoomable to 2.16.0.
- Runs Android Lint in its own CI job.
- Bumps `appCode` to 462.

## Contributors

- @npub1gcxzte5zlkncx26j68ez60fzkvtkm9e0vrwdcvsjakxf9mu9qewqlfnj5z
- @npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef
- @npub10npj3gydmv40m70ehemmal6vsdyfl7tewgvz043g54p0x23y0s8qzztl5h
- @npub17u5dneh8qjp43ecfxr6u5e9sjamsmxyuekrg2nlxrrk6nj9rsyrqywt4tp
- atesfurkan

## Translations

- Czech, German, Swedish, and Brazilian Portuguese by @npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef
- Polish by @npub16gjyljum0ksrrm28zzvejydgxwfm7xse98zwc4hlgq8epxeuggushqwyrm
- Hungarian by @npub1dnvslq0vvrs8d603suykc4harv94yglcxwna9sl2xu8grt2afm3qgfh0tp
- Hindi by @npub1ww6huwu3xye6r05n3qkjeq62wds5pq0jswhl7uc59lchc0n0ns4sdtw5e6
- Russian by Anton Zhao
- Slovenian by @npub1qqqqqqz7nhdqz3uuwmzlflxt46lyu7zkuqhcapddhgz66c4ddynswreecw
