Rust SDK

Rust integration using the reqwest crate with tokio async runtime.

Type-safe and memory-safe

Full async/await support with strong typing. Uses reqwest + serde_json for HTTP and JSON.

Installation

Add dependencies to your Cargo.toml:

Cargo.toml
TOML
[dependencies]
reqwest = { version = "0.12", features = ["json"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tokio = { version = "1", features = ["full"] }

SDK Implementation

src/authon.rs
Rust
use reqwest::Client;
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
use std::collections::HashMap;

#[derive(Debug, Clone, Default)]
pub struct UserData {
    pub username: String,
    pub level: i32,
    pub expires_at: String,
    pub session_token: String,
}

#[derive(Debug, Clone, Default)]
pub struct AppData {
    pub name: String,
    pub version: String,
}

pub struct Authon {
    app_id: String,
    api_key: String,
    api_url: String,
    client: Client,
    pub user: UserData,
    pub app: AppData,
    pub last_error: String,
    pub initialized: bool,
    session_token: String,
}

#[derive(Deserialize)]
struct ApiResponse {
    success: bool,
    message: Option<String>,
    data: Option<Value>,
}

impl Authon {
    pub fn new(app_id: &str, api_key: &str) -> Self {
        Self {
            app_id: app_id.to_string(),
            api_key: api_key.to_string(),
            api_url: "https://api.authon.pro".to_string(),
            client: Client::new(),
            user: UserData::default(),
            app: AppData::default(),
            last_error: String::new(),
            initialized: false,
            session_token: String::new(),
        }
    }

    async fn post(&mut self, data: Value) -> Option<ApiResponse> {
        let mut body = data.as_object().unwrap().clone();
        body.insert("appId".to_string(), json!(self.app_id));
        body.insert("apiKey".to_string(), json!(self.api_key));

        let result = self.client
            .post(format!("{}/v1", self.api_url))
            .json(&body)
            .send()
            .await;

        match result {
            Ok(resp) => {
                match resp.json::<ApiResponse>().await {
                    Ok(api_resp) => {
                        if !api_resp.success {
                            self.last_error = api_resp.message
                                .clone()
                                .unwrap_or_default();
                        }
                        Some(api_resp)
                    }
                    Err(e) => {
                        self.last_error = e.to_string();
                        None
                    }
                }
            }
            Err(e) => {
                self.last_error = e.to_string();
                None
            }
        }
    }

    pub async fn init(&mut self) -> bool {
        let resp = self.post(json!({"type": "init"})).await;
        if let Some(r) = resp {
            if r.success {
                if let Some(data) = r.data {
                    self.app.name = data["name"]
                        .as_str().unwrap_or("").to_string();
                    self.app.version = data["version"]
                        .as_str().unwrap_or("").to_string();
                }
                self.initialized = true;
                return true;
            }
        }
        false
    }

    pub async fn login(&mut self, username: &str, password: &str, hwid: &str) -> bool {
        let mut data = json!({"type": "login", "username": username, "password": password});
        if !hwid.is_empty() {
            data["hwid"] = json!(hwid);
        }
        let resp = self.post(data).await;
        if let Some(r) = resp {
            if r.success {
                if let Some(data) = r.data {
                    self.user.username = data["username"]
                        .as_str().unwrap_or("").to_string();
                    self.user.level = data["level"]
                        .as_i64().unwrap_or(0) as i32;
                    self.user.expires_at = data["expiresAt"]
                        .as_str().unwrap_or("").to_string();
                    self.session_token = data["sessionToken"]
                        .as_str().unwrap_or("").to_string();
                }
                return true;
            }
        }
        false
    }

    pub async fn register(
        &mut self, username: &str, password: &str,
        license_key: &str, hwid: &str
    ) -> bool {
        let mut data = json!({
            "type": "register", "username": username,
            "password": password, "licenseKey": license_key
        });
        if !hwid.is_empty() {
            data["hwid"] = json!(hwid);
        }
        let resp = self.post(data).await;
        if let Some(r) = resp {
            if r.success {
                if let Some(data) = r.data {
                    self.user.level = data["level"]
                        .as_i64().unwrap_or(0) as i32;
                    self.user.expires_at = data["expiresAt"]
                        .as_str().unwrap_or("").to_string();
                }
                return true;
            }
        }
        false
    }

    pub async fn license(&mut self, license_key: &str, hwid: &str) -> bool {
        let mut data = json!({"type": "license", "licenseKey": license_key});
        if !hwid.is_empty() {
            data["hwid"] = json!(hwid);
        }
        let resp = self.post(data).await;
        if let Some(r) = resp {
            if r.success {
                if let Some(data) = r.data {
                    self.user.level = data["level"]
                        .as_i64().unwrap_or(0) as i32;
                    self.user.expires_at = data["expiresAt"]
                        .as_str().unwrap_or("").to_string();
                    self.session_token = data["sessionToken"]
                        .as_str().unwrap_or("").to_string();
                }
                return true;
            }
        }
        false
    }

    pub async fn check(&mut self) -> bool {
        let resp = self.post(json!({
            "type": "check", "sessionToken": self.session_token
        })).await;
        resp.map(|r| r.success).unwrap_or(false)
    }

    pub async fn get_var(&mut self, key: &str) -> String {
        let resp = self.post(json!({
            "type": "var", "sessionToken": self.session_token, "key": key
        })).await;
        if let Some(r) = resp {
            if r.success {
                if let Some(data) = r.data {
                    return data["value"]
                        .as_str().unwrap_or("").to_string();
                }
            }
        }
        String::new()
    }

    pub async fn set_var(&mut self, key: &str, value: &str) -> bool {
        let resp = self.post(json!({
            "type": "setvar", "sessionToken": self.session_token,
            "key": key, "value": value
        })).await;
        resp.map(|r| r.success).unwrap_or(false)
    }

    pub async fn download_file(&mut self, file_id: &str) -> Option<Vec<u8>> {
        let resp = self.post(json!({
            "type": "file", "sessionToken": self.session_token, "fileId": file_id
        })).await;
        if let Some(r) = resp {
            if r.success {
                if let Some(data) = r.data {
                    let url = format!("{}{}",
                        self.api_url,
                        data["downloadUrl"].as_str().unwrap_or("")
                    );
                    if let Ok(resp) = self.client.get(&url).send().await {
                        return resp.bytes().await.ok().map(|b| b.to_vec());
                    }
                }
            }
        }
        None
    }

    pub async fn log(&mut self, message: &str) -> bool {
        let resp = self.post(json!({
            "type": "log", "sessionToken": self.session_token, "message": message
        })).await;
        resp.map(|r| r.success).unwrap_or(false)
    }

    pub fn get_hwid() -> String {
        let hostname = hostname::get()
            .unwrap_or_default()
            .to_string_lossy()
            .to_string();
        format!("HWID-{:X}", md5::compute(hostname.as_bytes()))
    }
}

Quick Start

src/main.rs
Rust
mod authon;
use authon::Authon;
use std::io::{self, Write};

const APP_ID: &str = "your-app-id";
const API_KEY: &str = "your-api-key";

#[tokio::main]
async fn main() {
    let mut auth = Authon::new(APP_ID, API_KEY);

    // Initialize
    println!("[*] Connecting...");
    if !auth.init().await {
        println!("[!] Failed: {}", auth.last_error);
        return;
    }
    println!("[+] Connected to {} v{}", auth.app.name, auth.app.version);

    // Login
    let hwid = Authon::get_hwid();
    print!("Username: ");
    io::stdout().flush().unwrap();
    let mut username = String::new();
    io::stdin().read_line(&mut username).unwrap();

    print!("Password: ");
    io::stdout().flush().unwrap();
    let mut password = String::new();
    io::stdin().read_line(&mut password).unwrap();

    if !auth.login(username.trim(), password.trim(), &hwid).await {
        println!("[!] Login failed: {}", auth.last_error);
        return;
    }

    println!("[+] Welcome {}!", auth.user.username);
    println!("    Level: {}", auth.user.level);
    println!("    Expires: {}", auth.user.expires_at);

    // Verify session
    if auth.check().await {
        println!("[+] Session verified.");
    }

    auth.log("User logged in from Rust app").await;
    println!("\nApplication ready!");
}

License-Only Authentication

License key validation
Rust
let mut auth = Authon::new(APP_ID, API_KEY);
auth.init().await;

let key = "AUTH-XXXX-XXXX-XXXX";
let hwid = Authon::get_hwid();

if auth.license(key, &hwid).await {
    println!("[+] License valid! Level: {}", auth.user.level);
    println!("    Expires: {}", auth.user.expires_at);
} else {
    println!("[!] Invalid: {}", auth.last_error);
}

Server Variables

Working with variables
Rust
// Get app-level variable
let download_url = auth.get_var("download_url").await;
let latest_version = auth.get_var("app_version").await;

// Set user-level variable
auth.set_var("theme", "dark").await;
auth.set_var("last_used", "2025-06-15").await;

println!("Download URL: {}", download_url);
println!("Latest version: {}", latest_version);

File Download

Download a protected file
Rust
use std::fs;

if let Some(bytes) = auth.download_file("your-file-id").await {
    fs::write("downloaded_module.bin", &bytes).unwrap();
    println!("[+] File downloaded ({} bytes)", bytes.len());
} else {
    println!("[!] Download failed: {}", auth.last_error);
}

Error Handling

Error handling pattern
Rust
if !auth.login(&username, &password, &hwid).await {
    let error = &auth.last_error;
    if error.contains("Invalid credentials") {
        println!("Wrong username or password");
    } else if error.contains("Hardware ID mismatch") {
        println!("This account is locked to another device");
    } else if error.contains("Account banned") {
        println!("Your account has been suspended");
    } else if error.contains("Subscription expired") {
        println!("Your subscription has expired");
    } else {
        println!("Error: {}", error);
    }
}

Notes

Rust Edition

Requires Rust 2021 edition. Compatible with stable Rust 1.63+.

Async Runtime

Uses tokio as the async runtime. The SDK methods are all async and must be awaited.

TLS Backend

reqwest uses native-tls by default (OpenSSL on Linux, Schannel on Windows). Add features = ["rustls-tls"] for a pure-Rust TLS implementation.

Binary Size

Use opt-level = "z" and lto = true in release profile to minimize output size.