mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-25 07:09:59 -07:00
global: snapshot
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { colors } from "../utils/colors.js";
|
||||
import { brk } from "../client.js";
|
||||
import { brk } from "../utils/client.js";
|
||||
import { Unit } from "../utils/units.js";
|
||||
import {
|
||||
dots,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/** Constant helpers for creating price lines and reference lines */
|
||||
|
||||
import { colors } from "../utils/colors.js";
|
||||
import { brk } from "../client.js";
|
||||
import { brk } from "../utils/client.js";
|
||||
import { line } from "./series.js";
|
||||
|
||||
/**
|
||||
@@ -13,9 +13,7 @@ import { line } from "./series.js";
|
||||
*/
|
||||
export function getConstant(constants, num) {
|
||||
const key =
|
||||
num >= 0
|
||||
? `_${String(num).replace(".", "")}`
|
||||
: `minus${Math.abs(num)}`;
|
||||
num >= 0 ? `_${String(num).replace(".", "")}` : `minus${Math.abs(num)}`;
|
||||
const constant = /** @type {AnySeriesPattern | undefined} */ (
|
||||
/** @type {Record<string, AnySeriesPattern>} */ (constants)[key]
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { colors } from "../../utils/colors.js";
|
||||
import { entries } from "../../utils/array.js";
|
||||
import { brk } from "../../client.js";
|
||||
import { brk } from "../../utils/client.js";
|
||||
|
||||
/** @type {readonly AddressableType[]} */
|
||||
const ADDRESSABLE_TYPES = [
|
||||
|
||||
@@ -8,7 +8,7 @@ import { setQr } from "../panes/share.js";
|
||||
import { getConstant } from "./constants.js";
|
||||
import { colors } from "../utils/colors.js";
|
||||
import { Unit } from "../utils/units.js";
|
||||
import { brk } from "../client.js";
|
||||
import { brk } from "../utils/client.js";
|
||||
|
||||
export function initOptions() {
|
||||
const LS_SELECTED_KEY = `selected_path`;
|
||||
@@ -435,9 +435,11 @@ export function initOptions() {
|
||||
} else if (!("tree" in match)) {
|
||||
selected.set(match);
|
||||
return;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
selected.set(list[0]);
|
||||
selected.set(!segments.length && savedOption ? savedOption : list[0]);
|
||||
}
|
||||
|
||||
resolveUrl();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/** Investing section - Investment strategy tools and analysis */
|
||||
|
||||
import { colors } from "../utils/colors.js";
|
||||
import { brk } from "../client.js";
|
||||
import { brk } from "../utils/client.js";
|
||||
import { percentRatioBaseline, price } from "./series.js";
|
||||
import { satsBtcUsd } from "./shared.js";
|
||||
import { periodIdToName } from "../utils/time.js";
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { colors } from "../utils/colors.js";
|
||||
import { periodIdToName } from "../utils/time.js";
|
||||
import { brk } from "../client.js";
|
||||
import { brk } from "../utils/client.js";
|
||||
import { includes } from "../utils/array.js";
|
||||
import { Unit } from "../utils/units.js";
|
||||
import { priceLine, priceLines } from "./constants.js";
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
revenueRollingBtcSatsUsd,
|
||||
formatCohortTitle,
|
||||
} from "./shared.js";
|
||||
import { brk } from "../client.js";
|
||||
import { brk } from "../utils/client.js";
|
||||
|
||||
/** Major pools to show in Compare section (by current hashrate dominance) */
|
||||
const MAJOR_POOL_IDS = /** @type {const} */ ([
|
||||
@@ -90,20 +90,37 @@ export function createMiningSection() {
|
||||
title: title(metric),
|
||||
bottom: [
|
||||
...ROLLING_WINDOWS.flatMap((w) =>
|
||||
percentRatio({ pattern: dominance[w.key], name: w.name, color: w.color, defaultActive: w.key !== "_24h" }),
|
||||
percentRatio({
|
||||
pattern: dominance[w.key],
|
||||
name: w.name,
|
||||
color: w.color,
|
||||
defaultActive: w.key !== "_24h",
|
||||
}),
|
||||
),
|
||||
...percentRatio({ pattern: dominance, name: "All Time", color: colors.time.all }),
|
||||
...percentRatio({
|
||||
pattern: dominance,
|
||||
name: "All Time",
|
||||
color: colors.time.all,
|
||||
}),
|
||||
],
|
||||
},
|
||||
...ROLLING_WINDOWS.map((w) => ({
|
||||
name: w.name,
|
||||
title: title(`${w.title} ${metric}`),
|
||||
bottom: percentRatio({ pattern: dominance[w.key], name: "Dominance", color: w.color }),
|
||||
bottom: percentRatio({
|
||||
pattern: dominance[w.key],
|
||||
name: "Dominance",
|
||||
color: w.color,
|
||||
}),
|
||||
})),
|
||||
{
|
||||
name: "All Time",
|
||||
title: title(`All Time ${metric}`),
|
||||
bottom: percentRatio({ pattern: dominance, name: "Dominance", color: colors.time.all }),
|
||||
bottom: percentRatio({
|
||||
pattern: dominance,
|
||||
name: "Dominance",
|
||||
color: colors.time.all,
|
||||
}),
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -151,7 +168,11 @@ export function createMiningSection() {
|
||||
{
|
||||
name: "Dominance",
|
||||
title: title("Dominance"),
|
||||
bottom: percentRatio({ pattern: pool.dominance, name: "All Time", color: colors.time.all }),
|
||||
bottom: percentRatio({
|
||||
pattern: pool.dominance,
|
||||
name: "All Time",
|
||||
color: colors.time.all,
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "Blocks Mined",
|
||||
@@ -205,7 +226,6 @@ export function createMiningSection() {
|
||||
],
|
||||
});
|
||||
|
||||
|
||||
return {
|
||||
name: "Mining",
|
||||
tree: [
|
||||
@@ -342,7 +362,9 @@ export function createMiningSection() {
|
||||
tree: ROLLING_WINDOWS.map((w) => ({
|
||||
name: w.name,
|
||||
title: `${w.title} Fee Revenue per Block Distribution`,
|
||||
bottom: distributionBtcSatsUsd(statsAtWindow(mining.rewards.fees, w.key)),
|
||||
bottom: distributionBtcSatsUsd(
|
||||
statsAtWindow(mining.rewards.fees, w.key),
|
||||
),
|
||||
})),
|
||||
},
|
||||
],
|
||||
@@ -354,16 +376,32 @@ export function createMiningSection() {
|
||||
name: w.name,
|
||||
title: `${w.title} Mining Revenue Dominance`,
|
||||
bottom: [
|
||||
...percentRatio({ pattern: mining.rewards.subsidy.dominance[w.key], name: "Subsidy", color: colors.mining.subsidy }),
|
||||
...percentRatio({ pattern: mining.rewards.fees.dominance[w.key], name: "Fees", color: colors.mining.fee }),
|
||||
...percentRatio({
|
||||
pattern: mining.rewards.subsidy.dominance[w.key],
|
||||
name: "Subsidy",
|
||||
color: colors.mining.subsidy,
|
||||
}),
|
||||
...percentRatio({
|
||||
pattern: mining.rewards.fees.dominance[w.key],
|
||||
name: "Fees",
|
||||
color: colors.mining.fee,
|
||||
}),
|
||||
],
|
||||
})),
|
||||
{
|
||||
name: "All Time",
|
||||
title: "All Time Mining Revenue Dominance",
|
||||
bottom: [
|
||||
...percentRatio({ pattern: mining.rewards.subsidy.dominance, name: "Subsidy", color: colors.mining.subsidy }),
|
||||
...percentRatio({ pattern: mining.rewards.fees.dominance, name: "Fees", color: colors.mining.fee }),
|
||||
...percentRatio({
|
||||
pattern: mining.rewards.subsidy.dominance,
|
||||
name: "Subsidy",
|
||||
color: colors.mining.subsidy,
|
||||
}),
|
||||
...percentRatio({
|
||||
pattern: mining.rewards.fees.dominance,
|
||||
name: "Fees",
|
||||
color: colors.mining.fee,
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
@@ -373,7 +411,14 @@ export function createMiningSection() {
|
||||
tree: ROLLING_WINDOWS.map((w) => ({
|
||||
name: w.name,
|
||||
title: `${w.title} Fee-to-Subsidy Ratio`,
|
||||
bottom: [line({ series: mining.rewards.fees.toSubsidyRatio[w.key].ratio, name: "Ratio", color: colors.mining.fee, unit: Unit.ratio })],
|
||||
bottom: [
|
||||
line({
|
||||
series: mining.rewards.fees.toSubsidyRatio[w.key].ratio,
|
||||
name: "Ratio",
|
||||
color: colors.mining.fee,
|
||||
unit: Unit.ratio,
|
||||
}),
|
||||
],
|
||||
})),
|
||||
},
|
||||
{
|
||||
@@ -395,28 +440,76 @@ export function createMiningSection() {
|
||||
name: "Hash Price",
|
||||
title: "Hash Price",
|
||||
bottom: [
|
||||
line({ series: mining.hashrate.price.ths, name: "per TH/s", color: colors.usd, unit: Unit.usdPerThsPerDay }),
|
||||
line({ series: mining.hashrate.price.phs, name: "per PH/s", color: colors.usd, unit: Unit.usdPerPhsPerDay }),
|
||||
dotted({ series: mining.hashrate.price.thsMin, name: "per TH/s ATL", color: colors.stat.min, unit: Unit.usdPerThsPerDay }),
|
||||
dotted({ series: mining.hashrate.price.phsMin, name: "per PH/s ATL", color: colors.stat.min, unit: Unit.usdPerPhsPerDay }),
|
||||
line({
|
||||
series: mining.hashrate.price.ths,
|
||||
name: "per TH/s",
|
||||
color: colors.usd,
|
||||
unit: Unit.usdPerThsPerDay,
|
||||
}),
|
||||
line({
|
||||
series: mining.hashrate.price.phs,
|
||||
name: "per PH/s",
|
||||
color: colors.usd,
|
||||
unit: Unit.usdPerPhsPerDay,
|
||||
}),
|
||||
dotted({
|
||||
series: mining.hashrate.price.thsMin,
|
||||
name: "per TH/s ATL",
|
||||
color: colors.stat.min,
|
||||
unit: Unit.usdPerThsPerDay,
|
||||
}),
|
||||
dotted({
|
||||
series: mining.hashrate.price.phsMin,
|
||||
name: "per PH/s ATL",
|
||||
color: colors.stat.min,
|
||||
unit: Unit.usdPerPhsPerDay,
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Hash Value",
|
||||
title: "Hash Value",
|
||||
bottom: [
|
||||
line({ series: mining.hashrate.value.ths, name: "per TH/s", color: colors.bitcoin, unit: Unit.satsPerThsPerDay }),
|
||||
line({ series: mining.hashrate.value.phs, name: "per PH/s", color: colors.bitcoin, unit: Unit.satsPerPhsPerDay }),
|
||||
dotted({ series: mining.hashrate.value.thsMin, name: "per TH/s ATL", color: colors.stat.min, unit: Unit.satsPerThsPerDay }),
|
||||
dotted({ series: mining.hashrate.value.phsMin, name: "per PH/s ATL", color: colors.stat.min, unit: Unit.satsPerPhsPerDay }),
|
||||
line({
|
||||
series: mining.hashrate.value.ths,
|
||||
name: "per TH/s",
|
||||
color: colors.bitcoin,
|
||||
unit: Unit.satsPerThsPerDay,
|
||||
}),
|
||||
line({
|
||||
series: mining.hashrate.value.phs,
|
||||
name: "per PH/s",
|
||||
color: colors.bitcoin,
|
||||
unit: Unit.satsPerPhsPerDay,
|
||||
}),
|
||||
dotted({
|
||||
series: mining.hashrate.value.thsMin,
|
||||
name: "per TH/s ATL",
|
||||
color: colors.stat.min,
|
||||
unit: Unit.satsPerThsPerDay,
|
||||
}),
|
||||
dotted({
|
||||
series: mining.hashrate.value.phsMin,
|
||||
name: "per PH/s ATL",
|
||||
color: colors.stat.min,
|
||||
unit: Unit.satsPerPhsPerDay,
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Recovery",
|
||||
title: "Hash Price & Value Recovery",
|
||||
bottom: [
|
||||
...percentRatio({ pattern: mining.hashrate.price.rebound, name: "Hash Price", color: colors.usd }),
|
||||
...percentRatio({ pattern: mining.hashrate.value.rebound, name: "Hash Value", color: colors.bitcoin }),
|
||||
...percentRatio({
|
||||
pattern: mining.hashrate.price.rebound,
|
||||
name: "Hash Price",
|
||||
color: colors.usd,
|
||||
}),
|
||||
...percentRatio({
|
||||
pattern: mining.hashrate.value.rebound,
|
||||
name: "Hash Value",
|
||||
color: colors.bitcoin,
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
@@ -429,14 +522,28 @@ export function createMiningSection() {
|
||||
name: "Countdown",
|
||||
title: "Next Halving",
|
||||
bottom: [
|
||||
line({ series: blocks.halving.blocksToHalving, name: "Blocks", unit: Unit.blocks }),
|
||||
line({ series: blocks.halving.daysToHalving, name: "Days", unit: Unit.days }),
|
||||
line({
|
||||
series: blocks.halving.blocksToHalving,
|
||||
name: "Blocks",
|
||||
unit: Unit.blocks,
|
||||
}),
|
||||
line({
|
||||
series: blocks.halving.daysToHalving,
|
||||
name: "Days",
|
||||
unit: Unit.days,
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Epoch",
|
||||
title: "Halving Epoch",
|
||||
bottom: [line({ series: blocks.halving.epoch, name: "Epoch", unit: Unit.epoch })],
|
||||
bottom: [
|
||||
line({
|
||||
series: blocks.halving.epoch,
|
||||
name: "Epoch",
|
||||
unit: Unit.epoch,
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -447,25 +554,48 @@ export function createMiningSection() {
|
||||
{
|
||||
name: "Current",
|
||||
title: "Mining Difficulty",
|
||||
bottom: [line({ series: blocks.difficulty.value, name: "Difficulty", unit: Unit.difficulty })],
|
||||
bottom: [
|
||||
line({
|
||||
series: blocks.difficulty.value,
|
||||
name: "Difficulty",
|
||||
unit: Unit.difficulty,
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Adjustment",
|
||||
title: "Difficulty Adjustment",
|
||||
bottom: percentRatioBaseline({ pattern: blocks.difficulty.adjustment, name: "Change" }),
|
||||
bottom: percentRatioBaseline({
|
||||
pattern: blocks.difficulty.adjustment,
|
||||
name: "Change",
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "Countdown",
|
||||
title: "Next Difficulty Adjustment",
|
||||
bottom: [
|
||||
line({ series: blocks.difficulty.blocksToRetarget, name: "Blocks", unit: Unit.blocks }),
|
||||
line({ series: blocks.difficulty.daysToRetarget, name: "Days", unit: Unit.days }),
|
||||
line({
|
||||
series: blocks.difficulty.blocksToRetarget,
|
||||
name: "Blocks",
|
||||
unit: Unit.blocks,
|
||||
}),
|
||||
line({
|
||||
series: blocks.difficulty.daysToRetarget,
|
||||
name: "Days",
|
||||
unit: Unit.days,
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Epoch",
|
||||
title: "Difficulty Epoch",
|
||||
bottom: [line({ series: blocks.difficulty.epoch, name: "Epoch", unit: Unit.epoch })],
|
||||
bottom: [
|
||||
line({
|
||||
series: blocks.difficulty.epoch,
|
||||
name: "Epoch",
|
||||
unit: Unit.epoch,
|
||||
}),
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/** Network section - On-chain activity and health */
|
||||
|
||||
import { colors } from "../utils/colors.js";
|
||||
import { brk } from "../client.js";
|
||||
import { brk } from "../utils/client.js";
|
||||
import { Unit } from "../utils/units.js";
|
||||
import { entries } from "../utils/array.js";
|
||||
import {
|
||||
@@ -19,7 +19,12 @@ import {
|
||||
multiSeriesTree,
|
||||
percentRatioDots,
|
||||
} from "./series.js";
|
||||
import { satsBtcUsd, satsBtcUsdFrom, satsBtcUsdFullTree, formatCohortTitle } from "./shared.js";
|
||||
import {
|
||||
satsBtcUsd,
|
||||
satsBtcUsdFrom,
|
||||
satsBtcUsdFullTree,
|
||||
formatCohortTitle,
|
||||
} from "./shared.js";
|
||||
|
||||
/**
|
||||
* Create Network section
|
||||
@@ -119,75 +124,79 @@ export function createNetworkSection() {
|
||||
const createAddressSeriesTree = (key, typeName) => {
|
||||
const title = formatCohortTitle(typeName);
|
||||
return [
|
||||
{
|
||||
name: "Count",
|
||||
tree: [
|
||||
{
|
||||
name: "Compare",
|
||||
title: title("Address Count"),
|
||||
bottom: countMetrics.map((m) =>
|
||||
line({
|
||||
series: addrs[m.key][key],
|
||||
name: m.name,
|
||||
color: m.color,
|
||||
unit: Unit.count,
|
||||
}),
|
||||
),
|
||||
},
|
||||
...countMetrics.map((m) => ({
|
||||
name: m.name,
|
||||
title: title(`${m.name} Addresses`),
|
||||
bottom: [
|
||||
line({ series: addrs[m.key][key], name: m.name, unit: Unit.count }),
|
||||
],
|
||||
})),
|
||||
],
|
||||
},
|
||||
...simpleDeltaTree({
|
||||
delta: addrs.delta[key],
|
||||
title,
|
||||
metric: "Address Count",
|
||||
unit: Unit.count,
|
||||
}),
|
||||
{
|
||||
name: "New",
|
||||
tree: chartsFromCount({
|
||||
pattern: addrs.new[key],
|
||||
title,
|
||||
metric: "New Addresses",
|
||||
unit: Unit.count,
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "Activity",
|
||||
tree: [
|
||||
{
|
||||
name: "Compare",
|
||||
tree: ROLLING_WINDOWS.map((w) => ({
|
||||
name: w.name,
|
||||
title: title(`${w.title} Active Addresses`),
|
||||
bottom: activityTypes.map((t, i) =>
|
||||
{
|
||||
name: "Count",
|
||||
tree: [
|
||||
{
|
||||
name: "Compare",
|
||||
title: title("Address Count"),
|
||||
bottom: countMetrics.map((m) =>
|
||||
line({
|
||||
series: addrs.activity[key][t.key][w.key],
|
||||
name: t.name,
|
||||
color: colors.at(i, activityTypes.length),
|
||||
series: addrs[m.key][key],
|
||||
name: m.name,
|
||||
color: m.color,
|
||||
unit: Unit.count,
|
||||
}),
|
||||
),
|
||||
},
|
||||
...countMetrics.map((m) => ({
|
||||
name: m.name,
|
||||
title: title(`${m.name} Addresses`),
|
||||
bottom: [
|
||||
line({
|
||||
series: addrs[m.key][key],
|
||||
name: m.name,
|
||||
unit: Unit.count,
|
||||
}),
|
||||
],
|
||||
})),
|
||||
},
|
||||
...activityTypes.map((t) => ({
|
||||
name: t.name,
|
||||
tree: averagesArray({
|
||||
windows: addrs.activity[key][t.key],
|
||||
title,
|
||||
metric: `${t.name} Addresses`,
|
||||
unit: Unit.count,
|
||||
}),
|
||||
})),
|
||||
],
|
||||
},
|
||||
];
|
||||
],
|
||||
},
|
||||
...simpleDeltaTree({
|
||||
delta: addrs.delta[key],
|
||||
title,
|
||||
metric: "Address Count",
|
||||
unit: Unit.count,
|
||||
}),
|
||||
{
|
||||
name: "New",
|
||||
tree: chartsFromCount({
|
||||
pattern: addrs.new[key],
|
||||
title,
|
||||
metric: "New Addresses",
|
||||
unit: Unit.count,
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "Activity",
|
||||
tree: [
|
||||
{
|
||||
name: "Compare",
|
||||
tree: ROLLING_WINDOWS.map((w) => ({
|
||||
name: w.name,
|
||||
title: title(`${w.title} Active Addresses`),
|
||||
bottom: activityTypes.map((t, i) =>
|
||||
line({
|
||||
series: addrs.activity[key][t.key][w.key],
|
||||
name: t.name,
|
||||
color: colors.at(i, activityTypes.length),
|
||||
unit: Unit.count,
|
||||
}),
|
||||
),
|
||||
})),
|
||||
},
|
||||
...activityTypes.map((t) => ({
|
||||
name: t.name,
|
||||
tree: averagesArray({
|
||||
windows: addrs.activity[key][t.key],
|
||||
title,
|
||||
metric: `${t.name} Addresses`,
|
||||
unit: Unit.count,
|
||||
}),
|
||||
})),
|
||||
],
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
/** @type {Record<string, typeof scriptTypes[number]>} */
|
||||
|
||||
Reference in New Issue
Block a user