Version: reproduced on thirdweb@5.119.1; the relevant code is unchanged in 5.121.4 (latest at time of writing).
Summary
On a desktop browser with a viewport narrower than 640px, starting a WalletConnect connection incorrectly takes the mobile deep-link path instead of displaying the QR code.
The result is an infinite spinner and a connection that cannot complete.
Steps to reproduce
- Open an app in desktop Chrome with a desktop user agent and no touch screen.
- Resize the browser window below 640px, or dock DevTools so the viewport becomes narrower than 640px.
- Do not use device emulation.
- Start a WalletConnect connection.
Expected: The inline WalletConnect QR code is displayed, as it is at wider viewport sizes.
Actual: The connection shows an infinite spinner.
The console reports:
Failed to launch 'wc:…' because the scheme does not have a registered handler
Widening the viewport above 640px and retrying immediately displays the QR code correctly. We reproduced this at 555px (spinner) versus 1000px (QR) on the same machine, browser, and session.
Root cause
isMobile() treats a viewport narrower than 640px as a mobile device:
export function isMobile() {
// Primary signal: OS detection via user agent
const isMobileOS = isAndroid() || isIOS();
if (isMobileOS) return true;
// Secondary signal: catch edge cases like webviews with modified user agents
if (hasTouchScreen() && hasMobileAPIs()) return true;
const isMobileViewport =
typeof window !== "undefined" && window.innerWidth < 640;
if (isMobileViewport) return true;
return false;
}
create-wallet.js uses isMobile() to choose between the mobile deep-link flow and the desktop QR flow.
When isMobile() returns true, it attempts to open the WalletConnect URI:
openWindow(formatWalletConnectUrl(mobileAppLink, uri).redirect)
or, when no mobile app link is available:
It then returns without reaching the desktop QR-overlay path.
On a real desktop browser there is no wc: URI handler, so the hand-off fails and the connection remains stuck on the spinner.
Version: reproduced on
thirdweb@5.119.1; the relevant code is unchanged in5.121.4(latest at time of writing).Summary
On a desktop browser with a viewport narrower than 640px, starting a WalletConnect connection incorrectly takes the mobile deep-link path instead of displaying the QR code.
The result is an infinite spinner and a connection that cannot complete.
Steps to reproduce
Expected: The inline WalletConnect QR code is displayed, as it is at wider viewport sizes.
Actual: The connection shows an infinite spinner.
The console reports:
Widening the viewport above 640px and retrying immediately displays the QR code correctly. We reproduced this at 555px (spinner) versus 1000px (QR) on the same machine, browser, and session.
Root cause
isMobile()treats a viewport narrower than 640px as a mobile device:create-wallet.jsusesisMobile()to choose between the mobile deep-link flow and the desktop QR flow.When
isMobile()returnstrue, it attempts to open the WalletConnect URI:or, when no mobile app link is available:
It then returns without reaching the desktop QR-overlay path.
On a real desktop browser there is no
wc:URI handler, so the hand-off fails and the connection remains stuck on the spinner.