watchContractEvent
Watches and returns emitted contract event logs with ABI decoding
Unlike watchEvent, watchContractEvent:
- Requires an ABI for event decoding
- Automatically encodes event topics from ABI
- Decodes event logs using the ABI
- Filters by EventName
Watch actions return a channel of events. Cancel the context to stop watching.
Import
Import the public actions package so you can call this action.
import "github.com/ChefBingbong/viem-go/actions/public"Usage
An example showing how to watch for a specific contract event and decode logs using an ABI.
import ( "context" "fmt" "log"
"github.com/ethereum/go-ethereum/common" "github.com/ChefBingbong/viem-go/actions/public" "github.com/ChefBingbong/viem-go/abi" "github.com/ChefBingbong/viem-go/client" "github.com/ChefBingbong/viem-go/client/transport" "github.com/ChefBingbong/viem-go/chain/definitions")
ctx, cancel := context.WithCancel(context.Background())defer cancel()
publicClient, err := client.CreatePublicClient(client.PublicClientConfig{ Chain: definitions.Mainnet, Transport: transport.HTTP("https://eth.llamarpc.com"),})if err != nil { log.Fatal(err)}defer func() { _ = publicClient.Close() }()
contractAddr := common.HexToAddress("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48")erc20ABI, _ := abi.ParseABI(`[{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]`)
events := public.WatchContractEvent(ctx, publicClient, public.WatchContractEventParameters{ Address: contractAddr, ABI: erc20ABI, EventName: "Transfer", Batch: true,})
for event := range events { if event.Error != nil { log.Printf("error: %v", event.Error) continue } fmt.Printf("Received %d Transfer logs", len(event.Logs))}Returns
<-chan WatchContractEventEvent
A channel that emits WatchContractEventEvent structs containing:
Logs []formatters.Log- The decoded event logs (may contain multiple whenBatchis true)Error error- Any error that occurred
Parameters
Configuration options accepted by this action.
Address
- Type:
any(acceptscommon.Address,*common.Address,[]common.Address,string, or[]string) - Required
The contract address(es) to filter logs from.
import ( "github.com/ethereum/go-ethereum/common" "github.com/ChefBingbong/viem-go/actions/public")
contractAddr := common.HexToAddress("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48")events := public.WatchContractEvent(ctx, publicClient, public.WatchContractEventParameters{ Address: contractAddr, ABI: erc20ABI, EventName: "Transfer",})ABI
- Type:
*abi.ABI - Required
The contract ABI for decoding event logs.
import "github.com/ChefBingbong/viem-go/abi"
erc20ABI, _ := abi.ParseABI(`[{"anonymous":false,"inputs":[...],"name":"Transfer",...}]`)events := public.WatchContractEvent(ctx, publicClient, public.WatchContractEventParameters{ Address: contractAddr, ABI: erc20ABI, EventName: "Transfer",})EventName
- Type:
string - Required
The name of the event to filter for. Must match an event in the ABI.
events := public.WatchContractEvent(ctx, publicClient, public.WatchContractEventParameters{ Address: contractAddr, ABI: erc20ABI, EventName: "Transfer",})Args
- Type:
map[string]any - Optional
Indexed event arguments to filter by. Keys are parameter names, values are the expected values.
senderAddr := common.HexToAddress("0xd8da6bf26964af9d7eed9e03e53415d37aa96045")events := public.WatchContractEvent(ctx, publicClient, public.WatchContractEventParameters{ Address: contractAddr, ABI: erc20ABI, EventName: "Transfer", Args: map[string]any{"from": senderAddr},})Batch
- Type:
bool - Default:
true - Optional
Whether to batch logs together. When true, multiple logs are collected and emitted together. When false, each log is emitted as a separate event.
events := public.WatchContractEvent(ctx, publicClient, public.WatchContractEventParameters{ Address: contractAddr, ABI: erc20ABI, EventName: "Transfer", Batch: false,})FromBlock
- Type:
*uint64 - Optional
The block number to start watching from. If set, forces polling mode.
fromBlock := uint64(16330000)events := public.WatchContractEvent(ctx, publicClient, public.WatchContractEventParameters{ Address: contractAddr, ABI: erc20ABI, EventName: "Transfer", FromBlock: &fromBlock,})Poll
- Type:
*bool - Default:
falsefor WebSocket Transports,truefor non-WebSocket Transports - Optional
Whether or not to use a polling mechanism instead of a WebSocket subscription.
poll := trueevents := public.WatchContractEvent(ctx, publicClient, public.WatchContractEventParameters{ Address: contractAddr, ABI: erc20ABI, EventName: "Transfer", Poll: &poll,})PollingInterval
- Type:
time.Duration - Default: Client's
PollingInterval - Optional
The interval between polls when using polling mode.
import "time"
events := public.WatchContractEvent(ctx, publicClient, public.WatchContractEventParameters{ Address: contractAddr, ABI: erc20ABI, EventName: "Transfer", PollingInterval: 5 * time.Second,})Strict
- Type:
bool - Default:
false - Optional
Determines whether logs must match the event definition exactly. When true, logs with mismatched indexed/non-indexed arguments are skipped.
events := public.WatchContractEvent(ctx, publicClient, public.WatchContractEventParameters{ Address: contractAddr, ABI: erc20ABI, EventName: "Transfer", Strict: true,})WorkerPoolSize
- Type:
int - Default:
4 - Optional
The number of workers for parallel log decoding.
events := public.WatchContractEvent(ctx, publicClient, public.WatchContractEventParameters{ Address: contractAddr, ABI: erc20ABI, EventName: "Transfer", WorkerPoolSize: 8,})JSON-RPC Method
Underlying JSON-RPC methods used by this action.
- When polling with filter support:
- Calls
eth_newFilterto create a filter - Calls
eth_getFilterChangeson a polling interval
- Calls
- When polling without filter support: calls
eth_getLogsfor each block range - When subscribing: uses
eth_subscribewith"logs"event