use super::args::Args;
use crate::{
commands::contract::Durability,
config::{self, locator},
xdr::{
self, ContractDataDurability, ContractId, Hash, LedgerKey, LedgerKeyContractData, Limits,
ReadXdr, ScAddress, ScVal,
},
};
use clap::Parser;
#[derive(Parser, Debug, Clone)]
#[group(skip)]
pub struct Cmd {
#[arg(long)]
pub contract: config::UnresolvedContract,
#[command(flatten)]
pub args: Args,
#[arg(long, value_enum, default_value = "persistent")]
pub durability: Durability,
#[arg(long = "key", required_unless_present_any = vec!("key_xdr", "instance"))]
pub key: Option<Vec<String>>,
#[arg(long = "key-xdr", required_unless_present_any = vec!("key", "instance"))]
pub key_xdr: Option<Vec<String>>,
#[arg(long = "instance", required_unless_present_any = vec!("key", "key_xdr"))]
pub instance: bool,
}
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error(transparent)]
Run(#[from] super::args::Error),
#[error(transparent)]
Locator(#[from] locator::Error),
#[error(transparent)]
Spec(#[from] soroban_spec_tools::Error),
#[error(transparent)]
StellarXdr(#[from] stellar_xdr::curr::Error),
}
impl Cmd {
pub async fn run(&self) -> Result<(), Error> {
let mut ledger_keys = vec![];
self.insert_keys(&mut ledger_keys)?;
Ok(self.args.run(ledger_keys).await?)
}
fn insert_keys(&self, ledger_keys: &mut Vec<LedgerKey>) -> Result<(), Error> {
let network = self.args.network()?;
let contract_id = self
.contract
.resolve_contract_id(&self.args.locator, &network.network_passphrase)?;
let contract_address_arg = ScAddress::Contract(ContractId(Hash(contract_id.0)));
if self.instance {
let contract_instance_key = LedgerKey::ContractData(LedgerKeyContractData {
contract: contract_address_arg.clone(),
key: ScVal::LedgerKeyContractInstance,
durability: ContractDataDurability::Persistent,
});
ledger_keys.push(contract_instance_key);
}
if let Some(keys) = &self.key {
for key in keys {
let key = LedgerKey::ContractData(LedgerKeyContractData {
contract: contract_address_arg.clone(),
key: soroban_spec_tools::from_string_primitive(
key,
&xdr::ScSpecTypeDef::Symbol,
)?,
durability: ContractDataDurability::Persistent,
});
ledger_keys.push(key);
}
}
if let Some(keys) = &self.key_xdr {
for key in keys {
let key = LedgerKey::ContractData(LedgerKeyContractData {
contract: contract_address_arg.clone(),
key: ScVal::from_xdr_base64(key, Limits::none())?,
durability: ContractDataDurability::Persistent,
});
ledger_keys.push(key);
}
}
Ok(())
}
}