You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Rust toolkit for Internet Computer canister development. Standardizes common patterns: authentication, HTTP handling, storage, telemetry, inter-canister calls, and ML model serving.
Installation
Add to your Cargo.toml:
[dependencies]
ic-dev-kit-rs = "0.1.0"# Enable optional features (most common)ic-dev-kit-rs = { version = "0.1.0", features = ["storage", "telemetry"] }
# ML features (includes storage automatically)ic-dev-kit-rs = { version = "0.1.0", features = ["text-generation"] }
Features
Feature
Description
Dependencies
storage
Stable storage utilities
ic-stable-structures
telemetry
Canistergeek monitoring/logging
canistergeek_ic_rust
candle
ML model infrastructure
candle-core, candle-nn
text-generation
LLM text generation
candle, tokenizers
Quick Start
1. Authentication
use ic_dev_kit_rs::auth;#[ic_cdk::init]fninit(){// Initialize auth with deployer as first authorized principal
auth::init_with_caller();}#[ic_cdk::update(guard = "auth::is_authorized")]fnprotected_method(){// Only authorized principals can call this}#[ic_cdk::update(guard = "auth::is_authorized")]fnadd_admin(principal:Principal){
auth::add_principal(principal).unwrap();}
use ic_dev_kit_rs::storage::{self,StorageRegistry};use ic_stable_structures::{StableBTreeMap, memory_manager::*,DefaultMemoryImpl};use std::cell::RefCell;typeMemory = VirtualMemory<DefaultMemoryImpl>;thread_local!{staticMEMORY_MANAGER:RefCell<MemoryManager<DefaultMemoryImpl>> =
RefCell::new(MemoryManager::init(DefaultMemoryImpl::default()));staticREGISTRY:RefCell<StableBTreeMap<String,Vec<u8>,Memory>> = RefCell::new(StableBTreeMap::init(MEMORY_MANAGER.with(|m| m.borrow().get(MemoryId::new(1))),));}// Save any CandidType#[ic_cdk::update]fnsave_config(config:MyConfig) -> Result<(),String>{REGISTRY.with(|reg| {
storage::save_candid(reg,"config",&config)})}// Load it back#[ic_cdk::query]fnget_config() -> Option<MyConfig>{REGISTRY.with(|reg| {
storage::load_candid(reg,"config")})}// Raw bytes for binary data#[ic_cdk::update]fnsave_binary(key:String,data:Vec<u8>){REGISTRY.with(|reg| {
storage::save_bytes(reg,&key, data);});}
4. Telemetry (requires telemetry feature)
use ic_dev_kit_rs::telemetry;#[ic_cdk::init]fninit(){
telemetry::init();}#[ic_cdk::update]fnprocess_data(){
telemetry::collect_metrics();
telemetry::log_info("Processing started");// Your logic here...
telemetry::log_info("Processing completed");}// Use the macro to export Canistergeek-compatible endpoints
ic_dev_kit_rs::export_telemetry_endpoints!();
5. Large Object Uploads
use ic_dev_kit_rs::large_objects;// Sequential upload (simple, chunks must arrive in order)#[ic_cdk::update]fnupload_chunk(data:Vec<u8>) -> usize{
large_objects::append_chunk(data);
large_objects::buffer_size()}#[ic_cdk::update]fnfinalize_upload() -> Vec<u8>{
large_objects::get_buffer_data()}// Parallel upload (faster, chunks can arrive out of order)#[ic_cdk::update]fnupload_parallel_chunk(chunk_id:u32,data:Vec<u8>){
large_objects::append_parallel_chunk(chunk_id, data);}#[ic_cdk::query]fncheck_upload_complete(expected_count:u32) -> bool{
large_objects::parallel_chunks_complete(expected_count)}#[ic_cdk::query]fnget_missing_chunks(expected_count:u32) -> Vec<u32>{
large_objects::missing_chunks(expected_count)}#[ic_cdk::update]fnfinalize_parallel_upload() -> Result<Vec<u8>,String>{
large_objects::consolidate_parallel_chunks()?;Ok(large_objects::get_buffer_data())}#[ic_cdk::query]fnupload_status() -> String{
large_objects::storage_status().to_string()}
6. Inter-canister Calls
use ic_dev_kit_rs::intercanister;use candid::Principal;#[ic_cdk::update]asyncfncall_other_canister(canister_id:Principal) -> Result<String,String>{// Simple call with automatic logging
intercanister::call(canister_id,"get_data",()).await}#[ic_cdk::update]asyncfncall_with_args(canister_id:Principal,arg:String) -> Result<u64,String>{// Call with arguments (use tuple for multiple args)
intercanister::call(canister_id,"process",(arg,)).await}#[ic_cdk::update]asyncfncall_with_cycles(canister_id:Principal) -> Result<String,String>{// Call with cycles attached
intercanister::call_with_payment(
canister_id,"paid_method",(),1_000_000,// cycles).await}#[ic_cdk::update]fnfire_and_forget(canister_id:Principal) -> Result<(),String>{// One-way notification (no response)
intercanister::call_one_way(canister_id,"log_event",("user_action",))}
See the examples directory for complete canister examples.
License
MIT OR Apache-2.0
About
Rust development kit for the Internet Computer - standardizes HTTP call generation, large object storage, Canister Geek integration, and query timeouts with battle-tested abstractions