Spectraplex is a Rust multi-chain indexing and normalization system for blockchain ETL. It ingests raw chain data into canonical data tiers (Bronze records, materializes reusable Silver and Gold datasets) and exposes both compatibility wallet endpoints and newer target- and dataset-oriented APIs.
The project treats wallets, contracts, programs, markets, pools, and protocol analytics as first-class indexing targets.
- Bronze storage for raw chain transactions and events
- Silver datasets for transfers, balance deltas, decoded events, fills, funding, and positions
- Gold datasets for wallet ledger, balance history, Hyperliquid analytics, protocol activity, and TVL
- Legacy wallet-centric CLI and API flows
- V2 target and network primitives for broader indexing use cases
- Export jobs with JSONL and CSV output
Current ingestion adapters:
| Family | Chain / Source | Current status |
|---|---|---|
| Solana | RPC and Yellowstone gRPC | Implemented |
| EVM | eth_getLogs via alloy |
Implemented |
| Hyperliquid | REST and WebSocket | Implemented |
Seeded V2 networks after init-db:
| Network ID | Family | Notes |
|---|---|---|
solana-mainnet |
solana |
probabilistic-slot finality |
ethereum-mainnet |
evm |
probabilistic-block finality |
base-mainnet |
evm |
deterministic-block finality |
arbitrum-mainnet |
evm |
deterministic-block finality |
hyperevm-mainnet |
evm |
deterministic-block finality |
hypercore-mainnet |
hyperliquid |
instant finality |
| Path | Purpose |
|---|---|
core/ |
shared config, V1/V2 models, target and materializer types |
adapters/ |
chain adapters, parsers, dataset derivation, repository layer |
cli/ |
CLI entry points for DB setup, ingestion, normalization, and V2 target management |
api/ |
Axum API server for ingestion, queries, exports, and analytics |
migrations/ |
PostgreSQL schema and seed data |
- Rust stable
- PostgreSQL 14+
- Docker, if you want the bundled local database
git clone https://github.com/user1303836/spectraplex.git
cd spectraplex
cargo build --workspacedocker-compose up -dOr point DATABASE_URL at an existing PostgreSQL instance.
Spectraplex loads configuration from:
- defaults
spectraplex.tomlSPECTRAPLEX_*environment variables- direct env vars such as
DATABASE_URL
Start from the example file if you want a local config:
cp spectraplex.toml.example spectraplex.tomlMost useful environment variables:
export DATABASE_URL=postgresql://localhost/spectraplex
export SPECTRAPLEX_API_KEY=change-me
export SOLANA_RPC_URL=https://api.mainnet-beta.solana.com
export EVM_RPC_URL=https://eth.llamarpc.com
# Optional:
export SOLANA_GRPC_URL=https://your-yellowstone-endpoint
export SOLANA_GRPC_TOKEN=your-token
export SPECTRAPLEX_ALLOWED_WALLETS=<wallet1>,<wallet2>cargo run --bin spectraplex-cli -- --db-url "$DATABASE_URL" init-dbcargo run --bin spectraplex-cli -- --db-url "$DATABASE_URL" list-networksWallet compatibility path:
cargo run --bin spectraplex-cli -- --db-url "$DATABASE_URL" ingest \
--chain solana \
--wallet <WALLET_ADDRESS> \
--rpc "$SOLANA_RPC_URL" \
--limit 10Solana gRPC:
cargo run --bin spectraplex-cli -- --db-url "$DATABASE_URL" ingest \
--chain solana \
--wallet <WALLET_ADDRESS> \
--grpc-url "$SOLANA_GRPC_URL" \
--x-token "$SOLANA_GRPC_TOKEN" \
--limit 10EVM:
cargo run --bin spectraplex-cli -- --db-url "$DATABASE_URL" ingest \
--chain ethereum \
--wallet <EVM_ADDRESS> \
--rpc "$EVM_RPC_URL" \
--limit 10Hyperliquid:
cargo run --bin spectraplex-cli -- --db-url "$DATABASE_URL" ingest \
--chain hyperliquid \
--wallet <HYPERLIQUID_ADDRESS> \
--limit 10cargo run --bin spectraplex-cli -- --db-url "$DATABASE_URL" normalize \
--input db:<WALLET_ADDRESS>Wallet target:
cargo run --bin spectraplex-cli -- --db-url "$DATABASE_URL" register-target \
--kind wallet \
--network solana-mainnet \
--address <WALLET_ADDRESS> \
--mode both \
--label "Primary wallet"Topic filter target:
cargo run --bin spectraplex-cli -- --db-url "$DATABASE_URL" register-target \
--kind topic_filter \
--network ethereum-mainnet \
--filter-spec '{"topics":["0xddf252ad00000000000000000000000000000000000000000000000000000000"]}' \
--mode backfill \
--label "ERC20 transfers"cargo run --bin spectraplex-apiThe API binds to SPECTRAPLEX_HOST:SPECTRAPLEX_PORT, defaulting to 127.0.0.1:3000.
cargo run --bin spectraplex-cli -- --helpCurrent commands:
init-dbingestnormalizeregister-targetlist-targetslist-networks
Examples:
cargo run --bin spectraplex-cli -- --db-url "$DATABASE_URL" list-targets
cargo run --bin spectraplex-cli -- --db-url "$DATABASE_URL" list-targets --network solana-mainnet
cargo run --bin spectraplex-cli -- --db-url "$DATABASE_URL" list-targets --kind walletAll /v1/* routes require:
Authorization: Bearer <SPECTRAPLEX_API_KEY>
/health does not require auth.
POST /v1/ingestPOST /v1/ingest/batchPOST /v1/normalizeGET /v1/jobs/:job_idGET /v1/transactions/:walletGET /v1/transactions/:wallet/:tx_hashGET /v1/ledger/:walletGET /v1/export/:walletGET /v1/balances/:walletGET /v1/stats/:walletPOST /v1/stream/startPOST /v1/stream/:stream_id/stopGET /v1/streams
POST /v1/targetsGET /v1/targetsGET /v1/targets/:target_idGET /v1/networksGET /v1/networks/:network_idGET /v1/datasetsGET /v1/datasets/:name/versionsGET /v1/datasets/:name/recordsGET /v1/datasets/:name/completenessGET /v1/datasets/:name/statusPOST /v1/export/datasetGET /v1/export/jobs/:job_idGET /v1/export/jobs/:job_id/download
GET /v1/export/taxGET /v1/forensics/activityGET /v1/analytics/hl/traderGET /v1/analytics/hl/marketGET /v1/analytics/protocol/activityGET /v1/analytics/protocol/tvl
Health:
curl http://127.0.0.1:3000/healthList networks:
curl -H "Authorization: Bearer $SPECTRAPLEX_API_KEY" \
http://127.0.0.1:3000/v1/networksRegister a target:
curl -X POST http://127.0.0.1:3000/v1/targets \
-H "Authorization: Bearer $SPECTRAPLEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"kind": "wallet",
"network": "solana-mainnet",
"address": "<WALLET_ADDRESS>",
"mode": "both",
"label": "Primary wallet"
}'Query a dataset:
curl -H "Authorization: Bearer $SPECTRAPLEX_API_KEY" \
"http://127.0.0.1:3000/v1/datasets/token_transfers/records?network=solana-mainnet&limit=50"Create a dataset export job:
curl -X POST http://127.0.0.1:3000/v1/export/dataset \
-H "Authorization: Bearer $SPECTRAPLEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"dataset": "wallet_ledger",
"format": "csv",
"network": "solana-mainnet"
}'Dataset export jobs support optional sinks:
local_filewebhook
Example webhook sink:
curl -X POST http://127.0.0.1:3000/v1/export/dataset \
-H "Authorization: Bearer $SPECTRAPLEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"dataset": "protocol_events",
"format": "jsonl",
"sink": {
"sink_type": "webhook",
"url": "https://example.com/ingest"
}
}'Datasets exposed today:
token_transfersnative_balance_deltasdecoded_eventshl_fillshl_fundingpositionswallet_ledgerbalance_historyhl_pnl_summaryhl_trade_historyprotocol_eventspool_snapshots
cargo fmt --all --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace- Wallet ingestion and wallet query paths are still the most mature parts of the system.
- V2 target registration and dataset APIs exist, but ingestion orchestration is still uneven across target kinds.
- Local planning and research files are intentionally kept out of version control.