A community based topic aggregation platform built on atproto
1# AT Protocol Implementation Guide 2 3This guide provides comprehensive information about implementing AT Protocol (atproto) in the Coves platform. 4 5## Table of Contents 6- [Core Concepts](#core-concepts) 7- [Architecture Overview](#architecture-overview) 8- [Lexicons](#lexicons) 9- [XRPC](#xrpc) 10- [Data Storage](#data-storage) 11- [Identity & Authentication](#identity--authentication) 12- [Firehose & Sync](#firehose--sync) 13- [Go Implementation Patterns](#go-implementation-patterns) 14- [Best Practices](#best-practices) 15 16## Core Concepts 17 18### What is AT Protocol? 19AT Protocol is a federated social networking protocol that enables: 20- **Decentralized identity** - Users own their identity (DID) and can move between providers 21- **Data portability** - Users can export and migrate their full social graph and content 22- **Interoperability** - Different apps can interact with the same underlying data 23 24### Key Components 251. **DIDs (Decentralized Identifiers)** - Persistent user identifiers (e.g., `did:plc:xyz123`) 262. **Handles** - Human-readable names that resolve to DIDs (e.g., `alice.bsky.social`) 273. **Repositories** - User data stored as signed Merkle trees in CAR files 284. **Lexicons** - Schema definitions for data types and API methods 295. **XRPC** - The RPC protocol for client-server communication 306. **Firehose** - Real-time event stream of repository changes 31 32## Architecture Overview 33 34### Two-Database Pattern 35AT Protocol requires two distinct data stores: 36 37#### 1. Repository Database (Source of Truth) 38- **Purpose**: Stores user-generated content as immutable, signed records 39- **Storage**: CAR files containing Merkle trees + PostgreSQL metadata 40- **Access**: Through XRPC procedures that modify repositories 41- **Properties**: 42 - Append-only (soft deletes via tombstones) 43 - Cryptographically verifiable 44 - User-controlled and portable 45 46#### 2. AppView Database (Query Layer) 47- **Purpose**: Denormalized, indexed data optimized for queries 48- **Storage**: PostgreSQL with application-specific schema 49- **Access**: Through XRPC queries (read-only) 50- **Properties**: 51 - Eventually consistent with repositories 52 - Can be rebuilt from repository data 53 - Application-specific aggregations 54 55### Data Flow 56 57``` 58Write Path: 59Client → XRPC Procedure → Service → Write Repo → CAR Store 60 61 Firehose Event 62 63 AppView Indexer 64 65 AppView Database 66 67Read Path: 68Client → XRPC Query → Service → Read Repo → AppView Database 69``` 70 71## Lexicons 72 73### What are Lexicons? 74Lexicons are JSON schema files that define: 75- Data types (records stored in repositories) 76- API methods (queries and procedures) 77- Input/output schemas for API calls 78 79### Lexicon Structure 80```json 81{ 82 "lexicon": 1, 83 "id": "social.coves.community.profile", 84 "defs": { 85 "main": { 86 "type": "record", 87 "key": "self", 88 "record": { 89 "type": "object", 90 "required": ["name", "createdAt"], 91 "properties": { 92 "name": {"type": "string", "maxLength": 64}, 93 "description": {"type": "string", "maxLength": 256}, 94 "rules": {"type": "array", "items": {"type": "string"}}, 95 "createdAt": {"type": "string", "format": "datetime"} 96 } 97 } 98 } 99 } 100} 101``` 102 103### Lexicon Types 104 105#### 1. Record Types 106Define data structures stored in user repositories: 107```json 108{ 109 "type": "record", 110 "key": "tid|rkey|literal", 111 "record": { /* schema */ } 112} 113``` 114 115#### 2. Query Types (Read-only) 116Define read operations that don't modify state: 117```json 118{ 119 "type": "query", 120 "parameters": { /* input schema */ }, 121 "output": { /* response schema */ } 122} 123``` 124 125#### 3. Procedure Types (Write) 126Define operations that modify repositories: 127```json 128{ 129 "type": "procedure", 130 "input": { /* request body schema */ }, 131 "output": { /* response schema */ } 132} 133``` 134 135### Naming Conventions 136- Use reverse-DNS format: `social.coves.community.profile` 137- Queries often start with `get`, `list`, or `search` 138- Procedures often start with `create`, `update`, or `delete` 139- Keep names descriptive but concise 140 141## XRPC 142 143### What is XRPC? 144XRPC (Cross-Protocol RPC) is AT Protocol's HTTP-based RPC system: 145- All methods live under `/xrpc/` path 146- Method names map directly to Lexicon IDs 147- Supports both JSON and binary data 148 149### Request Format 150``` 151# Query (GET) 152GET /xrpc/social.coves.community.getCommunity?id=123 153 154# Procedure (POST) 155POST /xrpc/social.coves.community.createPost 156Content-Type: application/json 157Authorization: Bearer <token> 158 159{"text": "Hello, Coves!"} 160``` 161 162### Authentication 163- Uses Bearer tokens in Authorization header 164- Tokens are JWTs signed by the user's signing key 165- Service auth for server-to-server calls 166 167## Data Storage 168 169### CAR Files 170Content Addressable archive files store repository data: 171- Contains IPLD blocks forming a Merkle tree 172- Each block identified by CID (Content IDentifier) 173- Enables cryptographic verification and efficient sync 174 175### Record Keys (rkeys) 176- Unique identifiers for records within a collection 177- Can be TIDs (timestamp-based) or custom strings 178- Must match pattern: `[a-zA-Z0-9._~-]{1,512}` 179 180### Repository Structure 181``` 182Repository (did:plc:user123) 183├── social.coves.post 184│ ├── 3kkreaz3amd27 (TID) 185│ └── 3kkreaz3amd28 (TID) 186├── social.coves.community.member 187│ ├── community123 188│ └── community456 189└── app.bsky.actor.profile 190 └── self 191``` 192 193## Identity & Authentication 194 195### DIDs (Decentralized Identifiers) 196- Permanent, unique identifiers for users 197- Two types supported: 198 - `did:plc:*` - Hosted by PLC Directory 199 - `did:web:*` - Self-hosted 200 201### Handle Resolution 202Handles resolve to DIDs via: 2031. DNS TXT record: `_atproto.alice.com → did:plc:xyz` 2042. HTTPS well-known: `https://alice.com/.well-known/atproto-did` 205 206### Authentication Flow 2071. Client creates session with identifier/password 2082. Server returns access/refresh tokens 2093. Client uses access token for API requests 2104. Refresh when access token expires 211 212## Firehose & Sync 213 214### Firehose Events 215Real-time stream of repository changes: 216- Commit events (creates, updates, deletes) 217- Identity events (handle changes) 218- Account events (status changes) 219 220### Subscribing to Firehose 221Connect via WebSocket to `com.atproto.sync.subscribeRepos`: 222``` 223wss://bsky.network/xrpc/com.atproto.sync.subscribeRepos 224``` 225 226### Processing Events 227- Events include full record data and operation type 228- Process events to update AppView database 229- Handle out-of-order events with sequence numbers 230 231## Go Implementation Patterns 232 233### Using Indigo Library 234Bluesky's official Go implementation provides: 235- Lexicon code generation 236- CAR file handling 237- XRPC client/server 238- Firehose subscription 239 240### Code Generation 241Generate Go types from Lexicons: 242```bash 243go run github.com/bluesky-social/indigo/cmd/lexgen \ 244 --package coves \ 245 --prefix social.coves \ 246 --outdir api/coves \ 247 lexicons/social/coves/*.json 248``` 249 250### Repository Operations 251```go 252// Write to repository 253rkey := models.GenerateTID() 254err := repoStore.CreateRecord(ctx, userDID, "social.coves.post", rkey, &Post{ 255 Text: "Hello", 256 CreatedAt: time.Now().Format(time.RFC3339), 257}) 258 259// Read from repository 260records, err := repoStore.ListRecords(ctx, userDID, "social.coves.post", limit, cursor) 261``` 262 263### XRPC Handler Pattern 264```go 265func (s *Server) HandleGetCommunity(ctx context.Context) error { 266 // 1. Parse and validate input 267 id := xrpc.QueryParam(ctx, "id") 268 269 // 2. Call service layer 270 community, err := s.communityService.GetByID(ctx, id) 271 if err != nil { 272 return err 273 } 274 275 // 3. Return response 276 return xrpc.WriteJSONResponse(ctx, community) 277} 278``` 279 280## Best Practices 281 282### 1. Lexicon Design 283- Keep schemas focused and single-purpose 284- Use references (`$ref`) for shared types 285- Version carefully - Lexicons are contracts 286- Document thoroughly with descriptions 287 288### 2. Data Modeling 289- Store minimal data in repositories 290- Denormalize extensively in AppView 291- Use record keys that are meaningful 292- Plan for data portability 293 294### 3. Performance 295- Batch firehose processing 296- Use database transactions wisely 297- Index AppView tables appropriately 298- Cache frequently accessed data 299 300### 4. Error Handling 301- Use standard XRPC error codes 302- Provide meaningful error messages 303- Handle network failures gracefully 304- Implement proper retry logic 305 306### 5. Security 307- Validate all inputs against Lexicons 308- Verify signatures on repository data 309- Rate limit API endpoints 310- Sanitize user-generated content 311 312### 6. Federation 313- Design for multi-instance deployment 314- Handle remote user identities 315- Respect instance-specific policies 316- Plan for cross-instance data sync 317 318## Common Patterns 319 320### Handling User Content 321- Always validate against Lexicon schemas 322- Store in user's repository via CAR files 323- Index in AppView for efficient queries 324- Emit firehose events for subscribers 325 326## Resources 327 328### Official Documentation 329- [ATProto Specifications](https://atproto.com/specs) 330- [Lexicon Documentation](https://atproto.com/specs/lexicon) 331- [XRPC Specification](https://atproto.com/specs/xrpc) 332 333### Reference Implementations 334- [Indigo (Go)](https://github.com/bluesky-social/indigo) 335- [ATProto SDK (TypeScript)](https://github.com/bluesky-social/atproto) 336 337### Tools 338- [Lexicon CLI](https://github.com/bluesky-social/atproto/tree/main/packages/lex-cli) 339- [goat CLI](https://github.com/bluesky-social/indigo/tree/main/cmd/goat)