this repo has no description
Rust 99.8%
Dockerfile 0.2%
6 1 1

Clone this repository

https://tangled.org/ngerakines.me/atproto-crates https://tangled.org/did:plc:cbkjy5n7bk3ax2wplmtjofq2/atproto-crates
git@tangled.org:ngerakines.me/atproto-crates git@tangled.org:did:plc:cbkjy5n7bk3ax2wplmtjofq2/atproto-crates

For self-hosted knots, clone URLs may differ based on your setup.

Download tar.gz
README.md

AT Protocol Rust Crates#

A Rust workspace of crates for building AT Protocol applications. This collection provides building blocks for content-addressed data, identity management, repository operations, record signing, OAuth 2.0 authentication flows, HTTP client operations, XRPC services, real-time event streaming, and developer tooling.

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.

Components#

This workspace contains 17 crates that work together to provide complete AT Protocol application development capabilities:

Data Foundations#

  • 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.

Identity & Cryptography#

  • 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 2 CLI tools.
  • atproto-lexicon - Lexicon schema resolution and validation for AT Protocol, supporting recursive resolution, NSID validation, and DNS-based lexicon discovery. Includes 1 CLI tool.

Repository#

  • atproto-repo - AT Protocol repository handling with Merkle Search Tree (MST) encoding/decoding, commit structures, tree diffing for sync, and configurable verification. Builds on atproto-dasl for CAR and storage. Includes 2 CLI tools.

Authentication & Authorization#

  • 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.

Client & Service Development#

  • 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.
  • atpxrpc - XRPC CLI client with persistent session management for making authenticated AT Protocol API calls. Includes 1 CLI tool.

Real-time Event Processing#

  • 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.

Developer Tools#

  • atpmcp - MCP (Model Context Protocol) server for AT Protocol DAG-CBOR CID generation, enabling AI assistants to compute content identifiers for records. Includes 1 server binary.

Utilities#

  • 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.

Quick Start#

Add the crates to your Cargo.toml:

[dependencies]
atproto-dasl = "0.14.2"
atproto-identity = "0.14.2"
atproto-attestation = "0.14.2"
atproto-record = "0.14.2"
atproto-repo = "0.14.2"
atproto-lexicon = "0.14.2"
atproto-oauth = "0.14.2"
atproto-oauth-aip = "0.14.2"
atproto-client = "0.14.2"
atproto-extras = "0.14.2"
atproto-tap = "0.14.2"
# Add others as needed

Basic Identity Resolution#

use 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(())
}

Lexicon Resolution#

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(())
}

Record Signing#

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(())
}

XRPC Service#

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(())
}

OAuth Client Flow#

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(())
}

Command Line Tools#

The workspace includes command-line tools and server binaries across the 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 atpcid -- '{"text":"hello"}'

# 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
cargo run --package atproto-record --features clap --bin atptid
cargo run --package atproto-record --features clap --bin atptid -- -n 5

# 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"

# XRPC CLI client (atpxrpc crate)
cargo run --package atpxrpc --bin atpxrpc -- --help

# MCP server (atpmcp crate)
cargo build -p atpmcp

Development#

# Build all crates
cargo build

# Run all tests
cargo test

# Format and lint
cargo fmt && cargo clippy

# Generate documentation
cargo doc --workspace --open

License#

This project is licensed under the MIT License - see the LICENSE file for details.

Architecture#

These components are designed to work together as building blocks for AT Protocol applications:

  • Data Foundation Layer: atproto-dasl provides CID computation, deterministic DAG-CBOR encoding, CAR v1 archives, and pluggable block storage
  • Identity Layer: atproto-identity provides the foundation for DID resolution and cryptographic operations
  • Repository Layer: atproto-repo provides Merkle Search Tree operations, commit structures, and repository handling
  • Data Layer: atproto-record and atproto-attestation handle record operations, CID generation, and cryptographic attestations
  • Schema Layer: atproto-lexicon provides 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-client and atproto-xrpcs* enable client applications and service development
  • Event Layer: atproto-jetstream and atproto-tap provide real-time event processing capabilities
  • Utilities Layer: atproto-extras provides rich text facet parsing for AT Protocol applications

Use Cases#

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

Contributing#

Contributions are welcome! This project follows standard Rust development practices:

  1. Fork this repository
  2. Create a feature branch
  3. Run tests: cargo test
  4. Run linting: cargo fmt && cargo clippy
  5. Submit a pull request

Acknowledgments#

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.