kibo: part 3 (broken)

This commit is contained in:
nym21
2025-03-29 13:01:46 +01:00
parent 50bf670931
commit 50ad5f681b
18 changed files with 1077 additions and 2364 deletions

4
Cargo.lock generated
View File

@@ -146,9 +146,9 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
[[package]]
name = "async-compression"
version = "0.4.21"
version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0cf008e5e1a9e9e22a7d3c9a4992e21a350290069e36d8fb72304ed17e8f2d2"
checksum = "59a194f9d963d8099596278594b3107448656ba73831c9d8c783e613ce86da64"
dependencies = [
"brotli",
"flate2",

View File

@@ -8,7 +8,7 @@ package.version = "0.0.10"
package.repository = "https://github.com/bitcoinresearchkit/brk"
[profile.release]
lto = "thin"
lto = "fat"
codegen-units = 1
panic = "abort"

View File

@@ -30,7 +30,7 @@
The Bitcoin Research Kit is a suite of tools designed to parse, index, compute, serve and display data stored on a Bitcoin Core node.
In other words it's an alternative to [Glassnode](https://glassnode.com), [mempool.space](https://mempool.space/) and [electrs](https://github.com/romanz/electrs) all in one package with a particular focus on the self-hosting experience.
In other words it's an alternative to [Glassnode](https://glassnode.com), [mempool.space](https://mempool.space/) and [esplora](https://github.com/Blockstream/electrs)/[electrs](https://github.com/romanz/esplora) all in one package with a particular focus on the self-hosting experience.
The toolkit can be used in various ways to accommodate as many needs as possible.

View File

@@ -1,7 +1,7 @@
use std::ops::{Add, Div};
use derive_deref::Deref;
use serde::Serialize;
use serde::{Serialize, Serializer, ser::SerializeTuple};
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
use super::{Cents, Dollars, Sats};
@@ -37,7 +37,7 @@ impl From<Close<Cents>> for OHLCCents {
}
}
#[derive(Debug, Default, Clone, FromBytes, Immutable, IntoBytes, KnownLayout, Serialize)]
#[derive(Debug, Default, Clone, FromBytes, Immutable, IntoBytes, KnownLayout)]
#[repr(C)]
pub struct OHLCDollars {
pub open: Open<Dollars>,
@@ -46,6 +46,20 @@ pub struct OHLCDollars {
pub close: Close<Dollars>,
}
impl Serialize for OHLCDollars {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut tup = serializer.serialize_tuple(4)?;
tup.serialize_element(&self.open)?;
tup.serialize_element(&self.high)?;
tup.serialize_element(&self.low)?;
tup.serialize_element(&self.close)?;
tup.end()
}
}
impl From<(Open<Dollars>, High<Dollars>, Low<Dollars>, Close<Dollars>)> for OHLCDollars {
fn from(value: (Open<Dollars>, High<Dollars>, Low<Dollars>, Close<Dollars>)) -> Self {
Self {

View File

@@ -5,7 +5,6 @@ use brk_query::{Index, Query};
use crate::Website;
const SCRIPTS: &str = "scripts";
const TPYES: &str = "types";
#[allow(clippy::upper_case_acronyms)]
pub trait DTS {
@@ -24,23 +23,26 @@ impl DTS for Query<'static> {
return Ok(());
}
let path = path.join(SCRIPTS).join(TPYES);
let path = path.join(SCRIPTS);
fs::create_dir_all(&path)?;
let path = path.join(Path::new("vecid-to-indexes.d.ts"));
let path = path.join(Path::new("vecid-to-indexes.js"));
let indexes = Index::all();
let mut contents = indexes
.iter()
.enumerate()
.map(|(i_of_i, i)| format!("type {} = {};", i, i_of_i))
.map(|(i_of_i, i)| {
// let lowered = i.to_string().to_lowercase();
format!("const {i} = {i_of_i};\n/** @typedef {{typeof {i}}} {i} */",)
})
.collect::<Vec<_>>()
.join("\n");
contents += &format!(
"\n\nexport type Index = {};",
"\n\n/** @typedef {{{}}} Index */",
indexes
.iter()
.map(|i| i.to_string())
@@ -48,7 +50,7 @@ impl DTS for Query<'static> {
.join(" | ")
);
contents += "\n\nexport interface VecIdToIndexes {\n";
contents += "\n\nexport const VecIdToIndexes = {\n";
self.vecid_to_index_to_vec
.iter()
@@ -60,7 +62,7 @@ impl DTS for Query<'static> {
.join(", ");
contents += &format!(
" {}: [{indexes}]\n",
" {}: [{indexes}],\n",
if id.contains("-") {
format!("\"{id}\"")
} else {
@@ -71,7 +73,8 @@ impl DTS for Query<'static> {
contents.push('}');
contents += "\n\nexport type VecId = keyof VecIdToIndexes;";
contents += "\n/** @typedef {typeof VecIdToIndexes} VecIdToIndexes */";
contents += "\n/** @typedef {keyof VecIdToIndexes} VecId */\n";
fs::write(path, contents)
}

View File

@@ -7,12 +7,10 @@ import {
LineStyleOptions,
SeriesOptionsCommon,
Time,
CandlestickData,
ISeriesApi,
BaselineData,
} from "./v5.0.4/types";
import { Color, Valued, ValuedCandlestickData } from "../../scripts/types/self";
import { VecId, VecIdToIndexes } from "../../scripts/types/vecid-to-indexes";
} from "./v5.0.5/types";
import { VecId } from "../../scripts/vecid-to-indexes";
interface BaseSeriesBlueprint {
title: string;
@@ -28,7 +26,7 @@ interface CandlestickSeriesBlueprint extends BaseSeriesBlueprint {
type: "Candlestick";
color?: Color;
options?: DeepPartial<CandlestickStyleOptions & SeriesOptionsCommon>;
data?: Accessor<(CandlestickData<Time> & Valued)[]>;
data?: Accessor<CandlestickData[]>;
}
interface LineSeriesBlueprint extends BaseSeriesBlueprint {
type?: "Line";
@@ -47,9 +45,8 @@ type PriceSeriesType = "Candlestick" | "Line";
type RemoveSeriesBlueprintFluff<Blueprint extends AnySpecificSeriesBlueprint> =
Omit<Blueprint, "type" | "title">;
type SplitSeriesBlueprint = {
type SplitSeriesBlueprint<> = {
key: VecId;
main?: boolean;
} & AnySpecificSeriesBlueprint;
type SingleSeriesBlueprint = AnySpecificSeriesBlueprint;
@@ -68,7 +65,7 @@ interface BaseSeries {
}
interface SingleSeries extends BaseSeries {
iseries: ISeriesApi<any>;
dataset: Accessor<(SingleValueData | ValuedCandlestickData)[] | null>;
dataset: Accessor<(SingleValueData | CandlestickData)[] | null>;
}
interface SplitSeries extends BaseSeries {
chunks: Array<Accessor<ISeriesApi<SeriesType> | undefined>>;
@@ -103,8 +100,6 @@ type ChartPane = IChartApi & {
};
interface CreatePaneParameters {
// unit: Unit;
paneIndex?: number;
options?: DeepPartial<ChartOptions>;
config?: SingleSeriesBlueprint[];
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -9,6 +9,7 @@
* @param {Utilities} args.utils
* @param {WebSockets} args.webSockets
* @param {Elements} args.elements
* @param {VecsResources} args.vecsResources
*/
export function init({
colors,
@@ -18,6 +19,7 @@ export function init({
signals,
utils,
webSockets,
vecsResources,
}) {
console.log("init chart state");
@@ -30,7 +32,7 @@ export function init({
titleElement.innerHTML = option.title;
});
const chart = lightweightCharts.createChartElement({
const chartElement = lightweightCharts.createChartElement({
parent: elements.charts,
signals,
colors,
@@ -43,7 +45,6 @@ export function init({
title: "Index",
selected: "date",
choices: [
"Height",
"Timestamp",
"Date",
"Week",
@@ -62,12 +63,20 @@ export function init({
elements.charts.append(fieldset);
// const activeDatasets = signals.createSignal(
// /** @type {Set<ResourceDataset<any, any>>} */ (new Set()),
// {
// equals: false,
// },
// );
const vecs = signals.createSignal(
/** @type {Set<VecResource<any>>} */ (new Set()),
{
equals: false,
},
);
const index = /** @satisfies {Dateindex} */ (1);
chartElement.createChart(index);
const ohlc = vecsResources.getOrCreate(index, "ohlc");
const date = vecsResources.getOrCreate(index, "date");
date.fetch(-10_000);
// function createFetchChunksOfVisibleDatasetsEffect() {
// signals.createEffect(

File diff suppressed because it is too large Load Diff

View File

@@ -5119,7 +5119,6 @@ function createPartialOptions(colors) {
* @param {Object} args
* @param {Colors} args.colors
* @param {Signals} args.signals
* @param {Ids} args.ids
* @param {Env} args.env
* @param {Utilities} args.utils
* @param {WebSockets} args.webSockets
@@ -5128,7 +5127,6 @@ function createPartialOptions(colors) {
export function initOptions({
colors,
signals,
ids,
env,
utils,
webSockets,
@@ -5424,17 +5422,29 @@ export function initOptions({
let title;
if ("kind" in anyPartial) {
// Simulation
kind = anyPartial.kind;
id = anyPartial.kind;
title = anyPartial.title;
} else if ("url" in anyPartial) {
// Url
kind = "url";
id = `${utils.stringToId(anyPartial.name)}-url`;
title = anyPartial.name;
} else {
// Chart
kind = "chart";
title = anyPartial.title || anyPartial.name;
id = `${kind}-${utils.stringToId(title)}`;
const key = anyPartial.bottom?.at(0)?.key;
if (key) {
if (key.includes("-interval")) {
anyPartial.unit = "Seconds";
} else {
console.log(anyPartial);
throw Error("Unit not set");
}
}
}
/** @type {ProcessedOptionAddons} */

View File

@@ -7,16 +7,8 @@
* @param {Signals} args.signals
* @param {Utilities} args.utils
* @param {Elements} args.elements
* @param {Constants} args.consts
*/
export function init({
colors,
elements,
lightweightCharts,
signals,
utils,
consts,
}) {
export function init({ colors, elements, lightweightCharts, signals, utils }) {
/**
* @import { ColorName } from './types/self';
*
@@ -246,7 +238,6 @@ export function init({
parametersElement.append(
utils.dom.createHeader({
title: "Save in Bitcoin",
description: "What if you bought Bitcoin in the past ?",
}).headerElement,
);
@@ -557,7 +548,6 @@ export function init({
kind: "static",
scale: "date",
utils,
consts,
config: [
{
unit: "US Dollars",
@@ -599,7 +589,6 @@ export function init({
scale: "date",
kind: "static",
utils,
consts,
config: [
{
unit: "US Dollars",
@@ -623,7 +612,6 @@ export function init({
scale: "date",
kind: "static",
utils,
consts,
config: [
{
unit: "US Dollars",
@@ -653,7 +641,6 @@ export function init({
scale: "date",
kind: "static",
utils,
consts,
config: [
{
unit: "US Dollars",
@@ -687,7 +674,6 @@ export function init({
scale: "date",
utils,
owner,
consts,
config: [
{
unit: "Percentage",

View File

@@ -10,14 +10,13 @@ import {
SeriesOptionsCommon,
IRange,
Time,
SingleValueData,
CandlestickData,
SingleValueData as _SingleValueData,
CandlestickData as _CandlestickData,
SeriesType,
ISeriesApi,
BaselineData,
} from "../../packages/lightweight-charts/v5.0.4/types";
} from "../../packages/lightweight-charts/v5.0.5/types";
import { AnyPossibleCohortId, Groups } from "../options";
import { Index as _Index, VecIdToIndexes } from "./vecid-to-indexes";
import { Signal } from "../../packages/solid-signals/types";
// type TimeScale = "date" | "height";
@@ -61,10 +60,9 @@ interface PartialOption {
name: string;
}
type DatasetId = keyof VecIdToIndexes;
interface PartialChartOption extends PartialOption {
title?: string;
unit?: string;
top?: SplitSeriesBlueprint[];
bottom?: SplitSeriesBlueprint[];
}
@@ -108,6 +106,7 @@ interface ChartOption
extends Omit<PartialChartOption, "title">,
ProcessedOptionAddons {
kind: "chart";
unit: string;
}
type Option = UrlOption | ChartOption | SimulationOption;
@@ -126,19 +125,11 @@ interface OHLC {
close: number;
}
interface VecResource<Type extends OHLC | number = number> {
url: string;
fetch: (from: number, to: number) => Promise<void>;
ranges: FetchedVecRange<Type>[];
}
type ValuedCandlestickData = CandlestickData & Valued;
interface FetchedVecRange<
Value extends number | OHLC,
Data extends SingleValueData | ValuedCandlestickData = Value extends number
Data extends SingleValueData | CandlestickData = Value extends number
? SingleValueData
: ValuedCandlestickData,
: CandlestickData,
> {
at: Date | null;
fetched: Signal<Value[] | null>;
@@ -149,8 +140,12 @@ interface FetchedVecRange<
interface Valued {
value: number;
}
type DatasetValue<T> = T & Valued;
interface Indexed {
index: number;
}
type ChartData<T> = T & Valued & Indexed;
type SingleValueData = ChartData<_SingleValueData>;
type CandlestickData = ChartData<_CandlestickData>;
type FetchedSource = string;
@@ -164,9 +159,9 @@ interface Weighted {
weight: number;
}
type DatasetCandlestickData = DatasetValue<CandlestickData> & { year: number };
type DatasetCandlestickData = ChartData<CandlestickData>;
type NotFunction<T> = T extends Function ? never : T;
// type NotFunction<T> = T extends Function ? never : T;
type DefaultCohortOption = CohortOption<AnyPossibleCohortId>;
@@ -201,6 +196,3 @@ interface RatioOptions {
// TODO: Remove
// Fetch last of each individually when in viewport
// type LastValues = Record<LastPath, number> | null;
type Timestamp = -1;
type Index = _Index | Timestamp;

View File

@@ -0,0 +1,134 @@
const Addressindex = 0;
/** @typedef {typeof Addressindex} Addressindex */
const Dateindex = 1;
/** @typedef {typeof Dateindex} Dateindex */
const Height = 2;
/** @typedef {typeof Height} Height */
const P2PK33index = 3;
/** @typedef {typeof P2PK33index} P2PK33index */
const P2PK65index = 4;
/** @typedef {typeof P2PK65index} P2PK65index */
const P2PKHindex = 5;
/** @typedef {typeof P2PKHindex} P2PKHindex */
const P2SHindex = 6;
/** @typedef {typeof P2SHindex} P2SHindex */
const P2TRindex = 7;
/** @typedef {typeof P2TRindex} P2TRindex */
const P2WPKHindex = 8;
/** @typedef {typeof P2WPKHindex} P2WPKHindex */
const P2WSHindex = 9;
/** @typedef {typeof P2WSHindex} P2WSHindex */
const Txindex = 10;
/** @typedef {typeof Txindex} Txindex */
const Txinindex = 11;
/** @typedef {typeof Txinindex} Txinindex */
const Txoutindex = 12;
/** @typedef {typeof Txoutindex} Txoutindex */
const Weekindex = 13;
/** @typedef {typeof Weekindex} Weekindex */
const Monthindex = 14;
/** @typedef {typeof Monthindex} Monthindex */
const Yearindex = 15;
/** @typedef {typeof Yearindex} Yearindex */
const Decadeindex = 16;
/** @typedef {typeof Decadeindex} Decadeindex */
const Difficultyepoch = 17;
/** @typedef {typeof Difficultyepoch} Difficultyepoch */
const Halvingepoch = 18;
/** @typedef {typeof Halvingepoch} Halvingepoch */
/** @typedef {Addressindex | Dateindex | Height | P2PK33index | P2PK65index | P2PKHindex | P2SHindex | P2TRindex | P2WPKHindex | P2WSHindex | Txindex | Txinindex | Txoutindex | Weekindex | Monthindex | Yearindex | Decadeindex | Difficultyepoch | Halvingepoch} Index */
export const VecIdToIndexes = {
addressindex: [Txoutindex],
addresstype: [Addressindex],
addresstypeindex: [Addressindex],
"base-size": [Txindex],
"block-count": [Dateindex],
"block-interval": [Height],
"block-interval-10p": [Dateindex],
"block-interval-25p": [Dateindex],
"block-interval-75p": [Dateindex],
"block-interval-90p": [Dateindex],
"block-interval-average": [Dateindex, Weekindex, Monthindex, Yearindex, Decadeindex, Difficultyepoch],
"block-interval-max": [Dateindex, Weekindex, Monthindex, Yearindex, Decadeindex, Difficultyepoch],
"block-interval-median": [Dateindex],
"block-interval-min": [Dateindex, Weekindex, Monthindex, Yearindex, Decadeindex, Difficultyepoch],
blockhash: [Height],
close: [Dateindex, Height, Weekindex, Monthindex, Yearindex, Decadeindex, Difficultyepoch],
"close-in-cents": [Dateindex, Height],
date: [Dateindex],
dateindex: [Dateindex, Height],
decadeindex: [Yearindex, Decadeindex],
difficulty: [Height],
difficultyepoch: [Height, Difficultyepoch],
"first-addressindex": [Height],
"first-dateindex": [Weekindex, Monthindex],
"first-emptyindex": [Height],
"first-height": [Dateindex, Difficultyepoch, Halvingepoch],
"first-monthindex": [Yearindex],
"first-multisigindex": [Height],
"first-open": [Weekindex, Monthindex, Yearindex, Decadeindex, Difficultyepoch],
"first-opreturnindex": [Height],
"first-p2pk33index": [Height],
"first-p2pk65index": [Height],
"first-p2pkhindex": [Height],
"first-p2shindex": [Height],
"first-p2trindex": [Height],
"first-p2wpkhindex": [Height],
"first-p2wshindex": [Height],
"first-pushonlyindex": [Height],
"first-txindex": [Height],
"first-txinindex": [Height, Txindex],
"first-txoutindex": [Height, Txindex],
"first-unkownindex": [Height],
"first-yearindex": [Decadeindex],
"fixed-date": [Height],
halvingepoch: [Height, Halvingepoch],
height: [Addressindex, Height, Txindex],
high: [Dateindex, Height],
"high-in-cents": [Dateindex, Height],
"high-max": [Weekindex, Monthindex, Yearindex, Decadeindex, Difficultyepoch],
"inputs-count": [Txindex],
"is-coinbase": [Txindex],
"is-explicitly-rbf": [Txindex],
"last-dateindex": [Weekindex, Monthindex],
"last-height": [Dateindex, Difficultyepoch, Halvingepoch],
"last-monthindex": [Yearindex],
"last-txindex": [Height],
"last-txinindex": [Txindex],
"last-txoutindex": [Txindex],
"last-yearindex": [Decadeindex],
locktime: [Txindex],
low: [Dateindex, Height],
"low-in-cents": [Dateindex, Height],
"low-min": [Weekindex, Monthindex, Yearindex, Decadeindex, Difficultyepoch],
monthindex: [Dateindex, Monthindex],
ohlc: [Dateindex, Height, Weekindex, Monthindex, Yearindex, Decadeindex, Difficultyepoch],
"ohlc-in-cents": [Dateindex, Height],
open: [Dateindex, Height],
"open-in-cents": [Dateindex, Height],
"outputs-count": [Txindex],
p2pk33addressbytes: [P2PK33index],
p2pk65addressbytes: [P2PK65index],
p2pkhaddressbytes: [P2PKHindex],
p2shaddressbytes: [P2SHindex],
p2traddressbytes: [P2TRindex],
p2wpkhaddressbytes: [P2WPKHindex],
p2wshaddressbytes: [P2WSHindex],
"real-date": [Height],
"sats-per-dollar": [Dateindex, Height],
size: [Height],
timestamp: [Height],
"total-block-count": [Dateindex],
"total-size": [Txindex],
txid: [Txindex],
txoutindex: [Txinindex],
txversion: [Txindex],
value: [Txoutindex],
weekindex: [Dateindex, Weekindex],
weight: [Height],
yearindex: [Monthindex, Yearindex],
}
/** @typedef {typeof VecIdToIndexes} VecIdToIndexes */
/** @typedef {keyof VecIdToIndexes} VecId */

View File

@@ -1,7 +0,0 @@
#live-price {
> h1 {
font-size: 2.5rem;
line-height: 4rem;
text-align: center;
}
}