drk_cli.rs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. //use super::cli_config::DrkCliConfig;
  2. use crate::Result;
  3. use crate::serial::{deserialize, serialize};
  4. use blake2b_simd::Params;
  5. use clap::{App, Arg};
  6. use serde::{Deserialize, Serialize};
  7. use std::path::PathBuf;
  8. fn amount_f64(v: String) -> std::result::Result<(), String> {
  9. if v.parse::<f64>().is_ok() {
  10. Ok(())
  11. } else {
  12. Err(String::from("The value is not an integer of type u64"))
  13. }
  14. }
  15. #[derive(Deserialize, Debug)]
  16. pub struct TransferParams {
  17. pub asset_id: Vec<u8>,
  18. pub pub_key: String,
  19. pub amount: f64,
  20. }
  21. impl TransferParams {
  22. pub fn new(asset_id: Vec<u8>, pub_key: String, amount: f64) -> Self {
  23. Self {
  24. asset_id,
  25. pub_key,
  26. amount,
  27. }
  28. }
  29. }
  30. pub struct Deposit {
  31. pub asset_id: Vec<u8>,
  32. }
  33. impl Deposit {
  34. pub fn new(asset_id: Vec<u8>) -> Self {
  35. Self { asset_id }
  36. }
  37. }
  38. #[derive(Deserialize, Debug)]
  39. pub struct WithdrawParams {
  40. pub asset_id: Vec<u8>,
  41. pub pub_key: String,
  42. pub amount: f64,
  43. }
  44. impl WithdrawParams {
  45. pub fn new(asset_id: Vec<u8>, pub_key: String, amount: f64) -> Self {
  46. Self {
  47. asset_id,
  48. pub_key,
  49. amount,
  50. }
  51. }
  52. }
  53. #[derive(Deserialize, Serialize, Debug)]
  54. pub struct Asset {
  55. pub name: String,
  56. pub id: Vec<u8>,
  57. }
  58. impl Asset {
  59. pub fn new(name: String) -> Self {
  60. let id = Self::id_hash(&name);
  61. Self { name, id }
  62. }
  63. pub fn id_hash(name: &String) -> Vec<u8> {
  64. let mut hasher = Params::new().hash_length(64).to_state();
  65. hasher.update(name.as_bytes());
  66. let result = hasher.finalize();
  67. let hash = jubjub::Fr::from_bytes_wide(result.as_array());
  68. let id = serialize(&hash);
  69. id
  70. }
  71. }
  72. pub struct DrkCli {
  73. pub verbose: bool,
  74. pub wallet: bool,
  75. pub key: bool,
  76. pub get_key: bool,
  77. pub info: bool,
  78. pub hello: bool,
  79. pub stop: bool,
  80. pub transfer: Option<TransferParams>,
  81. pub deposit: Option<Deposit>,
  82. pub withdraw: Option<WithdrawParams>,
  83. pub config: Box<Option<PathBuf>>,
  84. }
  85. impl DrkCli {
  86. pub fn load() -> Result<Self> {
  87. let app = App::new("Drk CLI")
  88. .version("0.1.0")
  89. .author("Dark Renaissance Technologies")
  90. .about("Run Drk Client")
  91. .arg(
  92. Arg::with_name("verbose")
  93. .short("v")
  94. .help("Increase verbosity")
  95. .long("verbose")
  96. .takes_value(false),
  97. )
  98. .arg(
  99. Arg::with_name("hello")
  100. .long("hello")
  101. .help("Say hello")
  102. .takes_value(false),
  103. )
  104. .arg(
  105. Arg::with_name("key")
  106. .short("k")
  107. .long("key")
  108. .help("Generate new keypair")
  109. .takes_value(false),
  110. )
  111. .arg(
  112. Arg::with_name("getkey")
  113. .long("getkey")
  114. .help("Get public key as base-58 encoded string")
  115. .takes_value(false),
  116. )
  117. .arg(
  118. Arg::with_name("wallet")
  119. .short("w")
  120. .long("wallet")
  121. .help("Create a new wallet")
  122. .takes_value(false),
  123. )
  124. .arg(
  125. Arg::with_name("info")
  126. .short("i")
  127. .long("info")
  128. .help("Request info from daemon")
  129. .takes_value(false),
  130. )
  131. .arg(
  132. Arg::with_name("stop")
  133. .short("s")
  134. .long("stop")
  135. .help("Send a stop signal to the daemon")
  136. .takes_value(false),
  137. )
  138. .arg(
  139. Arg::with_name("config")
  140. .help("Path for config file")
  141. .long("config")
  142. .takes_value(true),
  143. )
  144. .subcommand(
  145. App::new("transfer")
  146. .about("Transfer dark assets between users")
  147. .arg(
  148. Arg::with_name("asset")
  149. .value_name("ASSET_TYPE")
  150. .takes_value(true)
  151. .index(1)
  152. .help("Desired asset type")
  153. .required(true),
  154. )
  155. .arg(
  156. Arg::with_name("address")
  157. .value_name("RECEIVE_ADDRESS")
  158. .takes_value(true)
  159. .index(2)
  160. .help("Address of recipient")
  161. .required(true),
  162. )
  163. .arg(
  164. Arg::with_name("amount")
  165. .value_name("AMOUNT")
  166. .takes_value(true)
  167. .index(3)
  168. .validator(amount_f64)
  169. .help("Amount to send")
  170. .required(true),
  171. ),
  172. )
  173. .subcommand(
  174. App::new("deposit")
  175. .about("Deposit clear assets for dark assets")
  176. .arg(
  177. Arg::with_name("asset")
  178. .value_name("ASSET_TYPE")
  179. .takes_value(true)
  180. .index(1)
  181. .help("Desired asset type")
  182. .required(true),
  183. ),
  184. )
  185. .subcommand(
  186. App::new("withdraw")
  187. .about("Withdraw dark assets for clear assets")
  188. .arg(
  189. Arg::with_name("asset")
  190. .value_name("ASSET_TYPE")
  191. .takes_value(true)
  192. .index(1)
  193. .help("Desired asset type")
  194. .required(true),
  195. )
  196. .arg(
  197. Arg::with_name("address")
  198. .value_name("RECEIVE_ADDRESS")
  199. .takes_value(true)
  200. .index(2)
  201. .help("Address of recipient")
  202. .required(true),
  203. )
  204. .arg(
  205. Arg::with_name("amount")
  206. .value_name("AMOUNT")
  207. .takes_value(true)
  208. .index(3)
  209. .validator(amount_f64)
  210. .help("Amount to send")
  211. .required(true),
  212. ),
  213. )
  214. .get_matches();
  215. let verbose = app.is_present("verbose");
  216. let wallet = app.is_present("wallet");
  217. let key = app.is_present("key");
  218. let info = app.is_present("info");
  219. let hello = app.is_present("hello");
  220. let stop = app.is_present("stop");
  221. let get_key = app.is_present("getkey");
  222. let mut deposit = None;
  223. match app.subcommand_matches("deposit") {
  224. Some(deposit_sub) => {
  225. let asset_value = deposit_sub.value_of("asset").unwrap();
  226. let asset = Asset::new(asset_value.to_string());
  227. let dep = Deposit::new(asset.id.clone());
  228. deposit = Some(dep);
  229. let id: jubjub::Fr = deserialize(&asset.id)?;
  230. println!(
  231. "deposit request for asset: {}, asset ID: {:?}",
  232. asset_value, id
  233. );
  234. }
  235. None => {}
  236. }
  237. let mut transfer = None;
  238. match app.subcommand_matches("transfer") {
  239. Some(transfer_sub) => {
  240. let asset_value = transfer_sub.value_of("asset").unwrap().to_string();
  241. let asset = Asset::new(asset_value.clone());
  242. let address = transfer_sub.value_of("address").unwrap().to_string();
  243. let amount = transfer_sub
  244. .value_of("amount")
  245. .unwrap()
  246. .parse()
  247. .expect("Convert the amount to f64");
  248. let trn = TransferParams::new(asset.id.clone(), address, amount);
  249. transfer = Some(trn);
  250. let id: jubjub::Fr = deserialize(&asset.id)?;
  251. println!(
  252. "transfer request for asset: {}, amount: {}, asset ID: {:?}",
  253. asset_value, amount, id
  254. );
  255. }
  256. None => {}
  257. }
  258. let mut withdraw = None;
  259. match app.subcommand_matches("withdraw") {
  260. Some(withdraw_sub) => {
  261. let asset_value = withdraw_sub.value_of("asset").unwrap().to_string();
  262. let asset = Asset::new(asset_value.clone());
  263. let address = withdraw_sub.value_of("address").unwrap().to_string();
  264. let amount = withdraw_sub
  265. .value_of("amount")
  266. .unwrap()
  267. .parse()
  268. .expect("Convert the amount to f64");
  269. let wdraw = WithdrawParams::new(asset.id.clone(), address, amount);
  270. withdraw = Some(wdraw);
  271. let id: jubjub::Fr = deserialize(&asset.id)?;
  272. println!(
  273. "withdraw request for asset: {}, amount: {}, asset ID: {:?}",
  274. asset_value, amount, id
  275. );
  276. }
  277. None => {}
  278. }
  279. let config = Box::new(if let Some(config_path) = app.value_of("config") {
  280. Some(std::path::Path::new(config_path).to_path_buf())
  281. } else {
  282. None
  283. });
  284. Ok(Self {
  285. verbose,
  286. wallet,
  287. key,
  288. get_key,
  289. info,
  290. hello,
  291. stop,
  292. deposit,
  293. transfer,
  294. withdraw,
  295. config,
  296. })
  297. }
  298. }