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}