use serde_json::{Value, json};
use vta_sdk::client::VtaClient;
use crate::render::{DIM, RESET, is_json_output, print_json};
fn print_result(label: &str, value: &Value) -> Result<(), Box<dyn std::error::Error>> {
if is_json_output() {
print_json(value)?;
} else {
println!("{label}");
println!("{}", serde_json::to_string_pretty(value)?);
}
Ok(())
}
pub async fn cmd_vault_list(
client: &VtaClient,
filters: Option<Value>,
status: Option<String>,
) -> Result<(), Box<dyn std::error::Error>> {
let mut filters = filters.unwrap_or_else(|| json!({}));
if let Some(s) = status
&& let Some(obj) = filters.as_object_mut()
{
obj.insert("status".to_string(), json!(s));
}
let result = client.vault_list(filters).await?;
print_result("Vault entries:", &result)
}
pub async fn cmd_vault_get(
client: &VtaClient,
id: String,
) -> Result<(), Box<dyn std::error::Error>> {
let result = client.vault_get(&id).await?;
print_result("Vault entry:", &result)
}
pub async fn cmd_vault_delete(
client: &VtaClient,
id: String,
expected_version: Option<u32>,
force: bool,
reason: Option<String>,
) -> Result<(), Box<dyn std::error::Error>> {
let result = client
.vault_delete(&id, expected_version, force, reason.as_deref())
.await?;
if force {
println!("{DIM}Vault entry {id} permanently hard-deleted (no recovery).{RESET}");
} else {
let grace = result.get("graceUntil").and_then(Value::as_str);
match grace {
Some(g) => println!(
"{DIM}Vault entry {id} moved to trash — recoverable with `vault restore {id}` until {g}.{RESET}"
),
None => println!(
"{DIM}Vault entry {id} soft-deleted — recoverable with `vault restore {id}`.{RESET}"
),
}
}
print_result("Result:", &result)
}
pub async fn cmd_vault_archive(
client: &VtaClient,
id: String,
expected_version: Option<u32>,
reason: Option<String>,
) -> Result<(), Box<dyn std::error::Error>> {
let result = client
.vault_archive(&id, expected_version, reason.as_deref())
.await?;
println!("{DIM}Vault entry {id} archived — restore with `vault unarchive {id}`.{RESET}");
print_result("Result:", &result)
}
pub async fn cmd_vault_unarchive(
client: &VtaClient,
id: String,
expected_version: Option<u32>,
reason: Option<String>,
) -> Result<(), Box<dyn std::error::Error>> {
let result = client
.vault_unarchive(&id, expected_version, reason.as_deref())
.await?;
println!("{DIM}Vault entry {id} unarchived.{RESET}");
print_result("Result:", &result)
}
pub async fn cmd_vault_restore(
client: &VtaClient,
id: String,
expected_version: Option<u32>,
reason: Option<String>,
) -> Result<(), Box<dyn std::error::Error>> {
let result = client
.vault_restore(&id, expected_version, reason.as_deref())
.await?;
println!("{DIM}Vault entry {id} restored to active.{RESET}");
print_result("Result:", &result)
}
pub async fn cmd_vault_purge(
client: &VtaClient,
id: String,
expected_version: Option<u32>,
reason: Option<String>,
) -> Result<(), Box<dyn std::error::Error>> {
let result = client
.vault_purge(&id, expected_version, reason.as_deref())
.await?;
println!("{DIM}Vault entry {id} permanently purged (no recovery).{RESET}");
print_result("Result:", &result)
}
pub async fn cmd_vault_upsert(
client: &VtaClient,
entry: Value,
secret: Option<Value>,
) -> Result<(), Box<dyn std::error::Error>> {
let sealed_secret = match secret {
Some(s) => {
let jwe = client.seal_vault_secret(s).await?;
Some(json!({ "envelope": "didcomm-authcrypt", "jwe": jwe }))
}
None => None,
};
let result = client.vault_upsert(entry, sealed_secret).await?;
print_result("Upserted entry:", &result)
}
pub async fn cmd_vault_release(
client: &VtaClient,
id: String,
target: Option<Value>,
) -> Result<(), Box<dyn std::error::Error>> {
let mut payload = json!({ "id": id });
if let Some(t) = target {
payload["target"] = t;
}
let response = client.vault_release(payload).await?;
let jwe = response
.get("sealedSecret")
.and_then(|s| s.get("jwe"))
.and_then(|j| j.as_str());
match jwe {
Some(jwe) => {
let secret = client.open_sealed_secret(jwe).await?;
print_result("Released secret (cleartext):", &secret)
}
None => {
eprintln!("{DIM}(no didcomm-authcrypt sealedSecret in response — printing raw){RESET}");
print_result("Release response:", &response)
}
}
}
pub async fn cmd_vault_proxy_login(
client: &VtaClient,
payload: Value,
) -> Result<(), Box<dyn std::error::Error>> {
let result = client.vault_proxy_login(payload).await?;
print_result("Proxy-login result:", &result)
}
pub async fn cmd_vault_sign_trust_task(
client: &VtaClient,
payload: Value,
) -> Result<(), Box<dyn std::error::Error>> {
let result = client.vault_sign_trust_task(payload).await?;
print_result("Signed envelope:", &result)
}