UNPKG

@lodestar/utils

Version:

Utilities required across multiple lodestar packages

118 lines 3.95 kB
import { toRootHex } from "#bytes"; import { ETH_TO_WEI } from "./ethConversion.js"; /** * Format bytes as `0x1234…1234` * 4 bytes can represent 4294967296 values, so the chance of collision is low */ export function prettyBytes(root) { const str = typeof root === "string" ? root : toRootHex(root); return `${str.slice(0, 6)}${str.slice(-4)}`; } /** * Format bytes as `0x1234…` * Paired with block numbers or slots, it can still act as a decent identify-able format */ export function prettyBytesShort(root) { const str = typeof root === "string" ? root : toRootHex(root); return `${str.slice(0, 6)}…`; } /** * Truncate and format bytes as `0x123456789abc` * 6 bytes is sufficient to avoid collisions and it allows to easily look up * values on explorers like beaconcha.in while improving readability of logs */ export function truncBytes(root) { const str = typeof root === "string" ? root : toRootHex(root); return str.slice(0, 14); } /** * Format a bigint value as a decimal string */ export function formatBigDecimal(numerator, denominator, maxDecimalFactor) { const full = numerator / denominator; const fraction = ((numerator - full * denominator) * maxDecimalFactor) / denominator; // zeros to be added post decimal are number of zeros in maxDecimalFactor - number of digits in fraction const zerosPostDecimal = String(maxDecimalFactor).length - 1 - String(fraction).length; return `${full}.${"0".repeat(zerosPostDecimal)}${fraction}`; } // display upto 5 decimal places const MAX_DECIMAL_FACTOR = BigInt("100000"); /** * Format wei as ETH, with up to 5 decimals */ export function formatWeiToEth(wei) { return formatBigDecimal(wei, ETH_TO_WEI, MAX_DECIMAL_FACTOR); } /** * Format wei as ETH, with up to 5 decimals and append ' ETH' */ export function prettyWeiToEth(wei) { return `${formatWeiToEth(wei)} ETH`; } /** * Format milliseconds to time format HH:MM:SS.ms */ export function prettyMsToTime(timeMs) { const date = new Date(0, 0, 0, 0, 0, 0, timeMs); return `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}.${date.getMilliseconds()}`; } /** * Remove 0x prefix from a string */ export function strip0xPrefix(hex) { return hex.startsWith("0x") ? hex.slice(2) : hex; } export function groupSequentialIndices(indices) { if (indices.length === 0) { return []; } // Get unique values and sort them const uniqueValues = Array.from(new Set(indices)).sort((a, b) => a - b); const result = []; let start = uniqueValues[0]; let end = uniqueValues[0]; for (let i = 1; i < uniqueValues.length; i++) { const current = uniqueValues[i]; if (current === end + 1) { end = current; // extend the range } else { result.push(start === end ? `${start}` : `${start}-${end}`); start = current; end = current; } } // Push the last range result.push(start === end ? `${start}` : `${start}-${end}`); return result; } /** * Pretty print indices from an array of numbers. * * example: * ```ts * const indices = [1, 3, 109, 110, 111, 112, 113, 127]; * console.log(prettyPrintIndices(indices)); * // `1,3,110-113,127` * ``` */ export function prettyPrintIndices(indices) { const increments = groupSequentialIndices(indices); return `[${increments.join(", ")}]`; } export function formatBytes(bytes) { if (bytes < 0) { throw new Error("bytes must be a positive number, got " + bytes); } if (bytes === 0) { return "0 Bytes"; } // size of a kb const k = 1024; // only support up to GB const units = ["Bytes", "KB", "MB", "GB"]; const i = Math.min(Math.floor(Math.log(bytes) / Math.log(k)), units.length - 1); const formattedSize = (bytes / Math.pow(k, i)).toFixed(2); return `${formattedSize} ${units[i]}`; } //# sourceMappingURL=format.js.map