pcli/command/query/
community_pool.rs1use crate::App;
2use anyhow::{Context, Result};
3use futures::TryStreamExt;
4use penumbra_sdk_asset::Value;
5use penumbra_sdk_proto::{
6 core::component::community_pool::v1::CommunityPoolAssetBalancesRequest,
7 penumbra::core::component::community_pool::v1::query_service_client::QueryServiceClient as CommunityPoolQueryServiceClient,
8};
9use penumbra_sdk_view::ViewClient;
10use std::io::{stdout, Write};
11
12#[derive(Debug, clap::Subcommand)]
13pub enum CommunityPoolCmd {
14 Balance {
16 asset: Option<String>,
18 },
19}
20
21impl CommunityPoolCmd {
22 pub async fn exec(&self, app: &mut App) -> Result<()> {
23 match self {
24 CommunityPoolCmd::Balance { asset } => self.print_balance(app, asset).await,
25 }
26 }
27
28 pub async fn print_balance(&self, app: &mut App, asset: &Option<String>) -> Result<()> {
29 let asset_id = asset.as_ref().map(|asset| {
30 if let Ok(asset_id) = asset.parse() {
32 asset_id
33 } else {
34 penumbra_sdk_asset::asset::REGISTRY
35 .parse_unit(asset.as_str())
36 .id()
37 }
38 });
39
40 let mut client = CommunityPoolQueryServiceClient::new(app.pd_channel().await?);
41 let balances = client
42 .community_pool_asset_balances(CommunityPoolAssetBalancesRequest {
43 asset_ids: asset_id.map_or_else(std::vec::Vec::new, |id| vec![id.into()]),
44 })
45 .await?
46 .into_inner()
47 .try_collect::<Vec<_>>()
48 .await
49 .context("cannot process Community Pool balance data")?;
50
51 let asset_cache = app.view().assets().await?;
52 let mut writer = stdout();
53 for balance_response in balances {
54 let balance: Value = balance_response
55 .balance
56 .expect("balance should always be set")
57 .try_into()
58 .context("cannot parse balance")?;
59 let value_str = balance.format(&asset_cache);
60
61 writeln!(writer, "{value_str}")?;
62 }
63
64 Ok(())
65 }
66}