Skip to content

Revert NYM mix-fetch to v1 (1.4.4) - #732

Merged
j0ntz merged 2 commits into
masterfrom
jon/revert-nym-mixfetch-v2
Jul 17, 2026
Merged

Revert NYM mix-fetch to v1 (1.4.4)#732
j0ntz merged 2 commits into
masterfrom
jon/revert-nym-mixfetch-v2

Conversation

@j0ntz

@j0ntz j0ntz commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

CHANGELOG

Does this branch warrant an entry to the CHANGELOG?

  • Yes
  • No

Dependencies

none

Description

Asana task

Reverts the NYM mix-fetch v2 upgrade (#729) back to @nymproject/mix-fetch
1.4.4, and adds a setup timeout on the restored v1 API.

Asana: https://app.asana.com/1/9976422036640/project/1215088146871429/task/1216603961673510
QA report: https://app.asana.com/1/9976422036640/project/1213843652804305/task/1216438166625538

Why

v2 (2.0.0, shipped in 2.47.0) is a comprehensive regression for our workload,
not the timeout mis-port that PR #731 addresses. A controlled A/B against the
live mixnet (both stacks in one browser, driven concurrently in the same
seconds, so network conditions are identical):

Endpoint v1.4.4 v2.0.0 (pinned IPR, tunnel ready)
ETH cloudflare-eth ~2.6s (reachable) 120s operation timed out
AVAX api.avax.network ~2.1s, HTTP 200 120s timed out
Cosmos Hub :443 ~2.5s, HTTP 200 120s timed out
Coreum :26657 fails ~1s (exit policy) 120s timed out

Across four distinct pinned exit nodes, no v2 node matched v1's speed or
reliability; most requests failed and the few successes were 6-18x slower.
Tuning (disablePoissonTraffic, disableCoverTraffic, SURB budgets) did not
help. So Avalanche and the Cosmos family, which work in ~2s on v1, are broken
on v2, which is the 2026-07-15 staging QA report.

The reproduction harness and full data are attached to the task. The findings
have been sent to the Nym team; if they ship a fixed build we can re-adopt v2.

What this reverts to

1.4.4 with the pinned preferredGateway and preferredNetworkRequester, and
v1's mixFetchOverride.requestTimeoutMs: 300000 (the per-request bound v2
dropped).

Added on top

initMixFetch now bounds createMixFetch at 60s. v1 has no internal setup
budget, so a dead or unreachable gateway would otherwise block the first mixnet
request (and the wallet behind it) indefinitely. A healthy setup with the
pinned gateway completes in under 10s measured. On timeout, the abandoned setup
is torn down when it eventually settles, so it cannot hold a gateway connection
nobody will use, and the late rejection is handled rather than left unhandled.

Relationship to #731

#731 bounds v2's per-request
hang and is correct on its own terms, but it cannot make v2 deliver. This PR is
the actual fix for the QA report. If this lands, #731 can close as superseded.

Verification

verify-repo.sh passes (prepare + eslint + mocha). Driven in-app on the iOS
sim with this core embedded: the Avalanche wallet syncs (balance + history) with
NYM privacy on. A successful in-app send could not be captured because the
mixnet itself was not delivering during the run window (the same environmental
flakiness the A/B controls for); the controlled browser A/B is the load-bearing
evidence.


Note

Medium Risk
Changes affect all NYM privacy networking and the RN worker bundle (WASM/workers); behavior is intentionally reverted to v1 but setup timeout and global cleanup add new failure/race paths on first mixnet use.

Overview
Reverts @nymproject/mix-fetch from v2 to v1.4.4 so NYM privacy fetches use the v1 client again (pinned gateway/network requester, mixFetchOverride.requestTimeoutMs, disconnectMixFetch), undoing the 2.47.0 smolmix-tunnel stack that broke wallet sync/send over the mixnet.

initMixFetch races createMixFetch against a 60s setup timeout, clears __mixFetchGlobal and disconnects on failure, and returns mixFetchModule.mixFetch. Browser and React Native privacy: 'nym' paths pass mode: 'unsafe-ignore-cors' and mixFetchOptions as the third argument.

Webpack again enables async WASM and copies mix-fetch .wasm and web-worker-*.js into the RN bundle assets (v2 had inlined them).

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

This reverts commit 816be23, returning to
@nymproject/mix-fetch 1.4.4 with the pinned gateway and network requester.

A controlled A/B against the live mixnet (both stacks in one browser, driven
concurrently) shows the v2 stack failing to complete small HTTPS JSON-RPC
requests through most exit nodes (internal ~120s timeout on a tunnel that
reports ready), while 1.4.4 completes the same requests in 2-3 seconds at the
same instant. v2's exit-node auto-discovery also rarely converges, and the
upgrade dropped the pins that made node selection deterministic, so wallets
with NYM privacy enabled were left unable to sync or send (the 2026-07-15
staging QA report).
@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.

@socket-security

socket-security Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updated@​nymproject/​mix-fetch@​2.0.0 ⏵ 1.4.478 +810077 -2295 +5100

View full report

Comment thread src/util/nym.ts Outdated
@j0ntz
j0ntz force-pushed the jon/revert-nym-mixfetch-v2 branch from 4eac20b to 062120d Compare July 16, 2026 01:16

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 062120d. Configure here.

Comment thread src/util/nym.ts Outdated
createMixFetch has no internal budget, so a dead or unreachable gateway kept
the first mixnet request (and the wallet behind it) waiting indefinitely.
Race it against a 60 second bound: a healthy setup with the pinned gateway
completes in under 10 seconds measured, and on timeout the abandoned setup is
torn down when it eventually settles so it cannot hold a gateway connection
nobody will use.
@j0ntz
j0ntz force-pushed the jon/revert-nym-mixfetch-v2 branch from 062120d to a323e15 Compare July 16, 2026 01:23
@j0ntz
j0ntz merged commit 560f7a8 into master Jul 17, 2026
6 checks passed
@j0ntz
j0ntz deleted the jon/revert-nym-mixfetch-v2 branch July 17, 2026 22:41
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.

2 participants