Skip to main content

fintag_rust/
lib.rs

1use std::time::{SystemTime, UNIX_EPOCH};
2use hmac::{Hmac, Mac};
3use sha2::Sha256;
4use reqwest::blocking::Client;
5use serde_json::Value;
6
7type HmacSha256 = Hmac<Sha256>;
8
9pub struct FintagClient {
10    api_key: String,
11    base_url: String,
12    client: Client,
13}
14
15impl FintagClient {
16    pub fn new(api_key: &str) -> Self {
17        let base_url = "https://api.fintag.io"; // default base URL
18        FintagClient {
19            api_key: api_key.to_string(),
20            base_url: base_url.trim_end_matches('/').to_string(),
21            client: Client::new(),
22        }
23    }
24
25    fn get_headers(&self) -> reqwest::header::HeaderMap {
26        let mut headers = reqwest::header::HeaderMap::new();
27
28        // current timestamp in ms
29        let timestamp = SystemTime::now()
30            .duration_since(UNIX_EPOCH)
31            .unwrap()
32            .as_millis()
33            .to_string();
34
35        // signature: HMAC-SHA256(api_key, timestamp)
36        let mut mac = HmacSha256::new_from_slice(self.api_key.as_bytes())
37            .expect("HMAC can take key of any size");
38        mac.update(timestamp.as_bytes());
39        let signature = hex::encode(mac.finalize().into_bytes());
40
41        headers.insert("authorization", self.api_key.parse().unwrap());
42        headers.insert("x-timestamp", timestamp.parse().unwrap());
43        headers.insert("x-signature", signature.parse().unwrap());
44
45        headers
46    }
47
48    pub fn verify(&self, fintag: &str) -> Result<Value, reqwest::Error> {
49        let cleaned_fintag = fintag.strip_prefix('#').unwrap_or(fintag);
50        let url = format!("{}/fintag/verify/{}", self.base_url, cleaned_fintag);
51
52        let response = self.client
53            .get(&url)
54            .headers(self.get_headers())
55            .send()?
56            .error_for_status()?; // raises error on 4xx/5xx
57
58        response.json()
59    }
60
61    pub fn get_wallet_info(&self, fintag: &str) -> Result<Value, reqwest::Error> {
62        let cleaned_fintag = fintag.strip_prefix('#').unwrap_or(fintag);
63        let url = format!("{}/fintag/wallet/{}", self.base_url, cleaned_fintag);
64
65        let response = self.client
66            .get(&url)
67            .headers(self.get_headers())
68            .send()?
69            .error_for_status()?;
70
71        response.json()
72    }
73}