Compare commits

...

13 Commits

Author SHA1 Message Date
nym21 cde090685a release: v0.1.2 2026-01-29 12:30:45 +01:00
nym21 a9f1dad091 docs: update generated docs 2026-01-29 12:30:26 +01:00
nym21 54827cd0a2 log + help: improved 2026-01-29 11:54:38 +01:00
nym21 e01bb53b2e indexer: remove rollback test 2026-01-28 23:44:57 +01:00
nym21 9f2b808cdb deps: upgrade 2026-01-28 23:39:07 +01:00
nym21 6709ded66c global: reorg fixes + clients improved 2026-01-28 23:35:51 +01:00
nym21 fecaf0f400 bindgen: determinism 2026-01-27 23:48:19 +01:00
nym21 730e83472a ci: outdated 2026-01-27 17:52:40 +01:00
nym21 88145d08e5 release: v0.1.1 2026-01-27 01:45:01 +01:00
nym21 c367802b4a docs: update generated docs 2026-01-27 01:44:43 +01:00
nym21 3d36524707 scripts: split release 2026-01-27 01:42:24 +01:00
nym21 6cdc5879bb server: fix html caching rules 2026-01-27 01:39:09 +01:00
nym21 79d14cd260 docs: update generated docs 2026-01-27 01:18:15 +01:00
429 changed files with 11030 additions and 8225 deletions
-13
View File
@@ -1,18 +1,5 @@
[build]
rustflags = ["-C", "target-cpu=native"]
# pco (pcodec) decompression is significantly faster with these SIMD instructions
[target.x86_64-unknown-linux-gnu]
rustflags = ["-C", "target-cpu=native", "-C", "target-feature=+bmi1,+bmi2,+avx2"]
[target.x86_64-apple-darwin]
rustflags = ["-C", "target-cpu=native", "-C", "target-feature=+bmi1,+bmi2,+avx2"]
[target.x86_64-pc-windows-msvc]
rustflags = ["-C", "target-cpu=native", "-C", "target-feature=+bmi1,+bmi2,+avx2"]
[target.x86_64-pc-windows-gnu]
rustflags = ["-C", "target-cpu=native", "-C", "target-feature=+bmi1,+bmi2,+avx2"]
[alias]
dev = "run -p brk_cli --features brk_server/bindgen"
+15
View File
@@ -0,0 +1,15 @@
name: Check outdated dependencies
on:
schedule:
- cron: '0 9 * * *'
workflow_dispatch:
jobs:
outdated:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- run: cargo install cargo-outdated
- run: cargo outdated --exit-code 1 --depth 1
Generated
+36 -36
View File
@@ -334,7 +334,7 @@ dependencies = [
[[package]]
name = "brk"
version = "0.1.0"
version = "0.1.2"
dependencies = [
"brk_bencher",
"brk_bindgen",
@@ -358,7 +358,7 @@ dependencies = [
[[package]]
name = "brk_alloc"
version = "0.1.0"
version = "0.1.2"
dependencies = [
"libmimalloc-sys",
"mimalloc",
@@ -366,7 +366,7 @@ dependencies = [
[[package]]
name = "brk_bencher"
version = "0.1.0"
version = "0.1.2"
dependencies = [
"brk_error",
"brk_logger",
@@ -376,14 +376,14 @@ dependencies = [
[[package]]
name = "brk_bencher_visualizer"
version = "0.1.0"
version = "0.1.2"
dependencies = [
"plotters",
]
[[package]]
name = "brk_bindgen"
version = "0.1.0"
version = "0.1.2"
dependencies = [
"brk_cohort",
"brk_query",
@@ -395,7 +395,7 @@ dependencies = [
[[package]]
name = "brk_cli"
version = "0.1.0"
version = "0.1.2"
dependencies = [
"anyhow",
"brk_alloc",
@@ -422,7 +422,7 @@ dependencies = [
[[package]]
name = "brk_client"
version = "0.1.0"
version = "0.1.2"
dependencies = [
"brk_cohort",
"brk_types",
@@ -433,7 +433,7 @@ dependencies = [
[[package]]
name = "brk_cohort"
version = "0.1.0"
version = "0.1.2"
dependencies = [
"brk_error",
"brk_traversable",
@@ -445,7 +445,7 @@ dependencies = [
[[package]]
name = "brk_computer"
version = "0.1.0"
version = "0.1.2"
dependencies = [
"bitcoin",
"brk_alloc",
@@ -475,7 +475,7 @@ dependencies = [
[[package]]
name = "brk_error"
version = "0.1.0"
version = "0.1.2"
dependencies = [
"bitcoin",
"bitcoincore-rpc",
@@ -490,7 +490,7 @@ dependencies = [
[[package]]
name = "brk_fetcher"
version = "0.1.0"
version = "0.1.2"
dependencies = [
"brk_error",
"brk_logger",
@@ -502,7 +502,7 @@ dependencies = [
[[package]]
name = "brk_indexer"
version = "0.1.0"
version = "0.1.2"
dependencies = [
"bitcoin",
"brk_alloc",
@@ -527,7 +527,7 @@ dependencies = [
[[package]]
name = "brk_iterator"
version = "0.1.0"
version = "0.1.2"
dependencies = [
"brk_error",
"brk_reader",
@@ -537,7 +537,7 @@ dependencies = [
[[package]]
name = "brk_logger"
version = "0.1.0"
version = "0.1.2"
dependencies = [
"jiff",
"owo-colors",
@@ -548,7 +548,7 @@ dependencies = [
[[package]]
name = "brk_mempool"
version = "0.1.0"
version = "0.1.2"
dependencies = [
"brk_error",
"brk_logger",
@@ -563,7 +563,7 @@ dependencies = [
[[package]]
name = "brk_query"
version = "0.1.0"
version = "0.1.2"
dependencies = [
"bitcoin",
"brk_computer",
@@ -583,7 +583,7 @@ dependencies = [
[[package]]
name = "brk_reader"
version = "0.1.0"
version = "0.1.2"
dependencies = [
"bitcoin",
"brk_error",
@@ -598,7 +598,7 @@ dependencies = [
[[package]]
name = "brk_rpc"
version = "0.1.0"
version = "0.1.2"
dependencies = [
"bitcoin",
"bitcoincore-rpc",
@@ -611,7 +611,7 @@ dependencies = [
[[package]]
name = "brk_server"
version = "0.1.0"
version = "0.1.2"
dependencies = [
"aide",
"axum",
@@ -643,7 +643,7 @@ dependencies = [
[[package]]
name = "brk_store"
version = "0.1.0"
version = "0.1.2"
dependencies = [
"brk_error",
"brk_types",
@@ -654,7 +654,7 @@ dependencies = [
[[package]]
name = "brk_traversable"
version = "0.1.0"
version = "0.1.2"
dependencies = [
"brk_traversable_derive",
"brk_types",
@@ -666,7 +666,7 @@ dependencies = [
[[package]]
name = "brk_traversable_derive"
version = "0.1.0"
version = "0.1.2"
dependencies = [
"proc-macro2",
"quote",
@@ -675,7 +675,7 @@ dependencies = [
[[package]]
name = "brk_types"
version = "0.1.0"
version = "0.1.2"
dependencies = [
"bitcoin",
"brk_error",
@@ -695,7 +695,7 @@ dependencies = [
[[package]]
name = "brk_website"
version = "0.1.0"
version = "0.1.2"
dependencies = [
"axum",
"brk_logger",
@@ -1595,9 +1595,9 @@ dependencies = [
[[package]]
name = "iana-time-zone"
version = "0.1.64"
version = "0.1.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb"
checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
dependencies = [
"android_system_properties",
"core-foundation-sys",
@@ -2432,9 +2432,9 @@ dependencies = [
[[package]]
name = "rawdb"
version = "0.6.2"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9f53bd783ecee89e4b43e82634a355a28c74743e89596772287dbe06bb95942"
checksum = "4bf9c16af7a93d15280ceb0d502657f9ec524cce61c946a1c98390740270820d"
dependencies = [
"libc",
"log",
@@ -3252,9 +3252,9 @@ checksum = "8f54a172d0620933a27a4360d3db3e2ae0dd6cceae9730751a036bbf182c4b23"
[[package]]
name = "vecdb"
version = "0.6.2"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "867dfa2136db3ff905f3668eb0ed76daf8de14237338c1d498dbd7ce925bf90e"
checksum = "66b361b0614c0d367441dcbc7c28a885b7b088a8d379e23ad845d81324f2c5f6"
dependencies = [
"ctrlc",
"log",
@@ -3273,9 +3273,9 @@ dependencies = [
[[package]]
name = "vecdb_derive"
version = "0.6.2"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1819035219d794f6dd96feab3a700aa582e193ddd4ac730ef771c0d31ea03260"
checksum = "962dfcd7fc848c27f6ee051cf1a4dfd55d72a37d443fb525268eff41da9cacf8"
dependencies = [
"quote",
"syn",
@@ -3694,18 +3694,18 @@ dependencies = [
[[package]]
name = "zerocopy"
version = "0.8.34"
version = "0.8.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71ddd76bcebeed25db614f82bf31a9f4222d3fbba300e6fb6c00afa26cbd4d9d"
checksum = "fdea86ddd5568519879b8187e1cf04e24fce28f7fe046ceecbce472ff19a2572"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.34"
version = "0.8.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8187381b52e32220d50b255276aa16a084ec0a9017a0ca2152a1f55c539758d"
checksum = "0c15e1b46eff7c6c91195752e0eeed8ef040e391cdece7c25376957d5f15df22"
dependencies = [
"proc-macro2",
"quote",
+24 -24
View File
@@ -4,7 +4,7 @@ members = ["crates/*"]
package.description = "The Bitcoin Research Kit is a suite of tools designed to extract, compute and display data stored on a Bitcoin Core node"
package.license = "MIT"
package.edition = "2024"
package.version = "0.1.0"
package.version = "0.1.2"
package.homepage = "https://bitcoinresearchkit.org"
package.repository = "https://github.com/bitcoinresearchkit/brk"
package.readme = "README.md"
@@ -40,28 +40,28 @@ aide = { version = "0.16.0-alpha.2", features = ["axum-json", "axum-query"] }
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", path = "crates/brk_alloc" }
brk_bencher = { version = "0.1.0", path = "crates/brk_bencher" }
brk_bindgen = { version = "0.1.0", path = "crates/brk_bindgen" }
brk_cli = { version = "0.1.0", path = "crates/brk_cli" }
brk_client = { version = "0.1.0", path = "crates/brk_client" }
brk_cohort = { version = "0.1.0", path = "crates/brk_cohort" }
brk_computer = { version = "0.1.0", path = "crates/brk_computer" }
brk_error = { version = "0.1.0", path = "crates/brk_error" }
brk_fetcher = { version = "0.1.0", path = "crates/brk_fetcher" }
brk_indexer = { version = "0.1.0", path = "crates/brk_indexer" }
brk_iterator = { version = "0.1.0", path = "crates/brk_iterator" }
brk_logger = { version = "0.1.0", path = "crates/brk_logger" }
brk_mempool = { version = "0.1.0", path = "crates/brk_mempool" }
brk_query = { version = "0.1.0", path = "crates/brk_query", features = ["tokio"] }
brk_reader = { version = "0.1.0", path = "crates/brk_reader" }
brk_rpc = { version = "0.1.0", path = "crates/brk_rpc" }
brk_server = { version = "0.1.0", path = "crates/brk_server" }
brk_store = { version = "0.1.0", path = "crates/brk_store" }
brk_traversable = { version = "0.1.0", path = "crates/brk_traversable", features = ["pco", "derive"] }
brk_traversable_derive = { version = "0.1.0", path = "crates/brk_traversable_derive" }
brk_types = { version = "0.1.0", path = "crates/brk_types" }
brk_website = { version = "0.1.0", path = "crates/brk_website" }
brk_alloc = { version = "0.1.2", path = "crates/brk_alloc" }
brk_bencher = { version = "0.1.2", path = "crates/brk_bencher" }
brk_bindgen = { version = "0.1.2", path = "crates/brk_bindgen" }
brk_cli = { version = "0.1.2", path = "crates/brk_cli" }
brk_client = { version = "0.1.2", path = "crates/brk_client" }
brk_cohort = { version = "0.1.2", path = "crates/brk_cohort" }
brk_computer = { version = "0.1.2", path = "crates/brk_computer" }
brk_error = { version = "0.1.2", path = "crates/brk_error" }
brk_fetcher = { version = "0.1.2", path = "crates/brk_fetcher" }
brk_indexer = { version = "0.1.2", path = "crates/brk_indexer" }
brk_iterator = { version = "0.1.2", path = "crates/brk_iterator" }
brk_logger = { version = "0.1.2", path = "crates/brk_logger" }
brk_mempool = { version = "0.1.2", path = "crates/brk_mempool" }
brk_query = { version = "0.1.2", path = "crates/brk_query", features = ["tokio"] }
brk_reader = { version = "0.1.2", path = "crates/brk_reader" }
brk_rpc = { version = "0.1.2", path = "crates/brk_rpc" }
brk_server = { version = "0.1.2", path = "crates/brk_server" }
brk_store = { version = "0.1.2", path = "crates/brk_store" }
brk_traversable = { version = "0.1.2", path = "crates/brk_traversable", features = ["pco", "derive"] }
brk_traversable_derive = { version = "0.1.2", path = "crates/brk_traversable_derive" }
brk_types = { version = "0.1.2", path = "crates/brk_types" }
brk_website = { version = "0.1.2", path = "crates/brk_website" }
byteview = "0.10.0"
color-eyre = "0.6.5"
derive_more = { version = "2.1.1", features = ["deref", "deref_mut"] }
@@ -82,7 +82,7 @@ tokio = { version = "1.49.0", features = ["rt-multi-thread"] }
tracing = { version = "0.1", default-features = false, features = ["std"] }
tower-http = { version = "0.6.8", features = ["catch-panic", "compression-br", "compression-gzip", "compression-zstd", "cors", "normalize-path", "timeout", "trace"] }
tower-layer = "0.3"
vecdb = { version = "0.6.2", features = ["derive", "serde_json", "pco", "schemars"] }
vecdb = { version = "0.6.3", features = ["derive", "serde_json", "pco", "schemars"] }
# vecdb = { path = "../anydb/crates/vecdb", features = ["derive", "serde_json", "pco", "schemars"] }
[workspace.metadata.release]
+34 -29
View File
@@ -3,7 +3,7 @@
//! This module detects repeating tree structures and analyzes them
//! using the bottom-up name deconstruction algorithm.
use std::collections::{BTreeSet, HashMap};
use std::collections::{BTreeMap, BTreeSet};
use brk_types::{TreeNode, extract_json_type};
@@ -13,25 +13,25 @@ use crate::{PatternBaseResult, PatternField, StructuralPattern, to_pascal_case};
/// Context for pattern detection, holding all intermediate state.
struct PatternContext {
/// Maps field signatures to pattern names
signature_to_pattern: HashMap<Vec<PatternField>, String>,
signature_to_pattern: BTreeMap<Vec<PatternField>, String>,
/// Counts how many times each signature appears
signature_counts: HashMap<Vec<PatternField>, usize>,
signature_counts: BTreeMap<Vec<PatternField>, usize>,
/// Maps normalized signatures to pattern names (for naming consistency)
normalized_to_name: HashMap<Vec<PatternField>, String>,
normalized_to_name: BTreeMap<Vec<PatternField>, String>,
/// Counts pattern name usage (for unique naming)
name_counts: HashMap<String, usize>,
name_counts: BTreeMap<String, usize>,
/// Maps signatures to their child field lists
signature_to_child_fields: HashMap<Vec<PatternField>, Vec<Vec<PatternField>>>,
signature_to_child_fields: BTreeMap<Vec<PatternField>, Vec<Vec<PatternField>>>,
}
impl PatternContext {
fn new() -> Self {
Self {
signature_to_pattern: HashMap::new(),
signature_counts: HashMap::new(),
normalized_to_name: HashMap::new(),
name_counts: HashMap::new(),
signature_to_child_fields: HashMap::new(),
signature_to_pattern: BTreeMap::new(),
signature_counts: BTreeMap::new(),
normalized_to_name: BTreeMap::new(),
name_counts: BTreeMap::new(),
signature_to_child_fields: BTreeMap::new(),
}
}
}
@@ -45,9 +45,9 @@ pub fn detect_structural_patterns(
tree: &TreeNode,
) -> (
Vec<StructuralPattern>,
HashMap<Vec<PatternField>, String>,
HashMap<Vec<PatternField>, String>,
HashMap<String, PatternBaseResult>,
BTreeMap<Vec<PatternField>, String>,
BTreeMap<Vec<PatternField>, String>,
BTreeMap<String, PatternBaseResult>,
) {
let mut ctx = PatternContext::new();
resolve_branch_patterns(tree, "root", &mut ctx);
@@ -90,7 +90,7 @@ pub fn detect_structural_patterns(
patterns.extend(generic_patterns);
// Build pattern lookup for mode analysis (patterns appearing 2+ times)
let mut pattern_lookup: HashMap<Vec<PatternField>, String> = HashMap::new();
let mut pattern_lookup: BTreeMap<Vec<PatternField>, String> = BTreeMap::new();
for (sig, name) in &ctx.signature_to_pattern {
if ctx.signature_counts.get(sig).copied().unwrap_or(0) >= 2 {
pattern_lookup.insert(sig.clone(), name.clone());
@@ -110,29 +110,30 @@ pub fn detect_structural_patterns(
/// Detect generic patterns by grouping signatures by their normalized form.
fn detect_generic_patterns(
signature_to_pattern: &HashMap<Vec<PatternField>, String>,
signature_to_pattern: &BTreeMap<Vec<PatternField>, String>,
) -> (
Vec<StructuralPattern>,
HashMap<Vec<PatternField>, String>,
HashMap<Vec<PatternField>, String>,
BTreeMap<Vec<PatternField>, String>,
BTreeMap<Vec<PatternField>, String>,
) {
let mut normalized_groups: HashMap<
let mut normalized_groups: BTreeMap<
Vec<PatternField>,
Vec<(Vec<PatternField>, String, String)>,
> = HashMap::new();
> = BTreeMap::new();
for (fields, name) in signature_to_pattern {
if let Some((normalized, extracted_type)) = normalize_fields_for_generic(fields) {
normalized_groups
.entry(normalized)
.or_default()
.push((fields.clone(), name.clone(), extracted_type));
normalized_groups.entry(normalized).or_default().push((
fields.clone(),
name.clone(),
extracted_type,
));
}
}
let mut patterns = Vec::new();
let mut pattern_mappings: HashMap<Vec<PatternField>, String> = HashMap::new();
let mut type_mappings: HashMap<Vec<PatternField>, String> = HashMap::new();
let mut pattern_mappings: BTreeMap<Vec<PatternField>, String> = BTreeMap::new();
let mut type_mappings: BTreeMap<Vec<PatternField>, String> = BTreeMap::new();
for (normalized_fields, group) in normalized_groups {
if group.len() >= 2 {
@@ -205,7 +206,10 @@ fn normalize_fields_for_generic(fields: &[PatternField]) -> Option<(Vec<PatternF
// Only proceed if inner types differ from originals (meaning they had wrappers)
// and all inner types are the same
if inner_types.iter().all(|t| t == first_inner)
&& inner_types.iter().zip(leaf_types.iter()).any(|(inner, orig)| inner != *orig)
&& inner_types
.iter()
.zip(leaf_types.iter())
.any(|(inner, orig)| inner != *orig)
{
let normalized = fields
.iter()
@@ -301,7 +305,8 @@ fn resolve_branch_patterns(
.entry(normalized)
.or_insert_with(|| generate_pattern_name(field_name, &mut ctx.name_counts))
.clone();
ctx.signature_to_pattern.insert(fields.clone(), name.clone());
ctx.signature_to_pattern
.insert(fields.clone(), name.clone());
name
};
@@ -329,7 +334,7 @@ fn normalize_fields_for_naming(fields: &[PatternField]) -> Vec<PatternField> {
}
/// Generate a unique pattern name.
fn generate_pattern_name(field_name: &str, name_counts: &mut HashMap<String, usize>) -> String {
fn generate_pattern_name(field_name: &str, name_counts: &mut BTreeMap<String, usize>) -> String {
let pascal = to_pascal_case(field_name);
let sanitized = if pascal.chars().next().is_some_and(|c| c.is_ascii_digit()) {
format!("_{}", pascal)
+19 -19
View File
@@ -4,7 +4,7 @@
//! suffix mode (fields append to acc) or prefix mode (fields prepend to acc),
//! and extracts the field parts (relatives or prefixes) for code generation.
use std::collections::HashMap;
use std::collections::BTreeMap;
use brk_types::TreeNode;
@@ -18,7 +18,7 @@ struct InstanceAnalysis {
base: String,
/// For suffix mode: field -> relative name
/// For prefix mode: field -> prefix
field_parts: HashMap<String, String>,
field_parts: BTreeMap<String, String>,
/// Whether this instance appears to be suffix mode
is_suffix_mode: bool,
}
@@ -34,12 +34,12 @@ struct InstanceAnalysis {
pub fn analyze_pattern_modes(
tree: &TreeNode,
patterns: &mut [StructuralPattern],
pattern_lookup: &HashMap<Vec<PatternField>, String>,
) -> HashMap<String, PatternBaseResult> {
pattern_lookup: &BTreeMap<Vec<PatternField>, String>,
) -> BTreeMap<String, PatternBaseResult> {
// Collect analyses from all instances, keyed by pattern name
let mut all_analyses: HashMap<String, Vec<InstanceAnalysis>> = HashMap::new();
let mut all_analyses: BTreeMap<String, Vec<InstanceAnalysis>> = BTreeMap::new();
// Also collect base results for each node, keyed by tree path
let mut node_bases: HashMap<String, PatternBaseResult> = HashMap::new();
let mut node_bases: BTreeMap<String, PatternBaseResult> = BTreeMap::new();
// Bottom-up traversal
collect_instance_analyses(tree, "", pattern_lookup, &mut all_analyses, &mut node_bases);
@@ -61,9 +61,9 @@ pub fn analyze_pattern_modes(
fn collect_instance_analyses(
node: &TreeNode,
path: &str,
pattern_lookup: &HashMap<Vec<PatternField>, String>,
all_analyses: &mut HashMap<String, Vec<InstanceAnalysis>>,
node_bases: &mut HashMap<String, PatternBaseResult>,
pattern_lookup: &BTreeMap<Vec<PatternField>, String>,
all_analyses: &mut BTreeMap<String, Vec<InstanceAnalysis>>,
node_bases: &mut BTreeMap<String, PatternBaseResult>,
) -> Option<String> {
match node {
TreeNode::Leaf(leaf) => {
@@ -72,7 +72,7 @@ fn collect_instance_analyses(
}
TreeNode::Branch(children) => {
// First, process all children recursively (bottom-up)
let mut child_bases: HashMap<String, String> = HashMap::new();
let mut child_bases: BTreeMap<String, String> = BTreeMap::new();
for (field_name, child_node) in children {
let child_path = build_child_path(path, field_name);
if let Some(base) = collect_instance_analyses(
@@ -122,13 +122,13 @@ fn collect_instance_analyses(
}
/// Analyze a single pattern instance from its child bases.
fn analyze_instance(child_bases: &HashMap<String, String>) -> InstanceAnalysis {
fn analyze_instance(child_bases: &BTreeMap<String, String>) -> InstanceAnalysis {
let bases: Vec<&str> = child_bases.values().map(|s| s.as_str()).collect();
// Try suffix mode first: look for common prefix among children
if let Some(common_prefix) = find_common_prefix(&bases) {
let base = common_prefix.trim_end_matches('_').to_string();
let mut field_parts = HashMap::new();
let mut field_parts = BTreeMap::new();
for (field_name, child_base) in child_bases {
// Relative = child_base with common prefix stripped
@@ -154,7 +154,7 @@ fn analyze_instance(child_bases: &HashMap<String, String>) -> InstanceAnalysis {
// Try prefix mode: look for common suffix among children
if let Some(common_suffix) = find_common_suffix(&bases) {
let base = common_suffix.trim_start_matches('_').to_string();
let mut field_parts = HashMap::new();
let mut field_parts = BTreeMap::new();
for (field_name, child_base) in child_bases {
// Prefix = child_base with common suffix stripped, normalized to end with _
@@ -214,8 +214,8 @@ fn determine_pattern_mode(
}
// Find the most common field_parts within the majority group
// Convert to sorted Vec for comparison since HashMap isn't hashable
let mut parts_counts: HashMap<Vec<(String, String)>, usize> = HashMap::new();
// Convert to sorted Vec for comparison since BTreeMap isn't hashable
let mut parts_counts: BTreeMap<Vec<(String, String)>, usize> = BTreeMap::new();
for analysis in &majority_instances {
let mut sorted: Vec<_> = analysis
.field_parts
@@ -227,7 +227,7 @@ fn determine_pattern_mode(
}
let (best_parts_vec, _count) = parts_counts.into_iter().max_by_key(|(_, count)| *count)?;
let best_parts: HashMap<String, String> = best_parts_vec.into_iter().collect();
let best_parts: BTreeMap<String, String> = best_parts_vec.into_iter().collect();
// Verify all required fields have parts
for field in fields {
@@ -255,7 +255,7 @@ mod tests {
#[test]
fn test_analyze_instance_suffix_mode() {
let mut child_bases = HashMap::new();
let mut child_bases = BTreeMap::new();
child_bases.insert("max".to_string(), "lth_cost_basis_max".to_string());
child_bases.insert("min".to_string(), "lth_cost_basis_min".to_string());
child_bases.insert("percentiles".to_string(), "lth_cost_basis".to_string());
@@ -276,7 +276,7 @@ mod tests {
fn test_analyze_instance_prefix_mode() {
// Period-prefixed metrics like "1y_lump_sum_stack", "1m_lump_sum_stack"
// share a common suffix "_lump_sum_stack" with different period prefixes
let mut child_bases = HashMap::new();
let mut child_bases = BTreeMap::new();
child_bases.insert("_1y".to_string(), "1y_lump_sum_stack".to_string());
child_bases.insert("_1m".to_string(), "1m_lump_sum_stack".to_string());
child_bases.insert("_1w".to_string(), "1w_lump_sum_stack".to_string());
@@ -293,7 +293,7 @@ mod tests {
#[test]
fn test_analyze_instance_root_suffix() {
// At root level with suffix naming convention
let mut child_bases = HashMap::new();
let mut child_bases = BTreeMap::new();
child_bases.insert("max".to_string(), "cost_basis_max".to_string());
child_bases.insert("min".to_string(), "cost_basis_min".to_string());
child_bases.insert("percentiles".to_string(), "cost_basis".to_string());
+9 -9
View File
@@ -3,7 +3,7 @@
//! This module provides utilities for working with the TreeNode structure,
//! including leaf name extraction and index pattern detection.
use std::collections::{BTreeMap, BTreeSet, HashMap};
use std::collections::{BTreeMap, BTreeSet};
use brk_types::{Index, TreeNode, extract_json_type};
@@ -28,7 +28,7 @@ fn get_shortest_leaf_name(node: &TreeNode) -> Option<String> {
/// Get the field signature for a branch node's children.
pub fn get_node_fields(
children: &BTreeMap<String, TreeNode>,
pattern_lookup: &HashMap<Vec<PatternField>, String>,
pattern_lookup: &BTreeMap<Vec<PatternField>, String>,
) -> Vec<PatternField> {
let mut fields: Vec<PatternField> = children
.iter()
@@ -117,7 +117,7 @@ pub struct PatternBaseResult {
pub is_suffix_mode: bool,
/// The field parts (suffix in suffix mode, prefix in prefix mode) for each field.
/// Used to check if instance field parts match the pattern's field parts.
pub field_parts: HashMap<String, String>,
pub field_parts: BTreeMap<String, String>,
}
impl PatternBaseResult {
@@ -128,7 +128,7 @@ impl PatternBaseResult {
base: String::new(),
has_outlier: true,
is_suffix_mode: true,
field_parts: HashMap::new(),
field_parts: BTreeMap::new(),
}
}
@@ -139,7 +139,7 @@ impl PatternBaseResult {
base: String::new(),
has_outlier: false,
is_suffix_mode: true,
field_parts: HashMap::new(),
field_parts: BTreeMap::new(),
}
}
}
@@ -200,7 +200,7 @@ struct FindBaseResult {
base: String,
has_outlier: bool,
is_suffix_mode: bool,
field_parts: HashMap<String, String>,
field_parts: BTreeMap<String, String>,
}
/// Try to find a common base from child names using prefix/suffix detection.
@@ -214,7 +214,7 @@ fn try_find_base(
// Try common prefix first (suffix mode)
if let Some(prefix) = find_common_prefix(&leaf_names) {
let base = prefix.trim_end_matches('_').to_string();
let mut field_parts = HashMap::new();
let mut field_parts = BTreeMap::new();
for (field_name, leaf_name) in child_names {
// Compute the suffix part for this field
let suffix = if leaf_name == &base {
@@ -238,7 +238,7 @@ fn try_find_base(
// Try common suffix (prefix mode)
if let Some(suffix) = find_common_suffix(&leaf_names) {
let base = suffix.trim_start_matches('_').to_string();
let mut field_parts = HashMap::new();
let mut field_parts = BTreeMap::new();
for (field_name, leaf_name) in child_names {
// Compute the prefix part for this field, normalized to end with _
let prefix_part = leaf_name
@@ -300,7 +300,7 @@ pub fn infer_accumulated_name(parent_acc: &str, field_name: &str, descendant_lea
pub fn get_fields_with_child_info(
children: &BTreeMap<String, TreeNode>,
parent_name: &str,
pattern_lookup: &HashMap<Vec<PatternField>, String>,
pattern_lookup: &BTreeMap<Vec<PatternField>, String>,
) -> Vec<(PatternField, Option<Vec<PatternField>>)> {
children
.iter()
+8 -6
View File
@@ -1,10 +1,12 @@
//! Shared tree generation helpers.
use std::collections::{HashMap, HashSet};
use std::collections::{BTreeMap, BTreeSet};
use brk_types::TreeNode;
use crate::{ClientMetadata, PatternBaseResult, PatternField, child_type_name, get_fields_with_child_info};
use crate::{
ClientMetadata, PatternBaseResult, PatternField, child_type_name, get_fields_with_child_info,
};
/// Build a child path by appending a child name to a parent path.
/// Uses "/" as separator. If parent is empty, returns just the child name.
@@ -53,9 +55,9 @@ pub fn prepare_tree_node<'a>(
node: &'a TreeNode,
name: &str,
path: &str,
pattern_lookup: &HashMap<Vec<PatternField>, String>,
pattern_lookup: &BTreeMap<Vec<PatternField>, String>,
metadata: &ClientMetadata,
generated: &mut HashSet<String>,
generated: &mut BTreeSet<String>,
) -> Option<TreeNodeContext<'a>> {
let TreeNode::Branch(branch_children) = node else {
return None;
@@ -127,8 +129,8 @@ pub fn prepare_tree_node<'a>(
// should_inline determines if we generate an inline struct type
// We inline if: it's a branch AND (doesn't match any pattern OR pattern incompatible OR has outlier)
let should_inline =
!is_leaf && (!matches_any_pattern || !pattern_compatible || base_result.has_outlier);
let should_inline = !is_leaf
&& (!matches_any_pattern || !pattern_compatible || base_result.has_outlier);
// Inline type name (only used when should_inline is true)
let inline_type_name = if should_inline {
@@ -48,15 +48,120 @@ class BrkError extends Error {{
}}
}}
// Date conversion constants and helpers
const _GENESIS = new Date(2009, 0, 3); // dateindex 0, weekindex 0
const _DAY_ONE = new Date(2009, 0, 9); // dateindex 1 (6 day gap after genesis)
const _MS_PER_DAY = 24 * 60 * 60 * 1000;
const _MS_PER_WEEK = 7 * _MS_PER_DAY;
const _DATE_INDEXES = new Set(['dateindex', 'weekindex', 'monthindex', 'yearindex', 'quarterindex', 'semesterindex', 'decadeindex']);
/** @param {{number}} months @returns {{globalThis.Date}} */
const _addMonths = (months) => new Date(2009, months, 1);
/**
* Convert an index value to a Date for date-based indexes.
* @param {{Index}} index - The index type
* @param {{number}} i - The index value
* @returns {{globalThis.Date}}
*/
function indexToDate(index, i) {{
switch (index) {{
case 'dateindex': return i === 0 ? _GENESIS : new Date(_DAY_ONE.getTime() + (i - 1) * _MS_PER_DAY);
case 'weekindex': return new Date(_GENESIS.getTime() + i * _MS_PER_WEEK);
case 'monthindex': return _addMonths(i);
case 'yearindex': return new Date(2009 + i, 0, 1);
case 'quarterindex': return _addMonths(i * 3);
case 'semesterindex': return _addMonths(i * 6);
case 'decadeindex': return new Date(2009 + i * 10, 0, 1);
default: throw new Error(`${{index}} is not a date-based index`);
}}
}}
/**
* Check if an index type is date-based.
* @param {{Index}} index
* @returns {{boolean}}
*/
function isDateIndex(index) {{
return _DATE_INDEXES.has(index);
}}
/**
* Wrap raw metric data with helper methods.
* @template T
* @param {{MetricData<T>}} raw - Raw JSON response
* @returns {{MetricData<T>}}
*/
function _wrapMetricData(raw) {{
const {{ index, start, end, data }} = raw;
return /** @type {{MetricData<T>}} */ ({{
...raw,
dates() {{
/** @type {{globalThis.Date[]}} */
const result = [];
for (let i = start; i < end; i++) result.push(indexToDate(index, i));
return result;
}},
indexes() {{
/** @type {{number[]}} */
const result = [];
for (let i = start; i < end; i++) result.push(i);
return result;
}},
toDateMap() {{
/** @type {{Map<globalThis.Date, T>}} */
const map = new Map();
for (let i = 0; i < data.length; i++) map.set(indexToDate(index, start + i), data[i]);
return map;
}},
toIndexMap() {{
/** @type {{Map<number, T>}} */
const map = new Map();
for (let i = 0; i < data.length; i++) map.set(start + i, data[i]);
return map;
}},
dateEntries() {{
/** @type {{Array<[globalThis.Date, T]>}} */
const result = [];
for (let i = 0; i < data.length; i++) result.push([indexToDate(index, start + i), data[i]]);
return result;
}},
indexEntries() {{
/** @type {{Array<[number, T]>}} */
const result = [];
for (let i = 0; i < data.length; i++) result.push([start + i, data[i]]);
return result;
}},
*iter() {{
for (let i = 0; i < data.length; i++) yield [start + i, data[i]];
}},
*iterDates() {{
for (let i = 0; i < data.length; i++) yield [indexToDate(index, start + i), data[i]];
}},
[Symbol.iterator]() {{
return this.iter();
}},
}});
}}
/**
* @template T
* @typedef {{Object}} MetricData
* @property {{number}} version - Version of the metric data
* @property {{Index}} index - The index type used for this query
* @property {{number}} total - Total number of data points
* @property {{number}} start - Start index (inclusive)
* @property {{number}} end - End index (exclusive)
* @property {{string}} stamp - ISO 8601 timestamp of when the response was generated
* @property {{T[]}} data - The metric data
* @property {{() => globalThis.Date[]}} dates - Convert index range to dates (date-based indexes only)
* @property {{() => number[]}} indexes - Get index range as array
* @property {{() => Map<globalThis.Date, T>}} toDateMap - Return data as Map keyed by date (date-based only)
* @property {{() => Map<number, T>}} toIndexMap - Return data as Map keyed by index
* @property {{() => Array<[globalThis.Date, T]>}} dateEntries - Return data as [date, value] pairs (date-based only)
* @property {{() => Array<[number, T]>}} indexEntries - Return data as [index, value] pairs
* @property {{() => IterableIterator<[number, T]>}} iter - Iterate over [index, value] pairs
* @property {{() => IterableIterator<[globalThis.Date, T]>}} iterDates - Iterate over [date, value] pairs (date-based only)
*/
/** @typedef {{MetricData<any>}} AnyMetricData */
@@ -150,18 +255,18 @@ function _endpoint(client, name, index) {{
* @returns {{RangeBuilder<T>}}
*/
const rangeBuilder = (start, end) => ({{
fetch(onUpdate) {{ return client.getJson(buildPath(start, end), onUpdate); }},
fetch(onUpdate) {{ return client._fetchMetricData(buildPath(start, end), onUpdate); }},
fetchCsv() {{ return client.getText(buildPath(start, end, 'csv')); }},
then(resolve, reject) {{ return this.fetch().then(resolve, reject); }},
}});
/**
* @param {{number}} index
* @param {{number}} idx
* @returns {{SingleItemBuilder<T>}}
*/
const singleItemBuilder = (index) => ({{
fetch(onUpdate) {{ return client.getJson(buildPath(index, index + 1), onUpdate); }},
fetchCsv() {{ return client.getText(buildPath(index, index + 1, 'csv')); }},
const singleItemBuilder = (idx) => ({{
fetch(onUpdate) {{ return client._fetchMetricData(buildPath(idx, idx + 1), onUpdate); }},
fetchCsv() {{ return client.getText(buildPath(idx, idx + 1, 'csv')); }},
then(resolve, reject) {{ return this.fetch().then(resolve, reject); }},
}});
@@ -171,19 +276,19 @@ function _endpoint(client, name, index) {{
*/
const skippedBuilder = (start) => ({{
take(n) {{ return rangeBuilder(start, start + n); }},
fetch(onUpdate) {{ return client.getJson(buildPath(start, undefined), onUpdate); }},
fetch(onUpdate) {{ return client._fetchMetricData(buildPath(start, undefined), onUpdate); }},
fetchCsv() {{ return client.getText(buildPath(start, undefined, 'csv')); }},
then(resolve, reject) {{ return this.fetch().then(resolve, reject); }},
}});
/** @type {{MetricEndpointBuilder<T>}} */
const endpoint = {{
get(index) {{ return singleItemBuilder(index); }},
get(idx) {{ return singleItemBuilder(idx); }},
slice(start, end) {{ return rangeBuilder(start, end); }},
first(n) {{ return rangeBuilder(undefined, n); }},
last(n) {{ return n === 0 ? rangeBuilder(undefined, 0) : rangeBuilder(-n, undefined); }},
skip(n) {{ return skippedBuilder(n); }},
fetch(onUpdate) {{ return client.getJson(buildPath(), onUpdate); }},
fetch(onUpdate) {{ return client._fetchMetricData(buildPath(), onUpdate); }},
fetchCsv() {{ return client.getText(buildPath(undefined, undefined, 'csv')); }},
then(resolve, reject) {{ return this.fetch().then(resolve, reject); }},
get path() {{ return p; }},
@@ -263,6 +368,19 @@ class BrkClientBase {{
const res = await this.get(path);
return res.text();
}}
/**
* Fetch metric data and wrap with helper methods (internal)
* @template T
* @param {{string}} path
* @param {{(value: MetricData<T>) => void}} [onUpdate]
* @returns {{Promise<MetricData<T>>}}
*/
async _fetchMetricData(path, onUpdate) {{
const wrappedOnUpdate = onUpdate ? (/** @type {{MetricData<T>}} */ raw) => onUpdate(_wrapMetricData(raw)) : undefined;
const raw = await this.getJson(path, wrappedOnUpdate);
return _wrapMetricData(raw);
}}
}}
/**
@@ -299,6 +417,31 @@ pub fn generate_static_constants(output: &mut String) {
for (name, value) in CohortConstants::all() {
write_static_const(output, name, &format_json(&camel_case_keys(value)));
}
// Helper methods
writeln!(
output,
r#" /**
* Convert an index value to a Date for date-based indexes.
* @param {{Index}} index - The index type
* @param {{number}} i - The index value
* @returns {{globalThis.Date}}
*/
indexToDate(index, i) {{
return indexToDate(index, i);
}}
/**
* Check if an index type is date-based.
* @param {{Index}} index
* @returns {{boolean}}
*/
isDateIndex(index) {{
return isDateIndex(index);
}}
"#
)
.unwrap();
}
fn indent_json_const(json: &str) -> String {
@@ -11,6 +11,7 @@ use std::{fmt::Write, fs, io, path::Path};
use serde_json::json;
use super::write_if_changed;
use crate::{ClientMetadata, Endpoint, TypeSchemas, VERSION};
/// Generate JavaScript + JSDoc client from metadata and OpenAPI endpoints.
@@ -34,7 +35,7 @@ pub fn generate_javascript_client(
tree::generate_tree_typedefs(&mut output, &metadata.catalog, metadata);
tree::generate_main_client(&mut output, &metadata.catalog, metadata, endpoints);
fs::write(output_path, output)?;
write_if_changed(output_path, &output)?;
// Update package.json version if it exists in the same directory
if let Some(parent) = output_path.parent() {
@@ -59,7 +60,7 @@ fn update_package_json_version(package_json_path: &Path) -> io::Result<()> {
let updated = serde_json::to_string_pretty(&package)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
fs::write(package_json_path, updated + "\n")?;
write_if_changed(package_json_path, &(updated + "\n"))?;
Ok(())
}
@@ -1,6 +1,6 @@
//! JavaScript tree structure generation.
use std::collections::HashSet;
use std::collections::BTreeSet;
use std::fmt::Write;
use brk_types::TreeNode;
@@ -18,7 +18,7 @@ pub fn generate_tree_typedefs(output: &mut String, catalog: &TreeNode, metadata:
writeln!(output, "// Catalog tree typedefs\n").unwrap();
let pattern_lookup = metadata.pattern_lookup();
let mut generated = HashSet::new();
let mut generated = BTreeSet::new();
generate_tree_typedef(
output,
"MetricsTree",
@@ -35,9 +35,9 @@ fn generate_tree_typedef(
name: &str,
path: &str,
node: &TreeNode,
pattern_lookup: &std::collections::HashMap<Vec<PatternField>, String>,
pattern_lookup: &std::collections::BTreeMap<Vec<PatternField>, String>,
metadata: &ClientMetadata,
generated: &mut HashSet<String>,
generated: &mut BTreeSet<String>,
) {
let Some(ctx) = prepare_tree_node(node, name, path, pattern_lookup, metadata, generated) else {
return;
@@ -124,7 +124,7 @@ pub fn generate_main_client(
writeln!(output, " */").unwrap();
writeln!(output, " _buildTree(basePath) {{").unwrap();
writeln!(output, " return {{").unwrap();
let mut generated = HashSet::new();
let mut generated = BTreeSet::new();
generate_tree_initializer(
output,
catalog,
@@ -178,9 +178,9 @@ fn generate_tree_initializer(
name: &str,
path: &str,
indent: usize,
pattern_lookup: &std::collections::HashMap<Vec<PatternField>, String>,
pattern_lookup: &std::collections::BTreeMap<Vec<PatternField>, String>,
metadata: &ClientMetadata,
generated: &mut HashSet<String>,
generated: &mut BTreeSet<String>,
) {
let indent_str = " ".repeat(indent);
+12 -1
View File
@@ -7,7 +7,7 @@
//! - `api.rs` - API method generation
//! - `mod.rs` - Entry point
use std::fmt::Write;
use std::{fmt::Write, fs, io, path::Path};
pub mod javascript;
pub mod python;
@@ -41,3 +41,14 @@ pub fn normalize_return_type(return_type: &str) -> String {
}
result
}
/// Write content to a file only if it differs from existing content.
/// Preserves mtime when unchanged, avoiding unnecessary cargo rebuilds.
pub fn write_if_changed(path: &Path, content: &str) -> io::Result<()> {
if let Ok(existing) = fs::read_to_string(path)
&& existing == content
{
return Ok(());
}
fs::write(path, content)
}
@@ -39,6 +39,16 @@ pub fn generate_main_client(output: &mut String, endpoints: &[Endpoint]) {
writeln!(output, " return MetricEndpointBuilder(self, metric, index)").unwrap();
writeln!(output).unwrap();
// Generate helper methods
writeln!(output, " def index_to_date(self, index: Index, i: int) -> date:").unwrap();
writeln!(output, " \"\"\"Convert an index value to a date for date-based indexes.\"\"\"").unwrap();
writeln!(output, " return index_to_date(index, i)").unwrap();
writeln!(output).unwrap();
writeln!(output, " def is_date_index(self, index: Index) -> bool:").unwrap();
writeln!(output, " \"\"\"Check if an index type is date-based.\"\"\"").unwrap();
writeln!(output, " return is_date_index(index)").unwrap();
writeln!(output).unwrap();
// Generate API methods
generate_api_methods(output, endpoints);
}
@@ -131,16 +131,114 @@ def _p(prefix: str, acc: str) -> str:
pub fn generate_endpoint_class(output: &mut String) {
writeln!(
output,
r#"@dataclass
r#"# Date conversion constants
_GENESIS = date(2009, 1, 3) # dateindex 0, weekindex 0
_DAY_ONE = date(2009, 1, 9) # dateindex 1 (6 day gap after genesis)
_DATE_INDEXES = frozenset(['dateindex', 'weekindex', 'monthindex', 'yearindex', 'quarterindex', 'semesterindex', 'decadeindex'])
def is_date_index(index: str) -> bool:
"""Check if an index type is date-based."""
return index in _DATE_INDEXES
def index_to_date(index: str, i: int) -> date:
"""Convert an index value to a date for date-based indexes."""
if index == 'dateindex':
return _GENESIS if i == 0 else _DAY_ONE + timedelta(days=i - 1)
elif index == 'weekindex':
return _GENESIS + timedelta(weeks=i)
elif index == 'monthindex':
return date(2009 + i // 12, i % 12 + 1, 1)
elif index == 'yearindex':
return date(2009 + i, 1, 1)
elif index == 'quarterindex':
m = i * 3
return date(2009 + m // 12, m % 12 + 1, 1)
elif index == 'semesterindex':
m = i * 6
return date(2009 + m // 12, m % 12 + 1, 1)
elif index == 'decadeindex':
return date(2009 + i * 10, 1, 1)
else:
raise ValueError(f"{{index}} is not a date-based index")
@dataclass
class MetricData(Generic[T]):
"""Metric data with range information."""
version: int
index: Index
total: int
start: int
end: int
stamp: str
data: List[T]
def dates(self) -> List[date]:
"""Convert index range to dates. Only works for date-based indexes."""
return [index_to_date(self.index, i) for i in range(self.start, self.end)]
def indexes(self) -> List[int]:
"""Get index range as list."""
return list(range(self.start, self.end))
def to_date_dict(self) -> dict[date, T]:
"""Return data as {{date: value}} dict. Only works for date-based indexes."""
return dict(zip(self.dates(), self.data))
def to_index_dict(self) -> dict[int, T]:
"""Return data as {{index: value}} dict."""
return dict(zip(range(self.start, self.end), self.data))
def date_items(self) -> List[Tuple[date, T]]:
"""Return data as [(date, value), ...] pairs. Only works for date-based indexes."""
return list(zip(self.dates(), self.data))
def index_items(self) -> List[Tuple[int, T]]:
"""Return data as [(index, value), ...] pairs."""
return list(zip(range(self.start, self.end), self.data))
def iter(self) -> Iterator[Tuple[int, T]]:
"""Iterate over (index, value) pairs."""
return iter(zip(range(self.start, self.end), self.data))
def iter_dates(self) -> Iterator[Tuple[date, T]]:
"""Iterate over (date, value) pairs. Date-based indexes only."""
return iter(zip(self.dates(), self.data))
def __iter__(self) -> Iterator[Tuple[int, T]]:
"""Default iteration over (index, value) pairs."""
return self.iter()
def to_polars(self, with_dates: bool = True) -> pl.DataFrame:
"""Convert to Polars DataFrame. Requires polars to be installed.
Returns a DataFrame with columns:
- 'date' (date) and 'value' (T) if with_dates=True and index is date-based
- 'index' (int) and 'value' (T) otherwise
"""
try:
import polars as pl # type: ignore[import-not-found]
except ImportError:
raise ImportError("polars is required: pip install polars")
if with_dates and self.index in _DATE_INDEXES:
return pl.DataFrame({{"date": self.dates(), "value": self.data}})
return pl.DataFrame({{"index": list(range(self.start, self.end)), "value": self.data}})
def to_pandas(self, with_dates: bool = True) -> pd.DataFrame:
"""Convert to Pandas DataFrame. Requires pandas to be installed.
Returns a DataFrame with columns:
- 'date' (date) and 'value' (T) if with_dates=True and index is date-based
- 'index' (int) and 'value' (T) otherwise
"""
try:
import pandas as pd # type: ignore[import-not-found]
except ImportError:
raise ImportError("pandas is required: pip install pandas")
if with_dates and self.index in _DATE_INDEXES:
return pd.DataFrame({{"date": self.dates(), "value": self.data}})
return pd.DataFrame({{"index": list(range(self.start, self.end)), "value": self.data}})
# Type alias for non-generic usage
AnyMetricData = MetricData[Any]
@@ -177,9 +275,8 @@ class _EndpointConfig:
p = self.path()
return f"{{p}}?{{query}}" if query else p
def get_json(self) -> MetricData:
data = self.client.get_json(self._build_path())
return MetricData(**data)
def get_metric(self) -> MetricData:
return MetricData(**self.client.get_json(self._build_path()))
def get_csv(self) -> str:
return self.client.get_text(self._build_path(format='csv'))
@@ -193,7 +290,7 @@ class RangeBuilder(Generic[T]):
def fetch(self) -> MetricData[T]:
"""Fetch the range as parsed JSON."""
return self._config.get_json()
return self._config.get_metric()
def fetch_csv(self) -> str:
"""Fetch the range as CSV string."""
@@ -208,7 +305,7 @@ class SingleItemBuilder(Generic[T]):
def fetch(self) -> MetricData[T]:
"""Fetch the single item."""
return self._config.get_json()
return self._config.get_metric()
def fetch_csv(self) -> str:
"""Fetch as CSV."""
@@ -231,7 +328,7 @@ class SkippedBuilder(Generic[T]):
def fetch(self) -> MetricData[T]:
"""Fetch from skipped position to end."""
return self._config.get_json()
return self._config.get_metric()
def fetch_csv(self) -> str:
"""Fetch as CSV."""
@@ -315,7 +412,7 @@ class MetricEndpointBuilder(Generic[T]):
def fetch(self) -> MetricData[T]:
"""Fetch all data as parsed JSON."""
return self._config.get_json()
return self._config.get_metric()
def fetch_csv(self) -> str:
"""Fetch all data as CSV string."""
@@ -7,8 +7,9 @@ pub mod client;
pub mod tree;
pub mod types;
use std::{fmt::Write, fs, io, path::Path};
use std::{fmt::Write, io, path::Path};
use super::write_if_changed;
use crate::{ClientMetadata, Endpoint, TypeSchemas};
/// Generate Python client from metadata and OpenAPI endpoints.
@@ -28,7 +29,7 @@ pub fn generate_python_client(
writeln!(output, "from dataclasses import dataclass").unwrap();
writeln!(
output,
"from typing import TypeVar, Generic, Any, Optional, List, Literal, TypedDict, Union, Protocol, overload"
"from typing import TypeVar, Generic, Any, Optional, List, Literal, TypedDict, Union, Protocol, overload, Iterator, Tuple, TYPE_CHECKING"
)
.unwrap();
writeln!(
@@ -37,7 +38,11 @@ pub fn generate_python_client(
)
.unwrap();
writeln!(output, "from urllib.parse import urlparse").unwrap();
writeln!(output, "from datetime import date, timedelta").unwrap();
writeln!(output, "import json\n").unwrap();
writeln!(output, "if TYPE_CHECKING:").unwrap();
writeln!(output, " import pandas as pd # type: ignore[import-not-found]").unwrap();
writeln!(output, " import polars as pl # type: ignore[import-not-found]\n").unwrap();
writeln!(output, "T = TypeVar('T')\n").unwrap();
types::generate_type_definitions(&mut output, schemas);
@@ -48,7 +53,7 @@ pub fn generate_python_client(
tree::generate_tree_classes(&mut output, &metadata.catalog, metadata);
api::generate_main_client(&mut output, endpoints);
fs::write(output_path, output)?;
write_if_changed(output_path, &output)?;
Ok(())
}
@@ -1,6 +1,6 @@
//! Python tree structure generation.
use std::collections::HashSet;
use std::collections::BTreeSet;
use std::fmt::Write;
use brk_types::TreeNode;
@@ -15,7 +15,7 @@ pub fn generate_tree_classes(output: &mut String, catalog: &TreeNode, metadata:
writeln!(output, "# Metrics tree classes\n").unwrap();
let pattern_lookup = metadata.pattern_lookup();
let mut generated = HashSet::new();
let mut generated = BTreeSet::new();
generate_tree_class(
output,
"MetricsTree",
@@ -33,9 +33,9 @@ fn generate_tree_class(
name: &str,
path: &str,
node: &TreeNode,
pattern_lookup: &std::collections::HashMap<Vec<PatternField>, String>,
pattern_lookup: &std::collections::BTreeMap<Vec<PatternField>, String>,
metadata: &ClientMetadata,
generated: &mut HashSet<String>,
generated: &mut BTreeSet<String>,
) {
let Some(ctx) = prepare_tree_node(node, name, path, pattern_lookup, metadata, generated) else {
return;
@@ -74,7 +74,9 @@ fn generate_tree_class(
if child.is_leaf {
if let TreeNode::Leaf(leaf) = child.node {
generate_leaf_field(output, &syntax, "client", child.name, leaf, metadata, " ");
generate_leaf_field(
output, &syntax, "client", child.name, leaf, metadata, " ",
);
}
} else if child.should_inline {
// Inline class
@@ -1,11 +1,14 @@
//! Python type definitions generation.
use std::collections::{HashMap, HashSet};
use std::collections::{BTreeMap, BTreeSet};
use std::fmt::Write;
use serde_json::Value;
use crate::{TypeSchemas, escape_python_keyword, generators::MANUAL_GENERIC_TYPES, get_union_variants, ref_to_type_name};
use crate::{
TypeSchemas, escape_python_keyword, generators::MANUAL_GENERIC_TYPES, get_union_variants,
ref_to_type_name,
};
/// Generate type definitions from schemas.
pub fn generate_type_definitions(output: &mut String, schemas: &TypeSchemas) {
@@ -32,7 +35,7 @@ pub fn generate_type_definitions(output: &mut String, schemas: &TypeSchemas) {
// Generate simple type aliases first
// Quote references to TypedDicts since they're defined after
let typed_dict_set: HashSet<_> = typed_dicts.iter().cloned().collect();
let typed_dict_set: BTreeSet<_> = typed_dicts.iter().cloned().collect();
for name in type_aliases {
let schema = &schemas[&name];
let type_desc = schema.get("description").and_then(|d| d.as_str());
@@ -49,7 +52,10 @@ pub fn generate_type_definitions(output: &mut String, schemas: &TypeSchemas) {
for name in typed_dicts {
let schema = &schemas[&name];
let type_desc = schema.get("description").and_then(|d| d.as_str());
let props = schema.get("properties").and_then(|p| p.as_object()).unwrap();
let props = schema
.get("properties")
.and_then(|p| p.as_object())
.unwrap();
writeln!(output, "class {}(TypedDict):", name).unwrap();
@@ -100,9 +106,9 @@ pub fn generate_type_definitions(output: &mut String, schemas: &TypeSchemas) {
/// Types that reference other types (via $ref) must be defined after their dependencies.
fn topological_sort_schemas(schemas: &TypeSchemas) -> Vec<String> {
// Build dependency graph
let mut deps: HashMap<String, HashSet<String>> = HashMap::new();
let mut deps: BTreeMap<String, BTreeSet<String>> = BTreeMap::new();
for (name, schema) in schemas {
let mut type_deps = HashSet::new();
let mut type_deps = BTreeSet::new();
collect_schema_refs(schema, &mut type_deps);
// Only keep deps that are in our schemas
type_deps.retain(|d| schemas.contains_key(d));
@@ -110,7 +116,7 @@ fn topological_sort_schemas(schemas: &TypeSchemas) -> Vec<String> {
}
// Kahn's algorithm for topological sort
let mut in_degree: HashMap<String, usize> = HashMap::new();
let mut in_degree: BTreeMap<String, usize> = BTreeMap::new();
for name in schemas.keys() {
in_degree.insert(name.clone(), 0);
}
@@ -148,7 +154,7 @@ fn topological_sort_schemas(schemas: &TypeSchemas) -> Vec<String> {
result.reverse();
// Add any types that weren't processed (e.g., due to circular refs or other edge cases)
let result_set: HashSet<_> = result.iter().cloned().collect();
let result_set: BTreeSet<_> = result.iter().cloned().collect();
let mut missing: Vec<_> = schemas
.keys()
.filter(|k| !result_set.contains(*k))
@@ -161,7 +167,7 @@ fn topological_sort_schemas(schemas: &TypeSchemas) -> Vec<String> {
}
/// Collect all type references ($ref) from a schema
fn collect_schema_refs(schema: &Value, refs: &mut HashSet<String>) {
fn collect_schema_refs(schema: &Value, refs: &mut BTreeSet<String>) {
match schema {
Value::Object(map) => {
if let Some(ref_path) = map.get("$ref").and_then(|r| r.as_str())
@@ -215,7 +221,7 @@ fn json_type_to_python(ty: &str, schema: &Value, current_type: Option<&str>) ->
pub fn schema_to_python_type(
schema: &Value,
current_type: Option<&str>,
quote_types: Option<&HashSet<String>>,
quote_types: Option<&BTreeSet<String>>,
) -> String {
if let Some(all_of) = schema.get("allOf").and_then(|v| v.as_array()) {
for item in all_of {
@@ -230,8 +236,8 @@ pub fn schema_to_python_type(
if let Some(ref_path) = schema.get("$ref").and_then(|r| r.as_str()) {
let type_name = ref_to_type_name(ref_path).unwrap_or("Any");
// Quote self-references or types in quote_types set
let should_quote = current_type == Some(type_name)
|| quote_types.is_some_and(|qt| qt.contains(type_name));
let should_quote =
current_type == Some(type_name) || quote_types.is_some_and(|qt| qt.contains(type_name));
if should_quote {
return format!("\"{}\"", type_name);
}
@@ -7,8 +7,9 @@ pub mod client;
pub mod tree;
mod types;
use std::{fmt::Write, fs, io, path::Path};
use std::{fmt::Write, io, path::Path};
use super::write_if_changed;
use crate::{ClientMetadata, Endpoint};
/// Generate Rust client from metadata and OpenAPI endpoints.
@@ -38,7 +39,7 @@ pub fn generate_rust_client(
tree::generate_tree(&mut output, &metadata.catalog, metadata);
api::generate_main_client(&mut output, endpoints);
fs::write(output_path, output)?;
write_if_changed(output_path, &output)?;
Ok(())
}
@@ -1,6 +1,6 @@
//! Rust tree structure generation.
use std::collections::HashSet;
use std::collections::BTreeSet;
use std::fmt::Write;
use brk_types::TreeNode;
@@ -15,7 +15,7 @@ pub fn generate_tree(output: &mut String, catalog: &TreeNode, metadata: &ClientM
writeln!(output, "// Metrics tree\n").unwrap();
let pattern_lookup = metadata.pattern_lookup();
let mut generated = HashSet::new();
let mut generated = BTreeSet::new();
generate_tree_node(
output,
"MetricsTree",
@@ -32,9 +32,9 @@ fn generate_tree_node(
name: &str,
path: &str,
node: &TreeNode,
pattern_lookup: &std::collections::HashMap<Vec<PatternField>, String>,
pattern_lookup: &std::collections::BTreeMap<Vec<PatternField>, String>,
metadata: &ClientMetadata,
generated: &mut HashSet<String>,
generated: &mut BTreeSet<String>,
) {
let Some(ctx) = prepare_tree_node(node, name, path, pattern_lookup, metadata, generated) else {
return;
+5 -5
View File
@@ -1,6 +1,6 @@
//! Client metadata extracted from brk_query.
use std::collections::{BTreeSet, HashMap};
use std::collections::{BTreeMap, BTreeSet};
use brk_query::Vecs;
use brk_types::{Index, MetricLeafWithSchema};
@@ -18,11 +18,11 @@ pub struct ClientMetadata {
/// Index set patterns - sets of indexes that appear together on metrics
pub index_set_patterns: Vec<IndexSetPattern>,
/// Maps concrete field signatures to pattern names
concrete_to_pattern: HashMap<Vec<PatternField>, String>,
concrete_to_pattern: BTreeMap<Vec<PatternField>, String>,
/// Maps concrete field signatures to their type parameter (for generic patterns)
concrete_to_type_param: HashMap<Vec<PatternField>, String>,
concrete_to_type_param: BTreeMap<Vec<PatternField>, String>,
/// Maps tree paths to their computed PatternBaseResult
node_bases: HashMap<String, PatternBaseResult>,
node_bases: BTreeMap<String, PatternBaseResult>,
}
impl ClientMetadata {
@@ -134,7 +134,7 @@ impl ClientMetadata {
}
/// Build a lookup map from field signatures to pattern names.
pub fn pattern_lookup(&self) -> HashMap<Vec<PatternField>, String> {
pub fn pattern_lookup(&self) -> BTreeMap<Vec<PatternField>, String> {
let mut lookup = self.concrete_to_pattern.clone();
for p in &self.structural_patterns {
lookup.insert(p.fields.clone(), p.name.clone());
+3 -3
View File
@@ -4,7 +4,7 @@
//! - Suffix mode: `_m(acc, relative)` → `acc_relative` or just `relative` if acc empty
//! - Prefix mode: `_p(prefix, acc)` → `prefix_acc` or just `acc` if prefix empty
use std::collections::HashMap;
use std::collections::BTreeMap;
/// How a pattern constructs metric names from the accumulator.
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -14,13 +14,13 @@ pub enum PatternMode {
/// Example: `_m("lth", "max_cost_basis")` → `"lth_max_cost_basis"`
Suffix {
/// Maps field name to its relative name (full metric name when acc = "")
relatives: HashMap<String, String>,
relatives: BTreeMap<String, String>,
},
/// Fields prepend their prefix to acc.
/// Formula: `_p(prefix, acc)` → `{prefix}_{acc}` or `{acc}` if prefix empty
/// Example: `_p("cumulative", "lth_realized_loss")` → `"cumulative_lth_realized_loss"`
Prefix {
/// Maps field name to its prefix (empty string for identity)
prefixes: HashMap<String, String>,
prefixes: BTreeMap<String, String>,
},
}
+5 -3
View File
@@ -1,6 +1,6 @@
//! Structural pattern and field types.
use std::collections::{BTreeSet, HashMap};
use std::collections::{BTreeMap, BTreeSet};
use brk_types::Index;
@@ -37,7 +37,9 @@ impl StructuralPattern {
/// Get the field part (relative name or prefix) for a given field.
pub fn get_field_part(&self, field_name: &str) -> Option<&str> {
match &self.mode {
Some(PatternMode::Suffix { relatives }) => relatives.get(field_name).map(|s| s.as_str()),
Some(PatternMode::Suffix { relatives }) => {
relatives.get(field_name).map(|s| s.as_str())
}
Some(PatternMode::Prefix { prefixes }) => prefixes.get(field_name).map(|s| s.as_str()),
None => None,
}
@@ -50,7 +52,7 @@ impl StructuralPattern {
/// Check if the given instance field parts match this pattern's field parts.
/// Returns true if all field parts in the pattern match the instance's field parts.
pub fn field_parts_match(&self, instance_field_parts: &HashMap<String, String>) -> bool {
pub fn field_parts_match(&self, instance_field_parts: &BTreeMap<String, String>) -> bool {
match &self.mode {
Some(PatternMode::Suffix { relatives }) => {
// For each field in the pattern, check if the instance has the same suffix
+24 -20
View File
@@ -1,6 +1,6 @@
//! Tests that verify pattern analysis using the real catalog.
use std::collections::HashSet;
use std::collections::{BTreeMap, BTreeSet};
use std::fmt::Write;
use brk_bindgen::ClientMetadata;
@@ -26,7 +26,7 @@ fn load_metadata() -> ClientMetadata {
}
/// Collect all leaf metric names from a tree.
fn collect_leaf_names(node: &TreeNode, names: &mut HashSet<String>) {
fn collect_leaf_names(node: &TreeNode, names: &mut BTreeSet<String>) {
match node {
TreeNode::Leaf(leaf) => {
names.insert(leaf.name().to_string());
@@ -63,7 +63,7 @@ fn test_catalog_loads() {
#[test]
fn test_all_leaves_have_names() {
let catalog = load_catalog();
let mut names = HashSet::new();
let mut names = BTreeSet::new();
collect_leaf_names(&catalog, &mut names);
println!("Catalog has {} unique metric names", names.len());
@@ -246,11 +246,11 @@ fn test_parameterizable_patterns_have_mode() {
// Verify all parameterizable patterns have valid modes with all fields
for pattern in &parameterizable {
let mode = pattern.mode.as_ref().unwrap();
let field_names: HashSet<_> = pattern.fields.iter().map(|f| f.name.clone()).collect();
let field_names: BTreeSet<_> = pattern.fields.iter().map(|f| f.name.clone()).collect();
match mode {
brk_bindgen::PatternMode::Suffix { relatives } => {
let mode_fields: HashSet<_> = relatives.keys().cloned().collect();
let mode_fields: BTreeSet<_> = relatives.keys().cloned().collect();
assert_eq!(
field_names, mode_fields,
"Pattern {} suffix mode should have all fields",
@@ -258,7 +258,7 @@ fn test_parameterizable_patterns_have_mode() {
);
}
brk_bindgen::PatternMode::Prefix { prefixes } => {
let mode_fields: HashSet<_> = prefixes.keys().cloned().collect();
let mode_fields: BTreeSet<_> = prefixes.keys().cloned().collect();
assert_eq!(
field_names, mode_fields,
"Pattern {} prefix mode should have all fields",
@@ -333,7 +333,7 @@ fn test_generated_rust_output() {
let metadata = ClientMetadata::from_catalog(catalog.clone());
// Collect all metric names from the catalog
let mut all_metrics = HashSet::new();
let mut all_metrics = BTreeSet::new();
collect_leaf_names(&catalog, &mut all_metrics);
// Generate Rust client output
@@ -416,7 +416,7 @@ fn test_generated_javascript_output() {
let metadata = ClientMetadata::from_catalog(catalog.clone());
// Collect all metric names from the catalog
let mut all_metrics = HashSet::new();
let mut all_metrics = BTreeSet::new();
collect_leaf_names(&catalog, &mut all_metrics);
// Load schemas from OpenAPI spec only (catalog schemas require runtime data)
@@ -507,7 +507,7 @@ fn test_generated_python_output() {
let metadata = ClientMetadata::from_catalog(catalog.clone());
// Collect all metric names from the catalog
let mut all_metrics = HashSet::new();
let mut all_metrics = BTreeSet::new();
collect_leaf_names(&catalog, &mut all_metrics);
// Load schemas from OpenAPI spec only (catalog schemas require runtime data)
@@ -518,13 +518,18 @@ fn test_generated_python_output() {
let mut py_output = String::new();
writeln!(py_output, "# Auto-generated BRK Python client").unwrap();
writeln!(py_output, "# Do not edit manually\n").unwrap();
writeln!(py_output, "from typing import TypeVar, Generic, Any, Optional, List, Literal, TypedDict, Union, Protocol, overload").unwrap();
writeln!(py_output, "from typing import TypeVar, Generic, Any, Optional, List, Literal, TypedDict, Union, Protocol, overload, Iterator, Tuple, TYPE_CHECKING").unwrap();
writeln!(py_output, "\nif TYPE_CHECKING:").unwrap();
writeln!(py_output, " import pandas as pd # type: ignore[import-not-found]").unwrap();
writeln!(py_output, " import polars as pl # type: ignore[import-not-found]").unwrap();
writeln!(
py_output,
"from http.client import HTTPSConnection, HTTPConnection"
)
.unwrap();
writeln!(py_output, "from urllib.parse import urlparse").unwrap();
writeln!(py_output, "from datetime import date, timedelta").unwrap();
writeln!(py_output, "from dataclasses import dataclass").unwrap();
writeln!(py_output, "import json\n").unwrap();
writeln!(py_output, "T = TypeVar('T')\n").unwrap();
@@ -665,8 +670,8 @@ fn test_cost_basis_relatives() {
// For leaves (max, min), the base is the metric name
// For branches (percentiles), the base is the common prefix of its children
let mut child_bases: std::collections::HashMap<String, String> =
std::collections::HashMap::new();
let mut child_bases: std::collections::BTreeMap<String, String> =
std::collections::BTreeMap::new();
for (field, metric) in metrics {
if field.starts_with("percentiles.") {
// This is a percentile metric - compute what the percentiles branch would return
@@ -721,20 +726,20 @@ fn test_debug_cost_basis_pattern2_mode() {
#[derive(Debug, Clone)]
struct DebugInstanceAnalysis {
base: String,
field_parts: std::collections::HashMap<String, String>,
field_parts: std::collections::BTreeMap<String, String>,
is_suffix_mode: bool,
}
fn collect_debug(
node: &TreeNode,
pattern_lookup: &std::collections::HashMap<Vec<brk_bindgen::PatternField>, String>,
all_analyses: &mut std::collections::HashMap<String, Vec<DebugInstanceAnalysis>>,
pattern_lookup: &std::collections::BTreeMap<Vec<brk_bindgen::PatternField>, String>,
all_analyses: &mut std::collections::BTreeMap<String, Vec<DebugInstanceAnalysis>>,
) -> Option<String> {
match node {
TreeNode::Leaf(leaf) => Some(leaf.name().to_string()),
TreeNode::Branch(children) => {
let mut child_bases: std::collections::HashMap<String, String> =
std::collections::HashMap::new();
let mut child_bases: std::collections::BTreeMap<String, String> =
std::collections::BTreeMap::new();
for (field_name, child_node) in children {
if let Some(base) = collect_debug(child_node, pattern_lookup, all_analyses) {
child_bases.insert(field_name.clone(), base);
@@ -750,7 +755,7 @@ fn test_debug_cost_basis_pattern2_mode() {
let (base, field_parts, is_suffix_mode) =
if let Some(common_prefix) = brk_bindgen::find_common_prefix(&bases) {
let base = common_prefix.trim_end_matches('_').to_string();
let mut parts = std::collections::HashMap::new();
let mut parts = std::collections::BTreeMap::new();
for (field_name, child_base) in &child_bases {
let relative = if *child_base == base {
String::new()
@@ -792,8 +797,7 @@ fn test_debug_cost_basis_pattern2_mode() {
}
}
let mut all_analyses: std::collections::HashMap<String, Vec<DebugInstanceAnalysis>> =
std::collections::HashMap::new();
let mut all_analyses: BTreeMap<String, Vec<DebugInstanceAnalysis>> = BTreeMap::new();
collect_debug(&catalog, &pattern_lookup, &mut all_analyses);
if let Some(analyses) = all_analyses.get("CostBasisPattern2") {
+18 -6
View File
@@ -11,18 +11,16 @@ Command-line interface for running a Bitcoin Research Kit instance.
- Bitcoin Core running with RPC enabled
- Access to `blk*.dat` files
- ~400 GB disk space
- 12+ GB RAM
- [~400 GB disk space](https://bitview.space/api/server/disk)
- [12+ GB RAM](https://github.com/bitcoinresearchkit/benches#benchmarks)
## Install
```bash
rustup update
RUSTFLAGS="-C target-cpu=native -C target-feature=+bmi1,+bmi2,+avx2" cargo install --locked brk_cli --version "$(cargo search brk_cli | head -1 | awk -F'"' '{print $2}')"
RUSTFLAGS="-C target-cpu=native" cargo install --locked brk_cli"
```
The SIMD flags (`bmi1`, `bmi2`, `avx2`) significantly improve pcodec decompression performance.
Portable build (without native CPU optimizations):
```bash
@@ -46,7 +44,21 @@ brk -h # Show all options
brk -V # Show version
```
Options are saved to `~/.brk/config.toml` after first use.
Command-line options override `~/.brk/config.toml` for that run only. Edit the file directly to persist settings:
```toml
brkdir = "/path/to/data"
bitcoindir = "/path/to/.bitcoin"
```
All fields are optional. See `brk -h` for the full list.
## Environment Variables
```bash
LOG=debug brk # Enable debug logging (keeps noise filters)
RUST_LOG=... brk # Full control over log filtering (overrides all defaults)
```
## Files
+86 -22
View File
@@ -4,11 +4,11 @@ use std::{
};
use brk_error::{Error, Result};
use owo_colors::OwoColorize;
use brk_fetcher::Fetcher;
use brk_rpc::{Auth, Client};
use brk_server::Website;
use brk_types::Port;
use owo_colors::OwoColorize;
use serde::{Deserialize, Deserializer, Serialize};
use crate::{default_brk_path, dot_brk_path, fix_user_path};
@@ -97,8 +97,6 @@ impl Config {
config.check();
config.write(&path)?;
Ok(config)
}
@@ -156,25 +154,96 @@ impl Config {
println!("Bitcoin Research Kit");
println!();
println!("{}", "USAGE:".bold());
println!(" brk {}", "[OPTIONS]".bright_black());
println!(
" {} brk {}",
"[ENV]".bright_black(),
"[OPTIONS]".bright_black()
);
println!();
println!("{}", "OPTIONS:".bold());
println!(" -h, --help Print help");
println!(" -V, --version Print version");
println!(" -h, --help Print help");
println!(" -V, --version Print version");
println!();
println!(" --brkdir {} Output directory {}", "<PATH>".bright_black(), "[~/.brk]".bright_black());
println!(" --brkport {} Server port {}", "<PORT>".bright_black(), "[3110]".bright_black());
println!(" --website {} Website: true, false, or path {}", "<BOOL|PATH>".bright_black(), "[true]".bright_black());
println!(" --fetch {} Fetch prices {}", "<BOOL>".bright_black(), "[true]".bright_black());
println!(
" --brkdir {} Output directory {}",
"<PATH>".bright_black(),
"[~/.brk]".bright_black()
);
println!(
" --brkport {} Server port {}",
"<PORT>".bright_black(),
"[3110]".bright_black()
);
println!(
" --website {} Website {}",
"<BOOL|PATH>".bright_black(),
"[true]".bright_black()
);
println!(
" --fetch {} Fetch prices {}",
"<BOOL>".bright_black(),
"[true]".bright_black()
);
println!();
println!(" --bitcoindir {} Bitcoin directory {}", "<PATH>".bright_black(), "[~/.bitcoin, ~/Library/...]".bright_black());
println!(" --blocksdir {} Blocks directory {}", "<PATH>".bright_black(), "[<bitcoindir>/blocks]".bright_black());
println!(
" --bitcoindir {} Bitcoin directory {}",
"<PATH>".bright_black(),
"[OS default]".bright_black()
);
println!(
" --blocksdir {} Blocks directory {}",
"<PATH>".bright_black(),
"[<bitcoindir>/blocks]".bright_black()
);
println!();
println!(" --rpcconnect {} RPC host {}", "<IP>".bright_black(), "[localhost]".bright_black());
println!(" --rpcport {} RPC port {}", "<PORT>".bright_black(), "[8332]".bright_black());
println!(" --rpccookiefile {} RPC cookie file {}", "<PATH>".bright_black(), "[<bitcoindir>/.cookie]".bright_black());
println!(" --rpcuser {} RPC username", "<USERNAME>".bright_black());
println!(" --rpcpassword {} RPC password", "<PASSWORD>".bright_black());
println!(
" --rpcconnect {} RPC host {}",
"<IP>".bright_black(),
"[localhost]".bright_black()
);
println!(
" --rpcport {} RPC port {}",
"<PORT>".bright_black(),
"[8332]".bright_black()
);
println!(
" --rpccookiefile {} RPC cookie file {}",
"<PATH>".bright_black(),
"[<bitcoindir>/.cookie]".bright_black()
);
println!(
" --rpcuser {} RPC username",
"<USERNAME>".bright_black()
);
println!(
" --rpcpassword {} RPC password",
"<PASSWORD>".bright_black()
);
println!();
println!("{}", "ENVIRONMENT:".bold());
println!(
" LOG={} Log level {}",
"<LEVEL>".bright_black(),
"[info]".bright_black()
);
println!(
" RUST_LOG={} Full log filter",
"<RULES>".bright_black()
);
println!();
println!("{}", "CONFIG:".bold());
println!(
" Edit {} to persist settings:",
"~/.brk/config.toml".bright_black()
);
println!(
" {}",
"brkdir = \"/path/to/data\"".bright_black()
);
println!(
" {}",
"bitcoindir = \"/path/to/.bitcoin\"".bright_black()
);
}
fn check(&self) {
@@ -216,10 +285,6 @@ Finally, you can run the program with '-h' for help."
)
}
fn write(&self, path: &Path) -> std::io::Result<()> {
fs::write(path, toml::to_string(self).unwrap())
}
pub fn rpc(&self) -> Result<Client> {
Client::new(
&format!(
@@ -300,7 +365,6 @@ Finally, you can run the program with '-h' for help."
self.fetch()
.then(|| Fetcher::import(Some(self.harsdir().as_path())).unwrap())
}
}
fn default_on_error<'de, D, T>(deserializer: D) -> Result<T, D::Error>
+3 -1
View File
@@ -57,8 +57,10 @@ pub fn run() -> anyhow::Result<()> {
let indexed_height = indexer.vecs.starting_height();
let blocks_behind = chain_height.saturating_sub(*indexed_height);
if blocks_behind > 10_000 {
info!("---");
info!("Indexing {blocks_behind} blocks before starting server...");
sleep(Duration::from_secs(3));
info!("---");
sleep(Duration::from_secs(10));
indexer.index(&blocks, &client, &exit)?;
drop(indexer);
Mimalloc::collect();
+270 -270
View File
@@ -1535,18 +1535,18 @@ impl<T: DeserializeOwned> ClassDaysInLossPattern<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_max_drawdown")),
_2016: MetricPattern4::new(client.clone(), _m(&acc, "2016_max_drawdown")),
_2017: MetricPattern4::new(client.clone(), _m(&acc, "2017_max_drawdown")),
_2018: MetricPattern4::new(client.clone(), _m(&acc, "2018_max_drawdown")),
_2019: MetricPattern4::new(client.clone(), _m(&acc, "2019_max_drawdown")),
_2020: MetricPattern4::new(client.clone(), _m(&acc, "2020_max_drawdown")),
_2021: MetricPattern4::new(client.clone(), _m(&acc, "2021_max_drawdown")),
_2022: MetricPattern4::new(client.clone(), _m(&acc, "2022_max_drawdown")),
_2023: MetricPattern4::new(client.clone(), _m(&acc, "2023_max_drawdown")),
_2024: MetricPattern4::new(client.clone(), _m(&acc, "2024_max_drawdown")),
_2025: MetricPattern4::new(client.clone(), _m(&acc, "2025_max_drawdown")),
_2026: MetricPattern4::new(client.clone(), _m(&acc, "2026_max_drawdown")),
_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")),
_2026: MetricPattern4::new(client.clone(), _m(&acc, "2026_returns")),
}
}
}
@@ -1619,38 +1619,6 @@ 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>,
}
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 RelativePattern {
pub neg_unrealized_loss_rel_to_market_cap: MetricPattern1<StoredF32>,
@@ -1683,6 +1651,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>,
@@ -1833,32 +1833,6 @@ impl _0satsPattern {
}
}
/// Pattern struct for repeated tree structure.
pub struct _0satsPattern2 {
pub activity: ActivityPattern2,
pub cost_basis: CostBasisPattern,
pub outputs: OutputsPattern,
pub realized: RealizedPattern,
pub relative: RelativePattern4,
pub supply: SupplyPattern2,
pub unrealized: UnrealizedPattern,
}
impl _0satsPattern2 {
/// 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: RealizedPattern::new(client.clone(), acc.clone()),
relative: RelativePattern4::new(client.clone(), _m(&acc, "supply_in")),
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>,
@@ -1885,32 +1859,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 _100btcPattern {
pub activity: ActivityPattern2,
@@ -1937,6 +1885,32 @@ impl _100btcPattern {
}
}
/// Pattern struct for repeated tree structure.
pub struct _0satsPattern2 {
pub activity: ActivityPattern2,
pub cost_basis: CostBasisPattern,
pub outputs: OutputsPattern,
pub realized: RealizedPattern,
pub relative: RelativePattern4,
pub supply: SupplyPattern2,
pub unrealized: UnrealizedPattern,
}
impl _0satsPattern2 {
/// 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: RealizedPattern::new(client.clone(), acc.clone()),
relative: RelativePattern4::new(client.clone(), _m(&acc, "supply_in")),
supply: SupplyPattern2::new(client.clone(), _m(&acc, "supply")),
unrealized: UnrealizedPattern::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct _10yPattern {
pub activity: ActivityPattern2,
@@ -1963,6 +1937,32 @@ impl _10yPattern {
}
}
/// 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 UnrealizedPattern {
pub neg_unrealized_loss: MetricPattern1<Dollars>,
@@ -2055,60 +2055,6 @@ impl<T: DeserializeOwned> SplitPattern2<T> {
}
}
/// Pattern struct for repeated tree structure.
pub struct CoinbasePattern {
pub bitcoin: BitcoinPattern,
pub dollars: DollarsPattern<Dollars>,
pub sats: DollarsPattern<Sats>,
}
impl CoinbasePattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
bitcoin: BitcoinPattern::new(client.clone(), _m(&acc, "btc")),
dollars: DollarsPattern::new(client.clone(), _m(&acc, "usd")),
sats: DollarsPattern::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct CostBasisPattern2 {
pub max: ActivePricePattern,
pub min: ActivePricePattern,
pub percentiles: PercentilesPattern,
}
impl CostBasisPattern2 {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
max: ActivePricePattern::new(client.clone(), _m(&acc, "max_cost_basis")),
min: ActivePricePattern::new(client.clone(), _m(&acc, "min_cost_basis")),
percentiles: PercentilesPattern::new(client.clone(), _m(&acc, "cost_basis")),
}
}
}
/// 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 SegwitAdoptionPattern {
pub base: MetricPattern11<StoredF32>,
@@ -2127,24 +2073,6 @@ impl SegwitAdoptionPattern {
}
}
/// Pattern struct for repeated tree structure.
pub struct UnclaimedRewardsPattern {
pub bitcoin: BitcoinPattern2<Bitcoin>,
pub dollars: BlockCountPattern<Dollars>,
pub sats: BlockCountPattern<Sats>,
}
impl UnclaimedRewardsPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
bitcoin: BitcoinPattern2::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 ActiveSupplyPattern {
pub bitcoin: MetricPattern1<Bitcoin>,
@@ -2181,6 +2109,78 @@ impl _2015Pattern {
}
}
/// Pattern struct for repeated tree structure.
pub struct CoinbasePattern {
pub bitcoin: BitcoinPattern,
pub dollars: DollarsPattern<Dollars>,
pub sats: DollarsPattern<Sats>,
}
impl CoinbasePattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
bitcoin: BitcoinPattern::new(client.clone(), _m(&acc, "btc")),
dollars: DollarsPattern::new(client.clone(), _m(&acc, "usd")),
sats: DollarsPattern::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct UnclaimedRewardsPattern {
pub bitcoin: BitcoinPattern2<Bitcoin>,
pub dollars: BlockCountPattern<Dollars>,
pub sats: BlockCountPattern<Sats>,
}
impl UnclaimedRewardsPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
bitcoin: BitcoinPattern2::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 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 CostBasisPattern2 {
pub max: ActivePricePattern,
pub min: ActivePricePattern,
pub percentiles: PercentilesPattern,
}
impl CostBasisPattern2 {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
max: ActivePricePattern::new(client.clone(), _m(&acc, "max_cost_basis")),
min: ActivePricePattern::new(client.clone(), _m(&acc, "min_cost_basis")),
percentiles: PercentilesPattern::new(client.clone(), _m(&acc, "cost_basis")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct ActivePricePattern {
pub dollars: MetricPattern1<Dollars>,
@@ -2197,22 +2197,6 @@ impl ActivePricePattern {
}
}
/// Pattern struct for repeated tree structure.
pub struct CostBasisPattern {
pub max: ActivePricePattern,
pub min: ActivePricePattern,
}
impl CostBasisPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
max: ActivePricePattern::new(client.clone(), _m(&acc, "max_cost_basis")),
min: ActivePricePattern::new(client.clone(), _m(&acc, "min_cost_basis")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct _0sdUsdPattern {
pub dollars: MetricPattern4<Dollars>,
@@ -2229,6 +2213,38 @@ impl _0sdUsdPattern {
}
}
/// Pattern struct for repeated tree structure.
pub struct SupplyPattern2 {
pub halved: ActiveSupplyPattern,
pub total: ActiveSupplyPattern,
}
impl SupplyPattern2 {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
halved: ActiveSupplyPattern::new(client.clone(), _m(&acc, "halved")),
total: ActiveSupplyPattern::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct CostBasisPattern {
pub max: ActivePricePattern,
pub min: ActivePricePattern,
}
impl CostBasisPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
max: ActivePricePattern::new(client.clone(), _m(&acc, "max_cost_basis")),
min: ActivePricePattern::new(client.clone(), _m(&acc, "min_cost_basis")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct _1dReturns1mSdPattern {
pub sd: MetricPattern4<StoredF32>,
@@ -2261,22 +2277,6 @@ impl RelativePattern4 {
}
}
/// Pattern struct for repeated tree structure.
pub struct SupplyPattern2 {
pub halved: ActiveSupplyPattern,
pub total: ActiveSupplyPattern,
}
impl SupplyPattern2 {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
halved: ActiveSupplyPattern::new(client.clone(), _m(&acc, "halved")),
total: ActiveSupplyPattern::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct BlockCountPattern<T> {
pub cumulative: MetricPattern1<T>,
@@ -2293,22 +2293,6 @@ impl<T: DeserializeOwned> BlockCountPattern<T> {
}
}
/// Pattern struct for repeated tree structure.
pub struct SatsPattern<T> {
pub ohlc: MetricPattern1<T>,
pub split: SplitPattern2<T>,
}
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()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct BitcoinPattern2<T> {
pub cumulative: MetricPattern2<T>,
@@ -2326,15 +2310,17 @@ impl<T: DeserializeOwned> BitcoinPattern2<T> {
}
/// Pattern struct for repeated tree structure.
pub struct OutputsPattern {
pub utxo_count: MetricPattern1<StoredU64>,
pub struct SatsPattern<T> {
pub ohlc: MetricPattern1<T>,
pub split: SplitPattern2<T>,
}
impl OutputsPattern {
impl<T: DeserializeOwned> SatsPattern<T> {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
utxo_count: MetricPattern1::new(client.clone(), acc.clone()),
ohlc: MetricPattern1::new(client.clone(), _m(&acc, "ohlc_sats")),
split: SplitPattern2::new(client.clone(), _m(&acc, "sats")),
}
}
}
@@ -2353,6 +2339,20 @@ impl RealizedPriceExtraPattern {
}
}
/// Pattern struct for repeated tree structure.
pub struct OutputsPattern {
pub utxo_count: MetricPattern1<StoredU64>,
}
impl OutputsPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
utxo_count: MetricPattern1::new(client.clone(), acc.clone()),
}
}
}
// Metrics tree
/// Metrics tree node.
@@ -4277,9 +4277,9 @@ pub struct MetricsTree_Market_Dca {
pub class_average_price: MetricsTree_Market_Dca_ClassAveragePrice,
pub class_days_in_loss: MetricsTree_Market_Dca_ClassDaysInLoss,
pub class_days_in_profit: MetricsTree_Market_Dca_ClassDaysInProfit,
pub class_max_drawdown: ClassDaysInLossPattern<StoredF32>,
pub class_max_drawdown: MetricsTree_Market_Dca_ClassMaxDrawdown,
pub class_max_return: MetricsTree_Market_Dca_ClassMaxReturn,
pub class_returns: MetricsTree_Market_Dca_ClassReturns,
pub class_returns: ClassDaysInLossPattern<StoredF32>,
pub class_stack: MetricsTree_Market_Dca_ClassStack,
pub period_average_price: MetricsTree_Market_Dca_PeriodAveragePrice,
pub period_cagr: PeriodCagrPattern,
@@ -4303,9 +4303,9 @@ impl MetricsTree_Market_Dca {
class_average_price: MetricsTree_Market_Dca_ClassAveragePrice::new(client.clone(), format!("{base_path}_class_average_price")),
class_days_in_loss: MetricsTree_Market_Dca_ClassDaysInLoss::new(client.clone(), format!("{base_path}_class_days_in_loss")),
class_days_in_profit: MetricsTree_Market_Dca_ClassDaysInProfit::new(client.clone(), format!("{base_path}_class_days_in_profit")),
class_max_drawdown: ClassDaysInLossPattern::new(client.clone(), "dca_class".to_string()),
class_max_drawdown: MetricsTree_Market_Dca_ClassMaxDrawdown::new(client.clone(), format!("{base_path}_class_max_drawdown")),
class_max_return: MetricsTree_Market_Dca_ClassMaxReturn::new(client.clone(), format!("{base_path}_class_max_return")),
class_returns: MetricsTree_Market_Dca_ClassReturns::new(client.clone(), format!("{base_path}_class_returns")),
class_returns: ClassDaysInLossPattern::new(client.clone(), "dca_class".to_string()),
class_stack: MetricsTree_Market_Dca_ClassStack::new(client.clone(), format!("{base_path}_class_stack")),
period_average_price: MetricsTree_Market_Dca_PeriodAveragePrice::new(client.clone(), format!("{base_path}_period_average_price")),
period_cagr: PeriodCagrPattern::new(client.clone(), "dca_cagr".to_string()),
@@ -4430,6 +4430,41 @@ impl MetricsTree_Market_Dca_ClassDaysInProfit {
}
}
/// Metrics tree node.
pub struct MetricsTree_Market_Dca_ClassMaxDrawdown {
pub _2015: MetricPattern4<StoredF32>,
pub _2016: MetricPattern4<StoredF32>,
pub _2017: MetricPattern4<StoredF32>,
pub _2018: MetricPattern4<StoredF32>,
pub _2019: MetricPattern4<StoredF32>,
pub _2020: MetricPattern4<StoredF32>,
pub _2021: MetricPattern4<StoredF32>,
pub _2022: MetricPattern4<StoredF32>,
pub _2023: MetricPattern4<StoredF32>,
pub _2024: MetricPattern4<StoredF32>,
pub _2025: MetricPattern4<StoredF32>,
pub _2026: MetricPattern4<StoredF32>,
}
impl MetricsTree_Market_Dca_ClassMaxDrawdown {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
_2015: MetricPattern4::new(client.clone(), "dca_class_2015_max_drawdown".to_string()),
_2016: MetricPattern4::new(client.clone(), "dca_class_2016_max_drawdown".to_string()),
_2017: MetricPattern4::new(client.clone(), "dca_class_2017_max_drawdown".to_string()),
_2018: MetricPattern4::new(client.clone(), "dca_class_2018_max_drawdown".to_string()),
_2019: MetricPattern4::new(client.clone(), "dca_class_2019_max_drawdown".to_string()),
_2020: MetricPattern4::new(client.clone(), "dca_class_2020_max_drawdown".to_string()),
_2021: MetricPattern4::new(client.clone(), "dca_class_2021_max_drawdown".to_string()),
_2022: MetricPattern4::new(client.clone(), "dca_class_2022_max_drawdown".to_string()),
_2023: MetricPattern4::new(client.clone(), "dca_class_2023_max_drawdown".to_string()),
_2024: MetricPattern4::new(client.clone(), "dca_class_2024_max_drawdown".to_string()),
_2025: MetricPattern4::new(client.clone(), "dca_class_2025_max_drawdown".to_string()),
_2026: MetricPattern4::new(client.clone(), "dca_class_2026_max_drawdown".to_string()),
}
}
}
/// Metrics tree node.
pub struct MetricsTree_Market_Dca_ClassMaxReturn {
pub _2015: MetricPattern4<StoredF32>,
@@ -4465,41 +4500,6 @@ impl MetricsTree_Market_Dca_ClassMaxReturn {
}
}
/// Metrics tree node.
pub struct MetricsTree_Market_Dca_ClassReturns {
pub _2015: MetricPattern4<StoredF32>,
pub _2016: MetricPattern4<StoredF32>,
pub _2017: MetricPattern4<StoredF32>,
pub _2018: MetricPattern4<StoredF32>,
pub _2019: MetricPattern4<StoredF32>,
pub _2020: MetricPattern4<StoredF32>,
pub _2021: MetricPattern4<StoredF32>,
pub _2022: MetricPattern4<StoredF32>,
pub _2023: MetricPattern4<StoredF32>,
pub _2024: MetricPattern4<StoredF32>,
pub _2025: MetricPattern4<StoredF32>,
pub _2026: MetricPattern4<StoredF32>,
}
impl MetricsTree_Market_Dca_ClassReturns {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
_2015: MetricPattern4::new(client.clone(), "dca_class_2015_returns".to_string()),
_2016: MetricPattern4::new(client.clone(), "dca_class_2016_returns".to_string()),
_2017: MetricPattern4::new(client.clone(), "dca_class_2017_returns".to_string()),
_2018: MetricPattern4::new(client.clone(), "dca_class_2018_returns".to_string()),
_2019: MetricPattern4::new(client.clone(), "dca_class_2019_returns".to_string()),
_2020: MetricPattern4::new(client.clone(), "dca_class_2020_returns".to_string()),
_2021: MetricPattern4::new(client.clone(), "dca_class_2021_returns".to_string()),
_2022: MetricPattern4::new(client.clone(), "dca_class_2022_returns".to_string()),
_2023: MetricPattern4::new(client.clone(), "dca_class_2023_returns".to_string()),
_2024: MetricPattern4::new(client.clone(), "dca_class_2024_returns".to_string()),
_2025: MetricPattern4::new(client.clone(), "dca_class_2025_returns".to_string()),
_2026: MetricPattern4::new(client.clone(), "dca_class_2026_returns".to_string()),
}
}
}
/// Metrics tree node.
pub struct MetricsTree_Market_Dca_ClassStack {
pub _2015: _2015Pattern,
@@ -5278,16 +5278,16 @@ impl MetricsTree_Positions {
/// Metrics tree node.
pub struct MetricsTree_Price {
pub cents: MetricsTree_Price_Cents,
pub sats: MetricsTree_Price_Sats,
pub usd: SatsPattern<OHLCDollars>,
pub sats: SatsPattern<OHLCSats>,
pub usd: MetricsTree_Price_Usd,
}
impl MetricsTree_Price {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
cents: MetricsTree_Price_Cents::new(client.clone(), format!("{base_path}_cents")),
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")),
}
}
}
@@ -5327,16 +5327,16 @@ impl MetricsTree_Price_Cents_Split {
}
/// 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()),
}
}
}
@@ -5651,7 +5651,7 @@ pub struct BrkClient {
impl BrkClient {
/// Client version.
pub const VERSION: &'static str = "v0.1.0-beta.1";
pub const VERSION: &'static str = "v0.1.1";
/// Create a new client with the given base URL.
pub fn new(base_url: impl Into<String>) -> Self {
+1 -1
View File
@@ -56,7 +56,7 @@ fn run() -> Result<()> {
// Pre-run indexer if too far behind, then drop and reimport to reduce memory
let chain_height = client.get_last_height()?;
let indexed_height = indexer.vecs.starting_height();
if u32::from(chain_height) - u32::from(indexed_height) > 1000 {
if u32::from(chain_height).saturating_sub(u32::from(indexed_height)) > 1000 {
indexer.checked_index(&blocks, &client, &exit)?;
drop(indexer);
Mimalloc::collect();
@@ -58,9 +58,10 @@ macro_rules! define_any_address_indexes_vecs {
}
/// Get address index for a given type and typeindex.
/// Uses get_any_or_read_at_unwrap to check updated layer (needed after rollback).
pub fn get(&self, address_type: OutputType, typeindex: TypeIndex, reader: &Reader) -> AnyAddressIndex {
match address_type {
$(OutputType::$variant => self.$field.get_pushed_or_read_at_unwrap(typeindex.into(), reader),)*
$(OutputType::$variant => self.$field.get_any_or_read_at_unwrap(typeindex.into(), reader),)*
_ => unreachable!("Invalid address type: {:?}", address_type),
}
}
@@ -112,16 +112,18 @@ pub fn load_uncached_address_data(
Some(match anyaddressindex.to_enum() {
AnyAddressDataIndexEnum::Loaded(loaded_index) => {
let reader = &vr.anyaddressindex_to_anyaddressdata.loaded;
// Use get_any_or_read_unwrap to check updated layer (needed after rollback)
let loaded_data = addresses_data
.loaded
.get_pushed_or_read_unwrap(loaded_index, reader);
.get_any_or_read_unwrap(loaded_index, reader);
WithAddressDataSource::FromLoaded(loaded_index, loaded_data)
}
AnyAddressDataIndexEnum::Empty(empty_index) => {
let reader = &vr.anyaddressindex_to_anyaddressdata.empty;
// Use get_any_or_read_unwrap to check updated layer (needed after rollback)
let empty_data = addresses_data
.empty
.get_pushed_or_read_unwrap(empty_index, reader);
.get_any_or_read_unwrap(empty_index, reader);
WithAddressDataSource::FromEmpty(empty_index, empty_data.into())
}
})
@@ -2,6 +2,7 @@ use std::{cmp::Ordering, collections::BTreeSet};
use brk_error::Result;
use brk_types::Height;
use tracing::{debug, warn};
use vecdb::Stamp;
use super::super::{
@@ -44,27 +45,49 @@ pub fn recover_state(
// If rollbacks are inconsistent, start fresh
if consistent_height.is_zero() {
warn!("Rollback consistency check failed: inconsistent heights");
return Ok(RecoveredState {
starting_height: Height::ZERO,
});
}
// Rollback can land at an earlier height (multi-block change file), which is fine.
// But if it lands AHEAD of target, that means rollback failed (missing change files).
if consistent_height > height {
warn!(
"Rollback failed: still at {} but target was {}, falling back to fresh start",
consistent_height, height
);
return Ok(RecoveredState {
starting_height: Height::ZERO,
});
}
if consistent_height != height {
debug!(
"Rollback landed at {} instead of {}, will resume from there",
consistent_height, height
);
}
// Import UTXO cohort states - all must succeed
if !utxo_cohorts.import_separate_states(height) {
if !utxo_cohorts.import_separate_states(consistent_height) {
warn!("UTXO cohort state import failed at height {}", consistent_height);
return Ok(RecoveredState {
starting_height: Height::ZERO,
});
}
// Import address cohort states - all must succeed
if !address_cohorts.import_separate_states(height) {
if !address_cohorts.import_separate_states(consistent_height) {
warn!("Address cohort state import failed at height {}", consistent_height);
return Ok(RecoveredState {
starting_height: Height::ZERO,
});
}
Ok(RecoveredState {
starting_height: height,
starting_height: consistent_height,
})
}
@@ -132,28 +155,38 @@ fn rollback_states(
// All rollbacks must succeed - any error means fresh start
let Ok(s) = chain_state_rollback else {
warn!("chain_state rollback failed: {:?}", chain_state_rollback);
return Height::ZERO;
};
heights.insert(Height::from(s).incremented());
let chain_height = Height::from(s).incremented();
debug!("chain_state rolled back to stamp {:?}, height {}", s, chain_height);
heights.insert(chain_height);
let Ok(stamps) = address_indexes_rollbacks else {
warn!("address_indexes rollback failed: {:?}", address_indexes_rollbacks);
return Height::ZERO;
};
for s in stamps {
heights.insert(Height::from(s).incremented());
for (i, s) in stamps.iter().enumerate() {
let h = Height::from(*s).incremented();
debug!("address_indexes[{}] rolled back to stamp {:?}, height {}", i, s, h);
heights.insert(h);
}
let Ok(stamps) = address_data_rollbacks else {
warn!("address_data rollback failed: {:?}", address_data_rollbacks);
return Height::ZERO;
};
for s in stamps {
heights.insert(Height::from(s).incremented());
for (i, s) in stamps.iter().enumerate() {
let h = Height::from(*s).incremented();
debug!("address_data[{}] rolled back to stamp {:?}, height {}", i, s, h);
heights.insert(h);
}
// All must agree on the same height
if heights.len() == 1 {
heights.pop_first().unwrap()
} else {
warn!("Rollback heights inconsistent: {:?}", heights);
Height::ZERO
}
}
@@ -1,6 +1,6 @@
use std::ops::Bound;
use brk_types::{Dollars, Sats};
use brk_types::{CentsUnsigned, Dollars, Sats};
use vecdb::CheckedSub;
use super::price_to_amount::PriceToAmount;
@@ -11,6 +11,10 @@ pub struct UnrealizedState {
pub supply_in_loss: Sats,
pub unrealized_profit: Dollars,
pub unrealized_loss: Dollars,
/// Invested capital in profit: Σ(sats × price) where price <= spot
pub invested_capital_in_profit: Dollars,
/// Invested capital in loss: Σ(sats × price) where price > spot
pub invested_capital_in_loss: Dollars,
}
impl UnrealizedState {
@@ -19,6 +23,8 @@ impl UnrealizedState {
supply_in_loss: Sats::ZERO,
unrealized_profit: Dollars::NAN,
unrealized_loss: Dollars::NAN,
invested_capital_in_profit: Dollars::NAN,
invested_capital_in_loss: Dollars::NAN,
};
pub const ZERO: Self = Self {
@@ -26,6 +32,8 @@ impl UnrealizedState {
supply_in_loss: Sats::ZERO,
unrealized_profit: Dollars::ZERO,
unrealized_loss: Dollars::ZERO,
invested_capital_in_profit: Dollars::ZERO,
invested_capital_in_loss: Dollars::ZERO,
};
}
@@ -62,14 +70,17 @@ impl CachedUnrealizedState {
/// Update cached state when a receive happens.
/// Determines profit/loss classification relative to cached price.
pub fn on_receive(&mut self, purchase_price: Dollars, sats: Sats) {
let invested_capital = purchase_price * sats;
if purchase_price <= self.at_price {
self.state.supply_in_profit += sats;
self.state.invested_capital_in_profit += invested_capital;
if purchase_price < self.at_price {
let diff = self.at_price.checked_sub(purchase_price).unwrap();
self.state.unrealized_profit += diff * sats;
}
} else {
self.state.supply_in_loss += sats;
self.state.invested_capital_in_loss += invested_capital;
let diff = purchase_price.checked_sub(self.at_price).unwrap();
self.state.unrealized_loss += diff * sats;
}
@@ -77,9 +88,15 @@ impl CachedUnrealizedState {
/// Update cached state when a send happens from historical price.
pub fn on_send(&mut self, historical_price: Dollars, sats: Sats) {
let invested_capital = historical_price * sats;
if historical_price <= self.at_price {
// Was in profit
self.state.supply_in_profit -= sats;
self.state.invested_capital_in_profit = self
.state
.invested_capital_in_profit
.checked_sub(invested_capital)
.unwrap();
if historical_price < self.at_price {
let diff = self.at_price.checked_sub(historical_price).unwrap();
let profit_removed = diff * sats;
@@ -92,6 +109,11 @@ impl CachedUnrealizedState {
} else {
// Was in loss
self.state.supply_in_loss -= sats;
self.state.invested_capital_in_loss = self
.state
.invested_capital_in_loss
.checked_sub(invested_capital)
.unwrap();
let diff = historical_price.checked_sub(self.at_price).unwrap();
let loss_removed = diff * sats;
self.state.unrealized_loss = self
@@ -210,14 +232,17 @@ impl CachedUnrealizedState {
let mut state = UnrealizedState::ZERO;
for (price, &sats) in price_to_amount.iter() {
let invested_capital = price * sats;
if price <= current_price {
state.supply_in_profit += sats;
state.invested_capital_in_profit += invested_capital;
if price < current_price {
let diff = current_price.checked_sub(price).unwrap();
state.unrealized_profit += diff * sats;
}
} else {
state.supply_in_loss += sats;
state.invested_capital_in_loss += invested_capital;
let diff = price.checked_sub(current_price).unwrap();
state.unrealized_loss += diff * sats;
}
+1 -2
View File
@@ -1,12 +1,11 @@
use std::str::FromStr;
use brk_types::{Height, TxIndex, Txid, TxidPrefix, Version};
use brk_types::{TxIndex, Txid, TxidPrefix, Version};
// One version for all data sources
// Increment on **change _OR_ addition**
pub const VERSION: Version = Version::new(24);
pub const SNAPSHOT_BLOCK_RANGE: usize = 1_000;
pub const COLLISIONS_CHECKED_UP_TO: Height = Height::new(0);
/// Known duplicate Bitcoin transactions (BIP30)
/// https://github.com/bitcoin/bips/blob/master/bip-0030.mediawiki
+1 -4
View File
@@ -177,13 +177,10 @@ impl Indexer {
indexes.height = height;
// Used to check rapidhash collisions
let block_check_collisions = check_collisions && height > COLLISIONS_CHECKED_UP_TO;
let mut processor = BlockProcessor {
block: &block,
height,
check_collisions: block_check_collisions,
check_collisions,
indexes: &mut indexes,
vecs,
stores,
+10
View File
@@ -78,6 +78,8 @@ impl<'a> BlockProcessor<'a> {
pub fn store_transaction_metadata(&mut self, txs: Vec<ComputedTx>) -> Result<()> {
let height = self.height;
let mut inserted = 0usize;
let mut skipped = 0usize;
for ct in txs {
if ct.prev_txindex_opt.is_none() {
@@ -86,6 +88,9 @@ impl<'a> BlockProcessor<'a> {
ct.txindex,
height,
);
inserted += 1;
} else {
skipped += 1;
}
self.vecs
@@ -118,6 +123,11 @@ impl<'a> BlockProcessor<'a> {
.checked_push(ct.txindex, StoredBool::from(ct.tx.is_explicitly_rbf()))?;
}
tracing::debug!(
"store_transaction_metadata: height={}, inserted={}, skipped={}",
height, inserted, skipped
);
Ok(())
}
}
+5
View File
@@ -81,6 +81,11 @@ impl<'a> BlockProcessor<'a> {
{
txindex
} else {
let store_result = self.stores.txidprefix_to_txindex.get(&txid_prefix)?;
tracing::error!(
"UnknownTxid: txid={}, prefix={:?}, store_result={:?}, current_txindex={:?}",
txid, txid_prefix, store_result, self.indexes.txindex
);
return Err(Error::UnknownTxid);
};
+35 -6
View File
@@ -1,5 +1,7 @@
use std::{fs, path::Path, time::Instant};
use rustc_hash::FxHashSet;
use brk_cohort::ByAddressType;
use brk_error::Result;
use brk_store::{AnyStore, Kind, Mode, Store};
@@ -228,6 +230,7 @@ impl Stores {
});
// Remove address hashes for all address types starting from rollback height
// (each address only appears once in bytes vec, so no dedup needed)
for address_type in [
OutputType::P2PK65,
OutputType::P2PK33,
@@ -249,6 +252,14 @@ impl Stores {
}
if starting_indexes.txindex != TxIndex::ZERO {
let txid_vec_len = vecs.transactions.txid.len();
let skip_count = starting_indexes.txindex.to_usize();
let remove_count = txid_vec_len.saturating_sub(skip_count);
tracing::debug!(
"Rollback TXIDs: vec_len={}, skip={}, removing={}",
txid_vec_len, skip_count, remove_count
);
vecs.transactions
.txid
.iter()?
@@ -269,6 +280,9 @@ impl Stores {
self.txidprefix_to_txindex.remove(txidprefix);
}
});
// Clear caches to prevent stale reads after rollback
self.txidprefix_to_txindex.clear_caches();
} else {
unreachable!();
}
@@ -280,6 +294,11 @@ impl Stores {
let mut txoutindex_to_outputtype_iter = vecs.outputs.outputtype.iter()?;
let mut txoutindex_to_typeindex_iter = vecs.outputs.typeindex.iter()?;
// Collect unique (addresstype, addressindex, txindex) to avoid double deletion
// when same address receives multiple outputs in same transaction
let mut addressindex_txindex_to_remove: FxHashSet<(OutputType, TypeIndex, TxIndex)> =
FxHashSet::default();
for txoutindex in
starting_indexes.txoutindex.to_usize()..vecs.outputs.outputtype.len()
{
@@ -292,9 +311,7 @@ impl Stores {
let addressindex = txoutindex_to_typeindex_iter.get_at_unwrap(txoutindex);
let txindex = txoutindex_to_txindex_iter.get_at_unwrap(txoutindex);
self.addresstype_to_addressindex_and_txindex
.get_mut_unwrap(addresstype)
.remove(AddressIndexTxIndex::from((addressindex, txindex)));
addressindex_txindex_to_remove.insert((addresstype, addressindex, txindex));
let vout = Vout::from(
txoutindex
@@ -304,11 +321,14 @@ impl Stores {
);
let outpoint = OutPoint::new(txindex, vout);
// OutPoints are unique per output, no dedup needed
self.addresstype_to_addressindex_and_unspentoutpoint
.get_mut_unwrap(addresstype)
.remove(AddressIndexOutPoint::from((addressindex, outpoint)));
}
// Don't remove yet - merge with second loop's set first
// Collect outputs that were spent after the rollback point
// We need to: 1) reset their spend status, 2) restore address stores
let mut txindex_to_first_txoutindex_iter =
@@ -349,21 +369,30 @@ impl Stores {
.collect();
// Now process the collected outputs (iterators dropped, can mutate vecs)
// Add spending tx entries to the same set (avoid double deletion when same tx
// both creates output to address A and spends output from address A)
for (outpoint, outputtype, typeindex, spending_txindex) in outputs_to_unspend {
// Restore address stores if this is an address output
if outputtype.is_address() {
let addresstype = outputtype;
let addressindex = typeindex;
self.addresstype_to_addressindex_and_txindex
.get_mut_unwrap(addresstype)
.remove(AddressIndexTxIndex::from((addressindex, spending_txindex)));
// Add to same set as first loop
addressindex_txindex_to_remove.insert((addresstype, addressindex, spending_txindex));
// OutPoints are unique, no dedup needed for insert
self.addresstype_to_addressindex_and_unspentoutpoint
.get_mut_unwrap(addresstype)
.insert(AddressIndexOutPoint::from((addressindex, outpoint)), Unit);
}
}
// Now remove all deduplicated addressindex_txindex entries (from both loops)
for (addresstype, addressindex, txindex) in addressindex_txindex_to_remove {
self.addresstype_to_addressindex_and_txindex
.get_mut_unwrap(addresstype)
.remove(AddressIndexTxIndex::from((addressindex, txindex)));
}
} else {
unreachable!();
}
+5
View File
@@ -13,6 +13,11 @@ Drop-in logging initialization that silences noisy dependencies (bitcoin, fjall,
- **Sensible defaults**: Pre-configured filters silence common verbose libraries
- **Timestamp formatting**: Uses system timezone via jiff
## Environment Variables
- `LOG` - Set log level (default: `info` in release, `debug` in dev). Example: `LOG=debug brk`
- `RUST_LOG` - Full control over filtering (overrides all defaults)
## Core API
```rust,ignore
+3 -1
View File
@@ -23,9 +23,11 @@ pub fn init(path: Option<&Path>) -> io::Result<()> {
#[cfg(not(debug_assertions))]
const DEFAULT_LEVEL: &str = "info";
let level = std::env::var("LOG").unwrap_or_else(|_| DEFAULT_LEVEL.to_string());
let filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| {
EnvFilter::new(format!(
"{DEFAULT_LEVEL},bitcoin=off,bitcoincore-rpc=off,fjall=off,brk_fjall=off,lsm_tree=off,brk_rolldown=off,rolldown=off,tracing=off,aide=off,rustls=off,notify=off,oxc_resolver=off,tower_http=off"
"{level},bitcoin=off,bitcoincore-rpc=off,fjall=off,brk_fjall=off,lsm_tree=off,brk_rolldown=off,rolldown=off,tracing=off,aide=off,rustls=off,notify=off,oxc_resolver=off,tower_http=off"
))
});
+1 -1
View File
@@ -43,7 +43,7 @@ impl Inner {
.to_zoned(tz::TimeZone::system())
.strftime("%Y-%m-%d")
.to_string();
self.dir.join(format!("{}.{}", self.prefix, date))
self.dir.join(format!("{}_{}.txt", self.prefix, date))
}
}
+4 -2
View File
@@ -156,6 +156,7 @@ impl Query {
Ok(ResolvedQuery {
vecs,
format: params.format(),
index: params.index,
version,
total,
start,
@@ -170,6 +171,7 @@ impl Query {
let ResolvedQuery {
vecs,
format,
index,
version,
total,
start,
@@ -182,7 +184,7 @@ impl Query {
Format::JSON => {
if vecs.len() == 1 {
let mut buf = Vec::new();
MetricData::serialize(vecs[0], start, end, &mut buf)?;
MetricData::serialize(vecs[0], index, start, end, &mut buf)?;
Output::Json(buf)
} else {
let mut buf = Vec::new();
@@ -191,7 +193,7 @@ impl Query {
if i > 0 {
buf.push(b',');
}
MetricData::serialize(*vec, start, end, &mut buf)?;
MetricData::serialize(*vec, index, start, end, &mut buf)?;
}
buf.push(b']');
Output::Json(buf)
+2 -1
View File
@@ -1,4 +1,4 @@
use brk_types::{Etag, Format};
use brk_types::{Etag, Format, Index};
use vecdb::AnyExportableVec;
/// A resolved metric query ready for formatting.
@@ -6,6 +6,7 @@ use vecdb::AnyExportableVec;
pub struct ResolvedQuery {
pub(crate) vecs: Vec<&'static dyn AnyExportableVec>,
pub(crate) format: Format,
pub(crate) index: Index,
pub(crate) version: u64,
pub(crate) total: usize,
pub(crate) start: usize,
+5 -3
View File
@@ -1,6 +1,7 @@
use std::time::Duration;
use std::{net::SocketAddr, time::Duration};
use axum::{
Extension,
body::Body,
extract::{Query, State},
http::{HeaderMap, StatusCode, Uri},
@@ -11,7 +12,7 @@ use quick_cache::sync::GuardResult;
use crate::{
Result,
api::metrics::{CACHE_CONTROL, MAX_WEIGHT},
api::metrics::{CACHE_CONTROL, max_weight},
extended::HeaderMapExtended,
};
@@ -20,11 +21,12 @@ use super::AppState;
pub async fn handler(
uri: Uri,
headers: HeaderMap,
Extension(addr): Extension<SocketAddr>,
Query(params): Query<MetricSelection>,
State(AppState { query, cache, .. }): State<AppState>,
) -> Result<Response> {
// Phase 1: Search and resolve metadata (cheap)
let resolved = query.run(move |q| q.resolve(params, MAX_WEIGHT)).await?;
let resolved = query.run(move |q| q.resolve(params, max_weight(&addr))).await?;
let format = resolved.format();
let etag = resolved.etag();
+5 -3
View File
@@ -1,6 +1,7 @@
use std::time::Duration;
use std::{net::SocketAddr, time::Duration};
use axum::{
Extension,
body::Body,
extract::{Query, State},
http::{HeaderMap, StatusCode, Uri},
@@ -11,7 +12,7 @@ use quick_cache::sync::GuardResult;
use crate::{
Result,
api::metrics::{CACHE_CONTROL, MAX_WEIGHT},
api::metrics::{CACHE_CONTROL, max_weight},
extended::HeaderMapExtended,
};
@@ -20,11 +21,12 @@ use super::AppState;
pub async fn handler(
uri: Uri,
headers: HeaderMap,
Extension(addr): Extension<SocketAddr>,
Query(params): Query<MetricSelection>,
State(AppState { query, cache, .. }): State<AppState>,
) -> Result<Response> {
// Phase 1: Search and resolve metadata (cheap)
let resolved = query.run(move |q| q.resolve(params, MAX_WEIGHT)).await?;
let resolved = query.run(move |q| q.resolve(params, max_weight(&addr))).await?;
let format = resolved.format();
let etag = resolved.etag();
+5 -3
View File
@@ -1,6 +1,7 @@
use std::time::Duration;
use std::{net::SocketAddr, time::Duration};
use axum::{
Extension,
body::Body,
extract::{Query, State},
http::{HeaderMap, StatusCode, Uri},
@@ -11,7 +12,7 @@ use quick_cache::sync::GuardResult;
use crate::{
Result,
api::metrics::{CACHE_CONTROL, MAX_WEIGHT},
api::metrics::{CACHE_CONTROL, max_weight},
extended::HeaderMapExtended,
};
@@ -20,11 +21,12 @@ use super::AppState;
pub async fn handler(
uri: Uri,
headers: HeaderMap,
Extension(addr): Extension<SocketAddr>,
Query(params): Query<MetricSelection>,
State(AppState { query, cache, .. }): State<AppState>,
) -> Result<Response> {
// Phase 1: Search and resolve metadata (cheap)
let resolved = query.run(move |q| q.resolve(params, MAX_WEIGHT)).await?;
let resolved = query.run(move |q| q.resolve(params, max_weight(&addr))).await?;
let format = resolved.format();
let etag = resolved.etag();
+23 -4
View File
@@ -1,5 +1,8 @@
use std::net::SocketAddr;
use aide::axum::{ApiRouter, routing::get_with};
use axum::{
Extension,
extract::{Path, Query, State},
http::{HeaderMap, Uri},
response::{IntoResponse, Response},
@@ -20,9 +23,21 @@ mod legacy;
/// Maximum allowed request weight in bytes (650KB)
const MAX_WEIGHT: usize = 65 * 10_000;
/// Maximum allowed request weight for localhost (50MB)
const MAX_WEIGHT_LOCALHOST: usize = 50 * 1_000_000;
/// Cache control header for metric data responses
const CACHE_CONTROL: &str = "public, max-age=1, must-revalidate";
/// Returns the max weight for a request based on the client address.
/// Localhost requests get a generous limit, external requests get a stricter one.
fn max_weight(addr: &SocketAddr) -> usize {
if addr.ip().is_loopback() {
MAX_WEIGHT_LOCALHOST
} else {
MAX_WEIGHT
}
}
pub trait ApiMetricsRoutes {
fn add_metrics_routes(self) -> Self;
}
@@ -159,6 +174,7 @@ impl ApiMetricsRoutes for ApiRouter<AppState> {
get_with(
async |uri: Uri,
headers: HeaderMap,
addr: Extension<SocketAddr>,
state: State<AppState>,
Path(path): Path<MetricWithIndex>,
Query(range): Query<DataRangeFormat>|
@@ -166,6 +182,7 @@ impl ApiMetricsRoutes for ApiRouter<AppState> {
data::handler(
uri,
headers,
addr,
Query(MetricSelection::from((path.index, path.metric, range))),
state,
)
@@ -189,8 +206,8 @@ impl ApiMetricsRoutes for ApiRouter<AppState> {
.api_route(
"/api/metrics/bulk",
get_with(
|uri, headers, query, state| async move {
bulk::handler(uri, headers, query, state).await.into_response()
|uri, headers, addr, query, state| async move {
bulk::handler(uri, headers, addr, query, state).await.into_response()
},
|op| op
.id("get_metrics")
@@ -210,6 +227,7 @@ impl ApiMetricsRoutes for ApiRouter<AppState> {
get_with(
async |uri: Uri,
headers: HeaderMap,
addr: Extension<SocketAddr>,
Path(variant): Path<String>,
Query(range): Query<DataRangeFormat>,
state: State<AppState>|
@@ -228,7 +246,7 @@ impl ApiMetricsRoutes for ApiRouter<AppState> {
Metrics::from(split.collect::<Vec<_>>().join(separator)),
range,
));
legacy::handler(uri, headers, Query(params), state)
legacy::handler(uri, headers, addr, Query(params), state)
.await
.into_response()
},
@@ -251,11 +269,12 @@ impl ApiMetricsRoutes for ApiRouter<AppState> {
get_with(
async |uri: Uri,
headers: HeaderMap,
addr: Extension<SocketAddr>,
Query(params): Query<MetricSelectionLegacy>,
state: State<AppState>|
-> Response {
let params: MetricSelection = params.into();
legacy::handler(uri, headers, Query(params), state)
legacy::handler(uri, headers, addr, Query(params), state)
.await
.into_response()
},
+16 -6
View File
@@ -1,6 +1,7 @@
#![doc = include_str!("../README.md")]
use std::{
net::SocketAddr,
path::PathBuf,
sync::Arc,
time::{Duration, Instant},
@@ -8,7 +9,7 @@ use std::{
use aide::axum::ApiRouter;
use axum::{
Extension, ServiceExt,
Extension,
body::Body,
http::{Request, Response, StatusCode, Uri},
middleware::Next,
@@ -24,7 +25,6 @@ use tower_http::{
compression::CompressionLayer, cors::CorsLayer, normalize_path::NormalizePathLayer,
timeout::TimeoutLayer, trace::TraceLayer,
};
use tower_layer::Layer;
use tracing::{error, info};
mod api;
@@ -66,6 +66,16 @@ impl Server {
let compression_layer = CompressionLayer::new().br(true).gzip(true).zstd(true);
let connect_info_layer = axum::middleware::from_fn(
async |connect_info: axum::extract::ConnectInfo<SocketAddr>,
mut request: Request<Body>,
next: Next|
-> Response<Body> {
request.extensions_mut().insert(connect_info.0);
next.run(request).await
},
);
let response_uri_layer = axum::middleware::from_fn(
async |request: Request<Body>, next: Next| -> Response<Body> {
let uri = request.uri().clone();
@@ -114,7 +124,9 @@ impl Server {
StatusCode::GATEWAY_TIMEOUT,
Duration::from_secs(5),
))
.layer(CorsLayer::permissive());
.layer(CorsLayer::permissive())
.layer(connect_info_layer)
.layer(NormalizePathLayer::trim_trailing_slash());
let (listener, port) = match port {
Some(port) => {
@@ -173,11 +185,9 @@ impl Server {
.layer(Extension(Arc::new(openapi)))
.layer(Extension(api_json));
let service = NormalizePathLayer::trim_trailing_slash().layer(router);
serve(
listener,
ServiceExt::<Request<Body>>::into_make_service(service),
router.into_make_service_with_connect_info::<SocketAddr>(),
)
.await?;
+8
View File
@@ -212,6 +212,14 @@ where
}
}
/// Clear all caches. Call after bulk removals (e.g., rollback) to prevent stale reads.
#[inline]
pub fn clear_caches(&mut self) {
for cache in &mut self.caches {
cache.clear();
}
}
#[inline]
pub fn iter(&self) -> impl Iterator<Item = (K, V)> {
self.keyspace
+236
View File
@@ -0,0 +1,236 @@
use std::ops::{Add, AddAssign, Div, Mul, Sub, SubAssign};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use vecdb::{Formattable, Pco};
use super::Dollars;
/// Signed cents (i64) - for values that can be negative.
/// Used for profit/loss calculations, deltas, etc.
#[derive(
Debug,
Default,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Serialize,
Deserialize,
Pco,
JsonSchema,
)]
pub struct CentsSigned(i64);
impl CentsSigned {
pub const ZERO: Self = Self(0);
#[inline]
pub const fn new(value: i64) -> Self {
Self(value)
}
#[inline]
pub const fn inner(self) -> i64 {
self.0
}
#[inline]
pub fn is_negative(self) -> bool {
self.0 < 0
}
#[inline]
pub fn checked_sub(self, rhs: Self) -> Option<Self> {
self.0.checked_sub(rhs.0).map(Self)
}
#[inline]
pub fn checked_add(self, rhs: Self) -> Option<Self> {
self.0.checked_add(rhs.0).map(Self)
}
pub fn to_dollars(self) -> Dollars {
Dollars::from(self.0 as f64 / 100.0)
}
pub fn round_to(self, digits: i32) -> Self {
let v = self.0;
let ilog10 = v.unsigned_abs().checked_ilog10().unwrap_or(0) as i32;
Self::from(if ilog10 >= digits {
let log_diff = ilog10 - digits + 1;
let pow = 10.0_f64.powi(log_diff);
((v as f64 / pow).round() * pow) as i64
} else {
v
})
}
}
impl From<Dollars> for CentsSigned {
#[inline]
fn from(value: Dollars) -> Self {
Self((*value * 100.0).round() as i64)
}
}
impl From<CentsSigned> for Dollars {
#[inline]
fn from(value: CentsSigned) -> Self {
value.to_dollars()
}
}
impl From<CentsSigned> for f64 {
#[inline]
fn from(value: CentsSigned) -> Self {
value.0 as f64
}
}
impl From<i64> for CentsSigned {
#[inline]
fn from(value: i64) -> Self {
Self(value)
}
}
impl From<u64> for CentsSigned {
#[inline]
fn from(value: u64) -> Self {
Self(value as i64)
}
}
impl From<CentsSigned> for usize {
#[inline]
fn from(value: CentsSigned) -> Self {
debug_assert!(value.0 >= 0, "Cannot convert negative CentsSigned to usize");
value.0 as usize
}
}
impl From<usize> for CentsSigned {
#[inline]
fn from(value: usize) -> Self {
Self(value as i64)
}
}
impl From<CentsSigned> for i64 {
#[inline]
fn from(value: CentsSigned) -> Self {
value.0
}
}
impl From<CentsSigned> for u64 {
#[inline]
fn from(value: CentsSigned) -> Self {
debug_assert!(value.0 >= 0, "Cannot convert negative CentsSigned to u64");
value.0 as u64
}
}
impl Add for CentsSigned {
type Output = Self;
#[inline]
fn add(self, rhs: Self) -> Self::Output {
Self(self.0 + rhs.0)
}
}
impl AddAssign for CentsSigned {
#[inline]
fn add_assign(&mut self, rhs: Self) {
self.0 += rhs.0;
}
}
impl Sub for CentsSigned {
type Output = Self;
#[inline]
fn sub(self, rhs: Self) -> Self::Output {
Self(self.0 - rhs.0)
}
}
impl SubAssign for CentsSigned {
#[inline]
fn sub_assign(&mut self, rhs: Self) {
self.0 -= rhs.0;
}
}
impl Div<CentsSigned> for CentsSigned {
type Output = Self;
#[inline]
fn div(self, rhs: Self) -> Self::Output {
Self(self.0 / rhs.0)
}
}
impl Div<usize> for CentsSigned {
type Output = Self;
#[inline]
fn div(self, rhs: usize) -> Self::Output {
Self(self.0 / rhs as i64)
}
}
impl From<u128> for CentsSigned {
#[inline]
fn from(value: u128) -> Self {
debug_assert!(value <= i64::MAX as u128, "u128 overflow to CentsSigned");
Self(value as i64)
}
}
impl From<CentsSigned> for u128 {
#[inline]
fn from(value: CentsSigned) -> Self {
debug_assert!(value.0 >= 0, "Cannot convert negative CentsSigned to u128");
value.0 as u128
}
}
impl Mul<CentsSigned> for CentsSigned {
type Output = CentsSigned;
#[inline]
fn mul(self, rhs: CentsSigned) -> Self::Output {
Self(self.0.checked_mul(rhs.0).expect("CentsSigned overflow"))
}
}
impl Mul<i64> for CentsSigned {
type Output = CentsSigned;
#[inline]
fn mul(self, rhs: i64) -> Self::Output {
Self(self.0 * rhs)
}
}
impl Mul<usize> for CentsSigned {
type Output = CentsSigned;
#[inline]
fn mul(self, rhs: usize) -> Self::Output {
Self(self.0 * rhs as i64)
}
}
impl std::fmt::Display for CentsSigned {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut buf = itoa::Buffer::new();
let str = buf.format(self.0);
f.write_str(str)
}
}
impl Formattable for CentsSigned {
#[inline(always)]
fn may_need_escaping() -> bool {
false
}
}
@@ -0,0 +1,91 @@
use serde::{Deserialize, Serialize};
use super::Dollars;
/// Compact signed cents (i32) - memory-efficient for map keys.
/// Supports prices from -$21,474,836.47 to $21,474,836.47 (i32 range / 100).
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct CentsSignedCompact(i32);
impl CentsSignedCompact {
pub const ZERO: Self = Self(0);
#[inline]
pub const fn new(value: i32) -> Self {
Self(value)
}
#[inline]
pub const fn inner(self) -> i32 {
self.0
}
#[inline]
pub fn is_negative(self) -> bool {
self.0 < 0
}
#[inline]
pub fn to_dollars(self) -> Dollars {
Dollars::from(self.0 as f64 / 100.0)
}
#[inline]
pub fn checked_sub(self, rhs: Self) -> Option<Self> {
self.0.checked_sub(rhs.0).map(Self)
}
}
impl From<Dollars> for CentsSignedCompact {
#[inline]
fn from(value: Dollars) -> Self {
let f = f64::from(value);
if f.is_nan() {
Self::ZERO
} else {
let cents = (f * 100.0).round();
debug_assert!(
cents >= i32::MIN as f64 && cents <= i32::MAX as f64,
"Price ${} exceeds CentsSignedCompact range (~$21.5M)",
f
);
Self(cents as i32)
}
}
}
impl From<CentsSignedCompact> for Dollars {
#[inline]
fn from(value: CentsSignedCompact) -> Self {
value.to_dollars()
}
}
impl From<i32> for CentsSignedCompact {
#[inline]
fn from(value: i32) -> Self {
Self(value)
}
}
impl From<CentsSignedCompact> for i32 {
#[inline]
fn from(value: CentsSignedCompact) -> Self {
value.0
}
}
impl From<CentsSignedCompact> for f64 {
#[inline]
fn from(value: CentsSignedCompact) -> Self {
value.0 as f64
}
}
impl std::fmt::Display for CentsSignedCompact {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut buf = itoa::Buffer::new();
let str = buf.format(self.0);
f.write_str(str)
}
}
+207
View File
@@ -0,0 +1,207 @@
use std::ops::{Add, AddAssign, Div, Mul, Sub, SubAssign};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use vecdb::{Formattable, Pco};
use super::Dollars;
/// Unsigned cents (u64) - for values that should never be negative.
/// Used for invested capital, realized cap, etc.
#[derive(
Debug,
Default,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Serialize,
Deserialize,
Pco,
JsonSchema,
)]
pub struct CentsUnsigned(u64);
impl CentsUnsigned {
pub const ZERO: Self = Self(0);
pub const MAX: Self = Self(u64::MAX);
#[inline]
pub const fn new(value: u64) -> Self {
Self(value)
}
#[inline]
pub const fn inner(self) -> u64 {
self.0
}
#[inline]
pub fn checked_sub(self, rhs: Self) -> Option<Self> {
self.0.checked_sub(rhs.0).map(Self)
}
#[inline]
pub fn saturating_sub(self, rhs: Self) -> Self {
Self(self.0.saturating_sub(rhs.0))
}
#[inline]
pub fn checked_add(self, rhs: Self) -> Option<Self> {
self.0.checked_add(rhs.0).map(Self)
}
pub fn to_dollars(self) -> Dollars {
Dollars::from(self.0 as f64 / 100.0)
}
}
impl From<Dollars> for CentsUnsigned {
#[inline]
fn from(value: Dollars) -> Self {
let f = f64::from(value);
if f.is_nan() || f < 0.0 {
Self::ZERO
} else {
Self((f * 100.0).round() as u64)
}
}
}
impl From<CentsUnsigned> for Dollars {
#[inline]
fn from(value: CentsUnsigned) -> Self {
value.to_dollars()
}
}
impl From<u64> for CentsUnsigned {
#[inline]
fn from(value: u64) -> Self {
Self(value)
}
}
impl From<CentsUnsigned> for u64 {
#[inline]
fn from(value: CentsUnsigned) -> Self {
value.0
}
}
impl From<u128> for CentsUnsigned {
#[inline]
fn from(value: u128) -> Self {
debug_assert!(value <= u64::MAX as u128, "u128 overflow to CentsUnsigned");
Self(value as u64)
}
}
impl From<CentsUnsigned> for u128 {
#[inline]
fn from(value: CentsUnsigned) -> Self {
value.0 as u128
}
}
impl From<CentsUnsigned> for f64 {
#[inline]
fn from(value: CentsUnsigned) -> Self {
value.0 as f64
}
}
impl Add for CentsUnsigned {
type Output = Self;
#[inline]
fn add(self, rhs: Self) -> Self::Output {
Self(self.0 + rhs.0)
}
}
impl AddAssign for CentsUnsigned {
#[inline]
fn add_assign(&mut self, rhs: Self) {
self.0 += rhs.0;
}
}
impl Sub for CentsUnsigned {
type Output = Self;
#[inline]
fn sub(self, rhs: Self) -> Self::Output {
Self(self.0 - rhs.0)
}
}
impl SubAssign for CentsUnsigned {
#[inline]
fn sub_assign(&mut self, rhs: Self) {
self.0 -= rhs.0;
}
}
impl Mul for CentsUnsigned {
type Output = Self;
#[inline]
fn mul(self, rhs: Self) -> Self::Output {
Self(self.0.checked_mul(rhs.0).expect("CentsUnsigned overflow"))
}
}
impl Mul<u64> for CentsUnsigned {
type Output = Self;
#[inline]
fn mul(self, rhs: u64) -> Self::Output {
Self(self.0 * rhs)
}
}
impl Mul<usize> for CentsUnsigned {
type Output = Self;
#[inline]
fn mul(self, rhs: usize) -> Self::Output {
Self(self.0 * rhs as u64)
}
}
impl Div<CentsUnsigned> for CentsUnsigned {
type Output = Self;
#[inline]
fn div(self, rhs: Self) -> Self::Output {
Self(self.0 / rhs.0)
}
}
impl Div<u64> for CentsUnsigned {
type Output = Self;
#[inline]
fn div(self, rhs: u64) -> Self::Output {
Self(self.0 / rhs)
}
}
impl Div<usize> for CentsUnsigned {
type Output = Self;
#[inline]
fn div(self, rhs: usize) -> Self::Output {
Self(self.0 / rhs as u64)
}
}
impl std::fmt::Display for CentsUnsigned {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut buf = itoa::Buffer::new();
let str = buf.format(self.0);
f.write_str(str)
}
}
impl Formattable for CentsUnsigned {
#[inline(always)]
fn may_need_escaping() -> bool {
false
}
}
@@ -0,0 +1,92 @@
use serde::{Deserialize, Serialize};
use super::Dollars;
/// Compact unsigned cents (u32) - memory-efficient for map keys.
/// Supports values from $0.00 to $42,949,672.95 (u32::MAX / 100).
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct CentsUnsignedCompact(u32);
impl CentsUnsignedCompact {
pub const ZERO: Self = Self(0);
pub const MAX: Self = Self(u32::MAX);
#[inline]
pub const fn new(value: u32) -> Self {
Self(value)
}
#[inline]
pub const fn inner(self) -> u32 {
self.0
}
#[inline]
pub fn to_dollars(self) -> Dollars {
Dollars::from(self.0 as f64 / 100.0)
}
#[inline]
pub fn checked_sub(self, rhs: Self) -> Option<Self> {
self.0.checked_sub(rhs.0).map(Self)
}
#[inline]
pub fn saturating_sub(self, rhs: Self) -> Self {
Self(self.0.saturating_sub(rhs.0))
}
}
impl From<Dollars> for CentsUnsignedCompact {
#[inline]
fn from(value: Dollars) -> Self {
let f = f64::from(value);
if f.is_nan() || f < 0.0 {
Self::ZERO
} else {
let cents = (f * 100.0).round();
debug_assert!(
cents <= u32::MAX as f64,
"Price ${} exceeds CentsUnsignedCompact max (~$42.9M)",
f
);
Self(cents as u32)
}
}
}
impl From<CentsUnsignedCompact> for Dollars {
#[inline]
fn from(value: CentsUnsignedCompact) -> Self {
value.to_dollars()
}
}
impl From<u32> for CentsUnsignedCompact {
#[inline]
fn from(value: u32) -> Self {
Self(value)
}
}
impl From<CentsUnsignedCompact> for u32 {
#[inline]
fn from(value: CentsUnsignedCompact) -> Self {
value.0
}
}
impl From<CentsUnsignedCompact> for f64 {
#[inline]
fn from(value: CentsUnsignedCompact) -> Self {
value.0 as f64
}
}
impl std::fmt::Display for CentsUnsignedCompact {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut buf = itoa::Buffer::new();
let str = buf.format(self.0);
f.write_str(str)
}
}
+236 -1
View File
@@ -7,7 +7,7 @@ use vecdb::{Formattable, Pco};
use crate::ONE_DAY_IN_SEC_F64;
use super::{DateIndex, Timestamp};
use super::{DateIndex, DecadeIndex, MonthIndex, QuarterIndex, SemesterIndex, Timestamp, WeekIndex, YearIndex};
/// Date in YYYYMMDD format stored as u32
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Pco, JsonSchema)]
@@ -111,6 +111,72 @@ impl From<DateIndex> for Date {
}
}
impl From<WeekIndex> for Date {
#[inline]
fn from(value: WeekIndex) -> Self {
// Week 0 starts at genesis (2009-01-03), add i weeks
Self::from(
Self::INDEX_ZERO_
.checked_add(Span::new().weeks(i64::from(u16::from(value))))
.unwrap(),
)
}
}
impl From<MonthIndex> for Date {
#[inline]
fn from(value: MonthIndex) -> Self {
// Month 0 is January 2009, add i months
Self::from(
Date_::constant(2009, 1, 1)
.checked_add(Span::new().months(i64::from(u16::from(value))))
.unwrap(),
)
}
}
impl From<YearIndex> for Date {
#[inline]
fn from(value: YearIndex) -> Self {
// Year 0 is 2009
let year = 2009i16 + usize::from(value) as i16;
Self::from(Date_::constant(year, 1, 1))
}
}
impl From<QuarterIndex> for Date {
#[inline]
fn from(value: QuarterIndex) -> Self {
// Quarter 0 is Q1 2009, add i*3 months
Self::from(
Date_::constant(2009, 1, 1)
.checked_add(Span::new().months(usize::from(value) as i64 * 3))
.unwrap(),
)
}
}
impl From<SemesterIndex> for Date {
#[inline]
fn from(value: SemesterIndex) -> Self {
// Semester 0 is H1 2009, add i*6 months
Self::from(
Date_::constant(2009, 1, 1)
.checked_add(Span::new().months(usize::from(value) as i64 * 6))
.unwrap(),
)
}
}
impl From<DecadeIndex> for Date {
#[inline]
fn from(value: DecadeIndex) -> Self {
// Decade 0 is 2009, add i*10 years
let year = 2009i16 + usize::from(value) as i16 * 10;
Self::from(Date_::constant(year, 1, 1))
}
}
impl Serialize for Date {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@@ -190,3 +256,172 @@ impl Formattable for Date {
false
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_date_from_dateindex_zero() {
// DateIndex 0 is genesis: Jan 3, 2009
let date = Date::from(DateIndex::from(0_usize));
assert_eq!(date, Date::INDEX_ZERO);
assert_eq!(date.year(), 2009);
assert_eq!(date.month(), 1);
assert_eq!(date.day(), 3);
}
#[test]
fn test_date_from_dateindex_one() {
// DateIndex 1 is Jan 9, 2009 (6 day gap after genesis)
let date = Date::from(DateIndex::from(1_usize));
assert_eq!(date, Date::INDEX_ONE);
assert_eq!(date.year(), 2009);
assert_eq!(date.month(), 1);
assert_eq!(date.day(), 9);
}
#[test]
fn test_date_from_dateindex_two() {
// DateIndex 2 is Jan 10, 2009
let date = Date::from(DateIndex::from(2_usize));
assert_eq!(date.year(), 2009);
assert_eq!(date.month(), 1);
assert_eq!(date.day(), 10);
}
#[test]
fn test_date_from_weekindex_zero() {
// WeekIndex 0 starts at genesis: Jan 3, 2009
let date = Date::from(WeekIndex::from(0_usize));
assert_eq!(date.year(), 2009);
assert_eq!(date.month(), 1);
assert_eq!(date.day(), 3);
}
#[test]
fn test_date_from_weekindex_one() {
// WeekIndex 1 is Jan 10, 2009 (one week after genesis)
let date = Date::from(WeekIndex::from(1_usize));
assert_eq!(date.year(), 2009);
assert_eq!(date.month(), 1);
assert_eq!(date.day(), 10);
}
#[test]
fn test_date_from_monthindex_zero() {
// MonthIndex 0 is Jan 1, 2009
let date = Date::from(MonthIndex::from(0_usize));
assert_eq!(date.year(), 2009);
assert_eq!(date.month(), 1);
assert_eq!(date.day(), 1);
}
#[test]
fn test_date_from_monthindex_one() {
// MonthIndex 1 is Feb 1, 2009
let date = Date::from(MonthIndex::from(1_usize));
assert_eq!(date.year(), 2009);
assert_eq!(date.month(), 2);
assert_eq!(date.day(), 1);
}
#[test]
fn test_date_from_monthindex_twelve() {
// MonthIndex 12 is Jan 1, 2010
let date = Date::from(MonthIndex::from(12_usize));
assert_eq!(date.year(), 2010);
assert_eq!(date.month(), 1);
assert_eq!(date.day(), 1);
}
#[test]
fn test_date_from_yearindex_zero() {
// YearIndex 0 is Jan 1, 2009
let date = Date::from(YearIndex::from(0_usize));
assert_eq!(date.year(), 2009);
assert_eq!(date.month(), 1);
assert_eq!(date.day(), 1);
}
#[test]
fn test_date_from_yearindex_one() {
// YearIndex 1 is Jan 1, 2010
let date = Date::from(YearIndex::from(1_usize));
assert_eq!(date.year(), 2010);
assert_eq!(date.month(), 1);
assert_eq!(date.day(), 1);
}
#[test]
fn test_date_from_quarterindex_zero() {
// QuarterIndex 0 is Q1 2009: Jan 1, 2009
let date = Date::from(QuarterIndex::from(0_usize));
assert_eq!(date.year(), 2009);
assert_eq!(date.month(), 1);
assert_eq!(date.day(), 1);
}
#[test]
fn test_date_from_quarterindex_one() {
// QuarterIndex 1 is Q2 2009: Apr 1, 2009
let date = Date::from(QuarterIndex::from(1_usize));
assert_eq!(date.year(), 2009);
assert_eq!(date.month(), 4);
assert_eq!(date.day(), 1);
}
#[test]
fn test_date_from_quarterindex_four() {
// QuarterIndex 4 is Q1 2010: Jan 1, 2010
let date = Date::from(QuarterIndex::from(4_usize));
assert_eq!(date.year(), 2010);
assert_eq!(date.month(), 1);
assert_eq!(date.day(), 1);
}
#[test]
fn test_date_from_semesterindex_zero() {
// SemesterIndex 0 is H1 2009: Jan 1, 2009
let date = Date::from(SemesterIndex::from(0_usize));
assert_eq!(date.year(), 2009);
assert_eq!(date.month(), 1);
assert_eq!(date.day(), 1);
}
#[test]
fn test_date_from_semesterindex_one() {
// SemesterIndex 1 is H2 2009: Jul 1, 2009
let date = Date::from(SemesterIndex::from(1_usize));
assert_eq!(date.year(), 2009);
assert_eq!(date.month(), 7);
assert_eq!(date.day(), 1);
}
#[test]
fn test_date_from_semesterindex_two() {
// SemesterIndex 2 is H1 2010: Jan 1, 2010
let date = Date::from(SemesterIndex::from(2_usize));
assert_eq!(date.year(), 2010);
assert_eq!(date.month(), 1);
assert_eq!(date.day(), 1);
}
#[test]
fn test_date_from_decadeindex_zero() {
// DecadeIndex 0 is 2009: Jan 1, 2009
let date = Date::from(DecadeIndex::from(0_usize));
assert_eq!(date.year(), 2009);
assert_eq!(date.month(), 1);
assert_eq!(date.day(), 1);
}
#[test]
fn test_date_from_decadeindex_one() {
// DecadeIndex 1 is 2019: Jan 1, 2019
let date = Date::from(DecadeIndex::from(1_usize));
assert_eq!(date.year(), 2019);
assert_eq!(date.month(), 1);
assert_eq!(date.day(), 1);
}
}
+138 -1
View File
@@ -8,7 +8,7 @@ use vecdb::PrintableIndex;
use crate::PairOutputIndex;
use super::{
DateIndex, DecadeIndex, DifficultyEpoch, EmptyAddressIndex, EmptyOutputIndex, HalvingEpoch,
Date, DateIndex, DecadeIndex, DifficultyEpoch, EmptyAddressIndex, EmptyOutputIndex, HalvingEpoch,
Height, LoadedAddressIndex, MonthIndex, OpReturnIndex, P2AAddressIndex, P2MSOutputIndex,
P2PK33AddressIndex, P2PK65AddressIndex, P2PKHAddressIndex, P2SHAddressIndex, P2TRAddressIndex,
P2WPKHAddressIndex, P2WSHAddressIndex, QuarterIndex, SemesterIndex, TxInIndex, TxIndex,
@@ -144,6 +144,35 @@ impl Index {
_ => 1,
}
}
/// Returns true if this index type is date-based.
pub const fn is_date_based(&self) -> bool {
matches!(
self,
Self::DateIndex
| Self::WeekIndex
| Self::MonthIndex
| Self::YearIndex
| Self::QuarterIndex
| Self::SemesterIndex
| Self::DecadeIndex
)
}
/// Convert an index value to a date for date-based indexes.
/// Returns None for non-date-based indexes.
pub fn index_to_date(&self, i: usize) -> Option<Date> {
match self {
Self::DateIndex => Some(Date::from(DateIndex::from(i))),
Self::WeekIndex => Some(Date::from(WeekIndex::from(i))),
Self::MonthIndex => Some(Date::from(MonthIndex::from(i))),
Self::YearIndex => Some(Date::from(YearIndex::from(i))),
Self::QuarterIndex => Some(Date::from(QuarterIndex::from(i))),
Self::SemesterIndex => Some(Date::from(SemesterIndex::from(i))),
Self::DecadeIndex => Some(Date::from(DecadeIndex::from(i))),
_ => None,
}
}
}
impl TryFrom<&str> for Index {
@@ -219,3 +248,111 @@ impl<'de> Deserialize<'de> for Index {
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_is_date_based_dateindex() {
assert!(Index::DateIndex.is_date_based());
}
#[test]
fn test_is_date_based_weekindex() {
assert!(Index::WeekIndex.is_date_based());
}
#[test]
fn test_is_date_based_monthindex() {
assert!(Index::MonthIndex.is_date_based());
}
#[test]
fn test_is_date_based_yearindex() {
assert!(Index::YearIndex.is_date_based());
}
#[test]
fn test_is_date_based_quarterindex() {
assert!(Index::QuarterIndex.is_date_based());
}
#[test]
fn test_is_date_based_semesterindex() {
assert!(Index::SemesterIndex.is_date_based());
}
#[test]
fn test_is_date_based_decadeindex() {
assert!(Index::DecadeIndex.is_date_based());
}
#[test]
fn test_is_not_date_based_height() {
assert!(!Index::Height.is_date_based());
}
#[test]
fn test_is_not_date_based_txindex() {
assert!(!Index::TxIndex.is_date_based());
}
#[test]
fn test_index_to_date_dateindex_zero() {
let date = Index::DateIndex.index_to_date(0).unwrap();
assert_eq!(date, Date::from(DateIndex::from(0_usize)));
}
#[test]
fn test_index_to_date_dateindex_one() {
let date = Index::DateIndex.index_to_date(1).unwrap();
assert_eq!(date, Date::from(DateIndex::from(1_usize)));
}
#[test]
fn test_index_to_date_weekindex() {
let date = Index::WeekIndex.index_to_date(1).unwrap();
assert_eq!(date, Date::from(WeekIndex::from(1_usize)));
}
#[test]
fn test_index_to_date_monthindex() {
let date = Index::MonthIndex.index_to_date(12).unwrap();
assert_eq!(date, Date::from(MonthIndex::from(12_usize)));
}
#[test]
fn test_index_to_date_yearindex() {
let date = Index::YearIndex.index_to_date(5).unwrap();
assert_eq!(date, Date::from(YearIndex::from(5_usize)));
}
#[test]
fn test_index_to_date_quarterindex() {
let date = Index::QuarterIndex.index_to_date(4).unwrap();
assert_eq!(date, Date::from(QuarterIndex::from(4_usize)));
}
#[test]
fn test_index_to_date_semesterindex() {
let date = Index::SemesterIndex.index_to_date(2).unwrap();
assert_eq!(date, Date::from(SemesterIndex::from(2_usize)));
}
#[test]
fn test_index_to_date_decadeindex() {
let date = Index::DecadeIndex.index_to_date(1).unwrap();
assert_eq!(date, Date::from(DecadeIndex::from(1_usize)));
}
#[test]
fn test_index_to_date_height_returns_none() {
assert!(Index::Height.index_to_date(100).is_none());
}
#[test]
fn test_index_to_date_txindex_returns_none() {
assert!(Index::TxIndex.index_to_date(100).is_none());
}
}
+8
View File
@@ -37,6 +37,10 @@ mod blockweightentry;
mod bytes;
mod cents;
mod centscompact;
mod cents_signed;
mod cents_signed_compact;
mod cents_unsigned;
mod cents_unsigned_compact;
mod datarange;
mod datarangeformat;
mod date;
@@ -209,6 +213,10 @@ pub use blockweightentry::*;
pub use bytes::*;
pub use cents::*;
pub use centscompact::*;
pub use cents_signed::*;
pub use cents_signed_compact::*;
pub use cents_unsigned::*;
pub use cents_unsigned_compact::*;
pub use datarange::*;
pub use datarangeformat::*;
pub use date::*;
+159 -3
View File
@@ -5,7 +5,7 @@ use serde::Deserialize;
use serde_json::Value;
use vecdb::AnySerializableVec;
use super::Timestamp;
use super::{Index, Timestamp};
/// Metric data with range information.
///
@@ -15,6 +15,8 @@ use super::Timestamp;
pub struct MetricData<T = Value> {
/// Version of the metric data
pub version: u64,
/// The index type used for this query
pub index: Index,
/// Total number of data points in the metric
pub total: usize,
/// Start index (inclusive) of the returned range
@@ -28,14 +30,16 @@ pub struct MetricData<T = Value> {
}
impl MetricData {
/// Write metric data as JSON to buffer: `{"version":N,"total":N,"start":N,"end":N,"stamp":"...","data":[...]}`
/// Write metric data as JSON to buffer: `{"version":N,"index":"...","total":N,"start":N,"end":N,"stamp":"...","data":[...]}`
pub fn serialize(
vec: &dyn AnySerializableVec,
index: Index,
start: usize,
end: usize,
buf: &mut Vec<u8>,
) -> vecdb::Result<()> {
let version = u64::from(vec.version());
let index_str = index.serialize_long();
let total = vec.len();
let end = end.min(total);
let start = start.min(end);
@@ -43,10 +47,162 @@ impl MetricData {
write!(
buf,
r#"{{"version":{version},"total":{total},"start":{start},"end":{end},"stamp":"{stamp}","data":"#,
r#"{{"version":{version},"index":"{index_str}","total":{total},"start":{start},"end":{end},"stamp":"{stamp}","data":"#,
)?;
vec.write_json(Some(start), Some(end), buf)?;
buf.push(b'}');
Ok(())
}
}
impl<T> MetricData<T> {
/// Returns an iterator over the index range.
pub fn indexes(&self) -> std::ops::Range<usize> {
self.start..self.end
}
/// Returns true if this metric uses a date-based index.
pub fn is_date_based(&self) -> bool {
self.index.is_date_based()
}
/// Returns an iterator over dates for the index range.
/// Panics if the index is not date-based.
pub fn dates(&self) -> impl Iterator<Item = super::Date> + '_ {
let index = self.index;
self.indexes().map(move |i| {
index
.index_to_date(i)
.expect("dates() called on non-date-based index")
})
}
/// Iterate over (index, &value) pairs.
pub fn iter(&self) -> impl Iterator<Item = (usize, &T)> {
self.indexes().zip(self.data.iter())
}
/// Iterate over (date, &value) pairs.
/// Panics if the index is not date-based.
pub fn iter_dates(&self) -> impl Iterator<Item = (super::Date, &T)> + '_ {
self.dates().zip(self.data.iter())
}
}
#[cfg(test)]
mod tests {
use super::*;
fn date_based_metric() -> MetricData<i32> {
MetricData {
version: 1,
index: Index::DateIndex,
total: 100,
start: 0,
end: 5,
stamp: "2024-01-01T00:00:00Z".to_string(),
data: vec![100, 200, 300, 400, 500],
}
}
fn height_based_metric() -> MetricData<f64> {
MetricData {
version: 1,
index: Index::Height,
total: 1000,
start: 800000,
end: 800005,
stamp: "2024-01-01T00:00:00Z".to_string(),
data: vec![1.5, 2.5, 3.5, 4.5, 5.5],
}
}
#[test]
fn test_indexes_returns_range() {
let metric = date_based_metric();
let indexes: Vec<_> = metric.indexes().collect();
assert_eq!(indexes, vec![0, 1, 2, 3, 4]);
}
#[test]
fn test_indexes_with_offset() {
let metric = height_based_metric();
let indexes: Vec<_> = metric.indexes().collect();
assert_eq!(indexes, vec![800000, 800001, 800002, 800003, 800004]);
}
#[test]
fn test_is_date_based_true() {
let metric = date_based_metric();
assert!(metric.is_date_based());
}
#[test]
fn test_is_date_based_false() {
let metric = height_based_metric();
assert!(!metric.is_date_based());
}
#[test]
fn test_dates_for_dateindex() {
let metric = date_based_metric();
let dates: Vec<_> = metric.dates().collect();
assert_eq!(dates.len(), 5);
// DateIndex 0 = Jan 3, 2009 (genesis)
assert_eq!(dates[0].year(), 2009);
assert_eq!(dates[0].month(), 1);
assert_eq!(dates[0].day(), 3);
// DateIndex 1 = Jan 9, 2009 (day one)
assert_eq!(dates[1].year(), 2009);
assert_eq!(dates[1].month(), 1);
assert_eq!(dates[1].day(), 9);
}
#[test]
fn test_iter() {
let metric = date_based_metric();
let pairs: Vec<_> = metric.iter().collect();
assert_eq!(pairs.len(), 5);
assert_eq!(pairs[0], (0, &100));
assert_eq!(pairs[1], (1, &200));
assert_eq!(pairs[4], (4, &500));
}
#[test]
fn test_iter_with_offset() {
let metric = height_based_metric();
let pairs: Vec<_> = metric.iter().collect();
assert_eq!(pairs.len(), 5);
assert_eq!(pairs[0], (800000, &1.5));
assert_eq!(pairs[4], (800004, &5.5));
}
#[test]
fn test_iter_dates() {
let metric = date_based_metric();
let pairs: Vec<_> = metric.iter_dates().collect();
assert_eq!(pairs.len(), 5);
// First pair: (Jan 3 2009, 100)
assert_eq!(pairs[0].0.year(), 2009);
assert_eq!(pairs[0].0.month(), 1);
assert_eq!(pairs[0].0.day(), 3);
assert_eq!(pairs[0].1, &100);
// Second pair: (Jan 9 2009, 200)
assert_eq!(pairs[1].0.day(), 9);
assert_eq!(pairs[1].1, &200);
}
#[test]
#[should_panic(expected = "dates() called on non-date-based index")]
fn test_dates_panics_for_non_date_index() {
let metric = height_based_metric();
let _: Vec<_> = metric.dates().collect();
}
#[test]
#[should_panic(expected = "dates() called on non-date-based index")]
fn test_iter_dates_panics_for_non_date_index() {
let metric = height_based_metric();
let _: Vec<_> = metric.iter_dates().collect();
}
}
+6 -2
View File
@@ -23,13 +23,17 @@ fn serve(website: &Website, path: &str) -> Result<Response<Body>> {
let headers = response.headers_mut();
// Empty path or no extension = index.html (SPA fallback)
if path.is_empty() || Path::new(&path).extension().is_none() {
let is_html = path.is_empty()
|| Path::new(&path).extension().is_none()
|| path.ends_with(".html");
if is_html {
headers.insert_content_type_text_html();
} else {
headers.insert_content_type(Path::new(&path));
}
if cfg!(debug_assertions) {
if cfg!(debug_assertions) || is_html {
headers.insert_cache_control_must_revalidate();
} else {
headers.insert_cache_control_immutable();
+427
View File
@@ -4,6 +4,433 @@ All notable changes to the Bitcoin Research Kit (BRK) project will be documented
> *This changelog was generated by Claude Code*
## [v0.1.1](https://github.com/bitcoinresearchkit/brk/releases/tag/v0.1.1) - 2026-01-27
### Bug Fixes
#### `brk_website`
- Fixed HTML file caching rules to properly detect `.html` files and apply `must-revalidate` cache policy instead of immutable caching ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.1/crates/brk_website/src/handlers.rs))
#### `brk_client`
- Fixed metric name mappings in `ClassDaysInLossPattern` (changed from `max_drawdown` to `days_in_profit`)
- Regenerated client code with corrected metric patterns
### Internal Changes
#### `scripts`
- Split release scripts into separate components for better modularity
[View changes](https://github.com/bitcoinresearchkit/brk/compare/v0.1.0...v0.1.1)
## [v0.1.0](https://github.com/bitcoinresearchkit/brk/releases/tag/v0.1.0) - 2026-01-27
### New Features
#### `brk_computer`
- Added sats-denominated versions of all price metrics alongside USD versions ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0/crates/brk_computer/src/internal/multi/from_date/price.rs))
- New `Price` wrapper struct provides both `.dollars` and `.sats` representations
- Derefs to dollars for backward compatibility with existing code
- Sats values computed via `DollarsToSatsFract` transform
- Added address activity tracking metrics ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0/crates/brk_computer/src/distribution/address/activity.rs))
- `receiving` - Unique addresses that received funds in each block
- `sending` - Unique addresses that sent funds in each block
- `reactivated` - Addresses that were empty and now have funds
- `both` - Addresses that both sent AND received in same block
- `balance_increased` - Receive-only addresses
- `balance_decreased` - Send-only addresses
- Available globally and per address type (P2PKH, P2SH, P2WPKH, etc.)
- Added address growth rate metrics ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0/crates/brk_computer/src/distribution/address/growth_rate.rs))
- Computes `new_addr_count / total_addr_count` ratio globally and per type
- Includes distribution statistics (min, max, average, percentiles)
- Added new address count metrics per block
- Added total address count tracking
- Added `RatioU64F32` transform for u64 to f32 ratio calculations
- Added `U64Plus` transform for u64 addition operations
- Added price-aware multi modules: `lazy_binary_price`, `lazy_price`, `unary_last`
- Added height-based distribution and price modules
[View changes](https://github.com/bitcoinresearchkit/brk/compare/v0.1.0-beta.1...v0.1.0)
## [v0.1.0-beta.1](https://github.com/bitcoinresearchkit/brk/releases/tag/v0.1.0-beta.1) - 2026-01-26
### New Features
#### `brk_types`
- Added `SatsFract` type for fractional satoshi representation ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-beta.1/crates/brk_types/src/satsfract.rs))
- Stores f64 values representing sub-satoshi amounts
- Useful for expressing USD prices in sats when price is high (e.g., at $100k, $0.0001 = 0.1 sats)
- Includes arithmetic operations and NaN handling
#### `brk_computer`
- Added `DollarsToSatsFract` transform for converting USD prices to sats exchange rate ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-beta.1/crates/brk_computer/src/internal/single/transform/dollars_to_sats_fract.rs))
- Added `CloseDollarsToSatsFract` variant for close price conversion
#### `website`
- Added more investing data and charts
### Internal Changes
#### `scripts`
- Updated release workflow scripts
[View changes](https://github.com/bitcoinresearchkit/brk/compare/v0.1.0-beta.0...v0.1.0-beta.1)
## [v0.1.0-beta.0](https://github.com/bitcoinresearchkit/brk/releases/tag/v0.1.0-beta.0) - 2026-01-25
### Breaking Changes
#### `brk_mcp`
- Removed `brk_mcp` crate from workspace (MCP server functionality removed)
### New Features
#### `brk_computer`
- Added Reserve Risk metric to cointime module ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-beta.0/crates/brk_computer/src/cointime/reserve_risk/mod.rs))
- Computes VOCDD 365-day SMA (Value-weighted Outstanding Coin Days Destroyed)
- Calculates HODL Bank accumulation metric
- Derives Reserve Risk indicator for market cycle analysis
- Added `return_i8` transform for small integer returns
#### `brk_website` (New Crate)
- Created standalone website serving crate without BRK data layer dependencies ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-beta.0/crates/brk_website/src/lib.rs))
- Supports both embedded website and filesystem path serving
- Provides `router()` function for Axum integration
- Added example demonstrating standalone server usage
#### `brk_playground` (New Standalone Crate)
- Created experimental playground crate for on-chain price analysis (not published to crates.io) ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-beta.0/crates/brk_playground/src/lib.rs))
- Implements phase histogram analysis of UTXO patterns
- Provides filter-based output selection for price signal extraction
- Includes on-chain OHLC price oracle derivation with confidence metrics
- Features anchor-based price calibration using weekly OHLC data
#### `brk_logger`
- Added log hook system for custom log message handling ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-beta.0/crates/brk_logger/src/hook.rs))
- Added rate-limited file writer (100 writes/second max) to prevent log flooding ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-beta.0/crates/brk_logger/src/rate_limit.rs))
- Added custom log format module
#### `brk_client`
- Added `fetch_prices.rs` example demonstrating price data fetching
#### `brk_types`
- Added `StoredI8` type for signed 8-bit integer storage
#### `brk_server`
- Added Scalar API documentation JavaScript
### Internal Changes
#### `brk_computer`
- Refactored vecs.rs files to remove verbose comments
- Reduced verbosity and switched to vecdb cumulative function for cleaner code
#### `website`
- Replaced uFuzzy search library with quickmatch for better performance
- Major cleanup and refactoring of frontend code
#### `scripts`
- Updated release scripts with improved workflow
[View changes](https://github.com/bitcoinresearchkit/brk/compare/v0.1.0-alpha.6...v0.1.0-beta.0)
## [v0.1.0-alpha.6](https://github.com/bitcoinresearchkit/brk/releases/tag/v0.1.0-alpha.6) - 2026-01-18
### Bug Fixes
#### `brk_client`
- Fixed minreq HTTP client feature flag: changed from `serde_json` to `json-using-serde` for proper JSON serialization support
- Regenerated client code with corrected HTTP handling
#### `scripts`
- Added full workspace compilation check to release script to catch feature flag errors before publishing
[View changes](https://github.com/bitcoinresearchkit/brk/compare/v0.1.0-alpha.5...v0.1.0-alpha.6)
## [v0.1.0-alpha.5](https://github.com/bitcoinresearchkit/brk/releases/tag/v0.1.0-alpha.5) - 2026-01-17
### Bug Fixes
#### `brk_query`
- Fixed `tokio` feature flag to properly propagate to `brk_error` dependency, enabling async error handling when tokio feature is enabled
[View changes](https://github.com/bitcoinresearchkit/brk/compare/v0.1.0-alpha.4...v0.1.0-alpha.5)
## [v0.1.0-alpha.4](https://github.com/bitcoinresearchkit/brk/releases/tag/v0.1.0-alpha.4) - 2026-01-17
### New Features
#### `brk_computer`
- Implemented Phase Oracle V2 algorithm using round USD template cross-correlation for on-chain price discovery ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.4/crates/brk_computer/src/price/oracle/phase_v2.rs))
- Uses 200-bin phase histogram with weighted round USD template ($1, $5, $10, $20, etc.)
- Weekly OHLC anchors constrain search range for accuracy
- Cross-correlates satoshi values with expected USD fingerprint patterns
- Added `cents_to_dollars` transform for price conversions ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.4/crates/brk_computer/src/internal/single/transform/cents_to_dollars.rs))
#### `brk_query`
- Added `ResolvedQuery` struct for efficient metric query resolution with ETag generation ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.4/crates/brk_query/src/resolved.rs))
- Two-phase query processing: resolve metadata (cheap) then format output (expensive, cached)
#### `brk_server`
- Added bulk metrics API endpoint with ETag-based caching and 304 Not Modified support ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.4/crates/brk_server/src/api/metrics/bulk.rs))
- Implemented `CacheStrategy` module with Height, Static, and MaxAge caching strategies ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.4/crates/brk_server/src/cache.rs))
- Added compact OpenAPI spec generator optimized for LLM consumption ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.4/crates/brk_server/src/api/openapi/compact.rs))
- Removes redundant fields (error responses, descriptions, examples)
- Simplifies schemas and flattens allOf/anyOf constructs
- Compacts responses to "returns": "Type" format
- Added dedicated error handling module
- Added website file serving module with symlink to website directory
#### `brk_types`
- Added `Etag` type for HTTP ETag header handling ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.4/crates/brk_types/src/etag.rs))
- Added `Output` enum for JSON and CSV metric output formats ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.4/crates/brk_types/src/output.rs))
- Added `MetricOutput` struct wrapping output with metadata for ETag generation ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.4/crates/brk_types/src/metricoutput.rs))
- Added `OracleBins` type for 100-bin phase histogram storage used in price discovery ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.4/crates/brk_types/src/oracle_bins.rs))
- Added `PairOutputIndex` for indexing 2-output transactions (oracle pair candidates) ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.4/crates/brk_types/src/pairoutputindex.rs))
- Added `Port` type with default server port 3110 ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.4/crates/brk_types/src/port.rs))
#### `brk_fetcher`
- Added fetcher example demonstrating price data fetching
### Internal Changes
#### `brk_server`
- Reorganized OpenAPI generation into dedicated `openapi/` module
- Added Scalar API documentation HTML template
#### `modules/brk-client`
- Regenerated documentation with new types (OracleBins, PairOutputIndex, SyncStatus)
- Added README with usage examples
#### `packages/brk_client`
- Regenerated documentation and updated README
[View changes](https://github.com/bitcoinresearchkit/brk/compare/v0.1.0-alpha.3...v0.1.0-alpha.4)
## [v0.1.0-alpha.3](https://github.com/bitcoinresearchkit/brk/releases/tag/v0.1.0-alpha.3) - 2026-01-14
### Breaking Changes
#### `brk_bundler`
- Removed `brk_bundler` crate from workspace (JavaScript bundling functionality removed)
### New Features
#### `brk_computer`
- Implemented UTXOracle trustless on-chain price discovery algorithm that derives Bitcoin prices from transaction data without external price feeds ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.3/crates/brk_computer/src/price/oracle/mod.rs))
- Detects round USD amounts ($10, $20, $50, $100, etc.) in transaction outputs
- Uses histogram-based stencil matching with Gaussian smoothing
- Refines prices via geometric median convergence
- Filters "clean" transactions: 2 outputs, ≤5 inputs, no OP_RETURN, simple signatures
- Added `price/cents/` module for cent-based price storage with split components ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.3/crates/brk_computer/src/price/cents/mod.rs))
- Created dedicated index modules for time-based metric aggregation:
- `indexes/dateindex.rs` - Daily index with date, first_height, height_count, weekindex, monthindex mappings
- `indexes/weekindex.rs` - Weekly aggregation
- `indexes/monthindex.rs` - Monthly aggregation
- `indexes/quarterindex.rs` - Quarterly aggregation
- `indexes/semesterindex.rs` - Semester (half-year) aggregation
- `indexes/yearindex.rs` - Yearly aggregation
- `indexes/decadeindex.rs` - Decade aggregation
- `indexes/halvingepoch.rs` - Halving epoch indexing
- `indexes/difficultyepoch.rs` - Difficulty adjustment epoch indexing
- `indexes/height.rs` - Block height indexing
- `indexes/txindex.rs`, `txinindex.rs`, `txoutindex.rs` - Transaction-level indexing
- `indexes/address.rs` - Address type indexing with vecs for all output types (P2PK33, P2PK65, P2PKH, P2SH, P2TR, P2WPKH, P2WSH, P2A, P2MS, empty, unknown, OP_RETURN)
- Added comprehensive `internal/multi/` module with 100+ metric aggregation strategies ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.3/crates/brk_computer/src/internal/multi/mod.rs)):
- `from_height/` - Height-based metric derivation with lazy, binary, and value variants
- `from_date/` - Date-based aggregation with percentiles, ratios, statistics
- `from_height_and_date/` - Combined height+date metrics including OHLC
- `from_tx/` - Transaction-level distributions
- `height_derived/` - Height-to-higher-index derivations
- `date_derived/` - Date-to-higher-index derivations (average, first, last, min, max, spread, sum)
- `tx_derived/` - Transaction-derived distributions
- `height_and_date/` - Combined aggregations for OHLC and bytes
- Added `internal/single/` module with specialized metric computations ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.3/crates/brk_computer/src/internal/single/mod.rs)):
- `transform/` - 35+ value transformations (price conversions, ratios, percentages, RSI, volatility)
- `lazy/` - Lazy evaluation for sum, average, cumulative, first, last, min, max, spread
- `lazy_transform/` - Lazy binary operations with percentiles and statistics
- `vec/` - Vector-based aggregations (percentiles, sum, average)
- `group/` - Group statistics (min/max, average, percentiles, distribution)
- `height/` - Height-indexed value derivations
- `tx/` - Transaction-level distributions
- `difficultyepoch/` - Difficulty epoch lazy values
- Added `internal/compute.rs` for unified computation orchestration
- Added `internal/traits.rs` for shared metric computation traits
- Added `distribution/metrics/outputs.rs` for output-specific distribution metrics
#### `brk_client`
- Added `basic.rs` example demonstrating typed metrics API with method chaining ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.3/crates/brk_client/examples/basic.rs))
- Added `tree.rs` example for navigating the metrics tree structure
#### `brk_fetcher`
- Implemented retry mechanism for network requests with exponential backoff ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.3/crates/brk_fetcher/src/retry.rs))
- Added permanent network error detection to skip retries for blocked endpoints
#### `brk_indexer`
- Added `vecs/addresses.rs` for address-specific vector storage
- Added `vecs/inputs.rs` for input vector organization
- Added `vecs/outputs.rs` for output vector organization
- Added `vecs/transactions.rs` for transaction vector organization
- Added `vecs/scripts.rs` for script vector organization
#### `brk_types`
- Added `DiskUsage` type for tracking storage consumption per component ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.3/crates/brk_types/src/diskusage.rs))
- Added `FormatResponse` type for API response formatting ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.3/crates/brk_types/src/formatresponse.rs))
- Added `SyncStatus` type for indexer synchronization status ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.3/crates/brk_types/src/syncstatus.rs))
#### `brk_bindgen`
- Added `generate/constants.rs` for constant generation
- Added `generate/tree.rs` for tree structure generation
- Added catalog test suite ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.3/crates/brk_bindgen/tests/catalog_test.rs))
#### `brk_server`
- Added `/api/server/sync` endpoint returning `SyncStatus` with indexed_height, tip_height, blocks_behind, and last indexed timestamp ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.3/crates/brk_server/src/api/server/mod.rs))
- Added `/api/server/disk` endpoint returning `DiskUsage` with storage consumption per component
- Added `/api/server/health` endpoint for health checks
#### `brk_store`
- Added `any.rs` for type-erased store access
#### `modules/brk-client`
- Generated comprehensive TypeScript-style documentation with 300+ interface and type definitions
- Added test suites: `basic.js` and `tree.js`
- Added CLAUDE.md with development instructions
#### `packages/brk_client`
- Added Python documentation generation with pydoc-markdown
- Added DOCS.md with generated API documentation
- Added test suites: `test_basic.py`, `test_tree.py`
#### `website`
- Restructured from `websites/bitview/` to unified `website/` directory
- Added Progressive Web App (PWA) support with manifest and service worker ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.3/website/manifest.webmanifest))
- Added 40+ Apple splash screen images for iOS home screen support
- Added search pane (`panes/search.js`) and navigation pane (`panes/nav.js`)
- Added units utility (`utils/units.js`) for value formatting
- Reorganized options system with dedicated modules for chain, cohorts, cointime, market, and series configuration
#### `scripts`
- Added `js-docs.sh` for JavaScript documentation generation
- Added `js-publish.sh` for JavaScript package publishing
- Added `python-docs.sh` for Python documentation generation
- Added `python-publish.sh` for Python package publishing to PyPI
- Added `rust-publish.sh` for Rust crate publishing
- Added `release.sh` for coordinated multi-language releases
### Internal Changes
#### `workspace`
- Added build.rs scripts to all crates for consistent build configuration
- Shortened percentiles path in metric tree for cleaner API
#### `brk_computer`
- Reorganized traits into dedicated `traits/` module with `pricing.rs`
- Removed specialized percentiles, ratio, stddev modules from `internal/specialized/`
#### `brk_logger`
- Added example demonstrating logger usage
[View changes](https://github.com/bitcoinresearchkit/brk/compare/v0.1.0-alpha.2...v0.1.0-alpha.3)
## [v0.1.0-alpha.2](https://github.com/bitcoinresearchkit/brk/releases/tag/v0.1.0-alpha.2) - 2026-01-04
### Breaking Changes
#### `brk_binder` → `brk_bindgen`
- Replaced `brk_binder` crate with completely rewritten `brk_bindgen` crate featuring new architecture with separate `generators/`, `backends/`, and `analysis/` modules ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.2/crates/brk_bindgen/src/lib.rs))
#### `brk_grouper` → `brk_cohort`
- Migrated cohort filtering functionality from `brk_grouper` to new `brk_cohort` crate with expanded filtering capabilities ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.2/crates/brk_cohort/src/lib.rs))
#### `brk_computer`
- Replaced `brk_grouper` dependency with `brk_cohort` throughout the crate
- Removed monolithic `chain/` module containing compute.rs, import.rs, and mod.rs
- Removed monolithic `cointime.rs` in favor of modular `cointime/` directory structure
- Removed `stateful/` module tree including address cohorts, UTXO cohorts, and state management
- Removed `fetched.rs`, `grouped/`, `indexes.rs`, and `price.rs` modules
### New Features
#### `brk_alloc` (New Crate)
- Created global allocator crate using mimalloc for consistent memory allocation across all brk crates ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.2/crates/brk_alloc/src/lib.rs))
- Added `Mimalloc::collect()` function for eager memory release back to OS at natural pause points
#### `brk_bindgen` (New Crate)
- Implemented `ClientOutputPaths` builder for configuring output file paths per language ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.2/crates/brk_bindgen/src/lib.rs))
- Added `generate_clients()` function that generates all configured language clients from OpenAPI spec
- Created analysis module with name resolution, pattern detection, position tracking, and tree traversal ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.2/crates/brk_bindgen/src/analysis/mod.rs))
- Implemented language-specific backends for JavaScript, Python, and Rust code generation ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.2/crates/brk_bindgen/src/backends/mod.rs))
- Created generators module with separate API, client, tree, and types generation per language ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.2/crates/brk_bindgen/src/generators/mod.rs))
- Added syntax utilities for code generation formatting
- Implemented schema extraction and type metadata handling ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.2/crates/brk_bindgen/src/types/mod.rs))
#### `brk_client` (New Crate)
- Created Rust client crate with build-time CPU optimization for release builds ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.2/crates/brk_client/build.rs))
- Generated client library using brk_types for strong typing
#### `brk_cohort` (New Crate)
- Implemented comprehensive UTXO and address cohort filtering system ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.2/crates/brk_cohort/src/lib.rs))
- Added address type filtering for all output types: P2PK65, P2PK33, P2PKH, P2SH, P2WPKH, P2WSH, P2TR, P2A ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.2/crates/brk_cohort/src/by_address_type.rs))
- Added spendable and unspendable type filtering ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.2/crates/brk_cohort/src/by_spendable_type.rs))
- Implemented `CohortContext` for automatic metric name prefix generation based on cohort type ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.2/crates/brk_cohort/src/cohort_context.rs))
- Added `CohortName` system for generating consistent cohort identifiers
- Implemented `StateLevel` tracking for cohort state management
- Added year-based filtering with `ByYear` grouper
- Added `ByAnyAddress` for filtering across all address types
- Migrated and extended age range, amount range, epoch, term, min/max age, ge/lt amount filters from brk_grouper
#### `brk_computer`
- Created modular `blocks/` module with separate submodules for count, difficulty, halving, interval, mining, rewards, size, time, and weight metrics ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.2/crates/brk_computer/src/blocks/mod.rs))
- Created modular `cointime/` module with submodules for activity, adjusted, cap, pricing, supply, and value calculations ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.2/crates/brk_computer/src/cointime/mod.rs))
- Created `distribution/` module for UTXO distribution metrics with address, block, cohorts, compute, metrics, and state submodules ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.2/crates/brk_computer/src/distribution/mod.rs))
- Reorganized `indexes/` into modular structure with address, block, time, and transaction submodules
- Reorganized `inputs/` into count and spent submodules
- Reorganized `outputs/` into count and spent submodules
- Reorganized `market/` into ath, dca, indicators, lookback, moving_average, range, returns, and volatility submodules
- Reorganized `price/` into ohlc, sats, and usd submodules
- Reorganized `supply/` into burned, circulating, inflation, market_cap, and velocity submodules
- Reorganized `transactions/` into count, fees, size, versions, and volume submodules
- Reorganized `scripts/` into count and value submodules
- Added internal module with builder, computed, lazy, specialized, and value submodules for metric computation infrastructure
#### `brk_indexer`
- Refactored processor into modular structure with separate metadata, tx, txin, txout, and types submodules ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.2/crates/brk_indexer/src/processor/mod.rs))
#### `brk_bundler`
- Added bundle example demonstrating bundler usage ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.2/crates/brk_bundler/examples/bundle.rs))
#### `brk_types`
- Added `Age` type for UTXO age representation
- Added `CentsCompact` type for compact cent storage
- Added `Hex` type for hexadecimal string handling
- Added `Indexes` module for index type collections
- Added `OptionExt` trait for option extensions
- Added `Percentile` type for percentile values
- Added `SupplyState` type for supply tracking state
- Added `Term` type for short-term/long-term holder classification
#### `packages/brk_client` (Python)
- Created Python client package with httpx for HTTP requests ([source](https://github.com/bitcoinresearchkit/brk/blob/v0.1.0-alpha.2/packages/brk_client/pyproject.toml))
- Added typed dataclass-based client with full metric catalog support
- Included test suite for client functionality
### Internal Changes
#### `brk_computer`
- Removed debug_indexer.rs and pools.rs examples
- Simplified constants.rs by removing unused constant definitions
- Consolidated address data structures into distribution module
#### `brk_indexer`
- Removed BENCH.md benchmarking documentation
#### `brk_mempool`
- Removed DESIGN.md design documentation
#### `workspace`
- Added brk_alloc as dev-dependency for benchmarks using mimalloc
[View changes](https://github.com/bitcoinresearchkit/brk/compare/v0.1.0-alpha.1...v0.1.0-alpha.2)
## [v0.1.0-alpha.1](https://github.com/bitcoinresearchkit/brk/releases/tag/v0.1.0-alpha.1) - 2025-12-21
### New Features
-1
View File
@@ -12,4 +12,3 @@ worker.*
*.mts
*.cts
*.rs
*.md
+142 -60
View File
@@ -6,7 +6,7 @@
# Class: BrkClient
Defined in: [Developer/brk/modules/brk-client/index.js:4373](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L4373)
Defined in: [Developer/brk/modules/brk-client/index.js:4491](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L4491)
Main BRK client with metrics tree and API methods
@@ -20,7 +20,7 @@ Main BRK client with metrics tree and API methods
> **new BrkClient**(`options`): `BrkClient`
Defined in: [Developer/brk/modules/brk-client/index.js:5271](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L5271)
Defined in: [Developer/brk/modules/brk-client/index.js:5408](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L5408)
#### Parameters
@@ -42,7 +42,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:5271](https://github.com/
> **\_cachePromise**: `Promise`\<`Cache` \| `null`\>
Defined in: [Developer/brk/modules/brk-client/index.js:997](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L997)
Defined in: [Developer/brk/modules/brk-client/index.js:1102](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1102)
#### Inherited from
@@ -54,15 +54,49 @@ Defined in: [Developer/brk/modules/brk-client/index.js:997](https://github.com/b
> **metrics**: [`MetricsTree`](../interfaces/MetricsTree.md)
Defined in: [Developer/brk/modules/brk-client/index.js:5274](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L5274)
Defined in: [Developer/brk/modules/brk-client/index.js:5411](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L5411)
## Methods
### \_fetchMetricData()
> **\_fetchMetricData**\<`T`\>(`path`, `onUpdate?`): `Promise`\<[`MetricData`](../interfaces/MetricData.md)\<`T`\>\>
Defined in: [Developer/brk/modules/brk-client/index.js:1169](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1169)
Fetch metric data and wrap with helper methods (internal)
#### Type Parameters
##### T
`T`
#### Parameters
##### path
`string`
##### onUpdate?
(`value`) => `void`
#### Returns
`Promise`\<[`MetricData`](../interfaces/MetricData.md)\<`T`\>\>
#### Inherited from
`BrkClientBase._fetchMetricData`
***
### get()
> **get**(`path`): `Promise`\<`Response`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1004](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1004)
Defined in: [Developer/brk/modules/brk-client/index.js:1109](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1109)
#### Parameters
@@ -84,7 +118,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1004](https://github.com/
> **getAddress**(`address`): `Promise`\<[`AddressStats`](../interfaces/AddressStats.md)\>
Defined in: [Developer/brk/modules/brk-client/index.js:6446](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6446)
Defined in: [Developer/brk/modules/brk-client/index.js:6583](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6583)
Address information
@@ -110,7 +144,7 @@ Endpoint: `GET /api/address/{address}`
> **getAddressConfirmedTxs**(`address`, `after_txid?`, `limit?`): `Promise`\<`string`[]\>
Defined in: [Developer/brk/modules/brk-client/index.js:6487](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6487)
Defined in: [Developer/brk/modules/brk-client/index.js:6624](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6624)
Address confirmed transactions
@@ -148,7 +182,7 @@ Maximum number of results to return. Defaults to 25 if not specified.
> **getAddressMempoolTxs**(`address`): `Promise`\<`string`[]\>
Defined in: [Developer/brk/modules/brk-client/index.js:6508](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6508)
Defined in: [Developer/brk/modules/brk-client/index.js:6645](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6645)
Address mempool transactions
@@ -174,7 +208,7 @@ Endpoint: `GET /api/address/{address}/txs/mempool`
> **getAddressTxs**(`address`, `after_txid?`, `limit?`): `Promise`\<`string`[]\>
Defined in: [Developer/brk/modules/brk-client/index.js:6464](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6464)
Defined in: [Developer/brk/modules/brk-client/index.js:6601](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6601)
Address transaction IDs
@@ -212,7 +246,7 @@ Maximum number of results to return. Defaults to 25 if not specified.
> **getAddressUtxos**(`address`): `Promise`\<[`Utxo`](../interfaces/Utxo.md)[]\>
Defined in: [Developer/brk/modules/brk-client/index.js:6524](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6524)
Defined in: [Developer/brk/modules/brk-client/index.js:6661](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6661)
Address UTXOs
@@ -238,7 +272,7 @@ Endpoint: `GET /api/address/{address}/utxo`
> **getApi**(): `Promise`\<`any`\>
Defined in: [Developer/brk/modules/brk-client/index.js:6430](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6430)
Defined in: [Developer/brk/modules/brk-client/index.js:6567](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6567)
Compact OpenAPI specification
@@ -256,7 +290,7 @@ Endpoint: `GET /api.json`
> **getBlock**(`hash`): `Promise`\<[`BlockInfo`](../interfaces/BlockInfo.md)\>
Defined in: [Developer/brk/modules/brk-client/index.js:6556](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6556)
Defined in: [Developer/brk/modules/brk-client/index.js:6693](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6693)
Block information
@@ -282,7 +316,7 @@ Endpoint: `GET /api/block/{hash}`
> **getBlockByHeight**(`height`): `Promise`\<[`BlockInfo`](../interfaces/BlockInfo.md)\>
Defined in: [Developer/brk/modules/brk-client/index.js:6540](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6540)
Defined in: [Developer/brk/modules/brk-client/index.js:6677](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6677)
Block by height
@@ -308,7 +342,7 @@ Endpoint: `GET /api/block-height/{height}`
> **getBlockByTimestamp**(`timestamp`): `Promise`\<[`BlockTimestamp`](../interfaces/BlockTimestamp.md)\>
Defined in: [Developer/brk/modules/brk-client/index.js:7070](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L7070)
Defined in: [Developer/brk/modules/brk-client/index.js:7207](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L7207)
Block by timestamp
@@ -334,7 +368,7 @@ Endpoint: `GET /api/v1/mining/blocks/timestamp/{timestamp}`
> **getBlockFeeRates**(`time_period`): `Promise`\<`any`\>
Defined in: [Developer/brk/modules/brk-client/index.js:7006](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L7006)
Defined in: [Developer/brk/modules/brk-client/index.js:7143](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L7143)
Block fee rates (WIP)
@@ -360,7 +394,7 @@ Endpoint: `GET /api/v1/mining/blocks/fee-rates/{time_period}`
> **getBlockFees**(`time_period`): `Promise`\<[`BlockFeesEntry`](../interfaces/BlockFeesEntry.md)[]\>
Defined in: [Developer/brk/modules/brk-client/index.js:7022](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L7022)
Defined in: [Developer/brk/modules/brk-client/index.js:7159](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L7159)
Block fees
@@ -386,7 +420,7 @@ Endpoint: `GET /api/v1/mining/blocks/fees/{time_period}`
> **getBlockRaw**(`hash`): `Promise`\<`number`[]\>
Defined in: [Developer/brk/modules/brk-client/index.js:6572](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6572)
Defined in: [Developer/brk/modules/brk-client/index.js:6709](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6709)
Raw block
@@ -412,7 +446,7 @@ Endpoint: `GET /api/block/{hash}/raw`
> **getBlockRewards**(`time_period`): `Promise`\<[`BlockRewardsEntry`](../interfaces/BlockRewardsEntry.md)[]\>
Defined in: [Developer/brk/modules/brk-client/index.js:7038](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L7038)
Defined in: [Developer/brk/modules/brk-client/index.js:7175](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L7175)
Block rewards
@@ -438,7 +472,7 @@ Endpoint: `GET /api/v1/mining/blocks/rewards/{time_period}`
> **getBlocks**(): `Promise`\<[`BlockInfo`](../interfaces/BlockInfo.md)[]\>
Defined in: [Developer/brk/modules/brk-client/index.js:6652](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6652)
Defined in: [Developer/brk/modules/brk-client/index.js:6789](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6789)
Recent blocks
@@ -458,7 +492,7 @@ Endpoint: `GET /api/blocks`
> **getBlocksFromHeight**(`height`): `Promise`\<[`BlockInfo`](../interfaces/BlockInfo.md)[]\>
Defined in: [Developer/brk/modules/brk-client/index.js:6668](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6668)
Defined in: [Developer/brk/modules/brk-client/index.js:6805](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6805)
Blocks from height
@@ -484,7 +518,7 @@ Endpoint: `GET /api/blocks/{height}`
> **getBlockSizesWeights**(`time_period`): `Promise`\<[`BlockSizesWeights`](../interfaces/BlockSizesWeights.md)\>
Defined in: [Developer/brk/modules/brk-client/index.js:7054](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L7054)
Defined in: [Developer/brk/modules/brk-client/index.js:7191](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L7191)
Block sizes and weights
@@ -510,7 +544,7 @@ Endpoint: `GET /api/v1/mining/blocks/sizes-weights/{time_period}`
> **getBlockStatus**(`hash`): `Promise`\<[`BlockStatus`](../interfaces/BlockStatus.md)\>
Defined in: [Developer/brk/modules/brk-client/index.js:6588](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6588)
Defined in: [Developer/brk/modules/brk-client/index.js:6725](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6725)
Block status
@@ -536,7 +570,7 @@ Endpoint: `GET /api/block/{hash}/status`
> **getBlockTxid**(`hash`, `index`): `Promise`\<`string`\>
Defined in: [Developer/brk/modules/brk-client/index.js:6605](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6605)
Defined in: [Developer/brk/modules/brk-client/index.js:6742](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6742)
Transaction ID at index
@@ -570,7 +604,7 @@ Transaction index within the block (0-based)
> **getBlockTxids**(`hash`): `Promise`\<`string`[]\>
Defined in: [Developer/brk/modules/brk-client/index.js:6621](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6621)
Defined in: [Developer/brk/modules/brk-client/index.js:6758](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6758)
Block transaction IDs
@@ -596,7 +630,7 @@ Endpoint: `GET /api/block/{hash}/txids`
> **getBlockTxs**(`hash`, `start_index`): `Promise`\<[`Transaction`](../interfaces/Transaction.md)[]\>
Defined in: [Developer/brk/modules/brk-client/index.js:6638](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6638)
Defined in: [Developer/brk/modules/brk-client/index.js:6775](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6775)
Block transactions (paginated)
@@ -630,7 +664,7 @@ Starting transaction index within the block (0-based)
> **getDifficultyAdjustment**(): `Promise`\<[`DifficultyAdjustment`](../interfaces/DifficultyAdjustment.md)\>
Defined in: [Developer/brk/modules/brk-client/index.js:6962](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6962)
Defined in: [Developer/brk/modules/brk-client/index.js:7099](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L7099)
Difficulty adjustment
@@ -650,7 +684,7 @@ Endpoint: `GET /api/v1/difficulty-adjustment`
> **getDifficultyAdjustments**(): `Promise`\<[`DifficultyAdjustmentEntry`](../interfaces/DifficultyAdjustmentEntry.md)[]\>
Defined in: [Developer/brk/modules/brk-client/index.js:7084](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L7084)
Defined in: [Developer/brk/modules/brk-client/index.js:7221](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L7221)
Difficulty adjustments (all time)
@@ -670,7 +704,7 @@ Endpoint: `GET /api/v1/mining/difficulty-adjustments`
> **getDifficultyAdjustmentsByPeriod**(`time_period`): `Promise`\<[`DifficultyAdjustmentEntry`](../interfaces/DifficultyAdjustmentEntry.md)[]\>
Defined in: [Developer/brk/modules/brk-client/index.js:7100](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L7100)
Defined in: [Developer/brk/modules/brk-client/index.js:7237](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L7237)
Difficulty adjustments
@@ -696,7 +730,7 @@ Endpoint: `GET /api/v1/mining/difficulty-adjustments/{time_period}`
> **getDiskUsage**(): `Promise`\<[`DiskUsage`](../interfaces/DiskUsage.md)\>
Defined in: [Developer/brk/modules/brk-client/index.js:6855](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6855)
Defined in: [Developer/brk/modules/brk-client/index.js:6992](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6992)
Disk usage
@@ -714,7 +748,7 @@ Endpoint: `GET /api/server/disk`
> **getHashrate**(): `Promise`\<[`HashrateSummary`](../interfaces/HashrateSummary.md)\>
Defined in: [Developer/brk/modules/brk-client/index.js:7114](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L7114)
Defined in: [Developer/brk/modules/brk-client/index.js:7251](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L7251)
Network hashrate (all time)
@@ -734,7 +768,7 @@ Endpoint: `GET /api/v1/mining/hashrate`
> **getHashrateByPeriod**(`time_period`): `Promise`\<[`HashrateSummary`](../interfaces/HashrateSummary.md)\>
Defined in: [Developer/brk/modules/brk-client/index.js:7130](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L7130)
Defined in: [Developer/brk/modules/brk-client/index.js:7267](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L7267)
Network hashrate
@@ -760,7 +794,7 @@ Endpoint: `GET /api/v1/mining/hashrate/{time_period}`
> **getHealth**(): `Promise`\<[`Health`](../interfaces/Health.md)\>
Defined in: [Developer/brk/modules/brk-client/index.js:7220](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L7220)
Defined in: [Developer/brk/modules/brk-client/index.js:7357](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L7357)
Health check
@@ -778,7 +812,7 @@ Endpoint: `GET /health`
> **getIndexes**(): `Promise`\<[`IndexInfo`](../interfaces/IndexInfo.md)[]\>
Defined in: [Developer/brk/modules/brk-client/index.js:6806](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6806)
Defined in: [Developer/brk/modules/brk-client/index.js:6943](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6943)
List available indexes
@@ -796,7 +830,7 @@ Endpoint: `GET /api/metrics/indexes`
> **getJson**\<`T`\>(`path`, `onUpdate?`): `Promise`\<`T`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1019](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1019)
Defined in: [Developer/brk/modules/brk-client/index.js:1124](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1124)
Make a GET request with stale-while-revalidate caching
@@ -832,7 +866,7 @@ Called when data is available
> **getMempool**(): `Promise`\<[`MempoolInfo`](../interfaces/MempoolInfo.md)\>
Defined in: [Developer/brk/modules/brk-client/index.js:6682](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6682)
Defined in: [Developer/brk/modules/brk-client/index.js:6819](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6819)
Mempool statistics
@@ -852,7 +886,7 @@ Endpoint: `GET /api/mempool/info`
> **getMempoolBlocks**(): `Promise`\<[`MempoolBlock`](../interfaces/MempoolBlock.md)[]\>
Defined in: [Developer/brk/modules/brk-client/index.js:6976](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6976)
Defined in: [Developer/brk/modules/brk-client/index.js:7113](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L7113)
Projected mempool blocks
@@ -872,7 +906,7 @@ Endpoint: `GET /api/v1/fees/mempool-blocks`
> **getMempoolTxids**(): `Promise`\<`string`[]\>
Defined in: [Developer/brk/modules/brk-client/index.js:6696](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6696)
Defined in: [Developer/brk/modules/brk-client/index.js:6833](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6833)
Mempool transaction IDs
@@ -892,7 +926,7 @@ Endpoint: `GET /api/mempool/txids`
> **getMetric**(`metric`, `index`, `start?`, `end?`, `limit?`, `format?`): `Promise`\<`string` \| [`AnyMetricData`](../type-aliases/AnyMetricData.md)\>
Defined in: [Developer/brk/modules/brk-client/index.js:6729](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6729)
Defined in: [Developer/brk/modules/brk-client/index.js:6866](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6866)
Get metric data
@@ -948,7 +982,7 @@ Format of the output
> **getMetricInfo**(`metric`): `Promise`\<[`Index`](../type-aliases/Index.md)[]\>
Defined in: [Developer/brk/modules/brk-client/index.js:6710](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6710)
Defined in: [Developer/brk/modules/brk-client/index.js:6847](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6847)
Get supported indexes for a metric
@@ -972,7 +1006,7 @@ Endpoint: `GET /api/metric/{metric}`
> **getMetrics**(`metrics?`, `index?`, `start?`, `end?`, `limit?`, `format?`): `Promise`\<`string` \| [`AnyMetricData`](../type-aliases/AnyMetricData.md)[]\>
Defined in: [Developer/brk/modules/brk-client/index.js:6770](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6770)
Defined in: [Developer/brk/modules/brk-client/index.js:6907](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6907)
Bulk metric data
@@ -1028,7 +1062,7 @@ Format of the output
> **getMetricsCount**(): `Promise`\<[`MetricCount`](../interfaces/MetricCount.md)[]\>
Defined in: [Developer/brk/modules/brk-client/index.js:6794](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6794)
Defined in: [Developer/brk/modules/brk-client/index.js:6931](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6931)
Metric count
@@ -1046,7 +1080,7 @@ Endpoint: `GET /api/metrics/count`
> **getMetricsTree**(): `Promise`\<[`TreeNode`](../type-aliases/TreeNode.md)\>
Defined in: [Developer/brk/modules/brk-client/index.js:6751](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6751)
Defined in: [Developer/brk/modules/brk-client/index.js:6888](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6888)
Metrics catalog
@@ -1064,7 +1098,7 @@ Endpoint: `GET /api/metrics`
> **getOpenapi**(): `Promise`\<`any`\>
Defined in: [Developer/brk/modules/brk-client/index.js:7232](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L7232)
Defined in: [Developer/brk/modules/brk-client/index.js:7369](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L7369)
OpenAPI specification
@@ -1082,7 +1116,7 @@ Endpoint: `GET /openapi.json`
> **getPool**(`slug`): `Promise`\<[`PoolDetail`](../interfaces/PoolDetail.md)\>
Defined in: [Developer/brk/modules/brk-client/index.js:7146](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L7146)
Defined in: [Developer/brk/modules/brk-client/index.js:7283](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L7283)
Mining pool details
@@ -1108,7 +1142,7 @@ Endpoint: `GET /api/v1/mining/pool/{slug}`
> **getPools**(): `Promise`\<[`PoolInfo`](../interfaces/PoolInfo.md)[]\>
Defined in: [Developer/brk/modules/brk-client/index.js:7160](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L7160)
Defined in: [Developer/brk/modules/brk-client/index.js:7297](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L7297)
List all mining pools
@@ -1128,7 +1162,7 @@ Endpoint: `GET /api/v1/mining/pools`
> **getPoolStats**(`time_period`): `Promise`\<[`PoolsSummary`](../interfaces/PoolsSummary.md)\>
Defined in: [Developer/brk/modules/brk-client/index.js:7176](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L7176)
Defined in: [Developer/brk/modules/brk-client/index.js:7313](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L7313)
Mining pool statistics
@@ -1154,7 +1188,7 @@ Endpoint: `GET /api/v1/mining/pools/{time_period}`
> **getRecommendedFees**(): `Promise`\<[`RecommendedFees`](../interfaces/RecommendedFees.md)\>
Defined in: [Developer/brk/modules/brk-client/index.js:6990](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6990)
Defined in: [Developer/brk/modules/brk-client/index.js:7127](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L7127)
Recommended fees
@@ -1174,7 +1208,7 @@ Endpoint: `GET /api/v1/fees/recommended`
> **getRewardStats**(`block_count`): `Promise`\<[`RewardStats`](../interfaces/RewardStats.md)\>
Defined in: [Developer/brk/modules/brk-client/index.js:7192](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L7192)
Defined in: [Developer/brk/modules/brk-client/index.js:7329](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L7329)
Mining reward statistics
@@ -1202,7 +1236,7 @@ Number of recent blocks to include
> **getSyncStatus**(): `Promise`\<[`SyncStatus`](../interfaces/SyncStatus.md)\>
Defined in: [Developer/brk/modules/brk-client/index.js:6867](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6867)
Defined in: [Developer/brk/modules/brk-client/index.js:7004](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L7004)
Sync status
@@ -1220,7 +1254,7 @@ Endpoint: `GET /api/server/sync`
> **getText**(`path`): `Promise`\<`string`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1052](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1052)
Defined in: [Developer/brk/modules/brk-client/index.js:1157](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1157)
Make a GET request and return raw text (for CSV responses)
@@ -1244,7 +1278,7 @@ Make a GET request and return raw text (for CSV responses)
> **getTx**(`txid`): `Promise`\<[`Transaction`](../interfaces/Transaction.md)\>
Defined in: [Developer/brk/modules/brk-client/index.js:6883](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6883)
Defined in: [Developer/brk/modules/brk-client/index.js:7020](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L7020)
Transaction information
@@ -1270,7 +1304,7 @@ Endpoint: `GET /api/tx/{txid}`
> **getTxHex**(`txid`): `Promise`\<`string`\>
Defined in: [Developer/brk/modules/brk-client/index.js:6899](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6899)
Defined in: [Developer/brk/modules/brk-client/index.js:7036](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L7036)
Transaction hex
@@ -1296,7 +1330,7 @@ Endpoint: `GET /api/tx/{txid}/hex`
> **getTxOutspend**(`txid`, `vout`): `Promise`\<[`TxOutspend`](../interfaces/TxOutspend.md)\>
Defined in: [Developer/brk/modules/brk-client/index.js:6916](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6916)
Defined in: [Developer/brk/modules/brk-client/index.js:7053](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L7053)
Output spend status
@@ -1330,7 +1364,7 @@ Output index
> **getTxOutspends**(`txid`): `Promise`\<[`TxOutspend`](../interfaces/TxOutspend.md)[]\>
Defined in: [Developer/brk/modules/brk-client/index.js:6932](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6932)
Defined in: [Developer/brk/modules/brk-client/index.js:7069](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L7069)
All output spend statuses
@@ -1356,7 +1390,7 @@ Endpoint: `GET /api/tx/{txid}/outspends`
> **getTxStatus**(`txid`): `Promise`\<[`TxStatus`](../interfaces/TxStatus.md)\>
Defined in: [Developer/brk/modules/brk-client/index.js:6948](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6948)
Defined in: [Developer/brk/modules/brk-client/index.js:7085](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L7085)
Transaction status
@@ -1382,7 +1416,7 @@ Endpoint: `GET /api/tx/{txid}/status`
> **getVersion**(): `Promise`\<`string`\>
Defined in: [Developer/brk/modules/brk-client/index.js:7244](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L7244)
Defined in: [Developer/brk/modules/brk-client/index.js:7381](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L7381)
API version
@@ -1396,11 +1430,59 @@ Endpoint: `GET /version`
***
### indexToDate()
> **indexToDate**(`index`, `i`): `Date`
Defined in: [Developer/brk/modules/brk-client/index.js:5392](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L5392)
Convert an index value to a Date for date-based indexes.
#### Parameters
##### index
[`Index`](../type-aliases/Index.md)
The index type
##### i
`number`
The index value
#### Returns
`Date`
***
### isDateIndex()
> **isDateIndex**(`index`): `boolean`
Defined in: [Developer/brk/modules/brk-client/index.js:5401](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L5401)
Check if an index type is date-based.
#### Parameters
##### index
[`Index`](../type-aliases/Index.md)
#### Returns
`boolean`
***
### listMetrics()
> **listMetrics**(`page?`): `Promise`\<[`PaginatedMetrics`](../interfaces/PaginatedMetrics.md)\>
Defined in: [Developer/brk/modules/brk-client/index.js:6820](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6820)
Defined in: [Developer/brk/modules/brk-client/index.js:6957](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6957)
Metrics list
@@ -1426,7 +1508,7 @@ Pagination index
> **metric**(`metric`, `index`): [`MetricEndpointBuilder`](../interfaces/MetricEndpointBuilder.md)\<`unknown`\>
Defined in: [Developer/brk/modules/brk-client/index.js:6418](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6418)
Defined in: [Developer/brk/modules/brk-client/index.js:6555](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6555)
Create a dynamic metric endpoint builder for any metric/index combination.
@@ -1457,7 +1539,7 @@ The index name
> **searchMetrics**(`metric`, `limit?`): `Promise`\<`string`[]\>
Defined in: [Developer/brk/modules/brk-client/index.js:6839](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L6839)
Defined in: [Developer/brk/modules/brk-client/index.js:6976](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L6976)
Search metrics
@@ -1485,7 +1567,7 @@ Endpoint: `GET /api/metrics/search/{metric}`
> **validateAddress**(`address`): `Promise`\<[`AddressValidation`](../interfaces/AddressValidation.md)\>
Defined in: [Developer/brk/modules/brk-client/index.js:7208](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L7208)
Defined in: [Developer/brk/modules/brk-client/index.js:7345](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L7345)
Validate address
+2 -2
View File
@@ -6,7 +6,7 @@
# Class: BrkError
Defined in: [Developer/brk/modules/brk-client/index.js:829](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L829)
Defined in: [Developer/brk/modules/brk-client/index.js:829](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L829)
Custom error class for BRK client errors
@@ -20,7 +20,7 @@ Custom error class for BRK client errors
> **new BrkError**(`message`, `status?`): `BrkError`
Defined in: [Developer/brk/modules/brk-client/index.js:834](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L834)
Defined in: [Developer/brk/modules/brk-client/index.js:834](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L834)
#### Parameters
+2 -2
View File
@@ -161,8 +161,8 @@
- [MetricsTree\_Market\_Dca\_ClassAveragePrice](interfaces/MetricsTree_Market_Dca_ClassAveragePrice.md)
- [MetricsTree\_Market\_Dca\_ClassDaysInLoss](interfaces/MetricsTree_Market_Dca_ClassDaysInLoss.md)
- [MetricsTree\_Market\_Dca\_ClassDaysInProfit](interfaces/MetricsTree_Market_Dca_ClassDaysInProfit.md)
- [MetricsTree\_Market\_Dca\_ClassMaxDrawdown](interfaces/MetricsTree_Market_Dca_ClassMaxDrawdown.md)
- [MetricsTree\_Market\_Dca\_ClassMaxReturn](interfaces/MetricsTree_Market_Dca_ClassMaxReturn.md)
- [MetricsTree\_Market\_Dca\_ClassReturns](interfaces/MetricsTree_Market_Dca_ClassReturns.md)
- [MetricsTree\_Market\_Dca\_ClassStack](interfaces/MetricsTree_Market_Dca_ClassStack.md)
- [MetricsTree\_Market\_Dca\_PeriodAveragePrice](interfaces/MetricsTree_Market_Dca_PeriodAveragePrice.md)
- [MetricsTree\_Market\_Indicators](interfaces/MetricsTree_Market_Indicators.md)
@@ -181,7 +181,7 @@
- [MetricsTree\_Price](interfaces/MetricsTree_Price.md)
- [MetricsTree\_Price\_Cents](interfaces/MetricsTree_Price_Cents.md)
- [MetricsTree\_Price\_Cents\_Split](interfaces/MetricsTree_Price_Cents_Split.md)
- [MetricsTree\_Price\_Sats](interfaces/MetricsTree_Price_Sats.md)
- [MetricsTree\_Price\_Usd](interfaces/MetricsTree_Price_Usd.md)
- [MetricsTree\_Scripts](interfaces/MetricsTree_Scripts.md)
- [MetricsTree\_Scripts\_Count](interfaces/MetricsTree_Scripts_Count.md)
- [MetricsTree\_Scripts\_Value](interfaces/MetricsTree_Scripts_Value.md)
@@ -6,7 +6,7 @@
# Interface: \_0satsPattern
Defined in: [Developer/brk/modules/brk-client/index.js:2258](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2258)
Defined in: [Developer/brk/modules/brk-client/index.js:2376](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2376)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2258](https://github.com/
> **activity**: [`ActivityPattern2`](ActivityPattern2.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2259](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2259)
Defined in: [Developer/brk/modules/brk-client/index.js:2377](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2377)
***
@@ -22,7 +22,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2259](https://github.com/
> **addrCount**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2260](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2260)
Defined in: [Developer/brk/modules/brk-client/index.js:2378](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2378)
***
@@ -30,7 +30,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2260](https://github.com/
> **costBasis**: [`CostBasisPattern`](CostBasisPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2261](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2261)
Defined in: [Developer/brk/modules/brk-client/index.js:2379](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2379)
***
@@ -38,7 +38,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2261](https://github.com/
> **outputs**: [`OutputsPattern`](OutputsPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2262](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2262)
Defined in: [Developer/brk/modules/brk-client/index.js:2380](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2380)
***
@@ -46,7 +46,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2262](https://github.com/
> **realized**: [`RealizedPattern`](RealizedPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2263](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2263)
Defined in: [Developer/brk/modules/brk-client/index.js:2381](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2381)
***
@@ -54,7 +54,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2263](https://github.com/
> **relative**: [`RelativePattern`](RelativePattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2264](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2264)
Defined in: [Developer/brk/modules/brk-client/index.js:2382](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2382)
***
@@ -62,7 +62,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2264](https://github.com/
> **supply**: [`SupplyPattern2`](SupplyPattern2.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2265](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2265)
Defined in: [Developer/brk/modules/brk-client/index.js:2383](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2383)
***
@@ -70,4 +70,4 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2265](https://github.com/
> **unrealized**: [`UnrealizedPattern`](UnrealizedPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2266](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2266)
Defined in: [Developer/brk/modules/brk-client/index.js:2384](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2384)
@@ -6,7 +6,7 @@
# Interface: \_0satsPattern2
Defined in: [Developer/brk/modules/brk-client/index.js:2289](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2289)
Defined in: [Developer/brk/modules/brk-client/index.js:2465](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2465)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2289](https://github.com/
> **activity**: [`ActivityPattern2`](ActivityPattern2.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2290](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2290)
Defined in: [Developer/brk/modules/brk-client/index.js:2466](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2466)
***
@@ -22,7 +22,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2290](https://github.com/
> **costBasis**: [`CostBasisPattern`](CostBasisPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2291](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2291)
Defined in: [Developer/brk/modules/brk-client/index.js:2467](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2467)
***
@@ -30,7 +30,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2291](https://github.com/
> **outputs**: [`OutputsPattern`](OutputsPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2292](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2292)
Defined in: [Developer/brk/modules/brk-client/index.js:2468](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2468)
***
@@ -38,7 +38,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2292](https://github.com/
> **realized**: [`RealizedPattern`](RealizedPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2293](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2293)
Defined in: [Developer/brk/modules/brk-client/index.js:2469](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2469)
***
@@ -46,7 +46,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2293](https://github.com/
> **relative**: [`RelativePattern4`](RelativePattern4.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2294](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2294)
Defined in: [Developer/brk/modules/brk-client/index.js:2470](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2470)
***
@@ -54,7 +54,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2294](https://github.com/
> **supply**: [`SupplyPattern2`](SupplyPattern2.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2295](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2295)
Defined in: [Developer/brk/modules/brk-client/index.js:2471](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2471)
***
@@ -62,4 +62,4 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2295](https://github.com/
> **unrealized**: [`UnrealizedPattern`](UnrealizedPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2296](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2296)
Defined in: [Developer/brk/modules/brk-client/index.js:2472](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2472)
@@ -0,0 +1,25 @@
[**brk-client**](../README.md)
***
[brk-client](../globals.md) / \_0sdUsdPattern
# Interface: \_0sdUsdPattern
Defined in: [Developer/brk/modules/brk-client/index.js:2824](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2824)
## Properties
### dollars
> **dollars**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2825](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2825)
***
### sats
> **sats**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2826](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2826)
@@ -6,7 +6,7 @@
# Interface: \_100btcPattern
Defined in: [Developer/brk/modules/brk-client/index.js:2376](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2376)
Defined in: [Developer/brk/modules/brk-client/index.js:2436](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2436)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2376](https://github.com/
> **activity**: [`ActivityPattern2`](ActivityPattern2.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2377](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2377)
Defined in: [Developer/brk/modules/brk-client/index.js:2437](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2437)
***
@@ -22,7 +22,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2377](https://github.com/
> **costBasis**: [`CostBasisPattern`](CostBasisPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2378](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2378)
Defined in: [Developer/brk/modules/brk-client/index.js:2438](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2438)
***
@@ -30,7 +30,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2378](https://github.com/
> **outputs**: [`OutputsPattern`](OutputsPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2379](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2379)
Defined in: [Developer/brk/modules/brk-client/index.js:2439](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2439)
***
@@ -38,7 +38,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2379](https://github.com/
> **realized**: [`RealizedPattern`](RealizedPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2380](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2380)
Defined in: [Developer/brk/modules/brk-client/index.js:2440](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2440)
***
@@ -46,7 +46,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2380](https://github.com/
> **relative**: [`RelativePattern`](RelativePattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2381](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2381)
Defined in: [Developer/brk/modules/brk-client/index.js:2441](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2441)
***
@@ -54,7 +54,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2381](https://github.com/
> **supply**: [`SupplyPattern2`](SupplyPattern2.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2382](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2382)
Defined in: [Developer/brk/modules/brk-client/index.js:2442](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2442)
***
@@ -62,4 +62,4 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2382](https://github.com/
> **unrealized**: [`UnrealizedPattern`](UnrealizedPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2383](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2383)
Defined in: [Developer/brk/modules/brk-client/index.js:2443](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2443)
@@ -6,7 +6,7 @@
# Interface: \_10yPattern
Defined in: [Developer/brk/modules/brk-client/index.js:2405](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2405)
Defined in: [Developer/brk/modules/brk-client/index.js:2494](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2494)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2405](https://github.com/
> **activity**: [`ActivityPattern2`](ActivityPattern2.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2406](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2406)
Defined in: [Developer/brk/modules/brk-client/index.js:2495](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2495)
***
@@ -22,7 +22,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2406](https://github.com/
> **costBasis**: [`CostBasisPattern`](CostBasisPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2407](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2407)
Defined in: [Developer/brk/modules/brk-client/index.js:2496](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2496)
***
@@ -30,7 +30,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2407](https://github.com/
> **outputs**: [`OutputsPattern`](OutputsPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2408](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2408)
Defined in: [Developer/brk/modules/brk-client/index.js:2497](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2497)
***
@@ -38,7 +38,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2408](https://github.com/
> **realized**: [`RealizedPattern4`](RealizedPattern4.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2409](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2409)
Defined in: [Developer/brk/modules/brk-client/index.js:2498](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2498)
***
@@ -46,7 +46,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2409](https://github.com/
> **relative**: [`RelativePattern`](RelativePattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2410](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2410)
Defined in: [Developer/brk/modules/brk-client/index.js:2499](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2499)
***
@@ -54,7 +54,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2410](https://github.com/
> **supply**: [`SupplyPattern2`](SupplyPattern2.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2411](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2411)
Defined in: [Developer/brk/modules/brk-client/index.js:2500](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2500)
***
@@ -62,4 +62,4 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2411](https://github.com/
> **unrealized**: [`UnrealizedPattern`](UnrealizedPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2412](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2412)
Defined in: [Developer/brk/modules/brk-client/index.js:2501](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2501)
@@ -6,7 +6,7 @@
# Interface: \_10yTo12yPattern
Defined in: [Developer/brk/modules/brk-client/index.js:2347](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2347)
Defined in: [Developer/brk/modules/brk-client/index.js:2523](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2523)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2347](https://github.com/
> **activity**: [`ActivityPattern2`](ActivityPattern2.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2348](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2348)
Defined in: [Developer/brk/modules/brk-client/index.js:2524](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2524)
***
@@ -22,7 +22,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2348](https://github.com/
> **costBasis**: [`CostBasisPattern2`](CostBasisPattern2.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2349](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2349)
Defined in: [Developer/brk/modules/brk-client/index.js:2525](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2525)
***
@@ -30,7 +30,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2349](https://github.com/
> **outputs**: [`OutputsPattern`](OutputsPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2350](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2350)
Defined in: [Developer/brk/modules/brk-client/index.js:2526](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2526)
***
@@ -38,7 +38,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2350](https://github.com/
> **realized**: [`RealizedPattern2`](RealizedPattern2.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2351](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2351)
Defined in: [Developer/brk/modules/brk-client/index.js:2527](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2527)
***
@@ -46,7 +46,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2351](https://github.com/
> **relative**: [`RelativePattern2`](RelativePattern2.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2352](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2352)
Defined in: [Developer/brk/modules/brk-client/index.js:2528](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2528)
***
@@ -54,7 +54,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2352](https://github.com/
> **supply**: [`SupplyPattern2`](SupplyPattern2.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2353](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2353)
Defined in: [Developer/brk/modules/brk-client/index.js:2529](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2529)
***
@@ -62,4 +62,4 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2353](https://github.com/
> **unrealized**: [`UnrealizedPattern`](UnrealizedPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2354](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2354)
Defined in: [Developer/brk/modules/brk-client/index.js:2530](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2530)
@@ -6,7 +6,7 @@
# Interface: \_1dReturns1mSdPattern
Defined in: [Developer/brk/modules/brk-client/index.js:2744](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2744)
Defined in: [Developer/brk/modules/brk-client/index.js:2881](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2881)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2744](https://github.com/
> **sd**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2745](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2745)
Defined in: [Developer/brk/modules/brk-client/index.js:2882](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2882)
***
@@ -22,4 +22,4 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2745](https://github.com/
> **sma**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2746](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2746)
Defined in: [Developer/brk/modules/brk-client/index.js:2883](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2883)
@@ -6,7 +6,7 @@
# Interface: \_2015Pattern
Defined in: [Developer/brk/modules/brk-client/index.js:2666](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2666)
Defined in: [Developer/brk/modules/brk-client/index.js:2700](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2700)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2666](https://github.com/
> **bitcoin**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2667](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2667)
Defined in: [Developer/brk/modules/brk-client/index.js:2701](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2701)
***
@@ -22,7 +22,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2667](https://github.com/
> **dollars**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2668](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2668)
Defined in: [Developer/brk/modules/brk-client/index.js:2702](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2702)
***
@@ -30,4 +30,4 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2668](https://github.com/
> **sats**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2669](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2669)
Defined in: [Developer/brk/modules/brk-client/index.js:2703](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2703)
@@ -6,7 +6,7 @@
# Interface: AaopoolPattern
Defined in: [Developer/brk/modules/brk-client/index.js:1806](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1806)
Defined in: [Developer/brk/modules/brk-client/index.js:1924](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1924)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1806](https://github.com/
> **\_1mBlocksMined**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1807](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1807)
Defined in: [Developer/brk/modules/brk-client/index.js:1925](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1925)
***
@@ -22,7 +22,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1807](https://github.com/
> **\_1mDominance**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1808](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1808)
Defined in: [Developer/brk/modules/brk-client/index.js:1926](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1926)
***
@@ -30,7 +30,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1808](https://github.com/
> **\_1wBlocksMined**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1809](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1809)
Defined in: [Developer/brk/modules/brk-client/index.js:1927](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1927)
***
@@ -38,7 +38,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1809](https://github.com/
> **\_1wDominance**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1810](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1810)
Defined in: [Developer/brk/modules/brk-client/index.js:1928](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1928)
***
@@ -46,7 +46,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1810](https://github.com/
> **\_1yBlocksMined**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1811](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1811)
Defined in: [Developer/brk/modules/brk-client/index.js:1929](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1929)
***
@@ -54,7 +54,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1811](https://github.com/
> **\_1yDominance**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1812](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1812)
Defined in: [Developer/brk/modules/brk-client/index.js:1930](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1930)
***
@@ -62,7 +62,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1812](https://github.com/
> **\_24hBlocksMined**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1813](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1813)
Defined in: [Developer/brk/modules/brk-client/index.js:1931](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1931)
***
@@ -70,7 +70,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1813](https://github.com/
> **\_24hDominance**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1814](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1814)
Defined in: [Developer/brk/modules/brk-client/index.js:1932](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1932)
***
@@ -78,7 +78,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1814](https://github.com/
> **blocksMined**: [`BlockCountPattern`](BlockCountPattern.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1815](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1815)
Defined in: [Developer/brk/modules/brk-client/index.js:1933](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1933)
***
@@ -86,7 +86,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1815](https://github.com/
> **blocksSinceBlock**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1816](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1816)
Defined in: [Developer/brk/modules/brk-client/index.js:1934](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1934)
***
@@ -94,7 +94,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1816](https://github.com/
> **coinbase**: [`CoinbasePattern2`](CoinbasePattern2.md)
Defined in: [Developer/brk/modules/brk-client/index.js:1817](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1817)
Defined in: [Developer/brk/modules/brk-client/index.js:1935](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1935)
***
@@ -102,7 +102,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1817](https://github.com/
> **daysSinceBlock**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1818](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1818)
Defined in: [Developer/brk/modules/brk-client/index.js:1936](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1936)
***
@@ -110,7 +110,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1818](https://github.com/
> **dominance**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1819](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1819)
Defined in: [Developer/brk/modules/brk-client/index.js:1937](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1937)
***
@@ -118,7 +118,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1819](https://github.com/
> **fee**: [`UnclaimedRewardsPattern`](UnclaimedRewardsPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:1820](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1820)
Defined in: [Developer/brk/modules/brk-client/index.js:1938](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1938)
***
@@ -126,4 +126,4 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1820](https://github.com/
> **subsidy**: [`UnclaimedRewardsPattern`](UnclaimedRewardsPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:1821](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1821)
Defined in: [Developer/brk/modules/brk-client/index.js:1939](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1939)
@@ -0,0 +1,25 @@
[**brk-client**](../README.md)
***
[brk-client](../globals.md) / ActivePricePattern
# Interface: ActivePricePattern
Defined in: [Developer/brk/modules/brk-client/index.js:2805](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2805)
## Properties
### dollars
> **dollars**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2806](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2806)
***
### sats
> **sats**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2807](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2807)
@@ -6,7 +6,7 @@
# Interface: ActivePriceRatioPattern
Defined in: [Developer/brk/modules/brk-client/index.js:1702](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1702)
Defined in: [Developer/brk/modules/brk-client/index.js:1820](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1820)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1702](https://github.com/
> **ratio**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1703](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1703)
Defined in: [Developer/brk/modules/brk-client/index.js:1821](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1821)
***
@@ -22,7 +22,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1703](https://github.com/
> **ratio1mSma**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1704](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1704)
Defined in: [Developer/brk/modules/brk-client/index.js:1822](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1822)
***
@@ -30,7 +30,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1704](https://github.com/
> **ratio1wSma**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1705](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1705)
Defined in: [Developer/brk/modules/brk-client/index.js:1823](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1823)
***
@@ -38,7 +38,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1705](https://github.com/
> **ratio1ySd**: [`Ratio1ySdPattern`](Ratio1ySdPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:1706](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1706)
Defined in: [Developer/brk/modules/brk-client/index.js:1824](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1824)
***
@@ -46,7 +46,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1706](https://github.com/
> **ratio2ySd**: [`Ratio1ySdPattern`](Ratio1ySdPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:1707](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1707)
Defined in: [Developer/brk/modules/brk-client/index.js:1825](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1825)
***
@@ -54,7 +54,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1707](https://github.com/
> **ratio4ySd**: [`Ratio1ySdPattern`](Ratio1ySdPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:1708](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1708)
Defined in: [Developer/brk/modules/brk-client/index.js:1826](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1826)
***
@@ -62,7 +62,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1708](https://github.com/
> **ratioPct1**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1709](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1709)
Defined in: [Developer/brk/modules/brk-client/index.js:1827](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1827)
***
@@ -70,7 +70,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1709](https://github.com/
> **ratioPct1Usd**: [`_0sdUsdPattern`](0sdUsdPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:1710](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1710)
Defined in: [Developer/brk/modules/brk-client/index.js:1828](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1828)
***
@@ -78,7 +78,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1710](https://github.com/
> **ratioPct2**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1711](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1711)
Defined in: [Developer/brk/modules/brk-client/index.js:1829](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1829)
***
@@ -86,7 +86,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1711](https://github.com/
> **ratioPct2Usd**: [`_0sdUsdPattern`](0sdUsdPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:1712](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1712)
Defined in: [Developer/brk/modules/brk-client/index.js:1830](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1830)
***
@@ -94,7 +94,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1712](https://github.com/
> **ratioPct5**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1713](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1713)
Defined in: [Developer/brk/modules/brk-client/index.js:1831](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1831)
***
@@ -102,7 +102,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1713](https://github.com/
> **ratioPct5Usd**: [`_0sdUsdPattern`](0sdUsdPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:1714](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1714)
Defined in: [Developer/brk/modules/brk-client/index.js:1832](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1832)
***
@@ -110,7 +110,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1714](https://github.com/
> **ratioPct95**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1715](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1715)
Defined in: [Developer/brk/modules/brk-client/index.js:1833](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1833)
***
@@ -118,7 +118,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1715](https://github.com/
> **ratioPct95Usd**: [`_0sdUsdPattern`](0sdUsdPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:1716](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1716)
Defined in: [Developer/brk/modules/brk-client/index.js:1834](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1834)
***
@@ -126,7 +126,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1716](https://github.com/
> **ratioPct98**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1717](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1717)
Defined in: [Developer/brk/modules/brk-client/index.js:1835](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1835)
***
@@ -134,7 +134,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1717](https://github.com/
> **ratioPct98Usd**: [`_0sdUsdPattern`](0sdUsdPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:1718](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1718)
Defined in: [Developer/brk/modules/brk-client/index.js:1836](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1836)
***
@@ -142,7 +142,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1718](https://github.com/
> **ratioPct99**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1719](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1719)
Defined in: [Developer/brk/modules/brk-client/index.js:1837](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1837)
***
@@ -150,7 +150,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1719](https://github.com/
> **ratioPct99Usd**: [`_0sdUsdPattern`](0sdUsdPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:1720](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1720)
Defined in: [Developer/brk/modules/brk-client/index.js:1838](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1838)
***
@@ -158,4 +158,4 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1720](https://github.com/
> **ratioSd**: [`Ratio1ySdPattern`](Ratio1ySdPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:1721](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1721)
Defined in: [Developer/brk/modules/brk-client/index.js:1839](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L1839)
@@ -6,7 +6,7 @@
# Interface: ActiveSupplyPattern
Defined in: [Developer/brk/modules/brk-client/index.js:2645](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2645)
Defined in: [Developer/brk/modules/brk-client/index.js:2679](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2679)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2645](https://github.com/
> **bitcoin**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2646](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2646)
Defined in: [Developer/brk/modules/brk-client/index.js:2680](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2680)
***
@@ -22,7 +22,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2646](https://github.com/
> **dollars**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2647](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2647)
Defined in: [Developer/brk/modules/brk-client/index.js:2681](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2681)
***
@@ -30,4 +30,4 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2647](https://github.com/
> **sats**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2648](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2648)
Defined in: [Developer/brk/modules/brk-client/index.js:2682](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2682)
@@ -6,7 +6,7 @@
# Interface: ActivityPattern2
Defined in: [Developer/brk/modules/brk-client/index.js:2490](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2490)
Defined in: [Developer/brk/modules/brk-client/index.js:2608](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2608)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2490](https://github.com/
> **coinblocksDestroyed**: [`BlockCountPattern`](BlockCountPattern.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2491](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2491)
Defined in: [Developer/brk/modules/brk-client/index.js:2609](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2609)
***
@@ -22,7 +22,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2491](https://github.com/
> **coindaysDestroyed**: [`BlockCountPattern`](BlockCountPattern.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2492](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2492)
Defined in: [Developer/brk/modules/brk-client/index.js:2610](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2610)
***
@@ -30,7 +30,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2492](https://github.com/
> **satblocksDestroyed**: [`MetricPattern11`](../type-aliases/MetricPattern11.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2493](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2493)
Defined in: [Developer/brk/modules/brk-client/index.js:2611](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2611)
***
@@ -38,7 +38,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2493](https://github.com/
> **satdaysDestroyed**: [`MetricPattern11`](../type-aliases/MetricPattern11.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2494](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2494)
Defined in: [Developer/brk/modules/brk-client/index.js:2612](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2612)
***
@@ -46,4 +46,4 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2494](https://github.com/
> **sent**: [`UnclaimedRewardsPattern`](UnclaimedRewardsPattern.md)
Defined in: [Developer/brk/modules/brk-client/index.js:2495](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2495)
Defined in: [Developer/brk/modules/brk-client/index.js:2613](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2613)
@@ -6,7 +6,7 @@
# Interface: AddrCountPattern
Defined in: [Developer/brk/modules/brk-client/index.js:2155](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2155)
Defined in: [Developer/brk/modules/brk-client/index.js:2273](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2273)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2155](https://github.com/
> **all**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2156](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2156)
Defined in: [Developer/brk/modules/brk-client/index.js:2274](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2274)
***
@@ -22,7 +22,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2156](https://github.com/
> **p2a**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2157](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2157)
Defined in: [Developer/brk/modules/brk-client/index.js:2275](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2275)
***
@@ -30,7 +30,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2157](https://github.com/
> **p2pk33**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2158](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2158)
Defined in: [Developer/brk/modules/brk-client/index.js:2276](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2276)
***
@@ -38,7 +38,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2158](https://github.com/
> **p2pk65**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2159](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2159)
Defined in: [Developer/brk/modules/brk-client/index.js:2277](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2277)
***
@@ -46,7 +46,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2159](https://github.com/
> **p2pkh**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2160](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2160)
Defined in: [Developer/brk/modules/brk-client/index.js:2278](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2278)
***
@@ -54,7 +54,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2160](https://github.com/
> **p2sh**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2161](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2161)
Defined in: [Developer/brk/modules/brk-client/index.js:2279](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2279)
***
@@ -62,7 +62,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2161](https://github.com/
> **p2tr**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2162](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2162)
Defined in: [Developer/brk/modules/brk-client/index.js:2280](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2280)
***
@@ -70,7 +70,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2162](https://github.com/
> **p2wpkh**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2163](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2163)
Defined in: [Developer/brk/modules/brk-client/index.js:2281](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2281)
***
@@ -78,4 +78,4 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2163](https://github.com/
> **p2wsh**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2164](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2164)
Defined in: [Developer/brk/modules/brk-client/index.js:2282](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2282)
@@ -6,7 +6,7 @@
# Interface: AddressChainStats
Defined in: [Developer/brk/modules/brk-client/index.js:16](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L16)
Defined in: [Developer/brk/modules/brk-client/index.js:16](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L16)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:16](https://github.com/bi
> **fundedTxoCount**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:17](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L17)
Defined in: [Developer/brk/modules/brk-client/index.js:17](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L17)
Total number of transaction outputs that funded this address
@@ -24,7 +24,7 @@ Total number of transaction outputs that funded this address
> **fundedTxoSum**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:18](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L18)
Defined in: [Developer/brk/modules/brk-client/index.js:18](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L18)
Total amount in satoshis received by this address across all funded outputs
@@ -34,7 +34,7 @@ Total amount in satoshis received by this address across all funded outputs
> **spentTxoCount**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:19](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L19)
Defined in: [Developer/brk/modules/brk-client/index.js:19](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L19)
Total number of transaction outputs spent from this address
@@ -44,7 +44,7 @@ Total number of transaction outputs spent from this address
> **spentTxoSum**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:20](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L20)
Defined in: [Developer/brk/modules/brk-client/index.js:20](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L20)
Total amount in satoshis spent from this address
@@ -54,7 +54,7 @@ Total amount in satoshis spent from this address
> **txCount**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:21](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L21)
Defined in: [Developer/brk/modules/brk-client/index.js:21](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L21)
Total number of confirmed transactions involving this address
@@ -64,6 +64,6 @@ Total number of confirmed transactions involving this address
> **typeIndex**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:22](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L22)
Defined in: [Developer/brk/modules/brk-client/index.js:22](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L22)
Index of this address within its type on the blockchain
@@ -6,7 +6,7 @@
# Interface: AddressMempoolStats
Defined in: [Developer/brk/modules/brk-client/index.js:29](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L29)
Defined in: [Developer/brk/modules/brk-client/index.js:29](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L29)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:29](https://github.com/bi
> **fundedTxoCount**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:30](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L30)
Defined in: [Developer/brk/modules/brk-client/index.js:30](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L30)
Number of unconfirmed transaction outputs funding this address
@@ -24,7 +24,7 @@ Number of unconfirmed transaction outputs funding this address
> **fundedTxoSum**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:31](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L31)
Defined in: [Developer/brk/modules/brk-client/index.js:31](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L31)
Total amount in satoshis being received in unconfirmed transactions
@@ -34,7 +34,7 @@ Total amount in satoshis being received in unconfirmed transactions
> **spentTxoCount**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:32](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L32)
Defined in: [Developer/brk/modules/brk-client/index.js:32](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L32)
Number of unconfirmed transaction inputs spending from this address
@@ -44,7 +44,7 @@ Number of unconfirmed transaction inputs spending from this address
> **spentTxoSum**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:33](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L33)
Defined in: [Developer/brk/modules/brk-client/index.js:33](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L33)
Total amount in satoshis being spent in unconfirmed transactions
@@ -54,6 +54,6 @@ Total amount in satoshis being spent in unconfirmed transactions
> **txCount**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:34](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L34)
Defined in: [Developer/brk/modules/brk-client/index.js:34](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L34)
Number of unconfirmed transactions involving this address
@@ -6,7 +6,7 @@
# Interface: AddressParam
Defined in: [Developer/brk/modules/brk-client/index.js:37](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L37)
Defined in: [Developer/brk/modules/brk-client/index.js:37](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L37)
## Properties
@@ -14,4 +14,4 @@ Defined in: [Developer/brk/modules/brk-client/index.js:37](https://github.com/bi
> **address**: `string`
Defined in: [Developer/brk/modules/brk-client/index.js:38](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L38)
Defined in: [Developer/brk/modules/brk-client/index.js:38](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L38)
@@ -6,7 +6,7 @@
# Interface: AddressStats
Defined in: [Developer/brk/modules/brk-client/index.js:43](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L43)
Defined in: [Developer/brk/modules/brk-client/index.js:43](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L43)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:43](https://github.com/bi
> **address**: `string`
Defined in: [Developer/brk/modules/brk-client/index.js:44](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L44)
Defined in: [Developer/brk/modules/brk-client/index.js:44](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L44)
Bitcoin address string
@@ -24,7 +24,7 @@ Bitcoin address string
> **chainStats**: [`AddressChainStats`](AddressChainStats.md)
Defined in: [Developer/brk/modules/brk-client/index.js:45](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L45)
Defined in: [Developer/brk/modules/brk-client/index.js:45](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L45)
Statistics for confirmed transactions on the blockchain
@@ -34,6 +34,6 @@ Statistics for confirmed transactions on the blockchain
> `optional` **mempoolStats**: [`AddressMempoolStats`](AddressMempoolStats.md) \| `null`
Defined in: [Developer/brk/modules/brk-client/index.js:46](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L46)
Defined in: [Developer/brk/modules/brk-client/index.js:46](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L46)
Statistics for unconfirmed transactions in the mempool
@@ -6,7 +6,7 @@
# Interface: AddressTxidsParam
Defined in: [Developer/brk/modules/brk-client/index.js:49](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L49)
Defined in: [Developer/brk/modules/brk-client/index.js:49](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L49)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:49](https://github.com/bi
> `optional` **afterTxid**: `string` \| `null`
Defined in: [Developer/brk/modules/brk-client/index.js:50](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L50)
Defined in: [Developer/brk/modules/brk-client/index.js:50](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L50)
Txid to paginate from (return transactions before this one)
@@ -24,6 +24,6 @@ Txid to paginate from (return transactions before this one)
> `optional` **limit**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:51](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L51)
Defined in: [Developer/brk/modules/brk-client/index.js:51](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L51)
Maximum number of results to return. Defaults to 25 if not specified.
@@ -6,7 +6,7 @@
# Interface: AddressValidation
Defined in: [Developer/brk/modules/brk-client/index.js:56](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L56)
Defined in: [Developer/brk/modules/brk-client/index.js:56](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L56)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:56](https://github.com/bi
> `optional` **address**: `string` \| `null`
Defined in: [Developer/brk/modules/brk-client/index.js:58](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L58)
Defined in: [Developer/brk/modules/brk-client/index.js:58](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L58)
The validated address
@@ -24,7 +24,7 @@ The validated address
> `optional` **isscript**: `boolean` \| `null`
Defined in: [Developer/brk/modules/brk-client/index.js:60](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L60)
Defined in: [Developer/brk/modules/brk-client/index.js:60](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L60)
Whether this is a script address (P2SH)
@@ -34,7 +34,7 @@ Whether this is a script address (P2SH)
> **isvalid**: `boolean`
Defined in: [Developer/brk/modules/brk-client/index.js:57](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L57)
Defined in: [Developer/brk/modules/brk-client/index.js:57](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L57)
Whether the address is valid
@@ -44,7 +44,7 @@ Whether the address is valid
> `optional` **iswitness**: `boolean` \| `null`
Defined in: [Developer/brk/modules/brk-client/index.js:61](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L61)
Defined in: [Developer/brk/modules/brk-client/index.js:61](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L61)
Whether this is a witness address
@@ -54,7 +54,7 @@ Whether this is a witness address
> `optional` **scriptPubKey**: `string` \| `null`
Defined in: [Developer/brk/modules/brk-client/index.js:59](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L59)
Defined in: [Developer/brk/modules/brk-client/index.js:59](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L59)
The scriptPubKey in hex
@@ -64,7 +64,7 @@ The scriptPubKey in hex
> `optional` **witnessProgram**: `string` \| `null`
Defined in: [Developer/brk/modules/brk-client/index.js:63](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L63)
Defined in: [Developer/brk/modules/brk-client/index.js:63](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L63)
Witness program in hex
@@ -74,6 +74,6 @@ Witness program in hex
> `optional` **witnessVersion**: `number` \| `null`
Defined in: [Developer/brk/modules/brk-client/index.js:62](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L62)
Defined in: [Developer/brk/modules/brk-client/index.js:62](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L62)
Witness version (0 for P2WPKH/P2WSH, 1 for P2TR)
@@ -0,0 +1,57 @@
[**brk-client**](../README.md)
***
[brk-client](../globals.md) / AllPattern
# Interface: AllPattern
Defined in: [Developer/brk/modules/brk-client/index.js:2581](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2581)
## Properties
### balanceDecreased
> **balanceDecreased**: [`FullnessPattern`](FullnessPattern.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2582](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2582)
***
### balanceIncreased
> **balanceIncreased**: [`FullnessPattern`](FullnessPattern.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2583](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2583)
***
### both
> **both**: [`FullnessPattern`](FullnessPattern.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2584](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2584)
***
### reactivated
> **reactivated**: [`FullnessPattern`](FullnessPattern.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2585](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2585)
***
### receiving
> **receiving**: [`FullnessPattern`](FullnessPattern.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2586](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2586)
***
### sending
> **sending**: [`FullnessPattern`](FullnessPattern.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2587](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2587)
@@ -6,7 +6,7 @@
# Interface: BitcoinPattern
Defined in: [Developer/brk/modules/brk-client/index.js:1972](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1972)
Defined in: [Developer/brk/modules/brk-client/index.js:2090](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2090)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1972](https://github.com/
> **average**: [`MetricPattern2`](../type-aliases/MetricPattern2.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1973](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1973)
Defined in: [Developer/brk/modules/brk-client/index.js:2091](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2091)
***
@@ -22,7 +22,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1973](https://github.com/
> **base**: [`MetricPattern11`](../type-aliases/MetricPattern11.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1974](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1974)
Defined in: [Developer/brk/modules/brk-client/index.js:2092](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2092)
***
@@ -30,7 +30,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1974](https://github.com/
> **cumulative**: [`MetricPattern2`](../type-aliases/MetricPattern2.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1975](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1975)
Defined in: [Developer/brk/modules/brk-client/index.js:2093](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2093)
***
@@ -38,7 +38,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1975](https://github.com/
> **max**: [`MetricPattern2`](../type-aliases/MetricPattern2.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1976](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1976)
Defined in: [Developer/brk/modules/brk-client/index.js:2094](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2094)
***
@@ -46,7 +46,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1976](https://github.com/
> **median**: [`MetricPattern6`](../type-aliases/MetricPattern6.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1977](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1977)
Defined in: [Developer/brk/modules/brk-client/index.js:2095](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2095)
***
@@ -54,7 +54,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1977](https://github.com/
> **min**: [`MetricPattern2`](../type-aliases/MetricPattern2.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1978](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1978)
Defined in: [Developer/brk/modules/brk-client/index.js:2096](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2096)
***
@@ -62,7 +62,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1978](https://github.com/
> **pct10**: [`MetricPattern6`](../type-aliases/MetricPattern6.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1979](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1979)
Defined in: [Developer/brk/modules/brk-client/index.js:2097](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2097)
***
@@ -70,7 +70,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1979](https://github.com/
> **pct25**: [`MetricPattern6`](../type-aliases/MetricPattern6.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1980](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1980)
Defined in: [Developer/brk/modules/brk-client/index.js:2098](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2098)
***
@@ -78,7 +78,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1980](https://github.com/
> **pct75**: [`MetricPattern6`](../type-aliases/MetricPattern6.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1981](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1981)
Defined in: [Developer/brk/modules/brk-client/index.js:2099](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2099)
***
@@ -86,7 +86,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1981](https://github.com/
> **pct90**: [`MetricPattern6`](../type-aliases/MetricPattern6.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1982](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1982)
Defined in: [Developer/brk/modules/brk-client/index.js:2100](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2100)
***
@@ -94,4 +94,4 @@ Defined in: [Developer/brk/modules/brk-client/index.js:1982](https://github.com/
> **sum**: [`MetricPattern2`](../type-aliases/MetricPattern2.md)\<`number`\>
Defined in: [Developer/brk/modules/brk-client/index.js:1983](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L1983)
Defined in: [Developer/brk/modules/brk-client/index.js:2101](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2101)
@@ -6,7 +6,7 @@
# Interface: BitcoinPattern2\<T\>
Defined in: [Developer/brk/modules/brk-client/index.js:2844](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2844)
Defined in: [Developer/brk/modules/brk-client/index.js:2941](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2941)
## Type Parameters
@@ -20,7 +20,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2844](https://github.com/
> **cumulative**: [`MetricPattern2`](../type-aliases/MetricPattern2.md)\<`T`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2845](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2845)
Defined in: [Developer/brk/modules/brk-client/index.js:2942](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2942)
***
@@ -28,4 +28,4 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2845](https://github.com/
> **sum**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`T`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2846](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2846)
Defined in: [Developer/brk/modules/brk-client/index.js:2943](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2943)
@@ -6,7 +6,7 @@
# Interface: BlockCountParam
Defined in: [Developer/brk/modules/brk-client/index.js:81](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L81)
Defined in: [Developer/brk/modules/brk-client/index.js:81](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L81)
## Properties
@@ -14,6 +14,6 @@ Defined in: [Developer/brk/modules/brk-client/index.js:81](https://github.com/bi
> **blockCount**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:82](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L82)
Defined in: [Developer/brk/modules/brk-client/index.js:82](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L82)
Number of recent blocks to include
@@ -6,7 +6,7 @@
# Interface: BlockCountPattern\<T\>
Defined in: [Developer/brk/modules/brk-client/index.js:2802](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2802)
Defined in: [Developer/brk/modules/brk-client/index.js:2920](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2920)
## Type Parameters
@@ -20,7 +20,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2802](https://github.com/
> **cumulative**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`T`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2803](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2803)
Defined in: [Developer/brk/modules/brk-client/index.js:2921](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2921)
***
@@ -28,4 +28,4 @@ Defined in: [Developer/brk/modules/brk-client/index.js:2803](https://github.com/
> **sum**: [`MetricPattern1`](../type-aliases/MetricPattern1.md)\<`T`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2804](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L2804)
Defined in: [Developer/brk/modules/brk-client/index.js:2922](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2922)
@@ -6,7 +6,7 @@
# Interface: BlockFeesEntry
Defined in: [Developer/brk/modules/brk-client/index.js:87](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L87)
Defined in: [Developer/brk/modules/brk-client/index.js:87](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L87)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:87](https://github.com/bi
> **avgFees**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:90](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L90)
Defined in: [Developer/brk/modules/brk-client/index.js:90](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L90)
***
@@ -22,7 +22,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:90](https://github.com/bi
> **avgHeight**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:88](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L88)
Defined in: [Developer/brk/modules/brk-client/index.js:88](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L88)
***
@@ -30,4 +30,4 @@ Defined in: [Developer/brk/modules/brk-client/index.js:88](https://github.com/bi
> **timestamp**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:89](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L89)
Defined in: [Developer/brk/modules/brk-client/index.js:89](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L89)
@@ -6,7 +6,7 @@
# Interface: BlockHashParam
Defined in: [Developer/brk/modules/brk-client/index.js:98](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L98)
Defined in: [Developer/brk/modules/brk-client/index.js:98](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L98)
## Properties
@@ -14,4 +14,4 @@ Defined in: [Developer/brk/modules/brk-client/index.js:98](https://github.com/bi
> **hash**: `string`
Defined in: [Developer/brk/modules/brk-client/index.js:99](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L99)
Defined in: [Developer/brk/modules/brk-client/index.js:99](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L99)
@@ -6,7 +6,7 @@
# Interface: BlockHashStartIndex
Defined in: [Developer/brk/modules/brk-client/index.js:102](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L102)
Defined in: [Developer/brk/modules/brk-client/index.js:102](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L102)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:102](https://github.com/b
> **hash**: `string`
Defined in: [Developer/brk/modules/brk-client/index.js:103](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L103)
Defined in: [Developer/brk/modules/brk-client/index.js:103](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L103)
Bitcoin block hash
@@ -24,6 +24,6 @@ Bitcoin block hash
> **startIndex**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:104](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L104)
Defined in: [Developer/brk/modules/brk-client/index.js:104](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L104)
Starting transaction index within the block (0-based)
@@ -6,7 +6,7 @@
# Interface: BlockHashTxIndex
Defined in: [Developer/brk/modules/brk-client/index.js:107](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L107)
Defined in: [Developer/brk/modules/brk-client/index.js:107](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L107)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:107](https://github.com/b
> **hash**: `string`
Defined in: [Developer/brk/modules/brk-client/index.js:108](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L108)
Defined in: [Developer/brk/modules/brk-client/index.js:108](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L108)
Bitcoin block hash
@@ -24,6 +24,6 @@ Bitcoin block hash
> **index**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:109](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L109)
Defined in: [Developer/brk/modules/brk-client/index.js:109](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L109)
Transaction index within the block (0-based)
@@ -6,7 +6,7 @@
# Interface: BlockInfo
Defined in: [Developer/brk/modules/brk-client/index.js:114](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L114)
Defined in: [Developer/brk/modules/brk-client/index.js:114](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L114)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:114](https://github.com/b
> **difficulty**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:121](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L121)
Defined in: [Developer/brk/modules/brk-client/index.js:121](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L121)
Block difficulty as a floating point number
@@ -24,7 +24,7 @@ Block difficulty as a floating point number
> **height**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:116](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L116)
Defined in: [Developer/brk/modules/brk-client/index.js:116](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L116)
Block height
@@ -34,7 +34,7 @@ Block height
> **id**: `string`
Defined in: [Developer/brk/modules/brk-client/index.js:115](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L115)
Defined in: [Developer/brk/modules/brk-client/index.js:115](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L115)
Block hash
@@ -44,7 +44,7 @@ Block hash
> **size**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:118](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L118)
Defined in: [Developer/brk/modules/brk-client/index.js:118](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L118)
Block size in bytes
@@ -54,7 +54,7 @@ Block size in bytes
> **timestamp**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:120](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L120)
Defined in: [Developer/brk/modules/brk-client/index.js:120](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L120)
Block timestamp (Unix time)
@@ -64,7 +64,7 @@ Block timestamp (Unix time)
> **txCount**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:117](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L117)
Defined in: [Developer/brk/modules/brk-client/index.js:117](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L117)
Number of transactions in the block
@@ -74,6 +74,6 @@ Number of transactions in the block
> **weight**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:119](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L119)
Defined in: [Developer/brk/modules/brk-client/index.js:119](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L119)
Block weight in weight units
@@ -6,7 +6,7 @@
# Interface: BlockRewardsEntry
Defined in: [Developer/brk/modules/brk-client/index.js:126](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L126)
Defined in: [Developer/brk/modules/brk-client/index.js:126](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L126)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:126](https://github.com/b
> **avgHeight**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:127](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L127)
Defined in: [Developer/brk/modules/brk-client/index.js:127](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L127)
***
@@ -22,7 +22,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:127](https://github.com/b
> **avgRewards**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:129](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L129)
Defined in: [Developer/brk/modules/brk-client/index.js:129](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L129)
***
@@ -30,4 +30,4 @@ Defined in: [Developer/brk/modules/brk-client/index.js:129](https://github.com/b
> **timestamp**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:128](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L128)
Defined in: [Developer/brk/modules/brk-client/index.js:128](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L128)
@@ -6,7 +6,7 @@
# Interface: BlockSizeEntry
Defined in: [Developer/brk/modules/brk-client/index.js:134](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L134)
Defined in: [Developer/brk/modules/brk-client/index.js:134](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L134)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:134](https://github.com/b
> **avgHeight**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:135](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L135)
Defined in: [Developer/brk/modules/brk-client/index.js:135](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L135)
***
@@ -22,7 +22,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:135](https://github.com/b
> **avgSize**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:137](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L137)
Defined in: [Developer/brk/modules/brk-client/index.js:137](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L137)
***
@@ -30,4 +30,4 @@ Defined in: [Developer/brk/modules/brk-client/index.js:137](https://github.com/b
> **timestamp**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:136](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L136)
Defined in: [Developer/brk/modules/brk-client/index.js:136](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L136)
@@ -6,7 +6,7 @@
# Interface: BlockSizesWeights
Defined in: [Developer/brk/modules/brk-client/index.js:142](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L142)
Defined in: [Developer/brk/modules/brk-client/index.js:142](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L142)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:142](https://github.com/b
> **sizes**: [`BlockSizeEntry`](BlockSizeEntry.md)[]
Defined in: [Developer/brk/modules/brk-client/index.js:143](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L143)
Defined in: [Developer/brk/modules/brk-client/index.js:143](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L143)
***
@@ -22,4 +22,4 @@ Defined in: [Developer/brk/modules/brk-client/index.js:143](https://github.com/b
> **weights**: [`BlockWeightEntry`](BlockWeightEntry.md)[]
Defined in: [Developer/brk/modules/brk-client/index.js:144](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L144)
Defined in: [Developer/brk/modules/brk-client/index.js:144](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L144)
@@ -6,7 +6,7 @@
# Interface: BlockStatus
Defined in: [Developer/brk/modules/brk-client/index.js:149](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L149)
Defined in: [Developer/brk/modules/brk-client/index.js:149](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L149)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:149](https://github.com/b
> `optional` **height**: `number` \| `null`
Defined in: [Developer/brk/modules/brk-client/index.js:151](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L151)
Defined in: [Developer/brk/modules/brk-client/index.js:151](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L151)
Block height (only if in best chain)
@@ -24,7 +24,7 @@ Block height (only if in best chain)
> **inBestChain**: `boolean`
Defined in: [Developer/brk/modules/brk-client/index.js:150](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L150)
Defined in: [Developer/brk/modules/brk-client/index.js:150](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L150)
Whether this block is in the best chain
@@ -34,6 +34,6 @@ Whether this block is in the best chain
> `optional` **nextBest**: `string` \| `null`
Defined in: [Developer/brk/modules/brk-client/index.js:152](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L152)
Defined in: [Developer/brk/modules/brk-client/index.js:152](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L152)
Hash of the next block in the best chain (only if in best chain and not tip)
@@ -6,7 +6,7 @@
# Interface: BlockTimestamp
Defined in: [Developer/brk/modules/brk-client/index.js:157](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L157)
Defined in: [Developer/brk/modules/brk-client/index.js:157](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L157)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:157](https://github.com/b
> **hash**: `string`
Defined in: [Developer/brk/modules/brk-client/index.js:159](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L159)
Defined in: [Developer/brk/modules/brk-client/index.js:159](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L159)
Block hash
@@ -24,7 +24,7 @@ Block hash
> **height**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:158](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L158)
Defined in: [Developer/brk/modules/brk-client/index.js:158](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L158)
Block height
@@ -34,6 +34,6 @@ Block height
> **timestamp**: `string`
Defined in: [Developer/brk/modules/brk-client/index.js:160](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L160)
Defined in: [Developer/brk/modules/brk-client/index.js:160](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L160)
Block timestamp in ISO 8601 format
@@ -6,7 +6,7 @@
# Interface: BlockWeightEntry
Defined in: [Developer/brk/modules/brk-client/index.js:165](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L165)
Defined in: [Developer/brk/modules/brk-client/index.js:165](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L165)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:165](https://github.com/b
> **avgHeight**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:166](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L166)
Defined in: [Developer/brk/modules/brk-client/index.js:166](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L166)
***
@@ -22,7 +22,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:166](https://github.com/b
> **avgWeight**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:168](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L168)
Defined in: [Developer/brk/modules/brk-client/index.js:168](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L168)
***
@@ -30,4 +30,4 @@ Defined in: [Developer/brk/modules/brk-client/index.js:168](https://github.com/b
> **timestamp**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:167](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L167)
Defined in: [Developer/brk/modules/brk-client/index.js:167](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L167)
@@ -6,7 +6,7 @@
# Interface: BrkClientOptions
Defined in: [Developer/brk/modules/brk-client/index.js:806](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L806)
Defined in: [Developer/brk/modules/brk-client/index.js:806](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L806)
## Properties
@@ -14,7 +14,7 @@ Defined in: [Developer/brk/modules/brk-client/index.js:806](https://github.com/b
> **baseUrl**: `string`
Defined in: [Developer/brk/modules/brk-client/index.js:807](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L807)
Defined in: [Developer/brk/modules/brk-client/index.js:807](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L807)
Base URL for the API
@@ -24,7 +24,7 @@ Base URL for the API
> `optional` **cache**: `string` \| `boolean`
Defined in: [Developer/brk/modules/brk-client/index.js:809](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L809)
Defined in: [Developer/brk/modules/brk-client/index.js:809](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L809)
Enable browser cache with default name (true), custom name (string), or disable (false). No effect in Node.js. Default: true
@@ -34,6 +34,6 @@ Enable browser cache with default name (true), custom name (string), or disable
> `optional` **timeout**: `number`
Defined in: [Developer/brk/modules/brk-client/index.js:808](https://github.com/bitcoinresearchkit/brk/blob/ec1f2de5cfe92fbc8dc9dc980bbf7787003b4572/modules/brk-client/index.js#L808)
Defined in: [Developer/brk/modules/brk-client/index.js:808](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L808)
Request timeout in milliseconds
@@ -0,0 +1,111 @@
[**brk-client**](../README.md)
***
[brk-client](../globals.md) / ClassDaysInLossPattern
# Interface: ClassDaysInLossPattern\<T\>
Defined in: [Developer/brk/modules/brk-client/index.js:2050](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2050)
## Type Parameters
### T
`T`
## Properties
### \_2015
> **\_2015**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`T`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2051](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2051)
***
### \_2016
> **\_2016**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`T`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2052](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2052)
***
### \_2017
> **\_2017**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`T`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2053](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2053)
***
### \_2018
> **\_2018**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`T`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2054](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2054)
***
### \_2019
> **\_2019**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`T`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2055](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2055)
***
### \_2020
> **\_2020**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`T`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2056](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2056)
***
### \_2021
> **\_2021**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`T`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2057](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2057)
***
### \_2022
> **\_2022**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`T`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2058](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2058)
***
### \_2023
> **\_2023**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`T`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2059](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2059)
***
### \_2024
> **\_2024**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`T`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2060](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2060)
***
### \_2025
> **\_2025**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`T`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2061](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2061)
***
### \_2026
> **\_2026**: [`MetricPattern4`](../type-aliases/MetricPattern4.md)\<`T`\>
Defined in: [Developer/brk/modules/brk-client/index.js:2062](https://github.com/bitcoinresearchkit/brk/blob/54827cd0a2357417adb8631eb8f53a78e848b39a/modules/brk-client/index.js#L2062)

Some files were not shown because too many files have changed in this diff Show More