canic_host/cycle_balance/
mod.rs1#[cfg(test)]
8mod tests;
9
10use crate::{
11 icp::{IcpCli, IcpCommandError, IcpJsonResponseError, decode_json_result_response},
12 icp_config::IcpConfigError,
13 protocol_binding::ResolvedProtocolBinding,
14 replica_query::{self, ReplicaQueryError},
15};
16use candid::{CandidType, Deserialize};
17use canic_core::dto::role::CycleBalanceStatusResponse;
18use std::path::Path;
19use thiserror::Error as ThisError;
20
21use canic_core::protocol;
22
23const ICP_JSON_OUTPUT: &str = "json";
24
25#[derive(CandidType, Deserialize)]
26enum RoleStatusResponse {
27 CycleBalance(CycleBalanceStatusResponse),
28}
29
30#[derive(Debug, ThisError)]
35pub enum CycleBalanceQueryError {
36 #[error(transparent)]
37 IcpConfig(#[from] IcpConfigError),
38
39 #[error(transparent)]
40 Icp(#[from] IcpCommandError),
41
42 #[error(transparent)]
43 Replica(#[from] ReplicaQueryError),
44
45 #[error(transparent)]
46 Response(#[from] IcpJsonResponseError),
47}
48
49pub fn query_cycle_balance(
51 icp: &IcpCli,
52 canister_id: &str,
53 environment: &str,
54 icp_root: Option<&Path>,
55 binding: &ResolvedProtocolBinding,
56) -> Result<u128, CycleBalanceQueryError> {
57 if replica_query::uses_local_replica_transport(Some(environment), icp_root)? {
58 return replica_query::query_cycle_balance(Some(environment), canister_id, icp_root)
59 .map_err(Into::into);
60 }
61
62 let output = icp.canister_query_arg_output_with_candid(
63 canister_id,
64 protocol::CANIC_STATUS,
65 "(variant { CycleBalance })",
66 Some(ICP_JSON_OUTPUT),
67 Some(&binding.candid_path),
68 )?;
69 let response = decode_json_result_response::<RoleStatusResponse>(&output)?;
70 let RoleStatusResponse::CycleBalance(response) = response;
71 Ok(response.cycles)
72}