Both methods answered from currentNetwork(), which reads the module-level state singleton, and nothing populates that at module scope. A service worker revived by the page's own message therefore held DEFAULT_STATE and reported mainnet 0x1 / 1 to a page whose user was on Sepolia, so a dApp asking which chain the wallet is on built its interaction for the wrong one. Neither method is gated on a connection, so any page got the stale answer. One await loadState() covers the pair: they are the same read of the same value, and a second load in a sibling branch would be redundant. Same shape and placement idiom as the chain-switch handler and the transaction path. Read-side audit of the background, which the fix was the occasion for: the other singleton reads are wallet_switchEthereumChain, the transaction verify/broadcast path and backgroundRefresh, and all three already load first. Every other handler answers from storage per call through getState(). One stale read remains and is deliberately not fixed here, being a different handler rather than the same one-line shape: handleSendTransaction calls getProvider() with no network name, so balances.js falls back to the same unloaded singleton for ethers' static network hint, and a cold-worker send on Sepolia is prepared with a mainnet hint. It is caught later — the artifact is verified against the loaded chain before broadcast — so it fails the send rather than sending on the wrong chain. Verified failing first: reverting only src/background/index.js to next gives 3 failed / 775 passed, exactly the three cases that read the chain on a cold worker; the mainnet case and the persists-nothing case pass either way by design. With the fix, 778 passed / 36 suites, and lint ran uncached in the pinned container (eslint + prettier over the changed files).
6.3 KiB
6.3 KiB