A comprehensive collection of Rust components for creating AT Protocol applications. This workspace provides essential building blocks for content-addressed data, identity management, repository operations, record signing, OAuth 2.0 authentication flows, HTTP client operations, XRPC services, and real-time event streaming.
Origin: Parts of this project were extracted from the open-source smokesignal.events project, an AT Protocol event and RSVP management application. This library is released under the MIT license to enable broader AT Protocol ecosystem development.
This workspace contains 15 specialized crates that work together to provide complete AT Protocol application development capabilities:
atproto-dasl- DASL (Data-Addressed Structures & Links) framework implementing CID computation, DRISL (deterministic DAG-CBOR encoding), CAR v1 archives, block storage backends, RASL retrieval, BDASL large file hashing, and Web Tiles. Includes 1 CLI tool.
atproto-identity- Core identity management with multi-method DID resolution (plc, web, key), DNS/HTTP handle resolution, PLC directory operations, and P-256/P-384/K-256 cryptographic operations. Includes 6 CLI tools.atproto-attestation- CID-first attestation utilities for creating and verifying cryptographic signatures on AT Protocol records, supporting both inline and remote attestation workflows. Includes 2 CLI tools.atproto-record- Record utilities including TID generation, AT-URI parsing, datetime formatting, and CID generation using IPLD DAG-CBOR serialization. Includes 1 CLI tool.atproto-lexicon- Lexicon schema resolution and validation for AT Protocol, supporting recursive resolution, NSID validation, and DNS-based lexicon discovery. Includes 1 CLI tool.
atproto-repo- AT Protocol repository handling with Merkle Search Tree (MST) encoding/decoding, commit structures, tree diffing for sync, and configurable verification. Builds onatproto-daslfor CAR and storage. Includes 2 CLI tools.
atproto-oauth- Complete OAuth 2.0 implementation with AT Protocol security extensions including DPoP (RFC 9449), PKCE (RFC 7636), JWT operations, and secure storage abstractions. Includes 1 CLI tool.atproto-oauth-aip- OAuth AIP (Identity Provider) implementation providing complete authorization code flow with PAR, token exchange, and AT Protocol session management.atproto-oauth-axum- Production-ready Axum web handlers for OAuth endpoints including authorization callbacks, JWKS endpoints, and client metadata. Includes 1 CLI tool.
atproto-client- HTTP client library supporting multiple authentication methods (DPoP, Bearer tokens, sessions) with native XRPC protocol operations and repository management. Includes 4 CLI tools.atproto-xrpcs- XRPC service framework providing JWT authorization extractors, DID resolution integration, and Axum middleware for building AT Protocol services.atproto-xrpcs-helloworld- Complete example XRPC service demonstrating DID:web identity, service document generation, and JWT authentication patterns. Includes 1 service binary.
atproto-jetstream- WebSocket consumer for AT Protocol Jetstream events with Zstandard compression, automatic reconnection, and configurable event filtering. Includes 1 CLI tool.atproto-tap- TAP (Trusted Attestation Protocol) service consumer for filtered, verified AT Protocol repository events with MST integrity checks, automatic backfill, and acknowledgment-based delivery. Includes 2 CLI tools.
atproto-extras- Facet parsing and rich text utilities for AT Protocol, extracting mentions, URLs, and hashtags from plain text with correct UTF-8 byte offset calculation. Includes 1 CLI tool.
Add the crates to your Cargo.toml:
[dependencies]
atproto-dasl = "0.14.0"
atproto-identity = "0.14.0"
atproto-attestation = "0.14.0"
atproto-record = "0.14.0"
atproto-repo = "0.14.0"
atproto-lexicon = "0.14.0"
atproto-oauth = "0.14.0"
atproto-oauth-aip = "0.14.0"
atproto-client = "0.14.0"
atproto-extras = "0.14.0"
atproto-tap = "0.14.0"
# Add others as neededuse atproto_identity::resolve::{resolve_subject, create_resolver};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let http_client = reqwest::Client::new();
let dns_resolver = create_resolver(&[]);
let did = resolve_subject(&http_client, &dns_resolver, "alice.bsky.social").await?;
println!("Resolved DID: {}", did);
Ok(())
}use atproto_lexicon::resolve::{DefaultLexiconResolver, LexiconResolver};
use atproto_identity::resolve::HickoryDnsResolver;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let http_client = reqwest::Client::new();
let dns_resolver = HickoryDnsResolver::create_resolver(&[]);
let resolver = DefaultLexiconResolver::new(http_client, dns_resolver);
// Resolve a lexicon schema
let lexicon = resolver.resolve("app.bsky.feed.post").await?;
println!("Lexicon schema: {}", serde_json::to_string_pretty(&lexicon)?);
Ok(())
}use atproto_attestation::{create_inline_attestation, AnyInput};
use atproto_identity::key::{generate_key, KeyType};
use serde_json::json;
fn main() -> anyhow::Result<()> {
let key = generate_key(KeyType::P256Private)?;
let record = json!({
"$type": "app.bsky.feed.post",
"text": "Hello AT Protocol!",
"createdAt": "2024-01-01T00:00:00.000Z"
});
let metadata = json!({
"$type": "com.example.inlineSignature",
"key": "did:key:...",
"issuer": "did:plc:issuer123",
"issuedAt": "2024-01-01T00:00:00.000Z"
});
let signed_record = create_inline_attestation(
AnyInput::Serialize(record),
AnyInput::Serialize(metadata),
"did:plc:repo123",
&key
)?;
println!("Signed record: {}", serde_json::to_string_pretty(&signed_record)?);
Ok(())
}use atproto_xrpcs::authorization::Authorization;
use axum::{Json, Router, extract::Query, routing::get};
use serde::Deserialize;
use serde_json::json;
#[derive(Deserialize)]
struct HelloParams {
subject: Option<String>,
}
async fn handle_hello(
params: Query<HelloParams>,
authorization: Option<Authorization>,
) -> Json<serde_json::Value> {
let subject = params.subject.as_deref().unwrap_or("World");
let message = if let Some(auth) = authorization {
format!("Hello, authenticated {}! (caller: {})", subject, auth.subject())
} else {
format!("Hello, {}!", subject)
};
Json(json!({ "message": message }))
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let app = Router::new()
.route("/xrpc/com.example.hello", get(handle_hello))
.with_state(your_web_context);
let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await?;
axum::serve(listener, app).await?;
Ok(())
}use atproto_oauth_aip::workflow::{oauth_init, oauth_complete, session_exchange, OAuthClient};
use atproto_oauth::workflow::OAuthRequestState;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let http_client = reqwest::Client::new();
let oauth_client = OAuthClient {
redirect_uri: "https://your-app.com/callback".to_string(),
client_id: "your-client-id".to_string(),
client_secret: "your-client-secret".to_string(),
};
let oauth_request_state = OAuthRequestState {
state: "random-state".to_string(),
nonce: "random-nonce".to_string(),
code_challenge: "code-challenge".to_string(),
scope: "atproto transition:generic".to_string(),
};
// 1. Start OAuth flow with Pushed Authorization Request
let par_response = oauth_init(
&http_client,
&oauth_client,
Some("alice.bsky.social"),
"https://auth-server.example.com/par",
&oauth_request_state,
).await?;
println!("PAR request URI: {}", par_response.request_uri);
// 2. After user authorizes and returns with a code, exchange it for tokens
let token_response = oauth_complete(
&http_client,
&oauth_client,
"https://auth-server.example.com/token",
"received-auth-code",
&oauth_request, // OAuthRequest from your stored state
).await?;
// 3. Exchange token for AT Protocol session
let session = session_exchange(
&http_client,
"https://pds.example.com",
&token_response.access_token,
).await?;
println!("Authenticated as: {} ({})", session.handle, session.did);
Ok(())
}The workspace includes 23 command-line tools across 11 crates, providing ready-to-use utilities for AT Protocol development and testing. Most CLI tools require the clap feature:
# Build with CLI support
cargo build --features clap --bins
# DASL operations (atproto-dasl crate)
cargo run --package atproto-dasl --features clap --bin atproto-dasl -- --help
# Identity operations (atproto-identity crate)
cargo run --features clap,hickory-dns --bin atproto-identity-resolve -- alice.bsky.social
cargo run --features clap --bin atproto-identity-key -- generate p256
cargo run --features clap --bin atproto-identity-sign -- did:key:... data.json
cargo run --features clap --bin atproto-identity-validate -- did:key:... data.json signature
cargo run --features clap,hickory-dns --bin atproto-identity-plc-audit -- did:plc:...
cargo run --features clap,hickory-dns --bin atproto-identity-plc-fork-viz -- did:plc:...
# Attestation operations (atproto-attestation crate)
cargo run --package atproto-attestation --features clap,tokio --bin atproto-attestation-sign -- inline record.json did:key:... metadata.json
cargo run --package atproto-attestation --features clap,tokio --bin atproto-attestation-verify -- signed_record.json
# Record operations (atproto-record crate)
cat record.json | cargo run --features clap --bin atproto-record-cid
# Repository operations (atproto-repo crate)
cargo run --package atproto-repo --features clap --bin atproto-repo-car -- ls repo.car
cargo run --package atproto-repo --features clap --bin atproto-repo-mst -- ls repo.car
# Lexicon operations (atproto-lexicon crate)
cargo run --features clap,hickory-dns --bin atproto-lexicon-resolve -- app.bsky.feed.post
# Client operations (atproto-client crate)
cargo run --features clap --bin atproto-client-auth -- login alice.bsky.social password123
cargo run --features clap --bin atproto-client-app-password -- alice.bsky.social access_token /xrpc/com.atproto.repo.listRecords
cargo run --features clap --bin atproto-client-dpop -- alice.bsky.social did:key:... access_token /xrpc/com.atproto.repo.listRecords
cargo run --features clap --bin atproto-client-put-record -- --help
# OAuth operations (atproto-oauth crate)
cargo run --package atproto-oauth --features clap --bin atproto-oauth-service-token -- --help
# OAuth operations (atproto-oauth-axum crate)
cargo run --package atproto-oauth-axum --features clap --bin atproto-oauth-tool -- login did:key:... alice.bsky.social
# XRPC service (atproto-xrpcs-helloworld crate)
cargo run --bin atproto-xrpcs-helloworld
# Event streaming (atproto-jetstream crate)
cargo run --features clap --bin atproto-jetstream-consumer -- jetstream1.us-east.bsky.network dictionary.zstd
# TAP service consumer (atproto-tap crate)
cargo run --package atproto-tap --features clap --bin atproto-tap-client -- --help
cargo run --package atproto-tap --features clap --bin atproto-tap-extras -- --help
# Rich text utilities (atproto-extras crate)
cargo run --package atproto-extras --features clap,cli,hickory-dns --bin atproto-extras-parse-facets -- "Hello @alice.bsky.social"# Build all crates
cargo build
# Run all tests
cargo test
# Format and lint
cargo fmt && cargo clippy
# Generate documentation
cargo doc --workspace --openThis project is licensed under the MIT License - see the LICENSE file for details.
These components are designed to work together as building blocks for AT Protocol applications:
- Data Foundation Layer:
atproto-daslprovides CID computation, deterministic DAG-CBOR encoding, CAR v1 archives, and pluggable block storage - Identity Layer:
atproto-identityprovides the foundation for DID resolution and cryptographic operations - Repository Layer:
atproto-repoprovides Merkle Search Tree operations, commit structures, and repository handling - Data Layer:
atproto-recordandatproto-attestationhandle record operations, CID generation, and cryptographic attestations - Schema Layer:
atproto-lexiconprovides lexicon resolution and validation for AT Protocol schemas - Authentication Layer:
atproto-oauth*crates handle complete OAuth 2.0 flows with AT Protocol security extensions - Application Layer:
atproto-clientandatproto-xrpcs*enable client applications and service development - Event Layer:
atproto-jetstreamandatproto-tapprovide real-time event processing capabilities - Utilities Layer:
atproto-extrasprovides rich text facet parsing for AT Protocol applications
This workspace enables development of:
- AT Protocol Identity Providers (AIPs) - Complete OAuth servers with DID-based authentication
- Personal Data Servers (PDS) - XRPC services with JWT authorization and repository management
- AT Protocol Clients - Applications that authenticate and interact with AT Protocol services
- Event Processing Systems - Real-time processors for AT Protocol repository events via Jetstream or TAP
- Repository Tools - CAR file inspection, MST analysis, and repository verification utilities
- Development Tools - CLI utilities for testing, debugging, and managing AT Protocol identities
Contributions are welcome! This project follows standard Rust development practices:
- Fork this repository
- Create a feature branch
- Run tests:
cargo test - Run linting:
cargo fmt && cargo clippy - Submit a pull request
Parts of this project were extracted from the smokesignal.events project, an open-source AT Protocol event and RSVP management application. This extraction enables broader community use and contribution to AT Protocol tooling in Rust.