#!/usr/bin/env node
/**
* Mini CLI example for anproto
*
* Demonstrates the canonical 4 functions: gen → hash → sign → open
*
* Usage:
* node examples/cli.js gen Generate a new keypair
* node examples/cli.js hash <data> Hash some data
* node examples/cli.js sign <hash> <keypair> Sign a hash
* node examples/cli.js open <signature> Open a signature
* node examples/cli.js demo Run a full round-trip
* node examples/cli.js challenges Demo the Challenges helper
*/
import { an, Challenges } from '../index.js'
const args = process.argv.slice(2)
const cmd = args[0]
async function main () {
if (cmd === 'gen') {
const k = await an.gen()
console.log('keypair: %s', k)
console.log('pubkey: %s', an.publicKey(k))
} else if (cmd === 'hash') {
const data = args[1]
if (!data) { console.error('Usage: cli.js hash <data>'); process.exit(1) }
const h = await an.hash(data)
console.log(h)
} else if (cmd === 'sign') {
const h = args[1]
const k = args[2]
if (!h || !k) { console.error('Usage: cli.js sign <hash> <keypair>'); process.exit(1) }
const sig = await an.sign(h, k)
console.log(sig)
} else if (cmd === 'open') {
const sig = args[1]
if (!sig) { console.error('Usage: cli.js open <signature>'); process.exit(1) }
try {
const opened = await an.open(sig)
const parsed = an.parse(opened)
console.log('opened: %s', opened)
console.log('timestamp: %d (%s)', parsed.timestamp, new Date(parsed.timestamp).toISOString())
console.log('hash: %s', parsed.hash)
} catch (err) {
console.error('Invalid signature: %s', err.message)
process.exit(1)
}
} else if (cmd === 'demo') {
console.log('--- ANProto round-trip demo ---\n')
const message = args[1] || 'Hello, ANProto!'
console.log('1. Generate keypair')
const k = await an.gen()
console.log(' keypair: %s\n', k)
console.log('2. Hash message: %j', message)
const h = await an.hash(message)
console.log(' hash: %s\n', h)
console.log('3. Sign hash')
const sig = await an.sign(h, k)
console.log(' sig: %s\n', sig)
console.log('4. Open signature')
const opened = await an.open(sig)
const parsed = an.parse(opened)
console.log(' opened: %s', opened)
console.log(' timestamp: %d (%s)', parsed.timestamp, new Date(parsed.timestamp).toISOString())
console.log(' hash: %s\n', parsed.hash)
console.log('5. Verify hash matches')
console.log(' match: %s', parsed.hash === h ? 'YES ✓' : 'NO ✗')
} else if (cmd === 'challenges') {
console.log('--- Challenges helper demo ---\n')
const c = new Challenges({ ttl: 5000 })
console.log('Generate 3 challenges:')
const c1 = c.generate()
const c2 = c.generate()
const c3 = c.generate()
console.log(' c1: %s', c1)
console.log(' c2: %s', c2)
console.log(' c3: %s', c3)
console.log(' active: %d\n', c.size)
console.log('Consume c2:')
console.log(' consume(c2): %s', c.consume(c2))
console.log(' consume(c2): %s (single-use)', c.consume(c2))
console.log(' active: %d\n', c.size)
console.log('Verify c1 still active:')
console.log(' has(c1): %s', c.has(c1))
console.log(' has(c2): %s', c.has(c2))
console.log(' has(c3): %s', c.has(c3))
c.destroy()
} else {
console.log('anproto example CLI')
console.log(' gen Generate a keypair')
console.log(' hash <data> Hash data')
console.log(' sign <hash> <keypair> Sign a hash')
console.log(' open <signature> Open a signature')
console.log(' demo [message] Full round-trip demo')
console.log(' challenges Replay-protection helper demo')
}
}
main().catch((err) => { console.error(err.message); process.exit(1) })