AI agent documentation index: llms.txt. Raw markdown for any page is available by appending .md to the URL. Full content snapshot: llms-full.txt.
llms.txt — complete Cartesi documentation index. Append .md to any page URL for raw Markdown (e.g. /cartesi-rollups/2.0/development/building-an-application.md).
Skip to main content

Parsing inputs

Every input reaches your application as raw bytes. The CMA parser understands and processes three kinds of inputs and turns each one into typed values:

  1. Deposits sent by the Cartesi portal contracts.
  2. Application calls such as withdrawals and transfers, sent by users as ABI encoded payloads.
  3. Inspect queries for balances and total supply, sent as JSON.

Know who sent the input

The parser does not guess where an input came from. Your application checks the msg_sender of each advance request first:

  • If the sender is a portal contract, the input is a deposit. Pass the matching deposit type to the parser.
  • If the sender is anything else, treat it as an application call and let the parser detect the operation from the payload itself.
caution

Portal addresses change between Rollups versions. Always confirm the addresses for the version you deploy against.

Decoding deposits

Each portal encodes its deposits in a fixed ABI layout. The parser knows these layouts, so one call gives you all the deposit fields.

pycma has one decode function per deposit type. Each takes the advance request returned by read_advance_state() and returns a plain dictionary:

from pycma import (
decode_ether_deposit,
decode_erc20_deposit,
decode_erc721_deposit,
decode_erc1155_single_deposit,
decode_erc1155_batch_deposit,
)

advance = rollup.read_advance_state()
msg_sender = advance["msg_sender"].hex().lower()

if msg_sender == ERC20_PORTAL_ADDRESS:
deposit = decode_erc20_deposit(advance)
# deposit["sender"] -> depositor address
# deposit["token"] -> token contract address
# deposit["amount"] -> amount as an int

The full list of deposit result fields per asset is in Types and selectors.

Decoding application calls

Withdrawals and transfers are actions application users call directly. For the parser to decode them, the input must arrive as an ABI encoded call that matches one of the function selectors the parser knows. The first four bytes of the payload identify the operation, and the rest carries the arguments. The complete selector table is in Types and selectors.

When the sender is not a portal, the parser is tasked with detecting the operation automatically:

decode_advance detects the operation from the payload and returns a dictionary with a type key:

from pycma import decode_advance

decoded = decode_advance(advance)

if decoded["type"] == "ERC20_WITHDRAWAL":
# decoded["token"], decoded["amount"], decoded["exec_layer_data"]
...
elif decoded["type"] == "ERC20_TRANSFER":
# decoded["receiver"], decoded["token"], decoded["amount"]
...

The Python binding decodes all ten operations: Ether, ERC20, ERC721, ERC1155 single and ERC1155 batch, each as withdrawal and as transfer. It raises an exception when the payload does not match any known selector.

Decoding inspect queries

Balance and supply queries arrive as inspect requests. The payload is a small JSON document with a method name and a params array.

The C core and the Python binding accept the methods ledger_getBalance and ledger_getTotalSupply:

{
"method": "ledger_getBalance",
"params": ["0x0000000000000000000000000000000000000001"]
}

params[0] is the account. You can add a token address as params[1] and a token ID as params[2] to query a specific asset:

from pycma import decode_inspect

inspect = rollup.read_inspect_state()
query = decode_inspect(inspect)

if query["type"] == "BALANCE":
# query["account"], query["token"], query["token_id"]
...
elif query["type"] == "SUPPLY":
# query["token"], query["token_id"]
...

Handling parser errors

Every decode call can fail, for example when a payload is shorter than expected. Always check the result before you touch the ledger:

  • Python raises an exception with the error code and message.
  • Rust returns a Result with a CmaParserError.
  • C and C++ return a negative error code, and cma_parser_get_last_error_message() gives the matching text.

The complete error lists are in Types and selectors.

We use cookies to ensure that we give you the best experience on our website. By using the website, you agree to the use of cookies.