# Rollups Machine

The Rollups Machine provides a high-level interface for interacting with Cartesi rollups machines, supporting both advance and inspect requests, and exposing a generator-based pattern for streaming outputs and reports.

## Features

The API is centered around the [RollupsMachine](./api/rollups-machine) interface, which allows you to:

* Send advance or inspect requests to a Cartesi machine;
* Stream outputs, reports, and progress updates as they are produced;
* Handle input rejection and fatal errors;
* Automatic rollback behavior;
* Store and shutdown the machine.

The following sections will show step by step how to create, advance and inspect a Cartesi rollups machine.

## Creating a machine

```ts twoslash [example.ts]
import { rollups } from "@deroll/cm";

// create a rollups machine from a snapshot stored at .cartesi/image
const machine = rollups(".cartesi/image");
```

In this [rollups](/cm/api/rollups) constructor, that takes a directory, a remote machine is [spawned](/cm/api/spawn) and the snapshot is [loaded](/cm/api/load).
The [RemoteCartesiMachine](/cm/api/remote-cartesi-machine) instance is managed by the [RollupsMachine](/cm/api/rollups-machine).

If the user wants to keep ownership of the [RemoteCartesiMachine](/cm/api/remote-cartesi-machine) he can instantiate it himself, and use the [rollups](/cm/api/rollups) constructor that takes a [RemoteCartesiMachine](/cm/api/remote-cartesi-machine) instance instead.

A [RemoteCartesiMachine](/cm/api/remote-cartesi-machine) is necessary because `fork` is used to automatically revert rejected inputs.

## Creating an input

The rollups framework expects an input format that is the ABI encoding of the `EvmAdvance` function of the [Inputs.sol](https://github.com/cartesi/rollups-contracts/blob/v2.0.0/src/common/Inputs.sol) smart contract.

Using the viem utility [encodeFunctionData](https://viem.sh/docs/contract/encodeFunctionData#encodefunctiondata) and the `Inputs.sol` ABI, it's quite easy to build a rollups input.

:::code-group

```ts twoslash [input.ts]
// @filename: inputsAbi.ts
// [!include ~/snippets/cm/inputsAbi.ts]

// @filename: input.ts

// ---cut---
// [!include ~/snippets/cm/input.ts]
```

```ts twoslash [inputsAbi.ts]
// [!include ~/snippets/cm/inputsAbi.ts]
```

:::

## Advance

Now that we have a rollups machine and an input, we can advance the machine and collect the produced outputs, reports, and progress updates along the execution.

:::code-group

```ts twoslash [example.ts]
// @filename: inputsAbi.ts
// [!include ~/snippets/cm/inputsAbi.ts]

// @filename: input.ts
// [!include ~/snippets/cm/input.ts]

// @filename: example.ts

// ---cut---
import { rollups } from "@deroll/cm";
import { input } from  "./input";

// create a rollups machine from a snapshot stored at .cartesi/image
const machine = rollups(".cartesi/image");

for (const event of machine.advance(input)) {
    switch (event.type) {
        case "output":
            console.log(event);
            break;
        case "report":
            console.log(event);
            break;
        case "progress":
            console.log("Progress:", event.data);
            break;
    }
}
```

```ts twoslash [input.ts]
// @filename: inputsAbi.ts
// [!include ~/snippets/cm/inputsAbi.ts]

// @filename: input.ts

// ---cut---
// [!include ~/snippets/cm/input.ts]
```

```ts twoslash [inputsAbi.ts]
// [!include ~/snippets/cm/inputsAbi.ts]
```

:::

## Inspect

Inspects are simpler than advances. The input, called `query` in this case, is just a Buffer with data.
Inspects can only yield reports, so it yields the reports data itself.
The example below shows a simple inspect request.

```ts twoslash [example.ts]
import { rollups } from "@deroll/cm";
import { stringToBytes } from "viem";

const machine = rollups(".cartesi/image");

for (const report of machine.inspect(Buffer.from(stringToBytes("test")))) {
    console.log(report);
}

machine.shutdown();
```
