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
JavaScript
;
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}`;
}