bitcoin-heuristics 0.1.0

Pattern detection heuristics for Bitcoin on-chain analytics — consolidations, distributions, CoinJoin, fee spikes, dormant supply reactivation and more
Documentation
use evidence_chain::EvidenceChain;
use serde::{Deserialize, Serialize};

/// Result of a heuristic pattern match on a Bitcoin transaction.
///
/// Returned by [`crate::heuristics::Heuristic::evaluate`] when a pattern is detected.
/// The registry populates [`HeuristicMatch::evidence`] automatically by calling
/// [`crate::heuristics::Heuristic::build_evidence`] for every match.
///
/// # Example
///
/// ```
/// use bitcoin_heuristics::{HeuristicRegistry, TxFeatures};
///
/// let registry = HeuristicRegistry::default_registry(0.7);
/// let features = TxFeatures::default();
/// let matches = registry.evaluate_all(&features);
/// for m in &matches {
///     println!("{}: {}", m.event_type, m.summary);
/// }
/// ```
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HeuristicMatch {
    /// Unique identifier of the heuristic that fired (e.g. `"institutional-consolidation-v1"`).
    pub id: String,
    /// Semantic version of the heuristic (e.g. `"1.0.0"`).
    pub version: String,
    /// Machine-readable event type (e.g. `"institutional_consolidation"`).
    pub event_type: String,
    /// Short pattern label (e.g. `"structural_consolidation"`).
    pub pattern: String,
    /// Trigger scope: `"transaction"` or `"block"`.
    pub trigger_scope: String,
    /// Human-readable summary of the detected pattern.
    pub summary: String,
    /// Structured feature snapshot used to detect this pattern.
    pub features: serde_json::Value,
    /// Explainability chain — `Some` when `build_evidence` is implemented.
    pub evidence: Option<EvidenceChain>,
}

impl HeuristicMatch {
    /// Creates a new match result.
    pub fn new(
        id: &'static str,
        version: &'static str,
        event_type: &'static str,
        pattern: &'static str,
        trigger_scope: &'static str,
        summary: String,
        features: serde_json::Value,
    ) -> Self {
        Self {
            id: id.to_string(),
            version: version.to_string(),
            event_type: event_type.to_string(),
            pattern: pattern.to_string(),
            trigger_scope: trigger_scope.to_string(),
            summary,
            features,
            evidence: None,
        }
    }
}