# Work with Events

How to work with contract events

* [About events](#about-events)
* [Query/subscribe to events](#querysubscribe-to-events)
* [Query/Subscribe with SDK](#querysubscribe-with-sdk)
* [AppKit syntax](#appkit-syntax)
  * [Query](#query)
  * [Subscribe](#subscribe)
  * [Decode](#decode)

## About events

When contract emits an event, you can fetch it from blockchain or you can subscribe to it.

Events in blockchain are external outbound messages. In GraphQL API their `msg_type` is 2:

![scr1.jpg](/files/19IfAHHq6hFoM37Xehcr)

## Query/subscribe to events

You can fetch events of you contract with this filter from graphql. Try it out in playground <https://eri01.main.everos.dev/graphql>:

```
query{
messages(
      filter:{ 
      src:{
        eq:"-1:67f4bf95722e1bd6df845fca7991e5e7128ce4a6d25f6d4ef027d139a11a7964"
      }
      msg_type:{
        eq:2
      }
    }
)
{
   id
 body
}
}
```

Or subscribe to them:

```
subscription{
messages(
      filter:{ 
      src:{
        eq:"-1:67f4bf95722e1bd6df845fca7991e5e7128ce4a6d25f6d4ef027d139a11a7964"
      }
      msg_type:{
        eq:2
      }
    }
)
{
   id
  body
}
}
```

## Query/Subscribe with SDK

Let's assume our contract code is this:

```
pragma ton-solidity >= 0.38.2;
pragma AbiHeader expire;


contract HelloEvents {
// Event is an external message generated by the contract functions.
// Here we will emit this external outbound message (event)
// every time we have changed the hello text.
event TextUpdated(string text, uint32 time);

// Instance variable storing some user data.
string helloText;

// Instance variable storing the time of `constructor` call or `setHelloText` function call.
uint32 textUpdateTime;

// Constructor sets instance variables.
// All contracts need to call `tvm.accept()` for deploying.
constructor(string text) public {
    tvm.accept();
    helloText = text;
    textUpdateTime = now;
}

// Function `setHelloText` updates instance variables
// `helloText` and `textUpdateTime` 
// and emits `TextUpdated` event.
function setHelloText(string text) external returns (string oldText) {
    require(msg.pubkey() == tvm.pubkey(), 100);
    tvm.accept();
    string saveText = helloText;
    helloText = text;
    textUpdateTime = now;
    emit TextUpdated(helloText, textUpdateTime);
    return saveText;
}

// Function returns value of instance variable `helloText`.
// This function is a get method (it does not change state and has no `accept` function)
// so it can be called only on local TVM.
function getHelloText() public view returns (string text) {
    return helloText;
}

// Function returns value of instance variable `textUpdateTime`.
// This function is a get method (it does not change state and has no `accept` function)
// so it can be called only on local TVM.
function getTextUpdateTime() public view returns (uint32 time) {
    return textUpdateTime;
}
}
```

We see that we have 1 event `TextUpdated(helloText, textUpdateTime)`.

## AppKit syntax

See the full sample here <https://github.com/tonlabs/sdk-samples/tree/master/appkit-examples/listen-and-decode>

### Query

To fetch all the events do this query. It uses low level api, AppKit does not provide query options for account yet.

```
result = (await client.net.query_collection({
        collection: "messages",
        filter: {
            src: {
                eq: "-1:67f4bf95722e1bd6df845fca7991e5e7128ce4a6d25f6d4ef027d139a11a7964",
            },
            msg_type:{ eq:2 }
        },
        result: "boc",
})).result;
```

### Subscribe

To subscribe to new events do this. Don't forget to specify your own callback.

```
await account.subscribeMessages("boc",callback)
```

### Decode

```
const decoded = await hello.decodeMessage(msg.boc);
            switch (decoded.body_type) {
                // Message that triggered an on-chain contract call
            case MessageBodyType.Input:
                if (decoded.name === "setHelloText") {
                    decoded.value.text = decodeText(decoded.value.text);
                }
                console.log(`External inbound message, function "${decoded.name}", parameters: `, JSON.stringify(decoded.value));
                break;
                // External outbound message generated by a function's `return`
            case MessageBodyType.Output:
                if (decoded.name === "setHelloText") {
                    decoded.value.oldText = decodeText(decoded.value.text);
                }
                console.log(`External outbound message, function "${decoded.name}", result`, JSON.stringify(decoded.value));
                break;
                // Event generated by the contract
            case MessageBodyType.Event:
                if (decoded.name === "TextUpdated") {
                    decoded.value.text = decodeText(decoded.value.text);
                }
                console.log(`External outbound message, event "${decoded.name}", parameters`, JSON.stringify(decoded.value));
                break;
            }
```

Check out [core api documentation](https://docs.everos.dev/ever-sdk/guides/work_with_contracts/work_with_events) for more information.


---

# 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.everos.dev/appkit-js/guides/work_with_events.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.
