Connect to EVM - Wagmi quickstart
Get started with MetaMask Connect EVM in a React and Wagmi dapp. Download the quickstart template or manually set up MetaMask Connect EVM in an existing dapp.
If you are upgrading an existing wagmi project that used @metamask/sdk, see the
Wagmi connector migration reference at the bottom of this page
for a parameter mapping table.
Prerequisites
- Node.js version 19 or later installed.
- A package manager installed, such as npm, Yarn, pnpm, or bun.
- MetaMask installed in your browser or on mobile.
- An Infura API key from the MetaMask Developer dashboard.
Set up using a template
-
Download the MetaMask Connect Wagmi template:
npx degit MetaMask/metamask-connect-examples/integrations/wagmi metamask-wagmi -
Navigate into the repository:
cd metamask-wagmiDegit vs. Git clone
degitis a tool that enables cloning only the directory structure from a GitHub repository, without retrieving the entire repository.Alternatively, use
git cloneto download the entire repository. Clone the MetaMask Connect examples repository and navigate into thequickstarts/wagmidirectory:git clone https://github.com/MetaMask/metamask-connect-examples
cd metamask-connect-examples/integrations/wagmi -
Install dependencies:
pnpm install -
Run the project:
pnpm dev
Set up manually
1. Install dependencies
Install MetaMask Connect EVM along with its peer dependencies to an existing React project:
- npm
- Yarn
- pnpm
- Bun
npm install @metamask/connect-evm wagmi@latest @wagmi/connectors@latest viem@2.x @tanstack/react-query
yarn add @metamask/connect-evm wagmi@latest @wagmi/connectors@latest viem@2.x @tanstack/react-query
pnpm add @metamask/connect-evm wagmi@latest @wagmi/connectors@latest viem@2.x @tanstack/react-query
bun add @metamask/connect-evm wagmi@latest @wagmi/connectors@latest viem@2.x @tanstack/react-query
2. Import required dependencies
In the root of your project, import the required dependencies:
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { http, WagmiProvider, createConfig } from 'wagmi'
import { mainnet, sepolia, lineaSepolia } from 'wagmi/chains'
import { metaMask } from 'wagmi/connectors'
3. Configure your project
Set up your configuration with the desired chains and connectors.
In the following example, replace <NEXT_PUBLIC_INFURA_API_KEY> with your Infura API key:
const INFURA_KEY = process.env.NEXT_PUBLIC_INFURA_API_KEY!;
const config = createConfig({
ssr: true, // Enable this if your dapp uses server-side rendering.
chains: [mainnet, sepolia, lineaSepolia],
connectors: [
metaMask({
dapp: {
name: 'My Dapp',
url: window.location.origin,
},
}),
],
transports: {
[mainnet.id]: http(`https://mainnet.infura.io/v3/${INFURA_KEY}`),
[sepolia.id]: http(`https://sepolia.infura.io/v3/${INFURA_KEY}`),
[lineaSepolia.id]: http(`https://linea-sepolia.infura.io/v3/${INFURA_KEY}`),
},
});
4. Set up providers
Wrap your application with the necessary providers:
const client = new QueryClient()
const App = () => {
return (
<WagmiProvider config={config}>
<QueryClientProvider client={client}>
<Component {...pageProps} />
</QueryClientProvider>
</WagmiProvider>
)
}
5. Add the connect button
Add the wallet connect and disconnect buttons to your application:
import { useAccount, useConnect, useDisconnect } from 'wagmi'
export const ConnectButton = () => {
const { address } = useAccount()
const { connectors, connect } = useConnect()
const { disconnect } = useDisconnect()
return (
<div>
{address ? (
<button onClick={() => disconnect()}>Disconnect</button>
) : (
connectors.map(connector => (
<button key={connector.uid} onClick={() => connect({ connector })}>
{connector.name}
</button>
))
)}
</div>
)
}
After adding the connect button, test your dapp by running pnpm run dev.
Common operations
Switch chains
Use useSwitchChain and useChainId to let users switch between your configured chains:
import { useSwitchChain, useChainId } from 'wagmi'
function ChainSwitcher() {
const chainId = useChainId()
const { chains, switchChain } = useSwitchChain()
return (
<div>
{chains.map(chain => (
<button
key={chain.id}
disabled={chainId === chain.id}
onClick={() => switchChain({ chainId: chain.id })}>
{chain.name}
</button>
))}
</div>
)
}
Sign a message
Use useSignMessage to request a personal_sign signature from the connected wallet:
import { useSignMessage } from 'wagmi'
function SignMessage() {
const { data: signature, signMessage, isPending } = useSignMessage()
return (
<div>
<button disabled={isPending} onClick={() => signMessage({ message: 'Hello from my dapp!' })}>
Sign Message
</button>
{signature && <p>Signature: {signature}</p>}
</div>
)
}
Send a transaction
Use useSendTransaction and useWaitForTransactionReceipt to send ETH and track confirmation:
import { useSendTransaction, useWaitForTransactionReceipt } from 'wagmi'
import { parseEther } from 'viem'
function SendTransaction() {
const { data: hash, sendTransaction, isPending } = useSendTransaction()
const { isLoading: isConfirming, isSuccess } = useWaitForTransactionReceipt({ hash })
return (
<div>
<button
disabled={isPending}
onClick={() =>
sendTransaction({
to: '0xRecipientAddress',
value: parseEther('0.01'),
})
}>
{isPending ? 'Sending...' : 'Send 0.01 ETH'}
</button>
{isConfirming && <p>Confirming...</p>}
{isSuccess && <p>Confirmed! Hash: {hash}</p>}
</div>
)
}
Connect and sign
Use the connectAndSign connector option to connect and prompt the user to sign a message in a single approval:
metaMask({
dapp: { name: 'My Dapp', url: window.location.origin },
connectAndSign: 'By signing, you agree to our Terms of Service.',
})
Connect and execute
Use the connectWith connector option to connect and execute any RPC method in a single approval:
metaMask({
dapp: { name: 'My Dapp', url: window.location.origin },
connectWith: {
method: 'eth_signTypedData_v4',
params: [address, JSON.stringify(typedData)],
},
})
Production readiness
For production deployments, use reliable RPC providers instead of public nodes. We recommend using services like Infura to ensure better reliability and performance. See the production readiness checklist for more details.
Migrate from @metamask/sdk
If you previously used @metamask/sdk with Wagmi, the MetaMask connector now uses @metamask/connect-evm under the hood. Update your dependencies and connector configuration:
-
Replace
@metamask/sdkwith@metamask/connect-evm:- npm
- Yarn
- pnpm
- Bun
npm uninstall @metamask/sdk
npm install @metamask/connect-evmyarn remove @metamask/sdk
yarn add @metamask/connect-evmpnpm remove @metamask/sdk
pnpm add @metamask/connect-evmbun remove @metamask/sdk
bun add @metamask/connect-evm -
Update connector options:
Old parameter ( @metamask/sdk)New parameter ( @metamask/connect-evm)Notes dappMetadata: { name, url }dapp: { name, url, iconUrl }dappMetadatastill works but is deprecatedlogging: { sdk: true }debug: trueloggingstill works but is deprecateduseDeeplink: booleanmobile: { useDeeplink: boolean }Moved into mobilenamespacepreferredOpenLinkmobile: { preferredOpenLink }Moved into mobilenamespaceforceDeleteProvider(removed) Not needed with new SDK forceInjectProvider(removed) Not needed with new SDK injectProvider(removed) Not needed with new SDK readonlyRPCMap(auto-configured) Built automatically from Wagmi's chain config
For non-Wagmi migration details, see the full migration guide.
Next steps
After completing the basic setup, follow these guides to add your own functionality: