use crate::mgmt::settings::{create_canister_cycles, create_canister_settings};
use crate::mgmt::types::ic::WasmArg;
use crate::types::interface::DepositCyclesArgs;
use candid::Principal;
use ic_cdk::api::call::CallResult;
use ic_cdk::api::canister_balance128;
use ic_cdk::api::management_canister::main::{
create_canister, delete_canister, deposit_cycles as ic_deposit_cycles,
install_code as ic_install_code, stop_canister, update_settings, CanisterId, CanisterIdRecord,
CanisterInstallMode, CanisterSettings, CreateCanisterArgument, InstallCodeArgument,
UpdateSettingsArgument,
};
pub async fn create_canister_install_code(
controllers: Vec<Principal>,
wasm_arg: &WasmArg,
cycles: u128,
) -> Result<Principal, String> {
let record = create_canister(
CreateCanisterArgument {
settings: create_canister_settings(controllers),
},
create_canister_cycles(cycles),
)
.await;
match record {
Err((_, message)) => Err(["Failed to create canister.", &message].join(" - ")),
Ok(record) => {
let canister_id = record.0.canister_id;
let install = install_code(canister_id, wasm_arg, CanisterInstallMode::Install).await;
match install {
Err(_) => Err("Failed to install code in canister.".to_string()),
Ok(_) => Ok(canister_id),
}
}
}
}
pub async fn install_code(
canister_id: Principal,
WasmArg { wasm, install_arg }: &WasmArg,
mode: CanisterInstallMode,
) -> CallResult<()> {
let arg = InstallCodeArgument {
mode,
canister_id,
wasm_module: wasm.clone(),
arg: install_arg.clone(),
};
ic_install_code(arg).await
}
pub async fn update_canister_controllers(
canister_id: Principal,
controllers: Vec<Principal>,
) -> CallResult<()> {
let arg = UpdateSettingsArgument {
canister_id,
settings: CanisterSettings {
controllers: Some(controllers),
compute_allocation: None,
memory_allocation: None,
freezing_threshold: None,
reserved_cycles_limit: None,
log_visibility: None,
wasm_memory_limit: None,
},
};
update_settings(arg).await
}
pub async fn deposit_cycles(
DepositCyclesArgs {
destination_id,
cycles,
}: DepositCyclesArgs,
) -> Result<(), String> {
let balance = canister_balance128();
if balance < cycles {
return Err(format!(
"Balance ({}) is lower than the amount of cycles {} to deposit.",
balance, cycles
));
}
let result = ic_deposit_cycles(
CanisterIdRecord {
canister_id: destination_id,
},
cycles,
)
.await;
match result {
Err((_, message)) => Err(["Deposit cycles failed.", &message].join(" - ")),
Ok(_) => Ok(()),
}
}
pub async fn stop_segment(canister_id: CanisterId) -> Result<(), String> {
let result = stop_canister(CanisterIdRecord { canister_id }).await;
match result {
Err((_, message)) => Err(["Cannot stop segment.", &message].join(" - ")),
Ok(_) => Ok(()),
}
}
pub async fn delete_segment(canister_id: CanisterId) -> Result<(), String> {
let result = delete_canister(CanisterIdRecord { canister_id }).await;
match result {
Err((_, message)) => Err(["Cannot delete segment.", &message].join(" - ")),
Ok(_) => Ok(()),
}
}