UNPKG

beeline-cli

Version:

A terminal wallet for the Hive blockchain - type, sign, rule the chain

231 lines 12.6 kB
"use strict"; 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