SDK Quickstart

This guide walks through the core dregg-sdk APIs: creating a cipherclerk, minting tokens, attenuating and delegating, generating STARK proofs, and signing turns. All code examples use real API signatures from the codebase.

Creating a Cipherclerk

The AgentCipherclerk is the primary credential holder. It manages your Ed25519 identity, token collection, and proof generation.

use dregg_sdk::AgentCipherclerk;

// Option 1: Fresh random identity
let mut cclerk = AgentCipherclerk::new();

// Option 2: From a 24-word mnemonic (deterministic, recoverable)
let mut cclerk = AgentCipherclerk::from_mnemonic(
    "abandon abandon abandon ... (24 words)",
    ""  // optional passphrase
).unwrap();

// Option 3: From raw key bytes (restore from backup)
use zeroize::Zeroizing;
let secret = Zeroizing::new([0u8; 32]); // your saved key
let mut cclerk = AgentCipherclerk::from_key_bytes(secret);

// Get your public identity
let my_identity = cclerk.public_key();
println!("Agent ID: {:?}", my_identity);

Minting a Root Token

Root tokens are the origin of all authority. Mint one with a 32-byte secret key and a service name:

pub fn mint_token(&mut self, root_key: &[u8; 32], service: &str) -> HeldToken
use dregg_sdk::AgentCipherclerk;

let mut cclerk = AgentCipherclerk::new();

// The root_key is your HMAC secret. Guard it carefully.
let root_key: [u8; 32] = *b"my-secret-root-key-32-bytes!!!!!";
let root_token = cclerk.mint_token(&root_key, "my-service");

println!("Token: {} (service: {})", root_token.label, root_token.service);
assert!(root_token.can_mint()); // Root tokens can forge new ones

Attenuating (Restricting) a Token

Attenuation creates a strictly weaker token. The original remains unchanged.

pub fn attenuate(&mut self, token: &HeldToken, restrictions: &Attenuation) -> Result<HeldToken, SdkError>
use dregg_sdk::{AgentCipherclerk, Attenuation};

let mut cclerk = AgentCipherclerk::new();
let root = cclerk.mint_token(b"my-secret-root-key-32-bytes!!!!!", "api");

// Restrict to read-only on the "dns" service
let restricted = cclerk.attenuate(&root, &Attenuation {
    services: vec![("dns".into(), "r".into())],
    ..Default::default()
}).unwrap();

assert!(!restricted.can_mint()); // Attenuated tokens cannot forge

Delegating to Another Agent

Delegation attenuates a token and packages it for transmission to another agent.

pub fn delegate(&mut self, token: &HeldToken, to: &PublicKey, restrictions: &Attenuation) -> Result<DelegatedToken, SdkError>
use dregg_sdk::{AgentCipherclerk, Attenuation, PublicKey};

let mut alice = AgentCipherclerk::new();
let mut bob = AgentCipherclerk::new();

let root = alice.mint_token(b"alice-secret-key-32-bytes!!!!!!!", "storage");

// Alice delegates read-only to Bob
let delegated = alice.delegate(&root, &bob.public_key(), &Attenuation {
    services: vec![("storage".into(), "read".into())],
    max_ttl: Some(std::time::Duration::from_secs(3600)),
    ..Default::default()
}).unwrap();

// Bob receives the signed delegation envelope. He must declare the authority
// policy (which delegator key he trusts for this envelope) -- the SDK refuses
// to consume untrusted envelopes silently.
bob.receive_signed_delegation(
    delegated,
    &DelegationAuthority::TrustedKey(alice.public_key()),
).unwrap();

Generating Authorization Proofs

The unified authorize() method supports all three verification modes:

pub fn authorize(&self, token: &HeldToken, request: &AuthRequest, mode: VerificationMode) -> Result<AuthorizationPresentation, SdkError>
use dregg_sdk::{AgentCipherclerk, VerificationMode, AuthorizationPresentation, AuthRequest};

let mut cclerk = AgentCipherclerk::new();
let token = cclerk.mint_token(b"my-secret-root-key-32-bytes!!!!!", "dns");

let request = AuthRequest {
    service: Some("dns".into()),
    action: Some("read".into()),
    ..Default::default()
};

// Trusted mode: full visibility, ~8us
let trusted = cclerk.authorize(&token, &request, VerificationMode::Trusted).unwrap();

// Fully private: verifier learns only allow/deny, ~500ms
let private = cclerk.authorize(&token, &request, VerificationMode::FullyPrivate).unwrap();

match private {
    AuthorizationPresentation::Private { proof, conclusion } => {
        println!("Authorized: {}", conclusion);
        println!("Proof size: {} bytes", proof.len());
    }
    _ => unreachable!(),
}

Signing Turns

Turns are atomic state transitions. Sign one for submission to a federation node:

pub fn sign_turn(&self, turn: &Turn) -> SignedTurn
use dregg_sdk::{AgentCipherclerk, CellId, Turn, TurnBuilder, Effect};

let cclerk = AgentCipherclerk::new();

// Build a turn targeting a cell
let turn = TurnBuilder::new()
    .target(CellId::derive_raw(&cclerk.public_key().0, b"my-domain-hash-here-32bytes!"))
    .effect(Effect::SetField { key: "counter".into(), value: 42 })
    .build();

let signed = cclerk.sign_turn(&turn);
// Submit signed.turn + signed.signature + signed.signer to the node
State diff — balance, nonce, notes, capabilities before and after a turn.

One turn moves 120 units of value into a fresh note. Balance drops, nonce advances, the note count climbs, the capability list is untouched. The conservation constraint forces the deltas to sum to zero on the value side.

Receipt Chains (Proof-Carrying State)

After each successful turn, append the receipt to build a verifiable history:

use dregg_sdk::AgentCipherclerk;
use dregg_turn::TurnReceipt;

let mut cclerk = AgentCipherclerk::new();

// After a turn is committed by the federation:
// cclerk.append_receipt(receipt);

// Verify your own chain integrity
cclerk.verify_own_chain().unwrap();

// Export for anyone to verify offline
let chain = cclerk.receipt_chain();
dregg_turn::verify_receipt_chain(chain).unwrap();

IVC (Constant-Size State Proof)

Enable IVC to compress your entire receipt chain into a constant-size proof:

use dregg_sdk::{AgentCipherclerk, BabyBear, verify_ivc};

let mut cclerk = AgentCipherclerk::new();

// Enable IVC accumulation (provide initial state root)
cclerk.enable_ivc(BabyBear::new(0));

// ... append receipts as turns commit ...

// Export a constant-size proof of your entire history
if let Some(proof) = cclerk.export_state_proof() {
    // Anyone can verify this without seeing the full chain
    assert!(verify_ivc(&proof));
}

Sovereign Cell Operations

These APIs let you take ownership of your cell state and interact directly with peers, bypassing the federation entirely for routine operations.

Taking Sovereignty

pub fn make_sovereign(&mut self) -> Result<SovereignCell, SdkError>
// Transition your cell from hosted to sovereign mode.
// After this, the federation stores only your 32-byte commitment hash.
// You maintain full state locally and submit proofs of valid transitions.
let sovereign = cclerk.make_sovereign().unwrap();
println!("Commitment: {:?}", sovereign.commitment());

Private Transfers

pub fn private_transfer(&mut self, amount: u64, recipient: &StealthAddress) -> Result<PrivateTransferProof, SdkError>
// Amount-private send using Pedersen commitments.
// The federation sees: a nullifier (double-spend check), a new note commitment,
// and a conservation proof. It does NOT see the amount or recipient.
let stealth_addr = bob_cclerk.stealth_meta_address();
let proof = cclerk.private_transfer(1000, &stealth_addr).unwrap();

Stealth Receiving

pub fn stealth_meta_address(&self) -> StealthAddress
// Generate your stealth meta-address for receiving privately.
// Senders derive a one-time address from this; only you can detect and spend.
let my_stealth = cclerk.stealth_meta_address();
// Share my_stealth with potential senders

Peer-to-Peer Sessions

pub fn peer_exchange_session(&mut self, peer: &PublicKey) -> Result<PeerSession, SdkError>
// Open a direct agent-to-agent session. No federation contact.
// Both parties exchange signed state transitions with STARK proofs.
let session = cclerk.peer_exchange_session(&bob_pubkey).unwrap();

// Send a state transition directly to Bob
session.send_transition(my_transition, my_proof).await?;

// Receive and verify Bob's transition
let bob_transition = session.receive_transition().await?;
// Bob's proof is verified automatically -- you learn his new commitment

Next Steps