diff --git a/Cargo.lock b/Cargo.lock index 3a9a93f14..66f1bb156 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4875,7 +4875,7 @@ checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" [[package]] name = "meroctl" -version = "0.1.0" +version = "0.2.0-beta.1" dependencies = [ "bs58 0.5.1", "calimero-blobstore", @@ -4901,6 +4901,7 @@ dependencies = [ "reqwest 0.12.5", "semver", "serde", + "serde_json", "tokio", "toml", "toml_edit 0.22.20", diff --git a/crates/meroctl/Cargo.toml b/crates/meroctl/Cargo.toml index 6f16ccfb0..396c2f2d6 100644 --- a/crates/meroctl/Cargo.toml +++ b/crates/meroctl/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "meroctl" -version = "0.1.0" +version = "0.2.0-beta.1" authors.workspace = true edition.workspace = true repository.workspace = true @@ -24,6 +24,7 @@ rand.workspace = true reqwest = { workspace = true, features = ["json"] } semver.workspace = true serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true tokio = { workspace = true, features = ["io-std", "macros"] } toml.workspace = true toml_edit.workspace = true diff --git a/crates/meroctl/src/cli/app.rs b/crates/meroctl/src/cli/app.rs index 8ebed96fc..a8017ad02 100644 --- a/crates/meroctl/src/cli/app.rs +++ b/crates/meroctl/src/cli/app.rs @@ -2,9 +2,11 @@ use clap::{Parser, Subcommand}; use eyre::Result as EyreResult; use super::RootArgs; +use crate::cli::app::get::GetCommand; use crate::cli::app::install::InstallCommand; use crate::cli::app::list::ListCommand; +mod get; mod install; mod list; @@ -16,6 +18,7 @@ pub struct AppCommand { #[derive(Debug, Subcommand)] pub enum AppSubCommands { + Get(GetCommand), Install(InstallCommand), #[command(alias = "ls")] List(ListCommand), @@ -24,6 +27,7 @@ pub enum AppSubCommands { impl AppCommand { pub async fn run(self, args: RootArgs) -> EyreResult<()> { match self.subcommand { + AppSubCommands::Get(get) => get.run(args).await, AppSubCommands::Install(install) => install.run(args).await, AppSubCommands::List(list) => list.run(args).await, } diff --git a/crates/meroctl/src/cli/app/get.rs b/crates/meroctl/src/cli/app/get.rs new file mode 100644 index 000000000..5395c1b4b --- /dev/null +++ b/crates/meroctl/src/cli/app/get.rs @@ -0,0 +1,56 @@ +use clap::{Parser, ValueEnum}; +use eyre::{bail, Result as EyreResult}; +use reqwest::Client; + +use crate::cli::RootArgs; +use crate::common::RequestType::GET; +use crate::common::{get_response, multiaddr_to_url}; +use crate::config_file::ConfigFile; + +#[derive(Parser, Debug)] +pub struct GetCommand { + #[arg(long, short)] + pub method: GetValues, + + #[arg(long, short)] + pub app_id: String, +} +#[derive(ValueEnum, Debug, Clone)] +pub enum GetValues { + Details, +} + +impl GetCommand { + pub async fn run(self, args: RootArgs) -> EyreResult<()> { + let path = args.home.join(&args.node_name); + + if !ConfigFile::exists(&path) { + bail!("Config file does not exist") + }; + + let Ok(config) = ConfigFile::load(&path) else { + bail!("Failed to load config file") + }; + + let Some(multiaddr) = config.network.server.listen.first() else { + bail!("No address.") + }; + + let client = Client::new(); + + let url = multiaddr_to_url( + multiaddr, + &format!("admin-api/dev/applications/{}", self.app_id), + )?; + + let response = get_response(&client, url, None::<()>, &config.identity, GET).await?; + + if !response.status().is_success() { + bail!("Request failed with status: {}", response.status()) + } + + println!("{}", response.text().await?); + + Ok(()) + } +} diff --git a/crates/meroctl/src/cli/app/install.rs b/crates/meroctl/src/cli/app/install.rs index 43a52f6b8..7347870e9 100644 --- a/crates/meroctl/src/cli/app/install.rs +++ b/crates/meroctl/src/cli/app/install.rs @@ -1,25 +1,38 @@ -use calimero_server_primitives::admin::{InstallApplicationResponse, InstallDevApplicationRequest}; +use calimero_primitives::hash::Hash; +use calimero_server_primitives::admin::{ + InstallApplicationRequest, InstallApplicationResponse, InstallDevApplicationRequest, +}; use camino::Utf8PathBuf; use clap::Parser; use eyre::{bail, Result}; use reqwest::Client; use semver::Version; use tracing::info; +use url::Url; use crate::cli::RootArgs; +use crate::common::RequestType::POST; use crate::common::{get_response, multiaddr_to_url}; use crate::config_file::ConfigFile; #[derive(Debug, Parser)] pub struct InstallCommand { /// Path to the application - #[arg(long, short)] - pub path: Utf8PathBuf, + #[arg(long, short, conflicts_with = "url")] + pub path: Option, + + /// Url of the application + #[clap(long, short, conflicts_with = "path", requires = "metadata")] + pub url: Option, - /// Version of the application #[clap(short, long, help = "Version of the application")] pub version: Option, + + #[clap(short, long, help = "Metadata for the application")] pub metadata: Option>, + + #[clap(long, help = "Hash of the application")] + pub hash: Option, } impl InstallCommand { @@ -40,19 +53,40 @@ impl InstallCommand { let client = Client::new(); - let install_url = multiaddr_to_url(multiaddr, "admin-api/dev/install-application")?; + let mut is_dev_installation = false; - let install_request = InstallDevApplicationRequest::new( - self.path.canonicalize_utf8()?, - self.version, - self.metadata.unwrap_or_default(), - ); + let install_request = if let Some(app_path) = self.path { + let install_dev_request = InstallDevApplicationRequest::new( + app_path.canonicalize_utf8()?, + self.version, + self.metadata.unwrap_or_default(), + ); + is_dev_installation = true; + serde_json::to_value(install_dev_request)? + } else if let Some(app_url) = self.url { + let install_request = InstallApplicationRequest::new( + Url::parse(&app_url)?, + self.version, + self.hash, + self.metadata.unwrap_or_default(), + ); + serde_json::to_value(install_request)? + } else { + bail!("Either path or url must be provided"); + }; + + let install_url = if is_dev_installation { + multiaddr_to_url(multiaddr, "admin-api/dev/install-dev-application")? + } else { + multiaddr_to_url(multiaddr, "admin-api/dev/install-application")? + }; let install_response = get_response( &client, install_url, Some(install_request), &config.identity, + POST, ) .await?; diff --git a/crates/meroctl/src/cli/app/list.rs b/crates/meroctl/src/cli/app/list.rs index 8795b55ec..9e39d5483 100644 --- a/crates/meroctl/src/cli/app/list.rs +++ b/crates/meroctl/src/cli/app/list.rs @@ -4,6 +4,7 @@ use eyre::{bail, Result as EyreResult}; use reqwest::Client; use crate::cli::RootArgs; +use crate::common::RequestType::GET; use crate::common::{get_response, multiaddr_to_url}; use crate::config_file::ConfigFile; @@ -25,7 +26,7 @@ impl ListCommand { let url = multiaddr_to_url(multiaddr, "admin-api/dev/applications")?; let client = Client::new(); - let response = get_response(&client, url, None::<()>, &config.identity).await?; + let response = get_response(&client, url, None::<()>, &config.identity, GET).await?; if !response.status().is_success() { bail!("Request failed with status: {}", response.status()) diff --git a/crates/meroctl/src/cli/context.rs b/crates/meroctl/src/cli/context.rs index ccd9f8c15..6be63b345 100644 --- a/crates/meroctl/src/cli/context.rs +++ b/crates/meroctl/src/cli/context.rs @@ -3,11 +3,15 @@ use const_format::concatcp; use eyre::Result as EyreResult; use crate::cli::context::create::CreateCommand; +use crate::cli::context::delete::DeleteCommand; +use crate::cli::context::get::GetCommand; use crate::cli::context::join::JoinCommand; use crate::cli::context::list::ListCommand; use crate::cli::RootArgs; mod create; +mod delete; +mod get; mod join; mod list; @@ -39,14 +43,19 @@ pub enum ContextSubCommands { List(ListCommand), Create(Box), Join(JoinCommand), + Get(GetCommand), + #[command(alias = "del")] + Delete(DeleteCommand), } impl ContextCommand { pub async fn run(self, args: RootArgs) -> EyreResult<()> { match self.subcommand { - ContextSubCommands::List(list) => list.run(args).await, ContextSubCommands::Create(create) => create.run(args).await, + ContextSubCommands::Delete(delete) => delete.run(args).await, + ContextSubCommands::Get(get) => get.run(args).await, ContextSubCommands::Join(join) => join.run(args).await, + ContextSubCommands::List(list) => list.run(args).await, } } } diff --git a/crates/meroctl/src/cli/context/create.rs b/crates/meroctl/src/cli/context/create.rs index e44f420c6..c973b0edd 100644 --- a/crates/meroctl/src/cli/context/create.rs +++ b/crates/meroctl/src/cli/context/create.rs @@ -19,6 +19,7 @@ use tokio::runtime::Handle; use tokio::sync::mpsc; use crate::cli::RootArgs; +use crate::common::RequestType::{GET, POST}; use crate::common::{get_response, multiaddr_to_url}; use crate::config_file::ConfigFile; @@ -143,7 +144,7 @@ async fn create_context( params.map(String::into_bytes).unwrap_or_default(), ); - let response = get_response(client, url, Some(request), &keypair).await?; + let response = get_response(client, url, Some(request), &keypair, POST).await?; if response.status().is_success() { let context_response: CreateContextResponse = response.json().await?; @@ -243,7 +244,7 @@ async fn update_context_application( let request = UpdateContextApplicationRequest::new(application_id); - let response = get_response(client, url, Some(request), keypair).await?; + let response = get_response(client, url, Some(request), keypair, POST).await?; if response.status().is_success() { println!( @@ -274,7 +275,7 @@ async fn app_installed( &format!("admin-api/dev/application/{application_id}"), )?; - let response = get_response(client, url, None::<()>, keypair).await?; + let response = get_response(client, url, None::<()>, keypair, GET).await?; if !response.status().is_success() { bail!("Request failed with status: {}", response.status()) @@ -292,13 +293,13 @@ async fn install_app( metadata: Option>, keypair: &Keypair, ) -> EyreResult { - let install_url = multiaddr_to_url(base_multiaddr, "admin-api/dev/install-application")?; + let install_url = multiaddr_to_url(base_multiaddr, "admin-api/dev/install-dev-application")?; let install_request = InstallDevApplicationRequest::new(path, None, metadata.unwrap_or_default()); let install_response = - get_response(client, install_url, Some(install_request), keypair).await?; + get_response(client, install_url, Some(install_request), keypair, POST).await?; if !install_response.status().is_success() { let status = install_response.status(); diff --git a/crates/meroctl/src/cli/context/delete.rs b/crates/meroctl/src/cli/context/delete.rs new file mode 100644 index 000000000..c00e35d23 --- /dev/null +++ b/crates/meroctl/src/cli/context/delete.rs @@ -0,0 +1,55 @@ +use clap::Parser; +use eyre::{bail, Result as EyreResult}; +use libp2p::Multiaddr; +use reqwest::Client; + +use crate::cli::RootArgs; +use crate::common::{get_response, multiaddr_to_url, RequestType}; +use crate::config_file::ConfigFile; + +#[derive(Debug, Parser)] +pub struct DeleteCommand { + #[clap(long, short)] + pub context_id: String, +} + +impl DeleteCommand { + pub async fn run(self, root_args: RootArgs) -> EyreResult<()> { + let path = root_args.home.join(&root_args.node_name); + if !ConfigFile::exists(&path) { + bail!("Config file does not exist") + } + let Ok(config) = ConfigFile::load(&path) else { + bail!("Failed to load config file"); + }; + let Some(multiaddr) = config.network.server.listen.first() else { + bail!("No address.") + }; + + let client = Client::new(); + + self.delete_context(multiaddr, &client, &config.identity) + .await + } + + async fn delete_context( + &self, + multiaddr: &Multiaddr, + client: &Client, + keypair: &libp2p::identity::Keypair, + ) -> EyreResult<()> { + let url = multiaddr_to_url( + multiaddr, + &format!("admin-api/dev/contexts/{}", self.context_id), + )?; + let response = get_response(client, url, None::<()>, keypair, RequestType::DELETE).await?; + + if !response.status().is_success() { + bail!("Request failed with status: {}", response.status()) + } + + let text = response.text().await?; + println!("Context deleted successfully: {}", text); + Ok(()) + } +} diff --git a/crates/meroctl/src/cli/context/get.rs b/crates/meroctl/src/cli/context/get.rs new file mode 100644 index 000000000..eb9b9922a --- /dev/null +++ b/crates/meroctl/src/cli/context/get.rs @@ -0,0 +1,148 @@ +use clap::{Parser, ValueEnum}; +use eyre::{bail, Result as EyreResult}; +use libp2p::Multiaddr; +use reqwest::Client; + +use crate::cli::RootArgs; +use crate::common::RequestType::GET; +use crate::common::{get_response, multiaddr_to_url}; +use crate::config_file::ConfigFile; + +#[derive(Parser, Debug)] +pub struct GetCommand { + #[clap(long, short)] + pub method: GetRequest, + + #[clap(long, short)] + pub context_id: String, +} + +#[derive(Clone, Debug, ValueEnum)] +pub enum GetRequest { + Context, + Users, + ClientKeys, + Storage, + Identities, +} + +impl GetCommand { + pub async fn run(self, root_args: RootArgs) -> EyreResult<()> { + let path = root_args.home.join(&root_args.node_name); + if !ConfigFile::exists(&path) { + bail!("Config file does not exist") + } + let Ok(config) = ConfigFile::load(&path) else { + bail!("Failed to load config file"); + }; + let Some(multiaddr) = config.network.server.listen.first() else { + bail!("No address.") + }; + + let client = Client::new(); + + match self.method { + GetRequest::Context => { + self.get_context(multiaddr, &client, &config.identity) + .await? + } + GetRequest::Users => self.get_users(multiaddr, &client, &config.identity).await?, + GetRequest::ClientKeys => { + self.get_client_keys(multiaddr, &client, &config.identity) + .await? + } + GetRequest::Storage => { + self.get_storage(multiaddr, &client, &config.identity) + .await? + } + GetRequest::Identities => { + self.get_identities(multiaddr, &client, &config.identity) + .await? + } + } + + Ok(()) + } + + async fn get_context( + &self, + multiaddr: &Multiaddr, + client: &Client, + keypair: &libp2p::identity::Keypair, + ) -> EyreResult<()> { + let url = multiaddr_to_url( + multiaddr, + &format!("admin-api/dev/contexts/{}", self.context_id), + )?; + self.make_request(client, url, keypair).await + } + + async fn get_users( + &self, + multiaddr: &Multiaddr, + client: &Client, + keypair: &libp2p::identity::Keypair, + ) -> EyreResult<()> { + let url = multiaddr_to_url( + multiaddr, + &format!("admin-api/dev/contexts/{}/users", self.context_id), + )?; + self.make_request(client, url, keypair).await + } + + async fn get_client_keys( + &self, + multiaddr: &Multiaddr, + client: &Client, + keypair: &libp2p::identity::Keypair, + ) -> EyreResult<()> { + let url = multiaddr_to_url( + multiaddr, + &format!("admin-api/dev/contexts/{}/client-keys", self.context_id), + )?; + self.make_request(client, url, keypair).await + } + + async fn get_storage( + &self, + multiaddr: &Multiaddr, + client: &Client, + keypair: &libp2p::identity::Keypair, + ) -> EyreResult<()> { + let url = multiaddr_to_url( + multiaddr, + &format!("admin-api/dev/contexts/{}/storage", self.context_id), + )?; + self.make_request(client, url, keypair).await + } + + async fn get_identities( + &self, + multiaddr: &Multiaddr, + client: &Client, + keypair: &libp2p::identity::Keypair, + ) -> EyreResult<()> { + let url = multiaddr_to_url( + multiaddr, + &format!("admin-api/dev/contexts/{}/identities", self.context_id), + )?; + self.make_request(client, url, keypair).await + } + + async fn make_request( + &self, + client: &Client, + url: reqwest::Url, + keypair: &libp2p::identity::Keypair, + ) -> EyreResult<()> { + let response = get_response(client, url, None::<()>, keypair, GET).await?; + + if !response.status().is_success() { + bail!("Request failed with status: {}", response.status()) + } + + let text = response.text().await?; + println!("{}", text); + Ok(()) + } +} diff --git a/crates/meroctl/src/cli/context/join.rs b/crates/meroctl/src/cli/context/join.rs index 434117aab..8c6170959 100644 --- a/crates/meroctl/src/cli/context/join.rs +++ b/crates/meroctl/src/cli/context/join.rs @@ -4,6 +4,7 @@ use reqwest::Client; use tracing::info; use crate::cli::RootArgs; +use crate::common::RequestType::POST; use crate::common::{get_response, multiaddr_to_url}; use crate::config_file::ConfigFile; @@ -31,7 +32,7 @@ impl JoinCommand { &format!("admin-api/dev/contexts/{}/join", self.context_id), )?; let client = Client::new(); - let response = get_response(&client, url, Some(()), &config.identity).await?; + let response = get_response(&client, url, Some(()), &config.identity, POST).await?; if !response.status().is_success() { bail!("Request failed with status: {}", response.status()) diff --git a/crates/meroctl/src/cli/context/list.rs b/crates/meroctl/src/cli/context/list.rs index b19d1443f..d6837da76 100644 --- a/crates/meroctl/src/cli/context/list.rs +++ b/crates/meroctl/src/cli/context/list.rs @@ -4,6 +4,7 @@ use eyre::{bail, Result as EyreResult}; use reqwest::Client; use crate::cli::RootArgs; +use crate::common::RequestType::GET; use crate::common::{get_response, multiaddr_to_url}; use crate::config_file::ConfigFile; @@ -26,7 +27,7 @@ impl ListCommand { let url = multiaddr_to_url(multiaddr, "admin-api/dev/contexts")?; let client = Client::new(); - let response = get_response(&client, url, None::<()>, &config.identity).await?; + let response = get_response(&client, url, None::<()>, &config.identity, GET).await?; if !response.status().is_success() { bail!("Request failed with status: {}", response.status()) diff --git a/crates/meroctl/src/common.rs b/crates/meroctl/src/common.rs index 47695e48b..6dc9a151b 100644 --- a/crates/meroctl/src/common.rs +++ b/crates/meroctl/src/common.rs @@ -35,14 +35,15 @@ pub async fn get_response( url: Url, body: Option, keypair: &Keypair, + req_type: RequestType, ) -> EyreResult { let timestamp = Utc::now().timestamp().to_string(); let signature = keypair.sign(timestamp.as_bytes())?; - let mut builder = if body.is_some() { - client.post(url).json(&body) - } else { - client.get(url) + let mut builder = match req_type { + RequestType::GET => client.get(url), + RequestType::POST => client.post(url).json(&body), + RequestType::DELETE => client.delete(url), }; builder = builder @@ -54,3 +55,9 @@ pub async fn get_response( .await .map_err(|_| eyre!("Error with client request")) } + +pub enum RequestType { + GET, + POST, + DELETE, +} diff --git a/crates/server-primitives/src/admin.rs b/crates/server-primitives/src/admin.rs index 7546ba155..6646f42db 100644 --- a/crates/server-primitives/src/admin.rs +++ b/crates/server-primitives/src/admin.rs @@ -17,6 +17,23 @@ pub struct InstallApplicationRequest { pub metadata: Vec, } +impl InstallApplicationRequest { + #[must_use] + pub const fn new( + url: Url, + version: Option, + hash: Option, + metadata: Vec, + ) -> Self { + Self { + url, + hash, + version, + metadata, + } + } +} + #[derive(Clone, Debug, Deserialize, Serialize)] #[non_exhaustive] pub struct InstallDevApplicationRequest { diff --git a/crates/server/src/admin/service.rs b/crates/server/src/admin/service.rs index 96392c031..f6240c4cb 100644 --- a/crates/server/src/admin/service.rs +++ b/crates/server/src/admin/service.rs @@ -121,7 +121,7 @@ pub(crate) fn setup( .route("/refresh-jwt-token", post(refresh_jwt_token_handler)) .route("/generate-jwt-token", post(generate_jwt_token_handler)) .layer(AuthSignatureLayer::new(store)) - .layer(Extension(shared_state.clone())); + .layer(Extension(Arc::clone(&shared_state))); let unprotected_router = Router::new() .route("/health", get(health_check_handler)) @@ -131,10 +131,18 @@ pub(crate) fn setup( let dev_router = Router::new() .route( - "/dev/install-application", + "/dev/install-dev-application", post(install_dev_application_handler), ) + .route( + "/dev/install-application", + post(install_application_handler), + ) .route("/dev/application/:application_id", get(get_application)) + .route( + "/dev/applications/:app_id", + get(get_application_details_handler), + ) .route( "/dev/contexts", get(get_contexts_handler).post(create_context_handler), @@ -145,6 +153,24 @@ pub(crate) fn setup( post(update_application_id), ) .route("/dev/applications", get(list_applications_handler)) + .route("/dev/contexts/:context_id", get(get_context_handler)) + .route( + "/dev/contexts/:context_id/users", + get(get_context_users_handler), + ) + .route( + "/dev/contexts/:context_id/client-keys", + get(get_context_client_keys_handler), + ) + .route( + "/dev/contexts/:context_id/storage", + get(get_context_storage_handler), + ) + .route( + "/dev/contexts/:context_id/identities", + get(get_context_identities_handler), + ) + .route("/dev/contexts/:context_id", delete(delete_context_handler)) .route_layer(axum::middleware::from_fn( middleware::dev_auth::dev_mode_auth, )); diff --git a/crates/server/src/admin/utils/auth.rs b/crates/server/src/admin/utils/auth.rs index 153beee26..6058e9a8c 100644 --- a/crates/server/src/admin/utils/auth.rs +++ b/crates/server/src/admin/utils/auth.rs @@ -335,13 +335,5 @@ pub fn verify_eth_signature(account: &str, message: &str, signature: &str) -> Ey } pub fn eth_message(message: &str) -> [u8; 32] { - keccak256( - format!( - "{}{}{}", - "\x19Ethereum Signed Message:\n", - message.len(), - message - ) - .as_bytes(), - ) + keccak256(format!("\x19Ethereum Signed Message:\n{}{message}", message.len()).as_bytes()) } diff --git a/crates/store/src/entry.rs b/crates/store/src/entry.rs index 0d2318560..c44c650c1 100644 --- a/crates/store/src/entry.rs +++ b/crates/store/src/entry.rs @@ -1,10 +1,15 @@ +#[cfg(feature = "borsh")] use std::io::Error as IoError; +#[cfg(feature = "borsh")] use borsh::{ from_slice as from_borsh_slice, to_vec as to_borsh_vec, BorshDeserialize, BorshSerialize, }; +#[cfg(feature = "serde")] use serde::de::DeserializeOwned; +#[cfg(feature = "serde")] use serde::Serialize; +#[cfg(feature = "serde")] use serde_json::{from_slice as from_json_slice, to_vec as to_json_vec, Error as JsonError}; use crate::key::AsKeyParts; diff --git a/crates/store/src/key.rs b/crates/store/src/key.rs index 3020923cc..baa1b0363 100644 --- a/crates/store/src/key.rs +++ b/crates/store/src/key.rs @@ -1,8 +1,10 @@ use core::cmp::Ordering; use core::fmt::{Debug, Formatter}; use core::{fmt, ptr}; +#[cfg(feature = "borsh")] use std::io::{Read, Result as IoResult, Write}; +#[cfg(feature = "borsh")] use borsh::{BorshDeserialize, BorshSerialize}; use component::KeyComponents; use generic_array::typenum::Const; diff --git a/crates/store/src/key/application.rs b/crates/store/src/key/application.rs index 123b5b0bc..0e0fe74a4 100644 --- a/crates/store/src/key/application.rs +++ b/crates/store/src/key/application.rs @@ -1,6 +1,7 @@ use core::convert::Infallible; use core::fmt::{self, Debug, Formatter}; +#[cfg(feature = "borsh")] use borsh::{BorshDeserialize, BorshSerialize}; use calimero_primitives::application::ApplicationId as PrimitiveApplicationId; use generic_array::typenum::U32; diff --git a/crates/store/src/key/blobs.rs b/crates/store/src/key/blobs.rs index 4c525f950..990113172 100644 --- a/crates/store/src/key/blobs.rs +++ b/crates/store/src/key/blobs.rs @@ -1,6 +1,7 @@ use core::convert::Infallible; use core::fmt::{self, Debug, Formatter}; +#[cfg(feature = "borsh")] use borsh::{BorshDeserialize, BorshSerialize}; use calimero_primitives::blobs::BlobId as PrimitiveBlobId; use generic_array::typenum::U32; diff --git a/crates/store/src/key/context.rs b/crates/store/src/key/context.rs index 52a243202..da6456141 100644 --- a/crates/store/src/key/context.rs +++ b/crates/store/src/key/context.rs @@ -1,6 +1,7 @@ use core::convert::Infallible; use core::fmt::{self, Debug, Formatter}; +#[cfg(feature = "borsh")] use borsh::{BorshDeserialize, BorshSerialize}; use calimero_primitives::context::ContextId as PrimitiveContextId; use calimero_primitives::identity::PublicKey as PrimitivePublicKey; diff --git a/crates/store/src/key/generic.rs b/crates/store/src/key/generic.rs index cf3c5943d..f8ab17a56 100644 --- a/crates/store/src/key/generic.rs +++ b/crates/store/src/key/generic.rs @@ -1,5 +1,6 @@ use core::fmt::{self, Debug, Formatter}; +#[cfg(feature = "borsh")] use borsh::{BorshDeserialize, BorshSerialize}; use generic_array::sequence::Concat; use generic_array::typenum::{U16, U32};