diff --git a/CHANGELOG.md b/CHANGELOG.md index d3b0c7ea3..1894ec120 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Unreleased +* feat: `icp token/cycles balance` now accept `--of-principal` * fix: The local wasm cache has moved from `.icp/cache/canisters/` to `.icp/cache/wasms/`. Existing cached files will be re-downloaded automatically on the next run. * feat: Canister manifests now support a `plugin` sync step type. Plugins are WebAssembly components that run in a sandboxed environment and can drive arbitrary post-deployment logic against the canister being synced. See `crates/icp-sync-plugin/DESIGN.md` for details. * feat: `icp sync` now accepts `--proxy` to route sync plugin calls to the target canister through a proxy canister. diff --git a/crates/icp-cli/src/commands/cycles/balance.rs b/crates/icp-cli/src/commands/cycles/balance.rs index ab7a1abde..192af682a 100644 --- a/crates/icp-cli/src/commands/cycles/balance.rs +++ b/crates/icp-cli/src/commands/cycles/balance.rs @@ -1,6 +1,7 @@ use std::io::stdout; use bigdecimal::BigDecimal; +use candid::Principal; use clap::Args; use icp::context::Context; use icp_canister_interfaces::cycles_ledger::CYCLES_LEDGER_PRINCIPAL; @@ -21,6 +22,10 @@ pub(crate) struct BalanceArgs { #[arg(long, value_parser = parse_subaccount)] pub(crate) subaccount: Option<[u8; 32]>, + /// Check the balance of this principal instead of the current identity + #[arg(long)] + pub(crate) of_principal: Option, + /// Output command results as JSON #[arg(long, conflicts_with = "quiet")] pub(crate) json: bool, @@ -41,9 +46,12 @@ pub(crate) async fn exec(ctx: &Context, args: &BalanceArgs) -> Result<(), anyhow &selections.environment, ) .await?; + let owner = args + .of_principal + .unwrap_or_else(|| agent.get_principal().unwrap()); // Get the balance from the ledger - let cycles = get_raw_balance(&agent, CYCLES_LEDGER_PRINCIPAL, args.subaccount).await?; + let cycles = get_raw_balance(&agent, CYCLES_LEDGER_PRINCIPAL, owner, args.subaccount).await?; let cycles_amount = TokenAmount { amount: BigDecimal::from_biguint(cycles.0, 0), symbol: "cycles".to_string(), diff --git a/crates/icp-cli/src/commands/token/balance.rs b/crates/icp-cli/src/commands/token/balance.rs index 5651a3a78..0875239e9 100644 --- a/crates/icp-cli/src/commands/token/balance.rs +++ b/crates/icp-cli/src/commands/token/balance.rs @@ -1,5 +1,6 @@ use std::io::stdout; +use candid::Principal; use clap::Args; use icp::context::Context; use serde::Serialize; @@ -19,6 +20,10 @@ pub(crate) struct BalanceArgs { #[arg(long, value_parser = parse_subaccount)] pub(crate) subaccount: Option<[u8; 32]>, + /// Check the balance of this principal instead of the current identity + #[arg(long)] + pub(crate) of_principal: Option, + /// Output command results as JSON #[arg(long, conflicts_with = "quiet")] pub(crate) json: bool, @@ -48,9 +53,12 @@ pub(crate) async fn exec( &selections.environment, ) .await?; + let owner = args + .of_principal + .unwrap_or_else(|| agent.get_principal().unwrap()); // Get the balance from the ledger - let balance = get_balance(&agent, args.subaccount, token).await?; + let balance = get_balance(&agent, token, owner, args.subaccount).await?; if args.json { serde_json::to_writer( diff --git a/crates/icp-cli/src/operations/token/balance.rs b/crates/icp-cli/src/operations/token/balance.rs index efc21566b..271a7672f 100644 --- a/crates/icp-cli/src/operations/token/balance.rs +++ b/crates/icp-cli/src/operations/token/balance.rs @@ -56,8 +56,9 @@ pub enum GetBalanceError { /// pub async fn get_balance( agent: &Agent, - subaccount: Option<[u8; 32]>, token: &str, + owner: Principal, + subaccount: Option<[u8; 32]>, ) -> Result { // Obtain token info let canister_id = match TOKEN_LEDGER_CIDS.get(token) { @@ -78,7 +79,7 @@ pub async fn get_balance( let (balance, decimals, symbol) = tokio::join!( // // Obtain token balance - get_raw_balance(agent, cid, subaccount), + get_raw_balance(agent, cid, owner, subaccount), // // Obtain the number of decimals the token uses async { @@ -119,11 +120,9 @@ pub async fn get_balance( pub async fn get_raw_balance( agent: &Agent, ledger: Principal, + owner: Principal, subaccount: Option<[u8; 32]>, ) -> Result { - let owner = agent - .get_principal() - .map_err(|err| GetBalanceError::GetPrincipal { err })?; // Perform query let resp = agent .query(&ledger, "icrc1_balance_of") diff --git a/crates/icp-cli/tests/cycles_tests.rs b/crates/icp-cli/tests/cycles_tests.rs index fb4e21a68..a29ee9b58 100644 --- a/crates/icp-cli/tests/cycles_tests.rs +++ b/crates/icp-cli/tests/cycles_tests.rs @@ -240,10 +240,16 @@ async fn cycles_transfer() { .success(); // Check bob's balance - icp_client.use_identity("bob"); ctx.icp() .current_dir(&project_dir) - .args(["cycles", "balance", "--environment", "random-environment"]) + .args([ + "cycles", + "balance", + "--of-principal", + &bob_principal.to_string(), + "--environment", + "random-environment", + ]) .assert() .stdout(contains("Balance: 2_000_000_000_000 cycles")) .success(); diff --git a/docs/reference/cli.md b/docs/reference/cli.md index 171122281..67dcd9c0a 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -781,6 +781,7 @@ Display the cycles balance * `-e`, `--environment ` — Override the environment to connect to. By default, the local environment is used * `--identity ` — The user identity to run this command as * `--subaccount ` — The subaccount to check the balance for +* `--of-principal ` — Check the balance of this principal instead of the current identity * `--json` — Output command results as JSON * `-q`, `--quiet` — Suppress human-readable output; print only the balance @@ -1583,6 +1584,7 @@ Display the token balance on the ledger (default token: icp) * `-e`, `--environment ` — Override the environment to connect to. By default, the local environment is used * `--identity ` — The user identity to run this command as * `--subaccount ` — The subaccount to check the balance for +* `--of-principal ` — Check the balance of this principal instead of the current identity * `--json` — Output command results as JSON * `-q`, `--quiet` — Suppress human-readable output; print only the balance