Skip to content
Oeiuwq Faith Blog OpenSource Porfolio

evbogue/ANonAT

ANProto on ATProto

evbogue/ANonAT.json
{
"createdAt": "2025-12-03T17:49:23Z",
"defaultBranch": "main",
"description": "ANProto on ATProto",
"fullName": "evbogue/ANonAT",
"homepage": null,
"language": "TypeScript",
"name": "ANonAT",
"pushedAt": "2025-12-03T21:17:09Z",
"stargazersCount": 1,
"topics": [],
"updatedAt": "2025-12-03T21:17:13Z",
"url": "https://github.com/evbogue/ANonAT"
}

Here’s a Bluesky message about what is going on here: https://bsky.app/profile/evbogue.com/post/3m742nrojn22z

This 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).

To demonstrate a secure, production-ready (conceptually) OAuth flow using @atproto/oauth-client-node, including:

  • Handle Resolution: Converting user.bsky.social to a DID.
  • Session Management: Persisting sessions securely using a database.
  • Scopes: Requesting appropriate permissions (Standard vs. Transition).
  • Token Management: Handling access and refresh tokens automatically.
  1. Install Dependencies:
    Terminal window
    npm install
  2. Run the Server:
    Terminal window
    npm run dev
  3. Open: Visit http://localhost:3000
  • [Architecture Overview]!(./docs/ARCHITECTURE.md): How the components (Client, DB, Storage, Express) fit together.
  • [Understanding Scopes]!(./docs/SCOPES.md): Which permissions to ask for and why.
  • [Handles vs. DIDs]!(./docs/HANDLES_AND_DIDS.md): How user identity works in ATProto.
  • [Setup & Configuration]!(./docs/SETUP.md): Configuring the client metadata for localhost vs. production.
  • src/index.ts: The web server and route handlers.
  • src/client.ts: Configuration of the OAuth client.
  • src/storage.ts: Interface between the OAuth client and the database.
  • src/db.ts: SQLite database connection.
  • DO use DIDs (did:plc:...) as the primary user key in your database, not handles. Handles are mutable.
  • DO persist the state and session data securely.
  • 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).
  • DON’T hardcode the PDS URL. Always resolve it from the user’s DID/Handle.