> ## Documentation Index
> Fetch the complete documentation index at: https://docs.requestscript.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Events: declare, emit and consume

> Declare event types, publish events from requests and contracts with emit, and run event contracts that consume them. Events need requestscript-js 1.6.0.

RequestScript events let one script announce that something happened and other scripts react to it. An **event declaration** defines an event type and its fields. A request or contract publishes an event with `emit`. An **event contract** names the event type it `consumes`, and its host runs it with each event of that type. Events need requestscript-js 1.6.0 or later.

The interpreter checks events and hands them to its host, but it doesn't deliver them. Which scripts may emit an event, and which event contracts run, is up to the host. A [Stellarium](https://docs.stellarium.sh/concepts/events) node, for example, delivers events across its network.

## Declaring an event type

An event declaration is a script of its own. It lists the fields its events carry, and has no body:

```kotlin theme={null}
event shop.OrderPlaced@1(orderId: string, total: decimal)
```

* The path, name and [version](https://docs.requestscript.org/contracts/versioning.md) work as they do for contracts. The version defaults to `1`.
* Fields are `name: type` pairs, like [contract parameters](https://docs.requestscript.org/contracts/overview.md#parameters), with any [type](https://docs.requestscript.org/language/types.md). Field names must be unique.
* An event type without fields leaves out the parentheses: `event shop.Tick`.
* An event declaration can't have a body or a return type. Either one is a parse error.

Prefix the declaration with `restricted` to mark the event type restricted:

```kotlin theme={null}
restricted event shop.InternalAudit(entry: object)
```

`restricted` is a flag for the host. Hosts deliver a restricted event only to event contracts deployed by the event type's owner.

## Emitting an event

A request or a contract publishes an event with `emit`, followed by the event type and a value for every field:

```kotlin theme={null}
contract shop.Checkout(orderId: string, total: decimal): string {
    emit shop.OrderPlaced(orderId: orderId, total: total)
    return orderId
}
```

* Name the event type as `path.Name`, or `path.Name@version` to pin a version. Without a version, the host picks one.
* Pass every field by name, in any order. A missing field, or a field the event type doesn't declare, is a runtime error.
* Each value is converted to its field's type, as an argument to a resource function is. A value that doesn't fit is a runtime error.
* `emit` can appear anywhere a statement can, including inside `if` branches. Its [tokens](https://docs.requestscript.org/reference/token-metering.md) are counted like any statement's.

The interpreter collects the run's events in order and returns them to the host. A host publishes them only if the run succeeds, so a run that fails publishes nothing.

## Consuming events

An event contract declares the event type it consumes with `consumes` after its name:

```kotlin theme={null}
contract shop.OnOrderPlaced consumes shop.OrderPlaced@1 {
    var state(orderId) seen: int32 = 0
    seen = seen + 1
}
```

* An event contract declares no parameters. The event's fields are its parameters, readable by name, like [`const`](https://docs.requestscript.org/language/variables#const) parameters.
* It has no return type and can't return a value. A bare `return` ends it, and `return` with a value is a parse error.
* `consumes` names the event type as `path.Name` or `path.Name@version`.
* An event contract can keep [state variables](https://docs.requestscript.org/contracts/overview.md#state-variables) and call resources like any contract.

When the host runs an event contract, it passes the event's data as the contract's parameters. They are checked against the event type's fields: a missing field, or one the type doesn't declare, is a parameter error.

## Reserved words

`event`, `emit`, `consumes` and `restricted` aren't reserved words. They act as keywords only where they're followed by a name, so you can still use them as variable names:

```kotlin theme={null}
request Names {
    var emit = 1
    var event = { consumes: 2 }
    return emit + event.consumes
}
```

## Hosting events

A host passes an `events` resolver to `interpret` or `interpretParsed`. The interpreter calls it to look up the event type of each `emit`, and the type an event contract consumes. The run's events come back in `result.events`:

```ts theme={null}
import { interpret, type EventResolver } from "requestscript";

const events: EventResolver = {
  // Returns { path, name, version, fields: [{ name, type }] }, or undefined for an unknown type.
  resolve: async (path, name, version) => lookup(path, name, version),
};

const result = await interpret(source, { events, parameters });
await publish(result.events); // [{ path, name, version, data }]
```

* `data` holds each field's value as JSON, encoded as in [JSON encoding](https://docs.requestscript.org/reference/json-encoding.md).
* Without a resolver, `emit` and running an event contract are runtime errors.
* A resolver can refuse an event by throwing a `RuntimeError`, which fails the script with its message. Hosts use this to decide who may emit what.
* `emittedEvents(script)` lists every event type a script's `emit` statements name, including those in branches that may not run, so a host can check a script before it accepts it.

> [!NOTE]
>
> Running an event declaration is a runtime error: it declares a type and has nothing to run. The requestscript-js HTTP server has no event resolver, so scripts that emit or consume events fail there.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.