beeline-cli
Version:
A terminal wallet for the Hive blockchain - type, sign, rule the chain
231 lines • 12.6 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 hive_js_1 = require("../utils/hive.js");
const inquirer_1 = __importDefault(require("inquirer"));
class Claim extends core_1.Command {
async run() {
const { args, flags } = await this.parse(Claim);
const keyManager = new crypto_js_1.KeyManager();
await keyManager.initialize();
let account = args.account || flags.from;
// Clean @ prefix if provided
if (account?.startsWith('@')) {
account = account.substring(1);
}
// Use default account if no account specified
if (!account) {
account = keyManager.getDefaultAccount();
if (!account) {
console.log(neon_js_1.neonChalk.warning(`${neon_js_1.neonSymbols.cross} No account specified and no default account set`));
console.log(neon_js_1.neonChalk.info('Import a key first with: ') + neon_js_1.neonChalk.highlight('beeline keys import <account> posting'));
return;
}
}
console.log(neon_js_1.neonChalk.glow(`${neon_js_1.neonSymbols.diamond} Checking available rewards...`));
console.log('');
const spinner = (0, neon_js_1.neonSpinner)('Fetching reward balances');
try {
const hiveClient = new hive_js_1.HiveClient(keyManager, flags.node);
const accountData = await hiveClient.getAccount(account);
clearInterval(spinner);
process.stdout.write('\r' + ' '.repeat(80) + '\r');
if (!accountData) {
console.log(neon_js_1.neonChalk.error(`${neon_js_1.neonSymbols.cross} Account @${account} not found`));
return;
}
// Extract reward balances from account data
const rewardHiveRaw = accountData.reward_hive_balance?.split(' ')[0] || '0.000';
const rewardHbdRaw = accountData.reward_hbd_balance?.split(' ')[0] || '0.000';
const rewardVestsRaw = accountData.reward_vesting_balance?.split(' ')[0] || '0.000000';
// Parse for display and logic
const rewardHive = parseFloat(rewardHiveRaw);
const rewardHbd = parseFloat(rewardHbdRaw);
const rewardVests = parseFloat(rewardVestsRaw);
// Check if there are any rewards to claim
const hasRewards = rewardHive > 0 || rewardHbd > 0 || rewardVests > 0;
if (!hasRewards) {
console.log(neon_js_1.neonChalk.info(`${neon_js_1.neonSymbols.info} No pending rewards for @${account}`));
console.log('');
const noRewardsMessage = [
`${neon_js_1.neonChalk.darkCyan('Account checked: @' + account)}`,
``,
`${neon_js_1.neonChalk.orange('Author Rewards:')} 0.000 HIVE`,
`${neon_js_1.neonChalk.cyan('Curation Rewards:')} 0.000 HBD`,
`${neon_js_1.neonChalk.electric('Vesting Rewards:')} 0.000 VESTS`,
``,
`${neon_js_1.neonChalk.info('💡 Rewards appear here after posts and votes')}`
].join('\n');
console.log((0, neon_js_1.createNeonBox)(noRewardsMessage, `${neon_js_1.neonSymbols.star} REWARD STATUS ${neon_js_1.neonSymbols.star}`));
return;
}
// Display available rewards
const rewardDetails = [
`${neon_js_1.neonChalk.darkCyan('Account: @' + account)}`,
``,
`${neon_js_1.neonChalk.orange('Author Rewards:')} ${neon_js_1.neonChalk.white(rewardHive.toFixed(3))} ${neon_js_1.neonChalk.yellow('HIVE')}`,
`${neon_js_1.neonChalk.cyan('Curation Rewards:')} ${neon_js_1.neonChalk.white(rewardHbd.toFixed(3))} ${neon_js_1.neonChalk.yellow('HBD')}`,
`${neon_js_1.neonChalk.electric('Vesting Rewards:')} ${neon_js_1.neonChalk.white(rewardVests.toFixed(6))} ${neon_js_1.neonChalk.yellow('VESTS')}`,
``,
`${neon_js_1.neonChalk.green('💰 Total value available to claim!')}`
].join('\n');
console.log((0, neon_js_1.createNeonBox)(rewardDetails, `${neon_js_1.neonSymbols.star} AVAILABLE REWARDS ${neon_js_1.neonSymbols.star}`));
console.log('');
// If show-only flag, just return after showing
if (flags['show-only']) {
console.log(neon_js_1.neonChalk.info('Use: ') + neon_js_1.neonChalk.highlight(`beeline claim ${account}`) + ' to claim these rewards');
return;
}
if (flags.mock) {
console.log(neon_js_1.neonChalk.warning(`${neon_js_1.neonSymbols.star} Mock mode - transaction will NOT be broadcast`));
console.log('');
}
// Confirmation prompt
if (!flags.confirm && !flags.all) {
const confirmPrompt = await inquirer_1.default.prompt([{
type: 'confirm',
name: 'confirm',
message: flags.mock ?
neon_js_1.neonChalk.cyan('Simulate claiming these rewards?') :
neon_js_1.neonChalk.warning('Claim all available rewards?'),
default: true
}]);
if (!confirmPrompt.confirm) {
console.log(neon_js_1.neonChalk.info('Reward claiming cancelled'));
return;
}
}
if (flags.mock) {
return this.simulateClaim(account, rewardHive, rewardHbd, rewardVests);
}
// Get PIN for key decryption (rewards require posting key)
const keys = await keyManager.listKeys(account);
const postingKey = keys.find(k => k.role === 'posting');
if (!postingKey) {
console.log(neon_js_1.neonChalk.error(`${neon_js_1.neonSymbols.cross} Posting key not found for account @${account}`));
console.log(neon_js_1.neonChalk.info('Import posting key with: ') + neon_js_1.neonChalk.highlight(`beeline keys import ${account} posting`));
return;
}
let pin;
if (postingKey.encrypted) {
const pinPrompt = await inquirer_1.default.prompt([{
type: 'password',
name: 'pin',
message: neon_js_1.neonChalk.cyan('Enter PIN to unlock posting key:'),
validate: (input) => input.length > 0 || 'PIN required'
}]);
pin = pinPrompt.pin;
}
const claimSpinner = (0, neon_js_1.neonSpinner)('Broadcasting reward claim to Hive blockchain');
// Execute reward claim
const txId = await hiveClient.claimRewards(account, rewardHive > 0 ? rewardHiveRaw : '0.000', rewardHbd > 0 ? rewardHbdRaw : '0.000', rewardVests > 0 ? rewardVestsRaw : '0.000000', pin);
clearInterval(claimSpinner);
process.stdout.write('\r' + ' '.repeat(80) + '\r');
console.log(neon_js_1.neonChalk.success(`${neon_js_1.neonSymbols.check} Rewards claimed successfully!`));
console.log('');
const successMessage = [
`${neon_js_1.neonChalk.glow('Reward claim transaction broadcast successfully')}`,
``,
`${neon_js_1.neonChalk.cyan('Transaction ID:')} ${neon_js_1.neonChalk.highlight(txId)}`,
`${neon_js_1.neonChalk.magenta('Account:')} @${account}`,
``,
`${neon_js_1.neonChalk.orange('Claimed HIVE:')} ${rewardHive > 0 ? rewardHiveRaw : '0.000'} HIVE`,
`${neon_js_1.neonChalk.cyan('Claimed HBD:')} ${rewardHbd > 0 ? rewardHbdRaw : '0.000'} HBD`,
`${neon_js_1.neonChalk.electric('Claimed VESTS:')} ${rewardVests > 0 ? rewardVestsRaw : '0.000000'} VESTS`,
``,
`${neon_js_1.neonChalk.green('🎉 Rewards added to your balance!')}`,
`${neon_js_1.neonChalk.info('Claim confirmed in ~3 seconds')}`
].join('\n');
console.log((0, neon_js_1.createNeonBox)(successMessage, `${neon_js_1.neonSymbols.star} REWARDS CLAIMED ${neon_js_1.neonSymbols.star}`));
// Memory scrubbing
if (pin)
keyManager.scrubMemory(pin);
}
catch (error) {
clearInterval(spinner);
process.stdout.write('\r' + ' '.repeat(80) + '\r');
console.log(neon_js_1.neonChalk.error(`${neon_js_1.neonSymbols.cross} Reward claiming failed: ${error instanceof Error ? error.message : 'Unknown error'}`));
console.log('');
console.log(neon_js_1.neonChalk.info('Possible causes:'));
console.log(neon_js_1.neonChalk.darkCyan('• No rewards available to claim'));
console.log(neon_js_1.neonChalk.darkCyan('• Invalid account name'));
console.log(neon_js_1.neonChalk.darkCyan('• Network connectivity issues'));
console.log(neon_js_1.neonChalk.darkCyan('• Incorrect PIN'));
console.log(neon_js_1.neonChalk.darkCyan('• Posting key not available'));
}
}
simulateClaim(account, rewardHive, rewardHbd, rewardVests) {
console.log(neon_js_1.neonChalk.glow(`${neon_js_1.neonSymbols.diamond} Simulating reward claim...`));
console.log('');
// Simulate some processing time
setTimeout(() => {
const mockTxId = '0x' + Math.random().toString(16).substring(2, 18);
console.log(neon_js_1.neonChalk.success(`${neon_js_1.neonSymbols.check} Reward claim simulation complete!`));
console.log('');
const simulationMessage = [
`${neon_js_1.neonChalk.warning('SIMULATION ONLY - NO REAL CLAIM')}`,
``,
`${neon_js_1.neonChalk.cyan('Mock Transaction ID:')} ${neon_js_1.neonChalk.highlight(mockTxId)}`,
`${neon_js_1.neonChalk.magenta('Account:')} @${account}`,
``,
`${neon_js_1.neonChalk.orange('Mock Claimed HIVE:')} ${rewardHive > 0 ? rewardHive.toFixed(3) : '0.000'} HIVE`,
`${neon_js_1.neonChalk.cyan('Mock Claimed HBD:')} ${rewardHbd > 0 ? rewardHbd.toFixed(3) : '0.000'} HBD`,
`${neon_js_1.neonChalk.electric('Mock Claimed VESTS:')} ${rewardVests > 0 ? rewardVests.toFixed(6) : '0.000000'} VESTS`,
``,
`${neon_js_1.neonChalk.green('🎉 Mock rewards would be added to balance!')}`,
`${neon_js_1.neonChalk.info('Remove --mock flag to execute real claim')}`
].join('\n');
console.log((0, neon_js_1.createNeonBox)(simulationMessage, `${neon_js_1.neonSymbols.star} SIMULATION RESULT ${neon_js_1.neonSymbols.star}`));
}, 1500);
}
}
Claim.description = 'Claim pending author, curation, and vesting rewards with cyberpunk style';
Claim.examples = [
`$ beeline claim`,
`$ beeline claim alice`,
`$ beeline claim alice --show-only`,
`$ beeline claim alice --all`
];
Claim.flags = {
from: core_1.Flags.string({
char: 'f',
description: 'account to claim rewards from (defaults to default account)'
}),
node: core_1.Flags.string({
char: 'n',
description: 'RPC node to use'
}),
confirm: core_1.Flags.boolean({
char: 'y',
description: 'skip confirmation prompt',
default: false
}),
mock: core_1.Flags.boolean({
char: 'm',
description: 'simulate reward claiming without broadcasting',
default: false
}),
'show-only': core_1.Flags.boolean({
char: 's',
description: 'only show available rewards without claiming',
default: false
}),
all: core_1.Flags.boolean({
char: 'a',
description: 'claim all available rewards (HIVE, HBD, and VESTS)',
default: false
})
};
Claim.args = {
account: core_1.Args.string({
description: 'account to claim rewards for',
required: false
})
};
exports.default = Claim;
//# sourceMappingURL=claim.js.map