
Skill
migrate-wagmi-metamask-connector
migrate wagmi apps to MetaMask connector
Description
Migrate a wagmi app from @metamask/sdk to the new @metamask/connect-evm connector (wagmi PR
SKILL.md
Migrate Wagmi MetaMask Connector to @metamask/connect-evm
When to use
- Upgrading a wagmi project from
@wagmi/connectorsv6.x/v7.x (which bundled@metamask/sdk) to v8.x+ / wagmi >= 3.6 (which uses@metamask/connect-evm) - You see errors like
Cannot find module '@metamask/sdk'after updating wagmi - You want to adopt the new MetaMask Connect SDK in an existing wagmi app
- Consumer is migrating to the latest wagmi version that includes the MetaMask connector refactor (PR #4960)
Breaking Change Summary
The MetaMask connector in wagmi has been completely rewritten. The underlying SDK changed from @metamask/sdk to @metamask/connect-evm. The connector now dynamically imports @metamask/connect-evm instead of bundling @metamask/sdk.
Key impacts:
- New optional peer dependency:
@metamask/connect-evmmust be installed explicitly, at a version inside wagmi's declared peer range (checknpm info @wagmi/connectors peerDependencies— currently^1.3.0) - Old dependency
@metamask/sdkshould be removed - Configuration parameter names changed (
dappMetadata→dapp,useDeeplink→mobile.useDeeplink) - Several deprecated SDK-specific options are removed entirely
- Internal provider type changed from
SDKProvidertoEIP1193Provider
Workflow
Step 1: Update Dependencies
Remove the old SDK and install the new one:
# npm
npm uninstall @metamask/sdk
npm install @metamask/connect-evm
# pnpm
pnpm remove @metamask/sdk
pnpm add @metamask/connect-evm
# yarn
yarn remove @metamask/sdk
yarn add @metamask/connect-evm
Then update wagmi packages to the latest:
npm install wagmi@latest @wagmi/core@latest @wagmi/connectors@latest
Step 2: Update MetaMask Connector Configuration
Before (old @metamask/sdk options):
import { metaMask } from 'wagmi/connectors'
metaMask({
dappMetadata: {
name: 'My Dapp',
url: 'https://mydapp.com',
},
useDeeplink: true,
logging: { sdk: false },
// These SDK-specific options are REMOVED:
forceDeleteProvider: false,
forceInjectProvider: false,
injectProvider: false,
})
After (new @metamask/connect-evm options):
import { metaMask } from 'wagmi/connectors'
metaMask({
dapp: {
name: 'My Dapp',
url: 'https://mydapp.com',
iconUrl: 'https://mydapp.com/icon.png', // new optional field
},
debug: false,
// Mobile options are now nested:
mobile: {
useDeeplink: true,
preferredOpenLink: undefined, // required for React Native
},
})
Step 3: Configuration Parameter Migration Reference
Old Parameter (@metamask/sdk) | New Parameter (@metamask/connect-evm) | Notes |
|---|---|---|
dappMetadata: { name, url } | dapp: { name, url, iconUrl } | dappMetadata still works but is deprecated |
logging: { sdk: true } | debug: true | logging still works but is deprecated |
useDeeplink: boolean | mobile: { useDeeplink: boolean } | Moved into mobile namespace |
preferredOpenLink | mobile: { preferredOpenLink } | Moved into mobile namespace |
forceDeleteProvider | (removed) | No replacement — not needed with new SDK |
forceInjectProvider | (removed) | No replacement — not needed with new SDK |
injectProvider | (removed) | No replacement — not needed with new SDK |
readonlyRPCMap | (auto-configured) | Built automatically from wagmi's chain config |
_source | (auto-set to 'wagmi') | Set internally by the connector |
Step 4: Update connectAndSign / connectWith Usage (if applicable)
The connectAndSign parameter name changed from msg to message internally. However, at the wagmi connector level the API is the same — you still pass connectAndSign: 'message string' in the metaMask() parameters.
// Still works the same at the wagmi config level:
metaMask({
dapp: { name: 'My Dapp' },
connectAndSign: 'Please sign this message to verify your identity',
})
The connectWith API is also unchanged at the wagmi level:
metaMask({
dapp: { name: 'My Dapp' },
connectWith: {
method: 'eth_signTypedData_v4',
params: [address, typedData],
},
})
Step 5: Handle Provider Type Changes
If your code directly accesses the provider from the connector, the type has changed:
// Before: provider was SDKProvider from @metamask/sdk
// After: provider is EIP1193Provider from @metamask/connect-evm
// The EIP1193Provider interface is the same standard interface,
// so provider.request() calls remain unchanged.
// New: You can access the underlying MetamaskConnectEVM instance:
const connector = config.connectors.find(c => c.id === 'metaMaskSDK')
if (connector) {
const instance = await connector.getInstance()
// instance.accounts, instance.getChainId(), instance.switchChain(), etc.
}
Step 6: Remove Deprecated Patterns
The new connector handles event listeners internally. If you had code that manually managed MetaMask SDK event listeners, you can remove it:
// REMOVE any manual SDK event management like:
// sdk.on('accountsChanged', ...)
// sdk.on('chainChanged', ...)
// provider.removeListener(...)
// Event handlers are now passed to createEVMClient internally.
// Wagmi hooks (useAccount, useChainId, etc.) handle state automatically.
Step 7: Additional Wagmi API Renames (same major version)
This wagmi release also includes several API renames. Deprecated aliases are provided but you should migrate:
| Old API | New API | Package |
|---|---|---|
useAccount() | useConnection() | wagmi |
useAccountEffect() | useConnectionEffect() | wagmi |
useSwitchAccount() | useSwitchConnection() | wagmi |
getAccount() | getConnection() | @wagmi/core |
switchAccount() | switchConnection() | @wagmi/core |
watchAccount() | watchConnection() | @wagmi/core |
WagmiConfig | WagmiProvider | wagmi (alias removed) |
useToken() | useReadContracts() | wagmi (hook removed) |
useFeeData() | useEstimateFeesPerGas() | wagmi (alias removed) |
normalizeChainId() | (removed) | wagmi (export removed) |
Step 8: Verify the Migration
After making changes, verify:
- Build succeeds —
npm run buildortsc --noEmitshould pass - No
@metamask/sdkimports remain — search your codebase:grep -r "@metamask/sdk" --include="*.ts" --include="*.tsx" --include="*.js" - Wallet connection works — test connecting via MetaMask browser extension
- Mobile deep-link works (if applicable) — test QR code / deep-link flow
- Chain switching works — test switching between configured chains
- Signing works — test message signing and transaction signing
Complete Before/After Example
Before (@wagmi/connectors <= 7.x + @metamask/sdk):
import { createConfig, http } from 'wagmi'
import { mainnet, sepolia, optimism } from 'wagmi/chains'
import { metaMask } from 'wagmi/connectors'
export const config = createConfig({
chains: [mainnet, sepolia, optimism],
connectors: [
metaMask({
dappMetadata: {
name: 'My Dapp',
url: window.location.origin,
},
useDeeplink: true,
}),
],
transports: {
[mainnet.id]: http(),
[sepolia.id]: http(),
[optimism.id]: http(),
},
})
After (wagmi >= 3.6 / @wagmi/connectors >= 8 + @metamask/connect-evm):
import { createConfig, http } from 'wagmi'
import { mainnet, sepolia, optimism } from 'wagmi/chains'
import { metaMask } from 'wagmi/connectors'
export const config = createConfig({
chains: [mainnet, sepolia, optimism],
connectors: [
metaMask({
dapp: {
name: 'My Dapp',
url: window.location.origin,
},
mobile: {
useDeeplink: true,
},
}),
],
transports: {
[mainnet.id]: http(),
[sepolia.id]: http(),
[optimism.id]: http(),
},
})
React Native Specific Migration
If you are using wagmi with React Native, the preferredOpenLink callback has moved:
// Before:
metaMask({
dappMetadata: { name: 'My RN App' },
preferredOpenLink: (link, target) => Linking.openURL(link),
useDeeplink: true,
})
// After:
metaMask({
dapp: { name: 'My RN App' },
mobile: {
preferredOpenLink: (link, target) => Linking.openURL(link),
useDeeplink: true,
},
})
Important Notes
@metamask/connect-evmis an optional peer dependency of@wagmi/connectors— you only need it if you use themetaMask()connector- The connector ID remains
'metaMaskSDK'and the name remains'MetaMask'— no changes to connector identity - The connector's
rdnsis['io.metamask', 'io.metamask.mobile']— unchanged - The
supportedNetworksmap is now auto-built from wagmi's configured chains and their default RPC URLs — you no longer need to passreadonlyRPCMap - The
dappMetadataparameter still works (it's mapped todappinternally) but is deprecated — migrate todappfor forward compatibility - The
loggingparameter still works (mapped todebug: true) but is deprecated - If no
dappconfig is provided, the connector defaults to{ name: window.location.hostname, url: window.location.href }in browsers, or{ name: 'wagmi' }in Node.js/SSR
More skills from the metamask-connect-cursor-plugin repository
View all 18 skillsmigrate-from-sdk
migrate MetaMask SDK to connect-evm and connect-solana
Jul 13EthereumMigrationSDKWeb3send-evm-transaction
send EVM transactions with MetaMask
Jul 13API DevelopmentEthereumWeb3send-solana-transaction
send Solana transactions via MetaMask
Jul 13PaymentsSolanaWeb3setup-evm-browser-app
scaffold EVM browser applications with MetaMask
Jul 13EthereumFrontendJavaScriptTypeScript +1setup-evm-react-app
scaffold React apps with MetaMask integration
Jul 13API DevelopmentEthereumFrontendReact +1setup-evm-react-native-app
scaffold React Native apps with MetaMask
Jul 13EthereumMobileReact NativeWeb3
More from MetaMask
View publishersmart-accounts-kit
build dApps with MetaMask Smart Accounts
smart-accounts-kit
Jul 13API DevelopmentAuthEthereumPermissions +1x402-payments
build x402 payment flows
smart-accounts-kit
Jul 13API DevelopmentPaymentsWeb3x402discovery
discover and use services
ocap-kernel
Jul 13API DevelopmentSearchmetamask
interact with MetaMask wallet capabilities
ocap-kernel
Jul 13API DevelopmentEthereumWeb3wallet
manage wallet balances and transactions
ocap-kernel
Jul 13EthereumPaymentsWeb3metamask-connect
integrate MetaMask into dApps
connect-monorepo
Jul 13API DevelopmentEthereumSolanawagmi +1