OverviewFilesCommitsIssuesDocsReleasesPeers

atproto-repo commits / 53e2594

docs: add README
Package purpose, module map, API, usage, and its place in the atproto-base self-custody stack (atproto-repo → atproto-store → atproto-identity → hyper-proto-peer → atproto-bridge). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
53e2594ef16a1ce1581e6ab34f9a3a0c0f04d592
by plankatron <fleeky@gmail.com> · 2026-07-05T21:46:45.000Z

Changed files (1) +59 -0

README.md +59 -0
……@@ -0,0 +1,59 @@
1# atproto-repo
2
3Byte-exact **AT Protocol repository serialization** — CAR + DAG-CBOR + CID + MST +
4signed commits — implemented in pure JS over Hypercore-friendly primitives. This is the
5*wire layer*: it turns a set of records into the exact bytes a real Bluesky relay accepts,
6and reads them back. Verified against the official atproto interop test vectors (CID
7heights, MST structure, commit proofs, low-S signatures).
8
9Part of the **atproto-base** self-custody stack:
10
11```
12atproto-repo ← you are here (serialization / codec)
13atproto-store P2P-native repo storage (Hyperbee)
14atproto-identity seed-anchored did:plc identity + auth
15hyper-proto-peer the self-custody peer (multi-device swarm PDS)
16atproto-bridge keyless membrane → Bluesky
17```
18
19## What it does
20
21- **CID** (`lib/cid.js`) — CIDv1 dag-cbor/sha-256, byte-exact. `cidForBytesSync`,
22 `cidForValue`, `cidForBlobSync`.
23- **MST** (`lib/mst.js`) — the Merkle Search Tree that determines every repo root CID.
24 `buildMst`, `keyHeight` (leading-zero-nibble fanout), `MSTNode`. Matches the interop
25 `key_heights` / `common_prefix` fixtures exactly.
26- **Commit** (`lib/commit.js`) — `unsignedCommit`, `signCommit` (ECDSA-secp256k1 **low-S**
27 over sha-256 of the dag-cbor unsigned commit), `commitCid`, `verifyCommit`.
28- **CAR** (`lib/car.js`) — `readCar` / `writeCar` (the IPLD Content-Addressed aRchive that
29 `com.atproto.sync.getRepo` returns).
30- **Repo** (`lib/repo.js`, main) — assemble/verify a full repo: `createRepo`, `loadCommit`,
31 `verifyRepo`, `listRecords`, plus the firehose proof helpers (`firehoseProofBlocks`,
32 `findRpathProof`, `reachableBlocks`) a `#commit` event must carry.
33
34## Usage
35
36```js
37import { signCommit, unsignedCommit, commitCid } from 'atproto-repo/lib/commit.js'
38import { cidForValue } from 'atproto-repo/lib/cid.js'
39import { writeCar } from 'atproto-repo/lib/car.js'
40
41const unsigned = unsignedCommit({ did, rev, data: mstRootCid, prev })
42const signed = signCommit(unsigned, privateKey) // secp256k1 low-S
43const cid = commitCid(signed)
44```
45
46## Design notes
47
48- **Pure JS crypto** (`@noble/curves`, `@noble/hashes`) — no Node `crypto` global, so it
49 runs unchanged under **Bare**. Signatures are canonical low-S, raw (r‖s), never DER.
50- **Serializer, not storage.** The P2P home for records is
51 [`atproto-store`](../atproto-store) (a Hyperbee); this module serializes *over* it.
52- Conformance is the whole point — if our output disagrees with an interop fixture, our
53 code is wrong. See the `atproto-interop-tests` fixtures.
54
55## Test
56
57```
58bare test/all.js # or: npm test
59```