ANProto over ATProto -- using Bluesky PDSes to store ANProto messages and blobs
1# ANProto over ATProto
2
3Here's a Bluesky message about what is going on here: https://bsky.app/profile/evbogue.com/post/3m742nrojn22z
4
5This project demonstrates ANProto messaging on top of the AT Protocol (Bluesky/ATProto) with OAuth auth. It is designed to be clear, concise, and "LLM-friendly" (easy for AI assistants to parse and understand context).
6
7## Purpose
8
9To demonstrate a secure, production-ready (conceptually) OAuth flow using `@atproto/oauth-client-node`, including:
10- **Handle Resolution**: Converting `user.bsky.social` to a DID.
11- **Session Management**: Persisting sessions securely using a database.
12- **Scopes**: Requesting appropriate permissions (Standard vs. Transition).
13- **Token Management**: Handling access and refresh tokens automatically.
14
15## Quick Start
16
171. **Install Dependencies**:
18 ```bash
19 npm install
20 ```
212. **Run the Server**:
22 ```bash
23 npm run dev
24 ```
253. **Open**: Visit `http://localhost:3000`
26
27## Documentation
28
29- **[Architecture Overview](./docs/ARCHITECTURE.md)**: How the components (Client, DB, Storage, Express) fit together.
30- **[Understanding Scopes](./docs/SCOPES.md)**: Which permissions to ask for and why.
31- **[Handles vs. DIDs](./docs/HANDLES_AND_DIDS.md)**: How user identity works in ATProto.
32- **[Setup & Configuration](./docs/SETUP.md)**: Configuring the client metadata for localhost vs. production.
33
34## Key Files
35
36- `src/index.ts`: The web server and route handlers.
37- `src/client.ts`: Configuration of the OAuth client.
38- `src/storage.ts`: Interface between the OAuth client and the database.
39- `src/db.ts`: SQLite database connection.
40
41## "Do's and Don'ts"
42
43- **DO** use DIDs (`did:plc:...`) as the primary user key in your database, not handles. Handles are mutable.
44- **DO** persist the `state` and `session` data securely.
45- **DON'T** request `atproto` (full access) scope unless you absolutely need it. Prefer granular scopes if available (though currently `atproto` or `transition:generic` are common).
46- **DON'T** hardcode the PDS URL. Always resolve it from the user's DID/Handle.