Contract Instances
A Contract Instance is a type-safe interface for performing contract-related actions with a specific ABI and address, created by the getContract
function.
Import
import { getContract } from 'viem'
import { getContract } from 'viem'
Usage
You can create a Contract Instance with the getContract
function by passing in a ABI, address, and Public and/or Wallet Client. Once created, you can call contract methods, fetch for events, listen to events, etc.
import { getContract } from 'viem'
import { wagmiAbi } from './abi'
import { publicClient, walletClient } from './client'
// 1. Create contract instance
const contract = getContract({
address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi: wagmiAbi,
// 1a. Insert a single client
client: publicClient,
// 1b. Or multiple clients
client: { publicClient, walletClient }
})
// 2. Call contract methods, fetch events, listen to events, etc.
const result = await contract.read.totalSupply()
const logs = await contract.getEvents.Transfer()
const unwatch = contract.watchEvent.Transfer(
{ from: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e' },
{ onLogs(logs) { console.log(logs) } }
)
import { getContract } from 'viem'
import { wagmiAbi } from './abi'
import { publicClient, walletClient } from './client'
// 1. Create contract instance
const contract = getContract({
address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi: wagmiAbi,
// 1a. Insert a single client
client: publicClient,
// 1b. Or multiple clients
client: { publicClient, walletClient }
})
// 2. Call contract methods, fetch events, listen to events, etc.
const result = await contract.read.totalSupply()
const logs = await contract.getEvents.Transfer()
const unwatch = contract.watchEvent.Transfer(
{ from: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e' },
{ onLogs(logs) { console.log(logs) } }
)
import { createPublicClient, http, injected } from 'viem'
import { mainnet } from 'viem/chains'
export const publicClient = createPublicClient({
chain: mainnet,
transport: http(),
})
export const walletClient = createPublicClient({
chain: mainnet,
transport: injected(window.ethereum),
})
import { createPublicClient, http, injected } from 'viem'
import { mainnet } from 'viem/chains'
export const publicClient = createPublicClient({
chain: mainnet,
transport: http(),
})
export const walletClient = createPublicClient({
chain: mainnet,
transport: injected(window.ethereum),
})
export const wagmiAbi = [
...
{
inputs: [],
name: 'totalSupply',
outputs: [{ type: 'uint256' }],
stateMutability: 'view',
type: 'function',
},
{
name: 'Transfer',
type: 'event',
inputs: [
{
indexed: true,
name: 'from',
type: 'address',
},
{ indexed: true, name: 'to', type: 'address' },
{
indexed: true,
name: 'tokenId',
type: 'uint256',
},
],
},
...
] as const;
export const wagmiAbi = [
...
{
inputs: [],
name: 'totalSupply',
outputs: [{ type: 'uint256' }],
stateMutability: 'view',
type: 'function',
},
{
name: 'Transfer',
type: 'event',
inputs: [
{
indexed: true,
name: 'from',
type: 'address',
},
{ indexed: true, name: 'to', type: 'address' },
{
indexed: true,
name: 'tokenId',
type: 'uint256',
},
],
},
...
] as const;
Using Contract Instances can make it easier to work with contracts if you don't want to pass the abi
and address
properties every time you perform contract actions, e.g. readContract
, writeContract
, estimateContractGas
, etc. Switch between the tabs below to see the difference between standalone Contract Actions and Contract Instance Actions:
import { getContract } from 'viem'
import { wagmiAbi } from './abi'
import { publicClient, walletClient } from './client'
const contract = getContract({
address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi: wagmiAbi,
client: {
publicClient,
walletClient,
}
})
const balance = await contract.read.balanceOf([
'0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
])
const hash = await contract.write.mint([69420])
const logs = await contract.getEvents.Transfer()
const unwatch = contract.watchEvent.Transfer(
{
from: '0xd8da6bf26964af9d7eed9e03e53415d37aa96045',
to: '0xa5cc3c03994db5b0d9a5eedd10cabab0813678ac'
},
{ onLogs: logs => console.log(logs) }
)
import { getContract } from 'viem'
import { wagmiAbi } from './abi'
import { publicClient, walletClient } from './client'
const contract = getContract({
address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi: wagmiAbi,
client: {
publicClient,
walletClient,
}
})
const balance = await contract.read.balanceOf([
'0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
])
const hash = await contract.write.mint([69420])
const logs = await contract.getEvents.Transfer()
const unwatch = contract.watchEvent.Transfer(
{
from: '0xd8da6bf26964af9d7eed9e03e53415d37aa96045',
to: '0xa5cc3c03994db5b0d9a5eedd10cabab0813678ac'
},
{ onLogs: logs => console.log(logs) }
)
import { wagmiAbi } from './abi'
import { publicClient, walletClient } from './client'
const balance = await publicClient.readContract({
address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi: wagmiAbi,
functionName: 'balanceOf',
args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC']
})
const hash = await walletClient.writeContract({
address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi: wagmiAbi,
functionName: 'mint',
args: [69420]
})
const unwatch = publicClient.watchContractEvent({
address: '0xfba3912ca04dd458c843e2ee08967fc04f3579c2',
abi: wagmiAbi,
eventName: 'Transfer',
args: {
from: '0xd8da6bf26964af9d7eed9e03e53415d37aa96045',
to: '0xa5cc3c03994db5b0d9a5eedd10cabab0813678ac'
},
onLogs: logs => console.log(logs)
})
import { wagmiAbi } from './abi'
import { publicClient, walletClient } from './client'
const balance = await publicClient.readContract({
address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi: wagmiAbi,
functionName: 'balanceOf',
args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC']
})
const hash = await walletClient.writeContract({
address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi: wagmiAbi,
functionName: 'mint',
args: [69420]
})
const unwatch = publicClient.watchContractEvent({
address: '0xfba3912ca04dd458c843e2ee08967fc04f3579c2',
abi: wagmiAbi,
eventName: 'Transfer',
args: {
from: '0xd8da6bf26964af9d7eed9e03e53415d37aa96045',
to: '0xa5cc3c03994db5b0d9a5eedd10cabab0813678ac'
},
onLogs: logs => console.log(logs)
})
TIP
While Contract Instances are great for reducing code duplication, they pull in multiple contract actions (e.g. createContractEventFilter
, estimateContractGas
, readContract
, simulateContract
, watchContractEvent
, writeContract
), so they can be a bit heavier than individual calls. If you only need a couple contract methods and you care about minimizing bundle size to the fullest extent, you may want to use individual calls instead.
Return Value
Contract instance object. Type is inferred.
Depending on if you create a contract instance with a Public Client, Wallet Client, or both, the methods available on the contract instance will vary.
With Public Client
If you pass in a publicClient
, the following methods are available:
With Wallet Client
If you pass in a walletClient
, the following methods are available:
Calling methods
If you are using TypeScript with viem, your editor will be able to provide autocomplete suggestions for the methods available on the contract instance, as well as the arguments and other options for each method.
In general, contract instance methods follow the following format:
// function
contract.(estimateGas|read|simulate|write).(functionName)(args, options)
// event
contract.(createEventFilter|getEvents|watchEvent).(eventName)(args, options)
// function
contract.(estimateGas|read|simulate|write).(functionName)(args, options)
// event
contract.(createEventFilter|getEvents|watchEvent).(eventName)(args, options)
If the contract function/event you are using does not accept arguments (e.g. function has no inputs, event has no indexed inputs), then you can omit the args
parameter so options
is the first and only parameter.
Parameters
address
- Type:
Address
The contract address.
const contract = getContract({
address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi: wagmiAbi,
client: {
publicClient,
walletClient,
}
})
const contract = getContract({
address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi: wagmiAbi,
client: {
publicClient,
walletClient,
}
})
abi
- Type:
Abi
The contract's ABI.
const contract = getContract({
address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi: wagmiAbi,
client: {
publicClient,
walletClient,
}
})
const contract = getContract({
address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi: wagmiAbi,
client: {
publicClient,
walletClient,
}
})
client
The Client used for performing contract actions.
const contract = getContract({
address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi: wagmiAbi,
client: publicClient,
})
const contract = getContract({
address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi: wagmiAbi,
client: publicClient,
})
You can also pass in multiple clients (ie. a Wallet Client and a Public Client):
const contract = getContract({
address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi: wagmiAbi,
client: {
publicClient,
walletClient
},
})
const contract = getContract({
address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
abi: wagmiAbi,
client: {
publicClient,
walletClient
},
})