A Rust SDK for the Quilibrium Name Service (QNS), providing easy-to-use APIs for resolving and managing domain names on the Quilibrium network.
- Async and blocking API support
- Name resolution and reverse lookups
- Batch operations for efficient multi-name queries
- Subdomain management
- Domain availability checking
- Type-safe error handling
- Comprehensive validation
- Poseidon hash addressing (iden3 implementation) - Quilibrium uses Poseidon hashes for addresses
- No expiration - Names in Quilibrium do not expire once registered
Add this to your Cargo.toml:
[dependencies]
quilibrium-names-sdk = "2.1.0"For blocking-only usage:
[dependencies]
quilibrium-names-sdk = { version = "2.1.0", default-features = false, features = ["blocking"] }use quilibrium_names_sdk::non_blocking::QnsClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = QnsClient::default();
// Resolve a name
let record = client.resolve("example.q").await?;
println!("Owner: {}", record.header.owner);
// Batch resolve
let names = vec!["alice.q".to_string(), "bob.q".to_string()];
let records = client.resolve_batch(names).await?;
// Reverse lookup by key
let names = client.reverse_lookup("646964796f756576657268656172746865747261676564796f666461727468706c616775656973746865776973656974686f756768746e80").await?;
// Reverse lookup by address
let name = client.reverse_lookup("217369687420646e696620756f792064276572656877206e6f73206e6d616420").await?;
// Check availability
let available = client.is_available("newname.q").await?;
Ok(())
}use quilibrium_names_sdk::blocking::QnsClient;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = QnsClient::default();
// Resolve a name
let record = client.resolve("example.q")?;
println!("Owner: {}", record.header.owner);
// Get subdomains
let subdomains = client.get_subdomains("example.q")?;
Ok(())
}use quilibrium_names_sdk::{NameRecord, RecordType};
// Access record information
let record = client.resolve("example.q").await?;
println!("Full name: {}", record.full_name());
println!("Owner: {}", record.header.owner); // Poseidon hash address
println!("Created: {}", record.header.created_at);
println!("Updated: {}", record.header.updated_at);
// Note: Names in Quilibrium do not expireuse std::time::Duration;
// Custom endpoint with timeout
let client = QnsClient::with_timeout(
"https://custom-endpoint.example.com",
Duration::from_secs(10)
);use quilibrium_names_sdk::derivation::{
validate_name,
normalize_name,
parse_domain
};
// Validate a name
validate_name("example.q")?;
// Normalize (lowercase + trim)
let normalized = normalize_name(" EXAMPLE.Q ");
// Returns: "example.q"
// Parse domain into parts
let (subdomain, parent) = parse_domain("sub.example.q")?;
// subdomain: Some("sub")
// parent: "example.q"use quilibrium_names_sdk::record::{
serialize_record,
deserialize_record,
serialize_record_json,
deserialize_record_json,
};
// Borsh serialization (compact binary)
let bytes = serialize_record(&record)?;
let record = deserialize_record(&bytes)?;
// JSON serialization
let json = serialize_record_json(&record)?;
let record = deserialize_record_json(&json)?;The SDK provides comprehensive error types:
use quilibrium_names_sdk::QnsError;
match client.resolve("name.q").await {
Ok(record) => println!("Found: {}", record.authority_key),
Err(QnsError::NameNotFound(name)) => println!("{} not found", name),
Err(QnsError::InvalidName(msg)) => println!("Invalid name: {}", msg),
Err(QnsError::NetworkError(msg)) => println!("Network error: {}", msg),
Err(e) => println!("Other error: {}", e),
}See the examples/ directory for complete examples:
async_resolve.rs- Async API usageblocking_resolve.rs- Blocking API usage
Run examples with:
cargo run --example async_resolve
cargo run --example blocking_resolve --features blocking# Build with default features (async)
cargo build
# Build with blocking features
cargo build --features blocking
# Build with all features
cargo build --all-featurescargo testMIT
Contributions are welcome! Please feel free to submit a Pull Request.