import { getBtcParts, satsToUsd } from "../../../btc/index.js"; import { getUsdParts } from "../../../usd/index.js"; import { formatFeeRate } from "../../../utils/fee-rate.js"; import { DIFFICULTY_EPOCH_BLOCKS, HALVING_EPOCH_BLOCKS, formatBlockFill, formatBytes, formatDateTime, formatEpoch, formatNumber, formatPoolBlockNumber, formatWeight, } from "../format.js"; /** @typedef {import("../../../modules/brk-client/index.js").BlockInfoV1} Block */ /** * @typedef {Object} ReceiptRow * @property {string} label * @property {string} value * @property {string} [detail] * @property {"total" | "wide"} [variant] */ /** * @typedef {Object} ReceiptSection * @property {string} title * @property {ReceiptRow[]} rows */ /** @param {number} value */ function formatBtc(value) { return getBtcParts(value).map(({ text }) => text).join(""); } /** @param {number} value */ function formatUsd(value) { return getUsdParts(value).map(({ text }) => text).join(""); } /** * @param {number} sats * @param {number} price */ function formatSatsUsd(sats, price) { return formatUsd(satsToUsd(sats, price)); } /** @param {Block} block */ export function createBlockUrl(block) { return new URL(`/block/${block.id}`, window.location.origin).href; } /** @param {string} url */ export function formatDisplayUrl(url) { return url.replace(/^https?:\/\//, ""); } /** * @param {string} label * @param {string} value * @param {"total" | "wide"} [variant] * @returns {ReceiptRow} */ function createRow(label, value, variant) { return { label, value, ...(variant ? { variant } : {}) }; } /** * @param {string} label * @param {string} value * @param {string} detail * @param {"total"} [variant] * @returns {ReceiptRow} */ function createAmountRow(label, value, detail, variant) { return { label, value, detail, ...(variant ? { variant } : {}) }; } /** * @param {string} title * @param {ReceiptRow[]} rows * @returns {ReceiptSection} */ function createSection(title, rows) { return { title, rows }; } /** @param {Block} block */ export function getReceiptSections(block) { const { extras } = block; const subsidy = extras.reward - extras.totalFees; return [ createSection("Summary", [ createRow("Time", formatDateTime(block.timestamp), "wide"), createRow("Price", formatUsd(extras.price)), createRow("Miner", extras.pool.name), createAmountRow( "Reward", formatBtc(extras.reward), formatSatsUsd(extras.reward, extras.price), "total", ), createAmountRow( "Fees", formatBtc(extras.totalFees), formatSatsUsd(extras.totalFees, extras.price), ), createRow("Tx", formatNumber(block.txCount)), createRow( "Size", `${formatBytes(block.size)} ยท ${formatBlockFill(block.weight)}`, ), ]), createSection("Reward split", [ createAmountRow( "Subsidy", formatBtc(subsidy), formatSatsUsd(subsidy, extras.price), ), createAmountRow( "Fees", formatBtc(extras.totalFees), formatSatsUsd(extras.totalFees, extras.price), ), ]), createSection("Block", [ createRow("Weight", formatWeight(block.weight)), createRow("Virtual", `${formatNumber(extras.virtualSize)} vB`), createRow("Avg tx", formatBytes(extras.avgTxSize)), createRow("Input", formatNumber(extras.totalInputs)), createRow("Output", formatNumber(extras.totalOutputs)), ]), createSection("Fees", [ createRow("Median", `${formatFeeRate(extras.medianFee)} sat/vB`), createRow("Average", `${formatFeeRate(extras.avgFeeRate)} sat/vB`), createRow( "Range", `${formatFeeRate(extras.feeRange[0])} - ${formatFeeRate(extras.feeRange[6])} sat/vB`, ), createRow("Avg fee", `${formatNumber(extras.avgFee)} sat`), createRow("Median fee", `${formatNumber(extras.medianFeeAmt)} sat`), ]), createSection("Mining", [ createRow("Pool slug", extras.pool.slug), createRow("Pool block", formatPoolBlockNumber(extras.pool.blockNumber)), createRow("Difficulty", formatNumber(block.difficulty), "wide"), createRow( "Diff epoch", formatEpoch(block.height, DIFFICULTY_EPOCH_BLOCKS), ), createRow("Halving", formatEpoch(block.height, HALVING_EPOCH_BLOCKS)), ]), createSection("Verify", [ createRow("Height", `#${formatNumber(block.height)}`), createRow("Hash", block.id, "wide"), createRow("Previous", block.previousblockhash, "wide"), ]), ]; }