Skip to content

Commit 27b6258

Browse files
author
Gleb
committed
Add reading contract entries
1 parent bfd3fc3 commit 27b6258

1 file changed

Lines changed: 63 additions & 5 deletions

File tree

  • cmd/soroban-cli/src/commands/ledger/entry

cmd/soroban-cli/src/commands/ledger/entry/get.rs

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
21
use std::fmt::Debug;
32

43
use clap::{command, Parser};
5-
use stellar_xdr::curr::{LedgerKey, LedgerKeyAccount, MuxedAccount};
4+
use stellar_xdr::curr::{ContractDataDurability, Hash, LedgerKey, LedgerKeyAccount, LedgerKeyContractData, Limits, MuxedAccount, ReadXdr, ScAddress, ScVal};
65
use crate::commands::config::network;
7-
use crate::config;
6+
use crate::{config, xdr};
87
use crate::config::{locator};
98
use crate::{
109
rpc::{self},
1110
};
12-
use crate::commands::ledger::entry::get::Error::EmptyKeys;
11+
use crate::commands::contract::Durability;
12+
use crate::commands::ledger::entry::get::Error::{ContractRequired, EmptyKeys};
1313

1414
#[derive(Parser, Debug, Clone)]
1515
#[group(skip)]
@@ -28,6 +28,21 @@ pub struct Cmd {
2828
#[arg(long)]
2929
pub hd_path: Option<usize>,
3030

31+
32+
#[arg(long = "id", env = "STELLAR_CONTRACT_ID")]
33+
pub contract_id: Option<config::UnresolvedContract>,
34+
35+
/// Storage entry durability
36+
#[arg(long, value_enum, default_value = "persistent")]
37+
pub durability: Durability,
38+
39+
/// Storage key (symbols only)
40+
#[arg(long = "key")]
41+
pub key: Option<Vec<String>>,
42+
/// Storage key (base64-encoded XDR)
43+
#[arg(long = "key-xdr")]
44+
pub key_xdr: Option<Vec<String>>,
45+
3146
/// Format of the output
3247
#[arg(long, default_value = "original")]
3348
pub output: OutputFormat,
@@ -45,8 +60,14 @@ pub enum Error {
4560
Network(#[from] network::Error),
4661
#[error(transparent)]
4762
Serde(#[from] serde_json::Error),
63+
#[error(transparent)]
64+
StellarXdr(#[from] stellar_xdr::curr::Error),
65+
#[error(transparent)]
66+
Spec(#[from] soroban_spec_tools::Error),
4867
#[error("at least one key must be provided")]
4968
EmptyKeys,
69+
#[error("contract id is required but was not provided")]
70+
ContractRequired,
5071
}
5172

5273
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, clap::ValueEnum, Default)]
@@ -63,15 +84,52 @@ pub enum OutputFormat {
6384

6485
impl Cmd {
6586
pub async fn run(&self) -> Result<(), Error> {
66-
let client = self.network.get(&self.locator)?.rpc_client()?;
87+
let network = self.network.get(&self.locator)?;
88+
let client = network.rpc_client()?;
6789
let mut ledger_keys = vec![];
6890

91+
if let Some(contract_id) = &self.contract_id {
92+
let contract_id = contract_id.resolve_contract_id(&self.locator, &network.network_passphrase)?;
93+
94+
let contract_address_arg = ScAddress::Contract(Hash(contract_id.0));
95+
96+
if let Some(keys) = &self.key {
97+
for key in keys {
98+
let key = LedgerKey::ContractData(LedgerKeyContractData {
99+
contract: contract_address_arg.clone(),
100+
key: soroban_spec_tools::from_string_primitive(
101+
key,
102+
&xdr::ScSpecTypeDef::Symbol,
103+
)?,
104+
durability: ContractDataDurability::Persistent,
105+
});
106+
107+
ledger_keys.push(key);
108+
}
109+
}
110+
111+
if let Some(keys) = &self.key_xdr {
112+
for key in keys {
113+
let key = LedgerKey::ContractData(LedgerKeyContractData {
114+
contract: contract_address_arg.clone(),
115+
key: ScVal::from_xdr_base64(key, Limits::none())?,
116+
durability: ContractDataDurability::Persistent,
117+
});
118+
119+
ledger_keys.push(key);
120+
}
121+
}
122+
} else if self.key.is_some() || self.key_xdr.is_some() {
123+
return Err(ContractRequired)
124+
}
125+
69126
if let Some(acc) = &self.account {
70127
let acc = self.muxed_account(acc)?;
71128
let key = LedgerKey::Account(LedgerKeyAccount { account_id: acc.account_id() });
72129
ledger_keys.push(key);
73130
}
74131

132+
75133
if ledger_keys.is_empty() {
76134
return Err(EmptyKeys);
77135
}

0 commit comments

Comments
 (0)