Files
explorer-monorepo/docs/feature-flags/track-feature-matrix.md
T

8.1 KiB

Track Feature Matrix

Feature flag mapping for SolaceScanScout Explorer tiered architecture.

Overview

Features are gated by track level. Users with higher track levels automatically have access to lower track features.

Track Level Description
Track 1 1 Public (no auth) - Basic explorer
Track 2 2 Approved users - Full indexed explorer
Track 3 3 Analytics users - Advanced analytics
Track 4 4 Operators - Control panels

UI Components → Track Requirements

Navigation & Layout

Component Track 1 Track 2 Track 3 Track 4
Home page ✅ ✅ ✅ ✅
Blocks list ✅ ✅ ✅ ✅
Transactions list ✅ ✅ ✅ ✅
Address detail (basic) ✅ ✅ ✅ ✅
Address detail (full) ❌ ✅ ✅ ✅
Token balances ❌ ✅ ✅ ✅
Transaction history ❌ ✅ ✅ ✅
Internal transactions ❌ ✅ ✅ ✅
Analytics dashboard ❌ ❌ ✅ ✅
Flow graphs ❌ ❌ ✅ ✅
Bridge analytics ❌ ❌ ✅ ✅
Operator panel ❌ ❌ ❌ ✅
Validator status ❌ ❌ ❌ ✅
Protocol config ❌ ❌ ❌ ✅

Search & Discovery

Feature Track 1 Track 2 Track 3 Track 4
Basic search (block/tx/addr) ✅ ✅ ✅ ✅
Enhanced search (tokens) ❌ ✅ ✅ ✅
Search history ❌ ✅ ✅ ✅
Saved addresses ❌ ✅ ✅ ✅
Advanced filters ❌ ❌ ✅ ✅

Bridge Features

Feature Track 1 Track 2 Track 3 Track 4
Bridge status monitor ✅ ✅ ✅ ✅
Bridge transfer history ❌ ✅ ✅ ✅
Bridge analytics ❌ ❌ ✅ ✅
Bridge control ❌ ❌ ❌ ✅

WETH Utilities

Feature Track 1 Track 2 Track 3 Track 4
WETH wrap/unwrap ✅ ✅ ✅ ✅
WETH balance check ✅ ✅ ✅ ✅
WETH history ❌ ✅ ✅ ✅

API Endpoints → Track Requirements

Track 1 Endpoints (Public)

  • GET /api/v1/track1/blocks/latest - Track 1
  • GET /api/v1/track1/txs/latest - Track 1
  • GET /api/v1/track1/block/:number - Track 1
  • GET /api/v1/track1/tx/:hash - Track 1
  • GET /api/v1/track1/address/:addr/balance - Track 1
  • GET /api/v1/track1/bridge/status - Track 1

Track 2 Endpoints (Approved)

  • GET /api/v1/track2/address/:addr/txs - Track 2+
  • GET /api/v1/track2/address/:addr/tokens - Track 2+
  • GET /api/v1/track2/token/:contract - Track 2+
  • GET /api/v1/track2/search?q= - Track 2+
  • GET /api/v1/track2/address/:addr/internal-txs - Track 2+

Track 3 Endpoints (Analytics)

  • GET /api/v1/track3/analytics/flows - Track 3+
  • GET /api/v1/track3/analytics/bridge - Track 3+
  • GET /api/v1/track3/analytics/token-distribution - Track 3+
  • GET /api/v1/track3/analytics/address-risk - Track 3+

Track 4 Endpoints (Operator)

  • GET /api/v1/track4/operator/bridge/events - Track 4 only
  • GET /api/v1/track4/operator/validators - Track 4 only
  • GET /api/v1/track4/operator/contracts - Track 4 only
  • GET /api/v1/track4/operator/protocol-state - Track 4 only

Frontend Routes → Track Requirements

Route Track 1 Track 2 Track 3 Track 4
/ (Home) ✅ ✅ ✅ ✅
/blocks ✅ ✅ ✅ ✅
/blocks/:number ✅ ✅ ✅ ✅
/transactions ✅ ✅ ✅ ✅
/transactions/:hash ✅ ✅ ✅ ✅
/address/:addr (basic) ✅ ✅ ✅ ✅
/address/:addr (full) ❌ ✅ ✅ ✅
/address/:addr/tokens ❌ ✅ ✅ ✅
/address/:addr/txs ❌ ✅ ✅ ✅
/token/:contract ❌ ✅ ✅ ✅
/analytics ❌ ❌ ✅ ✅
/analytics/flows ❌ ❌ ✅ ✅
/analytics/bridge ❌ ❌ ✅ ✅
/operator ❌ ❌ ❌ ✅
/operator/bridge ❌ ❌ ❌ ✅
/operator/validators ❌ ❌ ❌ ✅

Feature Flag Implementation

Backend Feature Flags

type FeatureFlag struct {
    Name        string
    RequiredTrack int
    Description string
}

var FeatureFlags = map[string]FeatureFlag{
    "address_full_detail": {Name: "address_full_detail", RequiredTrack: 2},
    "token_balances": {Name: "token_balances", RequiredTrack: 2},
    "tx_history": {Name: "tx_history", RequiredTrack: 2},
    "internal_txs": {Name: "internal_txs", RequiredTrack: 2},
    "analytics_dashboard": {Name: "analytics_dashboard", RequiredTrack: 3},
    "flow_tracking": {Name: "flow_tracking", RequiredTrack: 3},
    "bridge_analytics": {Name: "bridge_analytics", RequiredTrack: 3},
    "operator_panel": {Name: "operator_panel", RequiredTrack: 4},
    "validator_status": {Name: "validator_status", RequiredTrack: 4},
    "protocol_config": {Name: "protocol_config", RequiredTrack: 4},
}

Frontend Feature Flags

const FEATURE_FLAGS = {
    ADDRESS_FULL_DETAIL: { track: 2 },
    TOKEN_BALANCES: { track: 2 },
    TX_HISTORY: { track: 2 },
    INTERNAL_TXS: { track: 2 },
    ANALYTICS_DASHBOARD: { track: 3 },
    FLOW_TRACKING: { track: 3 },
    BRIDGE_ANALYTICS: { track: 3 },
    OPERATOR_PANEL: { track: 4 },
    VALIDATOR_STATUS: { track: 4 },
    PROTOCOL_CONFIG: { track: 4 },
};

Permission Mapping

Track 1 (Public)

{
  "permissions": [
    "explorer.read.blocks",
    "explorer.read.transactions",
    "explorer.read.address.basic",
    "explorer.read.bridge.status",
    "weth.wrap",
    "weth.unwrap"
  ]
}

Track 2 (Approved)

{
  "permissions": [
    "explorer.read.blocks",
    "explorer.read.transactions",
    "explorer.read.address.full",
    "explorer.read.tokens",
    "explorer.read.tx_history",
    "explorer.read.internal_txs",
    "explorer.search.enhanced",
    "explorer.read.bridge.status",
    "weth.wrap",
    "weth.unwrap"
  ]
}

Track 3 (Analytics)

{
  "permissions": [
    "explorer.read.blocks",
    "explorer.read.transactions",
    "explorer.read.address.full",
    "explorer.read.tokens",
    "explorer.read.tx_history",
    "explorer.read.internal_txs",
    "explorer.search.enhanced",
    "explorer.read.bridge.status",
    "analytics.read.flows",
    "analytics.read.bridge",
    "analytics.read.token_distribution",
    "analytics.read.address_risk",
    "weth.wrap",
    "weth.unwrap"
  ]
}

Track 4 (Operator)

{
  "permissions": [
    "explorer.read.blocks",
    "explorer.read.transactions",
    "explorer.read.address.full",
    "explorer.read.tokens",
    "explorer.read.tx_history",
    "explorer.read.internal_txs",
    "explorer.search.enhanced",
    "explorer.read.bridge.status",
    "analytics.read.flows",
    "analytics.read.bridge",
    "analytics.read.token_distribution",
    "analytics.read.address_risk",
    "operator.read.bridge_events",
    "operator.read.validators",
    "operator.read.contracts",
    "operator.read.protocol_state",
    "operator.write.bridge_control",
    "weth.wrap",
    "weth.unwrap"
  ]
}

Feature Gate Logic

Backend

func HasAccess(userTrack int, requiredTrack int) bool {
    return userTrack >= requiredTrack
}

Frontend

function hasAccess(userTrack, requiredTrack) {
    return userTrack >= requiredTrack;
}

function isFeatureEnabled(featureName, userTrack) {
    const feature = FEATURE_FLAGS[featureName];
    if (!feature) return false;
    return hasAccess(userTrack, feature.track);
}

Feature Flag API Endpoint

GET /api/v1/features

Get available features for current user.

Response:

{
  "track": 2,
  "features": {
    "address_full_detail": true,
    "token_balances": true,
    "tx_history": true,
    "internal_txs": true,
    "analytics_dashboard": false,
    "flow_tracking": false,
    "bridge_analytics": false,
    "operator_panel": false,
    "validator_status": false,
    "protocol_config": false
  },
  "permissions": [...]
}