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:
- Generate ABI at build time as JSON - The build process analyzes your Rust code and generates a JSON Schema-based ABI
- 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?
- Follow the Tutorial: Start with our Getting Started Tutorial for a complete walkthrough
- Explore Configuration: Learn about Configuration Options for advanced setups
- Understand the Build Process: Dive into How ABI Generation Works
- Integrate with Rust: See Rust Integration Patterns
Documentation
- Build Process - How ABI generation works under the hood
- Configuration - Configure ABI generation for your needs
- Rust Integration - Advanced Rust patterns and best practices
- Validation - ABI validation and testing strategies
- Protocol Support - Protocol-specific features and optimizations
- Tools - ABI tools and utilities
- Examples - Practical examples and use cases
- Troubleshooting - Common issues and solutions
Resources
- GitHub Repository - Source code and issues
- API Reference - Complete API documentation
- Community Discord - Get help from the community
- Blog Posts - Latest updates and tutorials