On This Page

  • Core
  • Migration Guide

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 (now getPublicClient)
  • fetchSigner (now getWalletClient)
  • getWebSocketProvider (now getWebSocketPublicClient)

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 now createConfig. 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

  • ProviderPublicClient
  • SignerWalletClient
  • WebSocketProviderWebSocketPublicClient

createClientcreateConfig

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>
  )
}

getClientgetConfig

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 with mainnet & 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 with arbitrum & 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
})