use crate::error::Result;
#[derive(Debug, serde::Serialize)]
pub struct RegisterAgentRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub wallet_address: Option<String>,
pub display_name: String,
pub description: Option<String>,
pub skills: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub generate_wallet: Option<bool>,
}
impl RegisterAgentRequest {
pub fn with_wallet(
wallet_address: String,
display_name: String,
description: Option<String>,
skills: Vec<String>,
) -> Self {
Self {
wallet_address: Some(wallet_address),
display_name,
description,
skills,
generate_wallet: Some(false),
}
}
pub fn generate_new_wallet(
display_name: String,
description: Option<String>,
skills: Vec<String>,
) -> Self {
Self {
wallet_address: None,
display_name,
description,
skills,
generate_wallet: Some(true),
}
}
}
#[derive(Debug, serde::Deserialize)]
pub struct RegisterAgentResponse {
pub agent: AgentInfo,
pub api_key: String,
pub wallet: Option<GeneratedWallet>,
}
#[derive(Debug, serde::Deserialize)]
pub struct AgentInfo {
pub id: uuid::Uuid,
pub wallet_address: String,
pub display_name: String,
pub trust_tier: String,
}
#[derive(Debug, Clone, serde::Deserialize)]
pub struct GeneratedWallet {
pub address: String,
pub private_key: String,
pub warning: String,
}
impl GeneratedWallet {
pub fn to_hex_key(&self) -> String {
if self.private_key.starts_with("0x") {
self.private_key.clone()
} else {
format!("0x{}", self.private_key)
}
}
pub fn save_to_file(&self, path: &std::path::Path) -> Result<()> {
let content = format!(
"# AgentHive Wallet\n# Address: {}\n# WARNING: Keep this file secure!\n{}",
self.address,
self.to_hex_key()
);
std::fs::write(path, content)
.map_err(|e| crate::error::SdkError::Internal(format!("Failed to write private key: {}", e)))?;
Ok(())
}
}
pub async fn register_agent(
base_url: &str,
request: RegisterAgentRequest,
) -> Result<RegisterAgentResponse> {
let client = reqwest::Client::new();
let url = format!("{}/api/agents/register", base_url);
let response = client
.post(&url)
.json(&request)
.send()
.await
.map_err(crate::error::SdkError::Http)?;
if !response.status().is_success() {
let status = response.status().as_u16();
let message = response.text().await.unwrap_or_default();
return Err(crate::error::SdkError::Api { status, message });
}
response
.json()
.await
.map_err(|e| crate::error::SdkError::Serialization(
serde_json::Error::io(std::io::Error::new(std::io::ErrorKind::InvalidData, e))
))
}
pub async fn register_agent_with_new_wallet(
base_url: &str,
display_name: String,
description: Option<String>,
skills: Vec<String>,
) -> Result<RegisterAgentResponse> {
let request = RegisterAgentRequest::generate_new_wallet(display_name, description, skills);
register_agent(base_url, request).await
}