Skip to main content
Version: Next

ABI Generation

ABI Generation provides automatic generation of Application Binary Interfaces (ABI) for your Calimero applications. This blockchain-agnostic tool generates ABIs driven by JSON Schema with compile-time validation and strong type safety.

What is ABI Generation?

Application Binary Interface (ABI) generation is a compile-time process that automatically creates standardized interface definitions for your Calimero applications using JSON Schema. This enables:

  • JSON Schema-Driven Generation: ABI generation is driven by a JSON Schema with compile-time validation
  • Strong Type Safety: Compile-time validation ensures your application interfaces are correct
  • Automatic Documentation: Generate human-readable interface documentation
  • Tool Integration: Seamless integration with development tools and IDEs

Key Features

JSON Schema-Driven Generation

  • Schema-Based: ABI generation is driven by a JSON Schema with compile-time validation
  • Type Safety: Strong type safety ensures your application interfaces are correct
  • Method Validation: Verifies method signatures and return types
  • Event Validation: Validates event structures and parameters

Developer Experience

  • Rust Macros: Simple attribute-based configuration
  • IDE Integration: Full IntelliSense and error highlighting
  • Documentation Generation: Automatic API documentation
  • Testing Support: Built-in testing utilities and validation

Quick Start

1. Add Dependencies

Add the ABI generation dependencies to your Cargo.toml:

[build-dependencies]
calimero-abi-emitter = "0.1.0"

[dependencies]
calimero-abi-emitter = "0.1.0"

2. Configure Build Script

Create a build.rs file:

use calimero_abi_emitter::emit_manifest;

fn main() {
emit_manifest().expect("Failed to generate ABI manifest");
}

3. Annotate Your Application

Use the calimero_app macro to enable ABI generation:

use calimero_abi_emitter::calimero_app;

#[calimero_app]
pub struct MyApp {
// Your application state
}

impl MyApp {
pub fn my_method(&self, input: String) -> String {
// Your method implementation
input
}
}

4. Build and Validate

Build your application and validate the generated ABI:

cargo build --target wasm32-unknown-unknown --release
calimero-abi extract target/wasm32-unknown-unknown/release/my_app.wasm > abi.json
calimero-abi validate abi.json

Two-Step Generation Process

ABI Generation follows a clear two-step process:

  1. Generate ABI at build time as JSON - The build process analyzes your Rust code and generates a JSON Schema-based ABI
  2. Optionally embed into WASM - The ABI can be embedded into the WASM binary for tools that may load/swap different WASMs

This split explains why we have both build-time and normal dependencies in your Cargo.toml.

Integration with Calimero Tools

Merobox Integration

Use ABI-enabled applications in your Merobox workflows:

steps:
- name: Install ABI App
type: install_application
node: node-1
path: ./my_app.wasm
validate_abi: true

- name: Call Method
type: call
node: node-1
method: my_method
args:
input: 'Hello, ABI!'

SDK Integration

The generated ABI can be used to create type-safe client SDKs. This is a separate process from ABI generation itself - the ABI serves as the interface definition that client generation tools can consume:

import { MyAppClient } from './generated/MyAppClient';

const client = new MyAppClient(nodeUrl);
const result = await client.myMethod('Hello, ABI!');

Testing Integration

Validate ABI conformance in your tests:

#[test]
fn test_abi_conformance() {
let abi = include_bytes!("../target/abi_conformance.abi.json");
validate_abi(abi).expect("ABI validation failed");
}

Best Practices

Type Design

  • Use primitive types when possible for better compatibility
  • Avoid complex nested structures
  • Consider protocol-specific limitations
  • Use enums for state management

Method Design

  • Keep method signatures simple
  • Use descriptive parameter names
  • Return meaningful error types
  • Consider gas costs for different protocols

Event Design

  • Use events for important state changes
  • Include relevant context in event data
  • Use indexed parameters for filtering
  • Keep event data minimal

Testing

  • Test ABI generation in CI/CD
  • Validate against multiple protocols
  • Test error conditions
  • Verify type safety

Troubleshooting

Common Issues

  • Type Mismatches: Ensure all types are protocol-compatible
  • Method Conflicts: Avoid naming conflicts with protocol methods
  • Validation Failures: Check ABI conformance requirements
  • Build Errors: Verify all dependencies are correctly configured

Debug Mode

Enable debug mode for detailed ABI generation logs:

// build.rs
use calimero_abi_emitter::{emit_manifest_with_config, AbiConfig};

fn main() {
let config = AbiConfig {
debug_mode: true,
// ... other config
};
emit_manifest_with_config(config).expect("Failed to generate ABI manifest");
}

Getting Started

Ready to implement ABI generation in your Calimero application?

  1. Follow the Tutorial: Start with our Getting Started Tutorial for a complete walkthrough
  2. Explore Configuration: Learn about Configuration Options for advanced setups
  3. Understand the Build Process: Dive into How ABI Generation Works
  4. Integrate with Rust: See Rust Integration Patterns

Documentation

Resources

Was this page helpful?
Need some help? Check Support page