A library for ATProtocol identities.
22
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v0.9.1 229 lines 7.7 kB view raw view rendered
1# atproto-identity-rs 2 3A comprehensive collection of Rust crates for building AT Protocol applications. This workspace provides identity management, record operations, OAuth 2.0 flows, HTTP client operations, XRPC services, and event streaming capabilities. 4 5**Note**: This project contains components extracted from the open-source [smokesignal.events](https://tangled.sh/@smokesignal.events/smokesignal) project, an AT Protocol event and RSVP management application. This library is released under the MIT license. 6 7## Components 8 9### Core Libraries 10 11- **[`atproto-identity`](crates/atproto-identity/)** - Identity management with DID resolution and cryptographic operations. Includes 4 CLI tools for identity resolution, key management, signing, and validation. 12- **[`atproto-record`](crates/atproto-record/)** - AT Protocol record signature operations. Includes 2 CLI tools for signing and verifying records. 13- **[`atproto-oauth`](crates/atproto-oauth/)** - OAuth 2.0 implementation with AT Protocol security extensions including PKCE, DPoP, and JWT operations. 14- **[`atproto-oauth-aip`](crates/atproto-oauth-aip/)** - AT Protocol Identity Provider (AIP) OAuth workflow implementation for client applications. 15- **[`atproto-client`](crates/atproto-client/)** - HTTP client with DPoP authentication and repository operations. Includes 3 CLI tools for client authentication testing. 16 17### Web Framework Integration 18 19- **[`atproto-oauth-axum`](crates/atproto-oauth-axum/)** - Axum web handlers for OAuth endpoints. Includes 1 CLI tool for OAuth client testing. 20- **[`atproto-xrpcs`](crates/atproto-xrpcs/)** - XRPC service components with JWT authorization extractors. 21- **[`atproto-xrpcs-helloworld`](crates/atproto-xrpcs-helloworld/)** - Example XRPC service implementation with DID web support. 22 23### Event Streaming 24 25- **[`atproto-jetstream`](crates/atproto-jetstream/)** - WebSocket event stream consumer with compression support. Includes 1 CLI tool for event consumption. 26 27## Quick Start 28 29Add the crates to your `Cargo.toml`: 30 31```toml 32[dependencies] 33atproto-identity = "0.9.1" 34atproto-record = "0.9.1" 35atproto-oauth = "0.9.1" 36atproto-oauth-aip = "0.9.1" 37atproto-client = "0.9.1" 38# Add others as needed 39``` 40 41### Basic Identity Resolution 42 43```rust 44use atproto_identity::resolve::{resolve_subject, create_resolver}; 45 46#[tokio::main] 47async fn main() -> anyhow::Result<()> { 48 let http_client = reqwest::Client::new(); 49 let dns_resolver = create_resolver(&[]); 50 51 let did = resolve_subject(&http_client, &dns_resolver, "alice.bsky.social").await?; 52 println!("Resolved DID: {}", did); 53 54 Ok(()) 55} 56``` 57 58### Record Signing 59 60```rust 61use atproto_identity::key::identify_key; 62use atproto_record::signature; 63use serde_json::json; 64 65#[tokio::main] 66async fn main() -> anyhow::Result<()> { 67 let signing_key = identify_key("did:key:zQ3shNzMp4oaaQ1gQRzCxMGXFrSW3NEM1M9T6KCY9eA7HhyEA")?; 68 69 let record = json!({ 70 "$type": "app.bsky.feed.post", 71 "text": "Hello AT Protocol!", 72 "createdAt": "2024-01-01T00:00:00.000Z" 73 }); 74 75 let signature_object = json!({ 76 "issuer": "did:plc:issuer123", 77 "issuedAt": "2024-01-01T00:00:00.000Z" 78 }); 79 80 let signed_record = signature::create( 81 &signing_key, 82 &record, 83 "did:plc:user123", 84 "app.bsky.feed.post", 85 signature_object, 86 ).await?; 87 88 Ok(()) 89} 90``` 91 92### XRPC Service 93 94```rust 95use atproto_xrpcs::authorization::ResolvingAuthorization; 96use axum::{Json, Router, extract::Query, routing::get}; 97use serde::Deserialize; 98use serde_json::json; 99 100#[derive(Deserialize)] 101struct HelloParams { 102 subject: Option<String>, 103} 104 105async fn handle_hello( 106 params: Query<HelloParams>, 107 authorization: Option<ResolvingAuthorization>, 108) -> Json<serde_json::Value> { 109 let subject = params.subject.as_deref().unwrap_or("World"); 110 111 let message = if let Some(auth) = authorization { 112 format!("Hello, authenticated {}! (caller: {})", subject, auth.subject()) 113 } else { 114 format!("Hello, {}!", subject) 115 }; 116 117 Json(json!({ "message": message })) 118} 119 120#[tokio::main] 121async fn main() -> anyhow::Result<()> { 122 let app = Router::new() 123 .route("/xrpc/com.example.hello", get(handle_hello)) 124 .with_state(your_web_context); 125 126 let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await?; 127 axum::serve(listener, app).await?; 128 129 Ok(()) 130} 131``` 132 133### OAuth Client Flow 134 135```rust 136use atproto_oauth_aip::{OAuthClient, oauth_init, oauth_complete, session_exchange}; 137use atproto_oauth::storage::MemoryStorage; 138 139#[tokio::main] 140async fn main() -> anyhow::Result<()> { 141 let client = OAuthClient::new( 142 "https://your-app.com/client-id".to_string(), 143 Some("your-client-secret".to_string()), 144 "https://your-app.com/callback".to_string(), 145 ); 146 147 let storage = MemoryStorage::new(); 148 149 // Start OAuth flow 150 let (authorization_url, state) = oauth_init( 151 &client, 152 "alice.bsky.social", 153 &storage, 154 ).await?; 155 156 println!("Visit: {}", authorization_url); 157 158 // After callback with code... 159 let access_token = oauth_complete( 160 &client, 161 "auth-code", 162 "state", 163 &storage, 164 ).await?; 165 166 // Get AT Protocol session 167 let session = session_exchange(&client, &access_token, &storage).await?; 168 println!("Authenticated as: {} ({})", session.handle, session.did); 169 170 Ok(()) 171} 172``` 173 174## Command Line Tools 175 176The workspace includes 12 command-line tools across the crates. All CLI tools require the `clap` feature: 177 178```bash 179# Build with CLI support 180cargo build --features clap --bins 181 182# Identity operations (atproto-identity crate) 183cargo run --features clap --bin atproto-identity-resolve -- alice.bsky.social 184cargo run --features clap --bin atproto-identity-key -- generate p256 185cargo run --features clap --bin atproto-identity-sign -- did:key:... data.json 186cargo run --features clap --bin atproto-identity-validate -- did:key:... data.json signature 187 188# Record operations (atproto-record crate) 189cargo run --features clap --bin atproto-record-sign -- did:key:... did:plc:issuer record.json repository=did:plc:user collection=app.bsky.feed.post 190cargo run --features clap --bin atproto-record-verify -- did:plc:issuer did:key:... signed_record.json repository=did:plc:user collection=app.bsky.feed.post 191 192# Client operations (atproto-client crate) 193cargo run --features clap --bin atproto-client-auth -- login alice.bsky.social password123 194cargo run --features clap --bin atproto-client-app-password -- alice.bsky.social access_token /xrpc/com.atproto.repo.listRecords 195cargo run --features clap --bin atproto-client-dpop -- alice.bsky.social did:key:... access_token /xrpc/com.atproto.repo.listRecords 196 197# OAuth operations (atproto-oauth-axum crate) 198cargo run --features clap --bin atproto-oauth-tool -- login did:key:... alice.bsky.social 199 200# XRPC service (atproto-xrpcs-helloworld crate) 201cargo run --bin atproto-xrpcs-helloworld 202 203# Event streaming (atproto-jetstream crate) 204cargo run --features clap --bin atproto-jetstream-consumer -- jetstream1.us-east.bsky.network dictionary.zstd 205``` 206 207## Development 208 209```bash 210# Build all crates 211cargo build 212 213# Run all tests 214cargo test 215 216# Format and lint 217cargo fmt && cargo clippy 218 219# Generate documentation 220cargo doc --workspace --open 221``` 222 223## License 224 225This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. 226 227## Acknowledgments 228 229This library was extracted from the [smokesignal.events](https://tangled.sh/@smokesignal.events/smokesignal) project, an open-source AT Protocol event and RSVP management application.