Chain Properties
Some chains support additional properties related to blocks and transactions. This is powered by Viem's formatters and serializers. For example, Celo, ZkSync, OP Stack chains support all support additional properties. In order to use these properties in a type-safe way, there are a few things you should be aware of.
TIP
Make sure you follow the TypeScript guide's Config Types section before moving on. The easiest way to do this is to use Declaration Merging to "register" your config
globally with TypeScript.
import { http, createConfig } from 'wagmi'
import { base, celo, mainnet } from 'wagmi/chains'
export const config = createConfig({
chains: [base, celo, mainnet],
transports: {
[base.id]: http(),
[celo.id]: http(),
[mainnet.id]: http(),
},
})
declare module 'wagmi' {
interface Register {
config: typeof config
}
}
import { http, createConfig } from 'wagmi'
import { base, celo, mainnet } from 'wagmi/chains'
export const config = createConfig({
chains: [base, celo, mainnet],
transports: {
[base.id]: http(),
[celo.id]: http(),
[mainnet.id]: http(),
},
})
declare module 'wagmi' {
interface Register {
config: typeof config
}
}
Narrowing Parameters
Once your Config is registered with TypeScript, you are ready to access chain-specifc properties! For example, Celo's feeCurrency
, gatewayFee
, and gatewayFeeRecipient
are all available.
import { parseEther } from 'viem'
import { useSimulateContract } from 'wagmi'
const result = useSimulateContract({
to: '0xd2135CfB216b74109775236E36d4b433F1DF507B',
value: parseEther('0.01'),
feeCurrency: '0x…',
gatewayFee: 100n,
gatewayFeeRecipient: '0x…',
})
import { parseEther } from 'viem'
import { useSimulateContract } from 'wagmi'
const result = useSimulateContract({
to: '0xd2135CfB216b74109775236E36d4b433F1DF507B',
value: parseEther('0.01'),
feeCurrency: '0x…',
gatewayFee: 100n,
gatewayFeeRecipient: '0x…',
})
import { http, createConfig } from 'wagmi'
import { base, celo, mainnet } from 'wagmi/chains'
export const config = createConfig({
chains: [base, celo, mainnet],
transports: {
[base.id]: http(),
[celo.id]: http(),
[mainnet.id]: http(),
},
})
declare module 'wagmi' {
interface Register {
config: typeof config
}
}
import { http, createConfig } from 'wagmi'
import { base, celo, mainnet } from 'wagmi/chains'
export const config = createConfig({
chains: [base, celo, mainnet],
transports: {
[base.id]: http(),
[celo.id]: http(),
[mainnet.id]: http(),
},
})
declare module 'wagmi' {
interface Register {
config: typeof config
}
}
This is great, but if you have multiple chains that support additional properties, your autocomplete could be overwhelmed with all of them. By setting the chainId
property to a specifc value (e.g. celo.id
), you can narrow parameters to a single chain.
import { parseEther } from 'viem'
import { useSimulateContract } from 'wagmi'
import { celo } from 'wagmi/chains'
const result = useSimulateContract({
to: '0xd2135CfB216b74109775236E36d4b433F1DF507B',
value: parseEther('0.01'),
chainId: celo.id,
feeCurrency: '0x…',
// ^? (property) feeCurrency?: `0x${string}` | undefined
gatewayFee: 100n,
// ^? (property) gatewayFee?: bigint | undefined
gatewayFeeRecipient: '0x…',
// ^? (property) gatewayFeeRecipient?: `0x${string}` | undefined
})
import { parseEther } from 'viem'
import { useSimulateContract } from 'wagmi'
import { celo } from 'wagmi/chains'
const result = useSimulateContract({
to: '0xd2135CfB216b74109775236E36d4b433F1DF507B',
value: parseEther('0.01'),
chainId: celo.id,
feeCurrency: '0x…',
// ^? (property) feeCurrency?: `0x${string}` | undefined
gatewayFee: 100n,
// ^? (property) gatewayFee?: bigint | undefined
gatewayFeeRecipient: '0x…',
// ^? (property) gatewayFeeRecipient?: `0x${string}` | undefined
})
import { http, createConfig } from 'wagmi'
import { base, celo, mainnet } from 'wagmi/chains'
export const config = createConfig({
chains: [base, celo, mainnet],
transports: {
[base.id]: http(),
[celo.id]: http(),
[mainnet.id]: http(),
},
})
declare module 'wagmi' {
interface Register {
config: typeof config
}
}
import { http, createConfig } from 'wagmi'
import { base, celo, mainnet } from 'wagmi/chains'
export const config = createConfig({
chains: [base, celo, mainnet],
transports: {
[base.id]: http(),
[celo.id]: http(),
[mainnet.id]: http(),
},
})
declare module 'wagmi' {
interface Register {
config: typeof config
}
}
Narrowing Return Types
Return types can also have chain-specific properties attached to them. There are a couple approaches for extracting these properties.
chainId
Parameter
Not only can you use the chainId
parameter to narrow parameters, you can also use it to narrow the return type.
import { useWaitForTransactionReceipt } from 'wagmi'
import { zkSync } from 'wagmi/chains'
const { data } = useWaitForTransactionReceipt({
chainId: zkSync.id,
hash: '0x16854fcdd0219cacf5aec5e4eb2154dac9e406578a1510a6fc48bd0b67e69ea9',
})
data?.logs
// ^? (property) logs: ZkSyncLog[] | undefined
import { useWaitForTransactionReceipt } from 'wagmi'
import { zkSync } from 'wagmi/chains'
const { data } = useWaitForTransactionReceipt({
chainId: zkSync.id,
hash: '0x16854fcdd0219cacf5aec5e4eb2154dac9e406578a1510a6fc48bd0b67e69ea9',
})
data?.logs
// ^? (property) logs: ZkSyncLog[] | undefined
import { http, createConfig } from 'wagmi'
import { base, celo, mainnet } from 'wagmi/chains'
export const config = createConfig({
chains: [base, celo, mainnet],
transports: {
[base.id]: http(),
[celo.id]: http(),
[mainnet.id]: http(),
},
})
declare module 'wagmi' {
interface Register {
config: typeof config
}
}
import { http, createConfig } from 'wagmi'
import { base, celo, mainnet } from 'wagmi/chains'
export const config = createConfig({
chains: [base, celo, mainnet],
transports: {
[base.id]: http(),
[celo.id]: http(),
[mainnet.id]: http(),
},
})
declare module 'wagmi' {
interface Register {
config: typeof config
}
}
chainId
Data Property
Wagmi internally will set a chainId
property on return types that you can use to narrow results. The chainId
is determined from the chainId
parameter or global state (e.g. connector). You can use this property to help TypeScript narrow the type.
import { useWaitForTransactionReceipt } from 'wagmi'
import { zkSync } from 'wagmi/chains'
const { data } = useWaitForTransactionReceipt({
hash: '0x16854fcdd0219cacf5aec5e4eb2154dac9e406578a1510a6fc48bd0b67e69ea9',
})
if (result.data?.chainId === zkSync.id) {
data?.logs
// ^? (property) logs: ZkSyncLog[] | undefined
}
import { useWaitForTransactionReceipt } from 'wagmi'
import { zkSync } from 'wagmi/chains'
const { data } = useWaitForTransactionReceipt({
hash: '0x16854fcdd0219cacf5aec5e4eb2154dac9e406578a1510a6fc48bd0b67e69ea9',
})
if (result.data?.chainId === zkSync.id) {
data?.logs
// ^? (property) logs: ZkSyncLog[] | undefined
}
import { http, createConfig } from 'wagmi'
import { base, celo, mainnet } from 'wagmi/chains'
export const config = createConfig({
chains: [base, celo, mainnet],
transports: {
[base.id]: http(),
[celo.id]: http(),
[mainnet.id]: http(),
},
})
declare module 'wagmi' {
interface Register {
config: typeof config
}
}
import { http, createConfig } from 'wagmi'
import { base, celo, mainnet } from 'wagmi/chains'
export const config = createConfig({
chains: [base, celo, mainnet],
transports: {
[base.id]: http(),
[celo.id]: http(),
[mainnet.id]: http(),
},
})
declare module 'wagmi' {
interface Register {
config: typeof config
}
}
Troubleshooting
If chain properties aren't working, make sure TypeScript is configured correctly. Not all chains have additional properties, to check which ones do, see the Viem repo (chains that have a top-level directory under src/chains
support additional properties).