Rust library for developing safe canisters.

Overview

IC Kit

Docs

This library provides an alternative to ic-cdk that can help developers write canisters and unit test them in their Rust code.

Install

Add this to your Cargo.toml

[dependencies]
ic-kit = "0.4.2"
ic-cdk = "0.3.1"

[target.'cfg(not(target_family = "wasm"))'.dependencies]
async-std = { version="1.10.0", features = ["attributes"] }

Example Usage

use ic_kit::macros::*;
use ic_kit::*;

#[update]
fn whoami() -> Principal {
    let ic = get_context();
    ic.caller()
}

#[update]
async fn send_cycles(canister_id: Principal, cycles: u64) -> Result<(), String> {
    let ic = get_context();
    ic.call_with_payment(canister_id, "wallet_accept", (), cycles)
        .await
        .map_err(|(code, msg)| format!("Call failed with code={}: {}", code as u8, msg))
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_whoami() {
        MockContext::new()
            .with_caller(mock_principals::alice())
            .inject();

        assert_eq!(whoami(), mock_principals::alice());
    }

    #[async_test]
    async fn test_send_cycles() {
        // Create a context that just consumes 1000 cycles from all the inter-canister calls and
        // returns "()" in response.
        let ctx = MockContext::new()
            .with_consume_cycles_handler(1000)
            .inject();

        // Init a watcher at this point that will track all of the calls made from now on.
        let watcher = ctx.watch();

        send_cycles(mock_principals::xtc(), 5000).await.unwrap();

        assert_eq!(watcher.cycles_consumed(), 1000);
        assert_eq!(watcher.cycles_sent(), 5000);
    }
}

Comments
  • Requesting clarification on the following: Dynamic canister creation, automatic Candid generation, inter canister calls

    Requesting clarification on the following: Dynamic canister creation, automatic Candid generation, inter canister calls

    It would be really helpful if you could document how to do the following with ic-kit:

    • dynamic canister creation
    • automatic Candid generation
    • inter canister calls

    as comments in the examples provided and provide any guidance on how to set it up from scratch on a new project.

    I was using ic-kit 0.4.8 before. It included calls to the management canister as documented here for the dynamic creations of canisters but that seems to have been removed in v0.5 onwards.

    And I had been using the cargo test mechanism of automatic Candid generation as used in some other Psychedelic projects like this

    For inter canister calls, I tried the mechanism outlined here but it's not type safe so it breaks compilation with Cargo. I created a post for it here

    I feel ic-kit 0.5 would probably solve all of the above but I'm unable to make it work atm.

    I see some of the examples have pending todos and I imagine you'll be fleshing them out in more details.

    In case you already plan to cover the above, please ignore this issue :)

    opened by saikatdas0790 6
  • Compitable with ic_cdk 0.4.0

    Compitable with ic_cdk 0.4.0

    I found that ic_cdk 0.4.0 deprecate block_on function and use its own spawn.

    ic_kit use ic_cdk::block_on to do the job of ic::spwan.

    Besides, ic_cdk::spawn doesn't need Send trait bound to the future F while ic_kit does.

    #[inline(always)]
    pub fn spawn<F: 'static + std::future::Future<Output = ()> + std::marker::Send>(future: F) {
        get_context().spawn(future)
    }
    

    When I have a job which call another canister, the future returned does not have Send trait. Thus ic::spawn can not execute the job.

        |
    498 |     let xtc_balance: (Nat, ) = ic::call(Principal::from_text(XTC).unwrap(), "balanceOf", (ic::id(),))
        |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ await occurs here on type `Pin<Box<dyn Future<Output = Result<(ic_kit::candid::Nat,), (RejectionCode, std::string::String)>>>>`, which is not `Send`
    note: required by a bound in `ic_kit::ic::spawn`
    
    
        |
    555 |     ic::spawn(schedule_job());
        |     ^^^^^^^^^ future returned by `schedule_job` is not `Send`
        |
    
    opened by Myse1f 1
  • adds ic-kit-macros

    adds ic-kit-macros

    this removes user-level dependency on ic-cdk, the macro is currently a copy of ic-cdk's but at least now it's in our repo so we can start being innovative on top of it.

    opened by qti3e 0
  • ic-kit-sys

    ic-kit-sys

    This implements and adds the ic-kit-sys crate, which is a low-level binding to the IC and provides us with a nicer level of abstraction that will be used to simplify the code for ic-kit.

    opened by qti3e 0
  • feat: ic-kit-http

    feat: ic-kit-http

    Adds HTTP routing to kit canisters!

    Currently, the functionality is provided as a flag on ic-kit, and will enable the required features in the kit macros.

    Example

    An example HTTP pastebin is provided in the examples

    use ic_kit::prelude::*;
    
    #[get(route = "/")]
    fn index_handler(_: HttpRequest, _: Params) -> HttpResponse {
        HttpResponse {
            status_code: 200,
            headers: vec![],
            body: b"this is an example".into(),
            streaming_strategy: None,
            upgrade: false,
        }
    }
    

    How it works?

    Internally, for the routing, we use matchit, a blazing fast URL router. Routing happens within the nanosecond scale :) This is the same library used for cloudflare/worker-rs

    Tasks

    • [x] initial implementation (get only)
    • [x] Support all HTTP methods (get, put, post, options, head, patch, delete, connect)
    • [x] simple pastebin example (basic usage + canister side rendering)
    • [x] Helper for getting a specific header field from an HttpRequest
    • [x] Helpers for building an HttpResponse
    • [x] DI support (integrate into existing entrypoint instead of custom)
    • [ ] graceful error macros + routing (handlers should return Results, catch error and route accordingly)
    opened by ozwaldorf 0
  • WIP: Dynamic canister

    WIP: Dynamic canister

    This implements the management canister with a custom ic_kit_install method. The final result should be having the ability to dynamically install typed canisters both in the kit-runtime and to make it work in the IC env as well.

    #[derive(KitCanister)]
    #[candid_path("candid.did")]
    #[wasm_path("canister.wasm")]
    pub struct CounterCanister;
    

    And a factory canister should now be able to deploy this canister on the fly by doing:

    use counter_canister::CounterCanister;
    
    #[update]
    fn deploy_canister(canister_id: Principal) {
      CounterCanister::install_code(canister_id, InstallConfig {...}).await;
    }
    

    The install_code implementation should use different targets #[cfg(not(target_family = "wasm"))] and #[cfg(target_family = "wasm")] to perform platform specific calls to the management canister.

    opened by qti3e 2
  • How to mock canister with existing method?

    How to mock canister with existing method?

    Hi. Amazing library! Can you please provide some insight on how to mock a canister with existing methods.

    Say, I have a method

    #[update]
    async fn do_nothing(my_arg: u64) -> Result<(), String> {
        Ok(())
    }
    

    How would I create a Canister mock with the method above? I've tried to use RawHandler, but cannot figure out how to transfer arguments correctly.

    The way I want to use it later is like so:

    let canister = Canister::new(mock_principals::alice())
        .method("do_nothing", ...);
    
    let ctx = canister.context().inject();
    ic::call_with_payment(mock_principals::alice(), "do_nothing", (1000), 100);
    

    Is it even possible with the current implementation?

    opened by Maximkaaa 0
Releases(0.5.0-alpha.4)
  • 0.5.0-alpha.4(Oct 13, 2022)

  • 0.4.8(Oct 13, 2022)

    Retroactive addition for the previous 0.4.8 release

    What's Changed

    • update ic_cdk to 0.4.0 by @Myse1f in https://github.com/Psychedelic/ic-kit/pull/3
    • Add update_id call by @awkure in https://github.com/Psychedelic/ic-kit/pull/7
    • Add link to blog post by @paulyoung in https://github.com/Psychedelic/ic-kit/pull/6
    • Add APIs to interact with stable storage by @qti3e in https://github.com/Psychedelic/ic-kit/pull/8
    • make stable public by @qti3e in https://github.com/Psychedelic/ic-kit/pull/9
    • Resolve ic-cdk error by @qti3e in https://github.com/Psychedelic/ic-kit/pull/10
    • ic-kit-sys by @qti3e in https://github.com/Psychedelic/ic-kit/pull/12
    • Safe memory APIs by @qti3e in https://github.com/Psychedelic/ic-kit/pull/11
    • adds ic-kit-macros by @qti3e in https://github.com/Psychedelic/ic-kit/pull/13

    Full Changelog: https://github.com/Psychedelic/ic-kit/commits/0.4.8

    Source code(tar.gz)
    Source code(zip)
Owner
Psychedelic
Decentralized venture studio focused on building products on the Internet Computer.
Psychedelic
A fast Rust-based safe and thead-friendly grammar-based fuzz generator

Intro fzero is a grammar-based fuzzer that generates a Rust application inspired by the paper "Building Fast Fuzzers" by Rahul Gopinath and Andreas Ze

null 203 Nov 9, 2022
CVEs for the Rust standard library

Rust CVE Preface This is a list of CVEs for unsound APIs in the Rust standard library. These bugs break Rust's memory safety guarantee and lead to sec

Yechan Bae 26 Dec 4, 2022
Rust library for building and running BPF/eBPF modules

RedBPF A Rust eBPF toolchain. Overview The redbpf project is a collection of tools and libraries to build eBPF programs using Rust. It includes: redbp

foniod 1.5k Jan 1, 2023
Advanced Fuzzing Library - Slot your Fuzzer together in Rust! Scales across cores and machines. For Windows, Android, MacOS, Linux, no_std, ...

LibAFL, the fuzzer library. Advanced Fuzzing Library - Slot your own fuzzers together and extend their features using Rust. LibAFL is written and main

Advanced Fuzzing League ++ 1.2k Jan 6, 2023
QuickCheck bug hunting in Rust standard library data structures

BugHunt, Rust This project is aiming to provide "stateful" QuickCheck models for Rust's standard library. That is, we build up a random list of operat

Brian L. Troutwine 161 Dec 15, 2022
Mundane is a Rust cryptography library backed by BoringSSL that is difficult to misuse, ergonomic, and performant (in that order).

Mundane Mundane is a Rust cryptography library backed by BoringSSL that is difficult to misuse, ergonomic, and performant (in that order). Issues and

Google 1.1k Jan 3, 2023
A simple rust library for working with ZIP archives

rust-zip A simple rust library to read and write Zip archives, which is also my pet project for learning Rust. At the moment you can list the files in

Jorge Gorbe Moya 11 Aug 6, 2022
An attempt to rewrite lite-client for TON Blockchain in Rust using ton-labs-adnl library.

An attempt to rewrite lite-client for TON Blockchain in Rust using ton-labs-adnl library.

TonStack 4 Nov 9, 2022
A new shellcode injection technique. Given as C++ header, standalone Rust program or library.

FunctionStomping Description This is a brand-new technique for shellcode injection to evade AVs and EDRs. This technique is inspired by Module Stompin

Ido Veltzman 608 Jan 4, 2023
Extended precision integer Rust library. Provides signed/unsigned integer 256 to 2048.

Extended precision integer Rust library. Provides signed/unsigned integer 256 to 2048.

Mohanson 4 Jul 28, 2022
Linux anti-debugging and anti-analysis rust library

DebugOff Library Linux anti-analysis Rust library The goal of this library is to make both static and dynamic (debugging) analysis more difficult. The

null 65 Jan 7, 2023
An R interface to Rust's h3o library

h3o h3o is a system-dependency free package to interact with the H3 Geospatial Indexing system by Uber. h3o utilizes the Rust library h3o with is a pu

Josiah Parry 5 Mar 27, 2023
A rust library for sharing and updating arbitrary slices between threads, optimized for wait-free reads

atomicslice A Rust library for thread-safe shared slices that are just about as fast as possible to read while also being writable. Overview Use Atomi

Tim Straubinger 5 Dec 6, 2023
unfuck is a utility and library for deobfuscating obfuscated Python 2.7 bytecode

unfuck is a utility and library for deobfuscating obfuscated Python 2.7 bytecode. It is essentially a reimplementation of the Python VM with taint tracking.

Lander Brandt 171 Dec 14, 2022
Xori is an automation-ready disassembly and static analysis library for PE32, 32+ and shellcode

Xori - Custom disassembly framework Xori is an automation-ready disassembly and static analysis library that consumes shellcode or PE binaries and pro

ENDGAME 712 Nov 28, 2022
Cross-platform async library for system information fetching 🦀

heim Cross-platform library for system information fetching heim is an ongoing attempt to create the best tool for system information fetching (ex., C

null 782 Jan 2, 2023
Memory hacking library for windows.

Memory hacking library for windows.

sy1ntexx 40 Jan 3, 2023
A library for building tools to determine if vulnerabilities are reachable in a code base.

Overview Vuln Reach is a library for developing tools that determine if a given vulnerability is reachable. Provided to the open source community by P

Phylum 3 May 5, 2023
Detects usage of unsafe Rust in a Rust crate and its dependencies.

cargo-geiger ☢️ Looking for maintainer: https://github.com/rust-secure-code/cargo-geiger/issues/210 A program that lists statistics related to the usa

Rust Secure Code Working Group 1.1k Jan 4, 2023