use nova_sdk_rs::{NovaSdk, NovaSdkConfig};
use std::env;
use std::error::Error;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let account_id = env::var("TEST_NOVA_ACCOUNT_ID")
.expect("TEST_NOVA_ACCOUNT_ID required (e.g., alice.nova-sdk.near)");
let session_token = env::var("TEST_SESSION_TOKEN")
.expect("TEST_SESSION_TOKEN required (get from nova-sdk.com/api/auth/session-token)");
let config = if account_id.contains("testnet") {
NovaSdkConfig {
rpc_url: "https://rpc.testnet.near.org".to_string(),
contract_id: "nova-sdk-5.testnet".to_string(),
mcp_url: "https://nova-mcp.fastmcp.app".to_string(),
}
} else {
NovaSdkConfig::default() };
let sdk = NovaSdk::with_config(&account_id, &session_token, config)?;
println!("đ§ SDK initialized");
println!(" Account: {}", sdk.account_id());
println!(" Contract: {}", sdk.contract_id());
println!(" Network: {}", sdk.network_id());
println!(" MCP: {}", sdk.mcp_url());
let group_id = "sdk_test_group_rs";
println!("\nđ Checking authentication...");
match sdk.auth_status(Some(group_id)).await {
Ok(status) => {
println!(" â
Authenticated: {}", status.authenticated);
if let Some(acc) = &status.near_account_id {
println!(" Account: {}", acc);
}
if let Some(auth) = status.authorized_for_group {
println!(" Authorized for {}: {}", group_id, auth);
}
}
Err(e) => {
println!(" â Auth failed: {}", e);
return Err(e.into());
}
}
println!("\nđ Ensuring group '{}' exists...", group_id);
match sdk.register_group(group_id).await {
Ok(msg) => println!(" â
{}", msg),
Err(e) => {
let err_str = e.to_string();
if err_str.contains("exists") || err_str.contains("already") || err_str.contains("registered") {
println!(" â ī¸ Group already exists (OK)");
} else {
println!(" â ī¸ Registration: {} (continuing anyway)", e);
}
}
}
let test_data = b"Hello from NOVA SDK Rust v1.0! \xF0\x9F\x94\x90 Client-side encrypted on IPFS.";
let filename = "hello_sdk_test_rs.txt";
println!("\nđ¤ Uploading file (client-side encryption)...");
println!(" Filename: {}", filename);
println!(" Data: {} bytes", test_data.len());
println!(" Preview: \"{}\"",
String::from_utf8_lossy(&test_data[..std::cmp::min(50, test_data.len())]));
let start = std::time::Instant::now();
let upload_result = sdk.upload(group_id, test_data, filename).await?;
let elapsed = start.elapsed();
println!("\nâ
Upload successful! ({:.2}s)", elapsed.as_secs_f64());
println!(" CID: {}", upload_result.cid);
println!(" Transaction ID: {}", upload_result.trans_id);
println!(" File Hash: {}", upload_result.file_hash);
println!("\nđĨ Retrieving file from CID: {}", upload_result.cid);
let start = std::time::Instant::now();
let retrieve_result = sdk.retrieve(group_id, &upload_result.cid).await?;
let elapsed = start.elapsed();
println!("\nâ
Retrieve successful! ({:.2}s)", elapsed.as_secs_f64());
println!(" Data: {} bytes", retrieve_result.data.len());
println!(" IPFS Hash: {}", retrieve_result.ipfs_hash);
println!(" Group: {}", retrieve_result.group_id);
println!("\nđ Verifying data integrity...");
if retrieve_result.data == test_data {
println!(" â
Data matches! Client-side encryption/decryption successful.");
println!(" Retrieved: \"{}\"", String::from_utf8_lossy(&retrieve_result.data));
} else {
println!(" â Data mismatch!");
println!(" Original length: {}", test_data.len());
println!(" Retrieved length: {}", retrieve_result.data.len());
return Err("Data integrity check failed".into());
}
let computed_hash = NovaSdk::compute_hash(&retrieve_result.data);
println!("\n Computed hash: {}", computed_hash);
println!(" Uploaded hash: {}", upload_result.file_hash);
if computed_hash == upload_result.file_hash {
println!(" â
Hash verified!");
} else {
println!(" â ī¸ Hash mismatch");
}
println!("\nđ Transaction history for group '{}':", group_id);
match sdk.get_transactions_for_group(group_id, None).await {
Ok(txs) => {
println!(" Found {} transaction(s)", txs.len());
for (i, tx) in txs.iter().take(3).enumerate() {
println!(" [{}] IPFS: {}... | Hash: {}...",
i + 1,
&tx.ipfs_hash[..20.min(tx.ipfs_hash.len())],
&tx.file_hash[..16]
);
}
if txs.len() > 3 {
println!(" ... and {} more", txs.len() - 3);
}
}
Err(e) => println!(" Could not fetch transactions: {}", e),
}
println!("\nđ SDK test complete!");
println!("\nđ Summary:");
println!(" â
Authentication working");
println!(" â
Client-side encryption (AES-256-GCM)");
println!(" â
IPFS upload via MCP");
println!(" â
NEAR transaction recording");
println!(" â
Client-side decryption");
println!(" â
Data integrity verified");
println!("\nâšī¸ Your file is now:");
println!(" - Encrypted locally (key never sent with data)");
println!(" - Stored on IPFS: {}", upload_result.cid);
println!(" - Recorded on NEAR: {}", upload_result.trans_id);
Ok(())
}