282 lines
8.1 KiB
Markdown
282 lines
8.1 KiB
Markdown
|
|
# 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
|
||
|
|
|
||
|
|
```go
|
||
|
|
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
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
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)
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"permissions": [
|
||
|
|
"explorer.read.blocks",
|
||
|
|
"explorer.read.transactions",
|
||
|
|
"explorer.read.address.basic",
|
||
|
|
"explorer.read.bridge.status",
|
||
|
|
"weth.wrap",
|
||
|
|
"weth.unwrap"
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Track 2 (Approved)
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"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)
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"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)
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"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
|
||
|
|
```go
|
||
|
|
func HasAccess(userTrack int, requiredTrack int) bool {
|
||
|
|
return userTrack >= requiredTrack
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Frontend
|
||
|
|
```javascript
|
||
|
|
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:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"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": [...]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|