···
1
+
# AT Protocol Implementation Guide
3
+
This guide provides comprehensive information about implementing AT Protocol (atproto) in the Coves platform.
6
+
- [Core Concepts](#core-concepts)
7
+
- [Architecture Overview](#architecture-overview)
8
+
- [Lexicons](#lexicons)
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)
18
+
### What is AT Protocol?
19
+
AT 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
25
+
1. **DIDs (Decentralized Identifiers)** - Persistent user identifiers (e.g., `did:plc:xyz123`)
26
+
2. **Handles** - Human-readable names that resolve to DIDs (e.g., `alice.bsky.social`)
27
+
3. **Repositories** - User data stored as signed Merkle trees in CAR files
28
+
4. **Lexicons** - Schema definitions for data types and API methods
29
+
5. **XRPC** - The RPC protocol for client-server communication
30
+
6. **Firehose** - Real-time event stream of repository changes
32
+
## Architecture Overview
34
+
### Two-Database Pattern
35
+
AT Protocol requires two distinct data stores:
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
42
+
- Append-only (soft deletes via tombstones)
43
+
- Cryptographically verifiable
44
+
- User-controlled and portable
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)
51
+
- Eventually consistent with repositories
52
+
- Can be rebuilt from repository data
53
+
- Application-specific aggregations
59
+
Client → XRPC Procedure → Service → Write Repo → CAR Store
68
+
Client → XRPC Query → Service → Read Repo → AppView Database
73
+
### What are Lexicons?
74
+
Lexicons 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
79
+
### Lexicon Structure
83
+
"id": "social.coves.community.profile",
90
+
"required": ["name", "createdAt"],
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"}
105
+
#### 1. Record Types
106
+
Define data structures stored in user repositories:
110
+
"key": "tid|rkey|literal",
111
+
"record": { /* schema */ }
115
+
#### 2. Query Types (Read-only)
116
+
Define read operations that don't modify state:
120
+
"parameters": { /* input schema */ },
121
+
"output": { /* response schema */ }
125
+
#### 3. Procedure Types (Write)
126
+
Define operations that modify repositories:
129
+
"type": "procedure",
130
+
"input": { /* request body schema */ },
131
+
"output": { /* response schema */ }
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
144
+
XRPC (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
152
+
GET /xrpc/social.coves.community.getCommunity?id=123
155
+
POST /xrpc/social.coves.community.createPost
156
+
Content-Type: application/json
157
+
Authorization: Bearer <token>
159
+
{"text": "Hello, Coves!"}
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
170
+
Content 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
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}`
180
+
### Repository Structure
182
+
Repository (did:plc:user123)
183
+
├── social.coves.post
184
+
│ ├── 3kkreaz3amd27 (TID)
185
+
│ └── 3kkreaz3amd28 (TID)
186
+
├── social.coves.community.member
189
+
└── app.bsky.actor.profile
193
+
## Identity & Authentication
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
201
+
### Handle Resolution
202
+
Handles resolve to DIDs via:
203
+
1. DNS TXT record: `_atproto.alice.com → did:plc:xyz`
204
+
2. HTTPS well-known: `https://alice.com/.well-known/atproto-did`
206
+
### Authentication Flow
207
+
1. Client creates session with identifier/password
208
+
2. Server returns access/refresh tokens
209
+
3. Client uses access token for API requests
210
+
4. Refresh when access token expires
214
+
### Firehose Events
215
+
Real-time stream of repository changes:
216
+
- Commit events (creates, updates, deletes)
217
+
- Identity events (handle changes)
218
+
- Account events (status changes)
220
+
### Subscribing to Firehose
221
+
Connect via WebSocket to `com.atproto.sync.subscribeRepos`:
223
+
wss://bsky.network/xrpc/com.atproto.sync.subscribeRepos
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
231
+
## Go Implementation Patterns
233
+
### Using Indigo Library
234
+
Bluesky's official Go implementation provides:
235
+
- Lexicon code generation
236
+
- CAR file handling
237
+
- XRPC client/server
238
+
- Firehose subscription
240
+
### Code Generation
241
+
Generate Go types from Lexicons:
243
+
go run github.com/bluesky-social/indigo/cmd/lexgen \
245
+
--prefix social.coves \
246
+
--outdir api/coves \
247
+
lexicons/social/coves/*.json
250
+
### Repository Operations
252
+
// Write to repository
253
+
rkey := models.GenerateTID()
254
+
err := repoStore.CreateRecord(ctx, userDID, "social.coves.post", rkey, &Post{
256
+
CreatedAt: time.Now().Format(time.RFC3339),
259
+
// Read from repository
260
+
records, err := repoStore.ListRecords(ctx, userDID, "social.coves.post", limit, cursor)
263
+
### XRPC Handler Pattern
265
+
func (s *Server) HandleGetCommunity(ctx context.Context) error {
266
+
// 1. Parse and validate input
267
+
id := xrpc.QueryParam(ctx, "id")
269
+
// 2. Call service layer
270
+
community, err := s.communityService.GetByID(ctx, id)
275
+
// 3. Return response
276
+
return xrpc.WriteJSONResponse(ctx, community)
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
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
295
+
- Batch firehose processing
296
+
- Use database transactions wisely
297
+
- Index AppView tables appropriately
298
+
- Cache frequently accessed data
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
307
+
- Validate all inputs against Lexicons
308
+
- Verify signatures on repository data
309
+
- Rate limit API endpoints
310
+
- Sanitize user-generated content
313
+
- Design for multi-instance deployment
314
+
- Handle remote user identities
315
+
- Respect instance-specific policies
316
+
- Plan for cross-instance data sync
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
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)
333
+
### Reference Implementations
334
+
- [Indigo (Go)](https://github.com/bluesky-social/indigo)
335
+
- [ATProto SDK (TypeScript)](https://github.com/bluesky-social/atproto)
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)