OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-proto-peer / test / device-custody.test.js

60 lines · javascript ref:
// Slice 2 (custody): a device boots from a provisioned BUNDLE, never the root mnemonic
// (atproto-base-REVOCATION.md §4). The root runs provisionDevice (holds the mnemonic → recovery +
// signing keys, attests the device); the device receives { did, signingKey, deviceProof,
// rootIdentityKey } and nothing more. This is what makes the recovery key real — a device that
// doesn't hold the root can't derive the recovery key or self-recover.

import '../lib/bare-globals.js'
import test from 'brittle'
import b4a from 'b4a'
import { provisionDevice, bootSwarmDevice } from '../lib/device-node.js'
import { makeAttest, makeVerifyAttest, deviceKeetKeyPair } from 'atproto-room/lib/membership.js'
import { createSwarmIdentity } from 'atproto-identity'

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 HANDLE = 'swarmtest.example.com'
const PDS = 'https://pds.example.com'
const POST = 'app.bsky.feed.post'

test('provisionDevice: bundle carries the DID/signing key/attestation but NOT the root', async (t) => {
  const dev = await deviceKeetKeyPair(DEVA)
  const bundle = await provisionDevice({ rootMnemonic: ROOT, devicePublicKey: dev.publicKey, handle: HANDLE, pdsUrl: PDS })
  const id = createSwarmIdentity(ROOT, { handle: HANDLE, pdsUrl: PDS })
  t.is(bundle.did, id.did, 'bundle DID = createSwarmIdentity DID')
  t.is(bundle.signingKey, b4a.toString(id.signingKey.privateKey, 'hex'), 'bundle carries the shared signing key')
  t.ok(bundle.deviceProof && bundle.rootIdentityKey, 'bundle carries the attestation + root identity pubkey')
  t.absent('rootMnemonic' in bundle || 'recoveryKey' in bundle, 'bundle does NOT carry the root mnemonic or recovery key')
})

test('the hex-serialized attestation from the bundle still verifies to (root, device)', async (t) => {
  const dev = await deviceKeetKeyPair(DEVA)
  const bundle = await provisionDevice({ rootMnemonic: ROOT, devicePublicKey: dev.publicKey, handle: HANDLE, pdsUrl: PDS })
  const attest = makeAttest(dev, b4a.from(bundle.deviceProof, 'hex')) // exactly how bootSwarmDevice decodes it
  const verify = makeVerifyAttest(b4a.from(bundle.rootIdentityKey, 'hex'))
  const signData = b4a.from('admission-bytes-test')
  const ok = await verify(await attest(signData), signData, dev.publicKey)
  t.ok(ok, 'attestation built from the hex-round-tripped proof verifies to (root, device)')
})

test('bootSwarmDevice boots from the bundle (no root mnemonic) and signs', async (t) => {
  const dev = await deviceKeetKeyPair(DEVA)
  const bundle = await provisionDevice({ rootMnemonic: ROOT, devicePublicKey: dev.publicKey, handle: HANDLE, pdsUrl: PDS })
  const node = await bootSwarmDevice({
    storage: '/tmp/hpp-custody-' + Math.floor(Math.random() * 1e9),
    deviceMnemonic: DEVA,
    did: bundle.did, signingKey: bundle.signingKey, deviceProof: bundle.deviceProof, rootIdentityKey: bundle.rootIdentityKey,
    handle: HANDLE, pdsUrl: PDS, swarm: false, control: false, signIntervalMs: 0
  })
  t.is(node.did, bundle.did, 'device booted on the provisioned DID')
  await node.device.putRecord(POST, '3mmwu7vak2000', { $type: POST, text: 'hi', createdAt: '2026-07-04T00:00:00.000Z' })
  await node.device.claimLease()
  const head = await node.device.sign()
  t.ok(head && head.commitCid, 'the device signed a commit with the received signing key')
  await node.close()
})

test('bootSwarmDevice refuses without the bundle (cannot fall back to the root)', async (t) => {
  await t.exception(() => bootSwarmDevice({ storage: '/tmp/hpp-x', deviceMnemonic: DEVA, handle: HANDLE, pdsUrl: PDS, swarm: false, control: false }), /bundle/, 'no bundle -> refuses')
})