Atupa is architected to be extensible to new execution environments (e.g. Move VM, Fuel VM, Aptos/Sui). This guide explains how to build a new VM adapter crate.
Every VM adapter should be an independent crate in the crates/ directory (e.g., crates/atupa-fuel). An adapter's primary responsibility is to fetch raw RPC execution data and transform it into the unified atupa_core::TraceStep model.
- Error Types (
error.rs): Domain-specific error enum (FuelError) with standardstd::error::ErrorandDisplayimplementations. - Data Models (
types.rs): Serde-compatible models mapping the target chain's JSON-RPC structures. - Trace Parser / Flattener (
parser.rs): Logic that converts logs, diagnostic events, or raw invocation trees intoVec<TraceStep>. - Client (
client.rs): Async RPC client communicating with the target chain endpoint. - Facade (
lib.rs): Clean re-export of public client, parser, and error types.
Add your new VM to the VmKind enum in crates/atupa-core/src/vm.rs:
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum VmKind {
Evm,
Stylus,
Starknet,
Solana,
Stellar,
Fuel, // New VM kind
}Implement the RPC fetching logic and map native execution events to TraceStep:
pub struct FuelClient {
rpc_url: String,
}
impl FuelClient {
pub fn new(rpc_url: String) -> Self {
Self { rpc_url }
}
pub async fn get_transaction_trace(&self, tx: &str) -> FuelResult<Vec<TraceStep>> {
// 1. Fetch raw transaction data from RPC
// 2. Parse opcodes or receipt receipts into TraceStep
// 3. Set vm_kind = VmKind::Fuel
}
}Atupa flamegraphs rely on the depth field:
- Flat sequential logs (like Solana): Implement a state machine tracking call/return markers.
- Recursive trees (like Starknet): Recursively flatten the tree while incrementing the depth counter at each level.
Map native gas or resource units to a meaningful gas_cost:
- Solana: 1 Compute Unit (CU) = 1
gas_cost. - Soroban: HostFn CPU/Memory weight = estimated
gas_cost. - Starknet: Cairo instruction steps + builtin resource weights =
gas_cost.
- Add the new crate to the workspace
Cargo.toml. - Add the dependency to
crates/atupa-sdkandbin/atupa. - Add CLI hint handling in
bin/atupa/src/cli.rs(VmTarget) andcrates/atupa-sdk/src/profile.rs(VmHint). - Update
atupa-outputwith chain-specific color schemes for SVG rendering. - Update
studio/src/types/trace.tswith color tokens for Atupa Studio.
Add unit tests in your crate using fixture JSON files or mocked responses:
- Verify that total
gas_costmatches expected weights. - Verify that call depth increments and decrements correctly.
- Verify error display formatting and failure paths.