Skip to content

Commit 0f2e01e

Browse files
Glebelizabethengelman
authored andcommitted
Add remaining types
1 parent b2d5be8 commit 0f2e01e

File tree

5 files changed

+195
-26
lines changed

5 files changed

+195
-26
lines changed

cmd/soroban-cli/src/commands/contract/read.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,18 +144,19 @@ impl Cmd {
144144
error,
145145
}
146146
})?,
147-
serde_json::to_string_pretty(&live_until_ledger_seq.unwrap_or_default()).map_err(|error| {
148-
Error::CannotPrintJsonResult {
147+
serde_json::to_string_pretty(&live_until_ledger_seq.unwrap_or_default())
148+
.map_err(|error| Error::CannotPrintJsonResult {
149149
result: val.clone(),
150150
error,
151-
}
152-
})?,
151+
})?,
153152
],
154153
Output::Xdr => [
155154
key.to_xdr_base64(Limits::none())?,
156155
val.to_xdr_base64(Limits::none())?,
157156
last_modified_ledger.to_xdr_base64(Limits::none())?,
158-
live_until_ledger_seq.unwrap_or_default().to_xdr_base64(Limits::none())?,
157+
live_until_ledger_seq
158+
.unwrap_or_default()
159+
.to_xdr_base64(Limits::none())?,
159160
],
160161
};
161162
out.write_record(output)

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

Lines changed: 184 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,79 @@
1+
use std::array::TryFromSliceError;
12
use std::fmt::Debug;
23

3-
use clap::{command, Parser};
4-
use stellar_xdr::curr::{ContractDataDurability, Hash, LedgerKey, LedgerKeyAccount, LedgerKeyContractData, Limits, MuxedAccount, ReadXdr, ScAddress, ScVal};
54
use crate::commands::config::network;
5+
use crate::commands::contract::Durability;
6+
use crate::commands::ledger::entry::get::Error::{
7+
AccountRequired, ContractRequired, EmptyKeys, InvalidAsset, InvalidConfigId, InvalidDataName,
8+
InvalidHash,
9+
};
10+
use crate::config::locator;
11+
use crate::rpc::{self};
612
use crate::{config, xdr};
7-
use crate::config::{locator};
8-
use crate::{
9-
rpc::{self},
13+
use clap::{command, Parser};
14+
use hex::FromHexError;
15+
use soroban_spec_tools::utils::padded_hex_from_str;
16+
use stellar_strkey::ed25519::PublicKey as Ed25519PublicKey;
17+
use stellar_xdr::curr::ClaimableBalanceId::ClaimableBalanceIdTypeV0;
18+
use stellar_xdr::curr::{
19+
AccountId, AlphaNum12, AlphaNum4, AssetCode12, AssetCode4, ConfigSettingId,
20+
ContractDataDurability, Hash, LedgerKey, LedgerKeyAccount, LedgerKeyClaimableBalance,
21+
LedgerKeyConfigSetting, LedgerKeyContractCode, LedgerKeyContractData, LedgerKeyData,
22+
LedgerKeyLiquidityPool, LedgerKeyOffer, LedgerKeyTrustLine, LedgerKeyTtl, Limits, MuxedAccount,
23+
PoolId, PublicKey, ReadXdr, ScAddress, ScVal, String64, TrustLineAsset, Uint256,
1024
};
11-
use crate::commands::contract::Durability;
12-
use crate::commands::ledger::entry::get::Error::{ContractRequired, EmptyKeys};
1325

1426
#[derive(Parser, Debug, Clone)]
1527
#[group(skip)]
1628
pub struct Cmd {
1729
#[command(flatten)]
1830
pub network: network::Args,
19-
2031
#[command(flatten)]
2132
pub locator: locator::Args,
2233

2334
/// Name of identity to lookup, default is test identity
2435
#[arg(long)]
2536
pub account: Option<String>,
26-
2737
/// If identity is a seed phrase use this hd path, default is 0
2838
#[arg(long)]
2939
pub hd_path: Option<usize>,
3040

41+
/// Assets to get trustline info for
42+
#[arg(long)]
43+
pub asset: Option<Vec<String>>,
44+
/// ID of an offer made on the Stellar DEX
45+
#[arg(long)]
46+
pub offer: Option<Vec<i64>>,
47+
/// Fetch key-value data entries attached to an account (see manageDataOp)
48+
#[arg(long)]
49+
pub data_name: Option<Vec<String>>,
50+
51+
/// Claimable Balance id
52+
#[arg(long)]
53+
pub claimable_id: Option<Vec<String>>,
3154

55+
/// Liquidity pool id
56+
#[arg(long)]
57+
pub pool_id: Option<Vec<String>>,
58+
59+
/// Defines the currently active network configuration
60+
#[arg(long)]
61+
pub config_setting_id: Option<Vec<i32>>,
62+
63+
/// Get WASM bytecode by hash
64+
#[arg(long)]
65+
pub wasm_hash: Option<Vec<String>>,
66+
67+
/// Get the time-to-live of an associated contract data or code entry
68+
#[arg(long)]
69+
pub ttl: Option<Vec<String>>,
70+
71+
/// Contract id to fetch an info for
3272
#[arg(long = "id", env = "STELLAR_CONTRACT_ID")]
3373
pub contract_id: Option<config::UnresolvedContract>,
34-
3574
/// Storage entry durability
3675
#[arg(long, value_enum, default_value = "persistent")]
3776
pub durability: Durability,
38-
3977
/// Storage key (symbols only)
4078
#[arg(long = "key")]
4179
pub key: Option<Vec<String>>,
@@ -64,10 +102,24 @@ pub enum Error {
64102
StellarXdr(#[from] stellar_xdr::curr::Error),
65103
#[error(transparent)]
66104
Spec(#[from] soroban_spec_tools::Error),
105+
#[error(transparent)]
106+
TryFromSliceError(#[from] TryFromSliceError),
107+
#[error(transparent)]
108+
FromHexError(#[from] FromHexError),
67109
#[error("at least one key must be provided")]
68110
EmptyKeys,
69111
#[error("contract id is required but was not provided")]
70112
ContractRequired,
113+
#[error("account is required but was not provided")]
114+
AccountRequired,
115+
#[error("provided asset is invalid: {0}")]
116+
InvalidAsset(String),
117+
#[error("provided data name is invalid: {0}")]
118+
InvalidDataName(String),
119+
#[error("provided hash value is invalid: {0}")]
120+
InvalidHash(String),
121+
#[error("provided config id is invalid: {0}")]
122+
InvalidConfigId(i32),
71123
}
72124

73125
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, clap::ValueEnum, Default)]
@@ -81,15 +133,15 @@ pub enum OutputFormat {
81133
JsonFormatted,
82134
}
83135

84-
85136
impl Cmd {
86137
pub async fn run(&self) -> Result<(), Error> {
87138
let network = self.network.get(&self.locator)?;
88139
let client = network.rpc_client()?;
89140
let mut ledger_keys = vec![];
90141

91142
if let Some(contract_id) = &self.contract_id {
92-
let contract_id = contract_id.resolve_contract_id(&self.locator, &network.network_passphrase)?;
143+
let contract_id =
144+
contract_id.resolve_contract_id(&self.locator, &network.network_passphrase)?;
93145

94146
let contract_address_arg = ScAddress::Contract(Hash(contract_id.0));
95147

@@ -120,15 +172,131 @@ impl Cmd {
120172
}
121173
}
122174
} else if self.key.is_some() || self.key_xdr.is_some() {
123-
return Err(ContractRequired)
175+
return Err(ContractRequired);
124176
}
125177

126178
if let Some(acc) = &self.account {
127179
let acc = self.muxed_account(acc)?;
128-
let key = LedgerKey::Account(LedgerKeyAccount { account_id: acc.account_id() });
129-
ledger_keys.push(key);
180+
181+
if let Some(asset) = &self.asset {
182+
for asset in asset {
183+
let asset = if asset.to_ascii_uppercase() == "XLM" {
184+
TrustLineAsset::Native
185+
} else if asset.contains(":") {
186+
let mut parts = asset.split(":");
187+
let code = parts.next().ok_or(InvalidAsset(asset.clone()))?;
188+
let issuer = parts.next().ok_or(InvalidAsset(asset.clone()))?;
189+
if !parts.next().is_none() {
190+
Err(InvalidAsset(asset.clone()))?
191+
}
192+
let source_bytes = Ed25519PublicKey::from_string(issuer).unwrap().0;
193+
let issuer =
194+
AccountId(PublicKey::PublicKeyTypeEd25519(Uint256(source_bytes)));
195+
196+
match code.len() {
197+
4 => TrustLineAsset::CreditAlphanum4(AlphaNum4 {
198+
asset_code: AssetCode4(code.as_bytes().try_into()?),
199+
issuer,
200+
}),
201+
12 => TrustLineAsset::CreditAlphanum12(AlphaNum12 {
202+
asset_code: AssetCode12(code.as_bytes().try_into()?),
203+
issuer,
204+
}),
205+
_ => Err(InvalidAsset(asset.clone()))?,
206+
}
207+
} else {
208+
Err(InvalidAsset(asset.clone()))?
209+
};
210+
let key = LedgerKey::Trustline(LedgerKeyTrustLine {
211+
account_id: acc.clone().account_id(),
212+
asset,
213+
});
214+
ledger_keys.push(key);
215+
}
216+
}
217+
218+
if let Some(offer) = &self.offer {
219+
for offer in offer {
220+
let key = LedgerKey::Offer(LedgerKeyOffer {
221+
seller_id: acc.clone().account_id(),
222+
offer_id: *offer,
223+
});
224+
ledger_keys.push(key);
225+
}
226+
}
227+
228+
if let Some(data_name) = &self.data_name {
229+
for data_name in data_name {
230+
let data_name: xdr::StringM<64> = data_name
231+
.parse()
232+
.map_err(|_| InvalidDataName(data_name.clone()))?;
233+
let data_name = String64(data_name);
234+
let key = LedgerKey::Data(LedgerKeyData {
235+
account_id: acc.clone().account_id(),
236+
data_name,
237+
});
238+
ledger_keys.push(key);
239+
}
240+
}
241+
242+
if self.asset.is_none() && self.offer.is_none() && self.data_name.is_none() {
243+
let key = LedgerKey::Account(LedgerKeyAccount {
244+
account_id: acc.account_id(),
245+
});
246+
ledger_keys.push(key);
247+
}
248+
} else if self.asset.is_some() || self.offer.is_some() || self.data_name.is_some() {
249+
return Err(AccountRequired);
130250
}
131251

252+
if let Some(claimable_id) = &self.claimable_id {
253+
for x in claimable_id {
254+
let hash = Hash(padded_hex_from_str(x, 32)?.try_into().unwrap());
255+
let key = LedgerKey::ClaimableBalance(LedgerKeyClaimableBalance {
256+
balance_id: ClaimableBalanceIdTypeV0(hash),
257+
});
258+
ledger_keys.push(key);
259+
}
260+
}
261+
262+
if let Some(pool_id) = &self.pool_id {
263+
for x in pool_id {
264+
let hash = Hash(padded_hex_from_str(x, 32)?.try_into().unwrap());
265+
let key = LedgerKey::LiquidityPool(LedgerKeyLiquidityPool {
266+
liquidity_pool_id: PoolId(hash),
267+
});
268+
ledger_keys.push(key);
269+
}
270+
}
271+
272+
if let Some(wasm_hash) = &self.wasm_hash {
273+
for wasm_hash in wasm_hash {
274+
let hash = Hash(
275+
soroban_spec_tools::utils::contract_id_from_str(wasm_hash)
276+
.map_err(|_| InvalidHash(wasm_hash.clone()))?,
277+
);
278+
let key = LedgerKey::ContractCode(LedgerKeyContractCode { hash });
279+
ledger_keys.push(key);
280+
}
281+
}
282+
283+
if let Some(config_setting_id) = &self.config_setting_id {
284+
for x in config_setting_id {
285+
let key = LedgerKey::ConfigSetting(LedgerKeyConfigSetting {
286+
config_setting_id: ConfigSettingId::try_from(*x)
287+
.map_err(|_| InvalidConfigId(*x))?,
288+
});
289+
ledger_keys.push(key);
290+
}
291+
}
292+
293+
if let Some(ttl) = &self.ttl {
294+
for x in ttl {
295+
let hash = Hash(padded_hex_from_str(x, 32)?.try_into().unwrap());
296+
let key = LedgerKey::Ttl(LedgerKeyTtl { key_hash: hash });
297+
ledger_keys.push(key);
298+
}
299+
}
132300

133301
if ledger_keys.is_empty() {
134302
return Err(EmptyKeys);
@@ -149,7 +317,6 @@ impl Cmd {
149317
}
150318
}
151319

152-
153320
return Ok(());
154321
}
155322

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ use clap::Parser;
33

44
#[derive(Debug, Parser)]
55
pub enum Cmd {
6-
/// Get ledger entries.
6+
/// Get ledger entries. This command supports every type of ledger entries supported by the
7+
/// RPC. Read more about RPC command here: https://developers.stellar.org/docs/data/apis/rpc/api-reference/methods/getLedgerEntries#types-of-ledgerkeys
78
Get(get::Cmd),
89
}
910

@@ -20,4 +21,4 @@ impl Cmd {
2021
};
2122
Ok(())
2223
}
23-
}
24+
}

cmd/soroban-cli/src/commands/ledger/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ impl Cmd {
2222
};
2323
Ok(())
2424
}
25-
}
25+
}

cmd/soroban-cli/src/commands/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ pub mod snapshot;
1919
pub mod tx;
2020
pub mod version;
2121

22-
pub mod txn_result;
2322
pub mod ledger;
23+
pub mod txn_result;
2424

2525
pub const HEADING_RPC: &str = "Options (RPC)";
2626
pub const HEADING_GLOBAL: &str = "Options (Global)";

0 commit comments

Comments
 (0)