LIBCMA is a lightweight Rust binding for Cartesi Machine Application (CMA) tooling: parse rollup inputs, build on-chain voucher payloads, and manage application assets (deposits, withdrawals, transfers, balances) for ETH, ERC-20, ERC-721, and ERC-1155.
Headers come from git submodules under third_party/:
third_party/machine-asset-tools—libcma(parser, types, ledger)third_party/machine-guest-tools—libcmtheaders used bylibcma
git clone --recurse-submodules https://github.com/Mugen-Builders/libcma_binding_rust
# or, if already cloned:
git submodule update --init --recursiveA plain cargo build works out of the box — build.rs takes care of the fiddly parts:
- Submodules auto-init. If
third_party/is empty (you cloned without--recurse-submodules),build.rsrunsgit submodule update --init --recursivefor you. - bindgen clang headers auto-fallback.
bindgenneeds the compiler's builtin headers (stdbool.h, …). If yourlibclangships without them (e.g. you havelibclang1but notlibclang-common-*-dev),build.rsfalls back to GCC's builtin header dir automatically — noBINDGEN_EXTRA_CLANG_ARGSneeded. Set that env var yourself to override.
So the only hard host requirement for the default build is:
- A Rust toolchain +
libclang(forbindgen) andgit(for the submodule fetch).
For the riscv64 build (linking the real C++ libcma), build.rs also cross-compiles the static archive from source if it isn't already present. That path additionally needs:
- GNU
make,wget, and network access - The RISC-V GCC 14 cross toolchain —
g++-14-riscv64-linux-gnu/gcc-14-riscv64-linux-gnu(libcma's C++ source requires GCC ≥ 14). Override the compiler names withCMA_RISCV64_CXX/CMA_RISCV64_CC.
The Cartesi SDK / app Docker image used to build the machine already provides all of these.
| Feature | Default | Purpose |
|---|---|---|
native |
yes | Compiles src/mocks.rs shims so host tests run without the RISC-V libcma archive |
riscv64 |
no | Cross-build path that links the real C++ cma library; build.rs cross-compiles build/riscv64/libcma.a from the submodule source if it isn't already present (needs the RISC-V GCC 14 cross toolchain) |
cargo build --no-default-features --features riscv64Ledger wraps cma_ledger_* with helpers for file/buffer initialization, asset/account retrieval, deposit/withdraw/transfer, balance, and total supply.
retrieve_ether_assets()usesAssetType::BaseAssetTypealso supportsTokenAddress,TokenAddressId, andTokenAddressIdAmountRetrieveOperation::FindAndRemoveis supported
Pure-Rust parser aligned with machine-asset-tools / Cartesi Rollups v2.0:
- Portal deposit decoding (packed + ABI tails for ERC-721/1155)
- Auto-decode withdrawals/transfers by function selector
- Inspect decoding for
ledger_getBalanceandledger_getTotalSupply - Voucher encoding for Ether, ERC-20, ERC-721 (
safeTransferFrom), ERC-1155 single/batch (safeTransferFrom/safeBatchTransferFrom)
cma_decode_advance(req_type, input) -> Result<CmaParserInput, CmaParserError>cma_decode_inspect(input) -> Result<CmaParserInput, CmaParserError>cma_encode_voucher(req_type, app_address, voucher_request) -> Result<CmaVoucher, CmaParserError>
CmaVoucher fields: destination, value (wei for ether vouchers), payload.
Inspect params are flat JSON strings, e.g.:
{"method":"ledger_getBalance","params":["0x...account...","0x...token...","0x1"]}cargo testtests/parser_tests.rs— integration tests against the pure-Rust parsertests/parser_vectors.rs— vectors ported fromthird_party/machine-asset-tools/tests/parser.ctests/ledger_tests.rs— ledger tests via native mocks
CI runs native tests on every push/PR and attempts an riscv64 link check when libcma can be built.
MIT (see Cargo.toml).
