|
| 1 | +--- |
| 2 | +id: creating-an-application |
| 3 | +title: Creating an Application |
| 4 | +resources: |
| 5 | + - url: https://github.com/Calindra/nonodo |
| 6 | + title: NoNodo |
| 7 | + - url: https://cartesiscan.io/ |
| 8 | + title: CartesiScan |
| 9 | +--- |
| 10 | + |
| 11 | + |
| 12 | + |
| 13 | +Cartesi CLI simplifies creating applications on Cartesi. To create a new application, run: |
| 14 | + |
| 15 | +```shell |
| 16 | +cartesi create <application-name> --template <language> |
| 17 | +``` |
| 18 | + |
| 19 | +For example, create a Javascript project. |
| 20 | + |
| 21 | +```shell |
| 22 | +cartesi create new-app --template javascript |
| 23 | +``` |
| 24 | + |
| 25 | +This command creates a `new-app` directory with essential files for your application development. |
| 26 | + |
| 27 | +- `Dockerfile`: Contains configurations to build a complete Cartesi machine with your app's dependencies. Your backend code will run in this environment. |
| 28 | + |
| 29 | +- `README.md`: A markdown file with basic information and instructions about your application. |
| 30 | + |
| 31 | +- `src/index.js`: A javascript file with template backend code that serves as your application's entry point. |
| 32 | + |
| 33 | +- `package.json`: A list of dependencies required for your application along with the name, version and description of your application. |
| 34 | + |
| 35 | +Cartesi CLI has templates for the following languages – `cpp`, `cpp-low-level`, `go`, `javascript`, `lua`, `python`, `ruby`, `rust`, and `typescript`. |
| 36 | + |
| 37 | +:::note Building with Go? |
| 38 | +For Go applications on Cartesi, we recommend using [Rollmelette](https://github.com/rollmelette/rollmelette). It’s a high-level Go framework and an alternative template that simplifies development and enhances input management, providing a smoother and more efficient experience. |
| 39 | +::: |
| 40 | + |
| 41 | +## Implementing your application Logic |
| 42 | + |
| 43 | +After creating your application, you can begin building your application by adding your logic to the index.js file. This file serves as the entry point of your application. While your project can include multiple files and directories, the default application file should remain the entry point of your application. |
| 44 | + |
| 45 | +It’s important not to modify or remove existing code in index.js unless you fully understand its purpose, as doing so may prevent your application from functioning correctly. Instead, you are encouraged to extend the file by adding your own logic and implementations alongside the default code. |
| 46 | + |
| 47 | +If your application needs to emit notices, vouchers, or reports, make sure to implement the corresponding logic within your codebase to properly handle these outputs. You can check out the respective pages for [Notice](../api-reference/backend/notices.md), [Vouchers](../api-reference/backend/vouchers.md) or [Report](../api-reference/backend/reports.md) for better understanding of what they are and how to implement them. |
| 48 | + |
| 49 | +The default application template includes two primary functions; handle_advance and handle_inspect. These act as entry points for different types of operations within your application. The `handle_advance` function is the entry point for state modifying logic, you can think of this like handling "write" requests in traditional web context. It is intended to carry out computations, updates, and other logic that changes the state of the application. Where appropriate, it can emit outputs such as `notices`, `vouchers`, or `reports`. |
| 50 | + |
| 51 | +On the other hand, the `handle_inspect` function serves as the entry point for read only operations, similar to "read" requests in a typical web context. This function should be implemented to accept user input, perform any necessary lookups or calculations based on the current state, and return the results by emitting a `report`. It's important to understand that handle_inspect is designed strictly for reading the application's state, it should not perform any modifications. |
| 52 | + |
| 53 | +Below is a sample application that has been modified to include the logic to simply receive an input from a user in both inspect and advance route then, emits a notice, voucher and a report. For your application you'll need to include your personal logic and also emit outputs when necessary: |
| 54 | + |
| 55 | +```javascript |
| 56 | + |
| 57 | +import { stringToHex, encodeFunctionData, erc20Abi, hexToString } from "viem"; |
| 58 | + |
| 59 | +const rollup_server = process.env.ROLLUP_HTTP_SERVER_URL; |
| 60 | +console.log("HTTP rollup_server url is " + rollup_server); |
| 61 | + |
| 62 | +async function handle_advance(data) { |
| 63 | + console.log("Received advance request data " + JSON.stringify(data)); |
| 64 | + |
| 65 | + const sender = data["metadata"]["msg_sender"]; |
| 66 | + const payload = hexToString(data.payload); |
| 67 | + const erc20Token = "0x784f0c076CC55EAD0a585a9A13e57c467c91Dc3a"; // Sample ERC20 token address |
| 68 | + |
| 69 | + await emitNotice(payload); |
| 70 | + await emitReport(payload); |
| 71 | + |
| 72 | + const call = encodeFunctionData({ |
| 73 | + abi: erc20Abi, |
| 74 | + functionName: "transfer", |
| 75 | + args: [sender, BigInt(10)], |
| 76 | + }); |
| 77 | + |
| 78 | + let voucher = { |
| 79 | + destination: erc20Token, |
| 80 | + payload: call, |
| 81 | + value: '0x', |
| 82 | + }; |
| 83 | + |
| 84 | + await emitVoucher(voucher); |
| 85 | + return "accept"; |
| 86 | +} |
| 87 | + |
| 88 | +async function handle_inspect(data) { |
| 89 | + console.log("Received inspect request data " + JSON.stringify(data)); |
| 90 | + const payload = data.payload; |
| 91 | + await emitReport(payload); |
| 92 | + return "accept"; |
| 93 | +} |
| 94 | + |
| 95 | +const emitNotice = async (inputPayload) => { |
| 96 | + let hexPayload = stringToHex(inputPayload); |
| 97 | + try { |
| 98 | + await fetch(rollup_server + "/notice", { |
| 99 | + method: "POST", |
| 100 | + headers: { |
| 101 | + "Content-Type": "application/json", |
| 102 | + }, |
| 103 | + body: JSON.stringify({ payload: hexPayload }), |
| 104 | + }); |
| 105 | + } catch (error) { |
| 106 | + //Do something when there is an error |
| 107 | + } |
| 108 | +} |
| 109 | + |
| 110 | +const emitVoucher = async (voucher) => { |
| 111 | + try { |
| 112 | + await fetch(rollup_server + "/voucher", { |
| 113 | + method: "POST", |
| 114 | + headers: { |
| 115 | + "Content-Type": "application/json", |
| 116 | + }, |
| 117 | + body: JSON.stringify(voucher), |
| 118 | + }); |
| 119 | + } catch (error) { |
| 120 | + //Do something when there is an error |
| 121 | + } |
| 122 | +}; |
| 123 | + |
| 124 | +const emitReport = async (payload) => { |
| 125 | + let hexPayload = stringToHex(payload); |
| 126 | + try { |
| 127 | + await fetch(rollup_server + "/report", { |
| 128 | + method: "POST", |
| 129 | + headers: { |
| 130 | + "Content-Type": "application/json", |
| 131 | + }, |
| 132 | + body: JSON.stringify({ payload: hexPayload }), |
| 133 | + }); |
| 134 | + } catch (error) { |
| 135 | + //Do something when there is an error |
| 136 | + } |
| 137 | +}; |
| 138 | + |
| 139 | +var handlers = { |
| 140 | + advance_state: handle_advance, |
| 141 | + inspect_state: handle_inspect, |
| 142 | +}; |
| 143 | + |
| 144 | +var finish = { status: "accept" }; |
| 145 | + |
| 146 | +(async () => { |
| 147 | + while (true) { |
| 148 | + const finish_req = await fetch(rollup_server + "/finish", { |
| 149 | + method: "POST", |
| 150 | + headers: { |
| 151 | + "Content-Type": "application/json", |
| 152 | + }, |
| 153 | + body: JSON.stringify({ status: "accept" }), |
| 154 | + }); |
| 155 | + |
| 156 | + console.log("Received finish status " + finish_req.status); |
| 157 | + |
| 158 | + if (finish_req.status == 202) { |
| 159 | + console.log("No pending rollup request, trying again"); |
| 160 | + } else { |
| 161 | + const rollup_req = await finish_req.json(); |
| 162 | + var handler = handlers[rollup_req["request_type"]]; |
| 163 | + finish["status"] = await handler(rollup_req["data"]); |
| 164 | + } |
| 165 | + } |
| 166 | +})(); |
| 167 | + |
| 168 | + |
| 169 | +``` |
0 commit comments