Connect wallet
Connect a wallet, display its name or address, and disconnect through wagmi.
ConnectWallet detects available wallets and handles connection and disconnection through wagmi. Once connected, it shows the wallet's address or resolved name. You can also use its ConnectorList and WalletButton components separately.
connect-wallet.tsxShow code
import { ConnectWallet } from "@/components/ui/connect-wallet"export function Header() { return <ConnectWallet />}The preview uses wagmi's mock connector. It does not connect to your wallet or request a signature. In your app, the component lists the available connectors from your wagmi config.
Installation
npx shadcn add @onchain-ui/connect-walletRequirements
ConnectWallet targets wagmi 3 and needs a WagmiProvider and TanStack QueryClientProvider above it. See Wallet connection for setup. The menu uses the shadcn dropdown-menu.
The default setup uses injected() and EIP-6963 discovery for browser extension wallets. It needs no extra SDK or project ID. For QR codes and mobile deep links, add a connector and install its SDK dependencies.
Usage
import { ConnectWallet } from "@/components/ui/connect-wallet"
<ConnectWallet />With one available wallet, the button connects directly. With several, it opens a picker. The button stays disabled while the component checks for providers.
The pieces
To build your own connection UI, use the items installed with ConnectWallet:
| Item | Type | What it does |
|---|---|---|
connector-list | registry:ui | Lists wallets and reports the selected ID |
wallet-button | registry:ui | Shows the connected address or name in a button |
use-available-connectors | registry:hook | EIP-6963 probing. Returns wagmi connectors |
connect-wallet | registry:block | Combines the picker, button, and hook with wagmi connection actions |
Only useAvailableConnectors and ConnectWallet import wagmi. You can use ConnectorList and WalletButton with another wallet library.
Connector list
Pass a list of objects with id and name fields. Add icon and description as needed. Map wagmi connectors to this shape or provide your own list.
connector-list.tsxShow code
import { ConnectorList } from "@/components/ui/connector-list"export function Wallets() { return ( <ConnectorList connectors={wallets} pendingId={pendingId} onSelect={setPendingId} /> )}When the list is empty, ConnectorList shows a message that no wallet is available.
No compatible wallet connection is available on this device.
connector-list-empty.tsxShow code
import { ConnectorList } from "@/components/ui/connector-list"export function NoWallets() { return <ConnectorList connectors={[]} onSelect={connect} />}Wallet button
wallet-button.tsxShow code
import { WalletButton } from "@/components/ui/wallet-button"export function Account() { return ( <WalletButton address="0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" chainId={1} onClick={openMenu} /> )}WalletButton forwards button props to its underlying button, so you can use it as a menu trigger:
<DropdownMenuTrigger render={<WalletButton address={address} chainId={chainId} />} />wallet-button-states.tsxShow code
import { WalletButton } from "@/components/ui/wallet-button"export function WalletButtonStates() { return ( <div className="flex items-center gap-3"> <WalletButton address={address} chainId={8453} size="sm" /> <WalletButton address={address} chainId={8453} /> <WalletButton address={address} showNetwork={false} /> <WalletButton address={address} chainId={1} isPending /> </div> )}useAvailableConnectors
When your config includes injected(), wagmi can return that connector even if the browser has no wallet provider. Connecting then throws ProviderNotFoundError. useAvailableConnectors calls each injected connector's async getProvider() method and filters out those without a provider.
import { useAvailableConnectors } from "@/hooks/use-available-connectors"
const { connectors, isProbing } = useAvailableConnectors()The hook also removes wagmi's generic injected() fallback when it finds a named injected wallet. The fallback reads window.ethereum and can duplicate an announced wallet. The hook also removes a MetaMask fallback when the list contains the MetaMask SDK connector.
If a provider has no matching named connector, ConnectWallet lists it as "Browser wallet". This covers wallets that inject a provider without announcing themselves through EIP-6963.
Props
ConnectWallet
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | "Connect wallet" | Label for the disconnected trigger |
showNetwork | boolean | true | Show the network mark on the connected pill |
size | "sm" | "default" | "default" | Visual size |
onError | (error: Error) => void | - | Called when a connection attempt fails |
className | string | - | Applied to the trigger |
contentClassName | string | - | Applied to the menu |
ConnectorList
| Prop | Type | Default | Description |
|---|---|---|---|
connectors | ConnectorOption[] | - | Wallets the user can pick from |
onSelect | (id: string) => void | - | Called with the id of the wallet picked |
pendingId | string | null | - | Connector being connected. Blocks selection |
disabled | boolean | false | Disable every row |
emptyMessage | ReactNode | "No compatible wallet connection is available on this device." | Shown when connectors is empty |
className | string | - | Applied to the list wrapper |
itemClassName | string | - | Applied to each row |
WalletButton
| Prop | Type | Default | Description |
|---|---|---|---|
address | Address | - | Connected wallet address |
chainId | number | null | - | Connected chain id |
name | string | null | Resolved | Name override, skips resolution |
avatarUrl | string | null | Resolved | Avatar override |
isPending | boolean | false | Spinner in place of the chevron |
showNetwork | boolean | true | Show the network mark |
showChevron | boolean | true | Show the trailing chevron |
size | "sm" | "default" | "default" | Visual size |
WalletButton forwards other button props to the underlying button.