import fs from '#node:fs'
import os from '#node:os'
import path from '#node:path'
import process from '#node:process'
import b4a from 'b4a'
import HypercoreId from 'hypercore-id-encoding'
function homedir () {
if (os.homedir) return os.homedir()
return process.env.HOME || process.env.USERPROFILE || '.'
}
const DEFAULT_VAULT = () => path.join(homedir(), '.hyperident')
/**
* Load the device keyPair straight from the hyperident vault.
*
* `device.key` is a 64-byte libsodium Ed25519 secret key (hex) and `device.pub`
* the 32-byte public key (hex) — both stored plaintext regardless of any vault
* passphrase. A libsodium 64-byte secret is `seed(32) || pub(32)`, and this is
* itself a valid hyperdht keyPair, so it can be passed straight to
* `server.listen(keyPair)` / `node.connect(pubkey, { keyPair })` — the shell's
* address then equals the device pubkey. No keyfile is written to disk.
*
* Reads only via `#node:fs` (bare-fs on bare) — no pgh/hyperident runtime dep.
*/
export function loadDeviceKeyPair (vault = DEFAULT_VAULT()) {
let secretHex, publicHex
try {
secretHex = fs.readFileSync(path.join(vault, 'device.key'), 'utf8').trim()
publicHex = fs.readFileSync(path.join(vault, 'device.pub'), 'utf8').trim()
} catch (e) {
if (e.code === 'ENOENT') {
throw new Error('no hyperident device identity at ' + vault + ' — run `pgh init` first')
}
throw e
}
const secretKey = b4a.from(secretHex, 'hex')
const publicKey = b4a.from(publicHex, 'hex')
if (secretKey.length !== 64 || publicKey.length !== 32) {
throw new Error('unexpected device key sizes (secret=' + secretKey.length + ' public=' + publicKey.length + ')')
}
return {
publicKey,
secretKey,
pub: HypercoreId.encode(publicKey), // z-base32 — the shell address
publicKeyHex: publicHex
}
}
export { serve } from './lib/server.js'
export { connect } from './lib/client.js'