UNPKG

beeline-cli

Version:

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

727 lines 36.6 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); 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 fs = __importStar(require("fs-extra")); const path = __importStar(require("path")); const inquirer_1 = __importDefault(require("inquirer")); class History extends core_1.Command { async run() { const { args, flags } = await this.parse(History); const theme = await (0, neon_js_1.getTheme)(); const keyManager = new crypto_js_1.KeyManager(); await keyManager.initialize(); let account = args.account; // 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(theme.chalk.warning(`${neon_js_1.neonSymbols.cross} No account specified and no default account set`)); console.log(theme.chalk.info('Import a key first with: ') + theme.chalk.highlight('beeline keys import <account> <role>')); return; } } if (flags.mock) { return await this.showMockHistory(account, flags); } if (flags.interactive) { return await this.showInteractiveHistory(account, keyManager, flags, theme); } console.log(theme.chalk.glow(`${neon_js_1.neonSymbols.diamond} Fetching transaction history for ${theme.chalk.highlight('@' + account)}...`)); const spinner = theme.spinner('Connecting to Hive blockchain'); try { const hiveClient = new hive_js_1.HiveClient(keyManager, flags.node); // Build transaction filter let filter = { types: flags.type, startDate: flags['start-date'] ? new Date(flags['start-date']) : undefined, endDate: flags['end-date'] ? new Date(flags['end-date']) : undefined, minAmount: flags['min-amount'] ? parseFloat(flags['min-amount']) : undefined, maxAmount: flags['max-amount'] ? parseFloat(flags['max-amount']) : undefined, currency: flags.currency, direction: flags.direction !== 'all' ? flags.direction : undefined }; // If no specific types are requested, default to meaningful transactions (unless --all flag) if ((!flags.type || flags.type.length === 0) && !flags.all) { filter.types = [ // Monetary transactions 'transfer', 'transfer_to_vesting', 'withdraw_vesting', 'transfer_to_savings', 'transfer_from_savings', 'claim_reward_balance', 'author_reward', 'curation_reward', 'interest', 'fill_vesting_withdraw', 'fill_transfer_from_savings', // Content & Social transactions 'vote', 'comment', // Governance transactions (actual operation types) 'account_witness_vote', 'account_witness_proxy', // Delegation transactions 'delegate_vesting_shares', // Account management 'account_update' ]; } // Remove undefined values Object.keys(filter).forEach(key => { if (filter[key] === undefined) { delete filter[key]; } }); // Fetch transactions const transactions = await hiveClient.getAccountHistory(account, flags.limit, flags.start, Object.keys(filter).length > 0 ? filter : undefined); clearInterval(spinner); process.stdout.write('\r' + ' '.repeat(80) + '\r'); if (flags.debug) { console.log(theme.chalk.info(`${neon_js_1.neonSymbols.bullet} Debug: Raw transaction count: ${transactions.length}`)); if (transactions.length > 0) { console.log(theme.chalk.info(`${neon_js_1.neonSymbols.bullet} Debug: First transaction type: ${transactions[0].op[0]}`)); console.log(theme.chalk.info(`${neon_js_1.neonSymbols.bullet} Debug: First transaction data: ${JSON.stringify(transactions[0].op[1], null, 2)}`)); } } console.log(''); if (flags.analytics) { const analytics = await hiveClient.getTransactionAnalytics(account, Object.keys(filter).length > 0 ? filter : undefined); await this.displayAnalytics(analytics, theme); console.log(''); } if (flags.export) { await this.exportTransactions(transactions, flags.export, account); console.log(theme.chalk.success(`${neon_js_1.neonSymbols.check} Transactions exported to ${flags.export}`)); console.log(''); } await this.displayTransactions(transactions, account, flags.format, theme); // Show summary console.log(''); console.log(theme.chalk.success(`${neon_js_1.neonSymbols.check} Found ${transactions.length} transactions`)); if (Object.keys(filter).length > 0) { console.log(theme.chalk.info(`${neon_js_1.neonSymbols.bullet} Filters applied: ${this.getFilterSummary(filter)}`)); } } catch (error) { clearInterval(spinner); process.stdout.write('\r' + ' '.repeat(80) + '\r'); console.log(theme.chalk.error(`${neon_js_1.neonSymbols.cross} Failed to fetch history: ${error instanceof Error ? error.message : 'Unknown error'}`)); console.log(''); console.log(theme.chalk.info('Try using mock data: ') + theme.chalk.highlight(`beeline history ${account} --mock`)); } } async displayTransactions(transactions, account, format, theme) { if (transactions.length === 0) { console.log(theme.chalk.warning(`${neon_js_1.neonSymbols.info} No transactions found`)); return; } if (format === 'json') { console.log(JSON.stringify(transactions, null, 2)); return; } if (format === 'detailed') { await this.displayDetailedTransactions(transactions, account, theme); return; } // Table format console.log(theme.createBox(this.formatTransactionTable(transactions, account, theme), `TRANSACTION HISTORY ${neon_js_1.neonSymbols.star} @${account.toUpperCase()}`)); } formatTransactionTable(transactions, account, theme) { const headers = [ theme.chalk.glow('DATE'), theme.chalk.glow('TYPE'), theme.chalk.glow('DESCRIPTION'), theme.chalk.glow('AMOUNT'), theme.chalk.glow('BLOCK') ]; const rows = transactions.slice(0, 20).map(tx => { const date = new Date(tx.timestamp).toLocaleDateString(); const type = tx.op[0].toUpperCase().replace(/_/g, ' '); const description = (0, hive_js_1.getTransactionDescription)(tx, account); let amount = ''; const opData = tx.op[1]; if (opData.amount) { const formatted = (0, hive_js_1.formatTransactionAmount)(opData.amount); amount = `${theme.chalk.highlight(formatted.formatted)} ${theme.chalk.accent(formatted.currency)}`; } else if (opData.reward) { const formatted = (0, hive_js_1.formatTransactionAmount)(opData.reward); amount = `${theme.chalk.highlight(formatted.formatted)} ${theme.chalk.accent(formatted.currency)}`; } else if (opData.vesting_payout) { const formatted = (0, hive_js_1.formatTransactionAmount)(opData.vesting_payout); amount = `${theme.chalk.highlight(formatted.formatted)} ${theme.chalk.accent(formatted.currency)}`; } const block = tx.block.toLocaleString(); return [ theme.chalk.info(date), theme.chalk.success(type), theme.chalk.white(description), amount || theme.chalk.darkCyan('--'), theme.chalk.darkCyan(block) ]; }); // Simple table formatting const colWidths = [12, 18, 25, 15, 10]; let table = ''; // Header table += headers.map((header, i) => header.padEnd(colWidths[i])).join(' | ') + '\n'; table += colWidths.map(w => '─'.repeat(w)).join('─┼─') + '\n'; // Rows rows.forEach(row => { table += row.map((cell, i) => { // Remove ANSI codes for length calculation const cleanCell = cell.replace(/\u001b\[[0-9;]*m/g, ''); const padding = Math.max(0, colWidths[i] - cleanCell.length); return cell + ' '.repeat(padding); }).join(' │ ') + '\n'; }); if (transactions.length > 20) { table += '\n' + theme.chalk.darkCyan(`... and ${transactions.length - 20} more transactions`); } return table; } async displayDetailedTransactions(transactions, account, theme) { for (let i = 0; i < Math.min(10, transactions.length); i++) { const tx = transactions[i]; const opType = tx.op[0]; const opData = tx.op[1]; const date = new Date(tx.timestamp); console.log(theme.createBox([ `${theme.chalk.glow('Type')} ${neon_js_1.neonSymbols.arrow} ${theme.chalk.success(opType.replace(/_/g, ' ').toUpperCase())}`, `${theme.chalk.glow('Description')} ${neon_js_1.neonSymbols.arrow} ${theme.chalk.white((0, hive_js_1.getTransactionDescription)(tx, account))}`, `${theme.chalk.glow('Date')} ${neon_js_1.neonSymbols.arrow} ${theme.chalk.info(date.toLocaleString())}`, `${theme.chalk.glow('Block')} ${neon_js_1.neonSymbols.arrow} ${theme.chalk.darkCyan('#' + tx.block.toLocaleString())}`, opData.amount ? `${theme.chalk.glow('Amount')} ${neon_js_1.neonSymbols.arrow} ${theme.chalk.highlight((0, hive_js_1.formatTransactionAmount)(opData.amount).formatted)} ${theme.chalk.accent((0, hive_js_1.formatTransactionAmount)(opData.amount).currency)}` : '', opData.memo && opData.memo !== '' ? `${theme.chalk.glow('Memo')} ${neon_js_1.neonSymbols.arrow} ${theme.chalk.darkCyan(opData.memo)}` : '', opData.from ? `${theme.chalk.glow('From')} ${neon_js_1.neonSymbols.arrow} ${theme.chalk.white('@' + opData.from)}` : '', opData.to ? `${theme.chalk.glow('To')} ${neon_js_1.neonSymbols.arrow} ${theme.chalk.white('@' + opData.to)}` : '', tx.trx_id ? `${theme.chalk.glow('Tx Hash')} ${neon_js_1.neonSymbols.arrow} ${theme.chalk.darkCyan(tx.trx_id)}` : '' ].filter(line => line !== '').join('\n'), `TRANSACTION #${i + 1}`)); if (i < Math.min(9, transactions.length - 1)) { console.log(''); } } if (transactions.length > 10) { console.log(''); console.log(theme.chalk.darkCyan(`... and ${transactions.length - 10} more transactions (use --format table to see more)`)); } } async displayAnalytics(analytics, theme) { const volumeDisplay = [ `${theme.chalk.success('HIVE')} ${neon_js_1.neonSymbols.arrow} ${theme.chalk.highlight(analytics.totalVolume.hive.toLocaleString('en-US', { minimumFractionDigits: 3 }))} HIVE`, `${theme.chalk.accent('HBD')} ${neon_js_1.neonSymbols.arrow} ${theme.chalk.highlight(analytics.totalVolume.hbd.toLocaleString('en-US', { minimumFractionDigits: 3 }))} HBD`, `${theme.chalk.glow('VESTS')} ${neon_js_1.neonSymbols.arrow} ${theme.chalk.highlight(analytics.totalVolume.vests.toLocaleString('en-US', { minimumFractionDigits: 0 }))} VESTS` ]; const averageDisplay = [ `${theme.chalk.success('HIVE')} ${neon_js_1.neonSymbols.arrow} ${theme.chalk.highlight(analytics.averageAmount.hive.toLocaleString('en-US', { minimumFractionDigits: 3 }))}`, `${theme.chalk.accent('HBD')} ${neon_js_1.neonSymbols.arrow} ${theme.chalk.highlight(analytics.averageAmount.hbd.toLocaleString('en-US', { minimumFractionDigits: 3 }))}` ]; const topTypes = Object.entries(analytics.transactionsByType) .sort(([, a], [, b]) => b - a) .slice(0, 5) .map(([type, count]) => `${theme.chalk.white(type.replace(/_/g, ' '))} ${neon_js_1.neonSymbols.arrow} ${theme.chalk.highlight(count)}`); console.log(theme.createBox([ `${theme.chalk.glow('Total Transactions')} ${neon_js_1.neonSymbols.arrow} ${theme.chalk.highlight(analytics.totalTransactions)}`, ``, `${theme.chalk.glow('TOTAL VOLUME')}`, ...volumeDisplay, ``, `${theme.chalk.glow('AVERAGE AMOUNTS')}`, ...averageDisplay, ``, `${theme.chalk.glow('TOP TRANSACTION TYPES')}`, ...topTypes ].join('\n'), `ANALYTICS ${neon_js_1.neonSymbols.diamond}`)); // Show rewards summary if available if (analytics.rewardsSummary.author > 0 || analytics.rewardsSummary.curator > 0) { console.log(''); console.log(theme.createBox([ `${theme.chalk.success('Author')} ${neon_js_1.neonSymbols.arrow} ${theme.chalk.highlight(analytics.rewardsSummary.author.toFixed(3))} HIVE`, `${theme.chalk.accent('Curator')} ${neon_js_1.neonSymbols.arrow} ${theme.chalk.highlight(analytics.rewardsSummary.curator.toFixed(3))} HP`, `${theme.chalk.glow('Vesting')} ${neon_js_1.neonSymbols.arrow} ${theme.chalk.highlight(analytics.rewardsSummary.vesting.toFixed(3))} HP` ].join('\n'), `REWARDS SUMMARY ${neon_js_1.neonSymbols.star}`)); } } async exportTransactions(transactions, filename, account) { const ext = path.extname(filename).toLowerCase(); if (ext === '.json') { await fs.writeJSON(filename, { account, timestamp: new Date().toISOString(), count: transactions.length, transactions }, { spaces: 2 }); } else if (ext === '.csv') { const csvHeader = 'Date,Type,Description,Amount,Currency,From,To,Memo,Block,TxHash\n'; const csvRows = transactions.map(tx => { const opType = tx.op[0]; const opData = tx.op[1]; const date = new Date(tx.timestamp).toISOString(); const description = (0, hive_js_1.getTransactionDescription)(tx, account).replace(/,/g, ';'); let amount = ''; let currency = ''; if (opData.amount) { const formatted = (0, hive_js_1.formatTransactionAmount)(opData.amount); amount = formatted.value.toString(); currency = formatted.currency; } const from = opData.from || ''; const to = opData.to || ''; const memo = (opData.memo || '').replace(/,/g, ';'); const block = tx.block; const txHash = tx.trx_id || ''; return `${date},${opType},${description},${amount},${currency},${from},${to},${memo},${block},${txHash}`; }).join('\n'); await fs.writeFile(filename, csvHeader + csvRows); } else { throw new Error('Unsupported export format. Use .json or .csv extension.'); } } getFilterSummary(filter) { const parts = []; if (filter.types) { parts.push(`types: ${filter.types.join(', ')}`); } if (filter.direction) { parts.push(`direction: ${filter.direction}`); } if (filter.currency) { parts.push(`currency: ${filter.currency}`); } if (filter.startDate) { parts.push(`from: ${filter.startDate.toDateString()}`); } if (filter.endDate) { parts.push(`to: ${filter.endDate.toDateString()}`); } if (filter.minAmount) { parts.push(`min: ${filter.minAmount}`); } if (filter.maxAmount) { parts.push(`max: ${filter.maxAmount}`); } return parts.join(', '); } async showMockHistory(account, flags) { const theme = await (0, neon_js_1.getTheme)(); const mockTransactions = [ { trx_id: '4a1b2c3d4e5f', block: 87654321, trx_in_block: 5, op_in_trx: 0, virtual_op: 0, timestamp: new Date(Date.now() - 86400000).toISOString(), op: ['transfer', { from: 'alice', to: account, amount: '10.000 HIVE', memo: 'Payment for services' }] }, { trx_id: '5f6e7d8c9b0a', block: 87654300, trx_in_block: 12, op_in_trx: 0, virtual_op: 0, timestamp: new Date(Date.now() - 172800000).toISOString(), op: ['transfer_to_vesting', { from: account, to: account, amount: '50.000 HIVE' }] }, { trx_id: '', block: 87654280, trx_in_block: 0, op_in_trx: 0, virtual_op: 1, timestamp: new Date(Date.now() - 259200000).toISOString(), op: ['author_reward', { author: account, permlink: 'my-post', hive_payout: '5.234 HIVE', hbd_payout: '2.100 HBD', vesting_payout: '15.678 VESTS' }] }, { trx_id: '9a8b7c6d5e4f', block: 87654250, trx_in_block: 8, op_in_trx: 0, virtual_op: 0, timestamp: new Date(Date.now() - 345600000).toISOString(), op: ['transfer_to_savings', { from: account, to: account, amount: '100.000 HBD', memo: 'Long term savings' }] } ]; console.log(''); if (flags.analytics) { const mockAnalytics = { totalTransactions: 4, totalVolume: { hive: 65.234, hbd: 102.100, vests: 15.678 }, averageAmount: { hive: 21.745, hbd: 51.050 }, transactionsByType: { 'transfer': 1, 'transfer_to_vesting': 1, 'author_reward': 1, 'transfer_to_savings': 1 }, rewardsSummary: { author: 5.234, curator: 0, vesting: 15.678 } }; await this.displayAnalytics(mockAnalytics, theme); console.log(''); } if (flags.export) { await this.exportTransactions(mockTransactions, flags.export, account); console.log(theme.chalk.success(`${neon_js_1.neonSymbols.check} Mock transactions exported to ${flags.export}`)); console.log(''); } await this.displayTransactions(mockTransactions, account, flags.format, theme); console.log(''); console.log(theme.chalk.warning(`${neon_js_1.neonSymbols.star} Mock data displayed`)); console.log(theme.chalk.info('Remove --mock flag for real blockchain data')); } async showInteractiveHistory(account, keyManager, flags, theme) { const hiveClient = new hive_js_1.HiveClient(keyManager, flags.node); // Transaction type groups for easy selection const transactionGroups = { 'monetary': ['transfer', 'transfer_to_vesting', 'withdraw_vesting', 'transfer_to_savings', 'transfer_from_savings', 'claim_reward_balance', 'author_reward', 'curation_reward', 'interest', 'fill_vesting_withdraw', 'fill_transfer_from_savings'], 'transfers': ['transfer', 'transfer_to_vesting', 'transfer_to_savings', 'transfer_from_savings'], 'rewards': ['author_reward', 'curation_reward', 'interest', 'claim_reward_balance'], 'power': ['transfer_to_vesting', 'withdraw_vesting', 'fill_vesting_withdraw'], 'savings': ['transfer_to_savings', 'transfer_from_savings', 'fill_transfer_from_savings', 'interest'], 'social': ['vote', 'comment', 'custom_json', 'follow'], 'account': ['account_update', 'account_update2', 'change_recovery_account'], 'all': [] }; let currentFilter = { types: transactionGroups.monetary }; let transactions = []; let currentPage = 0; const pageSize = 20; // Initial load console.log(theme.chalk.glow(`${neon_js_1.neonSymbols.diamond} Welcome to Interactive Transaction History for ${theme.chalk.highlight('@' + account)}`)); await this.loadTransactions(hiveClient, account, currentFilter, theme); while (true) { console.clear(); // Header console.log(theme.createBox(`${theme.chalk.glow('INTERACTIVE HISTORY')} ${neon_js_1.neonSymbols.star} ${theme.chalk.highlight('@' + account.toUpperCase())}\n` + `${theme.chalk.info('Use arrow keys to navigate, Enter to select, q to quit')}\n\n` + `Current Filter: ${theme.chalk.accent(this.getCurrentFilterName(currentFilter))}`, 'TRANSACTION BROWSER')); console.log(''); const choices = [ { name: `${neon_js_1.neonSymbols.diamond} View Transactions`, value: 'view' }, { name: `${neon_js_1.neonSymbols.bullet} Filter: ${this.getCurrentFilterName(currentFilter)}`, value: 'filter' }, { name: `${neon_js_1.neonSymbols.bullet} Analytics`, value: 'analytics' }, { name: `${neon_js_1.neonSymbols.bullet} Export Data`, value: 'export' }, { name: `${neon_js_1.neonSymbols.bullet} Change Account`, value: 'account' }, new inquirer_1.default.Separator(), { name: `${neon_js_1.neonSymbols.cross} Quit`, value: 'quit' } ]; const { action } = await inquirer_1.default.prompt([{ type: 'list', name: 'action', message: 'What would you like to do?', choices: choices, pageSize: 10 }]); switch (action) { case 'view': await this.showTransactionView(hiveClient, account, currentFilter, theme); break; case 'filter': const newFilter = await this.showFilterMenu(transactionGroups, currentFilter, theme); if (newFilter) { currentFilter = newFilter; console.log(theme.chalk.info(`${neon_js_1.neonSymbols.bullet} Filter updated!`)); await new Promise(resolve => setTimeout(resolve, 1000)); } break; case 'analytics': await this.showAnalyticsView(hiveClient, account, currentFilter, theme); break; case 'export': await this.showExportMenu(hiveClient, account, currentFilter, theme); break; case 'account': console.log(theme.chalk.info('Account switching not implemented yet')); await new Promise(resolve => setTimeout(resolve, 1000)); break; case 'quit': console.log(theme.chalk.glow(`${neon_js_1.neonSymbols.star} Thanks for using Beeline Transaction History!`)); return; } } } async loadTransactions(hiveClient, account, filter, theme) { const spinner = theme.spinner('Loading transactions...'); try { const transactions = await hiveClient.getAccountHistory(account, 100, -1, filter); clearInterval(spinner); process.stdout.write('\r' + ' '.repeat(80) + '\r'); return transactions; } catch (error) { clearInterval(spinner); process.stdout.write('\r' + ' '.repeat(80) + '\r'); console.log(theme.chalk.error(`${neon_js_1.neonSymbols.cross} Failed to load transactions: ${error instanceof Error ? error.message : 'Unknown error'}`)); return []; } } getCurrentFilterName(filter) { if (!filter.types || filter.types.length === 0) return 'All Transactions'; const transactionGroups = { 'monetary': ['transfer', 'transfer_to_vesting', 'withdraw_vesting', 'transfer_to_savings', 'transfer_from_savings', 'claim_reward_balance', 'author_reward', 'curation_reward', 'interest', 'fill_vesting_withdraw', 'fill_transfer_from_savings'], 'transfers': ['transfer', 'transfer_to_vesting', 'transfer_to_savings', 'transfer_from_savings'], 'rewards': ['author_reward', 'curation_reward', 'interest', 'claim_reward_balance'], 'power': ['transfer_to_vesting', 'withdraw_vesting', 'fill_vesting_withdraw'], 'savings': ['transfer_to_savings', 'transfer_from_savings', 'fill_transfer_from_savings', 'interest'], 'social': ['vote', 'comment', 'custom_json', 'follow'], 'account': ['account_update', 'account_update2', 'change_recovery_account'] }; for (const [groupName, types] of Object.entries(transactionGroups)) { if (JSON.stringify(filter.types.sort()) === JSON.stringify(types.sort())) { return groupName.charAt(0).toUpperCase() + groupName.slice(1); } } return `${filter.types.length} Selected Types`; } async showFilterMenu(transactionGroups, currentFilter, theme) { console.clear(); console.log(theme.createBox(`${theme.chalk.glow('TRANSACTION FILTERS')}\n` + `${theme.chalk.info('Select transaction types to display')}`, 'FILTER SELECTION')); console.log(''); const choices = [ { name: `${neon_js_1.neonSymbols.star} Monetary (Transfers, Rewards, Power)`, value: 'monetary' }, { name: `${neon_js_1.neonSymbols.arrow} Transfers Only`, value: 'transfers' }, { name: `${neon_js_1.neonSymbols.diamond} Rewards Only`, value: 'rewards' }, { name: `${neon_js_1.neonSymbols.bullet} Power Operations`, value: 'power' }, { name: `${neon_js_1.neonSymbols.bullet} Savings Operations`, value: 'savings' }, { name: `${neon_js_1.neonSymbols.bullet} Social (Votes, Comments)`, value: 'social' }, { name: `${neon_js_1.neonSymbols.bullet} Account Updates`, value: 'account' }, { name: `${neon_js_1.neonSymbols.grid} All Transactions`, value: 'all' }, new inquirer_1.default.Separator(), { name: `${neon_js_1.neonSymbols.cross} Cancel`, value: 'cancel' } ]; const { filterType } = await inquirer_1.default.prompt([{ type: 'list', name: 'filterType', message: 'Select transaction filter:', choices: choices, pageSize: 10 }]); if (filterType === 'cancel') return null; return { ...currentFilter, types: transactionGroups[filterType] }; } async showTransactionView(hiveClient, account, filter, theme) { const transactions = await this.loadTransactions(hiveClient, account, filter, theme); if (transactions.length === 0) { console.clear(); console.log(theme.chalk.warning(`${neon_js_1.neonSymbols.info} No transactions found with current filter`)); console.log(theme.chalk.info('Press Enter to continue...')); await inquirer_1.default.prompt([{ type: 'input', name: 'continue', message: '' }]); return; } console.clear(); await this.displayTransactions(transactions, account, 'table', theme); console.log(''); console.log(theme.chalk.info('Press Enter to continue...')); await inquirer_1.default.prompt([{ type: 'input', name: 'continue', message: '' }]); } async showAnalyticsView(hiveClient, account, filter, theme) { console.clear(); console.log(theme.chalk.glow(`${neon_js_1.neonSymbols.diamond} Generating analytics...`)); try { const analytics = await hiveClient.getTransactionAnalytics(account, filter); console.clear(); await this.displayAnalytics(analytics, theme); console.log(''); console.log(theme.chalk.info('Press Enter to continue...')); await inquirer_1.default.prompt([{ type: 'input', name: 'continue', message: '' }]); } catch (error) { console.log(theme.chalk.error(`${neon_js_1.neonSymbols.cross} Failed to generate analytics`)); await new Promise(resolve => setTimeout(resolve, 2000)); } } async showExportMenu(hiveClient, account, filter, theme) { console.clear(); console.log(theme.createBox('Export transaction data to file', 'EXPORT DATA')); console.log(''); const { format } = await inquirer_1.default.prompt([{ type: 'list', name: 'format', message: 'Select export format:', choices: [ { name: `${neon_js_1.neonSymbols.bullet} CSV (Excel compatible)`, value: 'csv' }, { name: `${neon_js_1.neonSymbols.bullet} JSON (Developer format)`, value: 'json' }, { name: `${neon_js_1.neonSymbols.cross} Cancel`, value: 'cancel' } ] }]); if (format === 'cancel') return; const { filename } = await inquirer_1.default.prompt([{ type: 'input', name: 'filename', message: 'Enter filename:', default: `${account}-transactions.${format}` }]); console.log(theme.chalk.info(`${neon_js_1.neonSymbols.bullet} Exporting...`)); try { const transactions = await hiveClient.getAccountHistory(account, 1000, -1, filter); await this.exportTransactions(transactions, filename, account); console.log(theme.chalk.success(`${neon_js_1.neonSymbols.check} Exported ${transactions.length} transactions to ${filename}`)); } catch (error) { console.log(theme.chalk.error(`${neon_js_1.neonSymbols.cross} Export failed: ${error instanceof Error ? error.message : 'Unknown error'}`)); } await new Promise(resolve => setTimeout(resolve, 2000)); } } History.description = 'View account transaction history with filtering and analytics'; History.examples = [ `$ beeline history`, `$ beeline history alice`, `$ beeline history -i (interactive mode)`, `$ beeline history --all (show all transaction types)`, `$ beeline history --type transfer --limit 50`, `$ beeline history --start-date 2024-01-01 --end-date 2024-12-31`, `$ beeline history --direction incoming --currency HIVE`, `$ beeline history --analytics`, `$ beeline history --export transactions.csv` ]; History.flags = { limit: core_1.Flags.integer({ char: 'l', description: 'number of transactions to fetch', default: 100, min: 1, max: 1000 }), start: core_1.Flags.integer({ char: 's', description: 'start from transaction index (-1 for most recent)', default: -1 }), type: core_1.Flags.string({ char: 't', description: 'filter by transaction type', options: [ 'transfer', 'transfer_to_vesting', 'withdraw_vesting', 'transfer_to_savings', 'transfer_from_savings', 'claim_reward_balance', 'author_reward', 'curation_reward', 'delegate_vesting_shares', 'custom_json', 'vote', 'comment', 'account_witness_vote', 'account_witness_proxy', 'interest', 'fill_vesting_withdraw', 'fill_transfer_from_savings', 'limit_order_create', 'limit_order_cancel', 'convert', 'account_create', 'account_update' ], multiple: true }), 'start-date': core_1.Flags.string({ description: 'filter transactions after this date (YYYY-MM-DD)' }), 'end-date': core_1.Flags.string({ description: 'filter transactions before this date (YYYY-MM-DD)' }), 'min-amount': core_1.Flags.string({ description: 'minimum transaction amount' }), 'max-amount': core_1.Flags.string({ description: 'maximum transaction amount' }), currency: core_1.Flags.string({ char: 'c', description: 'filter by currency type', options: ['HIVE', 'HBD', 'VESTS'] }), direction: core_1.Flags.string({ char: 'd', description: 'filter by transfer direction', options: ['incoming', 'outgoing', 'all'], default: 'all' }), format: core_1.Flags.string({ char: 'f', description: 'output format', options: ['table', 'json', 'detailed'], default: 'table' }), analytics: core_1.Flags.boolean({ char: 'a', description: 'show transaction analytics and statistics', default: false }), export: core_1.Flags.string({ char: 'e', description: 'export to CSV or JSON file' }), node: core_1.Flags.string({ char: 'n', description: 'RPC node to use' }), mock: core_1.Flags.boolean({ char: 'm', description: 'use mock data for testing', default: false }), debug: core_1.Flags.boolean({ description: 'show debug information', default: false }), interactive: core_1.Flags.boolean({ char: 'i', description: 'launch interactive mode with keyboard navigation', default: false }), all: core_1.Flags.boolean({ description: 'show all transaction types (overrides default monetary filter)', default: false }) }; History.args = { account: core_1.Args.string({ description: 'account name (defaults to current user)', required: false }) }; exports.default = History; //# sourceMappingURL=history.js.map