Skip to main content

Rust Protocol SDK

Calimero SDK Macros for Rust​

This guide provides a comprehensive reference of the essential macros provided by the Calimero SDK for building Rust applications.

Core Macros​

#[app::state]​

Marks a struct as the application state. The state struct must implement BorshSerialize and BorshDeserialize.

#[app::state]
#[derive(Default, BorshSerialize, BorshDeserialize)]
#[borsh(crate = "calimero_sdk::borsh")]
struct MyAppState {
// Your state fields here
}

When emitting events, spcify the event type:

#[app::state(emits = for<'a> MyEvent<'a>)]
struct MyAppState {
// Your state fields here
}

#[app::logic]​

Marks an implementation block as containing the application logic.

#[app::logic]
impl MyAppState {
// Your methods here
}

#[app::init]​

Marks a method as the initializer, which is called when the application is first deployed.

#[app::logic]
impl MyAppState {
#[app::init]
pub fn init() -> Self {
Self::default()
}
}

#[app::event]​

Defines an event type that can be emitted by your application.

#[app::event]
pub enum MyEvent<'a> {
ValueUpdated { key: &'a str, value: &'a str },
ValueRemoved { key: &'a str },
}

Event emission​

Use the app::emit! macro to emit events from your application:

app::emit!(MyEvent::ValueUpdated { 
key: &key,
value: &new_value
});

Complete Example​

Here's a minimal example showing how these macros work together:

use calimero_sdk::borsh::{BorshDeserialize, BorshSerialize};
use calimero_sdk::{app, env};
use calimero_storage::collections::UnorderedMap;

#[app::event]
pub enum StoreEvent<'a> {
ValueSet { key: &'a str, value: &'a str },
}

#[app::state(emits = for<'a> StoreEvent<'a>)]
#[derive(Default, BorshSerialize, BorshDeserialize)]
#[borsh(crate = "calimero_sdk::borsh")]
struct Store {
values: UnorderedMap<String, String>,
}

#[app::logic]
impl Store {
#[app::init]
pub fn init() -> Self {
Self {
values: UnorderedMap::new(),
}
}

pub fn set(&mut self, key: String, value: String) {
self.values.insert(key, value).unwrap();
app::emit!(StoreEvent::ValueSet {
key: &key,
value: &value
});
}
}

Important Notes​

  1. State changes are atomic - if a method fails, all changes are rolled back
  2. Events are only emitted if the transaction succeeds
  3. Read-only operations have no network overhead
  4. All public methods in the #[app::logic] block become available as application endpoints

For a detailed guide on building a complete application using these macros, see our Tutorial Guide on building a Key Value Store.

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