# The Rollup Loop

A Cartesi application backend is a long-running process that reads requests from inside the Cartesi Machine and produces outputs. That loop is owned by [`@cartesi/rollup`](https://github.com/cartesi/rollups-ts), the Node.js binding for libcmt — deroll does not wrap it.

You open the rollup device by constructing a `Rollup`, and hand it your request handlers:

```ts twoslash
/// <reference types="node" />
// ---cut---
import { Rollup, chain } from "@cartesi/rollup";

// open the rollup device // [!code focus]
const rollup = new Rollup(); // [!code focus]

rollup // [!code focus]
    .run({ // [!code focus]
        advance: (request) => { // [!code focus]
            console.log(request); // [!code focus]
            return true; // [!code focus]
        }, // [!code focus]
    }) // [!code focus]
    .catch((e) => { // [!code focus]
        console.error(e); // [!code focus]
        process.exit(1); // [!code focus]
    }); // [!code focus]
```

`run` enters a continuous loop, fetching requests and dispatching them to the handler for their kind. It never returns normally — inside a machine the loop is meant to run forever — so the rejection is what you handle.

:::warning
Only **one** `Rollup` may be open per process. The rollup device allows a single handle, so constructing a second one fails with `-EBUSY`. This is also why `@cartesi/rollup` is a peer dependency of the deroll packages: the dependency tree must resolve to a single copy.
:::

## Where deroll fits

`run` takes exactly **one** advance handler and **one** inspect handler. A real application usually has several independently authored concerns — a wallet that claims portal deposits, then the application's own logic — so `@cartesi/rollup` also ships the composition that turns many handlers into one:

```ts twoslash
/// <reference types="node" />
import { Rollup, chain } from "@cartesi/rollup";
import { createWallet } from "@deroll/wallet";

const rollup = new Rollup();
const wallet = createWallet();
const application = () => true;
// ---cut---
rollup.run({
    advance: chain(wallet.handler, application), // [!code focus]
});
```

deroll is not involved in the loop at all. What it offers is libraries you plug in as handlers, like the [wallet](/app/wallet).

## Requests and outputs

The two kinds of request, and the outputs a handler may produce, are the rollup protocol's, not deroll's:

* [Advance handlers](/app/advance-handlers) process state-changing inputs.
* [Inspect handlers](/app/inspect-handlers) answer read-only queries.
* [Outputs](/app/outputs) — notices, reports, vouchers and delegate-call vouchers — are emitted through the `Rollup` handle.

For the full method reference (including `progress`, `gio` and the merkle-tree helpers), see the [`@cartesi/rollup` documentation](https://github.com/cartesi/rollups-ts).
