taurus_api/
config.rs

1use anyhow::bail;
2use log::{debug, trace};
3use serde::{Deserialize, Serialize};
4use std::fs;
5use std::path::Path;
6
7#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
8pub struct Chain {
9    pub prefix: String,
10    pub denom: String,
11    pub lcd: String,
12    pub rpc: String,
13    pub chain_id: String,
14}
15
16#[derive(Deserialize, Serialize, Clone, Debug)]
17pub struct Taurus {
18    pub api_url: String,
19    pub mail: String,
20    pub passwd: String,
21}
22
23#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
24pub struct Wallet {
25    pub name: String,
26    pub address: String,
27}
28
29#[derive(Deserialize, Serialize, Clone, Debug)]
30pub struct Config {
31    pub taurus: Taurus,
32    pub chain: Vec<Chain>,
33    pub wallet: Vec<Wallet>,
34    pub slack_web_hook: Option<String>,
35}
36
37impl Config {
38    fn get_config_path_and_file() -> Result<(String, String), anyhow::Error> {
39        let homedir = std::env::var("HOME")?;
40
41        Ok((
42            format!("{}/.taurus-api", homedir),
43            format!("{}/.taurus-api/config.toml", homedir),
44        ))
45    }
46
47    fn default() -> Result<Self, anyhow::Error> {
48        debug!("generating default config");
49        Ok(Config {
50            taurus: Taurus {
51                api_url: "taurus.io".to_string(),
52                mail: "taurus@taurus.io".to_string(),
53                passwd: "password".to_string(),
54            },
55            chain: vec![
56                Chain {
57                    prefix: "tki".to_string(),
58                    denom: "utki".to_string(),
59                    lcd: "https://api-challenge.blockchain.ki".to_string(),
60                    rpc: "https://rpc-challenge.blockchain.ki".to_string(),
61                    chain_id: "kichain-t-4".to_string(),
62                },
63                Chain {
64                    prefix: "xki".to_string(),
65                    denom: "uxki".to_string(),
66                    lcd: "https://api-mainnet.blockchain.ki".to_string(),
67                    rpc: "https://rpc-mainnet.blockchain.ki".to_string(),
68                    chain_id: "kichain-2".to_string(),
69                },
70            ],
71            wallet: vec![Wallet {
72                name: "toto".to_string(),
73                address: "toto".to_string(),
74            }],
75            slack_web_hook: None,
76        })
77    }
78
79    fn save(config: &Config, config_file: String) -> Result<(), anyhow::Error> {
80        debug!("saving config file {}", config_file);
81        let conf_content = toml::to_string(config);
82        trace!("config: {:#?}", conf_content);
83
84        fs::write(config_file, conf_content?)?;
85        Ok(())
86    }
87
88    pub fn load() -> Result<Self, anyhow::Error> {
89        let (config_path, config_file) = Self::get_config_path_and_file()?;
90
91        if Path::new(&config_file).exists() {
92            debug!("loading config file {}", config_file);
93
94            let config_file = std::fs::read_to_string(config_file)?;
95
96            Ok(toml::from_str(config_file.as_str())?)
97        } else {
98            fs::create_dir_all(config_path)?;
99
100            let cfg = Config::default()?;
101            Self::save(&cfg, config_file)?;
102            Ok(cfg)
103        }
104    }
105
106    pub fn find_wallet(&self, name: &String) -> Result<Wallet, anyhow::Error> {
107        let index = self.wallet.iter().position(|w| w.name == *name);
108
109        if let Some(idx) = index {
110            Ok(self.wallet[idx].clone())
111        } else {
112            bail!("unknown wallet");
113        }
114    }
115
116    pub fn find_chain(&self, chain_id: &String) -> Result<Chain, anyhow::Error> {
117        let index = self.chain.iter().position(|c| c.chain_id == *chain_id);
118
119        if let Some(idx) = index {
120            Ok(self.chain[idx].clone())
121        } else {
122            bail!("unknown chain_id");
123        }
124    }
125}