# Quick Start

## Overview

[Cartesi](https://cartesi.io) is an application-specific rollups technology that allows developers to build powerful decentralized rollups applications using any programming language or library (as long as it compiles to RISC-V).
It does that by running the application inside a powerful virtual machine, the Cartesi VM, that can run an entire Linux OS.

Deroll is a collection of [TypeScript](https://www.typescriptlang.org) libraries that helps developers to build Cartesi applications, by introducing a framework and concepts familiar to TypeScript developers.

## Installation

Before you start building you need to setup the Cartesi development environment:

* Install Docker Desktop on [Mac](https://docs.docker.com/desktop/install/mac-install/), [Linux](https://docs.docker.com/desktop/install/linux-install/) or [Windows with WSL2](https://docs.docker.com/desktop/install/windows-install/).
* Install the Cartesi CLI

:::code-group

```bash [npm]
npm install -g @cartesi/cli@alpha
```

:::

If you have any issues, please refer to the [official installation guide](https://docs.cartesi.io/cartesi-rollups/1.5/development/installation/) for more information.

## Create a project

Execute the command below to create a new deroll application. It will guide you through some project options.
:::code-group

```bash [npm]
npm init @deroll/app@alpha
```

```bash [pnpm]
pnpm create @deroll/app@alpha
```

```bash [bun]
bun create @deroll/app@alpha
```

:::

If you select the default options (no wallet or router library, more on that later), you will get the following `src/index.ts` file.

```ts twoslash [src/index.ts]
/// <reference types="node" />
// ---cut---
import { createApp } from "@deroll/app";

// create application
const app = createApp();

// log incoming advance request
app.addAdvanceHandler(async ({ metadata, payload }) => {
    console.log({ metadata, payload });
    return "accept";
});

// log incoming inspect request
app.addInspectHandler(async ({ payload }) => {
    console.log(payload);
});

// start app
app.start().catch((e) => process.exit(1));
```

This application reads inputs (requests) from the Cartesi device inside the Cartesi machine, and only prints those inputs to the `console`.

## Build Cartesi Machine

The next step is to build the application Cartesi Machine, by using the `cartesi build` command.
That will start a build process powered by Docker, and create a Cartesi Machine that is stored in the `.cartesi` directory.
You should see the Cartesi Machine booting and showing the output below:

```bash
$ cartesi build

         .
        / \
      /    \
\---/---\  /----\
 \       X       \
  \----/  \---/---\
       \    / CARTESI
        \ /   MACHINE
         '


Manual yield rx-accepted (1) (0x000020 data)
Cycles: 514075423
514075423: ab02926c6b95088e96a71df8a94aff86bd9e72628315db08e2481a9856592e6a
Storing machine: please wait
```

## Run Cartesi Node

Now that you built a Cartesi Machine you can run a Cartesi Node with the `cartesi rollups start` command, which should produce the following output:

```bash
$ cartesi run
✔ <application> starting at http://127.0.0.1:6751
✔ anvil service ready at http://127.0.0.1:6751/anvil
✔ rpc service ready at http://127.0.0.1:6751/rpc
✔ inspect service ready at http://127.0.0.1:6751/inspect/<application>
```

This will run a few services on your machine:

1. an [anvil](https://book.getfoundry.sh/anvil/) instance running at http://127.0.0.1:6751/anvil which contains all Cartesi infrastructure [smart contracts](https://github.com/cartesi/rollups-contracts/tree/next/3.0) deployed to it, and also a few test contracts. You can see the addresses of these contracts by executing the `cartesi address-book` command.

2. a [JSON-RPC]() server running at http://127.0.0.1:6751/rpc which you can use to query outputs produced by your application.

3. an inspect server running at http://127.0.0.1:6751/inspect/ which you can use to simulate an input, or query read-only computations from your application.

Some of these services will be used below.

## Send Input

The first step to interact with your application backend is to send an input to it. Typically inputs will be sent by your application frontend.
For testing you can send inputs directly to the local `anvil` instance using the Cartesi smart contracts, or you can use the `cartesi send` command.

### Send input using `cartesi send`

The `cartesi send` command will guide you through some steps to send different kinds of inputs, like in the example below where we send a string `hello` as the input to the application.

:::code-group

```bash [command]
cartesi send
✔ Input String encoding
✔ Input (as string) hello
✔ Input sent: 0x79b4d8dec9a3b4705a4a95d4dc3f73f75ac330a12d5eff94714edb77258e8e8f
```

```bash [log]
{
  metadata: {
    chainId: 31337n,
    appContract: '0xa418ed392a99a1a0c08f96345e9a9b7514047ee2',
    msgSender: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
    blockNumber: 158n,
    blockTimestamp: 1782243979n,
    prevRandao: 50953495096857333910293917481377617449822294969307609189375131362321353489028n,
    index: 0n
  },
  payload: <Buffer 68 65 6c 6c 6f>
}
```

```ts [src/index.ts]
// log incoming advance request
app.addAdvanceHandler(async ({ metadata, payload }) => {
    console.log({ metadata, payload }); // [!code focus]
    return "accept";
});
```

:::

If you check in the `cartesi rollups logs` log you will see the output above, which is the result of the `console.log(data)` of the application code.
Notice that the `payload` is the hex encoding of the `hello` string. More on that on the [Data Encoding](/app/data-encoding) section.

### Send input using `cast`

First you need to [install cast](https://book.getfoundry.sh/getting-started/installation#using-foundryup), a swiss-army knife to play with anvil.

Then you can use the `cast send` command to send inputs to your application through the Cartesi smart contracts.
As an example, to send the `hello` string as input, you can use the command below:

```bash
cast send \
    --rpc-url http://127.0.0.1:6751/anvil \
    --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \
    $(cartesi address-book --json | jq -r '.InputBox') \
    "addInput(address,bytes)" \
    $(cartesi address-book --json | jq -r '.Application') \
    $(cast from-utf8 hello)
```

where:

* http://127.0.0.1:6751/anvil is where anvil is running
* `0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80` is the private key of the first default anvil test account;
* `cartesi address-book --json | jq -r '.InputBox'` gets the address of the `InputBox` contract;
* `addInput(address,bytes)` is the method to send inputs to the application;
* `$(cartesi address-book --json | jq -r '.Application')` gets the address of the deployed `Application` contract;
* `$(cast from-utf8 hello)` is the hex encoding of the `hello` string.

## Querying JSON-RPC

The inputs received and outputs produced by your application can be queried using a JSON-RPC API.
Ultimately these RPC queries will come from your application front-end, or some intermediate application-specific server.

The following example queries the list of inputs received by an application deployed name `cartesi`.

```shell
cast rpc --rpc-url http://127.0.0.1:6751/rpc cartesi_listInputs cartesi
```

## Inspecting State

Inspect state is useful to execute some kind of application logic that does not change the state of the application.
This can include an input simulation, or a read-only computation to query internal state of the application.

You can make an inspect call using a tool like `curl`, like in the example below.
The body of a POST request, specified with `-d`, is received by the application inspect handler.

:::code-group

```bash [command]
$ curl -X POST -d "hello" http://127.0.0.1:6751/inspect/<application>
{"status":"Accepted","reports":null,"processed_input_count":1}
```

```bash [log]
{ payload: <Buffer 68 65 6c 6c 6f> }
```

```ts [src/index.ts]
// log incoming inspect request
app.addInspectHandler(async (data) => {
    console.log(data); // [!code focus]
});
```

:::

If you check in the `cartesi logs` log you will see the output above, which is the result of the `console.log(data)` of the application code.
Inspected state should be returned as report outputs, in this example no reports were produced.

:::warning
Inspect is a costly operation when compared to querying the JSON-RPC API.
It actually executes the application code using the Cartesi VM, which is much slower than bare metal execution performance of the JSON-RPC Server.
So be careful when designing its use in your application.
:::

## Summary

In this section you learned the basics of the development workflow, creating an application, building it, running in a test environment.
In the following sections we will dive deeper into the concepts and features of the deroll framework.
