1#[macro_use]
6mod macros;
7pub mod admin;
8#[cfg(feature = "cait-sith")]
9pub mod cait_sith;
10mod common;
11pub mod encryption;
12mod error;
13mod execute_function;
14mod handshake;
15mod payload;
16mod pkp_claim;
17mod pkp_sign;
18mod session_key;
19mod sev_snp;
20pub mod signature;
21
22pub use common::*;
23pub use encryption::{EncryptionSignRequest, EncryptionSignRequestBuilder, EncryptionSignResponse};
24pub use error::*;
25pub use execute_function::*;
26pub use handshake::*;
27pub use payload::*;
28pub use pkp_claim::*;
29pub use pkp_sign::*;
30pub use session_key::*;
31pub use sev_snp::*;
32
33pub use lit_node_core;
34pub use sev;
35pub use uuid;
36
37use serde::Serialize;
38use std::{collections::HashMap, sync::OnceLock, time::Duration};
39
40static HTTP_CLIENT: OnceLock<reqwest::Client> = OnceLock::new();
41
42fn get_http_client() -> &'static reqwest::Client {
43 HTTP_CLIENT.get_or_init(|| {
44 reqwest::Client::builder()
45 .pool_idle_timeout(Some(Duration::from_secs(10)))
46 .tls_sni(false)
47 .build()
48 .expect("Failed to build HTTP client")
49 })
50}
51
52pub fn compute_ipfs_hash(code: &str) -> String {
54 ipfs_hasher::IpfsHasher::default().compute(code.as_bytes())
55}
56
57async fn request<B>(
58 url_prefix: UrlPrefix,
59 socket_address: &str,
60 api_path: &str,
61 request_id: &str,
62 custom_headers: &HashMap<String, String>,
63 body: B,
64) -> SdkResult<reqwest::Response>
65where
66 B: Serialize,
67{
68 let client = get_http_client();
69 let mut request_builder = client
70 .post(format!("{}://{}/{}", url_prefix, socket_address, api_path))
71 .header("Content-Type", "application/json")
72 .header("Accept", "application/json");
73 if !request_id.is_empty() {
74 request_builder = request_builder.header("X-Request-Id", request_id);
75 }
76 for (custom_header, value) in custom_headers {
77 request_builder = request_builder.header(custom_header, value);
78 }
79 let response_output = request_builder
80 .body(serde_json::to_string(&body)?)
81 .send()
82 .await?;
83 Ok(response_output)
84}
85
86fn extract_headers(response_output: &reqwest::Response) -> SdkResult<HashMap<String, String>> {
87 let response_headers = response_output.headers();
88 let mut out_headers = HashMap::with_capacity(response_headers.len());
89 for (k, v) in response_headers {
90 out_headers.insert(k.to_string(), v.to_str()?.to_string());
91 }
92 Ok(out_headers)
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98
99 #[test]
100 fn url_prefix_parse() {
101 assert_eq!(UrlPrefix::Http, "http".parse::<UrlPrefix>().unwrap());
102 assert_eq!(UrlPrefix::Http, "HTTP".parse::<UrlPrefix>().unwrap());
103 assert_eq!(UrlPrefix::Https, "https".parse::<UrlPrefix>().unwrap());
104 assert_eq!(UrlPrefix::Https, "HTTPS".parse::<UrlPrefix>().unwrap());
105 assert!("ftp".parse::<UrlPrefix>().is_err());
106 }
107
108 #[test]
109 fn url_prefix_to_string() {
110 assert_eq!(UrlPrefix::Http.to_string(), "http");
111 assert_eq!(UrlPrefix::Https.to_string(), "https");
112 }
113
114 #[test]
115 fn url_prefix_default() {
116 assert_eq!(UrlPrefix::Https, UrlPrefix::default());
117 }
118}