use ai_cortex_sdk::{
verify_offline_license, CortexClient, CortexConfig, OfflineLicenseFile,
};
#[tokio::main]
async fn main() {
let server_url =
std::env::var("CORTEX_SERVER_URL").unwrap_or_else(|_| "http://localhost:40404".into());
let pat = std::env::args()
.nth(1)
.or_else(|| std::env::var("CORTEX_PAT").ok())
.unwrap_or_else(|| "REPLACE_WITH_YOUR_PAT".to_string());
let software_id = std::env::args()
.nth(2)
.or_else(|| std::env::var("CORTEX_SOFTWARE_ID").ok())
.unwrap_or_else(|| "00000000-0000-0000-0000-000000000000".to_string());
let pinned_pk = std::env::args().nth(3);
let config = CortexConfig::new(&server_url, &pat, &software_id)
.without_heartbeat();
let config = if let Some(pk) = &pinned_pk {
config.with_software_public_key(pk)
} else {
config
};
let client = CortexClient::new(config);
let dev = ai_cortex_sdk::device::collect();
let fingerprint = dev.fingerprint.as_str();
println!("Device fingerprint: {fingerprint}");
println!("\n=== Fetch offline license ===");
let file: OfflineLicenseFile = match client.fetch_offline_license(fingerprint).await {
Ok(f) => f,
Err(e) => {
eprintln!("fetch failed: {e}");
return;
}
};
println!("public_key: {}", file.public_key);
println!("signature : {}", file.signature);
println!("payload : {}", file.payload);
println!("\n=== Verify offline license ===");
match verify_offline_license(
&file,
&software_id,
fingerprint,
pinned_pk.as_deref(),
) {
Ok(payload) => {
println!("VALID. payload parsed:");
println!(" license_id : {}", payload.license_id);
println!(" user_id : {}", payload.user_id);
println!(" software_id : {}", payload.software_id);
println!(" fingerprint : {}", payload.fingerprint);
println!(" max_devices : {}", payload.max_devices);
println!(" issued_at : {}", payload.issued_at);
println!(" expire_time : {}", payload.expire_time);
}
Err(e) => {
eprintln!("INVALID license: {e}");
}
}
}