1pub mod built_in_plugins;
2pub mod ckb_config;
3pub mod network;
4pub mod script;
5
6pub use ckb_config::CkbConfig;
7pub use network::NetworkConfig;
8pub use script::ScriptConfigItem;
9
10use built_in_plugins::{AtomicSwapConfig, DustCollectorConfig, SignerConfig};
11
12use anyhow::Result;
13use ckb_jsonrpc_types::{CellDep, DepType, Script};
14use ckb_types::packed;
15use ckb_types::prelude::*;
16use ckb_types::H256;
17use serde::de::DeserializeOwned;
18use serde::Deserialize;
19
20use std::collections::HashMap;
21use std::{fs::File, io::Read, path::Path};
22
23#[derive(Clone, Debug, PartialEq, Eq)]
24pub struct ScriptInfo {
25 pub script: packed::Script,
26 pub cell_dep: packed::CellDep,
27}
28
29#[derive(Deserialize, Default, Clone, Debug)]
30pub struct ConfigFile {
31 pub network_config: NetworkConfig,
32 pub ckb_config: CkbConfig,
33 pub scripts: Vec<ScriptConfigItem>,
34 pub built_in_plugin_dust_collector: DustCollectorConfig,
35 pub built_in_plugin_atomic_swap: AtomicSwapConfig,
36 pub built_in_plugin_signer: SignerConfig,
37}
38
39impl ConfigFile {
40 pub fn to_script_map(&self) -> HashMap<String, ScriptInfo> {
41 self.scripts
42 .iter()
43 .map(|s| {
44 (
45 s.get_script_name().to_owned(),
46 ScriptInfo {
47 script: serde_json::from_str::<Script>(s.get_script())
48 .expect("config string to script")
49 .into(),
50 cell_dep: serde_json::from_str::<CellDep>(s.get_cell_dep())
51 .expect("config string to cell dep")
52 .into(),
53 },
54 )
55 })
56 .collect()
57 }
58}
59
60impl From<ConfigFile> for AppConfig {
61 fn from(config_file: ConfigFile) -> Self {
62 Self::new(config_file)
63 }
64}
65
66pub struct AppConfig {
67 network_config: NetworkConfig,
68 ckb_config: CkbConfig,
69 script_config: ScriptConfig,
70 plugin_dust_collector_config: DustCollectorConfig,
71 plugin_atomic_swap_config: AtomicSwapConfig,
72 plugin_signer_config: SignerConfig,
73}
74
75impl AppConfig {
76 pub fn new(config_file: ConfigFile) -> Self {
77 let script_config = config_file.to_script_map();
78 Self {
79 network_config: config_file.network_config,
80 ckb_config: config_file.ckb_config,
81 script_config: ScriptConfig::new(script_config),
82 plugin_dust_collector_config: config_file.built_in_plugin_dust_collector,
83 plugin_atomic_swap_config: config_file.built_in_plugin_atomic_swap,
84 plugin_signer_config: config_file.built_in_plugin_signer,
85 }
86 }
87
88 pub fn get_ckb_config(&self) -> CkbConfig {
89 self.ckb_config.clone()
90 }
91
92 pub fn get_network_config(&self) -> NetworkConfig {
93 self.network_config.clone()
94 }
95
96 pub fn get_script_config(&self) -> ScriptConfig {
97 self.script_config.clone()
98 }
99
100 pub fn get_dust_collector_config(&self) -> DustCollectorConfig {
101 self.plugin_dust_collector_config.clone()
102 }
103
104 pub fn get_atomic_swap_config(&self) -> AtomicSwapConfig {
105 self.plugin_atomic_swap_config.clone()
106 }
107
108 pub fn get_signer_config(&self) -> SignerConfig {
109 self.plugin_signer_config.clone()
110 }
111}
112
113#[derive(Clone, Debug)]
114pub struct ScriptConfig {
115 script_map: HashMap<String, ScriptInfo>,
116}
117
118impl ScriptConfig {
119 pub fn new(script_map: HashMap<String, ScriptInfo>) -> Self {
120 Self { script_map }
121 }
122
123 pub fn get_script_info(&self, script_name: &str) -> Option<ScriptInfo> {
124 self.script_map.get(script_name).cloned()
125 }
126
127 pub fn get_cell_dep(&self, script_name: &str) -> Option<CellDep> {
128 self.script_map
129 .get(script_name)
130 .map(|s| s.cell_dep.clone().into())
131 }
132
133 pub fn get_secp256k1_blake160_sighash_all_code_hash(&self) -> H256 {
134 self.script_map
135 .get("secp256k1_blake160")
136 .expect("secp256k1_blake160")
137 .script
138 .code_hash()
139 .unpack()
140 }
141
142 pub fn get_xudt_rce_code_hash(&self) -> H256 {
143 self.script_map
144 .get("xudt_rce")
145 .expect("xudt_rce")
146 .script
147 .code_hash()
148 .unpack()
149 }
150
151 pub fn get_omni_lock_code_hash(&self) -> H256 {
152 self.script_map
153 .get("omni_lock")
154 .expect("omni_lock")
155 .script
156 .code_hash()
157 .unpack()
158 }
159
160 pub fn get_anyone_can_pay_code_hash(&self) -> H256 {
161 self.script_map
162 .get("anyone_can_pay")
163 .expect("anyone_can_pay")
164 .script
165 .code_hash()
166 .unpack()
167 }
168
169 pub fn get_sudt_code_hash(&self) -> H256 {
170 self.script_map
171 .get("sudt")
172 .expect("sudt")
173 .script
174 .code_hash()
175 .unpack()
176 }
177
178 pub fn get_secp_data_cell_dep(&self) -> CellDep {
179 let tx_hash = self
180 .script_map
181 .get("dao")
182 .expect("dao")
183 .cell_dep
184 .out_point()
185 .tx_hash();
186 let out_point = ckb_types::packed::OutPoint::new_builder()
187 .tx_hash(tx_hash)
188 .index(3u32.pack())
189 .build();
190 CellDep {
191 out_point: out_point.into(),
192 dep_type: DepType::Code,
193 }
194 }
195
196 pub fn get_xdut_cell_dep(&self) -> CellDep {
197 self.script_map
198 .get("xudt_rce")
199 .expect("xudt_rce")
200 .cell_dep
201 .clone()
202 .into()
203 }
204
205 pub fn get_omni_lock_cell_dep(&self) -> CellDep {
206 self.script_map
207 .get("omni_lock")
208 .expect("omni_lock")
209 .cell_dep
210 .clone()
211 .into()
212 }
213}
214
215pub fn parse<T: DeserializeOwned>(name: impl AsRef<Path>) -> Result<T> {
216 parse_reader(&mut File::open(name)?)
217}
218
219fn parse_reader<R: Read, T: DeserializeOwned>(r: &mut R) -> Result<T> {
220 let mut buf = Vec::new();
221 r.read_to_end(&mut buf)?;
222 Ok(toml::from_slice(&buf)?)
223}