use detee_shared::app_proto::brain_app_cli_client::BrainAppCliClient; use detee_shared::app_proto::{ AppContract, AppNodeFilters, AppNodeListResp, DelAppReq, ListAppContractsReq, NewAppReq, NewAppRes, }; use detee_shared::sgx::types::brain::AppDeployConfig; use tokio_stream::StreamExt; use crate::config::Config; use crate::sgx::utils::calculate_nanolp_for_app; use crate::utils::{self, sign_request}; #[derive(thiserror::Error, Debug)] pub enum Error { #[error("Failed to connect to the brain: {0}")] BrainConnection(#[from] tonic::transport::Error), #[error("Received error from brain: {}", _0.message())] ResponseStatus(#[from] tonic::Status), #[error(transparent)] InternalError(#[from] utils::Error), #[error(transparent)] ConfigError(#[from] crate::config::Error), } type Result = std::result::Result; pub async fn new_app(app_deploy_config: AppDeployConfig) -> Result { let resource = app_deploy_config.clone().resource; let mut req: NewAppReq = app_deploy_config.clone().into(); let locked_nano = calculate_nanolp_for_app( resource.vcpu, resource.memory_mb, resource.disk_mb, app_deploy_config.hours, req.price_per_unit, ); req.uuid = "".to_string(); req.locked_nano = locked_nano; req.admin_pubkey = Config::get_detee_wallet()?; req.hratls_pubkey = Config::get_hratls_pubkey_hex()?; let mut daemon_serivce = BrainAppCliClient::connect(Config::get_brain_url()).await?; let res = daemon_serivce.deploy_app(sign_request(req)?).await?; Ok(res.into_inner()) } pub async fn delete_app(app_uuid: String) -> Result<()> { let admin_pubkey = Config::get_detee_wallet()?; let delete_req = DelAppReq { uuid: app_uuid, admin_pubkey }; let mut daemon_serivce = BrainAppCliClient::connect(Config::get_brain_url()).await?; let _ = daemon_serivce.delete_app(sign_request(delete_req)?).await?; Ok(()) } pub async fn list_apps() -> Result> { let admin_pubkey = Config::get_detee_wallet().unwrap(); let list_req = ListAppContractsReq { admin_pubkey }; let mut daemon_serivce = BrainAppCliClient::connect(Config::get_brain_url()).await?; let mut res_stream = daemon_serivce.list_app_contracts(sign_request(list_req)?).await?.into_inner(); let mut app_contracts = vec![]; while let Some(stream_update) = res_stream.next().await { match stream_update { Ok(contract) => { app_contracts.push(contract); } Err(e) => { println!("Brain disconnected from register_node: {e}"); } } } Ok(app_contracts) } pub async fn get_one_app_node(req: AppNodeFilters) -> Result { let mut daemon_serivce = BrainAppCliClient::connect(Config::get_brain_url()).await?; let res = daemon_serivce.get_one_app_node(sign_request(req)?).await?; Ok(res.into_inner()) } pub async fn get_app_node_list(req: AppNodeFilters) -> Result> { log::debug!("Getting app nodes from brain..."); let mut daemon_serivce = BrainAppCliClient::connect(Config::get_brain_url()).await?; let mut nodes = Vec::new(); let mut grpc_stream = daemon_serivce.list_app_nodes(sign_request(req)?).await?.into_inner(); while let Some(stream_update) = grpc_stream.next().await { match stream_update { Ok(node) => { log::debug!("Received node from brain: {node:?}"); nodes.push(node); } Err(e) => { log::warn!("Received error instead of node list: {e:?}"); } } } log::debug!("Brain terminated list_nodes stream."); Ok(nodes) }