Skip to content

Rust

quidnug, the official Rust crate for [Quidnug](https://github.com/bhmortim/quidnug), a decentralized protocol for relational, per-observer trust.

full cargo add quidnug clients/rust →

Quidnug Rust SDK

quidnug, the official Rust crate for Quidnug, a decentralized protocol for relational, per-observer trust.

Covers the full protocol surface: identity, trust, titles, event streams, anchors, guardian sets, recovery, cross-domain gossip, K-of-K bootstrap, fork-block activation, compact Merkle inclusion proofs (QDPs 0001–0010).

Install

Cargo.toml
[dependencies]
quidnug = "2"
tokio = { version = "1", features = ["full"] }

Requires Rust 1.74+.

Thirty-second example

use quidnug::{Client, Quid, TrustParams};
#[tokio::main]
async fn main() -> Result<(), quidnug::Error> {
let client = Client::new("http://localhost:8080")?;
let alice = Quid::generate();
let bob = Quid::generate();
client.register_identity(&alice, "Alice", "contractors.home").await?;
client.register_identity(&bob, "Bob", "contractors.home").await?;
client.grant_trust(&alice, TrustParams {
trustee: bob.id(),
level: 0.9,
domain: "contractors.home",
nonce: 1,
}).await?;
let tr = client.get_trust(alice.id(), bob.id(), "contractors.home", 5).await?;
println!("{:.3} via {:?}", tr.trust_level, tr.path);
Ok(())
}

Runnable examples live in examples/:

FileShows
quickstart.rsEnd-to-end two-party trust against a local node.
merkle_proof.rsOffline QDP-0010 proof verification.

What’s in the crate

ModuleContents
quidnug::ClientAsync HTTP client (reqwest under the hood).
quidnug::QuidECDSA P-256 keypair + signing + verification.
quidnug::canonical_bytesCanonical signable bytes (matches Go / Python byte-for-byte).
quidnug::verify_inclusion_proofQDP-0010 Merkle proof verifier.
quidnug::MerkleProofFrameProof frame (hash, side).
quidnug::{TrustResult, TrustEdge, Title, IdentityRecord, Event, ...}Wire types.
quidnug::{Error, Result}Structured error taxonomy + result alias.

Error taxonomy

match err {
Error::Validation(m) => eprintln!("bad input: {m}"),
Error::Conflict { code, .. } => eprintln!("node rejected: {code}"),
Error::Unavailable { .. } => eprintln!("retry later"),
Error::Node { status, .. } => eprintln!("HTTP {status}"),
Error::Crypto(m) => eprintln!("crypto: {m}"),
other => eprintln!("{other:?}"),
}

Features

FeaturePurpose
default = ["blocking"]Enable blocking HTTP (also requires tokio). Leave in if you don’t know you don’t need it.
rustlsSwap native TLS for rustls (pure Rust, better for static binaries).

Enable with cargo build --no-default-features --features rustls etc.

Canonicalization

use quidnug::canonical_bytes;
let tx = serde_json::json!({
"type": "TRUST", "truster": "a", "trustee": "b",
"trustLevel": 0.9, "nonce": 1, "trustDomain": "x",
"timestamp": 1_700_000_000_i64,
});
let bytes = canonical_bytes(&tx, &["signature", "txId"])?;

See schemas/types/canonicalization.md in the repo root for the cross-language specification.

Tests

Terminal window
cd clients/rust
cargo test

Integration tests use wiremock to stub node responses, so no running node is required.

License

Apache-2.0.