# [zat](https://zat.dev) AT Protocol building blocks for zig.
this readme is an ATProto record → [view in zat.dev's repository](https://at-me.zzstoatzz.io/view?handle=zat.dev) zat publishes these docs as [`site.standard.document`](https://standard.site) records, signed by its DID.
## install ```bash zig fetch --save https://tangled.sh/zat.dev/zat/archive/main ``` then in `build.zig`: ```zig const zat = b.dependency("zat", .{}).module("zat"); exe.root_module.addImport("zat", zat); ``` ## what's here
string primitives - parsing and validation for atproto identifiers - **Tid** - timestamp identifiers (base32-sortable) - **Did** - decentralized identifiers - **Handle** - domain-based handles - **Nsid** - namespaced identifiers (lexicon types) - **Rkey** - record keys - **AtUri** - `at://` URIs ```zig const zat = @import("zat"); if (zat.AtUri.parse(uri_string)) |uri| { const authority = uri.authority(); const collection = uri.collection(); const rkey = uri.rkey(); } ```
did resolution - resolve did:plc and did:web to documents ```zig var resolver = zat.DidResolver.init(allocator); defer resolver.deinit(); const did = zat.Did.parse("did:plc:z72i7hdynmk6r22z27h6tvur").?; var doc = try resolver.resolve(did); defer doc.deinit(); const handle = doc.handle(); // "bsky.app" const pds = doc.pdsEndpoint(); // "https://..." const key = doc.signingKey(); // verification method ```
handle resolution - resolve handles to DIDs via HTTP well-known ```zig var resolver = zat.HandleResolver.init(allocator); defer resolver.deinit(); const handle = zat.Handle.parse("bsky.app").?; const did = try resolver.resolve(handle); defer allocator.free(did); // did = "did:plc:z72i7hdynmk6r22z27h6tvur" ```
xrpc client - call AT Protocol endpoints ```zig var client = zat.XrpcClient.init(allocator, "https://bsky.social"); defer client.deinit(); const nsid = zat.Nsid.parse("app.bsky.actor.getProfile").?; var response = try client.query(nsid, params); defer response.deinit(); if (response.ok()) { var json = try response.json(); defer json.deinit(); // use json.value } ```
sync types - enums for firehose/event stream consumption ```zig // use in struct definitions for automatic json parsing: const RepoOp = struct { action: zat.CommitAction, // .create, .update, .delete path: []const u8, cid: ?[]const u8, }; // then exhaustive switch: switch (op.action) { .create, .update => processUpsert(op), .delete => processDelete(op), } ``` - **CommitAction** - `.create`, `.update`, `.delete` - **EventKind** - `.commit`, `.sync`, `.identity`, `.account`, `.info` - **AccountStatus** - `.takendown`, `.suspended`, `.deleted`, `.deactivated`, `.desynchronized`, `.throttled`
json helpers - navigate nested json without verbose if-chains ```zig // runtime paths for one-offs: const uri = zat.json.getString(value, "embed.external.uri"); const count = zat.json.getInt(value, "meta.count"); // comptime extraction for complex structures: const FeedPost = struct { uri: []const u8, cid: []const u8, record: struct { text: []const u8 = "", }, }; const post = try zat.json.extractAt(FeedPost, allocator, value, .{"post"}); ```
jwt verification - verify service auth tokens ```zig var jwt = try zat.Jwt.parse(allocator, token_string); defer jwt.deinit(); // check claims if (jwt.isExpired()) return error.TokenExpired; if (!std.mem.eql(u8, jwt.payload.aud, expected_audience)) return error.InvalidAudience; // verify signature against issuer's public key (from DID document) try jwt.verify(public_key_multibase); ``` supports ES256 (P-256) and ES256K (secp256k1) signing algorithms.
multibase decoding - decode public keys from DID documents ```zig const key_bytes = try zat.multibase.decode(allocator, "zQ3sh..."); defer allocator.free(key_bytes); const parsed = try zat.multicodec.parsePublicKey(key_bytes); // parsed.key_type: .secp256k1 or .p256 // parsed.raw: 33-byte compressed public key ```
## specs validation follows [atproto.com/specs](https://atproto.com/specs/atp). ## versioning pre-1.0 semver: - `0.x.0` - new features (backwards compatible) - `0.x.y` - bug fixes breaking changes bump the minor version and are documented in commit messages. ## license MIT --- [roadmap](docs/roadmap.md) · [changelog](CHANGELOG.md)