A library for ATProtocol identities.
1# atproto-record 2 3Utilities for working with AT Protocol records. 4 5## Overview 6 7A Rust library for working with AT Protocol records, providing AT-URI parsing, TID generation, datetime formatting, and CID generation. Built on IPLD DAG-CBOR serialization for deterministic content addressing. 8 9## Features 10 11- **AT-URI parsing**: Parse and validate AT Protocol URIs (at://authority/collection/record_key) with robust error handling 12- **TID generation**: Timestamp-based identifiers for AT Protocol records with microsecond precision 13- **CID generation**: Content Identifier generation using DAG-CBOR serialization and SHA-256 hashing 14- **DateTime utilities**: RFC 3339 datetime serialization with millisecond precision for consistent timestamp handling 15- **Typed records**: Type-safe record handling with lexicon type validation 16- **Bytes handling**: Base64 encoding/decoding for binary data in AT Protocol records 17- **Structured errors**: Type-safe error handling following project conventions with detailed error messages 18 19## CLI Tools 20 21The following command-line tool is available when built with the `clap` feature: 22 23- **`atproto-record-cid`**: Generate CID (Content Identifier) for AT Protocol records from JSON input 24 25## Library Usage 26 27### Generating CIDs 28 29```rust 30use serde_json::json; 31use cid::Cid; 32use sha2::{Digest, Sha256}; 33use multihash::Multihash; 34 35// Serialize a record to DAG-CBOR and generate its CID 36let record = json!({ 37 "$type": "app.bsky.feed.post", 38 "text": "Hello world!", 39 "createdAt": "2024-01-01T00:00:00.000Z" 40}); 41 42let dag_cbor_bytes = serde_ipld_dagcbor::to_vec(&record)?; 43let hash = Sha256::digest(&dag_cbor_bytes); 44let multihash = Multihash::wrap(0x12, &hash)?; 45let cid = Cid::new_v1(0x71, multihash); 46 47println!("Record CID: {}", cid); 48``` 49 50### Generating TIDs 51 52```rust 53use atproto_record::tid::Tid; 54 55// Generate a new timestamp-based identifier 56let tid = Tid::new(); 57println!("TID: {}", tid); // e.g., "3l2k4j5h6g7f8d9s" 58 59// TIDs are sortable by creation time 60let tid1 = Tid::new(); 61std::thread::sleep(std::time::Duration::from_millis(1)); 62let tid2 = Tid::new(); 63assert!(tid1 < tid2); 64``` 65 66### AT-URI Parsing 67 68```rust 69use atproto_record::aturi::ATURI; 70use std::str::FromStr; 71 72// Parse an AT-URI into its components 73let aturi = ATURI::from_str("at://did:plc:abc123/app.bsky.feed.post/3k2k4j5h6g")?; 74 75// Access the parsed components 76println!("Authority: {}", aturi.authority); // "did:plc:abc123" 77println!("Collection: {}", aturi.collection); // "app.bsky.feed.post" 78println!("Record Key: {}", aturi.record_key); // "3k2k4j5h6g" 79 80// The Display trait formats back to a valid AT-URI 81println!("Full URI: {}", aturi); // "at://did:plc:abc123/app.bsky.feed.post/3k2k4j5h6g" 82``` 83 84### DateTime Utilities 85 86```rust 87use chrono::{DateTime, Utc}; 88use serde::{Deserialize, Serialize}; 89 90// Use the datetime module for consistent RFC 3339 formatting 91#[derive(Serialize, Deserialize)] 92struct Record { 93 #[serde(with = "atproto_record::datetime::format")] 94 created_at: DateTime<Utc>, 95 96 #[serde(with = "atproto_record::datetime::optional_format")] 97 updated_at: Option<DateTime<Utc>>, 98} 99``` 100 101## Command Line Usage 102 103The CLI tool requires the `clap` feature: 104 105```bash 106# Build with CLI support 107cargo build --features clap --bins 108 109# Generate CID from JSON file 110cat record.json | cargo run --features clap --bin atproto-record-cid 111 112# Generate CID from inline JSON 113echo '{"$type":"app.bsky.feed.post","text":"Hello!"}' | cargo run --features clap --bin atproto-record-cid 114 115# Example with a complete AT Protocol record 116cat <<EOF | cargo run --features clap --bin atproto-record-cid 117{ 118 "$type": "app.bsky.feed.post", 119 "text": "Hello AT Protocol!", 120 "createdAt": "2024-01-01T00:00:00.000Z" 121} 122EOF 123``` 124 125The tool outputs the CID in base32 format: 126``` 127bafyreibjzlvhtyxnhbvvzl3gj4qmg2ufl2jbhh5qr3gvvxlm7ksf3qwxqq 128``` 129 130## License 131 132MIT License