Skip to content

Rerandomize the NYM mixnet client id on each connect - #737

Open
j0ntz wants to merge 1 commit into
masterfrom
jon/nym-mixfetch-v2-remeasure
Open

Rerandomize the NYM mixnet client id on each connect#737
j0ntz wants to merge 1 commit into
masterfrom
jon/nym-mixfetch-v2-remeasure

Conversation

@j0ntz

@j0ntz j0ntz commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

CHANGELOG

Does this branch warrant an entry to the CHANGELOG?

  • Yes
  • No

Dependencies

none

Description

Asana task

clientId names the mixnet client's persistent key storage, and src/util/nym.ts passed the same hardcoded 'edge-core-js-2026-03-10' on every setup. A client whose registration went bad therefore reloaded that same bad storage on every later connect, and across app restarts, so a wallet that got stuck stayed stuck until the app was reinstalled. This mints a fresh 16-byte random id per connect instead, which is what the Nym team recommends for exactly this failure mode.

The change also drops the third argument at both fetch call sites. initMixFetch has already created the instance, and the instance-bound mixFetch takes only (url, args), so the options object was being silently discarded. That removes the last consumer of the exported options object, which is now private to nym.ts.

Verified on the iOS sim (Nym mixnet ON for Ethereum, Avalanche, Coreum and Monero on a throwaway account):

  • Two launches minted edge-core-js-a260f91f… and edge-core-js-33ca108a…; across the whole session 11 distinct random ids were written. Every file still containing the old constant has an mtime from July, so it survives only as residue from earlier builds.
  • com.apple.WebKit.Networking (the core WebView's network process) held an established WSS connection to nym-exit.tha1.craftdome.app:9001, a Nym entry/exit gateway, throughout.
  • A real ETH send completed through the mixnet: 0.0010499 ETH ($2.08, fee 0.000043 ETH) reached Transaction Success. Fee calculation resolved in about 90s. Both prior runs on this feature recorded "no successful send was reached" as a testing gap, so this closes it.

This PR carries the code change only. The task it belongs to is an evaluation of re-upgrading to @nymproject/mix-fetch v2; that verdict is do not upgrade yet, and the measurements behind it are attached to the Asana task rather than repeated here. The short version: 2.0.1 cannot connect at all (its WASM panics in nym_http_api_client calling std::time::Instant::now, which is unsupported on wasm32-unknown-unknown), and 2.0.0 was 4-in-10 clean against v1's 9-in-10 over ten paired harness runs, with the same in-app send hanging at tunnel error: IPR connect timed out where v1 succeeded.


Note

Medium Risk
Changes NYM mixnet client identity and registration on each setup (extra ~10s handshake tradeoff), but scope is limited to privacy fetch initialization and call wiring.

Overview
Fixes NYM mixnet wallets that never recover after a bad gateway registration by minting a fresh clientId on each initMixFetch setup instead of reusing the hardcoded edge-core-js-2026-03-10. Because clientId keys persistent registration storage, a poisoned registration was reused on every connect and across app launches until reinstall.

makeClientId() in nym.ts generates a 16-byte random edge-core-js-… id (with crypto.getRandomValues when available). Static mixnet options stay the same but mixFetchOptions is no longer exported; clientId is injected only when calling createMixFetch.

Browser and React Native privacy: 'nym' fetch paths now call the instance nymFetch with only URL and request options, dropping a third argument that was ignored after init anyway.

Reviewed by Cursor Bugbot for commit 87dffc6. Bugbot is set up for automated code reviews on this repo. Configure here.

@j0ntz

j0ntz commented Aug 17, 2026

Copy link
Copy Markdown
Contributor Author

📸 Test evidence

nym toggles on

nym toggles on

nym wallets synced

nym wallets synced

throwaway eth funded

throwaway eth funded

send nym mixnet on

send nym mixnet on

v1 send success nym on

v1 send success nym on

v2 ipr connect timed out

v2 ipr connect timed out

Captured by the agent's in-app test run (build-and-test).

clientId names the mixnet client's persistent key storage, so the fixed id
made every setup adopt the previous registration. A registration that went
bad therefore stayed bad for every later connect and across app launches,
which surfaces as a wallet that never syncs and never recovers.

Also drop the third argument at both fetch call sites: initMixFetch has
already created the instance, and the instance-bound mixFetch takes only
(url, args), so the options object was silently discarded.
@j0ntz
j0ntz marked this pull request as ready for review August 17, 2026 20:36
@j0ntz
j0ntz force-pushed the jon/nym-mixfetch-v2-remeasure branch from ef22402 to 87dffc6 Compare August 17, 2026 20:36
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant