import test from 'brittle'
import { createTestDb } from './helpers.js'
import { IdentityManager } from '../lib/identity-manager.js'
test('ready() generates persistent keypair', async (t) => {
const { db, cleanup } = await createTestDb()
const mgr = new IdentityManager(db)
await mgr.ready()
t.ok(mgr.getPublicKey(), 'has public key')
t.is(mgr.getPublicKey().length, 32, 'public key is 32 bytes')
t.ok(mgr.getKeypair(), 'has keypair')
t.is(mgr.getKeypair().secretKey.length, 64, 'secret key is 64 bytes')
mgr.destroy()
await cleanup()
})
test('ready() loads existing keypair on re-init', async (t) => {
const { db, cleanup } = await createTestDb()
const mgr1 = new IdentityManager(db)
await mgr1.ready()
const pk1 = mgr1.getPublicKeyBase64()
mgr1.destroy()
const mgr2 = new IdentityManager(db)
await mgr2.ready()
const pk2 = mgr2.getPublicKeyBase64()
mgr2.destroy()
t.is(pk1, pk2, 'same keypair on re-init')
await cleanup()
})
test('getPublicKeyBase64 returns 44-char base64', async (t) => {
const { db, cleanup } = await createTestDb()
const mgr = new IdentityManager(db)
await mgr.ready()
const pk = mgr.getPublicKeyBase64()
t.is(typeof pk, 'string')
t.is(pk.length, 44, '44-char base64')
mgr.destroy()
await cleanup()
})
test('getKeypairString returns 132-char base64', async (t) => {
const { db, cleanup } = await createTestDb()
const mgr = new IdentityManager(db)
await mgr.ready()
const kp = mgr.getKeypairString()
t.is(typeof kp, 'string')
t.is(kp.length, 132, '132-char keypair')
t.is(kp.substring(0, 44), mgr.getPublicKeyBase64(), 'first 44 chars = pubkey')
mgr.destroy()
await cleanup()
})
test('getPublicKeyHex returns hex string', async (t) => {
const { db, cleanup } = await createTestDb()
const mgr = new IdentityManager(db)
await mgr.ready()
const hex = mgr.getPublicKeyHex()
t.is(typeof hex, 'string')
t.is(hex.length, 64, '64-char hex (32 bytes)')
mgr.destroy()
await cleanup()
})
test('sign and verify', async (t) => {
const { db, cleanup } = await createTestDb()
const mgr = new IdentityManager(db)
await mgr.ready()
const data = Buffer.from('test data to sign')
const sig = mgr.sign(data)
t.ok(sig, 'produces signature')
t.is(sig.length, 64, 'signature is 64 bytes')
t.ok(mgr.verify(data, sig), 'valid signature verifies')
t.absent(mgr.verify(Buffer.from('wrong data'), sig), 'wrong data fails')
mgr.destroy()
await cleanup()
})
test('setMnemonic and getMnemonic', async (t) => {
const { db, cleanup } = await createTestDb()
const mgr = new IdentityManager(db)
await mgr.ready()
t.absent(mgr.getMnemonic(), 'no mnemonic initially')
await mgr.setMnemonic('test word list here for mnemonic storage')
t.is(mgr.getMnemonic(), 'test word list here for mnemonic storage')
mgr.destroy()
await cleanup()
})
test('destroy zeros secret key', async (t) => {
const { db, cleanup } = await createTestDb()
const mgr = new IdentityManager(db)
await mgr.ready()
const secretKey = mgr.getKeypair().secretKey
mgr.destroy()
// After destroy, the buffer should be zeroed
let allZero = true
for (let i = 0; i < secretKey.length; i++) {
if (secretKey[i] !== 0) { allZero = false; break }
}
t.ok(allZero, 'secret key zeroed after destroy')
t.absent(mgr.getKeypair(), 'keypair is null after destroy')
await cleanup()
})