import test from 'brittle'
import crypto from 'hypercore-crypto'
import bip39 from 'bip39-mnemonic'
import { ServerIdentity } from '../../lib/p2p/identity/server-identity.js'
import fs from 'bare-fs'
import path from 'bare-path'
import os from 'bare-os'
const { entropyToMnemonic, mnemonicToEntropy, validateMnemonic } = bip39
test('server key seed encodes as 24-word BIP39 mnemonic', (t) => {
const keypair = crypto.keyPair()
const seed = keypair.secretKey.subarray(0, 32)
const mnemonic = entropyToMnemonic(seed)
const words = mnemonic.split(' ')
t.is(words.length, 24, '32 bytes = 256 bits = 24 words')
t.ok(validateMnemonic(mnemonic), 'valid BIP39 mnemonic')
})
test('mnemonic round-trips to same keypair', (t) => {
const keypair = crypto.keyPair()
const seed = keypair.secretKey.subarray(0, 32)
const mnemonic = entropyToMnemonic(seed)
const recoveredSeed = mnemonicToEntropy(mnemonic)
const recoveredKeypair = crypto.keyPair(Buffer.from(recoveredSeed))
t.alike(recoveredKeypair.publicKey, keypair.publicKey, 'same public key')
t.alike(recoveredKeypair.secretKey, keypair.secretKey, 'same secret key')
})
test('ServerIdentity.toMnemonic() and initFromMnemonic() round-trip', async (t) => {
const suffix = Date.now() + '-' + Math.random().toString(36).slice(2)
const tmpDir = path.join(os.tmpdir(), 'pear-git-mnemonic-test-' + suffix)
const tmpDir2 = path.join(os.tmpdir(), 'pear-git-mnemonic-test2-' + suffix)
try {
// Manually create identity (bypass _generateIdentity's StorageLocator check)
const keypair = crypto.keyPair()
fs.mkdirSync(tmpDir, { recursive: true })
fs.writeFileSync(
path.join(tmpDir, 'server-identity.json'),
JSON.stringify({
publicKey: keypair.publicKey.toString('hex'),
secretKey: keypair.secretKey.toString('hex'),
createdAt: Date.now()
}, null, 2),
{ mode: 0o600 }
)
const identity = new ServerIdentity({ storagePath: tmpDir })
await identity.init()
const mnemonic = identity.toMnemonic()
t.is(mnemonic.split(' ').length, 24, '24-word mnemonic')
const restored = new ServerIdentity({ storagePath: tmpDir2 })
await restored.initFromMnemonic(mnemonic)
t.alike(restored.publicKey, identity.publicKey, 'same public key')
t.alike(restored.secretKey, identity.secretKey, 'same secret key')
// Verify the saved file has restoredFromMnemonic flag
const saved = JSON.parse(fs.readFileSync(path.join(tmpDir2, 'server-identity.json'), 'utf-8'))
t.is(saved.restoredFromMnemonic, true, 'restoredFromMnemonic flag set')
} finally {
try { fs.rmSync(tmpDir, { recursive: true }) } catch {}
try { fs.rmSync(tmpDir2, { recursive: true }) } catch {}
}
})