Skip to content

Events

Retrieves events from the blockchain matching specified filter criteria with pagination support. Events are emitted by smart contracts during transaction execution and can be filtered by contract address, event keys, and block range.

Method Signature

func (provider *Provider) Events(ctx context.Context, input EventsInput) (*EventChunk, error)

Source: events.go

Parameters

  • ctx (context.Context): Context for request cancellation and timeout
  • input (EventsInput): Filter parameters and pagination settings for event retrieval

Returns

  • *EventChunk: Chunk of events matching the filter with optional continuation token for pagination
  • error: Error if the request fails

Type Definitions

  1. Input Type (EventsInput) embeds EventFilter for filtering criteria and ResultPageRequest for pagination controls.
  2. Result Type (EventChunk) contains an array of EmittedEvent and an optional continuation token for fetching more results.
  3. Filter Types (EventFilter, ResultPageRequest) define block range, contract address, event keys, chunk size, and continuation token.
  4. Event Types (EmittedEvent, Event, EventContent) represent the actual event data with contract address, keys, data, block information, and transaction hash.

The method accepts an EventsInput with embedded filter and pagination settings, returning an EventChunk with events and a continuation token if more results are available.

EventsInput

type EventsInput struct {
	EventFilter
	ResultPageRequest
}

Source: types_event.go

EventFilter

type EventFilter struct {
	// FromBlock from block
	FromBlock BlockID `json:"from_block,omitempty"`
	// ToBlock to block
	ToBlock BlockID `json:"to_block,omitempty"`
	// Address from contract
	Address *felt.Felt `json:"address,omitempty"`
	// Keys the values used to filter the events
	Keys [][]*felt.Felt `json:"keys,omitempty"`
}

Source: types_event.go

ResultPageRequest

type ResultPageRequest struct {
	// a pointer to the last element of the delivered page, use this token in a
	// subsequent query to obtain the next page
	ContinuationToken string `json:"continuation_token,omitempty"`
	ChunkSize         int    `json:"chunk_size"`
}

Source: types.go

EventChunk

type EventChunk struct {
	Events            []EmittedEvent `json:"events"`
	ContinuationToken string         `json:"continuation_token,omitempty"`
}

Source: types_event.go

EmittedEvent

type EmittedEvent struct {
	Event
	// BlockHash the hash of the block in which the event was emitted
	BlockHash *felt.Felt `json:"block_hash,omitempty"`
	// BlockNumber the number of the block in which the event was emitted
	BlockNumber uint64 `json:"block_number,omitempty"`
	// TransactionHash the transaction that emitted the event
	TransactionHash *felt.Felt `json:"transaction_hash"`
}

Source: types_event.go

Event

type Event struct {
	FromAddress *felt.Felt `json:"from_address"`
	EventContent
}

Source: types_event.go

EventContent

type EventContent struct {
	Keys []*felt.Felt `json:"keys"`
	Data []*felt.Felt `json:"data"`
}

Source: types_event.go

BlockID

The blockID parameter specifies which block state to query. You can identify a block in three ways:

type BlockID struct {
	Number *uint64    `json:"block_number,omitempty"`
	Hash   *felt.Felt `json:"block_hash,omitempty"`
	Tag    BlockTag   `json:"tag,omitempty"`
}

Source: types_block.go

There are helper functions for creating BlockID. So Instead of manually creating the BlockID struct, use these convenience functions.

  • By Block Number - Get a specific block by its height

    blockID := rpc.WithBlockNumber(123456)

    Source: block.go

  • By Block Hash - Get a specific block by its hash

    hash, _ := new(felt.Felt).SetString("0x1234...")
    blockID := rpc.WithBlockHash(hash)

    Source: block.go

  • By Block Tag - Get a dynamic block reference

    blockID := rpc.WithBlockTag("latest")      // Latest accepted block
    blockID := rpc.WithBlockTag("pending")     // Block currently being built

    Source: block.go

Usage Example

package main
 
import (
	"context"
	"fmt"
	"log"
	"os"
 
	"github.com/NethermindEth/starknet.go/rpc"
	"github.com/joho/godotenv"
)
 
func main() {
	// Load environment variables from .env file
	err := godotenv.Load()
	if err != nil {
		log.Fatal("Error loading .env file")
	}
 
	// Get RPC URL from environment variable
	rpcURL := os.Getenv("STARKNET_RPC_URL")
	if rpcURL == "" {
		log.Fatal("STARKNET_RPC_URL not found in .env file")
	}
 
	// Initialize provider
	provider, err := rpc.NewProvider(context.Background(), rpcURL)
	if err != nil {
		log.Fatal(err)
	}
 
	ctx := context.Background()
 
	// Query events from a specific block range
	eventsInput := rpc.EventsInput{
		EventFilter: rpc.EventFilter{
			FromBlock: rpc.WithBlockNumber(1676500),
			ToBlock:   rpc.WithBlockNumber(1676510),
		},
		ResultPageRequest: rpc.ResultPageRequest{
			ChunkSize: 10,
		},
	}
 
	// Get first page of events
	eventChunk, err := provider.Events(ctx, eventsInput)
	if err != nil {
		log.Fatal(err)
	}
 
	fmt.Printf("Found %d events\n", len(eventChunk.Events))
 
	// Display event details
	for i, event := range eventChunk.Events {
		fmt.Printf("\nEvent %d:\n", i+1)
		fmt.Printf("  From Contract: %s\n", event.FromAddress)
		fmt.Printf("  Block Number: %d\n", event.BlockNumber)
		fmt.Printf("  Transaction Hash: %s\n", event.TransactionHash)
		fmt.Printf("  Number of Keys: %d\n", len(event.Keys))
		fmt.Printf("  Number of Data Fields: %d\n", len(event.Data))
	}
 
	// Fetch next page if available
	if eventChunk.ContinuationToken != "" {
		fmt.Printf("\nMore events available. Continuation token: %s\n", eventChunk.ContinuationToken)
 
		// Use continuation token for next page
		eventsInput.ContinuationToken = eventChunk.ContinuationToken
		nextPage, err := provider.Events(ctx, eventsInput)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("Next page has %d events\n", len(nextPage.Events))
	}
}

Error Handling

eventChunk, err := provider.Events(ctx, eventsInput)
if err != nil {
	if errors.Is(err, rpc.ErrPageSizeTooBig) {
		log.Printf("Chunk size too large, reduce ChunkSize")
		return
	}
	if errors.Is(err, rpc.ErrInvalidContinuationToken) {
		log.Printf("Invalid continuation token")
		return
	}
	if errors.Is(err, rpc.ErrBlockNotFound) {
		log.Printf("Block not found")
		return
	}
	if errors.Is(err, rpc.ErrTooManyKeysInFilter) {
		log.Printf("Too many keys in filter, reduce filter complexity")
		return
	}
	log.Printf("Error retrieving events: %v", err)
	return
}
 
fmt.Printf("Retrieved %d events\n", len(eventChunk.Events))

Common Use Cases

  • Monitoring token transfers by filtering Transfer events from ERC20 contracts.
  • Tracking contract state changes by querying events from specific contract addresses.
  • Building event indexers by paginating through historical events with continuation tokens.
  • Analyzing transaction activity within specific block ranges.