1. Lock Android to portrait (screenOrientation="portrait" on MainActivity).
Phone-first GRIM-style wallet; no cheap phone/tablet split so the whole
Android app is locked, matching the single phone surface.
2. Enlarge the mobile Home header wordmark: mark 24 to 36 (+50%), "goblin"
text 18 to 26, gap 8 to 9, so the top-left lockup carries the same
visual weight as the 40 to 44px right cluster (owner asked for a
noticeably bigger bump than the first +25% pass).
3. Swap the Pay-screen inline mark for the official GoblinPay lockup: the
black Apple-Pay-style badge on light surfaces, the white wordmark on
dark (theme dark_base split). New img assets from the GoblinPay repo.
4. Plain GoblinPay/receive QR: drop the yellow center-mark overlay from
w::qr_code (mirrors the prior "plain QR default" decision). Test
goblin_receive_qr_decodes updated to the plain render.
Two new Settings pages, each the single home for its feature.
Username (SettingsPage::Username) consolidates everything name-related
off the main Settings and out of the identity card: claim a name if you
have none, release the one you own, and choose the name authority from a
known list OR a free-typed custom server. Reuses the existing claim_ui and
claim/release worker flow; the old inline name-authority editor and the
main-settings claim card are removed (single home).
Advanced Privacy (SettingsPage::AdvancedPrivacy) replaces the lone
"hide amounts" toggle. Notifications section: hide amounts (existing),
hide names, or hide all details (a generic localized private alert that
leaks no name or amount; an empty amount collapses the Android
notification template to just the private line). Anonymous mode: one
toggle that censors STRICTLY the home balance (dots, tap to reveal; the
fiat rate fetch stays off until revealed) and the activity list (dots for
names and amounts, tap a row to reveal and open). Presentation only, with
no money-path or storage change.
Migration: the existing hide_amounts config keeps its exact meaning
(notification amount hiding); the three new fields default off, so no
surprise on upgrade. Covered by a new config test (227 lib tests).
All new strings via t!() in all six locales; drift test green.
Web "Open in Goblin" pay buttons fired generic nostr: URIs, which the
OS routed to whatever social client claims nostr:. Register a dedicated
goblin: scheme and route it (plus nostr: pay URIs) to the prefilled
send-review screen, the same destination as scanning a checkout QR.
Parser (payuri): accept goblin: alongside nostr: (same payload, either
scheme); add is_pay_uri() to tell a payment link from a slatepack.
Runtime: an argv/intent/socket payload that is a pay URI is stashed and
opened by the Goblin surface via SendFlow::from_deeplink, which shares
the exact apply_scan path the camera uses. Desktop cold + warm start
(argv + single-instance socket) and Android cold + warm (intent-filter)
covered.
Registration: Linux .desktop x-scheme-handler/goblin, Android goblin
intent-filter, macOS CFBundleURLTypes, Windows WiX HKCR URL protocol.
Bugfix: the mixnet exit-liveness probe now races two stable targets over two
rounds instead of a single one-shot 1.1.1.1 connect, so a healthy tunnel is no
longer false-condemned and reselected forever. Fixes the intermittent
Connecting to Nym hangs that could take minutes or never resolve (verified:
15/15 cold starts connected, zero hangs).
Also: the Android versionCode/versionName now track the Goblin build number
(were frozen at GRIM's 5 / "0.3.6"), so the OS detects upgrades correctly.
Floonet scoped Nym exit on the money-path relay (dial a relay operator's
co-located exit over a MixnetStream, TLS end to end, no public DNS; anchor +
fallback, never pin-only), NIP-44 v3 gift wraps (G4), mix-DNS, localization,
GUI polish. Verified end to end: two wallets complete a real gift-wrapped Grin
payment over relay.goblin.st, finalized + posted on mainnet.