canic_core/interface/ic/
mod.rs1pub mod canister;
5pub mod cycles;
6pub mod helper;
7pub mod icp;
8pub mod network;
9pub mod sns;
10
11pub use helper::*;
12
13use crate::{
14 Error,
15 cdk::{
16 call::Call,
17 mgmt::{
18 self, CanisterInstallMode, CanisterStatusArgs, CanisterStatusResult,
19 DeleteCanisterArgs, DepositCyclesArgs, InstallCodeArgs, UninstallCodeArgs, WasmModule,
20 },
21 },
22 env::nns::NNS_REGISTRY_CANISTER,
23 interface::prelude::*,
24 log,
25 log::Topic,
26 spec::nns::{GetSubnetForCanisterRequest, GetSubnetForCanisterResponse},
27};
28use candid::{CandidType, Principal, decode_one, encode_args, utils::ArgumentEncoder};
29
30pub async fn canister_status(canister_pid: Principal) -> Result<CanisterStatusResult, Error> {
36 let args = CanisterStatusArgs {
37 canister_id: canister_pid,
38 };
39
40 mgmt::canister_status(&args).await.map_err(Error::from)
41}
42
43#[must_use]
49pub fn canister_cycle_balance() -> Cycles {
50 crate::cdk::api::canister_cycle_balance().into()
51}
52
53pub async fn deposit_cycles(canister_pid: Principal, cycles: u128) -> Result<(), Error> {
55 let args = DepositCyclesArgs {
56 canister_id: canister_pid,
57 };
58 mgmt::deposit_cycles(&args, cycles)
59 .await
60 .map_err(Error::from)
61}
62
63pub async fn get_cycles(canister_pid: Principal) -> Result<Cycles, Error> {
65 let status = canister_status(canister_pid).await?;
66
67 Ok(status.cycles.into())
68}
69
70pub async fn get_current_subnet_pid() -> Result<Option<Principal>, Error> {
76 let request = GetSubnetForCanisterRequest::new(canister_self());
77
78 let subnet_id_opt = Call::unbounded_wait(*NNS_REGISTRY_CANISTER, "get_subnet_for_canister")
79 .with_arg(request)
80 .await?
81 .candid::<GetSubnetForCanisterResponse>()?
82 .map_err(Error::CallFailed)?
83 .subnet_id;
84
85 if let Some(subnet_id) = subnet_id_opt {
86 log!(Topic::Topology, Info, "get_current_subnet_pid: {subnet_id}");
87 } else {
88 log!(Topic::Topology, Warn, "get_current_subnet_pid: not found");
89 }
90
91 Ok(subnet_id_opt)
92}
93
94pub async fn install_code<T: ArgumentEncoder>(
100 mode: CanisterInstallMode,
101 canister_pid: Principal,
102 wasm: &[u8],
103 args: T,
104) -> Result<(), Error> {
105 let arg = encode_args(args)?;
106 let install_args = InstallCodeArgs {
107 mode,
108 canister_id: canister_pid,
109 wasm_module: WasmModule::from(wasm),
110 arg,
111 };
112
113 mgmt::install_code(&install_args).await.map_err(Error::from)
114}
115
116pub async fn uninstall_code(canister_pid: Principal) -> Result<(), Error> {
118 let args = UninstallCodeArgs {
119 canister_id: canister_pid,
120 };
121
122 mgmt::uninstall_code(&args).await.map_err(Error::from)
123}
124
125pub async fn delete_canister(canister_pid: Principal) -> Result<(), Error> {
127 let args = DeleteCanisterArgs {
128 canister_id: canister_pid,
129 };
130
131 mgmt::delete_canister(&args).await.map_err(Error::from)
132}
133
134pub async fn call_and_decode<T: CandidType + for<'de> candid::Deserialize<'de>>(
140 pid: Principal,
141 method: &str,
142 arg: impl CandidType,
143) -> Result<T, Error> {
144 let response = Call::unbounded_wait(pid, method)
145 .with_arg(arg)
146 .await
147 .map_err(Error::from)?;
148
149 decode_one(&response).map_err(Error::from)
150}