Skip to main content

Module atproto

Module atproto 

Source
Expand description

The atproto identity + PDS record layer.

FeatherReader’s defining bet is that a user’s feed subscriptions, folders, saved items, and batched read-state live as records in the user’s own atproto PDS under the open community.lexicon.rss.* community lexicon — not in the app’s database. This module is the client that reads and writes those records.

It has three layers:

  1. Identity resolution (resolve_handle, resolve_did_to_pds) — turn a handle (alice.example.com) into a DID (did:plc:…), then resolve the DID document to the PDS service endpoint. Handles resolve via the account’s PDS com.atproto.identity.resolveHandle (or the well-known /.well-known/atproto-did); DIDs resolve via the PLC directory (did:plc:*) or the did:web well-known document.
  2. A lightweight PdsClient — holds the resolved DID, the PDS base URL, and an Auth token, and exposes typed calls over com.atproto.repo.*: list_records, create_record, put_record, delete_record, and apply_writes (the batch call the read-state flusher uses to coalesce many per-feed cursor writes into one round-trip).
  3. Typed convenience wrappers wired to the crate::lexicon record types (list/create Subscription/Folder/Saved, put ReadState, batch-flush many ReadState cursors).

§Auth — the OAuth sidecar is the live path

Auth is a trait/enum boundary so the mechanism can vary without touching call sites. There are two paths:

  • The live path — the atproto OAuth confidential client, via SidecarClient. atproto OAuth (DPoP, PAR, token refresh) is fiddly and is not hand-rolled in Rust: it runs in a small, supported @atproto/oauth-client-node sidecar. The Rust server never holds PDS tokens — it POSTs every com.atproto.repo.* op to the sidecar’s /internal/repo endpoint (gated by a shared X-Internal-Secret), and the sidecar restores the DID’s OAuth session (transparent DPoP + token refresh) and runs the matching XRPC call. SidecarClient is that client; the typed convenience wrappers (list/create/put/delete subscriptions, batch-flush read-state) live on it and map 1:1 to the old PdsClient surface.
  • The interim path — Auth::Session (app password). A session obtained from com.atproto.server.createSession. Kept behind the Auth seam as a fallback for local runs without the sidecar, but it is no longer the live path: PdsClient and login_with_app_password remain for tests and dev, while SidecarClient is what the web layer routes through.

All network I/O is reqwest (rustls, no OpenSSL); every fallible path returns anyhow::Result or the typed AtProtoError — nothing panics.

Structs§

DidDocument
The subset of a DID document FeatherReader needs: its services, so it can find the #atproto_pds endpoint.
DidService
One service entry in a DidDocument.
ListRecordsResponse
The com.atproto.repo.listRecords response envelope.
OauthPlaceholder
Placeholder for the OAuth variant of Auth.
PdsClient
A lightweight client for one user’s PDS repo.
RecordEntry
A single record as returned in a listRecords / getRecord response.
RevokeResult
The sidecar’s /internal/revoke response body: { ok:true, did, revoked, hadSession }.
SessionAuth
A session obtained from com.atproto.server.createSession (interim app-password auth). Holds the DID + tokens + handle the server returned.
SidecarClient
A client for the atproto OAuth sidecar’s internal API.
SidecarSession
The {did, handle} a session-id resolves to (the sidecar’s /internal/session/:id body).
WriteResult
The com.atproto.repo.createRecord / putRecord response (a strong ref to the written record).

Enums§

AtProtoError
Errors from the atproto identity + PDS layer.
Auth
The auth material a PdsClient carries.
RepoAction
The action verbs the sidecar’s /internal/repo endpoint dispatches on.
WriteOp
One operation in a PdsClient::apply_writes batch.

Constants§

DEFAULT_PLC_DIRECTORY
The public PLC directory, used to resolve did:plc:* DIDs to their DID document (and thus their PDS service endpoint).
DEFAULT_RESOLVER_HOST
The default appview/entryway used only as a bootstrap host for handle resolution when the caller has no PDS hint yet. Handle resolution ultimately works against any atproto host that implements com.atproto.identity.resolveHandle; bsky.social is a reliable default.

Traits§

TokenSource
A source of atproto access tokens.

Functions§

login_with_app_password
Create a session with an app password via com.atproto.server.createSession.
resolve_did_to_pds
Resolve a DID to its PDS service endpoint by fetching + parsing its DID document.
resolve_handle
Resolve an atproto handle to its DID.