// Emit a CAR that is byte-identical to lib/signer.js's materialize() output, for the goat
// external-oracle cross-check (scripts/goat-cross-check.sh). We build the CAR via atproto-repo's
// createRepo (which carries the MST node blocks needed to assemble a CAR) and ASSERT it matches
// signer.materialize's dataCid/commitCid — so the bytes goat verifies are exactly the signer's.
// Prints the expected {did, commitCid, dataCid, records} as JSON so the cross-check can compare
// goat's independent parse against them. Run: bare scripts/emit-signer-car.mjs
import '../lib/bare-globals.js'
import { writeFileSync } from 'bare-fs'
import b4a from 'b4a'
import { materialize } from '../lib/signer.js'
import { createRepo } from 'atproto-repo/lib/repo.js'
import { deriveAtprotoKey } from 'atproto-identity'
import { tidNow } from 'atproto-store/lib/tid.js'
const OUT = '/tmp/hpp-signer-repo.car'
const MNEMONIC = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about'
const DID = 'did:plc:yu4kgcktm7qtrwo5ofyiaf4c'
// rev + post rkeys MUST be valid 13-char TIDs (what a real atproto consumer requires) — this is
// what SwarmDevice.sign() uses in production (tidNow). Fixed micros -> deterministic TIDs here.
const REV = tidNow(0, () => 1_780_000_000_000_000n)
const RK1 = tidNow(0, () => 1_780_000_000_000_001n)
const RK2 = tidNow(0, () => 1_780_000_000_000_002n)
const RECORDS = [
{ collection: 'app.bsky.feed.post', rkey: RK1, record: { $type: 'app.bsky.feed.post', text: 'first', createdAt: '2026-07-01T00:00:00.000Z' } },
{ collection: 'app.bsky.feed.post', rkey: RK2, record: { $type: 'app.bsky.feed.post', text: 'second', createdAt: '2026-07-01T00:00:01.000Z' } },
{ collection: 'app.bsky.actor.profile', rkey: 'self', record: { $type: 'app.bsky.actor.profile', displayName: 'test' } }
]
const key = deriveAtprotoKey(MNEMONIC)
const sig = materialize(RECORDS, { did: DID, rev: REV, prev: null, privateKey: key.privateKey })
const repo = await createRepo({ records: RECORDS, did: DID, rev: REV, privateKey: key.privateKey })
if (!sig.dataCid.equals(repo.dataCid) || !sig.commitCid.equals(repo.commitCid)) {
console.error('EQUIVALENCE FAIL: the CAR does not match signer.materialize output'); process.exit(1)
}
writeFileSync(OUT, b4a.from(repo.carBytes))
console.log(JSON.stringify({
did: DID,
commitCid: sig.commitCid.toString(),
dataCid: sig.dataCid.toString(),
records: RECORDS.map((r) => r.collection + '/' + r.rkey),
car: OUT,
bytes: repo.carBytes.length
}))
process.exit(0)