High-level SDK for building applications on the Umbra protocol.
umbra-sdk provides a unified, developer-friendly interface to the Umbra ecosystem. It integrates all core components (networking, cryptography, identity, messaging) into a single, easy-to-use API for building secure, privacy-preserving applications.
- Simple Interface: High-level abstractions over complex protocols
- Async/Await: Modern Rust async programming
- Type Safety: Compile-time guarantees for security properties
- Comprehensive: Everything needed to build Umbra applications
- umbra-net: P2P networking with privacy features
- umbra-crypto: Post-quantum hybrid cryptography
- umbra-mls: Group messaging with MLS protocol
- umbra-zk: Zero-knowledge proofs and credentials
- umbra-vault: Secure key storage
- umbra-wire: Protocol message encoding
- Minimal boilerplate
- Sensible defaults
- Extensive examples
- Comprehensive documentation
Add to Cargo.toml:
[dependencies]
umbra-sdk = "0.1"
tokio = { version = "1", features = ["full"] }use umbra_sdk::{Umbra, UmbraConfig};
#[tokio::main]
async fn main() -> Result<()> {
// Initialize with default config
let config = UmbraConfig::default();
let umbra = Umbra::new(config).await?;
// Start network
umbra.start().await?;
// Create identity
let identity = umbra.create_identity().await?;
// Connect to peer
let peer = umbra.connect("peer_address").await?;
// Send message
umbra.send_message(peer, b"Hello, Umbra!").await?;
// Receive messages
while let Some(msg) = umbra.receive_message().await {
println!("Received: {:?}", msg);
}
Ok(())
}Main entry point for all operations:
use umbra_sdk::Umbra;
let umbra = Umbra::builder()
.with_storage_path("./umbra-data")
.with_network_config(network_config)
.with_privacy_mode(PrivacyMode::High)
.build()
.await?;// Create new identity
let identity = umbra.create_identity().await?;
// Add attributes for ZK proofs
identity.add_attribute("age", 25)?;
identity.add_attribute("country", "US")?;
// Generate proof
let proof = identity.prove_age_over(18).await?;
// Load existing identity
let identity = umbra.load_identity("my_identity").await?;// Send to peer
umbra.send_direct(peer_id, b"Private message").await?;
// Receive
let msg = umbra.receive_direct().await?;// Create group
let group = umbra.create_group("My Group").await?;
// Add members
group.add_member(peer_id).await?;
// Send to group
group.send(b"Hello, everyone!").await?;
// Receive
while let Some(msg) = group.receive().await {
println!("Group message: {:?}", msg);
}use umbra_sdk::PrivacyConfig;
// Configure privacy settings
let privacy = PrivacyConfig {
enable_cover_traffic: true,
enable_onion_routing: true,
circuit_length: 3,
timing_obfuscation: true,
metadata_resistance: true,
};
umbra.set_privacy_config(privacy)?;impl Umbra {
// Lifecycle
pub async fn new(config: UmbraConfig) -> Result<Self>;
pub async fn start(&self) -> Result<()>;
pub async fn stop(&self) -> Result<()>;
// Identity
pub async fn create_identity(&self) -> Result<Identity>;
pub async fn load_identity(&self, name: &str) -> Result<Identity>;
// Messaging
pub async fn send_message(&self, peer: PeerId, data: &[u8]) -> Result<()>;
pub async fn receive_message(&self) -> Option<Message>;
// Groups
pub async fn create_group(&self, name: &str) -> Result<Group>;
pub async fn join_group(&self, invite: &GroupInvite) -> Result<Group>;
// Network
pub async fn connect(&self, address: &str) -> Result<PeerId>;
pub async fn disconnect(&self, peer: PeerId) -> Result<()>;
pub fn peers(&self) -> Vec<PeerInfo>;
}pub struct UmbraConfig {
// Storage
pub storage_path: PathBuf,
// Network
pub listen_addresses: Vec<Multiaddr>,
pub bootstrap_peers: Vec<Multiaddr>,
// Privacy
pub privacy_mode: PrivacyMode,
pub enable_cover_traffic: bool,
pub circuit_length: usize,
// Performance
pub max_connections: usize,
pub connection_timeout: Duration,
}use umbra_sdk::{Umbra, UmbraConfig};
#[tokio::main]
async fn main() -> Result<()> {
let umbra = Umbra::new(UmbraConfig::default()).await?;
umbra.start().await?;
// Load or create identity
let identity = match umbra.load_identity("user").await {
Ok(id) => id,
Err(_) => umbra.create_identity().await?,
};
println!("Your peer ID: {}", umbra.peer_id());
// Accept messages in background
tokio::spawn(async move {
while let Some(msg) = umbra.receive_message().await {
println!("<< {}: {}", msg.from, String::from_utf8_lossy(&msg.data));
}
});
// Send messages from stdin
let mut input = String::new();
loop {
std::io::stdin().read_line(&mut input)?;
let parts: Vec<&str> = input.trim().split_whitespace().collect();
if parts.len() < 2 { continue; }
let peer_id = parts[0].parse()?;
let message = parts[1..].join(" ");
umbra.send_message(peer_id, message.as_bytes()).await?;
input.clear();
}
}// Create group with age requirement
let group = umbra.create_group("18+ Group").await?;
group.set_join_policy(JoinPolicy::RequireProof(
ProofRequirement::AgeOver(18)
))?;
// User generates proof to join
let proof = identity.prove_age_over(18).await?;
// Request to join with proof
let invite = group.request_join(proof).await?;
// Group automatically verifies proof and admits user// Create anonymous identity
let anon_id = umbra.create_anonymous_identity().await?;
// Join forum group
let forum = umbra.join_group(&forum_invite).await?;
// Post anonymously
forum.send_anonymous(anon_id, b"Anonymous message").await?;
// Messages are unlinkable to real identity- End-to-end encrypted chat
- Group messaging with forward secrecy
- Anonymous communication
- Metadata-resistant messaging
- P2P file sharing
- Distributed social networks
- Anonymous voting
- Collaborative tools
- Age verification without ID
- Anonymous credentials
- Privacy-preserving authentication
- Selective disclosure
SDK overhead is minimal:
| Operation | Time | Notes |
|---|---|---|
| Client initialization | ~100-500ms | One-time |
| Send message | ~1-10ms | Depends on privacy mode |
| Group message | ~5-20ms | Depends on group size |
| Create identity | ~50-200ms | One-time |
| ZK proof generation | ~100-500ms | Depends on circuit |
cargo build --release# Run all tests
cargo test
# Run integration tests
cargo test --test integration
# Run with logging
RUST_LOG=debug cargo test -- --nocapture# Run examples
cargo run --example chat
cargo run --example group_messaging
cargo run --example anonymous_forumuse umbra_sdk::Error;
match umbra.send_message(peer, data).await {
Ok(()) => println!("Sent!"),
Err(Error::PeerNotFound) => println!("Peer offline"),
Err(Error::NetworkError(e)) => eprintln!("Network error: {}", e),
Err(e) => eprintln!("Error: {}", e),
}// Graceful shutdown
tokio::select! {
_ = signal::ctrl_c() => {
println!("Shutting down...");
umbra.stop().await?;
}
}// High privacy (more latency, more cover traffic)
config.privacy_mode = PrivacyMode::High;
// Balanced (reasonable privacy, good performance)
config.privacy_mode = PrivacyMode::Balanced;
// Low privacy (faster, less overhead)
config.privacy_mode = PrivacyMode::Low;- Linux: Full support
- macOS: Full support
- Windows: Full support
- iOS: Experimental (via FFI)
- Android: Experimental (via FFI)
- WebAssembly: Planned
Umbra SDK follows Semantic Versioning:
- MAJOR: Breaking API changes
- MINOR: New features, backward compatible
- PATCH: Bug fixes
Contributions welcome! See CONTRIBUTING.md.
Report security issues to security@umbra.dev (if available) or via GitHub security advisories.
Licensed under Apache License 2.0 - see LICENSE.
Note: Individual components may use AGPL-3.0. Check component licenses for details.
- umbra-cli - Command-line interface
- umbra-net - Networking layer
- umbra-crypto - Cryptography
- umbra-identity - Zero-knowledge identity
- umbra-mls - Group messaging