Skip to main content

canic_host/cycle_balance/
mod.rs

1//! Module: cycle_balance
2//!
3//! Responsibility: query the maintained Canic cycle-balance endpoint.
4//! Does not own: cycle accounting, local replica transport, or report aggregation.
5//! Boundary: decodes the canonical typed endpoint result into a host balance.
6
7#[cfg(test)]
8mod tests;
9
10use crate::{
11    icp::{IcpCli, IcpCommandError, IcpJsonResponseError, decode_json_result_response},
12    icp_config::IcpConfigError,
13    replica_query::{self, ReplicaQueryError},
14};
15use std::path::Path;
16use thiserror::Error as ThisError;
17
18use canic_core::protocol;
19
20const ICP_JSON_OUTPUT: &str = "json";
21
22///
23/// CycleBalanceQueryError
24///
25
26#[derive(Debug, ThisError)]
27pub enum CycleBalanceQueryError {
28    #[error(transparent)]
29    IcpConfig(#[from] IcpConfigError),
30
31    #[error(transparent)]
32    Icp(#[from] IcpCommandError),
33
34    #[error(transparent)]
35    Replica(#[from] ReplicaQueryError),
36
37    #[error(transparent)]
38    Response(#[from] IcpJsonResponseError),
39}
40
41/// Query `canic_cycle_balance` through the transport selected by the environment.
42pub fn query_cycle_balance(
43    icp: &IcpCli,
44    canister_id: &str,
45    environment: &str,
46    icp_root: Option<&Path>,
47    candid_path: Option<&Path>,
48) -> Result<u128, CycleBalanceQueryError> {
49    if replica_query::uses_local_replica_transport(Some(environment), icp_root)? {
50        return replica_query::query_cycle_balance(Some(environment), canister_id, icp_root)
51            .map_err(Into::into);
52    }
53
54    let output = icp.canister_query_output_with_candid(
55        canister_id,
56        protocol::CANIC_CYCLE_BALANCE,
57        Some(ICP_JSON_OUTPUT),
58        candid_path,
59    )?;
60    decode_json_result_response(&output).map_err(Into::into)
61}