use sdkt_rpc::wasm::get_wasm_bytecode;
use sdkt_rpc::{inspect_contract, SorobanRpcClient};
use sdkt_wasm::spec::parse_contract_spec;
use sdkt_wasm::ContractSpec;
pub fn load_local_abi(wasm_path: &str) -> Result<ContractSpec, String> {
let wasm_bytes = std::fs::read(wasm_path).map_err(|e| format!("Failed to read WASM: {}", e))?;
parse_contract_spec(&wasm_bytes).map_err(|e| format!("Failed to parse ABI: {}", e))
}
pub async fn resolve_abi_spec(
abi: Option<&String>,
abi_contract: Option<&String>,
client: &SorobanRpcClient,
) -> Result<Option<ContractSpec>, String> {
match (abi, abi_contract) {
(Some(wasm_path), None) => load_local_abi(wasm_path).map(Some),
(None, Some(id)) => {
let inspection = inspect_contract(client, id).await.map_err(|e| match e {
sdkt_rpc::RpcError::ContractNotFound => format!("contract {} not found", id),
other => format!("{}", other),
})?;
let deployed_bytes = get_wasm_bytecode(client, &inspection.wasm_hash)
.await
.map_err(|e| format!("could not fetch on-chain WASM for {}: {}", id, e))?;
parse_contract_spec(&deployed_bytes)
.map(Some)
.map_err(|e| format!("failed to parse deployed ABI: {}", e))
}
(None, None) => Ok(None),
(Some(_), Some(_)) => Err("specify only one of --abi or --abi-contract".into()),
}
}
pub fn check_abi_mutual_exclusion(
abi: Option<&String>,
abi_contract: Option<&String>,
) -> Result<(), String> {
if abi.is_some() && abi_contract.is_some() {
Err("specify only one of --abi or --abi-contract".into())
} else {
Ok(())
}
}