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@latest
If 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:
createClient
configureChains
getProvider
(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
createClient
is 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
→PublicClient
Signer
→WalletClient
WebSocketProvider
→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 + value2
Using 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.isMetaMask
Renamed 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: bigint
fetchBlockNumber
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: bigint
fetchToken
Returns a bigint
Returns bigint
instead of a BigNumber
for totalSupply.value
.
const token = await fetchToken({
...
})
const value = token.totalSupply.value
// ^? const value: bigint
fetchTransaction
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:
chain
allChains
defaultChains
defaultL2Chains
chainId
etherscanBlockExplorers
alchemyRpcUrls
,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
defaultChains
export 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
defaultL2Chains
export 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.chainId
Removed 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.default
Removed 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.optimism
Chain
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.multicall3
waitForTransaction
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
})