Skip to content

fix: wallet init race lets external connect win before node is set#19

Open
alejoamiras wants to merge 1 commit into
AztecProtocol:mainfrom
alejoamiras:fix/wallet-init-race
Open

fix: wallet init race lets external connect win before node is set#19
alejoamiras wants to merge 1 commit into
AztecProtocol:mainfrom
alejoamiras:fix/wallet-init-race

Conversation

@alejoamiras
Copy link
Copy Markdown
Contributor

Problem

Clicking Connect Wallet while the embedded wallet is still initializing, then completing the external wallet flow before createEmbeddedWallet resolves, throws "Wallet not initialized" from ContractsContext.registerBaseContracts and leaves the "Connecting to network..." banner stuck.

Cause

node is only assigned to reducer state via wallet/INIT_EMBEDDED. That dispatch is gated on !hasConnectedExternalWalletRef.current. confirmConnection flips the ref to true before the slow createEmbeddedWallet resolves, so the gate fails, INIT_EMBEDDED is skipped, and node stays null. SET_EXTERNAL did not touch node or isLoading, so both stay stale.

Fix

Decouple node lifecycle from embedded wallet lifecycle. The node belongs to the network, not the wallet.

  • wallet/SET_NODE action publishes the node synchronously before awaiting createEmbeddedWallet. External flows no longer wait on the slow embedded init.
  • SET_EXTERNAL clears isLoading and error. The user has a usable wallet at that point.
  • RESTORE_EMBEDDED clears isLoading for symmetry.
  • initIdRef generation counter on the init effect. A stale createEmbeddedWallet resolving after a network switch checks it and bails before overwriting current state.
  • Clear embeddedWalletRef and embeddedAddressRef at init start so a network switch can't restore the previous network's wallet on later disconnect.
  • Embedded init failure while an external wallet is connected logs a warning instead of overwriting the working session with a fatal error.
  • disconnectWallet falls back to actions.disconnect() when there's no embedded wallet to restore. Otherwise the disconnected external wallet stays visible in state.

Test

  1. Hard reload on a slow network (devnet, or local with throttled CPU).
  2. Within ~500ms, click Connect Wallet, pick an external wallet, verify emojis, select an account.
  3. Pre-fix: throws "Wallet not initialized" in registerBaseContracts, banner persists.
  4. Post-fix: onboarding completes, banner clears.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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