lit_rust_sdk/client/
encrypt.rs1use crate::client::LitNodeClient;
2use crate::types::{EncryptRequest, EncryptResponse};
3use alloy::providers::Provider as ProviderTrait;
4use eyre::{eyre, Result};
5use sha2::{Digest, Sha256};
6use tracing::debug;
7
8impl<P> LitNodeClient<P>
9where
10 P: ProviderTrait,
11{
12 pub async fn encrypt(&self, params: EncryptRequest) -> Result<EncryptResponse> {
22 if !self.ready {
24 return Err(eyre!(
25 "LitNodeClient is not ready. Please call await client.connect() first."
26 ));
27 }
28
29 let subnet_pub_key = self
31 .subnet_pub_key
32 .as_ref()
33 .ok_or_else(|| eyre!("subnet_pub_key cannot be null"))?;
34
35 let has_conditions = params.access_control_conditions.is_some()
37 || params.evm_contract_conditions.is_some()
38 || params.sol_rpc_conditions.is_some()
39 || params.unified_access_control_conditions.is_some();
40
41 if !has_conditions {
42 return Err(eyre!(
43 "You must provide either accessControlConditions or evmContractConditions or solRpcConditions or unifiedAccessControlConditions"
44 ));
45 }
46
47 let hash_of_conditions = self.get_hashed_access_control_conditions(¶ms)?;
49 let hash_of_conditions_str = hex::encode(&hash_of_conditions);
50
51 debug!("hashOfConditionsStr: {}", hash_of_conditions_str);
52
53 let mut hasher = Sha256::new();
55 hasher.update(¶ms.data_to_encrypt);
56 let hash_of_private_data = hasher.finalize();
57 let hash_of_private_data_str = hex::encode(hash_of_private_data);
58
59 debug!("hashOfPrivateDataStr: {}", hash_of_private_data_str);
60
61 let identity_param = self
63 .get_identity_param_for_encryption(&hash_of_conditions_str, &hash_of_private_data_str);
64
65 debug!("identityParam: {}", identity_param);
66
67 let clean_pub_key = subnet_pub_key.strip_prefix("0x").unwrap_or(subnet_pub_key);
69
70 let ciphertext_bytes = crate::bls::encrypt(
72 &hex::decode(clean_pub_key)?,
73 ¶ms.data_to_encrypt,
74 identity_param.as_bytes(),
75 )?;
76
77 use base64::{engine::general_purpose::STANDARD, Engine as _};
79 let ciphertext = STANDARD.encode(&ciphertext_bytes);
80
81 Ok(EncryptResponse {
82 ciphertext,
83 data_to_encrypt_hash: hash_of_private_data_str,
84 })
85 }
86
87 fn get_hashed_access_control_conditions(&self, params: &EncryptRequest) -> Result<Vec<u8>> {
89 let conditions_json = if let Some(ref conditions) = params.unified_access_control_conditions
91 {
92 serde_json::to_string(conditions)?
93 } else if let Some(ref conditions) = params.access_control_conditions {
94 serde_json::to_string(conditions)?
95 } else if let Some(ref conditions) = params.evm_contract_conditions {
96 serde_json::to_string(conditions)?
97 } else if let Some(ref conditions) = params.sol_rpc_conditions {
98 serde_json::to_string(conditions)?
99 } else {
100 return Err(eyre!("No access control conditions provided"));
101 };
102
103 tracing::debug!(
104 "stringified_access_control_conditions: {:?}",
105 conditions_json
106 );
107
108 let mut hasher = Sha256::new();
110 hasher.update(conditions_json.as_bytes());
111 Ok(hasher.finalize().to_vec())
112 }
113
114 pub(crate) fn get_identity_param_for_encryption(
116 &self,
117 hash_of_conditions: &str,
118 hash_of_private_data: &str,
119 ) -> String {
120 format!(
121 "lit-accesscontrolcondition://{}/{}",
122 hash_of_conditions, hash_of_private_data
123 )
124 }
125}