UNPKG

caravan-x

Version:

A terminal-based utility for managing Caravan multisig wallets in regtest mode. This tool simplifies development and testing with Caravan by providing an easy-to-use interface

242 lines (240 loc) 8.26 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.caravanLogo = exports.colors = void 0; exports.formatNumber = formatNumber; exports.formatBitcoin = formatBitcoin; exports.truncate = truncate; exports.boxText = boxText; exports.displayCommandTitle = displayCommandTitle; exports.clearScreen = clearScreen; exports.createTable = createTable; exports.progressBar = progressBar; exports.updateSpinnerProgress = updateSpinnerProgress; exports.paginateOutput = paginateOutput; exports.getTerminalWidth = getTerminalWidth; exports.divider = divider; exports.keyValue = keyValue; exports.formatWarning = formatWarning; exports.formatError = formatError; exports.formatSuccess = formatSuccess; const chalk_1 = __importDefault(require("chalk")); /** * Consistent color scheme for the application */ exports.colors = { primary: chalk_1.default.hex("#F7931A"), // Bitcoin orange secondary: chalk_1.default.hex("#1C2C5B"), // Dark blue accent: chalk_1.default.hex("#00ACED"), // Light blue success: chalk_1.default.hex("#28a745"), // Green warning: chalk_1.default.hex("#ffc107"), // Yellow error: chalk_1.default.hex("#dc3545"), // Red info: chalk_1.default.hex("#17a2b8"), // Teal muted: chalk_1.default.hex("#6c757d"), // Gray header: chalk_1.default.bold.hex("#F7931A"), // Bold orange for headers commandName: chalk_1.default.bold.hex("#1C2C5B"), // Bold dark blue for command names subtle: chalk_1.default.hex("#adb5bd"), // Lighter gray for less important text highlight: chalk_1.default.hex("#0366d6").bold, // Bright blue for highlighting important values bitcoin: chalk_1.default.hex("#F7931A").bold, // Bitcoin orange bold for Bitcoin-related terms code: chalk_1.default.hex("#e83e8c"), // Pink for code/technical elements }; /** * ASCII art logo for Caravan */ exports.caravanLogo = ` ${exports.colors.primary(" ______ ")} ${exports.colors.primary(" / ____/___ __________ __ _____ ____ ")} ${exports.colors.primary(" / / / __ \`/ ___/ __ \`/ | / / _ \\/ __ \\ ")} ${exports.colors.primary("/ /___/ /_/ / / / /_/ /| |/ / /_/ / / / / ")} ${exports.colors.primary("\\____/\\__,_/_/ \\__,_/ |___/\\__,_/_/ /_/ ")} ${exports.colors.accent("========== R E G T E S T M O D E ==========")} `; /** * Format numbers with commas for better readability */ function formatNumber(num) { return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); } /** * Format Bitcoin amounts with appropriate precision */ function formatBitcoin(amount) { // For small amounts, show more decimal places if (amount < 0.001) { return `${amount.toFixed(8)} BTC`; } else if (amount < 0.1) { return `${amount.toFixed(6)} BTC`; } else { return `${amount.toFixed(4)} BTC`; } } /** * Truncate strings like transaction IDs or hashes for display */ function truncate(str, length = 8) { if (!str || str.length <= length * 2) return str; return `${str.substring(0, length)}...${str.substring(str.length - length)}`; } /** * Create a simple box around text */ function boxText(text, options) { const padding = options?.padding || 2; const title = options?.title || ""; const titleColor = options?.titleColor || exports.colors.header; const lines = text.split("\n"); const width = Math.max(...lines.map((line) => line.length)) + padding * 2; let result = "╔" + "═".repeat(width) + "╗\n"; // Add title if provided if (title) { const titlePadding = Math.floor((width - title.length) / 2); result = "╔" + "═".repeat(titlePadding) + titleColor(` ${title} `) + "═".repeat(width - titlePadding - title.length - 2) + "╗\n"; } // Add padding at top for (let i = 0; i < padding / 2; i++) { result += "║" + " ".repeat(width) + "║\n"; } // Add content with padding for (const line of lines) { const leftPadding = Math.floor((width - line.length) / 2); const rightPadding = width - leftPadding - line.length; result += "║" + " ".repeat(leftPadding) + line + " ".repeat(rightPadding) + "║\n"; } // Add padding at bottom for (let i = 0; i < padding / 2; i++) { result += "║" + " ".repeat(width) + "║\n"; } result += "╚" + "═".repeat(width) + "╝"; return result; } /** * Display a command title with consistent formatting */ function displayCommandTitle(title) { const separator = "═".repeat(title.length + 10); console.log("\n" + exports.colors.header(separator)); console.log(exports.colors.header(` ${title} `)); console.log(exports.colors.header(separator) + "\n"); } /** * Clear the terminal */ function clearScreen() { console.clear(); } /** * Create a table with column headers */ function createTable(headers, rows) { // Calculate column widths const columnWidths = headers.map((header, index) => { const maxRowLength = Math.max(header.length, ...rows.map((row) => (row[index] || "").toString().length)); return maxRowLength + 2; // Add padding }); // Create header row let table = ""; // Top border table += "┌" + columnWidths.map((w) => "─".repeat(w)).join("┬") + "┐\n"; // Header row table += "│"; headers.forEach((header, i) => { table += ` ${header}${" ".repeat(columnWidths[i] - header.length - 1)}│`; }); table += "\n"; // Separator table += "├" + columnWidths.map((w) => "─".repeat(w)).join("┼") + "┤\n"; // Data rows rows.forEach((row) => { table += "│"; row.forEach((cell, i) => { const cellStr = (cell || "").toString(); table += ` ${cellStr}${" ".repeat(columnWidths[i] - cellStr.length - 1)}│`; }); table += "\n"; }); // Bottom border table += "└" + columnWidths.map((w) => "─".repeat(w)).join("┴") + "┘"; return table; } /** * Format progress bar */ function progressBar(percent, width = 30) { const filled = Math.round(width * (percent / 100)); const empty = width - filled; const filledBar = exports.colors.primary("█".repeat(filled)); const emptyBar = exports.colors.muted("░".repeat(empty)); return `[${filledBar}${emptyBar}] ${percent.toFixed(1)}%`; } /** * Update a spinner with progress information */ function updateSpinnerProgress(spinner, current, total, message) { const percent = (current / total) * 100; spinner.text = `${message} ${progressBar(percent)} (${current}/${total})`; } /** * Paginate text output for display */ function paginateOutput(text, pageSize = 15) { const lines = text.split("\n"); const pages = []; for (let i = 0; i < lines.length; i += pageSize) { pages.push(lines.slice(i, i + pageSize).join("\n")); } return pages; } /** * Get terminal width */ function getTerminalWidth() { return process.stdout.columns || 80; } /** * Create a horizontal divider */ function divider(char = "─", //@ts-ignore color = exports.colors.muted) { const width = getTerminalWidth(); return color(char.repeat(width)); } /** * Display key-value information in a formatted way */ function keyValue(key, value) { const keyStr = exports.colors.muted(`${key}:`); const valueStr = typeof value === "number" ? exports.colors.highlight(formatNumber(value)) : exports.colors.highlight(value.toString()); return `${keyStr} ${valueStr}`; } /** * Format warnings in a consistent way */ function formatWarning(message) { return `${exports.colors.warning("⚠️ Warning:")} ${message}`; } /** * Format errors in a consistent way */ function formatError(message) { return `${exports.colors.error("❌ Error:")} ${message}`; } /** * Format success messages in a consistent way */ function formatSuccess(message) { return `${exports.colors.success("✓ Success:")} ${message}`; }