atproto utils for zig
zat.dev
atproto
sdk
zig
1# changelog
2
3## 0.2.18
4
5- **feat**: export `HttpTransport` from root module — consumers can now use `zat.HttpTransport` for direct HTTP access without going through `XrpcClient`
6
7## 0.2.17
8
9- **feat**: `Keypair.jwk()`, `Keypair.jwkThumbprint()`, `Keypair.uncompressedPublicKey()` — JWK export and RFC 7638 thumbprints for both P-256 and secp256k1
10- **feat**: `oauth` module — stateless PKCE, DPoP proofs, client assertions, form encoding, and related helpers for AT Protocol OAuth flows (based on OAuth 2.1)
11- **feat**: `jwt.base64UrlEncode`, `jwt.base64UrlDecode` now public
12- **test**: interop tests for did:key derivation and data model fixtures
13
14## 0.2.16
15
16- **fix**: bump websocket.zig to `395d0f4` — reads full HTTP body on TCP split writes (fixes empty body when headers and body arrive in separate TCP segments)
17
18## 0.2.15
19
20- **feat**: `parseDidKey`, `verifyDidKeySignature` — parse `did:key` strings back to key type + raw bytes, verify signatures by `did:key` with automatic curve dispatch
21- **feat**: `Keypair` struct — unified abstraction over secp256k1/P-256 for sign, publicKey, did:key formatting
22- **feat**: optional `onConnect` callback on `JetstreamClient` — exposes which host the client connected to
23
24## 0.2.14
25
26- **fix**: memory leak in `HttpTransport.fetch()` — `toArrayList()` transferred buffer ownership without freeing; use `written()` instead to keep ownership with the deferred `deinit()`
27
28## 0.2.13
29
30- **docs**: devlog 007 — up and to the right (corrections to 006, sync 1.1 verification, lightrail collection index)
31
32## 0.2.12
33
34- **feat**: configurable `keep_alive` on `HttpTransport` and `DidResolver.initWithOptions` — allows disabling HTTP connection reuse for memory leak investigation
35
36## 0.2.11
37
38- **fix**: enable TCP keepalive on websocket connections — detect dead peers in ~20s instead of blocking forever
39
40## 0.2.10
41
42- **deps**: bump websocket.zig to fork commit `9e6d732` — TCP split guard for HTTP body reads behind reverse proxies
43
44## 0.2.9
45
46- **fix**: SPA fallback routing for standard.site deep links — `_redirects`, `<base href="/">`, devlog short-name aliases
47- **fix**: add glibc to nixery deps for wisp-cli patchelf in CI
48- **docs**: devlog 006 — building a relay in zig (zlay architecture, deployment war stories, backfill)
49- **fix**: publish-docs.zig missing devlog entries 004-006
50
51## 0.2.8
52
53- **feat**: sync 1.1 — `ChildRef` union, `loadFromBlocks`, `putReturn`/`deleteReturn`, `verifyCommitDiff`
54- **feat**: `loadCommitFromCAR` returns unsigned commit bytes
55
56## 0.2.7
57
58- **feat**: `Value.getUint()` — extract unsigned integers as `?u64` from CBOR maps. `getInt()` truncates values > `i64` max; upstream AT Protocol firehose seq numbers now exceed this limit.
59
60## 0.2.6
61
62- **feat**: specialized MST decoder — `decodeMstNode()` parses known MST CBOR schema directly, zero-copy byte slicing, avoids generic `Value` union construction
63- **feat**: in-walk MST structure verification — `walkAndVerifyMst` checks key heights during traversal instead of full tree rebuild. MST step: 218ms → 39ms (5.5x), compute total: 300ms → 123ms (2.4x)
64- **docs**: devlog 005 — updated benchmark numbers and chart
65
66## 0.2.5
67
68- **feat**: O(1) block lookup in CAR parser — `StringHashMap` index built during `read()`/`readWithOptions()`, `findBlock()` uses index instead of linear scan
69- **fix**: `verifyRepo` bypasses default 2 MB / 10k block limits so large repos (e.g. pfrazee.com at 70 MB / 243k blocks) actually work
70- **docs**: devlog 005 — clarify Rust ecosystem (rsky, jacquard, hand-rolled RustCrypto)
71
72## 0.2.4
73
74- **feat**: configurable CAR size limits — `max_size` and `max_blocks` options in `readWithOptions` for large repo verification
75- **feat**: export `jwt` module (not just `Jwt` type) for direct access to `verifySecp256k1`/`verifyP256`
76- **docs**: devlog 005 — three-way trust chain verification (zig vs Go vs Rust)
77- **docs**: README rewrite — added CBOR, CAR, MST, firehose, jetstream, signing, repo verification
78
79## 0.2.3
80
81- **docs**: devlog 004 — the sig-verify saga (k256 5×52-bit field, Fermat scalar inversion, three-way bench with rsky)
82- changelog backfill for 0.2.1 and 0.2.2
83
84## 0.2.2
85
86- **feat**: CAR parser enforces size limits — 2MB max on blocks field, max block count. matches indigo's limits for production parity.
87
88## 0.2.1
89
90- **feat**: CID hash verification in CAR parser — `car.read()` SHA-256 hashes each block and compares against the CID digest. proves block content wasn't corrupted or tampered with. `readWithOptions(.{ .verify_block_hashes = false })` to skip for trusted local data.
91- **fix**: remove pfrazee.com from default test suite (network-dependent)
92
93## 0.2.0
94
95- **feat**: end-to-end repo verification — `verifyRepo(allocator, identifier)` exercises the full AT Protocol trust chain: handle → DID → DID document → signing key → fetch repo CAR → verify commit signature → walk MST → rebuild tree → CID match
96- **refactor**: organize `src/internal/` into domain subdirectories following the [TypeScript SDK](https://github.com/bluesky-social/atproto/tree/main/packages): `syntax/`, `crypto/`, `identity/`, `repo/`, `xrpc/`, `streaming/`, `testing/`
97
98## 0.1.9
99
100- **feat**: merkle search tree (MST) — `mst.Mst` with `put`, `get`, `delete`, `rootCid`
101- **feat**: ECDSA signing — `signSecp256k1`, `signP256` with low-S normalization (RFC 6979)
102- **feat**: `did:key` construction — `multicodec.formatDidKey`, `multicodec.encodePublicKey`
103- **feat**: multibase encoding — base58btc encode, base32lower encode/decode
104- interop tests: MST common prefix (13 vectors), commit proofs (6 fixtures)
105
106## 0.1.8
107
108- **fix**: NSID parser rejects TLD starting with digit (e.g. `1.0.0.127.record`)
109- **fix**: AT-URI parser validates authority (DID/handle), collection (NSID), and rkey components; rejects `#`, `?`, spaces
110- **fix**: reject high-S ECDSA signatures — atproto requires low-S normalization (BIP-62 style)
111- `verifySecp256k1` and `verifyP256` are now `pub`
112- atproto interop test suite: syntax validation (6 types), crypto signature verification (6 vectors), MST key heights (9 vectors)
113
114## 0.1.7
115
116- slim `Cid` struct from 56 to 16 bytes — store only raw bytes, parse version/codec/digest lazily on demand
117- `Value` union shrinks from 64 to 24 bytes, `MapEntry` from 80 to 40 bytes
118- zero-cost CID decode — tag 42 handler stores a byte slice reference instead of parsing varint fields
119- inline map key reading in CBOR decoder — skips full `decodeAt` + union construction per key
120- comptime size assertions for `Value` and `MapEntry`
121- **breaking**: `Cid` fields (`version`, `codec`, `hash_fn`, `digest`) are now accessor methods returning optionals — e.g. `cid.version` → `cid.version().?`
122- `parseCid` simplified to a trivial raw-bytes wrapper
123
124## 0.1.6
125
126- round-robin host rotation for jetstream and firehose clients
127- `Options.host` → `Options.hosts` with sensible defaults (bsky + community relays)
128- backoff resets on host switch, jetstream rewinds cursor by 10s
129- default jetstream hosts: 4 official bsky, waow.tech, fire.hose.cam, 6 firehose.stream regions
130- default firehose hosts: bsky.network + 3 firehose.network regions
131
132## 0.1.5
133
134- align firehose event types with AT Protocol sync spec
135
136## 0.1.4
137
138- firehose support: DAG-CBOR codec, CAR codec, CID creation, firehose client
139- encode and decode `com.atproto.sync.subscribeRepos` binary frames
140
141## 0.1.3
142
143- jetstream WebSocket client with typed events, reconnection, and cursor tracking
144- `extractAt` ignores unknown JSON fields by default
145- HTTP I/O isolated behind `HttpTransport` for 0.16 prep
146- websocket dependency pinned to specific commit
147
148## 0.1.2
149
150- `extractAt` logs diagnostic info on parse failures (enable with `.zat` debug scope)
151
152## 0.1.1
153
154- xrpc client sets `Content-Type: application/json` for POST requests
155- docs published as `site.standard.document` records on tag releases
156
157## 0.1.0
158
159sync types for firehose consumption:
160
161- `CommitAction` - `.create`, `.update`, `.delete`
162- `EventKind` - `.commit`, `.sync`, `.identity`, `.account`, `.info`
163- `AccountStatus` - `.takendown`, `.suspended`, `.deleted`, `.deactivated`, `.desynchronized`, `.throttled`
164
165these integrate with `std.json` for automatic parsing.
166
167## 0.0.2
168
169- xrpc client with gzip workaround for zig 0.15.x deflate bug
170- jwt parsing and verification
171
172## 0.0.1
173
174- string primitives (Tid, Did, Handle, Nsid, Rkey, AtUri)
175- did/handle resolution
176- json helpers