Goblin now links nym-sdk directly and runs its SOCKS5 client on an
internal tokio runtime exposing 127.0.0.1:1080 — the same loopback seam
the transport already dials. There is no sidecar subprocess and no
bundled/embedded/sideloaded helper binary; the goblin process itself owns
:1080. This mirrors how GRIM links arti/Tor in-process. Verified live: the
mixnet comes up in ~1.4-2s (gateway persisted in ~/.goblin/nym, reused
across launches) and a relay connects in ~2s over it, with no separate
process.
- Cargo.toml: add nym-sdk (path dep on the local nym checkout, which carries
the Android webpki-roots patch) + rustls with the ring feature.
- src/lib.rs: install rustls' ring CryptoProvider at startup. Linking nym-sdk
pulls aws-lc-rs alongside our ring; with two providers present rustls 0.23
won't auto-pick a default and tokio-tungstenite/reqwest panic on the first
TLS handshake. nym uses its own explicit provider, so this only steers our
relay/HTTP TLS.
- src/nym/sidecar.rs: replace the subprocess machinery with an in-process
Socks5MixnetClient (persistent storage; ephemeral fallback) kept alive for
the process lifetime on a dedicated runtime. Drops the binary lookup, embed
extraction, init/launch, and child management.
- build.rs: drop the GOBLIN_NYM_*_BIN embed block (nothing to embed).
- src/nym/{mod,transport}.rs, src/nostr/{mod,avatar}.rs: docs now describe the
in-process client; clear stray "old Tor/arti" wording (no Tor transport code
remains — only grin-core's slatepack OnionV3Address, which is unrelated).
Also: named users now get the pubkey-seeded gradient background with their
initial composited on top (instead of the Grin mark) — gui identicon.rs gains
gradient_bg_svg and widgets.rs gains gradient_letter_avatar; avatar_any routes
named keys to it. Verified live with @nymgoblin.
Ship the bundled nym-socks5-client on Windows and Android, not just Linux:
- sidecar.rs resolves the binary per platform — nym-socks5-client.exe on
Windows; on Android the sidecar rides in the APK jniLibs as
libnym_socks5_client.so and is launched from the native-library dir (the
one exec-allowed path), located via NATIVE_LIBS_DIR.
- Restore a vendored, statically-linked OpenSSL. Upstream Grim got this from
arti's static feature; dropping arti for Nym took it with it, which broke
Android/cross builds (no system OpenSSL for the target) and left desktop
dynamically linked to libssl. Inert on Windows/macOS (SChannel/Security.fw).
- android.sh bundles the sidecar into jniLibs per ABI; scripts/nym-android.sh
cross-builds it. Onboarding copy: Tor -> the Nym mixnet.
Verified end to end on an x86_64 emulator: the sidecar extracts, launches,
initialises, and opens the mixnet SOCKS5 proxy on 127.0.0.1:1080.
Route every relay and HTTP request (nostr relays, NIP-05, price) through
a local nym-socks5-client sidecar on 127.0.0.1:1080, so all traffic
egresses via the 5-hop Nym mixnet and nothing touches the clear net.
- Add src/nym/: SOCKS5 HTTP client (reqwest socks5h), NymWebSocketTransport
for the nostr relay pool (tokio-socks dial + TLS/ws handshake over the
mixnet), and a sidecar launcher that reuses or spawns nym-socks5-client.
- Swap the nostr-sdk transport off ArtiWebSocketTransport; route nip05.rs
and price.rs off Tor; revert the clearnet username-lookup shortcut.
- Remove the embedded arti Tor client wholesale: the onion-service
listener and send-to-onion path in the wallet, the legacy transport
GUI tab, the Tor settings page, src/tor/, the webtunnel pluggable
transport (Go build + submodule), and all arti crates from Cargo.toml.
The Grin node connection is unchanged (chain data, no payment metadata,
and never used Tor). The network requester the sidecar routes through is
configured via GOBLIN_NYM_PROVIDER / NETWORK_REQUESTER at deploy time.
The read-only NIP-05 username lookups (resolve + check_availability) carry no
secret and need no anonymity — routing them over Tor is what made choosing a
username slow. They now use a fast clearnet HTTPS GET (reqwest + rustls/ring,
so it still cross-compiles to Android), falling back to Tor only if clearnet is
blocked. The anonymity-critical paths (slatepack delivery, NIP-98-signed ops)
are untouched.
Infrastructure (P0): deployed nostr-rs-relay (wss://nrelay.us-ea.st) and the
goblin-nip05d NIP-05 service (goblin.st) on us-ea.st with TLS + DNS.
Brand & theme (P1): Goblin name/icon/data-dir (.goblin); three-theme token
system (light/dark/yellow) in gui/theme.rs with colors.rs remapped as a shim;
Geist + Geist Mono fonts; AppConfig theme/density/last_wallet_id.
Nostr subsystem (P2-P3): src/nostr/ with NIP-06 identity (seed-derived,
NIP-49 encrypted), per-wallet rkv archive, guarded ingest policy (never
auto-pays Invoice1; binds replies to the stored counterparty npub), NIP-17
send/receive pipeline, NIP-05 client. Relay traffic routed over the embedded
arti Tor client via a custom WebSocketTransport. Wired into Wallet lifecycle
and the task handler. 26 unit tests pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Limit loading at tix list
- Sort txs by confirmation status to show txs waiting for an action at top
- Ability to delete wallet from the list without opening
- Optimize Tor connection on account switch
Reviewed-on: https://code.gri.mw/GUI/grim/pulls/53
- Ability to export and verify payment proofs
Some fixes:
- Migrated tx heights store from lmdb (also changed heights key from local id to slate_id to avoid conflict between wallets)
- Close address panel on wallet change
Reviewed-on: https://code.gri.mw/GUI/grim/pulls/52
- Update common dependencies
- Optimize check of running Tor service
- Async peer saving
- Add mainnet and testnet seeds
- Remove grinnode.live from default external connections
Reviewed-on: https://code.gri.mw/GUI/grim/pulls/43
Use node and wallet submodules to avoid dependency conflicts inside grin-wallet on grin repo update.
Reviewed-on: https://code.gri.mw/GUI/grim/pulls/29