jsonrpc.rs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. use std::{net::TcpStream, os::unix::net::UnixStream, str, time::Duration};
  2. use async_std::io::timeout;
  3. use futures::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
  4. use rand::Rng;
  5. use serde::{Deserialize, Serialize};
  6. use serde_json::{json, Value};
  7. use smol::Async;
  8. use url::Url;
  9. use crate::{Error, Result};
  10. #[derive(Debug, Clone)]
  11. pub enum ErrorCode {
  12. ParseError,
  13. InvalidRequest,
  14. MethodNotFound,
  15. InvalidParams,
  16. InternalError,
  17. KeyGenError,
  18. GetAddressesError,
  19. ImportAndExportFile,
  20. SetDefaultAddress,
  21. InvalidAmountParam,
  22. InvalidNetworkParam,
  23. InvalidTokenIdParam,
  24. InvalidAddressParam,
  25. InvalidSymbolParam,
  26. ServerError(i64),
  27. }
  28. impl ErrorCode {
  29. pub fn code(&self) -> i64 {
  30. match *self {
  31. ErrorCode::ParseError => -32700,
  32. ErrorCode::InvalidRequest => -32600,
  33. ErrorCode::MethodNotFound => -32601,
  34. ErrorCode::InvalidParams => -32602,
  35. ErrorCode::InternalError => -32603,
  36. ErrorCode::KeyGenError => -32002,
  37. ErrorCode::GetAddressesError => -32003,
  38. ErrorCode::ImportAndExportFile => -32004,
  39. ErrorCode::SetDefaultAddress => -32005,
  40. ErrorCode::InvalidAmountParam => -32010,
  41. ErrorCode::InvalidNetworkParam => -32011,
  42. ErrorCode::InvalidTokenIdParam => -32012,
  43. ErrorCode::InvalidAddressParam => -32013,
  44. ErrorCode::InvalidSymbolParam => -32014,
  45. ErrorCode::ServerError(c) => c,
  46. }
  47. }
  48. pub fn description(&self) -> String {
  49. let desc = match *self {
  50. ErrorCode::ParseError => "Parse error",
  51. ErrorCode::InvalidRequest => "Invalid request",
  52. ErrorCode::MethodNotFound => "Method not found",
  53. ErrorCode::InvalidParams => "Invalid params",
  54. ErrorCode::InternalError => "Internal error",
  55. ErrorCode::KeyGenError => "Key gen error",
  56. ErrorCode::GetAddressesError => "get addresses error",
  57. ErrorCode::ImportAndExportFile => "error import/export a file",
  58. ErrorCode::SetDefaultAddress => "error set default address",
  59. ErrorCode::InvalidAmountParam => "Invalid amount param",
  60. ErrorCode::InvalidNetworkParam => "Invalid network param",
  61. ErrorCode::InvalidTokenIdParam => "Invalid token id param",
  62. ErrorCode::InvalidAddressParam => "Invalid address param",
  63. ErrorCode::InvalidSymbolParam => "Invalid symbol param",
  64. ErrorCode::ServerError(_) => "Server error",
  65. };
  66. desc.to_string()
  67. }
  68. }
  69. #[derive(Serialize, Deserialize, Clone, Debug)]
  70. #[serde(untagged)]
  71. pub enum JsonResult {
  72. Resp(JsonResponse),
  73. Err(JsonError),
  74. Notif(JsonNotification),
  75. }
  76. impl From<JsonResponse> for JsonResult {
  77. fn from(resp: JsonResponse) -> Self {
  78. Self::Resp(resp)
  79. }
  80. }
  81. impl From<JsonError> for JsonResult {
  82. fn from(err: JsonError) -> Self {
  83. Self::Err(err)
  84. }
  85. }
  86. impl From<JsonNotification> for JsonResult {
  87. fn from(notif: JsonNotification) -> Self {
  88. Self::Notif(notif)
  89. }
  90. }
  91. #[derive(Serialize, Deserialize, Clone, Debug)]
  92. pub struct JsonRequest {
  93. pub jsonrpc: Value,
  94. pub method: Value,
  95. pub params: Value,
  96. pub id: Value,
  97. }
  98. #[derive(Serialize, Deserialize, Clone, Debug)]
  99. pub struct JsonErrorVal {
  100. pub code: Value,
  101. pub message: Value,
  102. }
  103. #[derive(Serialize, Deserialize, Clone, Debug)]
  104. pub struct JsonError {
  105. pub jsonrpc: Value,
  106. pub error: JsonErrorVal,
  107. pub id: Value,
  108. }
  109. #[derive(Serialize, Deserialize, Clone, Debug)]
  110. pub struct JsonResponse {
  111. pub jsonrpc: Value,
  112. pub result: Value,
  113. pub id: Value,
  114. }
  115. #[derive(Serialize, Deserialize, Clone, Debug)]
  116. pub struct JsonNotification {
  117. pub jsonrpc: Value,
  118. pub method: Value,
  119. pub params: Value,
  120. }
  121. pub fn request(m: Value, p: Value) -> JsonRequest {
  122. let mut rng = rand::thread_rng();
  123. JsonRequest { jsonrpc: json!("2.0"), method: m, params: p, id: json!(rng.gen::<u32>()) }
  124. }
  125. pub fn response(r: Value, i: Value) -> JsonResponse {
  126. JsonResponse { jsonrpc: json!("2.0"), result: r, id: i }
  127. }
  128. pub fn error(c: ErrorCode, m: Option<String>, i: Value) -> JsonError {
  129. let ev = JsonErrorVal {
  130. code: json!(c.code()),
  131. message: if m.is_none() { json!(c.description()) } else { json!(Some(m)) },
  132. };
  133. JsonError { jsonrpc: json!("2.0"), error: ev, id: i }
  134. }
  135. pub fn notification(m: Value, p: Value) -> JsonNotification {
  136. JsonNotification { jsonrpc: json!("2.0"), method: m, params: p }
  137. }
  138. pub async fn send_request(uri: &Url, data: Value, socks_url: Option<Url>) -> Result<JsonResult> {
  139. let data_str = serde_json::to_string(&data)?;
  140. let socket_addr = uri.socket_addrs(|| None)?[0];
  141. let host = socket_addr.ip().to_string();
  142. let port = socket_addr.port();
  143. match uri.scheme() {
  144. "tcp" | "tls" => {
  145. let mut stream = Async::<TcpStream>::connect(socket_addr).await?;
  146. if uri.scheme() == "tls" {
  147. let mut stream = async_native_tls::connect(&host, stream).await?;
  148. get_reply(&mut stream, data_str).await
  149. } else {
  150. get_reply(&mut stream, data_str).await
  151. }
  152. }
  153. "unix" => {
  154. let mut stream = Async::<UnixStream>::connect(uri.path()).await?;
  155. get_reply(&mut stream, data_str).await
  156. }
  157. "tor" | "nym" => {
  158. use fast_socks5::client::{Config, Socks5Stream};
  159. if socks_url.is_none() {
  160. return Err(Error::NoSocks5UrlFound)
  161. }
  162. let socks_url = socks_url.unwrap();
  163. let config = Config::default();
  164. let socks_url_str = socks_url.socket_addrs(|| None)?[0].to_string();
  165. let mut stream = if !socks_url.username().is_empty() && socks_url.password().is_some() {
  166. Socks5Stream::connect_with_password(
  167. socks_url_str,
  168. host,
  169. port,
  170. socks_url.username().to_string(),
  171. socks_url.password().unwrap().to_string(),
  172. config,
  173. )
  174. .await?
  175. } else {
  176. Socks5Stream::connect(socks_url_str, host, port, config).await?
  177. };
  178. get_reply(&mut stream, data_str).await
  179. }
  180. _ => unimplemented!(),
  181. }
  182. }
  183. async fn get_reply<T: AsyncRead + AsyncWrite + Unpin>(
  184. stream: &mut T,
  185. data_str: String,
  186. ) -> Result<JsonResult> {
  187. // If we don't get a reply after 30 seconds, we'll fail.
  188. let read_timeout = Duration::from_secs(30);
  189. let mut buf = [0; 2048];
  190. stream.write_all(data_str.as_bytes()).await?;
  191. let bytes_read = timeout(read_timeout, async { stream.read(&mut buf[..]).await }).await?;
  192. let reply: JsonResult = serde_json::from_slice(&buf[0..bytes_read])?;
  193. Ok(reply)
  194. }
  195. // Utils to quickly handle errors
  196. pub type ValueResult<Value> = std::result::Result<Value, ErrorCode>;
  197. pub fn from_result(res: ValueResult<Value>, id: Value) -> JsonResult {
  198. match res {
  199. Ok(v) => JsonResult::Resp(response(v, id)),
  200. Err(e) => error(e, None, id).into(),
  201. }
  202. }