jsonserver.rs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. use crate::{net, serial, Error, Result};
  2. use async_executor::Executor;
  3. use async_native_tls::TlsAcceptor;
  4. use async_std::sync::Mutex;
  5. use easy_parallel::Parallel;
  6. use ff::Field;
  7. use http_types::{Request, Response, StatusCode};
  8. use log::*;
  9. use rand::rngs::OsRng;
  10. use rusqlite::Connection;
  11. use serde_json::json;
  12. use smol::Async;
  13. use std::fs::File;
  14. use std::io::prelude::*;
  15. use std::io::BufReader;
  16. use std::net::SocketAddr;
  17. use std::net::TcpListener;
  18. use std::sync::Arc;
  19. // json RPC server goes here
  20. pub struct RpcInterface {
  21. p2p: Arc<net::P2p>,
  22. pub started: Mutex<bool>,
  23. stop_send: async_channel::Sender<()>,
  24. stop_recv: async_channel::Receiver<()>,
  25. }
  26. impl RpcInterface {
  27. pub fn new(p2p: Arc<net::P2p>) -> Arc<Self> {
  28. let (stop_send, stop_recv) = async_channel::unbounded::<()>();
  29. Arc::new(Self {
  30. p2p,
  31. started: Mutex::new(false),
  32. stop_send,
  33. stop_recv,
  34. })
  35. }
  36. async fn db_connect() -> Connection {
  37. let path = dirs::home_dir()
  38. .expect("Cannot find home directory.")
  39. .as_path()
  40. .join(".config/darkfi/wallet.db");
  41. let connector = Connection::open(&path);
  42. connector.expect("Failed to connect to database.")
  43. }
  44. async fn generate_key() -> (Vec<u8>, Vec<u8>) {
  45. let secret: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
  46. let public = zcash_primitives::constants::SPENDING_KEY_GENERATOR * secret;
  47. let pubkey = serial::serialize(&public);
  48. let privkey = serial::serialize(&secret);
  49. (privkey, pubkey)
  50. }
  51. // TODO: fix this
  52. async fn store_key(conn: &Connection, pubkey: Vec<u8>, privkey: Vec<u8>) -> Result<()> {
  53. let mut db_file = File::open("wallet.sql")?;
  54. let mut contents = String::new();
  55. db_file.read_to_string(&mut contents)?;
  56. Ok(conn.execute_batch(&mut contents)?)
  57. }
  58. // add new methods to handle wallet commands
  59. pub async fn serve(self: Arc<Self>, mut req: Request) -> http_types::Result<Response> {
  60. info!("RPC serving {}", req.url());
  61. let request = req.body_string().await?;
  62. let mut io = jsonrpc_core::IoHandler::new();
  63. io.add_sync_method("say_hello", |_| {
  64. Ok(jsonrpc_core::Value::String("Hello World!".into()))
  65. });
  66. let self2 = self.clone();
  67. io.add_method("get_info", move |_| {
  68. let self2 = self2.clone();
  69. async move {
  70. Ok(json!({
  71. "started": *self2.started.lock().await,
  72. "connections": self2.p2p.connections_count().await
  73. }))
  74. }
  75. });
  76. let stop_send = self.stop_send.clone();
  77. io.add_method("stop", move |_| {
  78. let stop_send = stop_send.clone();
  79. async move {
  80. let _ = stop_send.send(()).await;
  81. Ok(jsonrpc_core::Value::Null)
  82. }
  83. });
  84. io.add_method("key_gen", move |_| async move {
  85. RpcInterface::db_connect().await;
  86. let (pubkey, privkey) = RpcInterface::generate_key().await;
  87. //println!("{}", pubkey, "{}", privkey);
  88. Ok(jsonrpc_core::Value::Null)
  89. });
  90. let response = io
  91. .handle_request_sync(&request)
  92. .ok_or(Error::BadOperationType)?;
  93. let mut res = Response::new(StatusCode::Ok);
  94. res.insert_header("Content-Type", "text/plain");
  95. res.set_body(response);
  96. Ok(res)
  97. }
  98. pub async fn wait_for_quit(self: Arc<Self>) -> Result<()> {
  99. Ok(self.stop_recv.recv().await?)
  100. }
  101. }