# Annotation of the Monitor

This section provides a very well-annotated version of the monitor program of the Hello World BVS. It aims to help developers get familiar with the programming environment. The monitor program simply listens to events on a BVS and prints it to the console.

In pseudo (and Python-like) code, the monitor program acts as the following:&#x20;

```python
chainio = init_chainio()
indexer = init_indexer(
    starting_block=chainio.latest_block,
    event_filter=["wasm-NewTaskCreated", "wasm-TaskResponded"])

while True:
    event = await indexer.wait_for_new_event()
    print(event)
```

Here's the annotated version taken from commit `c5764b62732516f634c08251258474cb8f4a97db`

```go
// The Monitor structure
type Monitor struct {
    bvsContract string       // The address of the BVS contract
    chainIO     io.ChainIO   // ChainIO to enable communication with the BVS
}

// RunMonitor runs the monitor. This is the entery point of the monitor
func RunMonitor() {
    m := NewMonitor()
    m.Run()
}

// NewMonitor creates a new instance of the Monitor struct.
func NewMonitor() *Monitor {
    // Create a new ChainIO instance
    // ChainIO is our main interfaace from a off-chain program to any on-chain contract
    chainIO, err := io.NewChainIO(core.C.Chain.Id, core.C.Chain.Rpc, core.C.Owner.KeyDir, core.C.Owner.Bech32Prefix, elkLogger, metricsIndicators, types.TxManagerParams{
        MaxRetries:             3,
        RetryInterval:          1 * time.Second,
        ConfirmationTimeout:    60 * time.Second,
        GasPriceAdjustmentRate: "1.1",
    })
    if err != nil {
        panic(err)
    }
    // Setup the keyring so we have access to private keys
    client, err := chainIO.SetupKeyring(core.C.Owner.KeyName, core.C.Owner.KeyringBackend)
    if err != nil {
        panic(err)
    }
    
    // Query the BVS directory and find the BVS we are monitoring
    txResp, err := api.NewBVSDirectoryImpl(client, core.C.Chain.BvsDirectory).GetBVSInfo(core.C.Chain.BvsHash)
    if err != nil {
        panic(err)
    }
    
    // Construct and returnthe Monitor structure
    return &Monitor{
        bvsContract: txResp.BVSContract,
        chainIO:     client,
    }
}

// Run runs the event indexer and monitors for new task created and task responded events.
func (m *Monitor) Run() {
    // Create a context (see https://pkg.go.dev/context for detail) that ChainIO and
    // other components will run in.
    ctx := context.Background()
    // Queries the RPC node to reterve the current latest block. The information
    // is later on passed to the EvenIndexer to listen to newly created event
    res, err := m.chainIO.QueryNodeStatus(ctx)
    if err != nil {
        panic(err)
    }
    latestBlock := res.SyncInfo.LatestBlockHeight
    fmt.Println("latestBlock: ", latestBlock)
    // Create the EventIndexer with listening to the BVS for new events
    // of type "wasm-NewTaskCreated" and "wasm-TaskResponded". And with a very 
    // small rate limiter. The last 2 parameters 1, 5 denotes 1 event (in a bucket
    // rate limiter) and 5 events per second.
    evtIndexer := indexer.NewEventIndexer(
        m.chainIO.GetClientCtx(),
        m.bvsContract,
        latestBlock,
        []string{"wasm-NewTaskCreated", "wasm-TaskResponded"},
        1,
        5)
    // start the event indexer
    evtChain, err := evtIndexer.Run(ctx)
    if err != nil {
        panic(err)
    }
    fmt.Println("chain: ", evtChain)
    
    // Now wait for events and print their respective information. Event data
    // is stored in evt.AttrMap while the type can be determined by checking 
    // evt.EventType
    for evt := range evtChain {
        switch evt.EventType {
        // For a NewTaskCreated event, we print the block height, transaction hash
        // the TaskId and it's input value 
        case "wasm-NewTaskCreated":
            blockHeight := evt.BlockHeight
            txnHash := evt.TxHash
            taskId := evt.AttrMap["taskId"]
            taskInput := evt.AttrMap["input"]
            fmt.Printf("[NewTaskCreated] blockHeight: %d, txnHash: %s, taskId: %s, taskInput: %s\n", blockHeight, txnHash, taskId, taskInput)
        // For a TaskResponded event, print block height, transaction hash taskId, result
        // and the operators whom performed the calculations.
        case "wasm-TaskResponded":
            blockHeight := evt.BlockHeight
            txnHash := evt.TxHash
            taskId := evt.AttrMap["taskId"]
            taskResult := evt.AttrMap["result"]
            taskOperators := evt.AttrMap["operators"]
            fmt.Printf("[TaskResponded] blockHeight: %d, txnHash: %s, taskId: %s, taskResult: %s, taskOperators: %s\n", blockHeight, txnHash, taskId, taskResult, taskOperators)
        default:
            // Should not reach here as we covered all event types specsifed to the EventIndexer
            fmt.Printf("Unknown event type. evt: %+v\n", evt)
        }
    }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.satlayer.xyz/bvs-developers-1/developer-toolbox/hello-world-details/annotation-of-the-monitor.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
