ANProto over ATProto -- using Bluesky PDSes to store ANProto messages and blobs
Work Order: ANProto Messages on Bluesky PDS#
Scope#
- Store ANProto-signed messages (and blobs) in a Bluesky PDS using the existing Node OAuth backend. APDS remains frontend-only.
- Use custom collections
com.anproto.message.v1(messages) and optionalcom.anproto.blobif we need standalone blob records.
First Steps#
- Lexicons:
com.anproto.message.v1hasanmsg(full ANProto message), optionalanblob,anhash(base64 ANProto hash), andblobhash(hash of the attached blob). PDS rkey uses a base64url form ofanhash(replace+→-,/→_, strip=) to satisfy record-key rules. IDs must match the collection names exactly.com.anproto.blobis optional if blobs stay inanblob. - OAuth/scopes: Keep Node OAuth flow; request repo read/write + blob upload (
atprotofor now). Continue storing DID in cookies and tokens server-side. - Signing/validation: Frontend APDS signs messages; send backend
{anmsg, blob?, blobMime?}. Backend recomputesanhashvia ANProto, converts to base64url rkey, and rejects mismatches. - Persistence: Upload blobs via
com.atproto.repo.uploadBlob; createcom.anproto.message.v1records with rkey = base64url(anhash), storinganmsg,anhash, optionalanblob, and optionalblobhash. - Retrieval/indexing: Add backend endpoints to fetch by rkey/anhash/DID; optional local index (DB) for search/filter; fallback to repo reads by rkey.
- Safety: Enforce size limits on content/blobs, rate-limit publish, reject tampered/duplicate/invalid signatures, log verification failures.
Client UI (Frontend)#
- Auth status: “Connect Bluesky” button; show connected DID/handle; disable publish until connected.
- Key management: Display ANProto pubkey; controls to generate/import/export (avoid leaking private key in production).
- Composer: Text area for content, optional “previous” hash, blob uploader, live display of computed hash/signature.
- Publish flow: “Sign & Save to Bluesky” runs APDS sign then POSTs to backend; show progress/errors.
- Viewer: Fetch by hash, display content, author pubkey, timestamp, previous chain, blob previews; simple search/filter if backend index exists.
- Notifications: Inline status/toasts for auth, signing, upload, and save failures.