soroban_cli/commands/ledger/entry/fetch/
account_data.rs

1use std::array::TryFromSliceError;
2use std::fmt::Debug;
3
4use super::args::Args;
5use crate::{
6    commands::config::{self, locator},
7    xdr::{self, LedgerKey, LedgerKeyData, MuxedAccount, String64},
8};
9use clap::{command, Parser};
10
11#[derive(Parser, Debug, Clone)]
12#[group(skip)]
13pub struct Cmd {
14    #[command(flatten)]
15    pub args: Args,
16
17    /// Account alias or address to lookup
18    #[arg(long)]
19    pub account: String,
20
21    /// Fetch key-value data entries attached to an account (see manageDataOp)
22    #[arg(long, required = true)]
23    pub data_name: Vec<String>,
24
25    /// If identity is a seed phrase use this hd path, default is 0
26    #[arg(long)]
27    pub hd_path: Option<usize>,
28}
29
30#[derive(thiserror::Error, Debug)]
31pub enum Error {
32    #[error(transparent)]
33    Config(#[from] config::key::Error),
34    #[error("provided asset is invalid: {0}")]
35    InvalidAsset(String),
36    #[error("provided data name is invalid: {0}")]
37    InvalidDataName(String),
38    #[error(transparent)]
39    Locator(#[from] locator::Error),
40    #[error(transparent)]
41    TryFromSliceError(#[from] TryFromSliceError),
42    #[error(transparent)]
43    Run(#[from] super::args::Error),
44}
45
46impl Cmd {
47    pub async fn run(&self) -> Result<(), Error> {
48        let mut ledger_keys = vec![];
49        self.insert_data_keys(&mut ledger_keys)?;
50        Ok(self.args.run(ledger_keys).await?)
51    }
52
53    fn insert_data_keys(&self, ledger_keys: &mut Vec<LedgerKey>) -> Result<(), Error> {
54        let acc = self.muxed_account(&self.account)?;
55        for data_name in &self.data_name {
56            let data_name: xdr::StringM<64> = data_name
57                .parse()
58                .map_err(|_| Error::InvalidDataName(data_name.clone()))?;
59            let data_name = String64(data_name);
60            let key = LedgerKey::Data(LedgerKeyData {
61                account_id: acc.clone().account_id(),
62                data_name,
63            });
64            ledger_keys.push(key);
65        }
66
67        Ok(())
68    }
69
70    fn muxed_account(&self, account: &str) -> Result<MuxedAccount, Error> {
71        Ok(self
72            .args
73            .locator
74            .read_key(account)?
75            .muxed_account(self.hd_path)?)
76    }
77}