diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..3aa6dd8
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2025 nate nowack
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
index 6ce355e..45bb4df 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@ zig primitives for AT Protocol.
## install
```bash
-zig fetch --save https://tangled.org/zzstoatzz.io/zat/archive/main
+zig fetch --save https://tangled.sh/zzstoatzz.io/zat/archive/main
```
then in `build.zig`:
@@ -17,9 +17,8 @@ exe.root_module.addImport("zat", zat);
## what's here
-### string primitives
-
-parsing and validation for atproto string identifiers:
+
+string primitives - parsing and validation for atproto identifiers
- **Tid** - timestamp identifiers (base32-sortable)
- **Did** - decentralized identifiers
@@ -38,9 +37,10 @@ if (zat.AtUri.parse(uri_string)) |uri| {
}
```
-### did resolution
+
-resolve `did:plc` and `did:web` identifiers to their documents:
+
+did resolution - resolve did:plc and did:web to documents
```zig
var resolver = zat.DidResolver.init(allocator);
@@ -55,9 +55,10 @@ const pds = doc.pdsEndpoint(); // "https://..."
const key = doc.signingKey(); // verification method
```
-### handle resolution
+
-resolve handles to DIDs via HTTP well-known:
+
+handle resolution - resolve handles to DIDs via HTTP well-known
```zig
var resolver = zat.HandleResolver.init(allocator);
@@ -69,9 +70,10 @@ defer allocator.free(did);
// did = "did:plc:z72i7hdynmk6r22z27h6tvur"
```
-### xrpc client
+
-call AT Protocol endpoints:
+
+xrpc client - call AT Protocol endpoints
```zig
var client = zat.XrpcClient.init(allocator, "https://bsky.social");
@@ -88,9 +90,10 @@ if (response.ok()) {
}
```
-### json helpers
+
-navigate nested json without verbose if-chains:
+
+json helpers - navigate nested json without verbose if-chains
```zig
// runtime paths for one-offs:
@@ -108,9 +111,10 @@ const FeedPost = struct {
const post = try zat.json.extractAt(FeedPost, allocator, value, .{"post"});
```
-### jwt verification
+
-verify service auth tokens:
+
+jwt verification - verify service auth tokens
```zig
var jwt = try zat.Jwt.parse(allocator, token_string);
@@ -126,9 +130,10 @@ try jwt.verify(public_key_multibase);
supports ES256 (P-256) and ES256K (secp256k1) signing algorithms.
-### multibase decoding
+
-decode public keys from DID documents:
+
+multibase decoding - decode public keys from DID documents
```zig
const key_bytes = try zat.multibase.decode(allocator, "zQ3sh...");
@@ -139,6 +144,12 @@ const parsed = try zat.multicodec.parsePublicKey(key_bytes);
// parsed.raw: 33-byte compressed public key
```
+
+
## specs
validation follows [atproto.com/specs](https://atproto.com/specs/atp).
+
+## license
+
+MIT