A Slop forward pastebin on the atmosphere

Files
README.md

atmobin.lol #

A stupid PDS-backed pastebin. Paste text and images; atmobin writes lol.atmobin.paste records into your atproto repo and proxies them back. No copies kept.

URL scheme #

Everything is atmobin.lol/<did or @handle>/<record nsid>/<rkey> — e.g. https://atmobin.lol/@chris.pardy.family/lol.atmobin.paste/3k.... Append /raw for text/plain (or record JSON). Any record type renders (non-pastes get a JSON view). Record pages carry <link rel="alternate" href="at://..."> per the at-uri page-linking convention. The only non-proxy routes are / (paste page), /login, /logout, /oauth/callback, /client-metadata.json, and /jwks.json.

Stack #

  • TanStack Start (React 19, Vite 8, nitro) — plain HTML forms, no client JS required
  • TypeScript 7, oxlint
  • node:sqlite for OAuth state/session + web session storage
  • @atproto/oauth-client-node (confidential client, ES256 private_key_jwt)
  • Fly.io, single shared instance, sqlite on a volume at /data

Dev #

npm install
npm run dev        # http://127.0.0.1:3000 — runs as an atproto loopback OAuth client
npm run lint
npm run typecheck

Use http://127.0.0.1:3000 (not localhost) so the loopback OAuth redirect matches.

Deploy #

npm run generate-key   # → fly secrets set OAUTH_PRIVATE_KEY_JWK='...'
fly deploy --ha=false

Env: PUBLIC_URL, DB_PATH, OAUTH_PRIVATE_KEY_JWK, OAUTH_SCOPE (default atproto repo:lol.atmobin.paste blob:image/* — set to atproto transition:generic if a PDS doesn't support granular scopes yet).

Lexicon #

lexicons/lol.atmobin.paste.json, published as com.atproto.lexicon.schema/lol.atmobin.paste in the authority repo, with _lexicon.atmobin.lol TXT did=did:plc:dp7v5b5kejmmzzpwmqyf5wj6. DNS for the domain is managed via at.marque.dns records (Marque nameservers).