synor/apps/cli/src/config.rs
Gulshan Yadav 48949ebb3f Initial commit: Synor blockchain monorepo
A complete blockchain implementation featuring:
- synord: Full node with GHOSTDAG consensus
- explorer-web: Modern React blockchain explorer with 3D DAG visualization
- CLI wallet and tools
- Smart contract SDK and example contracts (DEX, NFT, token)
- WASM crypto library for browser/mobile
2026-01-08 05:22:17 +05:30

113 lines
2.8 KiB
Rust

//! CLI configuration.
use std::fs;
use std::path::{Path, PathBuf};
use serde::{Deserialize, Serialize};
/// CLI configuration.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct CliConfig {
/// RPC server URL.
pub rpc_url: String,
/// Default wallet name.
pub default_wallet: String,
/// Wallet directory.
pub wallet_dir: PathBuf,
/// Network (mainnet, testnet, devnet).
pub network: String,
/// Default output format.
pub output_format: String,
}
impl Default for CliConfig {
fn default() -> Self {
CliConfig {
rpc_url: "http://127.0.0.1:16110".to_string(),
default_wallet: "default".to_string(),
wallet_dir: default_wallet_dir(),
network: "mainnet".to_string(),
output_format: "text".to_string(),
}
}
}
impl CliConfig {
/// Loads config from file or returns default.
pub fn load_or_default(path: Option<&Path>) -> Self {
if let Some(p) = path {
Self::load(p).unwrap_or_default()
} else if let Some(default_path) = default_config_path() {
Self::load(&default_path).unwrap_or_default()
} else {
Self::default()
}
}
/// Loads config from file.
pub fn load(path: &Path) -> anyhow::Result<Self> {
let content = fs::read_to_string(path)?;
let config: CliConfig = toml::from_str(&content)?;
Ok(config)
}
/// Saves config to file.
pub fn save(&self, path: &Path) -> anyhow::Result<()> {
let content = toml::to_string_pretty(self)?;
if let Some(parent) = path.parent() {
fs::create_dir_all(parent)?;
}
fs::write(path, content)?;
Ok(())
}
/// Gets wallet file path.
pub fn wallet_path(&self, name: &str) -> PathBuf {
self.wallet_dir.join(format!("{}.wallet", name))
}
/// Gets default wallet path.
pub fn default_wallet_path(&self) -> PathBuf {
self.wallet_path(&self.default_wallet)
}
}
/// Gets default config directory.
pub fn default_config_dir() -> Option<PathBuf> {
dirs::config_dir().map(|d| d.join("synor"))
}
/// Gets default config path.
pub fn default_config_path() -> Option<PathBuf> {
default_config_dir().map(|d| d.join("cli.toml"))
}
/// Gets default wallet directory.
pub fn default_wallet_dir() -> PathBuf {
dirs::data_dir()
.unwrap_or_else(|| PathBuf::from("."))
.join("synor")
.join("wallets")
}
#[cfg(test)]
mod tests {
use super::*;
use tempfile::tempdir;
#[test]
fn test_config_save_load() {
let dir = tempdir().unwrap();
let path = dir.path().join("config.toml");
let config = CliConfig::default();
config.save(&path).unwrap();
let loaded = CliConfig::load(&path).unwrap();
assert_eq!(loaded.rpc_url, config.rpc_url);
}
}