···11+MIT License
22+33+Copyright (c) 2026 Patrick Dewey
44+55+Permission is hereby granted, free of charge, to any person obtaining a copy
66+of this software and associated documentation files (the "Software"), to deal
77+in the Software without restriction, including without limitation the rights
88+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
99+copies of the Software, and to permit persons to whom the Software is
1010+furnished to do so, subject to the following conditions:
1111+1212+The above copyright notice and this permission notice shall be included in all
1313+copies or substantial portions of the Software.
1414+1515+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1616+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1717+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1818+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1919+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2020+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2121+SOFTWARE.
+49
README.md
···11+# atp
22+33+AT Protocol boilerplate for Go, extracted from [arabica.social](https://tangled.org/arabica.social/arabica). Covers OAuth flows, PDS client operations, real-time event consumption, session storage, HTTP middleware, and testing infrastructure.
44+55+> Note: The `testpds` package pulls in [cocoon](https://github.com/haileyok/cocoon) to spin up ephemeral PDS instances, which makes the dependency tree heavy (indigo, aws-sdk, etc.).
66+77+## Installation
88+99+```sh
1010+go get tangled.org/pdewey.com/atp@latest
1111+```
1212+1313+## Packages
1414+1515+### Root (`atp`)
1616+1717+Core types and clients for the AT Protocol.
1818+1919+- `Client` -- authenticated PDS client for CRUD operations on a user's repository (`CreateRecord`, `GetRecord`, `ListRecords`, `PutRecord`, `DeleteRecord`, `UploadBlob`, `GetBlob`).
2020+- `OAuthApp` -- manages the OAuth flow: login (browser-based and CLI), callback handling, session resumption, and logout. Supports public and localhost (development) client modes.
2121+- `PublicClient` -- unauthenticated access to public atproto APIs (handle resolution, profiles, record reads) with SSRF protection.
2222+- Helpers for AT-URI parsing/building, scope construction, and error handling.
2323+2424+### `jetstream`
2525+2626+WebSocket consumer for the [Jetstream](https://docs.bsky.app/blog/jetstream) relay. Reconnects with exponential backoff, rotates endpoints, optionally decompresses zstd, and persists cursors for resuming after restarts.
2727+2828+### `middleware`
2929+3030+Cookie-based AT Protocol auth middleware. Validates sessions against the OAuth store and injects the authenticated DID into the request context. Also serves the OAuth client metadata endpoint.
3131+3232+### `store/bolt` and `store/sqlite`
3333+3434+Two `oauth.ClientAuthStore` implementations for persisting OAuth sessions and auth request state:
3535+3636+- bolt: BoltDB-backed.
3737+- sqlite: SQLite-backed with automatic schema migration and expired request cleanup.
3838+3939+### `testpds`
4040+4141+Ephemeral, in-process PDS for integration testing. Uses in-memory SQLite and an optional `FakePLC` (from `plc`) so tests need no external services. Includes helpers for creating test accounts and subscribing to the firehose.
4242+4343+### `plc`
4444+4545+Mock PLC directory that stores operations in memory instead of posting to a real directory. Used by `testpds` for isolated test environments.
4646+4747+### `tracing`
4848+4949+OpenTelemetry span helpers for AT Protocol operations (PDS calls, database operations, HTTP handlers). Sets up an OTLP HTTP exporter and returns no-op spans when there is no active trace context.
+65
temp.html
···11+<h1 id="atp">atp</h1>
22+<p>AT Protocol boilerplate for Go, extracted from <a
33+href="https://tangled.org/arabica.social/arabica">arabica.social</a>.
44+Covers OAuth flows, PDS client operations, real-time event consumption,
55+session storage, HTTP middleware, and testing infrastructure.</p>
66+<blockquote>
77+<p>The <code>testpds</code> package pulls in <a
88+href="https://github.com/haileyok/cocoon">cocoon</a> to spin up
99+ephemeral PDS instances, which makes the dependency tree heavy. This is
1010+a single module, so the transitive cost applies even if you only use the
1111+client or OAuth packages.</p>
1212+</blockquote>
1313+<h2 id="packages">Packages</h2>
1414+<h3 id="root-atp">Root (<code>atp</code>)</h3>
1515+<p>Core types and clients for the AT Protocol.</p>
1616+<ul>
1717+<li><code>Client</code> – authenticated PDS client for CRUD operations
1818+on a user’s repository (<code>CreateRecord</code>,
1919+<code>GetRecord</code>, <code>ListRecords</code>,
2020+<code>PutRecord</code>, <code>DeleteRecord</code>,
2121+<code>UploadBlob</code>, <code>GetBlob</code>).</li>
2222+<li><code>OAuthApp</code> – manages the OAuth flow: login (browser-based
2323+and CLI), callback handling, session resumption, and logout. Supports
2424+public and localhost (development) client modes.</li>
2525+<li><code>PublicClient</code> – unauthenticated access to public atproto
2626+APIs (handle resolution, profiles, record reads) with SSRF
2727+protection.</li>
2828+<li>Helpers for AT-URI parsing/building, scope construction, and error
2929+handling.</li>
3030+</ul>
3131+<h3 id="jetstream"><code>jetstream</code></h3>
3232+<p>WebSocket consumer for the <a
3333+href="https://docs.bsky.app/blog/jetstream">Jetstream</a> relay.
3434+Reconnects with exponential backoff, rotates endpoints, optionally
3535+decompresses zstd, and persists cursors for resuming after restarts.</p>
3636+<h3 id="middleware"><code>middleware</code></h3>
3737+<p>Cookie-based AT Protocol auth middleware. Validates sessions against
3838+the OAuth store and injects the authenticated DID into the request
3939+context. Also serves the OAuth client metadata endpoint.</p>
4040+<h3 id="storebolt-and-storesqlite"><code>store/bolt</code> and
4141+<code>store/sqlite</code></h3>
4242+<p>Two <code>oauth.ClientAuthStore</code> implementations for persisting
4343+OAuth sessions and auth request state:</p>
4444+<ul>
4545+<li>bolt: BoltDB-backed.</li>
4646+<li>sqlite: SQLite-backed with automatic schema migration and expired
4747+request cleanup.</li>
4848+</ul>
4949+<h3 id="testpds"><code>testpds</code></h3>
5050+<p>Ephemeral, in-process PDS for integration testing. Uses in-memory
5151+SQLite and an optional <code>FakePLC</code> (from <code>plc</code>) so
5252+tests need no external services. Includes helpers for creating test
5353+accounts and subscribing to the firehose.</p>
5454+<h3 id="plc"><code>plc</code></h3>
5555+<p>Mock PLC directory that stores operations in memory instead of
5656+posting to a real directory. Used by <code>testpds</code> for isolated
5757+test environments.</p>
5858+<h3 id="tracing"><code>tracing</code></h3>
5959+<p>OpenTelemetry span helpers for AT Protocol operations (PDS calls,
6060+database operations, HTTP handlers). Sets up an OTLP HTTP exporter and
6161+returns no-op spans when there is no active trace context.</p>
6262+<h2 id="installation">Installation</h2>
6363+<div class="sourceCode" id="cb1"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ex">go</span> get tangled.org/pdewey.com/atp</span></code></pre></div>
6464+<h2 id="license">License</h2>
6565+<p>See <a href="LICENSE">LICENSE</a> for details.</p>