use crate::client::Result;
use crate::error::Error;
use hmac::{Hmac, Mac, NewMac};
use sha2::{Digest, Sha256, Sha512};
use std::time::{SystemTime, UNIX_EPOCH};
fn sha256(input: String) -> Vec<u8> {
let mut hasher = Sha256::new();
hasher.update(input.as_bytes());
hasher.finalize().to_vec()
}
fn sha512(input: Vec<u8>, secret: &[u8]) -> Result<Vec<u8>> {
let mut mac = Hmac::<Sha512>::new_varkey(secret)?;
mac.update(&input);
Ok(mac.finalize().into_bytes().to_vec())
}
pub(crate) fn compute_nonce() -> Result<u64> {
let now = SystemTime::now();
let since_the_epoch = now.duration_since(UNIX_EPOCH)?;
Ok(since_the_epoch.as_secs() * 1_000_000_000)
}
pub(crate) fn compute_signature(
api_secret: &str,
path: &str,
nonce: &str,
post_data: &str,
) -> Result<String> {
let mut query = String::from("");
query.push_str(nonce);
query.push_str(post_data);
let mut sha256_res = sha256(query);
let mut to_hash = vec![];
to_hash.append(&mut path.as_bytes().to_owned());
to_hash.append(&mut sha256_res);
let secret = base64::decode(api_secret).map_err(Error::internal)?;
let sha512_res = sha512(to_hash, &secret)?;
Ok(base64::encode(&sha512_res))
}