use hmac::{Hmac, Mac};
use sha2::Sha256;
use std::time::{SystemTime, UNIX_EPOCH};
type HmacSha256 = Hmac<Sha256>;
pub fn generate_signature(
api_secret: &str,
timestamp: u64,
api_key: &str,
recv_window: u64,
payload: &str,
) -> String {
let param_str = format!("{}{}{}{}", timestamp, api_key, recv_window, payload);
let mut mac =
HmacSha256::new_from_slice(api_secret.as_bytes()).expect("HMAC can take key of any size");
mac.update(param_str.as_bytes());
hex::encode(mac.finalize().into_bytes())
}
pub fn get_timestamp() -> u64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards")
.as_millis() as u64
}
pub fn generate_ws_signature(api_secret: &str, expires: u64) -> String {
let param_str = format!("GET/realtime{}", expires);
let mut mac =
HmacSha256::new_from_slice(api_secret.as_bytes()).expect("HMAC can take key of any size");
mac.update(param_str.as_bytes());
hex::encode(mac.finalize().into_bytes())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_generate_signature() {
let api_secret = "test_secret";
let timestamp = 1659582742000u64;
let api_key = "test_key";
let recv_window = 5000u64;
let payload = r#"{"symbol":"BTCUSDT"}"#;
let signature = generate_signature(api_secret, timestamp, api_key, recv_window, payload);
assert_eq!(signature.len(), 64);
}
#[test]
fn test_generate_ws_signature() {
let api_secret = "test_secret";
let expires = 1659582752000u64;
let signature = generate_ws_signature(api_secret, expires);
assert_eq!(signature.len(), 64);
}
#[test]
fn test_get_timestamp() {
let timestamp = get_timestamp();
assert!(timestamp > 1577836800000); }
}