Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No connect after selecting Mobile Wallet Adapter #1086

Open
Michaelsulistio opened this issue Jan 30, 2025 · 1 comment
Open

No connect after selecting Mobile Wallet Adapter #1086

Michaelsulistio opened this issue Jan 30, 2025 · 1 comment

Comments

@Michaelsulistio
Copy link
Contributor

Overview

When selecting the Mobile Wallet Adapter wallet option on a Mobile Browser, you may run into an issue where nothing happens, and wallet navigation never occurs.

This document explains the issue, its causes, and recommended solutions.

Explanation

Symptom

A common occurrence of what this looks like is:

  1. User loads a web dapp page on mobile (e.g Android Chrome)
  2. Opens the wallet modal or some selection
  3. Press the "Mobile Wallet Adapter" option
  4. Nothing happens, no navigation occurs

Repro

screen-20250130-121421.mp4

Why It Happens

Here are two scenarios where this issue occurs. In both cases, the root case is that Mobile Wallet Adapter is stuck as the "selected" wallet and dApps never explicitly call connect().

Default Selection Issue

  • Mobile Wallet Adapter is the default "selected" wallet by the wallet-adapter-react library.

  • Pressing the Mobile Wallet Adapter option does not result in any React state change, because it is already the selected wallet.

  • Because there is no state change, the auto connect useEffect is never triggered and connect() is never called.

No selection reset after connect error

This is another scenario where Mobile Wallet Adapter can get stuck as the default selected wallet.

  • The handleConnectError in WalletProvider has a special case that does not unselect Mobile Wallet Adapter in the case of an error during connection.
  • So when a user initiates an MWA connection and an error occurs, Mobile Wallet Adapter is stuck as the selected wallet,
  • Because its the selected wallet, no state change occurs, and the auto connect useEffect is never triggered (just like above)
  • This case occurs when user cancels a connect by tapping outside of Intent disambiguation (triggering an error) .

Workarounds

Call connect() directly

Instead of rendering a wallet selection modal, you can immediately call connect() if the selected wallet is Mobile Wallet Adapter. Jupiter Unified Wallet Kit is a good example of this.

import {
    SolanaMobileWalletAdapterWalletName,
} from '@solana-mobile/wallet-adapter-mobile';

async function handleConnectButtonClick {
	const { wallet, connect } = useWallet();
	if (wallet?.adapter.name === SolanaMobileWalletAdapterWalletName) {
		// If MWA is the selected wallet, immediately call connect
		await connect()
	} else {
		// Else, handle normally (e.g showing a modal)
		showWalletModal()
	}
}

Root cause fix in wallet-adapter-react

The concept of the selected wallet state lives in the WalletProviderBase component in wallet-adapter-react. There are two changes needed:

1. Remove MWA as a default selection

This logic needs to be changed:

// current implementation
const [walletName, setWalletName] = useLocalStorage<WalletName | null>(
        localStorageKey,
        // getIsMobile(adaptersWithStandardAdapters) ? SolanaMobileWalletAdapterWalletName : null
    );

// replace to
const [walletName, setWalletName] = useLocalStorage<WalletName | null>(
        localStorageKey,
        null
    );

With this change, MWA will be in a correct state starting from initial page load.

2. Unselect Mobile Wallet Adapter on connect error

This logic needs to be changed:

// current implementation
const handleConnectError = useCallback(() => {
        if (adapter && adapter.name !== SolanaMobileWalletAdapterWalletName) {
            // If any error happens while connecting, unset the adapter.
            changeWallet(null);
        }
    }, [adapter, changeWallet]);

// replace to
const handleConnectError = useCallback(() => {
        if (adapter) {
            // If any error happens while connecting, unset the adapter.
            changeWallet(null);
        }
    }, [adapter, changeWallet]);

With this change, any connection errors (or cancels) will not result in MWA getting stuck as the selection.

@Funkatronics
Copy link
Contributor

PR with fix on wallet-adapter here.

Thanks @Michaelsulistio for the comprehensive analysis

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

No branches or pull requests

3 participants
@Michaelsulistio @Funkatronics and others