pcli/command/view/
lps.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
use anyhow::{anyhow, Result};
use futures::stream::TryStreamExt;
use penumbra_dex::lp::position::{Position, State};
use penumbra_proto::core::component::dex::v1::{
    query_service_client::QueryServiceClient as DexQueryServiceClient,
    LiquidityPositionsByIdRequest,
};
use penumbra_view::ViewClient;

use crate::{command::utils, App};

#[derive(Debug, clap::Args)]
pub struct LiquidityPositionsCmd {}

impl LiquidityPositionsCmd {
    pub fn offline(&self) -> bool {
        false
    }

    pub async fn exec(&self, app: &mut App) -> Result<()> {
        let my_position_ids = app
            .view()
            .owned_position_ids(Some(State::Opened), None)
            .await?;
        let mut dex_client = DexQueryServiceClient::new(app.pd_channel().await?);

        let positions_stream = dex_client
            .liquidity_positions_by_id(LiquidityPositionsByIdRequest {
                position_id: my_position_ids.into_iter().map(Into::into).collect(),
            })
            .await?
            .into_inner()
            .map_err(|e| anyhow!("eror fetching liquidity positions: {}", e))
            .and_then(|msg| async move {
                msg.data
                    .ok_or_else(|| anyhow!("missing liquidity position in response"))
                    .map(Position::try_from)?
            });

        let asset_cache = app.view().assets().await?;

        let positions = positions_stream.try_collect::<Vec<_>>().await?;

        println!("{}", utils::render_positions(&asset_cache, &positions));

        Ok(())
    }
}