global: snapshot

This commit is contained in:
nym21
2026-01-17 22:35:13 +01:00
parent 626c52044d
commit 2e1037ff36
36 changed files with 950 additions and 1066 deletions

197
Cargo.lock generated
View File

@@ -85,54 +85,10 @@ dependencies = [
]
[[package]]
name = "anstream"
version = "0.6.21"
name = "anyhow"
version = "1.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78"
[[package]]
name = "anstyle-parse"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
dependencies = [
"anstyle",
"once_cell_polyfill",
"windows-sys 0.61.2",
]
checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
[[package]]
name = "arrayvec"
@@ -435,13 +391,13 @@ dependencies = [
"oas3",
"serde",
"serde_json",
"tracing",
]
[[package]]
name = "brk_cli"
version = "0.1.0-alpha.3"
dependencies = [
"anyhow",
"brk_alloc",
"brk_computer",
"brk_error",
@@ -454,8 +410,8 @@ dependencies = [
"brk_reader",
"brk_rpc",
"brk_server",
"clap",
"color-eyre",
"brk_types",
"lexopt",
"serde",
"tokio",
"toml",
@@ -729,7 +685,6 @@ dependencies = [
"derive_more",
"itoa",
"jiff",
"num_enum",
"rapidhash",
"ryu",
"schemars",
@@ -854,46 +809,6 @@ dependencies = [
"libloading",
]
[[package]]
name = "clap"
version = "4.5.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.7.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32"
[[package]]
name = "color-eyre"
version = "0.6.5"
@@ -927,12 +842,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "colorchoice"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
[[package]]
name = "compare"
version = "0.0.6"
@@ -1877,12 +1786,6 @@ dependencies = [
"compare",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
[[package]]
name = "itertools"
version = "0.13.0"
@@ -1905,7 +1808,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e67e8da4c49d6d9909fe03361f9b620f58898859f5c7aded68351e85e71ecf50"
dependencies = [
"jiff-static",
"jiff-tzdb-platform",
"log",
"portable-atomic",
"portable-atomic-util",
@@ -1924,21 +1826,6 @@ dependencies = [
"syn",
]
[[package]]
name = "jiff-tzdb"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68971ebff725b9e2ca27a601c5eb38a4c5d64422c4cbab0c535f248087eda5c2"
[[package]]
name = "jiff-tzdb-platform"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8"
dependencies = [
"jiff-tzdb",
]
[[package]]
name = "jobserver"
version = "0.1.34"
@@ -1983,6 +1870,12 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "lexopt"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fa0e2a1fcbe2f6be6c42e342259976206b383122fc152e872795338b5a3f3a7"
[[package]]
name = "libc"
version = "0.2.180"
@@ -2229,28 +2122,6 @@ dependencies = [
"autocfg",
]
[[package]]
name = "num_enum"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c"
dependencies = [
"num_enum_derive",
"rustversion",
]
[[package]]
name = "num_enum_derive"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7"
dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "oas3"
version = "0.20.1"
@@ -2298,12 +2169,6 @@ version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "once_cell_polyfill"
version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
[[package]]
name = "option-ext"
version = "0.2.0"
@@ -2492,15 +2357,6 @@ dependencies = [
"zerocopy",
]
[[package]]
name = "proc-macro-crate"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983"
dependencies = [
"toml_edit",
]
[[package]]
name = "proc-macro2"
version = "1.0.105"
@@ -3052,12 +2908,6 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "strum"
version = "0.27.2"
@@ -3272,18 +3122,6 @@ dependencies = [
"serde_core",
]
[[package]]
name = "toml_edit"
version = "0.23.10+spec-1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269"
dependencies = [
"indexmap",
"toml_datetime",
"toml_parser",
"winnow",
]
[[package]]
name = "toml_parser"
version = "1.0.6+spec-1.1.0"
@@ -3312,7 +3150,6 @@ dependencies = [
"tokio",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
@@ -3355,7 +3192,6 @@ version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
dependencies = [
"log",
"pin-project-lite",
"tracing-attributes",
"tracing-core",
@@ -3485,12 +3321,6 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "valuable"
version = "0.1.1"
@@ -3883,9 +3713,6 @@ name = "winnow"
version = "0.7.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829"
dependencies = [
"memchr",
]
[[package]]
name = "wio"

View File

@@ -37,7 +37,7 @@ debug = true
[workspace.dependencies]
aide = { version = "0.16.0-alpha.2", features = ["axum-json", "axum-query"] }
axum = "0.8.8"
axum = { version = "0.8.8", default-features = false, features = ["http1", "json", "query", "tokio", "tracing"] }
bitcoin = { version = "0.32.8", features = ["serde"] }
bitcoincore-rpc = "0.19.0"
brk_alloc = { version = "0.1.0-alpha.3", path = "crates/brk_alloc" }
@@ -65,7 +65,7 @@ byteview = "0.10.0"
color-eyre = "0.6.5"
derive_more = { version = "2.1.1", features = ["deref", "deref_mut"] }
fjall = "3.0.1"
jiff = "0.2.18"
jiff = { version = "0.2.18", features = ["perf-inline", "tz-system"], default-features = false }
minreq = { version = "2.14.1", features = ["https", "serde_json"] }
parking_lot = "0.12.5"
rayon = "1.11.0"

View File

@@ -14,4 +14,3 @@ brk_types = { workspace = true }
oas3 = "0.20"
serde = { workspace = true }
serde_json = { workspace = true }
tracing = { workspace = true }

View File

@@ -8,9 +8,10 @@ homepage.workspace = true
repository.workspace = true
[dependencies]
anyhow = "1.0"
brk_alloc = { workspace = true }
brk_computer = { workspace = true }
brk_error = { workspace = true }
brk_error = { workspace = true, features = ["tokio", "vecdb"] }
brk_fetcher = { workspace = true }
brk_indexer = { workspace = true }
brk_iterator = { workspace = true }
@@ -20,8 +21,8 @@ brk_query = { workspace = true }
brk_reader = { workspace = true }
brk_rpc = { workspace = true }
brk_server = { workspace = true }
clap = { version = "4.5.54", features = ["derive", "string"] }
color-eyre = { workspace = true }
brk_types = { workspace = true }
lexopt = "0.3"
tracing = { workspace = true }
serde = { workspace = true }
tokio = { workspace = true }

View File

@@ -35,39 +35,21 @@ brk
Indexes the blockchain, computes datasets, starts the server on `localhost:3110`, and waits for new blocks.
## Help
```
brk -h Show all options
brk -V Show version
```
## Options
```bash
brk -h # Show all options
brk -V # Show version
```
Options are saved to `~/.brk/config.toml` after first use.
```
--bitcoindir <PATH> Bitcoin data directory
--blocksdir <PATH> Blocks directory (default: bitcoindir/blocks)
--brkdir <PATH> Output directory (default: ~/.brk)
--rpcconnect <IP> RPC host (default: localhost)
--rpcport <PORT> RPC port (default: 8332)
--rpccookiefile <PATH> RPC cookie file (default: bitcoindir/.cookie)
--rpcuser <USERNAME> RPC username
--rpcpassword <PASSWORD> RPC password
-F, --fetch <BOOL> Fetch price data (default: true)
--exchanges <BOOL> Fetch from exchange APIs (default: true)
-w, --website <BOOL|PATH> Serve web interface (default: true)
```
## Files
```
~/.brk/
├── config.toml Configuration
└── log/ Logs
└── log Logs
<brkdir>/ Indexed data (default: ~/.brk)
```

View File

@@ -6,78 +6,53 @@ use std::{
use brk_error::{Error, Result};
use brk_fetcher::Fetcher;
use brk_rpc::{Auth, Client};
use clap::Parser;
use brk_types::Port;
use serde::{Deserialize, Deserializer, Serialize};
use crate::{default_brk_path, dot_brk_path, fix_user_path, website::WebsiteArg};
#[derive(Parser, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize)]
#[command(version, about)]
#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize)]
pub struct Config {
/// Bitcoin main directory path, defaults: ~/.bitcoin, ~/Library/Application\ Support/Bitcoin, saved
#[serde(default, deserialize_with = "default_on_error")]
#[arg(long, value_name = "PATH")]
bitcoindir: Option<String>,
/// Bitcoin blocks directory path, default: --bitcoindir/blocks, saved
#[serde(default, deserialize_with = "default_on_error")]
#[arg(long, value_name = "PATH")]
blocksdir: Option<String>,
/// Bitcoin Research Kit outputs directory path, default: ~/.brk, saved
#[serde(default, deserialize_with = "default_on_error")]
#[arg(long, value_name = "PATH")]
brkdir: Option<String>,
/// Activate fetching prices from BRK's API and the computation of all price related datasets, default: true, saved
#[serde(default, deserialize_with = "default_on_error")]
#[arg(short = 'F', long, value_name = "BOOL")]
fetch: Option<bool>,
brkport: Option<Port>,
/// Activate fetching prices from exchanges APIs if `fetch` is also set to `true`, default: true, saved
#[serde(default, deserialize_with = "default_on_error")]
#[arg(long, value_name = "BOOL")]
exchanges: Option<bool>,
/// Website served by the server: true (default), false, or PATH, saved
#[serde(default, deserialize_with = "default_on_error")]
#[arg(short, long, value_name = "BOOL|PATH")]
website: Option<WebsiteArg>,
/// Bitcoin RPC ip, default: localhost, saved
#[serde(default, deserialize_with = "default_on_error")]
#[arg(long, value_name = "IP")]
fetch: Option<bool>,
#[serde(default, deserialize_with = "default_on_error")]
bitcoindir: Option<String>,
#[serde(default, deserialize_with = "default_on_error")]
blocksdir: Option<String>,
#[serde(default, deserialize_with = "default_on_error")]
rpcconnect: Option<String>,
/// Bitcoin RPC port, default: 8332, saved
#[serde(default, deserialize_with = "default_on_error")]
#[arg(long, value_name = "PORT")]
rpcport: Option<u16>,
/// Bitcoin RPC cookie file, default: --bitcoindir/.cookie, saved
#[serde(default, deserialize_with = "default_on_error")]
#[arg(long, value_name = "PATH")]
rpccookiefile: Option<String>,
/// Bitcoin RPC username, saved
#[serde(default, deserialize_with = "default_on_error")]
#[arg(long, value_name = "USERNAME")]
rpcuser: Option<String>,
/// Bitcoin RPC password, saved
#[serde(default, deserialize_with = "default_on_error")]
#[arg(long, value_name = "PASSWORD")]
rpcpassword: Option<String>,
/// DEV: Activate checking address hashes for collisions when indexing, default: false, saved
#[serde(default, deserialize_with = "default_on_error")]
#[arg(skip)]
check_collisions: Option<bool>,
}
impl Config {
pub fn import() -> Result<Self> {
let config_args = Some(Config::parse());
let config_args = Self::parse_args();
let path = dot_brk_path();
@@ -85,64 +60,44 @@ impl Config {
let path = path.join("config.toml");
let mut config_saved = Self::read(&path);
let mut config = Self::read(&path);
if let Some(mut config_args) = config_args {
if let Some(bitcoindir) = config_args.bitcoindir.take() {
config_saved.bitcoindir = Some(bitcoindir);
}
if let Some(blocksdir) = config_args.blocksdir.take() {
config_saved.blocksdir = Some(blocksdir);
}
if let Some(brkdir) = config_args.brkdir.take() {
config_saved.brkdir = Some(brkdir);
}
if let Some(fetch) = config_args.fetch.take() {
config_saved.fetch = Some(fetch);
}
if let Some(exchanges) = config_args.exchanges.take() {
config_saved.exchanges = Some(exchanges);
}
if let Some(website) = config_args.website.take() {
config_saved.website = Some(website);
}
if let Some(rpcconnect) = config_args.rpcconnect.take() {
config_saved.rpcconnect = Some(rpcconnect);
}
if let Some(rpcport) = config_args.rpcport.take() {
config_saved.rpcport = Some(rpcport);
}
if let Some(rpccookiefile) = config_args.rpccookiefile.take() {
config_saved.rpccookiefile = Some(rpccookiefile);
}
if let Some(rpcuser) = config_args.rpcuser.take() {
config_saved.rpcuser = Some(rpcuser);
}
if let Some(rpcpassword) = config_args.rpcpassword.take() {
config_saved.rpcpassword = Some(rpcpassword);
}
if let Some(check_collisions) = config_args.check_collisions.take() {
config_saved.check_collisions = Some(check_collisions);
}
if config_args != Config::default() {
dbg!(config_args);
panic!("Didn't consume the full config")
}
if let Some(v) = config_args.brkdir {
config.brkdir = Some(v);
}
if let Some(v) = config_args.brkport {
config.brkport = Some(v);
}
if let Some(v) = config_args.website {
config.website = Some(v);
}
if let Some(v) = config_args.fetch {
config.fetch = Some(v);
}
if let Some(v) = config_args.bitcoindir {
config.bitcoindir = Some(v);
}
if let Some(v) = config_args.blocksdir {
config.blocksdir = Some(v);
}
if let Some(v) = config_args.rpcconnect {
config.rpcconnect = Some(v);
}
if let Some(v) = config_args.rpcport {
config.rpcport = Some(v);
}
if let Some(v) = config_args.rpccookiefile {
config.rpccookiefile = Some(v);
}
if let Some(v) = config_args.rpcuser {
config.rpcuser = Some(v);
}
if let Some(v) = config_args.rpcpassword {
config.rpcpassword = Some(v);
}
if let Some(v) = config_args.check_collisions {
config.check_collisions = Some(v);
}
let config = config_saved;
config.check();
@@ -151,6 +106,73 @@ impl Config {
Ok(config)
}
fn parse_args() -> Self {
use lexopt::prelude::*;
let mut config = Self::default();
let mut parser = lexopt::Parser::from_env();
while let Some(arg) = parser.next().unwrap() {
match arg {
Short('h') | Long("help") => {
Self::print_help();
std::process::exit(0);
}
Short('V') | Long("version") => {
println!("brk {}", env!("CARGO_PKG_VERSION"));
std::process::exit(0);
}
Long("brkdir") => config.brkdir = Some(parser.value().unwrap().parse().unwrap()),
Long("brkport") => config.brkport = Some(parser.value().unwrap().parse().unwrap()),
Long("website") => config.website = Some(parser.value().unwrap().parse().unwrap()),
Long("fetch") => config.fetch = Some(parser.value().unwrap().parse().unwrap()),
Long("bitcoindir") => config.bitcoindir = Some(parser.value().unwrap().parse().unwrap()),
Long("blocksdir") => config.blocksdir = Some(parser.value().unwrap().parse().unwrap()),
Long("rpcconnect") => config.rpcconnect = Some(parser.value().unwrap().parse().unwrap()),
Long("rpcport") => config.rpcport = Some(parser.value().unwrap().parse().unwrap()),
Long("rpccookiefile") => config.rpccookiefile = Some(parser.value().unwrap().parse().unwrap()),
Long("rpcuser") => config.rpcuser = Some(parser.value().unwrap().parse().unwrap()),
Long("rpcpassword") => config.rpcpassword = Some(parser.value().unwrap().parse().unwrap()),
Long("check-collisions") => config.check_collisions = Some(parser.value().unwrap().parse().unwrap()),
_ => {
eprintln!("{}", arg.unexpected());
std::process::exit(1);
}
}
}
config
}
fn print_help() {
println!(
"brk {}
Bitcoin Research Kit
USAGE:
brk [OPTIONS]
OPTIONS:
-h, --help Print help
-V, --version Print version
--brkdir <PATH> Output directory [~/.brk]
--brkport <PORT> Server port [3110]
--website <BOOL|PATH> Website: true, false, or path [true]
--fetch <BOOL> Fetch prices [true]
--bitcoindir <PATH> Bitcoin directory [~/.bitcoin, ~/Library/Application Support/Bitcoin]
--blocksdir <PATH> Blocks directory [<bitcoindir>/blocks]
--rpcconnect <IP> RPC host [localhost]
--rpcport <PORT> RPC port [8332]
--rpccookiefile <PATH> RPC cookie file [<bitcoindir>/.cookie]
--rpcuser <USERNAME> RPC username
--rpcpassword <PASSWORD> RPC password",
env!("CARGO_PKG_VERSION")
);
}
fn check(&self) {
if !self.bitcoindir().is_dir() {
println!("{:?} isn't a valid directory", self.bitcoindir());
@@ -262,17 +284,17 @@ Finally, you can run the program with '-h' for help."
self.website.clone().unwrap_or_default()
}
pub fn brkport(&self) -> Option<Port> {
self.brkport
}
pub fn fetch(&self) -> bool {
self.fetch.is_none_or(|b| b)
}
pub fn exchanges(&self) -> bool {
self.exchanges.is_none_or(|b| b)
}
pub fn fetcher(&self) -> Option<Fetcher> {
self.fetch()
.then(|| Fetcher::import(self.exchanges(), Some(self.harsdir().as_path())).unwrap())
.then(|| Fetcher::import(Some(self.harsdir().as_path())).unwrap())
}
pub fn check_collisions(&self) -> bool {

View File

@@ -24,7 +24,7 @@ mod website;
use crate::{config::Config, paths::*, website::WebsiteArg};
pub fn main() -> color_eyre::Result<()> {
pub fn main() -> anyhow::Result<()> {
// Can't increase main thread's stack size, thus we need to use another thread
thread::Builder::new()
.stack_size(512 * 1024 * 1024)
@@ -33,9 +33,7 @@ pub fn main() -> color_eyre::Result<()> {
.unwrap()
}
pub fn run() -> color_eyre::Result<()> {
color_eyre::install()?;
pub fn run() -> anyhow::Result<()> {
fs::create_dir_all(dot_brk_path())?;
brk_logger::init(Some(&dot_brk_log_path()))?;
@@ -72,11 +70,13 @@ pub fn run() -> color_eyre::Result<()> {
WebsiteArg::Path(p) => Website::Filesystem(p),
};
let port = config.brkport();
let future = async move {
let server = Server::new(&query, data_path, website);
tokio::spawn(async move {
server.serve().await.unwrap();
server.serve(port).await.unwrap();
});
Ok(()) as Result<()>

View File

@@ -1600,40 +1600,6 @@ impl BitcoinPattern {
}
}
/// Pattern struct for repeated tree structure.
pub struct ClassAveragePricePattern<T> {
pub _2015: MetricPattern4<T>,
pub _2016: MetricPattern4<T>,
pub _2017: MetricPattern4<T>,
pub _2018: MetricPattern4<T>,
pub _2019: MetricPattern4<T>,
pub _2020: MetricPattern4<T>,
pub _2021: MetricPattern4<T>,
pub _2022: MetricPattern4<T>,
pub _2023: MetricPattern4<T>,
pub _2024: MetricPattern4<T>,
pub _2025: MetricPattern4<T>,
}
impl<T: DeserializeOwned> ClassAveragePricePattern<T> {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
_2015: MetricPattern4::new(client.clone(), _m(&acc, "2015_returns")),
_2016: MetricPattern4::new(client.clone(), _m(&acc, "2016_returns")),
_2017: MetricPattern4::new(client.clone(), _m(&acc, "2017_returns")),
_2018: MetricPattern4::new(client.clone(), _m(&acc, "2018_returns")),
_2019: MetricPattern4::new(client.clone(), _m(&acc, "2019_returns")),
_2020: MetricPattern4::new(client.clone(), _m(&acc, "2020_returns")),
_2021: MetricPattern4::new(client.clone(), _m(&acc, "2021_returns")),
_2022: MetricPattern4::new(client.clone(), _m(&acc, "2022_returns")),
_2023: MetricPattern4::new(client.clone(), _m(&acc, "2023_returns")),
_2024: MetricPattern4::new(client.clone(), _m(&acc, "2024_returns")),
_2025: MetricPattern4::new(client.clone(), _m(&acc, "2025_returns")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct DollarsPattern<T> {
pub average: MetricPattern2<T>,
@@ -1669,33 +1635,35 @@ impl<T: DeserializeOwned> DollarsPattern<T> {
}
/// Pattern struct for repeated tree structure.
pub struct RelativePattern2 {
pub neg_unrealized_loss_rel_to_own_market_cap: MetricPattern1<StoredF32>,
pub neg_unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1<StoredF32>,
pub net_unrealized_pnl_rel_to_own_market_cap: MetricPattern1<StoredF32>,
pub net_unrealized_pnl_rel_to_own_total_unrealized_pnl: MetricPattern1<StoredF32>,
pub supply_in_loss_rel_to_own_supply: MetricPattern1<StoredF64>,
pub supply_in_profit_rel_to_own_supply: MetricPattern1<StoredF64>,
pub unrealized_loss_rel_to_own_market_cap: MetricPattern1<StoredF32>,
pub unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1<StoredF32>,
pub unrealized_profit_rel_to_own_market_cap: MetricPattern1<StoredF32>,
pub unrealized_profit_rel_to_own_total_unrealized_pnl: MetricPattern1<StoredF32>,
pub struct ClassAveragePricePattern<T> {
pub _2015: MetricPattern4<T>,
pub _2016: MetricPattern4<T>,
pub _2017: MetricPattern4<T>,
pub _2018: MetricPattern4<T>,
pub _2019: MetricPattern4<T>,
pub _2020: MetricPattern4<T>,
pub _2021: MetricPattern4<T>,
pub _2022: MetricPattern4<T>,
pub _2023: MetricPattern4<T>,
pub _2024: MetricPattern4<T>,
pub _2025: MetricPattern4<T>,
}
impl RelativePattern2 {
impl<T: DeserializeOwned> ClassAveragePricePattern<T> {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
neg_unrealized_loss_rel_to_own_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "neg_unrealized_loss_rel_to_own_market_cap")),
neg_unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "neg_unrealized_loss_rel_to_own_total_unrealized_pnl")),
net_unrealized_pnl_rel_to_own_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "net_unrealized_pnl_rel_to_own_market_cap")),
net_unrealized_pnl_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "net_unrealized_pnl_rel_to_own_total_unrealized_pnl")),
supply_in_loss_rel_to_own_supply: MetricPattern1::new(client.clone(), _m(&acc, "supply_in_loss_rel_to_own_supply")),
supply_in_profit_rel_to_own_supply: MetricPattern1::new(client.clone(), _m(&acc, "supply_in_profit_rel_to_own_supply")),
unrealized_loss_rel_to_own_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_loss_rel_to_own_market_cap")),
unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_loss_rel_to_own_total_unrealized_pnl")),
unrealized_profit_rel_to_own_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_profit_rel_to_own_market_cap")),
unrealized_profit_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_profit_rel_to_own_total_unrealized_pnl")),
_2015: MetricPattern4::new(client.clone(), _m(&acc, "2015_returns")),
_2016: MetricPattern4::new(client.clone(), _m(&acc, "2016_returns")),
_2017: MetricPattern4::new(client.clone(), _m(&acc, "2017_returns")),
_2018: MetricPattern4::new(client.clone(), _m(&acc, "2018_returns")),
_2019: MetricPattern4::new(client.clone(), _m(&acc, "2019_returns")),
_2020: MetricPattern4::new(client.clone(), _m(&acc, "2020_returns")),
_2021: MetricPattern4::new(client.clone(), _m(&acc, "2021_returns")),
_2022: MetricPattern4::new(client.clone(), _m(&acc, "2022_returns")),
_2023: MetricPattern4::new(client.clone(), _m(&acc, "2023_returns")),
_2024: MetricPattern4::new(client.clone(), _m(&acc, "2024_returns")),
_2025: MetricPattern4::new(client.clone(), _m(&acc, "2025_returns")),
}
}
}
@@ -1732,6 +1700,38 @@ impl RelativePattern {
}
}
/// Pattern struct for repeated tree structure.
pub struct RelativePattern2 {
pub neg_unrealized_loss_rel_to_own_market_cap: MetricPattern1<StoredF32>,
pub neg_unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1<StoredF32>,
pub net_unrealized_pnl_rel_to_own_market_cap: MetricPattern1<StoredF32>,
pub net_unrealized_pnl_rel_to_own_total_unrealized_pnl: MetricPattern1<StoredF32>,
pub supply_in_loss_rel_to_own_supply: MetricPattern1<StoredF64>,
pub supply_in_profit_rel_to_own_supply: MetricPattern1<StoredF64>,
pub unrealized_loss_rel_to_own_market_cap: MetricPattern1<StoredF32>,
pub unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1<StoredF32>,
pub unrealized_profit_rel_to_own_market_cap: MetricPattern1<StoredF32>,
pub unrealized_profit_rel_to_own_total_unrealized_pnl: MetricPattern1<StoredF32>,
}
impl RelativePattern2 {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
neg_unrealized_loss_rel_to_own_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "neg_unrealized_loss_rel_to_own_market_cap")),
neg_unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "neg_unrealized_loss_rel_to_own_total_unrealized_pnl")),
net_unrealized_pnl_rel_to_own_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "net_unrealized_pnl_rel_to_own_market_cap")),
net_unrealized_pnl_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "net_unrealized_pnl_rel_to_own_total_unrealized_pnl")),
supply_in_loss_rel_to_own_supply: MetricPattern1::new(client.clone(), _m(&acc, "supply_in_loss_rel_to_own_supply")),
supply_in_profit_rel_to_own_supply: MetricPattern1::new(client.clone(), _m(&acc, "supply_in_profit_rel_to_own_supply")),
unrealized_loss_rel_to_own_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_loss_rel_to_own_market_cap")),
unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_loss_rel_to_own_total_unrealized_pnl")),
unrealized_profit_rel_to_own_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_profit_rel_to_own_market_cap")),
unrealized_profit_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_profit_rel_to_own_total_unrealized_pnl")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct CountPattern2<T> {
pub average: MetricPattern1<T>,
@@ -1910,32 +1910,6 @@ impl<T: DeserializeOwned> PhaseDailyCentsPattern<T> {
}
}
/// Pattern struct for repeated tree structure.
pub struct _10yPattern {
pub activity: ActivityPattern2,
pub cost_basis: CostBasisPattern,
pub outputs: OutputsPattern,
pub realized: RealizedPattern4,
pub relative: RelativePattern,
pub supply: SupplyPattern2,
pub unrealized: UnrealizedPattern,
}
impl _10yPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
activity: ActivityPattern2::new(client.clone(), acc.clone()),
cost_basis: CostBasisPattern::new(client.clone(), acc.clone()),
outputs: OutputsPattern::new(client.clone(), _m(&acc, "utxo_count")),
realized: RealizedPattern4::new(client.clone(), acc.clone()),
relative: RelativePattern::new(client.clone(), acc.clone()),
supply: SupplyPattern2::new(client.clone(), _m(&acc, "supply")),
unrealized: UnrealizedPattern::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct PeriodCagrPattern {
pub _10y: MetricPattern4<StoredF32>,
@@ -1962,32 +1936,6 @@ impl PeriodCagrPattern {
}
}
/// Pattern struct for repeated tree structure.
pub struct _10yTo12yPattern {
pub activity: ActivityPattern2,
pub cost_basis: CostBasisPattern2,
pub outputs: OutputsPattern,
pub realized: RealizedPattern2,
pub relative: RelativePattern2,
pub supply: SupplyPattern2,
pub unrealized: UnrealizedPattern,
}
impl _10yTo12yPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
activity: ActivityPattern2::new(client.clone(), acc.clone()),
cost_basis: CostBasisPattern2::new(client.clone(), acc.clone()),
outputs: OutputsPattern::new(client.clone(), _m(&acc, "utxo_count")),
realized: RealizedPattern2::new(client.clone(), acc.clone()),
relative: RelativePattern2::new(client.clone(), acc.clone()),
supply: SupplyPattern2::new(client.clone(), _m(&acc, "supply")),
unrealized: UnrealizedPattern::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct _0satsPattern2 {
pub activity: ActivityPattern2,
@@ -2015,27 +1963,53 @@ impl _0satsPattern2 {
}
/// Pattern struct for repeated tree structure.
pub struct UnrealizedPattern {
pub neg_unrealized_loss: MetricPattern1<Dollars>,
pub net_unrealized_pnl: MetricPattern1<Dollars>,
pub supply_in_loss: ActiveSupplyPattern,
pub supply_in_profit: ActiveSupplyPattern,
pub total_unrealized_pnl: MetricPattern1<Dollars>,
pub unrealized_loss: MetricPattern1<Dollars>,
pub unrealized_profit: MetricPattern1<Dollars>,
pub struct _10yPattern {
pub activity: ActivityPattern2,
pub cost_basis: CostBasisPattern,
pub outputs: OutputsPattern,
pub realized: RealizedPattern4,
pub relative: RelativePattern,
pub supply: SupplyPattern2,
pub unrealized: UnrealizedPattern,
}
impl UnrealizedPattern {
impl _10yPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
neg_unrealized_loss: MetricPattern1::new(client.clone(), _m(&acc, "neg_unrealized_loss")),
net_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "net_unrealized_pnl")),
supply_in_loss: ActiveSupplyPattern::new(client.clone(), _m(&acc, "supply_in_loss")),
supply_in_profit: ActiveSupplyPattern::new(client.clone(), _m(&acc, "supply_in_profit")),
total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "total_unrealized_pnl")),
unrealized_loss: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_loss")),
unrealized_profit: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_profit")),
activity: ActivityPattern2::new(client.clone(), acc.clone()),
cost_basis: CostBasisPattern::new(client.clone(), acc.clone()),
outputs: OutputsPattern::new(client.clone(), _m(&acc, "utxo_count")),
realized: RealizedPattern4::new(client.clone(), acc.clone()),
relative: RelativePattern::new(client.clone(), acc.clone()),
supply: SupplyPattern2::new(client.clone(), _m(&acc, "supply")),
unrealized: UnrealizedPattern::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct _10yTo12yPattern {
pub activity: ActivityPattern2,
pub cost_basis: CostBasisPattern2,
pub outputs: OutputsPattern,
pub realized: RealizedPattern2,
pub relative: RelativePattern2,
pub supply: SupplyPattern2,
pub unrealized: UnrealizedPattern,
}
impl _10yTo12yPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
activity: ActivityPattern2::new(client.clone(), acc.clone()),
cost_basis: CostBasisPattern2::new(client.clone(), acc.clone()),
outputs: OutputsPattern::new(client.clone(), _m(&acc, "utxo_count")),
realized: RealizedPattern2::new(client.clone(), acc.clone()),
relative: RelativePattern2::new(client.clone(), acc.clone()),
supply: SupplyPattern2::new(client.clone(), _m(&acc, "supply")),
unrealized: UnrealizedPattern::new(client.clone(), acc.clone()),
}
}
}
@@ -2066,6 +2040,32 @@ impl _100btcPattern {
}
}
/// Pattern struct for repeated tree structure.
pub struct UnrealizedPattern {
pub neg_unrealized_loss: MetricPattern1<Dollars>,
pub net_unrealized_pnl: MetricPattern1<Dollars>,
pub supply_in_loss: ActiveSupplyPattern,
pub supply_in_profit: ActiveSupplyPattern,
pub total_unrealized_pnl: MetricPattern1<Dollars>,
pub unrealized_loss: MetricPattern1<Dollars>,
pub unrealized_profit: MetricPattern1<Dollars>,
}
impl UnrealizedPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
neg_unrealized_loss: MetricPattern1::new(client.clone(), _m(&acc, "neg_unrealized_loss")),
net_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "net_unrealized_pnl")),
supply_in_loss: ActiveSupplyPattern::new(client.clone(), _m(&acc, "supply_in_loss")),
supply_in_profit: ActiveSupplyPattern::new(client.clone(), _m(&acc, "supply_in_profit")),
total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "total_unrealized_pnl")),
unrealized_loss: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_loss")),
unrealized_profit: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_profit")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct ActivityPattern2 {
pub coinblocks_destroyed: BlockCountPattern<StoredF64>,
@@ -2108,60 +2108,6 @@ impl<T: DeserializeOwned> SplitPattern2<T> {
}
}
/// Pattern struct for repeated tree structure.
pub struct SegwitAdoptionPattern {
pub base: MetricPattern11<StoredF32>,
pub cumulative: MetricPattern2<StoredF32>,
pub sum: MetricPattern2<StoredF32>,
}
impl SegwitAdoptionPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
base: MetricPattern11::new(client.clone(), acc.clone()),
cumulative: MetricPattern2::new(client.clone(), _m(&acc, "cumulative")),
sum: MetricPattern2::new(client.clone(), _m(&acc, "sum")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct ActiveSupplyPattern {
pub bitcoin: MetricPattern1<Bitcoin>,
pub dollars: MetricPattern1<Dollars>,
pub sats: MetricPattern1<Sats>,
}
impl ActiveSupplyPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
bitcoin: MetricPattern1::new(client.clone(), _m(&acc, "btc")),
dollars: MetricPattern1::new(client.clone(), _m(&acc, "usd")),
sats: MetricPattern1::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct _2015Pattern {
pub bitcoin: MetricPattern4<Bitcoin>,
pub dollars: MetricPattern4<Dollars>,
pub sats: MetricPattern4<Sats>,
}
impl _2015Pattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
bitcoin: MetricPattern4::new(client.clone(), _m(&acc, "btc")),
dollars: MetricPattern4::new(client.clone(), _m(&acc, "usd")),
sats: MetricPattern4::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct CostBasisPattern2 {
pub max: MetricPattern1<Dollars>,
@@ -2180,24 +2126,6 @@ impl CostBasisPattern2 {
}
}
/// Pattern struct for repeated tree structure.
pub struct CoinbasePattern2 {
pub bitcoin: BlockCountPattern<Bitcoin>,
pub dollars: BlockCountPattern<Dollars>,
pub sats: BlockCountPattern<Sats>,
}
impl CoinbasePattern2 {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
bitcoin: BlockCountPattern::new(client.clone(), _m(&acc, "btc")),
dollars: BlockCountPattern::new(client.clone(), _m(&acc, "usd")),
sats: BlockCountPattern::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct CoinbasePattern {
pub bitcoin: BitcoinPattern,
@@ -2216,6 +2144,24 @@ impl CoinbasePattern {
}
}
/// Pattern struct for repeated tree structure.
pub struct ActiveSupplyPattern {
pub bitcoin: MetricPattern1<Bitcoin>,
pub dollars: MetricPattern1<Dollars>,
pub sats: MetricPattern1<Sats>,
}
impl ActiveSupplyPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
bitcoin: MetricPattern1::new(client.clone(), _m(&acc, "btc")),
dollars: MetricPattern1::new(client.clone(), _m(&acc, "usd")),
sats: MetricPattern1::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct UnclaimedRewardsPattern {
pub bitcoin: BitcoinPattern2<Bitcoin>,
@@ -2234,6 +2180,60 @@ impl UnclaimedRewardsPattern {
}
}
/// Pattern struct for repeated tree structure.
pub struct CoinbasePattern2 {
pub bitcoin: BlockCountPattern<Bitcoin>,
pub dollars: BlockCountPattern<Dollars>,
pub sats: BlockCountPattern<Sats>,
}
impl CoinbasePattern2 {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
bitcoin: BlockCountPattern::new(client.clone(), _m(&acc, "btc")),
dollars: BlockCountPattern::new(client.clone(), _m(&acc, "usd")),
sats: BlockCountPattern::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct _2015Pattern {
pub bitcoin: MetricPattern4<Bitcoin>,
pub dollars: MetricPattern4<Dollars>,
pub sats: MetricPattern4<Sats>,
}
impl _2015Pattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
bitcoin: MetricPattern4::new(client.clone(), _m(&acc, "btc")),
dollars: MetricPattern4::new(client.clone(), _m(&acc, "usd")),
sats: MetricPattern4::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct SegwitAdoptionPattern {
pub base: MetricPattern11<StoredF32>,
pub cumulative: MetricPattern2<StoredF32>,
pub sum: MetricPattern2<StoredF32>,
}
impl SegwitAdoptionPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
base: MetricPattern11::new(client.clone(), acc.clone()),
cumulative: MetricPattern2::new(client.clone(), _m(&acc, "cumulative")),
sum: MetricPattern2::new(client.clone(), _m(&acc, "sum")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct _1dReturns1mSdPattern {
pub sd: MetricPattern4<StoredF32>,
@@ -2250,22 +2250,6 @@ impl _1dReturns1mSdPattern {
}
}
/// Pattern struct for repeated tree structure.
pub struct RelativePattern4 {
pub supply_in_loss_rel_to_own_supply: MetricPattern1<StoredF64>,
pub supply_in_profit_rel_to_own_supply: MetricPattern1<StoredF64>,
}
impl RelativePattern4 {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
supply_in_loss_rel_to_own_supply: MetricPattern1::new(client.clone(), _m(&acc, "loss_rel_to_own_supply")),
supply_in_profit_rel_to_own_supply: MetricPattern1::new(client.clone(), _m(&acc, "profit_rel_to_own_supply")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct CostBasisPattern {
pub max: MetricPattern1<Dollars>,
@@ -2282,6 +2266,22 @@ impl CostBasisPattern {
}
}
/// Pattern struct for repeated tree structure.
pub struct RelativePattern4 {
pub supply_in_loss_rel_to_own_supply: MetricPattern1<StoredF64>,
pub supply_in_profit_rel_to_own_supply: MetricPattern1<StoredF64>,
}
impl RelativePattern4 {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
supply_in_loss_rel_to_own_supply: MetricPattern1::new(client.clone(), _m(&acc, "loss_rel_to_own_supply")),
supply_in_profit_rel_to_own_supply: MetricPattern1::new(client.clone(), _m(&acc, "profit_rel_to_own_supply")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct SupplyPattern2 {
pub halved: ActiveSupplyPattern,
@@ -2298,22 +2298,6 @@ impl SupplyPattern2 {
}
}
/// Pattern struct for repeated tree structure.
pub struct BlockCountPattern<T> {
pub cumulative: MetricPattern1<T>,
pub sum: MetricPattern1<T>,
}
impl<T: DeserializeOwned> BlockCountPattern<T> {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
cumulative: MetricPattern1::new(client.clone(), _m(&acc, "cumulative")),
sum: MetricPattern1::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct BitcoinPattern2<T> {
pub cumulative: MetricPattern2<T>,
@@ -2340,22 +2324,24 @@ impl<T: DeserializeOwned> SatsPattern<T> {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
ohlc: MetricPattern1::new(client.clone(), _m(&acc, "ohlc")),
split: SplitPattern2::new(client.clone(), acc.clone()),
ohlc: MetricPattern1::new(client.clone(), _m(&acc, "ohlc_sats")),
split: SplitPattern2::new(client.clone(), _m(&acc, "sats")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct RealizedPriceExtraPattern {
pub ratio: MetricPattern4<StoredF32>,
pub struct BlockCountPattern<T> {
pub cumulative: MetricPattern1<T>,
pub sum: MetricPattern1<T>,
}
impl RealizedPriceExtraPattern {
impl<T: DeserializeOwned> BlockCountPattern<T> {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
ratio: MetricPattern4::new(client.clone(), acc.clone()),
cumulative: MetricPattern1::new(client.clone(), _m(&acc, "cumulative")),
sum: MetricPattern1::new(client.clone(), acc.clone()),
}
}
}
@@ -2374,6 +2360,20 @@ impl OutputsPattern {
}
}
/// Pattern struct for repeated tree structure.
pub struct RealizedPriceExtraPattern {
pub ratio: MetricPattern4<StoredF32>,
}
impl RealizedPriceExtraPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
ratio: MetricPattern4::new(client.clone(), acc.clone()),
}
}
}
// Metrics tree
/// Metrics tree node.
@@ -4942,8 +4942,8 @@ impl MetricsTree_Positions {
pub struct MetricsTree_Price {
pub cents: MetricsTree_Price_Cents,
pub oracle: MetricsTree_Price_Oracle,
pub sats: MetricsTree_Price_Sats,
pub usd: SatsPattern<OHLCDollars>,
pub sats: SatsPattern<OHLCSats>,
pub usd: MetricsTree_Price_Usd,
}
impl MetricsTree_Price {
@@ -4951,8 +4951,8 @@ impl MetricsTree_Price {
Self {
cents: MetricsTree_Price_Cents::new(client.clone(), format!("{base_path}_cents")),
oracle: MetricsTree_Price_Oracle::new(client.clone(), format!("{base_path}_oracle")),
sats: MetricsTree_Price_Sats::new(client.clone(), format!("{base_path}_sats")),
usd: SatsPattern::new(client.clone(), "price".to_string()),
sats: SatsPattern::new(client.clone(), "price".to_string()),
usd: MetricsTree_Price_Usd::new(client.clone(), format!("{base_path}_usd")),
}
}
}
@@ -5055,16 +5055,16 @@ impl MetricsTree_Price_Oracle {
}
/// Metrics tree node.
pub struct MetricsTree_Price_Sats {
pub ohlc: MetricPattern1<OHLCSats>,
pub split: SplitPattern2<Sats>,
pub struct MetricsTree_Price_Usd {
pub ohlc: MetricPattern1<OHLCDollars>,
pub split: SplitPattern2<Dollars>,
}
impl MetricsTree_Price_Sats {
impl MetricsTree_Price_Usd {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
ohlc: MetricPattern1::new(client.clone(), "price_ohlc_sats".to_string()),
split: SplitPattern2::new(client.clone(), "price_sats".to_string()),
ohlc: MetricPattern1::new(client.clone(), "price_ohlc".to_string()),
split: SplitPattern2::new(client.clone(), "price".to_string()),
}
}
}

View File

@@ -8,7 +8,7 @@ homepage.workspace = true
repository.workspace = true
[dependencies]
brk_error = { workspace = true }
brk_error = { workspace = true, features = ["vecdb"] }
brk_types = { workspace = true }
brk_traversable = { workspace = true }
vecdb = { workspace = true }

View File

@@ -9,7 +9,7 @@ repository.workspace = true
[dependencies]
bitcoin = { workspace = true }
brk_error = { workspace = true }
brk_error = { workspace = true, features = ["vecdb"] }
brk_fetcher = { workspace = true }
brk_cohort = { workspace = true }
brk_indexer = { workspace = true }

View File

@@ -48,7 +48,7 @@ fn run() -> Result<()> {
let mut indexer = Indexer::forced_import(&outputs_dir)?;
let fetcher = Fetcher::import(true, None)?;
let fetcher = Fetcher::import(None)?;
let exit = Exit::new();
exit.set_ctrlc_handler();

View File

@@ -42,7 +42,7 @@ fn run() -> Result<()> {
let mut indexer = Indexer::forced_import(&outputs_dir)?;
let fetcher = Fetcher::import(true, None)?;
let fetcher = Fetcher::import(None)?;
let mut computer = Computer::forced_import(&outputs_benches_dir, &indexer, Some(fetcher))?;

View File

@@ -22,7 +22,7 @@ fn run() -> Result<()> {
let indexer = Indexer::forced_import(&outputs_dir)?;
let fetcher = Fetcher::import(true, None)?;
let fetcher = Fetcher::import(None)?;
let exit = Exit::new();
exit.set_ctrlc_handler();

View File

@@ -60,7 +60,7 @@ fn run() -> Result<()> {
let blocks = Blocks::new(&client, &reader);
let fetcher = Fetcher::import(true, None)?;
let fetcher = Fetcher::import(None)?;
info!("Ping: {:?}", fetcher.brk.ping()?);

View File

@@ -7,13 +7,23 @@ license.workspace = true
homepage.workspace = true
repository.workspace = true
[features]
bitcoin = ["dep:bitcoin"]
bitcoincore-rpc = ["dep:bitcoincore-rpc"]
fjall = ["dep:fjall"]
jiff = ["dep:jiff"]
minreq = ["dep:minreq"]
serde_json = ["dep:serde_json"]
tokio = ["dep:tokio"]
vecdb = ["dep:vecdb"]
[dependencies]
bitcoin = { workspace = true }
bitcoincore-rpc = { workspace = true }
fjall = { workspace = true }
jiff = { workspace = true }
minreq = { workspace = true }
serde_json = { workspace = true }
bitcoin = { workspace = true, optional = true }
bitcoincore-rpc = { workspace = true, optional = true }
fjall = { workspace = true, optional = true }
jiff = { workspace = true, optional = true }
minreq = { workspace = true, optional = true }
serde_json = { workspace = true, optional = true }
thiserror = "2.0"
tokio = { workspace = true }
vecdb = { workspace = true }
tokio = { workspace = true, optional = true }
vecdb = { workspace = true, optional = true }

View File

@@ -11,45 +11,58 @@ pub enum Error {
#[error(transparent)]
IO(#[from] io::Error),
#[cfg(feature = "bitcoincore-rpc")]
#[error(transparent)]
BitcoinRPC(#[from] bitcoincore_rpc::Error),
#[cfg(feature = "jiff")]
#[error(transparent)]
Jiff(#[from] jiff::Error),
#[cfg(feature = "fjall")]
#[error(transparent)]
Fjall(#[from] fjall::Error),
#[cfg(feature = "vecdb")]
#[error(transparent)]
VecDB(#[from] vecdb::Error),
#[cfg(feature = "vecdb")]
#[error(transparent)]
RawDB(#[from] vecdb::RawDBError),
#[cfg(feature = "minreq")]
#[error(transparent)]
Minreq(#[from] minreq::Error),
#[error(transparent)]
SystemTimeError(#[from] time::SystemTimeError),
#[cfg(feature = "bitcoin")]
#[error(transparent)]
BitcoinConsensusEncode(#[from] bitcoin::consensus::encode::Error),
#[cfg(feature = "bitcoin")]
#[error(transparent)]
BitcoinBip34Error(#[from] bitcoin::block::Bip34Error),
#[cfg(feature = "bitcoin")]
#[error(transparent)]
BitcoinHexError(#[from] bitcoin::consensus::encode::FromHexError),
#[cfg(feature = "bitcoin")]
#[error(transparent)]
BitcoinFromScriptError(#[from] bitcoin::address::FromScriptError),
#[cfg(feature = "bitcoin")]
#[error(transparent)]
BitcoinHexToArrayError(#[from] bitcoin::hex::HexToArrayError),
#[cfg(feature = "serde_json")]
#[error(transparent)]
SerdeJSON(#[from] serde_json::Error),
#[cfg(feature = "tokio")]
#[error(transparent)]
TokioJoin(#[from] tokio::task::JoinError),
@@ -139,12 +152,14 @@ pub enum Error {
impl Error {
/// Returns true if this error is due to a file lock (another process has the database open).
/// Lock errors are transient and should not trigger data deletion.
#[cfg(feature = "vecdb")]
pub fn is_lock_error(&self) -> bool {
matches!(self, Error::VecDB(e) if e.is_lock_error())
}
/// Returns true if this error indicates data corruption or version incompatibility.
/// These errors may require resetting/deleting the data to recover.
#[cfg(feature = "vecdb")]
pub fn is_data_error(&self) -> bool {
matches!(self, Error::VecDB(e) if e.is_data_error())
}
@@ -154,6 +169,7 @@ impl Error {
/// Returns false for transient errors worth retrying (timeouts, rate limits, server errors).
pub fn is_network_permanently_blocked(&self) -> bool {
match self {
#[cfg(feature = "minreq")]
Error::Minreq(e) => is_minreq_error_permanent(e),
Error::IO(e) => is_io_error_permanent(e),
// 403 Forbidden suggests IP/geo blocking; 429 and 5xx are transient
@@ -164,6 +180,7 @@ impl Error {
}
}
#[cfg(feature = "minreq")]
fn is_minreq_error_permanent(e: &minreq::Error) -> bool {
use minreq::Error::*;
match e {

View File

@@ -8,7 +8,7 @@ homepage.workspace = true
repository.workspace = true
[dependencies]
brk_error = { workspace = true }
brk_error = { workspace = true, features = ["minreq", "serde_json"] }
brk_logger = { workspace = true }
brk_types = { workspace = true }
tracing = { workspace = true }

View File

@@ -17,7 +17,7 @@ Fetch OHLC (Open/High/Low/Close) price data from Binance, Kraken, or BRK's own A
## Core API
```rust,ignore
let mut fetcher = Fetcher::import(true, Some(&hars_path))?;
let mut fetcher = Fetcher::import(Some(&hars_path))?;
// Daily price
let ohlc = fetcher.get_date(Date::new(2024, 4, 20))?;

View File

@@ -9,7 +9,7 @@ fn main() -> Result<()> {
dbg!(brk.get_from_height(Height::new(900_000))?);
dbg!(brk.get_from_date(Date::new(2025, 6, 7))?);
let mut fetcher = Fetcher::new(true, None)?;
let mut fetcher = Fetcher::new(None)?;
let _ = Binance::fetch_1d().map(|b| {
dbg!(b.last_key_value());

View File

@@ -37,20 +37,20 @@ pub fn check_response(response: minreq::Response, url: &str) -> Result<Vec<u8>>
#[derive(Clone)]
pub struct Fetcher {
pub binance: Option<TrackedSource<Binance>>,
pub kraken: Option<TrackedSource<Kraken>>,
pub binance: TrackedSource<Binance>,
pub kraken: TrackedSource<Kraken>,
pub brk: TrackedSource<BRK>,
}
impl Fetcher {
pub fn import(exchanges: bool, hars_path: Option<&Path>) -> Result<Self> {
Self::new(exchanges, hars_path)
pub fn import(hars_path: Option<&Path>) -> Result<Self> {
Self::new(hars_path)
}
pub fn new(exchanges: bool, hars_path: Option<&Path>) -> Result<Self> {
pub fn new(hars_path: Option<&Path>) -> Result<Self> {
Ok(Self {
binance: exchanges.then(|| TrackedSource::new(Binance::init(hars_path))),
kraken: exchanges.then(|| TrackedSource::new(Kraken::default())),
binance: TrackedSource::new(Binance::init(hars_path)),
kraken: TrackedSource::new(Kraken::default()),
brk: TrackedSource::new(BRK::default()),
})
}
@@ -60,12 +60,8 @@ impl Fetcher {
where
F: FnMut(&mut dyn PriceSource),
{
if let Some(binance) = &mut self.binance {
f(binance);
}
if let Some(kraken) = &mut self.kraken {
f(kraken);
}
f(&mut self.binance);
f(&mut self.kraken);
f(&mut self.brk);
}
@@ -74,14 +70,10 @@ impl Fetcher {
where
F: FnMut(&mut dyn PriceSource) -> Option<Result<OHLCCents>>,
{
if let Some(binance) = &mut self.binance
&& let Some(Ok(ohlc)) = fetch(binance)
{
if let Some(Ok(ohlc)) = fetch(&mut self.binance) {
return Some(Ok(ohlc));
}
if let Some(kraken) = &mut self.kraken
&& let Some(Ok(ohlc)) = fetch(kraken)
{
if let Some(Ok(ohlc)) = fetch(&mut self.kraken) {
return Some(Ok(ohlc));
}
if let Some(Ok(ohlc)) = fetch(&mut self.brk) {
@@ -168,30 +160,20 @@ How to fix this:
/// Clear caches and reset health state for all sources
pub fn clear(&mut self) {
if let Some(binance) = &mut self.binance {
binance.clear();
binance.reset_health();
}
if let Some(kraken) = &mut self.kraken {
kraken.clear();
kraken.reset_health();
}
self.binance.clear();
self.binance.reset_health();
self.kraken.clear();
self.kraken.reset_health();
self.brk.clear();
self.brk.reset_health();
}
/// Ping all sources and return results for each
pub fn ping(&self) -> Vec<(&'static str, Result<()>)> {
let mut results = Vec::new();
if let Some(binance) = &self.binance {
results.push((binance.name(), binance.ping()));
}
if let Some(kraken) = &self.kraken {
results.push((kraken.name(), kraken.ping()));
}
results.push((self.brk.name(), self.brk.ping()));
results
vec![
(self.binance.name(), self.binance.ping()),
(self.kraken.name(), self.kraken.ping()),
(self.brk.name(), self.brk.ping()),
]
}
}

View File

@@ -9,7 +9,7 @@ repository.workspace = true
[dependencies]
bitcoin = { workspace = true }
brk_error = { workspace = true }
brk_error = { workspace = true, features = ["fjall", "vecdb"] }
brk_cohort = { workspace = true }
brk_iterator = { workspace = true }
brk_logger = { workspace = true }

View File

@@ -13,7 +13,7 @@ tokio = ["dep:tokio"]
[dependencies]
bitcoin = { workspace = true }
brk_computer = { workspace = true }
brk_error = { workspace = true }
brk_error = { workspace = true, features = ["jiff", "vecdb"] }
brk_indexer = { workspace = true }
brk_mempool = { workspace = true }
brk_reader = { workspace = true }

View File

@@ -10,7 +10,7 @@ repository.workspace = true
[dependencies]
bitcoin = { workspace = true }
bitcoincore-rpc = { workspace = true }
brk_error = { workspace = true }
brk_error = { workspace = true, features = ["bitcoincore-rpc"] }
brk_logger = { workspace = true }
brk_types = { workspace = true }
tracing = { workspace = true }

View File

@@ -13,7 +13,7 @@ aide = { workspace = true }
axum = { workspace = true }
brk_bindgen = { workspace = true }
brk_computer = { workspace = true }
brk_error = { workspace = true }
brk_error = { workspace = true, features = ["jiff", "serde_json", "tokio", "vecdb"] }
brk_fetcher = { workspace = true }
brk_indexer = { workspace = true }
brk_logger = { workspace = true }
@@ -34,7 +34,7 @@ serde = { workspace = true }
serde_json = { workspace = true }
tokio = { workspace = true }
tracing = { workspace = true }
tower-http = { version = "0.6.8", features = ["catch-panic", "compression-full", "cors", "normalize-path", "timeout", "trace"] }
tower-http = { version = "0.6.8", features = ["catch-panic", "compression-br", "compression-gzip", "compression-zstd", "cors", "normalize-path", "timeout", "trace"] }
tower-layer = "0.3"
[dev-dependencies]

View File

@@ -34,7 +34,7 @@ fn run() -> Result<()> {
let reader = Reader::new(bitcoin_dir.join("blocks"), &client);
let indexer = Indexer::forced_import(&outputs_dir)?;
let fetcher = Some(Fetcher::import(true, None)?);
let fetcher = Some(Fetcher::import(None)?);
let computer = Computer::forced_import(&outputs_dir, &indexer, fetcher)?;
let mempool = Mempool::new(&client);

View File

@@ -40,6 +40,7 @@ mod files;
mod state;
use api::*;
pub use brk_types::Port;
pub use cache::{CacheParams, CacheStrategy};
pub use error::{Error, Result};
use extended::*;
@@ -65,12 +66,11 @@ impl Server {
})
}
pub async fn serve(self) -> brk_error::Result<()> {
pub async fn serve(self, port: Option<Port>) -> brk_error::Result<()> {
let state = self.0;
let compression_layer = CompressionLayer::new()
.br(true)
.deflate(true)
.gzip(true)
.zstd(true);
@@ -138,15 +138,23 @@ impl Server {
.layer(TimeoutLayer::with_status_code(StatusCode::GATEWAY_TIMEOUT, Duration::from_secs(5)))
.layer(CorsLayer::permissive());
const BASE_PORT: u16 = 3110;
const MAX_PORT: u16 = BASE_PORT + 100;
let mut port = BASE_PORT;
let listener = loop {
match TcpListener::bind(format!("0.0.0.0:{port}")).await {
Ok(l) => break l,
Err(_) if port < MAX_PORT => port += 1,
Err(e) => return Err(e.into()),
let (listener, port) = match port {
Some(port) => {
let listener = TcpListener::bind(format!("0.0.0.0:{port}")).await?;
(listener, *port)
}
None => {
let base_port: u16 = *Port::DEFAULT;
let max_port: u16 = base_port + 100;
let mut port = base_port;
let listener = loop {
match TcpListener::bind(format!("0.0.0.0:{port}")).await {
Ok(l) => break l,
Err(_) if port < max_port => port += 1,
Err(e) => return Err(e.into()),
}
};
(listener, port)
}
};

View File

@@ -10,7 +10,7 @@ homepage.workspace = true
repository.workspace = true
[dependencies]
brk_error = { workspace = true }
brk_error = { workspace = true, features = ["fjall"] }
brk_types = { workspace = true }
byteview = { workspace = true }
fjall = { workspace = true }

View File

@@ -9,12 +9,11 @@ repository.workspace = true
[dependencies]
bitcoin = { workspace = true }
brk_error = { workspace = true }
brk_error = { workspace = true, features = ["bitcoin", "jiff", "serde_json", "vecdb"] }
byteview = { workspace = true }
derive_more = { workspace = true }
itoa = "1.0.17"
jiff = { workspace = true }
num_enum = "0.7.5"
rapidhash = "4.2.1"
ryu = "1.0.22"
schemars = { workspace = true }

View File

@@ -115,6 +115,7 @@ mod paginationindex;
mod percentile;
mod pool;
mod pooldetail;
mod port;
mod poolinfo;
mod pools;
mod poolslug;
@@ -285,6 +286,7 @@ pub use percentile::*;
pub use pool::*;
pub use pooldetail::*;
pub use poolinfo::*;
pub use port::*;
pub use pools::*;
pub use poolslug::*;
pub use poolslugparam::*;

View File

@@ -1,4 +1,3 @@
use num_enum::{FromPrimitive, IntoPrimitive};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use strum::Display;
@@ -19,8 +18,6 @@ use vecdb::{Bytes, Formattable};
Serialize,
Deserialize,
JsonSchema,
FromPrimitive,
IntoPrimitive,
)]
#[serde(rename_all = "lowercase")]
#[strum(serialize_all = "lowercase")]
@@ -412,3 +409,18 @@ impl Bytes for PoolSlug {
Ok(s)
}
}
impl From<u8> for PoolSlug {
#[inline]
fn from(val: u8) -> Self {
// SAFETY: PoolSlug is repr(u8) and all 256 values are valid (includes dummy variants)
unsafe { std::mem::transmute(val) }
}
}
impl From<PoolSlug> for u8 {
#[inline]
fn from(val: PoolSlug) -> u8 {
val as u8
}
}

View File

@@ -0,0 +1,49 @@
use std::{fmt, str::FromStr};
use derive_more::Deref;
use serde::{Deserialize, Serialize};
/// Server port. Defaults to 3110.
#[derive(Debug, Clone, Copy, Deref, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord)]
#[serde(transparent)]
pub struct Port(u16);
impl Port {
pub const DEFAULT: Self = Self(3110);
pub const fn new(port: u16) -> Self {
Self(port)
}
}
impl Default for Port {
fn default() -> Self {
Self::DEFAULT
}
}
impl fmt::Display for Port {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl From<u16> for Port {
fn from(value: u16) -> Self {
Self(value)
}
}
impl From<Port> for u16 {
fn from(value: Port) -> Self {
value.0
}
}
impl FromStr for Port {
type Err = std::num::ParseIntError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
s.parse::<u16>().map(Self)
}
}

1
modules/.gitignore vendored
View File

@@ -1,7 +1,6 @@
LICENSE
**/*.*.*/*.json
*webcomponent*
README*.md
cli*
extras/
*.cjs

View File

@@ -2005,45 +2005,6 @@ function createBitcoinPattern(client, acc) {
};
}
/**
* @template T
* @typedef {Object} ClassAveragePricePattern
* @property {MetricPattern4<T>} _2015
* @property {MetricPattern4<T>} _2016
* @property {MetricPattern4<T>} _2017
* @property {MetricPattern4<T>} _2018
* @property {MetricPattern4<T>} _2019
* @property {MetricPattern4<T>} _2020
* @property {MetricPattern4<T>} _2021
* @property {MetricPattern4<T>} _2022
* @property {MetricPattern4<T>} _2023
* @property {MetricPattern4<T>} _2024
* @property {MetricPattern4<T>} _2025
*/
/**
* Create a ClassAveragePricePattern pattern node
* @template T
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {ClassAveragePricePattern<T>}
*/
function createClassAveragePricePattern(client, acc) {
return {
_2015: createMetricPattern4(client, _m(acc, '2015_returns')),
_2016: createMetricPattern4(client, _m(acc, '2016_returns')),
_2017: createMetricPattern4(client, _m(acc, '2017_returns')),
_2018: createMetricPattern4(client, _m(acc, '2018_returns')),
_2019: createMetricPattern4(client, _m(acc, '2019_returns')),
_2020: createMetricPattern4(client, _m(acc, '2020_returns')),
_2021: createMetricPattern4(client, _m(acc, '2021_returns')),
_2022: createMetricPattern4(client, _m(acc, '2022_returns')),
_2023: createMetricPattern4(client, _m(acc, '2023_returns')),
_2024: createMetricPattern4(client, _m(acc, '2024_returns')),
_2025: createMetricPattern4(client, _m(acc, '2025_returns')),
};
}
/**
* @template T
* @typedef {Object} DollarsPattern
@@ -2084,37 +2045,41 @@ function createDollarsPattern(client, acc) {
}
/**
* @typedef {Object} RelativePattern2
* @property {MetricPattern1<StoredF32>} negUnrealizedLossRelToOwnMarketCap
* @property {MetricPattern1<StoredF32>} negUnrealizedLossRelToOwnTotalUnrealizedPnl
* @property {MetricPattern1<StoredF32>} netUnrealizedPnlRelToOwnMarketCap
* @property {MetricPattern1<StoredF32>} netUnrealizedPnlRelToOwnTotalUnrealizedPnl
* @property {MetricPattern1<StoredF64>} supplyInLossRelToOwnSupply
* @property {MetricPattern1<StoredF64>} supplyInProfitRelToOwnSupply
* @property {MetricPattern1<StoredF32>} unrealizedLossRelToOwnMarketCap
* @property {MetricPattern1<StoredF32>} unrealizedLossRelToOwnTotalUnrealizedPnl
* @property {MetricPattern1<StoredF32>} unrealizedProfitRelToOwnMarketCap
* @property {MetricPattern1<StoredF32>} unrealizedProfitRelToOwnTotalUnrealizedPnl
* @template T
* @typedef {Object} ClassAveragePricePattern
* @property {MetricPattern4<T>} _2015
* @property {MetricPattern4<T>} _2016
* @property {MetricPattern4<T>} _2017
* @property {MetricPattern4<T>} _2018
* @property {MetricPattern4<T>} _2019
* @property {MetricPattern4<T>} _2020
* @property {MetricPattern4<T>} _2021
* @property {MetricPattern4<T>} _2022
* @property {MetricPattern4<T>} _2023
* @property {MetricPattern4<T>} _2024
* @property {MetricPattern4<T>} _2025
*/
/**
* Create a RelativePattern2 pattern node
* Create a ClassAveragePricePattern pattern node
* @template T
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {RelativePattern2}
* @returns {ClassAveragePricePattern<T>}
*/
function createRelativePattern2(client, acc) {
function createClassAveragePricePattern(client, acc) {
return {
negUnrealizedLossRelToOwnMarketCap: createMetricPattern1(client, _m(acc, 'neg_unrealized_loss_rel_to_own_market_cap')),
negUnrealizedLossRelToOwnTotalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'neg_unrealized_loss_rel_to_own_total_unrealized_pnl')),
netUnrealizedPnlRelToOwnMarketCap: createMetricPattern1(client, _m(acc, 'net_unrealized_pnl_rel_to_own_market_cap')),
netUnrealizedPnlRelToOwnTotalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'net_unrealized_pnl_rel_to_own_total_unrealized_pnl')),
supplyInLossRelToOwnSupply: createMetricPattern1(client, _m(acc, 'supply_in_loss_rel_to_own_supply')),
supplyInProfitRelToOwnSupply: createMetricPattern1(client, _m(acc, 'supply_in_profit_rel_to_own_supply')),
unrealizedLossRelToOwnMarketCap: createMetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_own_market_cap')),
unrealizedLossRelToOwnTotalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_own_total_unrealized_pnl')),
unrealizedProfitRelToOwnMarketCap: createMetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_own_market_cap')),
unrealizedProfitRelToOwnTotalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_own_total_unrealized_pnl')),
_2015: createMetricPattern4(client, _m(acc, '2015_returns')),
_2016: createMetricPattern4(client, _m(acc, '2016_returns')),
_2017: createMetricPattern4(client, _m(acc, '2017_returns')),
_2018: createMetricPattern4(client, _m(acc, '2018_returns')),
_2019: createMetricPattern4(client, _m(acc, '2019_returns')),
_2020: createMetricPattern4(client, _m(acc, '2020_returns')),
_2021: createMetricPattern4(client, _m(acc, '2021_returns')),
_2022: createMetricPattern4(client, _m(acc, '2022_returns')),
_2023: createMetricPattern4(client, _m(acc, '2023_returns')),
_2024: createMetricPattern4(client, _m(acc, '2024_returns')),
_2025: createMetricPattern4(client, _m(acc, '2025_returns')),
};
}
@@ -2153,6 +2118,41 @@ function createRelativePattern(client, acc) {
};
}
/**
* @typedef {Object} RelativePattern2
* @property {MetricPattern1<StoredF32>} negUnrealizedLossRelToOwnMarketCap
* @property {MetricPattern1<StoredF32>} negUnrealizedLossRelToOwnTotalUnrealizedPnl
* @property {MetricPattern1<StoredF32>} netUnrealizedPnlRelToOwnMarketCap
* @property {MetricPattern1<StoredF32>} netUnrealizedPnlRelToOwnTotalUnrealizedPnl
* @property {MetricPattern1<StoredF64>} supplyInLossRelToOwnSupply
* @property {MetricPattern1<StoredF64>} supplyInProfitRelToOwnSupply
* @property {MetricPattern1<StoredF32>} unrealizedLossRelToOwnMarketCap
* @property {MetricPattern1<StoredF32>} unrealizedLossRelToOwnTotalUnrealizedPnl
* @property {MetricPattern1<StoredF32>} unrealizedProfitRelToOwnMarketCap
* @property {MetricPattern1<StoredF32>} unrealizedProfitRelToOwnTotalUnrealizedPnl
*/
/**
* Create a RelativePattern2 pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {RelativePattern2}
*/
function createRelativePattern2(client, acc) {
return {
negUnrealizedLossRelToOwnMarketCap: createMetricPattern1(client, _m(acc, 'neg_unrealized_loss_rel_to_own_market_cap')),
negUnrealizedLossRelToOwnTotalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'neg_unrealized_loss_rel_to_own_total_unrealized_pnl')),
netUnrealizedPnlRelToOwnMarketCap: createMetricPattern1(client, _m(acc, 'net_unrealized_pnl_rel_to_own_market_cap')),
netUnrealizedPnlRelToOwnTotalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'net_unrealized_pnl_rel_to_own_total_unrealized_pnl')),
supplyInLossRelToOwnSupply: createMetricPattern1(client, _m(acc, 'supply_in_loss_rel_to_own_supply')),
supplyInProfitRelToOwnSupply: createMetricPattern1(client, _m(acc, 'supply_in_profit_rel_to_own_supply')),
unrealizedLossRelToOwnMarketCap: createMetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_own_market_cap')),
unrealizedLossRelToOwnTotalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_own_total_unrealized_pnl')),
unrealizedProfitRelToOwnMarketCap: createMetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_own_market_cap')),
unrealizedProfitRelToOwnTotalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_own_total_unrealized_pnl')),
};
}
/**
* @template T
* @typedef {Object} CountPattern2
@@ -2357,35 +2357,6 @@ function createPhaseDailyCentsPattern(client, acc) {
};
}
/**
* @typedef {Object} _10yPattern
* @property {ActivityPattern2} activity
* @property {CostBasisPattern} costBasis
* @property {OutputsPattern} outputs
* @property {RealizedPattern4} realized
* @property {RelativePattern} relative
* @property {SupplyPattern2} supply
* @property {UnrealizedPattern} unrealized
*/
/**
* Create a _10yPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {_10yPattern}
*/
function create_10yPattern(client, acc) {
return {
activity: createActivityPattern2(client, acc),
costBasis: createCostBasisPattern(client, acc),
outputs: createOutputsPattern(client, _m(acc, 'utxo_count')),
realized: createRealizedPattern4(client, acc),
relative: createRelativePattern(client, acc),
supply: createSupplyPattern2(client, _m(acc, 'supply')),
unrealized: createUnrealizedPattern(client, acc),
};
}
/**
* @typedef {Object} PeriodCagrPattern
* @property {MetricPattern4<StoredF32>} _10y
@@ -2415,35 +2386,6 @@ function createPeriodCagrPattern(client, acc) {
};
}
/**
* @typedef {Object} _10yTo12yPattern
* @property {ActivityPattern2} activity
* @property {CostBasisPattern2} costBasis
* @property {OutputsPattern} outputs
* @property {RealizedPattern2} realized
* @property {RelativePattern2} relative
* @property {SupplyPattern2} supply
* @property {UnrealizedPattern} unrealized
*/
/**
* Create a _10yTo12yPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {_10yTo12yPattern}
*/
function create_10yTo12yPattern(client, acc) {
return {
activity: createActivityPattern2(client, acc),
costBasis: createCostBasisPattern2(client, acc),
outputs: createOutputsPattern(client, _m(acc, 'utxo_count')),
realized: createRealizedPattern2(client, acc),
relative: createRelativePattern2(client, acc),
supply: createSupplyPattern2(client, _m(acc, 'supply')),
unrealized: createUnrealizedPattern(client, acc),
};
}
/**
* @typedef {Object} _0satsPattern2
* @property {ActivityPattern2} activity
@@ -2474,31 +2416,60 @@ function create_0satsPattern2(client, acc) {
}
/**
* @typedef {Object} UnrealizedPattern
* @property {MetricPattern1<Dollars>} negUnrealizedLoss
* @property {MetricPattern1<Dollars>} netUnrealizedPnl
* @property {ActiveSupplyPattern} supplyInLoss
* @property {ActiveSupplyPattern} supplyInProfit
* @property {MetricPattern1<Dollars>} totalUnrealizedPnl
* @property {MetricPattern1<Dollars>} unrealizedLoss
* @property {MetricPattern1<Dollars>} unrealizedProfit
* @typedef {Object} _10yPattern
* @property {ActivityPattern2} activity
* @property {CostBasisPattern} costBasis
* @property {OutputsPattern} outputs
* @property {RealizedPattern4} realized
* @property {RelativePattern} relative
* @property {SupplyPattern2} supply
* @property {UnrealizedPattern} unrealized
*/
/**
* Create a UnrealizedPattern pattern node
* Create a _10yPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {UnrealizedPattern}
* @returns {_10yPattern}
*/
function createUnrealizedPattern(client, acc) {
function create_10yPattern(client, acc) {
return {
negUnrealizedLoss: createMetricPattern1(client, _m(acc, 'neg_unrealized_loss')),
netUnrealizedPnl: createMetricPattern1(client, _m(acc, 'net_unrealized_pnl')),
supplyInLoss: createActiveSupplyPattern(client, _m(acc, 'supply_in_loss')),
supplyInProfit: createActiveSupplyPattern(client, _m(acc, 'supply_in_profit')),
totalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'total_unrealized_pnl')),
unrealizedLoss: createMetricPattern1(client, _m(acc, 'unrealized_loss')),
unrealizedProfit: createMetricPattern1(client, _m(acc, 'unrealized_profit')),
activity: createActivityPattern2(client, acc),
costBasis: createCostBasisPattern(client, acc),
outputs: createOutputsPattern(client, _m(acc, 'utxo_count')),
realized: createRealizedPattern4(client, acc),
relative: createRelativePattern(client, acc),
supply: createSupplyPattern2(client, _m(acc, 'supply')),
unrealized: createUnrealizedPattern(client, acc),
};
}
/**
* @typedef {Object} _10yTo12yPattern
* @property {ActivityPattern2} activity
* @property {CostBasisPattern2} costBasis
* @property {OutputsPattern} outputs
* @property {RealizedPattern2} realized
* @property {RelativePattern2} relative
* @property {SupplyPattern2} supply
* @property {UnrealizedPattern} unrealized
*/
/**
* Create a _10yTo12yPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {_10yTo12yPattern}
*/
function create_10yTo12yPattern(client, acc) {
return {
activity: createActivityPattern2(client, acc),
costBasis: createCostBasisPattern2(client, acc),
outputs: createOutputsPattern(client, _m(acc, 'utxo_count')),
realized: createRealizedPattern2(client, acc),
relative: createRelativePattern2(client, acc),
supply: createSupplyPattern2(client, _m(acc, 'supply')),
unrealized: createUnrealizedPattern(client, acc),
};
}
@@ -2531,6 +2502,35 @@ function create_100btcPattern(client, acc) {
};
}
/**
* @typedef {Object} UnrealizedPattern
* @property {MetricPattern1<Dollars>} negUnrealizedLoss
* @property {MetricPattern1<Dollars>} netUnrealizedPnl
* @property {ActiveSupplyPattern} supplyInLoss
* @property {ActiveSupplyPattern} supplyInProfit
* @property {MetricPattern1<Dollars>} totalUnrealizedPnl
* @property {MetricPattern1<Dollars>} unrealizedLoss
* @property {MetricPattern1<Dollars>} unrealizedProfit
*/
/**
* Create a UnrealizedPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {UnrealizedPattern}
*/
function createUnrealizedPattern(client, acc) {
return {
negUnrealizedLoss: createMetricPattern1(client, _m(acc, 'neg_unrealized_loss')),
netUnrealizedPnl: createMetricPattern1(client, _m(acc, 'net_unrealized_pnl')),
supplyInLoss: createActiveSupplyPattern(client, _m(acc, 'supply_in_loss')),
supplyInProfit: createActiveSupplyPattern(client, _m(acc, 'supply_in_profit')),
totalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'total_unrealized_pnl')),
unrealizedLoss: createMetricPattern1(client, _m(acc, 'unrealized_loss')),
unrealizedProfit: createMetricPattern1(client, _m(acc, 'unrealized_profit')),
};
}
/**
* @typedef {Object} ActivityPattern2
* @property {BlockCountPattern<StoredF64>} coinblocksDestroyed
@@ -2581,69 +2581,6 @@ function createSplitPattern2(client, acc) {
};
}
/**
* @typedef {Object} SegwitAdoptionPattern
* @property {MetricPattern11<StoredF32>} base
* @property {MetricPattern2<StoredF32>} cumulative
* @property {MetricPattern2<StoredF32>} sum
*/
/**
* Create a SegwitAdoptionPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {SegwitAdoptionPattern}
*/
function createSegwitAdoptionPattern(client, acc) {
return {
base: createMetricPattern11(client, acc),
cumulative: createMetricPattern2(client, _m(acc, 'cumulative')),
sum: createMetricPattern2(client, _m(acc, 'sum')),
};
}
/**
* @typedef {Object} ActiveSupplyPattern
* @property {MetricPattern1<Bitcoin>} bitcoin
* @property {MetricPattern1<Dollars>} dollars
* @property {MetricPattern1<Sats>} sats
*/
/**
* Create a ActiveSupplyPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {ActiveSupplyPattern}
*/
function createActiveSupplyPattern(client, acc) {
return {
bitcoin: createMetricPattern1(client, _m(acc, 'btc')),
dollars: createMetricPattern1(client, _m(acc, 'usd')),
sats: createMetricPattern1(client, acc),
};
}
/**
* @typedef {Object} _2015Pattern
* @property {MetricPattern4<Bitcoin>} bitcoin
* @property {MetricPattern4<Dollars>} dollars
* @property {MetricPattern4<Sats>} sats
*/
/**
* Create a _2015Pattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {_2015Pattern}
*/
function create_2015Pattern(client, acc) {
return {
bitcoin: createMetricPattern4(client, _m(acc, 'btc')),
dollars: createMetricPattern4(client, _m(acc, 'usd')),
sats: createMetricPattern4(client, acc),
};
}
/**
* @typedef {Object} CostBasisPattern2
* @property {MetricPattern1<Dollars>} max
@@ -2665,27 +2602,6 @@ function createCostBasisPattern2(client, acc) {
};
}
/**
* @typedef {Object} CoinbasePattern2
* @property {BlockCountPattern<Bitcoin>} bitcoin
* @property {BlockCountPattern<Dollars>} dollars
* @property {BlockCountPattern<Sats>} sats
*/
/**
* Create a CoinbasePattern2 pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {CoinbasePattern2}
*/
function createCoinbasePattern2(client, acc) {
return {
bitcoin: createBlockCountPattern(client, _m(acc, 'btc')),
dollars: createBlockCountPattern(client, _m(acc, 'usd')),
sats: createBlockCountPattern(client, acc),
};
}
/**
* @typedef {Object} CoinbasePattern
* @property {BitcoinPattern} bitcoin
@@ -2707,6 +2623,27 @@ function createCoinbasePattern(client, acc) {
};
}
/**
* @typedef {Object} ActiveSupplyPattern
* @property {MetricPattern1<Bitcoin>} bitcoin
* @property {MetricPattern1<Dollars>} dollars
* @property {MetricPattern1<Sats>} sats
*/
/**
* Create a ActiveSupplyPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {ActiveSupplyPattern}
*/
function createActiveSupplyPattern(client, acc) {
return {
bitcoin: createMetricPattern1(client, _m(acc, 'btc')),
dollars: createMetricPattern1(client, _m(acc, 'usd')),
sats: createMetricPattern1(client, acc),
};
}
/**
* @typedef {Object} UnclaimedRewardsPattern
* @property {BitcoinPattern2<Bitcoin>} bitcoin
@@ -2728,6 +2665,69 @@ function createUnclaimedRewardsPattern(client, acc) {
};
}
/**
* @typedef {Object} CoinbasePattern2
* @property {BlockCountPattern<Bitcoin>} bitcoin
* @property {BlockCountPattern<Dollars>} dollars
* @property {BlockCountPattern<Sats>} sats
*/
/**
* Create a CoinbasePattern2 pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {CoinbasePattern2}
*/
function createCoinbasePattern2(client, acc) {
return {
bitcoin: createBlockCountPattern(client, _m(acc, 'btc')),
dollars: createBlockCountPattern(client, _m(acc, 'usd')),
sats: createBlockCountPattern(client, acc),
};
}
/**
* @typedef {Object} _2015Pattern
* @property {MetricPattern4<Bitcoin>} bitcoin
* @property {MetricPattern4<Dollars>} dollars
* @property {MetricPattern4<Sats>} sats
*/
/**
* Create a _2015Pattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {_2015Pattern}
*/
function create_2015Pattern(client, acc) {
return {
bitcoin: createMetricPattern4(client, _m(acc, 'btc')),
dollars: createMetricPattern4(client, _m(acc, 'usd')),
sats: createMetricPattern4(client, acc),
};
}
/**
* @typedef {Object} SegwitAdoptionPattern
* @property {MetricPattern11<StoredF32>} base
* @property {MetricPattern2<StoredF32>} cumulative
* @property {MetricPattern2<StoredF32>} sum
*/
/**
* Create a SegwitAdoptionPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {SegwitAdoptionPattern}
*/
function createSegwitAdoptionPattern(client, acc) {
return {
base: createMetricPattern11(client, acc),
cumulative: createMetricPattern2(client, _m(acc, 'cumulative')),
sum: createMetricPattern2(client, _m(acc, 'sum')),
};
}
/**
* @typedef {Object} _1dReturns1mSdPattern
* @property {MetricPattern4<StoredF32>} sd
@@ -2747,25 +2747,6 @@ function create_1dReturns1mSdPattern(client, acc) {
};
}
/**
* @typedef {Object} RelativePattern4
* @property {MetricPattern1<StoredF64>} supplyInLossRelToOwnSupply
* @property {MetricPattern1<StoredF64>} supplyInProfitRelToOwnSupply
*/
/**
* Create a RelativePattern4 pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {RelativePattern4}
*/
function createRelativePattern4(client, acc) {
return {
supplyInLossRelToOwnSupply: createMetricPattern1(client, _m(acc, 'loss_rel_to_own_supply')),
supplyInProfitRelToOwnSupply: createMetricPattern1(client, _m(acc, 'profit_rel_to_own_supply')),
};
}
/**
* @typedef {Object} CostBasisPattern
* @property {MetricPattern1<Dollars>} max
@@ -2785,6 +2766,25 @@ function createCostBasisPattern(client, acc) {
};
}
/**
* @typedef {Object} RelativePattern4
* @property {MetricPattern1<StoredF64>} supplyInLossRelToOwnSupply
* @property {MetricPattern1<StoredF64>} supplyInProfitRelToOwnSupply
*/
/**
* Create a RelativePattern4 pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {RelativePattern4}
*/
function createRelativePattern4(client, acc) {
return {
supplyInLossRelToOwnSupply: createMetricPattern1(client, _m(acc, 'loss_rel_to_own_supply')),
supplyInProfitRelToOwnSupply: createMetricPattern1(client, _m(acc, 'profit_rel_to_own_supply')),
};
}
/**
* @typedef {Object} SupplyPattern2
* @property {ActiveSupplyPattern} halved
@@ -2804,27 +2804,6 @@ function createSupplyPattern2(client, acc) {
};
}
/**
* @template T
* @typedef {Object} BlockCountPattern
* @property {MetricPattern1<T>} cumulative
* @property {MetricPattern1<T>} sum
*/
/**
* Create a BlockCountPattern pattern node
* @template T
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {BlockCountPattern<T>}
*/
function createBlockCountPattern(client, acc) {
return {
cumulative: createMetricPattern1(client, _m(acc, 'cumulative')),
sum: createMetricPattern1(client, acc),
};
}
/**
* @template T
* @typedef {Object} BitcoinPattern2
@@ -2862,25 +2841,29 @@ function createBitcoinPattern2(client, acc) {
*/
function createSatsPattern(client, acc) {
return {
ohlc: createMetricPattern1(client, _m(acc, 'ohlc')),
split: createSplitPattern2(client, acc),
ohlc: createMetricPattern1(client, _m(acc, 'ohlc_sats')),
split: createSplitPattern2(client, _m(acc, 'sats')),
};
}
/**
* @typedef {Object} RealizedPriceExtraPattern
* @property {MetricPattern4<StoredF32>} ratio
* @template T
* @typedef {Object} BlockCountPattern
* @property {MetricPattern1<T>} cumulative
* @property {MetricPattern1<T>} sum
*/
/**
* Create a RealizedPriceExtraPattern pattern node
* Create a BlockCountPattern pattern node
* @template T
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {RealizedPriceExtraPattern}
* @returns {BlockCountPattern<T>}
*/
function createRealizedPriceExtraPattern(client, acc) {
function createBlockCountPattern(client, acc) {
return {
ratio: createMetricPattern4(client, acc),
cumulative: createMetricPattern1(client, _m(acc, 'cumulative')),
sum: createMetricPattern1(client, acc),
};
}
@@ -2901,6 +2884,23 @@ function createOutputsPattern(client, acc) {
};
}
/**
* @typedef {Object} RealizedPriceExtraPattern
* @property {MetricPattern4<StoredF32>} ratio
*/
/**
* Create a RealizedPriceExtraPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {RealizedPriceExtraPattern}
*/
function createRealizedPriceExtraPattern(client, acc) {
return {
ratio: createMetricPattern4(client, acc),
};
}
// Catalog tree typedefs
/**
@@ -4056,8 +4056,8 @@ function createOutputsPattern(client, acc) {
* @typedef {Object} MetricsTree_Price
* @property {MetricsTree_Price_Cents} cents
* @property {MetricsTree_Price_Oracle} oracle
* @property {MetricsTree_Price_Sats} sats
* @property {SatsPattern<OHLCDollars>} usd
* @property {SatsPattern<OHLCSats>} sats
* @property {MetricsTree_Price_Usd} usd
*/
/**
@@ -4105,9 +4105,9 @@ function createOutputsPattern(client, acc) {
*/
/**
* @typedef {Object} MetricsTree_Price_Sats
* @property {MetricPattern1<OHLCSats>} ohlc
* @property {SplitPattern2<Sats>} split
* @typedef {Object} MetricsTree_Price_Usd
* @property {MetricPattern1<OHLCDollars>} ohlc
* @property {SplitPattern2<Dollars>} split
*/
/**
@@ -6087,11 +6087,11 @@ class BrkClient extends BrkClientBase {
priceCents: createMetricPattern11(this, 'oracle_price_cents'),
txCount: createMetricPattern6(this, 'oracle_tx_count'),
},
sats: {
ohlc: createMetricPattern1(this, 'price_ohlc_sats'),
split: createSplitPattern2(this, 'price_sats'),
sats: createSatsPattern(this, 'price'),
usd: {
ohlc: createMetricPattern1(this, 'price_ohlc'),
split: createSplitPattern2(this, 'price'),
},
usd: createSatsPattern(this, 'price'),
},
scripts: {
count: {

View File

@@ -18,6 +18,7 @@ uv add brk-client
from brk_client import BrkClient
# Use the free public API or your own instance
# Has optional `, timeout=60.0` argument
client = BrkClient("https://bitview.space")
# Blockchain data (mempool.space compatible)
@@ -34,18 +35,3 @@ prices = client.metrics.price.usd.split.close \
# Generic metric fetching
data = client.get_metric("price_close", "dateindex", -30)
```
## API
```python
# Range methods
.head(n) # First n items
.tail(n) # Last n items
.fetch() # Execute the request
```
## Configuration
```python
client = BrkClient("https://bitview.space", timeout=60.0)
```

View File

@@ -2049,23 +2049,6 @@ class BitcoinPattern:
self.pct90: MetricPattern6[Bitcoin] = MetricPattern6(client, _m(acc, 'pct90'))
self.sum: MetricPattern2[Bitcoin] = MetricPattern2(client, _m(acc, 'sum'))
class ClassAveragePricePattern(Generic[T]):
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self._2015: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2015_returns'))
self._2016: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2016_returns'))
self._2017: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2017_returns'))
self._2018: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2018_returns'))
self._2019: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2019_returns'))
self._2020: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2020_returns'))
self._2021: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2021_returns'))
self._2022: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2022_returns'))
self._2023: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2023_returns'))
self._2024: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2024_returns'))
self._2025: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2025_returns'))
class DollarsPattern(Generic[T]):
"""Pattern struct for repeated tree structure."""
@@ -2083,21 +2066,22 @@ class DollarsPattern(Generic[T]):
self.pct90: MetricPattern6[T] = MetricPattern6(client, _m(acc, 'pct90'))
self.sum: MetricPattern2[T] = MetricPattern2(client, _m(acc, 'sum'))
class RelativePattern2:
class ClassAveragePricePattern(Generic[T]):
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.neg_unrealized_loss_rel_to_own_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'neg_unrealized_loss_rel_to_own_market_cap'))
self.neg_unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'neg_unrealized_loss_rel_to_own_total_unrealized_pnl'))
self.net_unrealized_pnl_rel_to_own_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'net_unrealized_pnl_rel_to_own_market_cap'))
self.net_unrealized_pnl_rel_to_own_total_unrealized_pnl: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'net_unrealized_pnl_rel_to_own_total_unrealized_pnl'))
self.supply_in_loss_rel_to_own_supply: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'supply_in_loss_rel_to_own_supply'))
self.supply_in_profit_rel_to_own_supply: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'supply_in_profit_rel_to_own_supply'))
self.unrealized_loss_rel_to_own_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_own_market_cap'))
self.unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_own_total_unrealized_pnl'))
self.unrealized_profit_rel_to_own_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_own_market_cap'))
self.unrealized_profit_rel_to_own_total_unrealized_pnl: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_own_total_unrealized_pnl'))
self._2015: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2015_returns'))
self._2016: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2016_returns'))
self._2017: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2017_returns'))
self._2018: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2018_returns'))
self._2019: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2019_returns'))
self._2020: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2020_returns'))
self._2021: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2021_returns'))
self._2022: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2022_returns'))
self._2023: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2023_returns'))
self._2024: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2024_returns'))
self._2025: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2025_returns'))
class RelativePattern:
"""Pattern struct for repeated tree structure."""
@@ -2115,6 +2099,22 @@ class RelativePattern:
self.unrealized_loss_rel_to_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_market_cap'))
self.unrealized_profit_rel_to_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_market_cap'))
class RelativePattern2:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.neg_unrealized_loss_rel_to_own_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'neg_unrealized_loss_rel_to_own_market_cap'))
self.neg_unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'neg_unrealized_loss_rel_to_own_total_unrealized_pnl'))
self.net_unrealized_pnl_rel_to_own_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'net_unrealized_pnl_rel_to_own_market_cap'))
self.net_unrealized_pnl_rel_to_own_total_unrealized_pnl: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'net_unrealized_pnl_rel_to_own_total_unrealized_pnl'))
self.supply_in_loss_rel_to_own_supply: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'supply_in_loss_rel_to_own_supply'))
self.supply_in_profit_rel_to_own_supply: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'supply_in_profit_rel_to_own_supply'))
self.unrealized_loss_rel_to_own_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_own_market_cap'))
self.unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_own_total_unrealized_pnl'))
self.unrealized_profit_rel_to_own_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_own_market_cap'))
self.unrealized_profit_rel_to_own_total_unrealized_pnl: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_own_total_unrealized_pnl'))
class CountPattern2(Generic[T]):
"""Pattern struct for repeated tree structure."""
@@ -2204,19 +2204,6 @@ class PhaseDailyCentsPattern(Generic[T]):
self.pct75: MetricPattern6[T] = MetricPattern6(client, _m(acc, 'pct75'))
self.pct90: MetricPattern6[T] = MetricPattern6(client, _m(acc, 'pct90'))
class _10yPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.activity: ActivityPattern2 = ActivityPattern2(client, acc)
self.cost_basis: CostBasisPattern = CostBasisPattern(client, acc)
self.outputs: OutputsPattern = OutputsPattern(client, _m(acc, 'utxo_count'))
self.realized: RealizedPattern4 = RealizedPattern4(client, acc)
self.relative: RelativePattern = RelativePattern(client, acc)
self.supply: SupplyPattern2 = SupplyPattern2(client, _m(acc, 'supply'))
self.unrealized: UnrealizedPattern = UnrealizedPattern(client, acc)
class PeriodCagrPattern:
"""Pattern struct for repeated tree structure."""
@@ -2230,6 +2217,32 @@ class PeriodCagrPattern:
self._6y: MetricPattern4[StoredF32] = MetricPattern4(client, _p('6y', acc))
self._8y: MetricPattern4[StoredF32] = MetricPattern4(client, _p('8y', acc))
class _0satsPattern2:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.activity: ActivityPattern2 = ActivityPattern2(client, acc)
self.cost_basis: CostBasisPattern = CostBasisPattern(client, acc)
self.outputs: OutputsPattern = OutputsPattern(client, _m(acc, 'utxo_count'))
self.realized: RealizedPattern = RealizedPattern(client, acc)
self.relative: RelativePattern4 = RelativePattern4(client, _m(acc, 'supply_in'))
self.supply: SupplyPattern2 = SupplyPattern2(client, _m(acc, 'supply'))
self.unrealized: UnrealizedPattern = UnrealizedPattern(client, acc)
class _10yPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.activity: ActivityPattern2 = ActivityPattern2(client, acc)
self.cost_basis: CostBasisPattern = CostBasisPattern(client, acc)
self.outputs: OutputsPattern = OutputsPattern(client, _m(acc, 'utxo_count'))
self.realized: RealizedPattern4 = RealizedPattern4(client, acc)
self.relative: RelativePattern = RelativePattern(client, acc)
self.supply: SupplyPattern2 = SupplyPattern2(client, _m(acc, 'supply'))
self.unrealized: UnrealizedPattern = UnrealizedPattern(client, acc)
class _10yTo12yPattern:
"""Pattern struct for repeated tree structure."""
@@ -2243,7 +2256,7 @@ class _10yTo12yPattern:
self.supply: SupplyPattern2 = SupplyPattern2(client, _m(acc, 'supply'))
self.unrealized: UnrealizedPattern = UnrealizedPattern(client, acc)
class _0satsPattern2:
class _100btcPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
@@ -2252,7 +2265,7 @@ class _0satsPattern2:
self.cost_basis: CostBasisPattern = CostBasisPattern(client, acc)
self.outputs: OutputsPattern = OutputsPattern(client, _m(acc, 'utxo_count'))
self.realized: RealizedPattern = RealizedPattern(client, acc)
self.relative: RelativePattern4 = RelativePattern4(client, _m(acc, 'supply_in'))
self.relative: RelativePattern = RelativePattern(client, acc)
self.supply: SupplyPattern2 = SupplyPattern2(client, _m(acc, 'supply'))
self.unrealized: UnrealizedPattern = UnrealizedPattern(client, acc)
@@ -2269,19 +2282,6 @@ class UnrealizedPattern:
self.unrealized_loss: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'unrealized_loss'))
self.unrealized_profit: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'unrealized_profit'))
class _100btcPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.activity: ActivityPattern2 = ActivityPattern2(client, acc)
self.cost_basis: CostBasisPattern = CostBasisPattern(client, acc)
self.outputs: OutputsPattern = OutputsPattern(client, _m(acc, 'utxo_count'))
self.realized: RealizedPattern = RealizedPattern(client, acc)
self.relative: RelativePattern = RelativePattern(client, acc)
self.supply: SupplyPattern2 = SupplyPattern2(client, _m(acc, 'supply'))
self.unrealized: UnrealizedPattern = UnrealizedPattern(client, acc)
class ActivityPattern2:
"""Pattern struct for repeated tree structure."""
@@ -2303,33 +2303,6 @@ class SplitPattern2(Generic[T]):
self.low: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'low'))
self.open: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'open'))
class SegwitAdoptionPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.base: MetricPattern11[StoredF32] = MetricPattern11(client, acc)
self.cumulative: MetricPattern2[StoredF32] = MetricPattern2(client, _m(acc, 'cumulative'))
self.sum: MetricPattern2[StoredF32] = MetricPattern2(client, _m(acc, 'sum'))
class ActiveSupplyPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.bitcoin: MetricPattern1[Bitcoin] = MetricPattern1(client, _m(acc, 'btc'))
self.dollars: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'usd'))
self.sats: MetricPattern1[Sats] = MetricPattern1(client, acc)
class _2015Pattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.bitcoin: MetricPattern4[Bitcoin] = MetricPattern4(client, _m(acc, 'btc'))
self.dollars: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'usd'))
self.sats: MetricPattern4[Sats] = MetricPattern4(client, acc)
class CostBasisPattern2:
"""Pattern struct for repeated tree structure."""
@@ -2339,15 +2312,6 @@ class CostBasisPattern2:
self.min: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'min_cost_basis'))
self.percentiles: PercentilesPattern = PercentilesPattern(client, _m(acc, 'cost_basis'))
class CoinbasePattern2:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.bitcoin: BlockCountPattern[Bitcoin] = BlockCountPattern(client, _m(acc, 'btc'))
self.dollars: BlockCountPattern[Dollars] = BlockCountPattern(client, _m(acc, 'usd'))
self.sats: BlockCountPattern[Sats] = BlockCountPattern(client, acc)
class CoinbasePattern:
"""Pattern struct for repeated tree structure."""
@@ -2357,6 +2321,15 @@ class CoinbasePattern:
self.dollars: DollarsPattern[Dollars] = DollarsPattern(client, _m(acc, 'usd'))
self.sats: DollarsPattern[Sats] = DollarsPattern(client, acc)
class ActiveSupplyPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.bitcoin: MetricPattern1[Bitcoin] = MetricPattern1(client, _m(acc, 'btc'))
self.dollars: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'usd'))
self.sats: MetricPattern1[Sats] = MetricPattern1(client, acc)
class UnclaimedRewardsPattern:
"""Pattern struct for repeated tree structure."""
@@ -2366,6 +2339,33 @@ class UnclaimedRewardsPattern:
self.dollars: BlockCountPattern[Dollars] = BlockCountPattern(client, _m(acc, 'usd'))
self.sats: BlockCountPattern[Sats] = BlockCountPattern(client, acc)
class CoinbasePattern2:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.bitcoin: BlockCountPattern[Bitcoin] = BlockCountPattern(client, _m(acc, 'btc'))
self.dollars: BlockCountPattern[Dollars] = BlockCountPattern(client, _m(acc, 'usd'))
self.sats: BlockCountPattern[Sats] = BlockCountPattern(client, acc)
class _2015Pattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.bitcoin: MetricPattern4[Bitcoin] = MetricPattern4(client, _m(acc, 'btc'))
self.dollars: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'usd'))
self.sats: MetricPattern4[Sats] = MetricPattern4(client, acc)
class SegwitAdoptionPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.base: MetricPattern11[StoredF32] = MetricPattern11(client, acc)
self.cumulative: MetricPattern2[StoredF32] = MetricPattern2(client, _m(acc, 'cumulative'))
self.sum: MetricPattern2[StoredF32] = MetricPattern2(client, _m(acc, 'sum'))
class _1dReturns1mSdPattern:
"""Pattern struct for repeated tree structure."""
@@ -2374,14 +2374,6 @@ class _1dReturns1mSdPattern:
self.sd: MetricPattern4[StoredF32] = MetricPattern4(client, _m(acc, 'sd'))
self.sma: MetricPattern4[StoredF32] = MetricPattern4(client, _m(acc, 'sma'))
class RelativePattern4:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.supply_in_loss_rel_to_own_supply: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'loss_rel_to_own_supply'))
self.supply_in_profit_rel_to_own_supply: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'profit_rel_to_own_supply'))
class CostBasisPattern:
"""Pattern struct for repeated tree structure."""
@@ -2390,6 +2382,14 @@ class CostBasisPattern:
self.max: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'max_cost_basis'))
self.min: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'min_cost_basis'))
class RelativePattern4:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.supply_in_loss_rel_to_own_supply: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'loss_rel_to_own_supply'))
self.supply_in_profit_rel_to_own_supply: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'profit_rel_to_own_supply'))
class SupplyPattern2:
"""Pattern struct for repeated tree structure."""
@@ -2398,14 +2398,6 @@ class SupplyPattern2:
self.halved: ActiveSupplyPattern = ActiveSupplyPattern(client, _m(acc, 'halved'))
self.total: ActiveSupplyPattern = ActiveSupplyPattern(client, acc)
class BlockCountPattern(Generic[T]):
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.cumulative: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'cumulative'))
self.sum: MetricPattern1[T] = MetricPattern1(client, acc)
class BitcoinPattern2(Generic[T]):
"""Pattern struct for repeated tree structure."""
@@ -2419,15 +2411,16 @@ class SatsPattern(Generic[T]):
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.ohlc: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'ohlc'))
self.split: SplitPattern2[T] = SplitPattern2(client, acc)
self.ohlc: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'ohlc_sats'))
self.split: SplitPattern2[T] = SplitPattern2(client, _m(acc, 'sats'))
class RealizedPriceExtraPattern:
class BlockCountPattern(Generic[T]):
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.ratio: MetricPattern4[StoredF32] = MetricPattern4(client, acc)
self.cumulative: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'cumulative'))
self.sum: MetricPattern1[T] = MetricPattern1(client, acc)
class OutputsPattern:
"""Pattern struct for repeated tree structure."""
@@ -2436,6 +2429,13 @@ class OutputsPattern:
"""Create pattern node with accumulated metric name."""
self.utxo_count: MetricPattern1[StoredU64] = MetricPattern1(client, acc)
class RealizedPriceExtraPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.ratio: MetricPattern4[StoredF32] = MetricPattern4(client, acc)
# Metrics tree classes
class MetricsTree_Addresses:
@@ -3702,12 +3702,12 @@ class MetricsTree_Price_Oracle:
self.price_cents: MetricPattern11[Cents] = MetricPattern11(client, 'oracle_price_cents')
self.tx_count: MetricPattern6[StoredU32] = MetricPattern6(client, 'oracle_tx_count')
class MetricsTree_Price_Sats:
class MetricsTree_Price_Usd:
"""Metrics tree node."""
def __init__(self, client: BrkClientBase, base_path: str = ''):
self.ohlc: MetricPattern1[OHLCSats] = MetricPattern1(client, 'price_ohlc_sats')
self.split: SplitPattern2[Sats] = SplitPattern2(client, 'price_sats')
self.ohlc: MetricPattern1[OHLCDollars] = MetricPattern1(client, 'price_ohlc')
self.split: SplitPattern2[Dollars] = SplitPattern2(client, 'price')
class MetricsTree_Price:
"""Metrics tree node."""
@@ -3715,8 +3715,8 @@ class MetricsTree_Price:
def __init__(self, client: BrkClientBase, base_path: str = ''):
self.cents: MetricsTree_Price_Cents = MetricsTree_Price_Cents(client)
self.oracle: MetricsTree_Price_Oracle = MetricsTree_Price_Oracle(client)
self.sats: MetricsTree_Price_Sats = MetricsTree_Price_Sats(client)
self.usd: SatsPattern[OHLCDollars] = SatsPattern(client, 'price')
self.sats: SatsPattern[OHLCSats] = SatsPattern(client, 'price')
self.usd: MetricsTree_Price_Usd = MetricsTree_Price_Usd(client)
class MetricsTree_Scripts_Count:
"""Metrics tree node."""

View File

@@ -2,17 +2,6 @@ const CACHE = "v1";
const ROOT = "/";
const API = "/api";
const BYPASS = new Set([
"/changelog",
"/crate",
"/discord",
"/github",
"/install",
"/nostr",
"/service",
"/status",
]);
// Match hashed filenames: name.abc12345.js/mjs/css
const HASHED_RE = /\.[0-9a-f]{8}\.(js|mjs|css)$/;
@@ -59,7 +48,7 @@ sw.addEventListener("fetch", (event) => {
const path = url.pathname;
// Bypass API and redirects
if (path.startsWith(API) || BYPASS.has(path)) return;
if (path.startsWith(API)) return;
// Navigation: network-first for shell
if (req.mode === "navigate") {