beeline-cli
Version:
A terminal wallet for the Hive blockchain - type, sign, rule the chain
239 lines • 11.8 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const core_1 = require("@oclif/core");
const neon_js_1 = require("../utils/neon.js");
const crypto_js_1 = require("../utils/crypto.js");
const inquirer_1 = __importDefault(require("inquirer"));
class Keys extends core_1.Command {
async run() {
const { args, flags } = await this.parse(Keys);
const keyManager = new crypto_js_1.KeyManager();
console.log(neon_js_1.neonChalk.glow(`${neon_js_1.neonSymbols.diamond} Accessing secure key vault...`));
const spinner = (0, neon_js_1.neonSpinner)('Initializing quantum encryption protocols');
await keyManager.initialize();
clearInterval(spinner);
process.stdout.write('\r' + ' '.repeat(80) + '\r');
console.log(neon_js_1.neonChalk.success(`${neon_js_1.neonSymbols.check} Key vault online`));
console.log('');
switch (args.action) {
case 'list':
await this.listKeys(keyManager);
break;
case 'import':
await this.importKey(keyManager, args.account, args.role, flags.pin);
break;
case 'remove':
await this.removeKey(keyManager, args.account, args.role, flags.force);
break;
case 'set-default':
await this.setDefault(keyManager, args.account);
break;
}
}
async listKeys(keyManager) {
const accounts = await keyManager.listAccounts();
const defaultAccount = keyManager.getDefaultAccount();
if (accounts.length === 0) {
console.log((0, neon_js_1.createNeonBox)(`${neon_js_1.neonChalk.warning('No keys found in vault')}\n\n` +
`Import keys with password login:\n` +
`${neon_js_1.neonChalk.highlight('beeline login <account>')}\n\n` +
`Or import individual keys:\n` +
`${neon_js_1.neonChalk.highlight('beeline keys import <account> <role>')}`, `${neon_js_1.neonSymbols.star} KEY VAULT ${neon_js_1.neonSymbols.star}`));
return;
}
let keyDisplay = '';
for (const account of accounts) {
const keys = await keyManager.listKeys(account);
const isDefault = account === defaultAccount;
keyDisplay += `${neon_js_1.neonChalk.glow('@' + account)}${isDefault ? neon_js_1.neonChalk.yellow(' (default)') : ''}\n`;
if (keys.length === 0) {
keyDisplay += `${neon_js_1.neonChalk.darkCyan('└─')} ${neon_js_1.neonChalk.warning('No keys imported')}\n\n`;
continue;
}
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
const isLast = i === keys.length - 1;
const connector = isLast ? '└─' : '├─';
const lockIcon = key.encrypted ? neon_js_1.neonSymbols.diamond : neon_js_1.neonSymbols.circle;
const roleColor = this.getRoleColor(key.role);
keyDisplay += `${neon_js_1.neonChalk.darkCyan(connector)} ${neon_js_1.neonChalk.cyan(lockIcon)} ${roleColor(key.role.padEnd(8))} ${neon_js_1.neonSymbols.arrow} ${neon_js_1.neonChalk.white(key.publicKey.substring(0, 20))}...\n`;
}
keyDisplay += '\n';
}
console.log((0, neon_js_1.createNeonBox)(keyDisplay.trim(), `${neon_js_1.neonSymbols.star} SECURE KEY VAULT ${neon_js_1.neonSymbols.star}`));
// Legend and commands
console.log('');
console.log(neon_js_1.neonChalk.darkCyan('Legend:'));
console.log(neon_js_1.neonChalk.darkCyan(`${neon_js_1.neonSymbols.diamond} PIN encrypted ${neon_js_1.neonSymbols.circle} OS keychain only`));
console.log('');
console.log(neon_js_1.neonChalk.info('Key management:'));
console.log(neon_js_1.neonChalk.darkCyan(`${neon_js_1.neonSymbols.bullet} Quick login: ${neon_js_1.neonChalk.highlight('beeline login <account>')}`));
console.log(neon_js_1.neonChalk.darkCyan(`${neon_js_1.neonSymbols.bullet} Manual import: ${neon_js_1.neonChalk.highlight('beeline keys import <account> <role>')}`));
console.log(neon_js_1.neonChalk.darkCyan(`${neon_js_1.neonSymbols.bullet} Account management: ${neon_js_1.neonChalk.highlight('beeline accounts list')}`));
}
async importKey(keyManager, account, role, usePin = true) {
if (!account) {
const accountPrompt = await inquirer_1.default.prompt([{
type: 'input',
name: 'account',
message: neon_js_1.neonChalk.cyan('Account name:'),
validate: (input) => input.length > 0 || 'Account name required'
}]);
account = accountPrompt.account;
}
if (!role) {
const rolePrompt = await inquirer_1.default.prompt([{
type: 'list',
name: 'role',
message: neon_js_1.neonChalk.cyan('Key role:'),
choices: [
{ name: `${neon_js_1.neonChalk.orange('posting')} - Social interactions, voting`, value: 'posting' },
{ name: `${neon_js_1.neonChalk.electric('active')} - Transfers, power operations`, value: 'active' },
{ name: `${neon_js_1.neonChalk.pink('memo')} - Private messages`, value: 'memo' },
{ name: `${neon_js_1.neonChalk.warning('owner')} - Account control (highest security)`, value: 'owner' }
]
}]);
role = rolePrompt.role;
}
const keyPrompt = await inquirer_1.default.prompt([{
type: 'password',
name: 'privateKey',
message: neon_js_1.neonChalk.cyan('Private key (WIF format):'),
validate: (input) => input.length > 0 || 'Private key required'
}]);
let pin;
if (usePin) {
const pinPrompt = await inquirer_1.default.prompt([{
type: 'password',
name: 'pin',
message: neon_js_1.neonChalk.cyan('Set encryption PIN:'),
validate: (input) => input.length >= 4 || 'PIN must be at least 4 characters'
}]);
pin = pinPrompt.pin;
}
try {
const importSpinner = (0, neon_js_1.neonSpinner)(`Importing ${role} key for ${account}`);
await keyManager.importPrivateKey(account, role, keyPrompt.privateKey, pin);
clearInterval(importSpinner);
process.stdout.write('\r' + ' '.repeat(80) + '\r');
console.log(neon_js_1.neonChalk.success(`${neon_js_1.neonSymbols.check} Key imported successfully`));
const statusMessage = [
`${neon_js_1.neonChalk.glow('Key secured in vault')}`,
``,
`Account: ${neon_js_1.neonChalk.highlight(account)}`,
`Role: ${this.getRoleColor(role)(role)}`,
`Encryption: ${usePin ? neon_js_1.neonChalk.success('PIN protected') : neon_js_1.neonChalk.warning('OS keychain only')}`,
``,
`${neon_js_1.neonChalk.info('Your key is now ready for blockchain operations')}`
].join('\n');
console.log((0, neon_js_1.createNeonBox)(statusMessage, `${neon_js_1.neonSymbols.star} IMPORT COMPLETE ${neon_js_1.neonSymbols.star}`));
// Memory scrubbing
keyManager.scrubMemory(keyPrompt.privateKey);
if (pin)
keyManager.scrubMemory(pin);
}
catch (error) {
clearInterval((0, neon_js_1.neonSpinner)(''));
process.stdout.write('\r' + ' '.repeat(80) + '\r');
console.log(neon_js_1.neonChalk.error(`${neon_js_1.neonSymbols.cross} Import failed: ${error instanceof Error ? error.message : 'Unknown error'}`));
}
}
async removeKey(keyManager, account, role, force = false) {
if (!account || !role) {
console.log(neon_js_1.neonChalk.error('Account and role required for key removal'));
return;
}
if (!force) {
const confirmPrompt = await inquirer_1.default.prompt([{
type: 'confirm',
name: 'confirm',
message: neon_js_1.neonChalk.warning(`Remove ${role} key for ${account}? This cannot be undone.`),
default: false
}]);
if (!confirmPrompt.confirm) {
console.log(neon_js_1.neonChalk.info('Operation cancelled'));
return;
}
}
try {
await keyManager.removeKey(account, role);
console.log(neon_js_1.neonChalk.success(`${neon_js_1.neonSymbols.check} Key removed from vault`));
}
catch (error) {
console.log(neon_js_1.neonChalk.error(`${neon_js_1.neonSymbols.cross} Removal failed: ${error instanceof Error ? error.message : 'Unknown error'}`));
}
}
async setDefault(keyManager, account) {
if (!account) {
const accounts = await keyManager.listAccounts();
if (accounts.length === 0) {
console.log(neon_js_1.neonChalk.warning('No accounts found in vault'));
return;
}
const accountPrompt = await inquirer_1.default.prompt([{
type: 'list',
name: 'account',
message: neon_js_1.neonChalk.cyan('Select default account:'),
choices: accounts
}]);
account = accountPrompt.account;
}
try {
await keyManager.setDefaultAccount(account);
console.log(neon_js_1.neonChalk.success(`${neon_js_1.neonSymbols.check} Default account set to ${neon_js_1.neonChalk.highlight(account)}`));
}
catch (error) {
console.log(neon_js_1.neonChalk.error(`${neon_js_1.neonSymbols.cross} Failed to set default: ${error instanceof Error ? error.message : 'Unknown error'}`));
}
}
getRoleColor(role) {
switch (role) {
case 'owner': return neon_js_1.neonChalk.warning;
case 'active': return neon_js_1.neonChalk.electric;
case 'posting': return neon_js_1.neonChalk.orange;
case 'memo': return neon_js_1.neonChalk.pink;
default: return neon_js_1.neonChalk.white;
}
}
}
Keys.description = 'Manage your encrypted key vault with neon security';
Keys.examples = [
`$ beeline keys list`,
`$ beeline keys import alice posting`,
`$ beeline keys remove alice posting`,
`$ beeline keys set-default alice`
];
Keys.flags = {
pin: core_1.Flags.boolean({
char: 'p',
description: 'use PIN encryption for key storage',
default: true
}),
force: core_1.Flags.boolean({
char: 'f',
description: 'force operation without confirmation',
default: false
})
};
Keys.args = {
action: core_1.Args.string({
description: 'action to perform',
required: false,
default: 'list',
options: ['list', 'import', 'remove', 'set-default']
}),
account: core_1.Args.string({
description: 'account name',
required: false
}),
role: core_1.Args.string({
description: 'key role (owner, active, posting, memo)',
required: false,
options: ['owner', 'active', 'posting', 'memo']
})
};
exports.default = Keys;
//# sourceMappingURL=keys.js.map