Skip to content

Commit 7fcb872

Browse files
authored
Merge branch 'cartesi:Staging' into Staging
2 parents cc4739a + a396188 commit 7fcb872

23 files changed

Lines changed: 33400 additions & 1964 deletions
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{"rule":"BASE_BASIS","sentence":"^\\QThis guide covers the Cartesi+Espresso integration and how to upgrade Cartesi application such that inputs can be submitted via Espresso instead of the regular base layer.\\E$"}
22
{"rule":"MORFOLOGIK_RULE_EN_US","sentence":"^\\QIntegrating Cartesi and Chronicle offers Cartesi applications access to onchain and offcahin data like, price feed without developers having to set up additional systems or intermediaries.\\E$"}
33
{"rule":"MORFOLOGIK_RULE_EN_US","sentence":"^\\QPrevado Id:\\E$"}
4+
{"rule":"MORFOLOGIK_RULE_EN_US","sentence":"^\\QThe Devnet environment functions similarly to a mainnet.\\E$"}

cartesi-rollups_versioned_docs/version-2.0/api-reference/backend/introduction.md

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ id: introduction
33
title: Introduction
44
---
55

6-
The backend of a Cartesi dApp retrieves a new request as follows:
6+
The backend of a Cartesi application as mentioned in the [overview section](../index.md#backend-apis) contains the applications logic and state, it interacts with the Cartesi rollups framework by retrieving request and submitting structured outputs. The application backend retrieves a new request as follows:
77

88
- Finish — Communicates that any previous processing has been completed and that the backend is ready to handle the subsequent request. This following request is returned as the call's response and can be of the following types:
99

@@ -120,6 +120,81 @@ while True:
120120
</code></pre>
121121
</TabItem>
122122

123+
<TabItem value="Rust" label="Rust" default>
124+
<pre><code>
125+
126+
```rust
127+
use json::{object, JsonValue};
128+
use std::env;
129+
130+
pub async fn handle_advance(
131+
_client: &hyper::Client<hyper::client::HttpConnector>,
132+
_server_addr: &str,
133+
request: JsonValue,
134+
) -> Result<&'static str, Box<dyn std::error::Error>> {
135+
println!("Received advance request data {}", &request);
136+
let _payload = request["data"]["payload"]
137+
.as_str()
138+
.ok_or("Missing payload")?;
139+
// TODO: add application logic here
140+
Ok("accept")
141+
}
142+
143+
pub async fn handle_inspect(
144+
_client: &hyper::Client<hyper::client::HttpConnector>,
145+
_server_addr: &str,
146+
request: JsonValue,
147+
) -> Result<&'static str, Box<dyn std::error::Error>> {
148+
println!("Received inspect request data {}", &request);
149+
let _payload = request["data"]["payload"]
150+
.as_str()
151+
.ok_or("Missing payload")?;
152+
// TODO: add application logic here
153+
Ok("accept")
154+
}
155+
156+
#[tokio::main]
157+
async fn main() -> Result<(), Box<dyn std::error::Error>> {
158+
let client = hyper::Client::new();
159+
let server_addr = env::var("ROLLUP_HTTP_SERVER_URL")?;
160+
161+
let mut status = "accept";
162+
loop {
163+
println!("Sending finish");
164+
let response = object! {"status" => status.clone()};
165+
let request = hyper::Request::builder()
166+
.method(hyper::Method::POST)
167+
.header(hyper::header::CONTENT_TYPE, "application/json")
168+
.uri(format!("{}/finish", &server_addr))
169+
.body(hyper::Body::from(response.dump()))?;
170+
let response = client.request(request).await?;
171+
println!("Received finish status {}", response.status());
172+
173+
if response.status() == hyper::StatusCode::ACCEPTED {
174+
println!("No pending rollup request, trying again");
175+
} else {
176+
let body = hyper::body::to_bytes(response).await?;
177+
let utf = std::str::from_utf8(&body)?;
178+
let req = json::parse(utf)?;
179+
180+
let request_type = req["request_type"]
181+
.as_str()
182+
.ok_or("request_type is not a string")?;
183+
status = match request_type {
184+
"advance_state" => handle_advance(&client, &server_addr[..], req).await?,
185+
"inspect_state" => handle_inspect(&client, &server_addr[..], req).await?,
186+
&_ => {
187+
eprintln!("Unknown request type");
188+
"reject"
189+
}
190+
};
191+
}
192+
}
193+
}
194+
```
195+
196+
</code></pre>
197+
</TabItem>
123198
</Tabs>
124199

125200
An **Advance** request involves sending input data to the base layer via JSON-RPC so they can reach the dApp backend to change the application's state.
@@ -140,10 +215,12 @@ An **Inspect** request involves making an external HTTP API call to the rollups
140215

141216
You can make a simple inspect call from your frontend client to retrieve reports.
142217

143-
To perform an Inspect call, use an HTTP GET request to `<address of the node>/inspect/<request path>`. For example:
218+
To perform an Inspect call, use an HTTP POST request to `<address of the node>/inspect/<application name or address>` with a body containing the request payload. For example:
144219

145220
```shell
146-
curl http://localhost:8080/inspect/mypath
221+
curl -X POST http://localhost:8080/inspect/0xb483897a2790a5D1a1C5413690bC5933f269b3A9 \
222+
-H "Content-Type: application/json" \
223+
-d '"test"'
147224
```
148225

149226
Once the call's response is received, the payload is extracted from the response data, allowing the backend code to examine it and produce outputs as **reports**.

cartesi-rollups_versioned_docs/version-2.0/api-reference/backend/notices.md

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Crucially, the base layer conducts on-chain validation of these notices through
1313

1414
This validation process ensures the integrity and authenticity of the submitted notices, enabling the blockchain to verify and authenticate the declared off-chain events or conditions.
1515

16-
Let's see how a Cartesi dApp's **Advance** request sends an output to the rollup server as a notice:
16+
Here are sample functions you can add to your application, then call to send a notice to the rollup server:
1717

1818
import Tabs from '@theme/Tabs';
1919
import TabItem from '@theme/TabItem';
@@ -23,25 +23,30 @@ import TabItem from '@theme/TabItem';
2323
<pre><code>
2424

2525
```javascript
26-
async function handle_advance(data) {
27-
console.log("Received advance request data " + JSON.stringify(data));
28-
29-
const inputPayload = data["payload"];
26+
import { stringToHex, hexToString } from "viem";
3027

28+
const emitNotice = async (inputPayload) => {
29+
let hexPayload = stringToHex(inputPayload); // convert payload from string to hex
3130
try {
3231
await fetch(rollup_server + "/notice", {
3332
method: "POST",
3433
headers: {
3534
"Content-Type": "application/json",
3635
},
37-
body: JSON.stringify({ payload: inputPayload }),
36+
body: JSON.stringify({ payload: hexPayload }),
3837
});
3938
} catch (error) {
4039
//Do something when there is an error
4140
}
41+
}
4242

43+
async function handle_advance(data) {
44+
console.log("Received advance request data " + JSON.stringify(data));
45+
const payload = hexToString(data.payload); // convert input from hex to string for processing
46+
await emitNotice(payload);
4347
return "accept";
4448
}
49+
4550
```
4651

4752
</code></pre>
@@ -51,24 +56,16 @@ async function handle_advance(data) {
5156
<pre><code>
5257

5358
```python
54-
55-
def handle_advance(data):
56-
logger.info(f"Received advance request data {data}")
57-
58-
status = "accept"
59-
try:
60-
inputPayload = data["payload"]
61-
## Send the input payload as a notice
62-
response = requests.post(
63-
rollup_server + "/notice", json={"payload": inputPayload}
64-
)
65-
logger.info(
66-
f"Received notice status {response.status_code} body {response.content}"
67-
)
68-
except Exception as e:
69-
# Emits report with error message here
70-
return status
71-
59+
# Notice creation Process from a message string
60+
def emit_notice(message):
61+
notice_payload = {"payload": "0x" + message.encode("utf-8").hex()}
62+
response = requests.post(rollup_server + "/notice", json=notice_payload)
63+
if response.status_code == 200 or response.status_code == 201:
64+
logger.info(f"Notice emitted successfully with data: {notice_payload}")
65+
else:
66+
logger.error(f"Failed to emit Notice with data: {notice_payload}. Status code: {response.status_code}")
67+
68+
emit_notice("hello world")
7269
```
7370

7471
</code></pre>

cartesi-rollups_versioned_docs/version-2.0/api-reference/backend/vouchers.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,89 @@ The [`CartesiDApp`](../contracts/application.md) contract is crucial in validati
1616

1717
The result of the voucher execution is recorded on the base layer. This recording typically involves submitting claims by a consensus contract, ensuring the integrity and transparency of the executed on-chain action.
1818

19+
import Tabs from '@theme/Tabs';
20+
import TabItem from '@theme/TabItem';
21+
22+
<Tabs>
23+
<TabItem value="Python" label="Python" default>
24+
<pre><code>
25+
26+
```python
27+
# Voucher creation process
28+
import requests
29+
import json
30+
from os import environ
31+
from eth_utils import function_signature_to_4byte_selector
32+
from eth_abi import decode, encode
33+
34+
rollup_server = environ["ROLLUP_HTTP_SERVER_URL"]
35+
36+
def emit_voucher(function_signature, destination, types, values):
37+
selector = function_signature_to_4byte_selector(function_signature)
38+
encoded_params = encode(types, values)
39+
payload = "0x" + (selector + encoded_params).hex()
40+
response = requests.post(rollup_server + "/voucher", json={"payload": payload, "destination": destination, "value": '0x' + encode(["uint256"], [0]).hex()})
41+
if response.status_code == 200 or response.status_code == 201:
42+
logger.info(f"Voucher emitted successfully with data: {payload}")
43+
else:
44+
logger.error(f"Failed to emit Voucher with data: {payload}. Status code: {response.status_code}")
45+
46+
47+
emit_voucher("mint(address)", "0x784f0c076CC55EAD0a585a9A13e57c467c91Dc3a", ["address"], [data["metadata"]["msg_sender"]])
48+
```
49+
50+
</code></pre>
51+
</TabItem>
52+
53+
<TabItem value="Javascript" label="Javascript" default>
54+
<pre><code>
55+
56+
```javascript
57+
import { stringToHex, encodeFunctionData, erc20Abi, zeroHash } from "viem";
58+
59+
async function handle_advance(data) {
60+
console.log("Received advance request data " + JSON.stringify(data));
61+
const sender = data["metadata"]["msg_sender"];
62+
const erc20Token = "0x784f0c076CC55EAD0a585a9A13e57c467c91Dc3a"; // Sample ERC20 token address
63+
64+
const call = encodeFunctionData({
65+
abi: erc20Abi,
66+
functionName: "transfer",
67+
args: [sender, BigInt(10)],
68+
});
69+
70+
let voucher = {
71+
destination: erc20Token,
72+
payload: call,
73+
value: zeroHash,
74+
};
75+
76+
await emitVoucher(voucher);
77+
return "accept";
78+
}
79+
80+
81+
const emitVoucher = async (voucher) => {
82+
try {
83+
await fetch(rollup_server + "/voucher", {
84+
method: "POST",
85+
headers: {
86+
"Content-Type": "application/json",
87+
},
88+
body: JSON.stringify(voucher),
89+
});
90+
} catch (error) {
91+
//Do something when there is an error
92+
}
93+
};
94+
95+
```
96+
97+
</code></pre>
98+
</TabItem>
99+
100+
</Tabs>
101+
19102
:::note create a voucher
20103
[Refer to the documentation here](../../development/asset-handling.md) for asset handling and creating vouchers in your dApp.
21104
:::

0 commit comments

Comments
 (0)