UNPKG

beeline-cli

Version:

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

220 lines 11.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 Withdraw extends core_1.Command { async run() { const { args, flags } = await this.parse(Withdraw); const keyManager = new crypto_js_1.KeyManager(); await keyManager.initialize(); let fromAccount = flags.from; let toAccount = args.to; // Clean @ prefix if provided if (fromAccount?.startsWith('@')) { fromAccount = fromAccount.substring(1); } if (toAccount?.startsWith('@')) { toAccount = toAccount.substring(1); } // Use default account if no from account specified if (!fromAccount) { fromAccount = keyManager.getDefaultAccount(); if (!fromAccount) { 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> active')); return; } } // If no to account specified, withdraw to self if (!toAccount) { toAccount = fromAccount; } // Validate amount format const amount = parseFloat(args.amount); if (isNaN(amount) || amount <= 0) { console.log(neon_js_1.neonChalk.error(`${neon_js_1.neonSymbols.cross} Invalid amount: ${args.amount}`)); return; } const currency = args.currency; const memo = args.memo || ''; // Generate unique request ID (timestamp-based) const requestId = Date.now() % 1000000; // Keep it reasonable length console.log(neon_js_1.neonChalk.glow(`${neon_js_1.neonSymbols.diamond} Preparing savings withdrawal...`)); console.log(''); // Display withdrawal details const withdrawalDetails = [ `${neon_js_1.neonChalk.cyan('FROM')} ${neon_js_1.neonSymbols.arrow} ${neon_js_1.neonChalk.highlight('@' + fromAccount)} ${neon_js_1.neonChalk.darkCyan('(savings)')}`, `${neon_js_1.neonChalk.magenta('TO')} ${neon_js_1.neonSymbols.arrow} ${neon_js_1.neonChalk.highlight('@' + toAccount)}`, `${neon_js_1.neonChalk.electric('AMOUNT')} ${neon_js_1.neonSymbols.arrow} ${neon_js_1.neonChalk.white(amount.toFixed(3))} ${neon_js_1.neonChalk.yellow(currency)}`, `${neon_js_1.neonChalk.orange('REQ ID')} ${neon_js_1.neonSymbols.arrow} ${neon_js_1.neonChalk.white(requestId.toString())}`, memo ? `${neon_js_1.neonChalk.pink('MEMO')} ${neon_js_1.neonSymbols.arrow} ${neon_js_1.neonChalk.white('"' + memo + '"')}` : '', ``, `${neon_js_1.neonChalk.warning('⚠️ Withdrawal takes 3 DAYS to process')}`, `${neon_js_1.neonChalk.info('💡 You can cancel during the 3-day waiting period')}`, `${neon_js_1.neonChalk.info('💡 Use the request ID above to track/cancel')}`, `${neon_js_1.neonChalk.darkCyan('Transaction will be signed with your active key')}` ].filter(Boolean).join('\n'); console.log((0, neon_js_1.createNeonBox)(withdrawalDetails, `${neon_js_1.neonSymbols.star} SAVINGS WITHDRAWAL PREVIEW ${neon_js_1.neonSymbols.star}`)); console.log(''); 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) { const confirmPrompt = await inquirer_1.default.prompt([{ type: 'confirm', name: 'confirm', message: flags.mock ? neon_js_1.neonChalk.cyan('Simulate this savings withdrawal?') : neon_js_1.neonChalk.warning('Execute this savings withdrawal? It will take 3 days to process.'), default: false }]); if (!confirmPrompt.confirm) { console.log(neon_js_1.neonChalk.info('Savings withdrawal cancelled')); return; } } if (flags.mock) { return this.simulateWithdrawal(fromAccount, toAccount, amount, currency, requestId, memo); } // Get PIN for key decryption const keys = await keyManager.listKeys(fromAccount); const activeKey = keys.find(k => k.role === 'active'); if (!activeKey) { console.log(neon_js_1.neonChalk.error(`${neon_js_1.neonSymbols.cross} Active key not found for account @${fromAccount}`)); console.log(neon_js_1.neonChalk.info('Import active key with: ') + neon_js_1.neonChalk.highlight(`beeline keys import ${fromAccount} active`)); return; } let pin; if (activeKey.encrypted) { const pinPrompt = await inquirer_1.default.prompt([{ type: 'password', name: 'pin', message: neon_js_1.neonChalk.cyan('Enter PIN to unlock active key:'), validate: (input) => input.length > 0 || 'PIN required' }]); pin = pinPrompt.pin; } const spinner = (0, neon_js_1.neonSpinner)('Broadcasting to Hive blockchain'); try { const hiveClient = new hive_js_1.HiveClient(keyManager, flags.node); // Execute savings withdrawal const txId = await hiveClient.transferFromSavings(fromAccount, requestId, toAccount, amount.toFixed(3), currency, memo, pin); clearInterval(spinner); process.stdout.write('\r' + ' '.repeat(80) + '\r'); console.log(neon_js_1.neonChalk.success(`${neon_js_1.neonSymbols.check} Savings withdrawal initiated!`)); console.log(''); const successMessage = [ `${neon_js_1.neonChalk.glow('Savings withdrawal transaction broadcast successfully')}`, ``, `${neon_js_1.neonChalk.cyan('Transaction ID:')} ${neon_js_1.neonChalk.highlight(txId)}`, `${neon_js_1.neonChalk.magenta('From:')} @${fromAccount} (savings)`, `${neon_js_1.neonChalk.electric('To:')} @${toAccount}`, `${neon_js_1.neonChalk.orange('Amount:')} ${amount.toFixed(3)} ${currency}`, `${neon_js_1.neonChalk.pink('Request ID:')} ${requestId}`, memo ? `${neon_js_1.neonChalk.white('Memo:')} "${memo}"` : '', `${neon_js_1.neonChalk.yellow('Status:')} Withdrawal initiated - processing for 3 days`, ``, `${neon_js_1.neonChalk.info('Funds will be available in 3 days')}`, `${neon_js_1.neonChalk.info('You can cancel before completion if needed')}` ].filter(Boolean).join('\n'); console.log((0, neon_js_1.createNeonBox)(successMessage, `${neon_js_1.neonSymbols.star} SAVINGS WITHDRAWAL INITIATED ${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} Savings withdrawal 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('• Insufficient savings balance')); console.log(neon_js_1.neonChalk.darkCyan('• Invalid recipient account')); 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('• Duplicate request ID (try again)')); // Memory scrubbing on error too if (pin) keyManager.scrubMemory(pin); } } simulateWithdrawal(from, to, amount, currency, requestId, memo) { console.log(neon_js_1.neonChalk.glow(`${neon_js_1.neonSymbols.diamond} Simulating savings withdrawal...`)); 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} Savings withdrawal simulation complete!`)); console.log(''); const simulationMessage = [ `${neon_js_1.neonChalk.warning('SIMULATION ONLY - NO REAL WITHDRAWAL')}`, ``, `${neon_js_1.neonChalk.cyan('Mock Transaction ID:')} ${neon_js_1.neonChalk.highlight(mockTxId)}`, `${neon_js_1.neonChalk.magenta('From:')} @${from} (savings)`, `${neon_js_1.neonChalk.electric('To:')} @${to}`, `${neon_js_1.neonChalk.orange('Amount:')} ${amount.toFixed(3)} ${currency}`, `${neon_js_1.neonChalk.pink('Mock Request ID:')} ${requestId}`, memo ? `${neon_js_1.neonChalk.white('Memo:')} "${memo}"` : '', `${neon_js_1.neonChalk.yellow('Mock Status:')} Would process for 3 days`, ``, `${neon_js_1.neonChalk.info('Remove --mock flag to execute real withdrawal')}` ].filter(Boolean).join('\n'); console.log((0, neon_js_1.createNeonBox)(simulationMessage, `${neon_js_1.neonSymbols.star} SIMULATION RESULT ${neon_js_1.neonSymbols.star}`)); }, 1500); } } Withdraw.description = 'Withdraw HIVE or HBD from savings (3-day processing time) with cyberpunk style'; Withdraw.examples = [ `$ beeline withdraw 100 HIVE`, `$ beeline withdraw 50.000 HBD @alice`, `$ beeline withdraw 1000 HIVE @alice --from @business "Emergency withdrawal"` ]; Withdraw.flags = { from: core_1.Flags.string({ char: 'f', description: 'account to withdraw 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 withdrawal without broadcasting', default: false }) }; Withdraw.args = { amount: core_1.Args.string({ description: 'amount to withdraw from savings', required: true }), currency: core_1.Args.string({ description: 'currency (HIVE or HBD)', required: true, options: ['HIVE', 'HBD'] }), to: core_1.Args.string({ description: 'account to withdraw to (defaults to from account)', required: false }), memo: core_1.Args.string({ description: 'withdrawal memo', required: false }) }; exports.default = Withdraw; //# sourceMappingURL=withdraw.js.map