pcli/command/view/
lps.rs

1use anyhow::{anyhow, Result};
2use futures::stream::TryStreamExt;
3use penumbra_sdk_dex::lp::position::{Position, State};
4use penumbra_sdk_proto::core::component::dex::v1::{
5    query_service_client::QueryServiceClient as DexQueryServiceClient,
6    LiquidityPositionsByIdRequest,
7};
8use penumbra_sdk_view::ViewClient;
9
10use crate::{command::utils, App};
11
12#[derive(Debug, clap::Args)]
13pub struct LiquidityPositionsCmd {}
14
15impl LiquidityPositionsCmd {
16    pub fn offline(&self) -> bool {
17        false
18    }
19
20    pub async fn exec(&self, app: &mut App) -> Result<()> {
21        let my_position_ids = app
22            .view()
23            .owned_position_ids(Some(State::Opened), None)
24            .await?;
25        let mut dex_client = DexQueryServiceClient::new(app.pd_channel().await?);
26
27        let positions_stream = dex_client
28            .liquidity_positions_by_id(LiquidityPositionsByIdRequest {
29                position_id: my_position_ids.into_iter().map(Into::into).collect(),
30            })
31            .await?
32            .into_inner()
33            .map_err(|e| anyhow!("error fetching liquidity positions: {}", e))
34            .and_then(|msg| async move {
35                msg.data
36                    .ok_or_else(|| anyhow!("missing liquidity position in response"))
37                    .map(Position::try_from)?
38            });
39
40        let asset_cache = app.view().assets().await?;
41
42        let positions = positions_stream.try_collect::<Vec<_>>().await?;
43
44        println!("{}", utils::render_positions(&asset_cache, &positions));
45
46        Ok(())
47    }
48}