webull_rs/utils/
crypto.rs

1use crate::error::{WebullError, WebullResult};
2use base64::{decode, encode};
3use hmac::{Hmac, Mac, NewMac};
4use rand::{thread_rng, Rng};
5use sha2::Sha256;
6
7/// Generate a random device ID.
8pub fn generate_device_id() -> String {
9    let mut rng = thread_rng();
10    let random_bytes: [u8; 16] = rng.gen();
11    encode(&random_bytes)
12}
13
14/// Generate an HMAC-SHA256 signature.
15pub fn generate_signature(key: &str, message: &str) -> WebullResult<String> {
16    type HmacSha256 = Hmac<Sha256>;
17
18    let mut mac = HmacSha256::new_from_slice(key.as_bytes())
19        .map_err(|e| WebullError::InvalidRequest(format!("Invalid key: {}", e)))?;
20
21    mac.update(message.as_bytes());
22    let result = mac.finalize();
23    let signature = encode(result.into_bytes());
24
25    Ok(signature)
26}
27
28/// Encrypt a password using the Webull algorithm.
29pub fn encrypt_password(password: &str, _key: &str) -> WebullResult<String> {
30    // This is a simplified version - in a real implementation,
31    // we would use the actual encryption algorithm used by Webull
32
33    // For now, we'll just use base64 encoding as a placeholder
34    let encrypted = encode(password.as_bytes());
35
36    Ok(encrypted)
37}
38
39/// Decrypt data using the Webull algorithm.
40pub fn decrypt_data(data: &str, _key: &str) -> WebullResult<String> {
41    // This is a simplified version - in a real implementation,
42    // we would use the actual decryption algorithm used by Webull
43
44    // For now, we'll just use base64 decoding as a placeholder
45    let decoded =
46        decode(data).map_err(|e| WebullError::InvalidRequest(format!("Invalid data: {}", e)))?;
47
48    let decrypted = String::from_utf8(decoded)
49        .map_err(|e| WebullError::InvalidRequest(format!("Invalid UTF-8: {}", e)))?;
50
51    Ok(decrypted)
52}
53
54/// Generate a timestamp for API requests.
55pub fn generate_timestamp() -> String {
56    let now = std::time::SystemTime::now()
57        .duration_since(std::time::UNIX_EPOCH)
58        .unwrap()
59        .as_millis();
60
61    now.to_string()
62}