Migration Guide
If you are coming from an earlier version of @wagmi/core, you will need to make sure to update the following APIs listed below.
1.x.x Breaking changes
Not ready to migrate yet? You can find the 0.10.x docs
here.
General
Removed ethers peer dependency
The ethers peer dependency has been removed in favour of viem.
npm uninstall ethers
npm i @wagmi/core@latest viem@latestIf your project is using modules from ethers directly, that are dependant on wagmi (e.g. BigNumber, etc), you will need to migrate to the viem-equivalent module. Check out the Ethers.js → viem migration guide.
If you have usages of ethers that are independent of wagmi, it is highly recommended to migrate to viem to take advantage of the smaller bundle size.
"Provider" & "Signer" terminology
Ethers Provider & Signer terminology is now known as viem's Public Client & Wallet Client terminology.
This directly affects:
createClientconfigureChainsgetProvider(nowgetPublicClient)fetchSigner(nowgetWalletClient)getWebSocketProvider(nowgetWebSocketPublicClient)
createClient
import { WagmiConfig, createConfig, mainnet } from 'wagmi'
- import { getDefaultProvider } from 'ethers'
+ import { createPublicClient, http } from 'viem'
+ import { mainnet } from 'viem/chains'
const config = createConfig({
autoConnect: true,
- provider: getDefaultProvider(),
+ publicClient: createPublicClient({
+ chain: mainnet,
+ transport: http()
+ })
})Note: You may notice that
createClientis nowcreateConfig. Don't worry – the migration for that is below.
configureChains
import { WagmiConfig, createConfig, configureChains, mainnet } from '@wagmi/core'
import { publicProvider } from '@wagmi/core/providers/public'
const {
chains,
- provider,
+ publicClient,
- webSocketProvider,
+ webSocketPublicClient
} = configureChains(
[mainnet],
[publicProvider()],
)
const config = createConfig({
autoConnect: true,
- provider,
+ publicClient,
- webSocketProvider,
+ webSocketPublicClient
})getProvider
- import { getProvider } from '@wagmi/core'
+ import { getPublicClient } from '@wagmi/core'
- const provider = getProvider()
+ const publicClient = getPublicClient()fetchSigner
- import { fetchSigner } from 'wagmi'
+ import { getWalletClient } from 'wagmi'
- const signer = await fetchSigner()
+ const walletClient = await getWalletClient()getWebSocketProvider
- import { getWebSocketProvider } from 'wagmi'
+ import { getWebSocketPublicClient } from 'wagmi'
- const webSocketProvider = getWebSocketProvider()
+ const webSocketPublicClient = getWebSocketPublicClient()Types
Provider→PublicClientSigner→WalletClientWebSocketProvider→WebSocketPublicClient
createClient → createConfig
The createClient function has been renamed to createConfig.
- import { createClient } from '@wagmi/core'
+ import { createConfig } from '@wagmi/core'
- const client = createClient({
+ const config = createConfig({
...
})WagmiClient
The WagmiConfig Context now takes the config prop instead of client.
import { createConfig, WagmiConfig } from 'wagmi'
const config = createConfig({
...
})
function App() {
return (
- <WagmiConfig client={client}>
+ <WagmiConfig config={config}>
/** your app */
</WagmiConfig>
)
}getClient → getConfig
If you are using getClient, that has been renamed to getConfig:
- import { getClient } from '@wagmi/core'
+ import { getConfig } from '@wagmi/core'
- const client = getClient()
+ const config = getConfig()BigNumber → native BigInt
All BigNumber instances are now platform native BigInt instances. This means you can no longer use arithmatic methods such as .add, .subtract, etc because BigInt is just a primitive type like number.
- const value = BigNumber.from('69420')
+ const value = 69420n- const value = BigNumber.from('69420')
+ const value = 69420n
- const value2 = BigNumber.from('42069')
+ const value2 = 42069n
- const value3 = value.add(value2)
+ const value3 = value + value2Using native BigInt with JSON.stringify will raise a TypeError as
BigInt values are not serializable. Read here for instructions to
mitigate.
from has been renamed to account
The from attribute has been renamed to account. Directly affects Actions that consist of a from parameter.
const config = prepareWriteContract({
...,
- from: '0x...'
+ account: '0x...'
})gasLimit has been renamed to gas
The gasLimit attribute has been renamed to gas, and still implies the same meaning. It was renamed to align closer to EIP-1474 and enforce consistency. Aligning closer to EIP-1474 means that you will not need to re-map from gas to gasLimit if you are deriving from an external source.
sendTransaction({
request: {
to: 'jxom.eth',
- gasLimit: 69420n,
+ gas: 69420n,
value: 1n
}
})Removed goerli export
Removed the goerli export from @wagmi/core. Goerli is now a deprecated testnet. You will now have to import it from wagmi/chains.
-import { goerli } from '@wagmi/core'
+import { goerli } from 'wagmi/chains'Removed window.ethereum global type
The window.ethereum global type has been removed in favor of an explicit @wagmi/core/window import.
+import '@wagmi/core/window';
const isMetaMask = window.ethereum.isMetaMaskRenamed the Ethereum type to WindowProvider
The Ethereum type has been renamed to WindowProvider.
Actions
connect
No longer returns the provider property. Use connector.getProvider() instead.
const result = await connect({
...
})
- const provider = result.provider
+ const provider = await result.connector.getProvider()fetchBalance
Returns a bigint
Returns a bigint instead of BigNumber for value. Maps to viem's getBalance.
const balance = await fetchBalance({
...
})
const value = balance.value
// ^? const value: bigintfetchBlockNumber
Returns a bigint
Returns a bigint instead of number. Maps to viem's getBlockNumber.
const blockNumber = await fetchBlockNumber({
// ^? const blockNumber: bigint
...
})fetchEnsAvatar
Replaced address with name
Replaced address with name in order to remove internal async call to resolve address to name. Maps to viem's getEnsAvatar.
+ const ensName = await fetchEnsName({
+ address: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
+ })
const avatar = await fetchEnsAvatar({
- address: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
+ name: ensName,
})fetchFeeData
Return type changes
Returns bigint instead of a BigNumber for gasPrice , maxFeePerGas , and maxPriorityFeePerGas.
const feeData = await fetchFeeData()
feeData.gasPrice
// ^? const gasPrice: bigint
feeData.maxFeePerGas
// ^? const maxFeePerGas: bigint
feeData.maxPriorityFeePerGas
// ^? const maxPriorityFeePerGas: bigintfetchToken
Returns a bigint
Returns bigint instead of a BigNumber for totalSupply.value.
const token = await fetchToken({
...
})
const value = token.totalSupply.value
// ^? const value: bigintfetchTransaction
Returns viem Transaction
Returns viem Transaction instead of an ethers Transaction. Maps to viem's getTransaction.
const transaction = await fetchTransaction({
// ^? const transaction: Transaction
...
})getContract
Returns viem Contract Instance
Returns viem Contract Instance instead of ethers Contract.
getProvider
Renamed to getPublicClient
Returns viem Public Client instead of ethers Provider.
- const provider = getProvider(...)
+ const publicClient = getPublicClient(...)getSigner
Renamed to getWalletClient
Returns viem Wallet Client instead of ethers Signer.
- const signer = await getSigner(...)
+ const walletClient = await getWalletClient(...)getWebSocketProvider
Renamed to getWebSocketPublicClient
Returns viem Public Client instead of ethers Provider.
- const webSocketProvider = getWebSocketProvider(...)
+ const webSocketPublicClient = getWebSocketPublicClient(...)multicall
Return type structure changed
When allowFailure is truthy (default), the return structure is now in the form of { error, result, status }[] instead of an array of contract function results (Result[]).
const data = await multicall({
...
})
- const result = data[0]
+ const { result } = data[0]The return type when allowFailure is falsy has not changed.
Removed console.warn logs for failing contract methods
The console.warn logs for failing contract methods has been removed. Failing methods can now be extracted from the error property of the return type.
const data = await multicall({
...
})
+ data.forEach(({ error, status }) => {
+ if (status === 'failure') console.warn(error.message)
+ })Removed overrides
The overrides parameter has been removed in favor of top-level blockNumber & blockTag parameters.
const data = await multicall({
...
- overrides: {
- blockTag: 'safe'
- }
+ blockTag: 'safe'
})prepareSendTransaction
Removed request
The request parameter has been removed in favor of top-level parameters. Maps to viem's sendTransaction parameters.
const request = await prepareSendTransaction({
- request: {
- to: 'jxom.eth',
- value: BigNumber.from('69420'),
- },
+ to: 'jxom.eth',
+ value: 69420n
})prepareWriteContract
Removed overrides
The overrides parameter has been removed in favor of top-level parameters. Maps to viem's simulateContract parameters.
const { config } = await prepareWriteContract({
address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1',
abi: wagmigotchiABI,
functionName: 'feed',
- overrides: {
- from: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
- value: BigNumber.from('69420'),
- },
+ account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
+ value: 69420n
})Return type structure changed
The returned request now returns the shape of viem's WriteContractParameters, instead of Ethers' TransactionRequest.
Removed abi, address, functionName from the return value, they now belong in request.
readContracts
Return type structure changed
When allowFailure is truthy (default), the return structure is now in the form of { error, result, status }[] instead of an array of contract function results (Result[]).
const data = await readContracts({
...
})
- const result = data[0]
+ const { result } = data[0]The return type when allowFailure is falsy has not changed.
Removed console.warn logs for failing contract methods
The console.warn logs for failing contract methods has been removed. Failing methods can now be extracted from the error property of the return type.
const data = await readContracts({
...
})
+ data.forEach(({ error, status }) => {
+ if (status === 'failure') console.warn(error.message)
+ })Removed overrides
The overrides parameter has been removed in favor of top-level blockNumber & blockTag parameters.
const data = await readContracts({
...
- overrides: {
- blockTag: 'safe'
- }
+ blockTag: 'safe'
})readContract
Removed overrides
The overrides parameter has been removed in favor of top-level blockNumber & blockTag parameters.
const data = await readContract({
...
- overrides: {
- blockTag: 'safe'
- }
+ blockTag: 'safe'
})sendTransaction
Removed request
The request parameter has been removed in favor of top-level parameters. Maps to viem's sendTransaction parameters.
const { hash } = await sendTransaction({
...
- request: {
- to: 'jxom.eth',
- value: BigNumber.from('69420'),
- },
+ to: 'jxom.eth',
+ value: 69420n
})wait has been removed from the return type
wait has been removed from the return type, favor waitForTransaction instead.
+ import { waitForTransaction } from '@wagmi/core'
const {
- wait
+ hash
} = await sendTransaction(...)
- const receipt = await wait()
+ const receipt = await waitForTransaction({ hash })signMessage
message no longer accepts a byte array
message no longer accepts a byte array, only a string value
signTypedData
value has been renamed to message
const signature = await signTypedData({
domain,
types,
primaryType: 'Mail',
- value,
+ message
})primaryType is now required
The primaryType attribute is now required. Aligns closer to EIP-712, and allows consumers to specify an alternative primary type. Previously, Ethers.js did some internal stuff to figure out the primary type. But it's not hard for a consumer to just provide that – and we believe it is more clear.
const signature = await signTypedData({
domain,
types,
+ primaryType: 'Mail',
message
})waitForTransaction
Renamed onSpeedUp to onReplaced
const waitForTransaction = await waitForTransaction({
hash: '0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060',
- onSpeedUp: (transaction) => console.log(transaction),
+ onReplaced: (transaction) => console.log(transaction)
})Return type changed
Now returns a viem TransactionReceipt instead of an Ethers TransactionReceipt.
watchPendingTransactions
Callback now returns batched transaction hashes
The callback now returns a batched array of transaction hashes, instead of callback being emitted several times with singular hashes.
const unwatch = watchPendingTransactions(
{},
- (hash) => console.log(hash),
+ (hashes) => console.log(hashes[0]),
)watchProvider
Renamed to watchPublicClient
Returns viem Public Client instead of ethers Provider.
- const unwatch = watchProvider({}, (provider) => { ... })
+ const unwatch = watchPublicClient({}, (publicClient) => { ... })watchSigner
Renamed to watchWalletClient
Returns viem Wallet Client instead of ethers Signer.
- const unwatch = watchSigner({}, (signer) => { ... })
+ const unwatch = watchWalletClient({}, (walletClient) => { ... })watchWebSocketProvider
Renamed to watchWebSocketPublicClient
Returns viem Public Client instead of ethers Provider.
- const unwatch = watchWebSocketProvider({}, (webSocketProvider) => { ... })
+ const unwatch = watchWebSocketPublicClient({}, (webSocketPublicClient) => { ... })writeContract
wait has been removed from the return type
wait has been removed from the return type, favor waitForTransaction instead.
+ import { waitForTransaction } from '@wagmi/core'
const {
- wait
+ hash
} = await writeContract(...)
- const receipt = await wait()
+ const receipt = await waitForTransaction({ hash })Removed overrides
The overrides parameter has been removed in favor of top-level parameters. Maps to viem's writeContract parameters.
const { config } = await writeContract({
...
- overrides: {
- from: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
- value: BigNumber.from('69420'),
- },
+ account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
+ value: 69420n
})watchContractEvent
Callback now returns array of logs
Callback now returns an array of Event Logs (with included decoded args), instead of positional decoded args with the log.
const unwatch = watchContractEvent(
{
address: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e',
abi: ensRegistryABI,
eventName: 'NewOwner',
},
- (node, label, owner) => {
+ (logs) => {
- console.log(node, label, owner)
+ const { args } = logs[0]
+ console.log(args.node, args.label, args.owner)
},
)Removed once
The once parameter has been removed. Use unwatch to cleanup the listener instead.
const unwatch = watchContractEvent(
{
address: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e',
abi: ensRegistryABI,
eventName: 'NewOwner',
- once: true
},
(logs) => {
const { args } = logs[0]
console.log(args.node, args.label, args.owner)
+ unwatch()
},
)configureChains
Removed quorum support
Removed quorum support: priority, minQuorum and targetQuorum (for now). viem does not support quorum in the fallback Transport yet, but will in the future!
Connectors
The breaking changes below only applies if you are building a Connector on top of wagmi.
Renamed getSigner to getWalletClient
The getSigner method has been renamed to getWalletClient, and also returns viem's WalletClient instead of an Ethers.js Signer
- async getSigner({ chainId }: { chainId?: number } = {}) {
+ async getWalletClient({ chainId }: { chainId?: number } = {}) {
const [provider, account] = await Promise.all([
this.getProvider(),
this.getAccount(),
])
+ const chain = this.chains.find((x) => x.id === chainId) || this.chains[0]
- return new providers.Web3Provider(
- provider,
- chainId,
- ).getSigner(account)
+ return createWalletClient({
+ account,
+ chain,
+ transport: custom(provider),
+ })
}Errors
ChainDoesNotSupportMulticallError
Use ChainDoesNotSupportContract from viem instead.
ContractMethodDoesNotExistError
Use ContractFunctionExecutionError from viem instead.
ContractMethodNoResultError
Use ContractFunctionZeroDataError from viem instead.
ContractMethodRevertedError
Use ContractFunctionRevertedError from viem instead.
ContractResultDecodeError
Use ContractFunctionExecutionError from viem instead.
ProviderRpcError
Use ProviderRpcError from viem instead.
ResourceUnavailableError
Use ResourceUnavailableRpcError from viem instead.
0.10.x Breaking changes
WalletConnectConnector
WalletConnect v1 has been sunset and WalletConnectConnector now uses WalletConnect v2 by default.
wagmi still supports WalletConnect v1 via a WalletConnectLegacyConnector, however, it is recommended to migrate to WalletConnect v2. Instructions can be found here.
If you are already using WalletConnect v2:
The version flag has been omitted, and qrcode has been renamed to showQrModal.
import { WalletConnectConnector } from 'wagmi/connectors/walletConnect'
const connector = new WalletConnectConnector({
options: {
- version: '2',
projectId: '...',
- qrcode: true,
+ showQrModal: true,
},
})Read more on WalletConnectConnector
If you are still using WalletConnect v1:
You must migrate to the WalletConnect v2
Connector before June 28, after which, the
WalletConnectLegacyConnector will be removed.
-import { WalletConnectConnector } from '@wagmi/core/connectors/walletConnect'
+import { WalletConnectLegacyConnector } from '@wagmi/core/connectors/walletConnectLegacy'
-const connector = new WalletConnectConnector({
+const connector = new WalletConnectLegacyConnector({
options: {
qrcode: true,
},
})Read more on WalletConnectLegacyConnector
0.9.x Breaking changes
Upgrade to typescript@>=4.9.4
TypeScript 5.0 is coming soon and has some great features we are excited to bring into wagmi. To prepare for this, update your TypeScript version to 4.9.4 or higher. There are likely no breaking changes if you are coming from typescript@4.7.x || typescript@4.8.x.
0.8.x Breaking changes
Chain exports
With the introduction of the @wagmi/core/chains entrypoint, @wagmi/core no longer exports the following:
chainallChainsdefaultChainsdefaultL2ChainschainIdetherscanBlockExplorersalchemyRpcUrls,infuraRpcUrls,publicRpcUrls
Read below for migration steps.
Removed chain
The chain export has been removed. @wagmi/core now only exports the mainnet & goerli chains. If you need to use an alternative chain (polygon, optimism, etc), you will need to import it from the @wagmi/core/chains entrypoint.
import {
- chain
configureChains
} from '@wagmi/core'
+ import { mainnet, polygon, optimism } from '@wagmi/core/chains'
const { ... } = configureChains(
- [chain.mainnet, chain.polygon, chain.optimism],
+ [mainnet, polygon, optimism],
{
...
}
)Removed allChains
The allChains export has been removed. If you need a list of all chains, you can utilize @wagmi/core/chains entrypoint.
- import { allChains } from '@wagmi/core'
+ import * as allChains from '@wagmi/core/chains'
const { ... } = configureChains(allChains, ...)Removed defaultChains & defaultL2Chains
The defaultChains & defaultL2Chains exports have been removed. If you still need the defaultChains or defaultL2Chains exports, you can build them yourself:
- import { defaultChains } from '@wagmi/core'
+ import { mainnet, goerli } from '@wagmi/core/chains'
+ const defaultChains = [mainnet, goerli]The
defaultChainsexport was previously populated withmainnet&goerli.
- import { defaultL2Chains } from '@wagmi/core'
+ import {
+ arbitrum,
+ arbitrumGoerli,
+ polygon,
+ polygonMumbai,
+ optimism,
+ optimismGoerli
+ } from '@wagmi/core/chains'
+ const defaultL2Chains = [
+ arbitrum,
+ arbitrumGoerli,
+ polygon,
+ polygonMumbai,
+ optimism
+ optimismGoerli
+ ]The
defaultL2Chainsexport was previously populated witharbitrum&optimism.
Removed chainId
The chainId export has been removed. You can extract a chain ID from the chain itself.
- import { chainId } from '@wagmi/core'
+ import { mainnet, polygon, optimism } from '@wagmi/core/chains'
-const mainnetChainId = chainId.mainnet
-const polygonChainId = chainId.polygon
-const optimismChainId = chainId.optimism
+const mainnetChainId = mainnet.chainId
+const polygonChainId = polygon.chainId
+const optimismChainId = optimism.chainIdRemoved etherscanBlockExplorers
The etherscanBlockExplorers export has been removed. You can extract a block explorer from the chain itself.
- import { etherscanBlockExplorers } from '@wagmi/core'
+ import { mainnet, polygon, optimism } from '@wagmi/core/chains'
-const mainnetEtherscanBlockExplorer = etherscanBlockExplorers.mainnet
-const polygonEtherscanBlockExplorer = etherscanBlockExplorers.polygon
-const optimismEtherscanBlockExplorer = etherscanBlockExplorers.optimism
+const mainnetEtherscanBlockExplorer = mainnet.blockExplorers.default
+const polygonEtherscanBlockExplorer = polygon.blockExplorers.default
+const optimismEtherscanBlockExplorer = optimism.blockExplorers.defaultRemoved alchemyRpcUrls, infuraRpcUrls & publicRpcUrls
The alchemyRpcUrls, infuraRpcUrls & publicRpcUrls exports have been removed. You can extract a RPC URL from the chain itself.
- import { alchemyRpcUrls, infuraRpcUrls, publicRpcUrls } from '@wagmi/core'
+ import { mainnet } from '@wagmi/core/chains'
-const mainnetAlchemyRpcUrl = alchemyRpcUrls.mainnet
-const mainnetInfuraRpcUrl = infuraRpcUrls.mainnet
-const mainnetOptimismRpcUrl = publicRpcUrls.mainnet
+const mainnetAlchemyRpcUrl = mainnet.rpcUrls.alchemy
+const mainnetInfuraRpcUrl = mainnet.rpcUrls.infura
+const mainnetOptimismRpcUrl = mainnet.rpcUrls.optimismChain type
RPC URLs
The rpcUrls shape has changed to include an array of URLs, and also the transport method (http or webSocket):
type Chain = {
...
rpcUrls: {
- [key: string]: string
+ [key: string]: {
+ http: string[]
+ webSocket: string[]
+ }
}
...
}Note that you will also need to ensure that usage is migrated:
- const rpcUrl = mainnet.rpcUrls.alchemy
+ const rpcUrl = mainnet.rpcUrls.alchemy.http[0]Contracts
The multicall and ens attributes have been moved into the contracts object:
type Contract = {
address: Address
blockCreated?: number
}
type Chain = {
...
- multicall: Contract
- ens: Contract
+ contracts: {
+ multicall3: Contract
+ ensRegistry: Contract
+ }
...
}Note that you will also need to ensure that usage is migrated:
- const multicallContract = mainnet.multicall
+ const multicallContract = mainnet.contracts.multicall3waitForTransaction
Behavioral changes
waitForTransaction will throw an error if the transaction has been reverted or cancelled.
Configuration changes
Removed the wait config option on waitForTransaction. Use the transaction hash instead.
const { data } = await waitForTransaction({
- wait: transaction.wait
+ hash: transaction.hash
})