diff --git a/playground/browser-playground/CHANGELOG.md b/playground/browser-playground/CHANGELOG.md index 3b6b21b6..62ccf4d4 100644 --- a/playground/browser-playground/CHANGELOG.md +++ b/playground/browser-playground/CHANGELOG.md @@ -15,6 +15,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **BREAKING**: Update connect/disconnect button labels to include connector names ("Connect" → "Connect (Multichain)", "Disconnect" → "Disconnect (Multichain)" / "Disconnect All") for clarity and consistency with other connector buttons +### Fixed + +- Fix Solana connect race condition that caused `WalletNotSelectedError` when extension not installed + ## [0.1.1] ### Added diff --git a/playground/browser-playground/src/App.tsx b/playground/browser-playground/src/App.tsx index f100632c..aabce6a5 100644 --- a/playground/browser-playground/src/App.tsx +++ b/playground/browser-playground/src/App.tsx @@ -71,11 +71,26 @@ function App() { connected: solanaConnected, publicKey: solanaPublicKey, wallets, + wallet: solanaWallet, select, connect: solanaConnect, disconnect: solanaDisconnect, } = useWallet(); + // Track when user has requested a Solana connection + const [solanaPendingConnect, setSolanaPendingConnect] = useState(false); + + // Effect to connect once wallet is selected (avoids race condition between select and connect) + useEffect(() => { + if (solanaPendingConnect && solanaWallet && !solanaConnected) { + solanaConnect().catch((error) => { + console.error('Solana connection error:', error); + }).finally(() => { + setSolanaPendingConnect(false); + }); + } + }, [solanaPendingConnect, solanaWallet, solanaConnected, solanaConnect]); + const handleCheckboxChange = useCallback( (value: string, isChecked: boolean) => { if (isChecked) { @@ -161,22 +176,21 @@ function App() { } }, [customScopes, connectors, wagmiConnectAsync]); - const connectSolana = useCallback(async () => { + const connectSolana = useCallback(() => { // Find the MetaMask wallet in registered wallets const metamaskWallet = wallets.find((w) => w.adapter.name.toLowerCase().includes('metamask connect'), ); if (metamaskWallet) { - try { - select(metamaskWallet.adapter.name); - await solanaConnect(); - } catch (error) { - console.error('Solana connection error:', error); - } + // Select the wallet and set pending connect flag. + // The useEffect will call connect() once the wallet state updates, + // avoiding the race condition between select() and connect(). + select(metamaskWallet.adapter.name); + setSolanaPendingConnect(true); } else { console.error('MetaMask wallet not found in registered wallets'); } - }, [wallets, select, solanaConnect]); + }, [wallets, select]); const isConnected = status === 'connected'; const isDisconnected = diff --git a/playground/browser-playground/src/sdk/SolanaProvider.tsx b/playground/browser-playground/src/sdk/SolanaProvider.tsx index ae94e2f9..a00722e4 100644 --- a/playground/browser-playground/src/sdk/SolanaProvider.tsx +++ b/playground/browser-playground/src/sdk/SolanaProvider.tsx @@ -1,5 +1,4 @@ import { createSolanaClient, type SolanaClient } from '@metamask/connect-solana'; -import { METAMASK_PROD_CHROME_ID } from '@metamask/playground-ui'; import { ConnectionProvider, WalletProvider, @@ -10,7 +9,6 @@ import { WalletModalProvider } from '@solana/wallet-adapter-react-ui'; import type React from 'react'; import { createContext, - useCallback, useContext, useEffect, useMemo,