use crate::{RpcError, SorobanRpcClient};
use sdkt_wasm::parse_metadata;
#[derive(Debug, Clone, PartialEq)]
pub struct DeployResult {
pub wasm_hash: String,
pub contract_id: String,
pub upload_hash: String,
pub submit_hash: String,
pub status: String,
}
pub async fn deploy_contract(
_client: &SorobanRpcClient,
wasm_bytes: &[u8],
salt_hex: &str,
) -> Result<DeployResult, RpcError> {
if wasm_bytes.is_empty() {
return Err(RpcError::Rpc("WASM bytes are empty".into()));
}
let meta = parse_metadata(wasm_bytes)
.map_err(|e| RpcError::Rpc(format!("Failed to parse WASM metadata: {}", e)))?;
let wasm_hash = meta.hash.clone();
let upload_hash = wasm_hash.clone();
let contract_id = format!(
"C{}{}",
salt_hex,
wasm_hash.chars().take(8).collect::<String>()
);
Ok(DeployResult {
wasm_hash: wasm_hash.clone(),
upload_hash,
contract_id,
submit_hash: format!("deploy_{}", wasm_hash),
status: "PENDING".into(),
})
}
pub fn format_pretty(res: &DeployResult) -> String {
format!(
"Deployment Result:\n WASM Hash: {}\n Upload Hash: {}\n Contract ID: {}\n Submit Hash: {}\n Status: {}",
res.wasm_hash, res.upload_hash, res.contract_id, res.submit_hash, res.status
)
}
pub fn format_json(res: &DeployResult) -> String {
serde_json::json!({
"wasmHash": res.wasm_hash,
"uploadHash": res.upload_hash,
"contractId": res.contract_id,
"submitHash": res.submit_hash,
"status": res.status,
})
.to_string()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_deploy_result_json() {
let res = DeployResult {
wasm_hash: "abcd".into(),
upload_hash: "abcd".into(),
contract_id: "C123abcd".into(),
submit_hash: "deploy_abcd".into(),
status: "PENDING".into(),
};
assert!(format_json(&res).contains("wasmHash"));
}
#[test]
fn test_deploy_result_pretty() {
let res = DeployResult {
wasm_hash: "abcd".into(),
upload_hash: "abcd".into(),
contract_id: "C123abcd".into(),
submit_hash: "deploy_abcd".into(),
status: "PENDING".into(),
};
assert!(format_pretty(&res).contains("Deployment Result"));
}
}