ic_kit/
interface.rs

1use std::future::Future;
2use std::pin::Pin;
3
4use ic_cdk::api::call::CallResult;
5use ic_cdk::export::candid::utils::{ArgumentDecoder, ArgumentEncoder};
6use ic_cdk::export::candid::{decode_args, encode_args};
7use ic_cdk::export::{candid, Principal};
8
9pub type CallResponse<T> = Pin<Box<dyn Future<Output = CallResult<T>>>>;
10
11/// A possible error value when dealing with stable memory.
12#[derive(Debug)]
13pub struct StableMemoryError();
14
15pub trait Context {
16    /// Trap the code.
17    fn trap(&self, message: &str) -> !;
18
19    /// Print a message.
20    fn print<S: AsRef<str>>(&self, s: S);
21
22    /// ID of the current canister.
23    fn id(&self) -> Principal;
24
25    /// The time in nanoseconds.
26    fn time(&self) -> u64;
27
28    /// The balance of the canister.
29    fn balance(&self) -> u64;
30
31    /// The caller who has invoked this method on the canister.
32    fn caller(&self) -> Principal;
33
34    /// Return the number of available cycles that is sent by the caller.
35    fn msg_cycles_available(&self) -> u64;
36
37    /// Accept the given amount of cycles, returns the actual amount of accepted cycles.
38    fn msg_cycles_accept(&self, amount: u64) -> u64;
39
40    /// Return the cycles that were sent back by the canister that was just called.
41    /// This method should only be called right after an inter-canister call.
42    fn msg_cycles_refunded(&self) -> u64;
43
44    /// Store the given data to the stable storage.
45    fn stable_store<T>(&self, data: T) -> Result<(), candid::Error>
46    where
47        T: ArgumentEncoder;
48
49    /// Restore the data from the stable storage. If the data is not already stored the None value
50    /// is returned.
51    fn stable_restore<T>(&self) -> Result<T, String>
52    where
53        T: for<'de> ArgumentDecoder<'de>;
54
55    /// Perform a call.
56    fn call_raw<S: Into<String>>(
57        &'static self,
58        id: Principal,
59        method: S,
60        args_raw: Vec<u8>,
61        cycles: u64,
62    ) -> CallResponse<Vec<u8>>;
63
64    /// Perform the call and return the response.
65    #[inline(always)]
66    fn call<T: ArgumentEncoder, R: for<'a> ArgumentDecoder<'a>, S: Into<String>>(
67        &'static self,
68        id: Principal,
69        method: S,
70        args: T,
71    ) -> CallResponse<R> {
72        self.call_with_payment(id, method, args, 0)
73    }
74
75    #[inline(always)]
76    fn call_with_payment<T: ArgumentEncoder, R: for<'a> ArgumentDecoder<'a>, S: Into<String>>(
77        &'static self,
78        id: Principal,
79        method: S,
80        args: T,
81        cycles: u64,
82    ) -> CallResponse<R> {
83        let args_raw = encode_args(args).expect("Failed to encode arguments.");
84        let method = method.into();
85        Box::pin(async move {
86            let bytes = self.call_raw(id, method, args_raw, cycles).await?;
87            decode_args(&bytes).map_err(|err| panic!("{:?}", err))
88        })
89    }
90
91    /// Set the certified data of the canister, this method traps if data.len > 32.
92    fn set_certified_data(&self, data: &[u8]);
93
94    /// Returns the data certificate authenticating certified_data set by this canister.
95    fn data_certificate(&self) -> Option<Vec<u8>>;
96
97    /// Execute a future without blocking the current call.
98    fn spawn<F: 'static + std::future::Future<Output = ()>>(&mut self, future: F);
99
100    /// Returns the current size of the stable memory in WebAssembly pages.
101    /// (One WebAssembly page is 64KiB)
102    fn stable_size(&self) -> u32;
103
104    /// Tries to grow the memory by new_pages many pages containing zeroes.
105    /// This system call traps if the previous size of the memory exceeds 2^32 bytes.
106    /// Errors if the new size of the memory exceeds 2^32 bytes or growing is unsuccessful.
107    /// Otherwise, it grows the memory and returns the previous size of the memory in pages.
108    fn stable_grow(&self, new_pages: u32) -> Result<u32, StableMemoryError>;
109
110    /// Writes data to the stable memory location specified by an offset.
111    fn stable_write(&self, offset: u32, buf: &[u8]);
112
113    /// Reads data from the stable memory location specified by an offset.
114    fn stable_read(&self, offset: u32, buf: &mut [u8]);
115
116    /// Pass an immutable reference of data with type `T` to the callback, stores the default value
117    /// if not present, and return the transformation.
118    fn with<T: 'static + Default, U, F: FnOnce(&T) -> U>(&self, callback: F) -> U;
119
120    /// Pass an immutable reference of data with type `T` to the callback, and return the mapped
121    /// value.
122    fn maybe_with<T: 'static, U, F: FnOnce(&T) -> U>(&self, callback: F) -> Option<U>;
123
124    /// Pass the mutable reference of data with type `T` to the callback, stores the default value
125    /// if not present, and return the transformation.
126    fn with_mut<T: 'static + Default, U, F: FnOnce(&mut T) -> U>(&self, callback: F) -> U;
127
128    /// Pass the mutable reference of data with type `T` to the callback, and return the callback's
129    /// result.
130    fn maybe_with_mut<T: 'static, U, F: FnOnce(&mut T) -> U>(&self, callback: F) -> Option<U>;
131
132    /// Remove the data associated with the given type, and return it.
133    fn take<T: 'static>(&self) -> Option<T>;
134
135    /// Replaced the stored value of type `T` with the new provided one and return the old one if
136    /// any.
137    fn swap<T: 'static>(&self, value: T) -> Option<T>;
138
139    /// See [ic::store](crate::ic::store)
140    #[deprecated]
141    fn store<T: 'static>(&self, data: T);
142
143    /// See [ic::store](crate::ic::get_maybe)
144    #[deprecated]
145    fn get_maybe<T: 'static>(&self) -> Option<&T>;
146
147    /// See [ic::store](crate::ic::get)
148    #[deprecated]
149    fn get<T: 'static + Default>(&self) -> &T;
150
151    /// See [ic::store](crate::ic::get_mut)
152    #[deprecated]
153    fn get_mut<T: 'static + Default>(&self) -> &mut T;
154
155    /// See [ic::store](crate::ic::delete)
156    #[deprecated]
157    fn delete<T: 'static + Default>(&self) -> bool;
158}