// createSwarmIdentity — the atproto-base swarm genesis with a SEPARATE root recovery key.
// The custody invariant (atproto-base-REVOCATION.md §4-5): the shared #atproto signing key
// (distributed to devices) is NOT a rotation key; the root recovery key (never on devices) is the
// sole rotation authority. So a device that holds only the signing key cannot rotate/revoke the DID.
import test from 'brittle'
import { createSwarmIdentity, deriveAtprotoKey, ATPROTO_SIGNING_PATH, ATPROTO_RECOVERY_PATH } from '../lib/atproto-identity.js'
import { checkGenesisOp, verifyOpSignedByAny } from '../lib/plc-directory.js'
const MNEMONIC = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about'
const HANDLE = 'swarmtest.example.com'
const PDS = 'https://pds.example.com'
test('recovery key is the sole rotation authority; the shared signing key only signs commits', (t) => {
const id = createSwarmIdentity(MNEMONIC, { handle: HANDLE, pdsUrl: PDS })
const signing = deriveAtprotoKey(MNEMONIC, ATPROTO_SIGNING_PATH)
const recovery = deriveAtprotoKey(MNEMONIC, ATPROTO_RECOVERY_PATH)
t.not(signing.didKey, recovery.didKey, 'signing and recovery keys are distinct paths')
t.is(id.signingKey.didKey, signing.didKey, 'signingKey = SIGNING_PATH (distributed to devices)')
t.is(id.recoveryKey.didKey, recovery.didKey, 'recoveryKey = RECOVERY_PATH (root-only)')
t.is(id.signedOp.verificationMethods.atproto, signing.didKey, 'vm.atproto = shared signing key')
t.alike(id.signedOp.rotationKeys, [recovery.didKey], 'rotationKeys = [recovery key] only')
t.absent(id.signedOp.rotationKeys.includes(signing.didKey), 'the shared signing key has NO rotation authority')
})
test('genesis is valid and signed BY the recovery key (not the signing key)', (t) => {
const id = createSwarmIdentity(MNEMONIC, { handle: HANDLE, pdsUrl: PDS })
const chk = checkGenesisOp(id.signedOp, id.did)
t.ok(chk.ok, 'checkGenesisOp passes: ' + (chk.error || 'ok'))
t.is(chk.did, id.did, 'DID matches the op hash')
t.ok(verifyOpSignedByAny(id.signedOp, [id.recoveryKey.didKey]), 'signed by the recovery key')
t.absent(verifyOpSignedByAny(id.signedOp, [id.signingKey.didKey]), 'NOT signed by the signing key')
})
test('deterministic: same root + handle + pds reproduces the same DID', (t) => {
const a = createSwarmIdentity(MNEMONIC, { handle: HANDLE, pdsUrl: PDS })
const b = createSwarmIdentity(MNEMONIC, { handle: HANDLE, pdsUrl: PDS })
t.is(a.did, b.did, 'reproducible DID')
})