// SwarmDevice end-to-end (real StateBaseV3, single device): write repo intents → the lease-holder
// materializes the linearized view into the canonical signed atproto commit chain, continuing
// from the last head. This is the atproto-base core proven at the daemon level, under bare.
import '../lib/bare-globals.js'
import test from 'brittle'
import crypto from 'hypercore-crypto'
import fs from 'bare-fs'
import { secp256k1 } from '@noble/curves/secp256k1'
import { verifyCommit } from 'atproto-repo/lib/commit.js'
import { StateBaseV3 } from 'atproto-room/lib/state-base.js'
import { SwarmDevice } from '../lib/swarm-device.js'
const PRIV = new Uint8Array(Buffer.from('9085d2bef69286a6cbb51623c8fa258629945cd55ca705cc4e66700396894e0c', 'hex'))
const PUB = secp256k1.getPublicKey(PRIV, true)
const DID = 'did:plc:test22222222222222222222'
const POST = 'app.bsky.feed.post'
function tmp () { const d = '/tmp/hpp-dev-' + Math.floor(Math.random() * 1e9); fs.mkdirSync(d, { recursive: true }); return d }
test('device loop: intents → lease-holder signs → continue-from-head chain', async (t) => {
const sb = new StateBaseV3(tmp(), crypto.randomBytes(32), { roomSeed: crypto.randomBytes(32), network: false })
await sb.ready()
t.teardown(() => sb.close())
const dev = new SwarmDevice(sb, { did: DID, privateKey: PRIV, self: 'deviceA' })
t.is(await dev.sign(), null, 'without the lease, does not sign')
await dev.claimLease()
t.ok(await dev.holdsLease(), 'holds the lease')
await dev.putRecord(POST, '3a', { $type: POST, text: 'a', createdAt: '2026-07-04T00:00:00.000Z' })
await dev.putRecord(POST, '3b', { $type: POST, text: 'b', createdAt: '2026-07-04T00:00:00.000Z' })
const h1 = await dev.sign()
t.ok(h1 && h1.commitCid, 'signed commit 1')
t.is(h1.signedCommit.prev, null, 'first commit prev = null')
t.is(h1.recordBlocks.length, 2, 'commit 1 covers 2 records')
t.ok(verifyCommit(h1.signedCommit, PUB), 'commit 1 verifies against the shared key')
t.is(await dev.sign(), null, 'no new intents → no new commit')
await dev.putRecord(POST, '3c', { $type: POST, text: 'c', createdAt: '2026-07-04T00:00:01.000Z' })
const h2 = await dev.sign()
t.ok(h2 && h2.commitCid, 'signed commit 2')
t.ok(h2.signedCommit.prev.equals(h1.commitCid), 'commit 2 prev == commit 1 (continue-from-head)')
t.absent(h2.dataCid.equals(h1.dataCid), 'data root advanced with the new record')
t.ok(verifyCommit(h2.signedCommit, PUB), 'commit 2 verifies')
// a delete is an intent too → chain advances again
await dev.deleteRecord(POST, '3a')
const h3 = await dev.sign()
t.ok(h3.signedCommit.prev.equals(h2.commitCid), 'commit 3 continues from commit 2')
t.is(h3.recordBlocks.length, 2, 'delete removed a record from the signed set')
})