AppKit's controllers (RouterController, ChainController, ...) are
module-level singletons, so a per-namespace modal rebuilt on each switch
re-ran AppKit init against the same globals and left the previous open's
router history behind - a stray back button in the modal header when
opening BTC after EVM (or the reverse).
Build the modal once with both networks registered up front and choose
the active one per connect with switchNetwork, so open() sees a matching
active chain and takes its clean, non-switching path.
- modal.ts: single instance ([mainnet, bitcoin]); prepareModalForNamespace
runs ready() + switchNetwork() before open. The active chain is now
shared mutable state, safe only because connects are serialized by the
adapter's #sessionQueue.
- modal-cache.ts: build once, no per-namespace rebuild.
- adapter.ts: drop namespace from getModal (one instance now).
- lifecycle.ts: call prepareModalForNamespace before open; reuse
WC_NAMESPACE_TO_CAIP for the open namespace instead of sniffing the
payload keys.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Summary
Add a UTXO namespace to the WalletConnect hub provider with Bitcoin connect/disconnect/eager-connect support and a transfer signer.
Changes
Test Plan
Checklist: