// Copyright 2021-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 use crate::client::config::{ default_config_directory, default_config_filepath, default_data_directory, }; use crate::commands::CliNativeClient; use crate::{ client::config::Config, commands::{override_config, OverrideConfig}, error::ClientError, }; use clap::Args; use nym_bin_common::output_format::OutputFormat; use nym_client_core::cli_helpers::client_init::{ initialise_client, CommonClientInitArgs, InitResultsWithConfig, InitialisableClient, }; use serde::Serialize; use std::fmt::Display; use std::fs; use std::net::IpAddr; use std::path::PathBuf; impl InitialisableClient for CliNativeClient { type InitArgs = Init; fn initialise_storage_paths(id: &str) -> Result<(), Self::Error> { fs::create_dir_all(default_data_directory(id))?; fs::create_dir_all(default_config_directory(id))?; Ok(()) } fn default_config_path(id: &str) -> PathBuf { default_config_filepath(id) } fn construct_config(init_args: &Self::InitArgs) -> Self::Config { override_config( Config::new(&init_args.common_args.id), OverrideConfig::from(init_args.clone()), ) } } #[derive(Args, Clone, Debug)] pub(crate) struct Init { #[command(flatten)] common_args: CommonClientInitArgs, /// Whether to not start the websocket #[clap(long)] disable_socket: Option, /// Port for the socket (if applicable) to listen on in all subsequent runs #[clap(short, long)] port: Option, /// Ip for the socket (if applicable) to listen for requests. #[clap(long)] host: Option, #[clap(short, long, default_value_t = OutputFormat::default())] output: OutputFormat, } impl AsRef for Init { fn as_ref(&self) -> &CommonClientInitArgs { &self.common_args } } impl From for OverrideConfig { fn from(init_config: Init) -> Self { OverrideConfig { nym_apis: init_config.common_args.nym_apis, disable_socket: init_config.disable_socket, port: init_config.port, host: init_config.host, fastmode: init_config.common_args.fastmode, no_cover: init_config.common_args.no_cover, nyxd_urls: init_config.common_args.nyxd_urls, enabled_credentials_mode: init_config.common_args.enabled_credentials_mode, stats_reporting_address: init_config.common_args.stats_reporting_address, } } } #[derive(Debug, Serialize)] pub struct InitResults { #[serde(flatten)] client_core: nym_client_core::init::types::InitResults, client_listening_port: u16, client_address: String, } impl InitResults { fn new(res: InitResultsWithConfig) -> Self { Self { client_address: res.init_results.address.to_string(), client_core: res.init_results, client_listening_port: res.config.socket.listening_port, } } } impl Display for InitResults { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { writeln!(f, "{}", self.client_core)?; writeln!(f, "Client listening port: {}", self.client_listening_port)?; write!(f, "Address of this client: {}", self.client_address) } } pub(crate) async fn execute(args: Init) -> Result<(), ClientError> { eprintln!("Initialising client..."); let user_agent = nym_bin_common::bin_info!().into(); let output = args.output; let res = initialise_client::(args, Some(user_agent)).await?; let init_results = InitResults::new(res); println!("{}", output.format(&init_results)); Ok(()) }