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::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 controllers: Vec<Principal>,
31 wasm_arg: &WasmArg,
32 cycles: u128,
33) -> Result<Principal, String> {
34 let record = create_canister(
35 CreateCanisterArgument {
36 settings: create_canister_settings(controllers),
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 "{} (balance {}, {} to deposit)",
133 JUNO_ERROR_CYCLES_DEPOSIT_BALANCE_LOW, balance, cycles
134 ));
135 }
136
137 let result = ic_deposit_cycles(
138 CanisterIdRecord {
139 canister_id: destination_id,
140 },
141 cycles,
142 )
143 .await;
144
145 match result {
146 Err((_, message)) => Err(format!(
147 "{} ({})",
148 JUNO_ERROR_CYCLES_DEPOSIT_FAILED, &message
149 )),
150 Ok(_) => Ok(()),
151 }
152}
153
154pub async fn stop_segment(canister_id: CanisterId) -> Result<(), String> {
163 let result = stop_canister(CanisterIdRecord { canister_id }).await;
164
165 match result {
166 Err((_, message)) => Err(format!("{} ({})", JUNO_ERROR_SEGMENT_STOP_FAILED, &message)),
167 Ok(_) => Ok(()),
168 }
169}
170
171pub async fn delete_segment(canister_id: CanisterId) -> Result<(), String> {
180 let result = delete_canister(CanisterIdRecord { canister_id }).await;
181
182 match result {
183 Err((_, message)) => Err(format!(
184 "{} ({})",
185 JUNO_ERROR_SEGMENT_DELETE_FAILED, &message
186 )),
187 Ok(_) => Ok(()),
188 }
189}