Skip to content

watchEvent

Watches and returns emitted Event Logs.

This Action will batch up all the Event Logs found within the pollingInterval, and invoke them via onLogs.

watchEvent will attempt to create an Event Filter and listen to changes to the Filter per polling interval, however, if the RPC Provider does not support Filters (ie. eth_newFilter), then watchEvent will fall back to using getLogs instead.

Usage

By default, you can watch all broadcasted events to the blockchain by just passing onLogs.

These events will be batched up into Event Logs and sent to onLogs:

example.ts
import { publicClient } from './client'
import { wagmiAbi } from './abi'
 
const unwatch = publicClient.watchEvent({
  onLogs: logs => console.log(logs)
})
> [{ ... }, { ... }, { ... }]
> [{ ... }, { ... }]
> [{ ... }, { ... }, { ... }, { ... }]

Scoping

You can also scope watchEvent to a set of given attributes (listed below).

Address

watchEvent can be scoped to an address:

example.ts
import { publicClient } from './client'
import { wagmiAbi } from './abi'
 
const unwatch = publicClient.watchEvent({
  address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', 
  onLogs: logs => console.log(logs)
})
> [{ ... }, { ... }, { ... }]
> [{ ... }, { ... }]
> [{ ... }, { ... }, { ... }, { ... }]

Event

watchEvent can be scoped to an event.

The event argument takes in an event in ABI format – we have a parseAbiItem utility that you can use to convert from a human-readable event signature → ABI.

example.ts
import { parseAbiItem } from 'viem'
import { publicClient } from './client'
import { wagmiAbi } from './abi'
 
const unwatch = publicClient.watchEvent({
  address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
  event: parseAbiItem('event Transfer(address indexed from, address indexed to, uint256 value)'), 
  onLogs: logs => console.log(logs)
})
> [{ ... }, { ... }, { ... }]
> [{ ... }, { ... }]
> [{ ... }, { ... }, { ... }, { ... }]

By default, event accepts the AbiEvent type:

example.ts
import { publicClient } from './client'
 
const unwatch = publicClient.watchEvent(publicClient, {
  address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
  event: { 
    name: 'Transfer', 
    inputs: [
      { type: 'address', indexed: true, name: 'from' },
      { type: 'address', indexed: true, name: 'to' },
      { type: 'uint256', indexed: false, name: 'value' }
    ] 
  },
  onLogs: logs => console.log(logs)
})

Arguments

watchEvent can be scoped to given indexed arguments on the event:

example.ts
import { parseAbiItem } from 'viem'
import { publicClient } from './client'
 
const unwatch = publicClient.watchEvent({
  address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
  event: parseAbiItem('event Transfer(address indexed from, address indexed to, uint256 value)'),
  args: { 
    from: '0xd8da6bf26964af9d7eed9e03e53415d37aa96045',
    to: '0xa5cc3c03994db5b0d9a5eedd10cabab0813678ac'
  },
  onLogs: logs => console.log(logs)
})
// > [{ ... }, { ... }, { ... }]
// > [{ ... }, { ... }]
// > [{ ... }, { ... }, { ... }, { ... }]

Only indexed arguments in event are candidates for args.

These arguments can also be an array to indicate that other values can exist in the position:

import { parseAbiItem } from 'viem'
 
const unwatch = publicClient.watchEvent({
  address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
  event: parseAbiItem('event Transfer(address indexed from, address indexed to, uint256 value)'),
  args: { 
    // '0xd8da...' OR '0xa5cc...' OR '0xa152...'
    from: [
      '0xd8da6bf26964af9d7eed9e03e53415d37aa96045', 
      '0xa5cc3c03994db5b0d9a5eedd10cabab0813678ac',
      '0xa152f8bb749c55e9943a3a0a3111d18ee2b3f94e',
    ],
  },
  onLogs: logs => console.log(logs)
})

Multiple Events

watchEvent can be scoped to multiple events:

import { parseAbi } from 'viem'
 
const unwatch = publicClient.watchEvent({
  events: parseAbi([ 
    'event Approval(address indexed owner, address indexed sender, uint256 value)',
    'event Transfer(address indexed from, address indexed to, uint256 value)',
  ]),
  onLogs: logs => console.log(logs)
})

Note: watchEvent scoped to multiple events cannot be also scoped with indexed arguments (args).

Returns

UnwatchFn

A function that can be invoked to stop watching for new Event Logs.

Parameters

onLogs

  • Type: (logs: Log[]) => void

The new Event Logs.

const unwatch = publicClient.watchEvent(
  { onLogs: logs => console.log(logs) } 
)

address (optional)

  • Type: Address | Address[]

The contract address or a list of addresses from which Logs should originate.

const unwatch = publicClient.watchEvent(
  { 
    address: '0xfba3912ca04dd458c843e2ee08967fc04f3579c2', 
    onLogs: logs => console.log(logs) 
  }
)

event (optional)

The event in ABI format.

A parseAbiItem utility is exported from viem that converts from a human-readable event signature → ABI.

import { parseAbiItem } from 'viem'
 
const unwatch = publicClient.watchEvent(
  { 
    address: '0xfba3912ca04dd458c843e2ee08967fc04f3579c2',
    event: parseAbiItem('event Transfer(address indexed from, address indexed to, uint256 value)'), 
    onLogs: logs => console.log(logs) 
  }
)

args (optional)

  • Type: Inferred.

A list of indexed event arguments.

import { parseAbiItem } from 'viem'
 
const unwatch = publicClient.watchEvent(
  { 
    address: '0xfba3912ca04dd458c843e2ee08967fc04f3579c2',
    event: parseAbiItem('event Transfer(address indexed from, address indexed to, uint256 value)'),
    args: { 
      from: '0xd8da6bf26964af9d7eed9e03e53415d37aa96045',
      to: '0xa5cc3c03994db5b0d9a5eedd10cabab0813678ac'
    },
    onLogs: logs => console.log(logs) 
  }
)

batch (optional)

  • Type: boolean
  • Default: true

Whether or not to batch the Event Logs between polling intervals.

const unwatch = publicClient.watchEvent(
  { 
    batch: false, 
    onLogs: logs => console.log(logs),
  }
)

onError (optional)

  • Type: (error: Error) => void

Error thrown from listening for new Event Logs.

import { http, createPublicClient } from 'viem'
import { mainnet } from 'viem/chains'
 
export const publicClient = createPublicClient({
  chain: mainnet,
  transport: http(),
})
// ---cut---
const unwatch = publicClient.watchEvent(
  { 
    onError: error => console.log(error) 
    onLogs: logs => console.log(logs),
  }
)
## Errors were thrown in the sample, but not included in an error tag These errors were not marked as being expected: 1005. Expected: // @errors: 1005 Compiler Errors: index.ts [1005] 301 - ',' expected.

poll (optional)

  • Type: boolean
  • Default: false for WebSocket Clients, true for non-WebSocket Clients

Whether or not to use a polling mechanism to check for new logs instead of a WebSocket subscription.

This option is only configurable for Clients with a WebSocket Transport.

import { createPublicClient, webSocket } from 'viem'
import { mainnet } from 'viem/chains'
 
const publicClient = createPublicClient({
  chain: mainnet,
  transport: webSocket()
})
 
const unwatch = publicClient.watchEvent(
  { 
    onLogs: logs => console.log(logs),
    poll: true, 
  }
)

pollingInterval (optional)

  • Type: number

Polling frequency (in ms). Defaults to the Client's pollingInterval config.

const unwatch = publicClient.watchEvent(
  { 
    pollingInterval: 1_000, 
    onLogs: logs => console.log(logs),
  }
)

fromBlock (optional)

  • Type: bigint

The block number to start listening for logs from.

const unwatch = publicClient.watchEvent(
  { 
    fromBlock: 1n, 
    onLogs: logs => console.log(logs),
  }
)

Live Example

Check out the usage of watchEvent in the live Event Logs Example below.

JSON-RPC Methods

When poll true and RPC Provider supports eth_newFilter: When poll true RPC Provider does not support eth_newFilter:
  • Calls eth_getLogs for each block between the polling interval.
When poll false and WebSocket Transport:
  • Uses a WebSocket subscription via eth_subscribe and the "logs" event.