For AI agents: a documentation index is available at /llms.txt. A markdown version of this page is available at the same URL with .md appended (or via Accept: text/markdown).
Skip to main content

Multi-wallet linking and switching

Web SDK only

Multi-wallet linking and switching ships in Web SDK v11 (@web3auth/modal for JavaScript, React, and Vue).

Users can link multiple external wallets to a single Embedded Wallets account and switch between them during an active session, including across chains. Your dapp receives one canonical user object instead of treating each wallet connection as a separate user.

How it works

  1. The user signs in with an embedded wallet method (for example, Google or email passwordless) through the AUTH connector.
  2. While authenticated, the user links an external wallet (for example, MetaMask or WalletConnect) to the same account.
  3. The linked wallet appears in userInfo.linkedAccounts.
  4. The user switches the active wallet with switchAccount() or the useWallets hook.
  5. The SDK updates connection.ethereumProvider or connection.solanaWallet and emits a connection_updated event so Wagmi and your UI resync.
info

Account linking requires an AUTH primary session. You cannot link wallets when the user's only sign-in method is an external wallet connection.

Linked account fields

Each entry in userInfo.linkedAccounts is a LinkedAccountInfo object:

FieldDescription
idLinked account identifier
isPrimaryWhether this is the user's primary account
eoaAddressExternally owned account (EOA) address
aaAddressSmart account address, if configured
aaProviderSmart account provider name
connectorConnector that owns this account
activeWhether this account is currently active

Call linkAccount() after the user is connected through the AUTH connector:

import { useWeb3Auth } from '@web3auth/modal/react'
import { WALLET_CONNECTORS } from '@web3auth/modal'

function LinkWalletButton() {
const { web3Auth } = useWeb3Auth()

const handleLink = async () => {
if (!web3Auth) return
const result = await web3Auth.linkAccount({
connector: WALLET_CONNECTORS.METAMASK,
})
console.log('Linked address:', result.address)
}

return <button onClick={handleLink}>Link MetaMask</button>
}
review

Confirm the exact linkAccount parameter shape and return type for your SDK version in the @web3auth/modal release notes. Account linking may require accountLinking.serverUrl in Web3AuthOptions.

Switch the active wallet

Use switchAccount() with a LinkedAccountInfo entry from userInfo.linkedAccounts:

import { useWeb3Auth, useWeb3AuthUser } from '@web3auth/modal/react'

function WalletSwitcher() {
const { web3Auth } = useWeb3Auth()
const { userInfo } = useWeb3AuthUser()

const handleSwitch = async (accountId: string) => {
if (!web3Auth || !userInfo?.linkedAccounts) return
const account = userInfo.linkedAccounts.find(a => a.id === accountId)
if (!account) return
await web3Auth.switchAccount(account)
}

return (
<ul>
{userInfo?.linkedAccounts?.map(account => (
<li key={account.id}>
{account.eoaAddress}
{account.active ? ' (active)' : ''}
{!account.active && <button onClick={() => handleSwitch(account.id)}>Switch</button>}
</li>
))}
</ul>
)
}

React and Vue hooks

The Web SDK exports a useWallets hook (React) and composable (Vue) for wallet linking and switching. Import from @web3auth/modal/react or @web3auth/modal/vue.

review

Add a dedicated hook reference page once the useWallets API surface is finalized in the SDK docs.

Remove a linked wallet with unlinkAccount():

await web3Auth.unlinkAccount('<LINKED_EOA_ADDRESS>')

Why this matters for dapps

  • Analytics: One user ID maps to every wallet the user owns, not one ID per connection.
  • CRM: Store a single profile with multiple wallet addresses attached.
  • UX: Users can bring a hot wallet, hardware wallet, and side-project wallet under one login without signing out.

Next steps