// The goal proof: TWO attested devices of ONE DID share one repo. Device B (a second attested
// device) writes a repo intent; device A admits it via the attestation-admission path; the
// linearized view converges so BOTH devices see the record. Real StateBaseV3 replication over a
// local testnet. This is multi-device — N equal devices, one DID.
import '../lib/bare-globals.js'
import test from 'brittle'
import crypto from 'hypercore-crypto'
import fs from 'bare-fs'
import b4a from 'b4a'
import createTestnet from '@hyperswarm/testnet'
import { StateBaseV3 } from 'atproto-room/lib/state-base.js'
import { RepoBase } from 'atproto-room/lib/repo-base.js'
import { makeAttest, makeVerifyAttest, attestDeviceChain, deviceKeetKeyPair, rootIdentityPublicKey } from 'atproto-room/lib/membership.js'
const ROOT = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about'
const DEVA = 'legal winner thank year wave sausage worth useful legal winner thank yellow'
const DEVB = 'zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong'
const DID = 'did:plc:swarm2222222222222222222'
const POST = 'app.bsky.feed.post'
function tmp () { const d = '/tmp/hpp-md-' + Math.floor(Math.random() * 1e9); fs.mkdirSync(d, { recursive: true }); return d }
const sleep = (ms) => new Promise(r => setTimeout(r, ms))
test('two attested devices of one DID share one repo', async (t) => {
const testnet = await createTestnet(3)
const rootPub = await rootIdentityPublicKey(ROOT)
const devA = await deviceKeetKeyPair(DEVA); const proofA = await attestDeviceChain({ rootMnemonic: ROOT, devicePublicKey: devA.publicKey })
const devB = await deviceKeetKeyPair(DEVB); const proofB = await attestDeviceChain({ rootMnemonic: ROOT, devicePublicKey: devB.publicKey })
const members = [
{ key: b4a.toString(devA.publicKey, 'hex'), role: 1 },
{ key: b4a.toString(devB.publicKey, 'hex'), role: 1 }
]
const roomSeed = crypto.randomBytes(32); const roomKey = crypto.randomBytes(32); const encryptionKey = crypto.randomBytes(32)
const mk = (dev, proof) => new StateBaseV3(tmp(), roomKey, {
roomSeed, encryptionKey, swarmOpts: { bootstrap: testnet.bootstrap },
selfKey: dev.publicKey, attest: makeAttest(dev, proof), verifyAttest: makeVerifyAttest(rootPub),
getMembers: async () => members
})
const A = mk(devA, proofA); await A.ready()
await A.projectMembers(members) // seed the __members__/__devices__ roster
const B = mk(devB, proofB); await B.ready()
t.teardown(async () => { try { await A.close(); await B.close() } catch {} ; await testnet.destroy() })
// B (second device) writes a repo intent — admitted by A via attestation, then it linearizes.
const rbB = new RepoBase(B, { did: DID })
const rec = { $type: POST, text: 'posted from device B', createdAt: '2026-07-04T00:00:00.000Z' }
let admitted = false
for (let i = 0; i < 40 && !admitted; i++) {
try { await rbB.putRecord(POST, '3fromB', rec) } catch {}
await B.set('__ping__', { i }).catch(() => {}) // nudge replication/admission
await sleep(1500)
admitted = await B.effectiveWritable().catch(() => false)
}
t.ok(admitted, 'device B was admitted as a writer via attestation')
// convergence: A (the other device) sees B's record
const rbA = new RepoBase(A, { did: DID })
let seen = null
for (let i = 0; i < 30 && !seen; i++) { await A.base.update().catch(() => {}); seen = await rbA.getRecord(POST, '3fromB'); if (!seen) await sleep(1000) }
t.ok(seen && seen.text === rec.text, "device A sees device B's record (one shared repo)")
})