junobuild_shared/mgmt/
ic.rs1use crate::errors::{
2 JUNO_ERROR_CANISTER_CREATE_FAILED, JUNO_ERROR_CANISTER_INSTALL_CODE_FAILED,
3 JUNO_ERROR_CYCLES_DEPOSIT_BALANCE_LOW, JUNO_ERROR_CYCLES_DEPOSIT_FAILED,
4 JUNO_ERROR_SEGMENT_DELETE_FAILED, JUNO_ERROR_SEGMENT_STOP_FAILED,
5};
6use crate::mgmt::settings::{create_canister_cycles, create_canister_settings};
7use crate::mgmt::types::ic::{CreateCanisterInitSettingsArg, WasmArg};
8use crate::types::interface::DepositCyclesArgs;
9use candid::Principal;
10use ic_cdk::api::call::CallResult;
11use ic_cdk::api::canister_balance128;
12use ic_cdk::api::management_canister::main::{
13 create_canister, delete_canister, deposit_cycles as ic_deposit_cycles,
14 install_code as ic_install_code, stop_canister, update_settings, CanisterId, CanisterIdRecord,
15 CanisterInstallMode, CanisterSettings, CreateCanisterArgument, InstallCodeArgument,
16 UpdateSettingsArgument,
17};
18
19pub async fn create_canister_install_code(
30 create_settings_arg: &CreateCanisterInitSettingsArg,
31 wasm_arg: &WasmArg,
32 cycles: u128,
33) -> Result<Principal, String> {
34 let record = create_canister(
35 CreateCanisterArgument {
36 settings: create_canister_settings(create_settings_arg),
37 },
38 create_canister_cycles(cycles),
39 )
40 .await;
41
42 match record {
43 Err((_, message)) => Err(format!(
44 "{} ({})",
45 JUNO_ERROR_CANISTER_CREATE_FAILED, &message
46 )),
47 Ok(record) => {
48 let canister_id = record.0.canister_id;
49
50 let install = install_code(canister_id, wasm_arg, CanisterInstallMode::Install).await;
51
52 match install {
53 Err(_) => Err(JUNO_ERROR_CANISTER_INSTALL_CODE_FAILED.to_string()),
54 Ok(_) => Ok(canister_id),
55 }
56 }
57 }
58}
59
60pub async fn install_code(
70 canister_id: Principal,
71 WasmArg { wasm, install_arg }: &WasmArg,
72 mode: CanisterInstallMode,
73) -> CallResult<()> {
74 let arg = InstallCodeArgument {
75 mode,
76 canister_id,
77 wasm_module: wasm.clone(),
78 arg: install_arg.clone(),
79 };
80
81 ic_install_code(arg).await
82}
83
84pub async fn update_canister_controllers(
93 canister_id: Principal,
94 controllers: Vec<Principal>,
95) -> CallResult<()> {
96 let arg = UpdateSettingsArgument {
99 canister_id,
100 settings: CanisterSettings {
101 controllers: Some(controllers),
102 compute_allocation: None,
103 memory_allocation: None,
104 freezing_threshold: None,
105 reserved_cycles_limit: None,
106 log_visibility: None,
107 wasm_memory_limit: None,
108 },
109 };
110
111 update_settings(arg).await
112}
113
114pub async fn deposit_cycles(
123 DepositCyclesArgs {
124 destination_id,
125 cycles,
126 }: DepositCyclesArgs,
127) -> Result<(), String> {
128 let balance = canister_balance128();
129
130 if balance < cycles {
131 return Err(format!(
132 "{JUNO_ERROR_CYCLES_DEPOSIT_BALANCE_LOW} (balance {balance}, {cycles} to deposit)"
133 ));
134 }
135
136 let result = ic_deposit_cycles(
137 CanisterIdRecord {
138 canister_id: destination_id,
139 },
140 cycles,
141 )
142 .await;
143
144 match result {
145 Err((_, message)) => Err(format!(
146 "{} ({})",
147 JUNO_ERROR_CYCLES_DEPOSIT_FAILED, &message
148 )),
149 Ok(_) => Ok(()),
150 }
151}
152
153pub async fn stop_segment(canister_id: CanisterId) -> Result<(), String> {
162 let result = stop_canister(CanisterIdRecord { canister_id }).await;
163
164 match result {
165 Err((_, message)) => Err(format!("{} ({})", JUNO_ERROR_SEGMENT_STOP_FAILED, &message)),
166 Ok(_) => Ok(()),
167 }
168}
169
170pub async fn delete_segment(canister_id: CanisterId) -> Result<(), String> {
179 let result = delete_canister(CanisterIdRecord { canister_id }).await;
180
181 match result {
182 Err((_, message)) => Err(format!(
183 "{} ({})",
184 JUNO_ERROR_SEGMENT_DELETE_FAILED, &message
185 )),
186 Ok(_) => Ok(()),
187 }
188}