4.7 KiB
Explorer unification — luxfi/explorer
Target: one binary, one Docker image, one deploy — serving the indexer + graph + frontend for any number of chains (Lux, Zoo, Hanzo, SPC, Pars, local 1337s, and white-label tenants), white-labeled by hostname at the ingress.
Owner: lux/cli drives config; luxfi/explorer is the runtime.
Current state (as of this doc)
| Component | Location | Status |
|---|---|---|
| Indexer + FE server | lux/indexer/cmd/explorer/ (Go, 587 LoC main) |
working, multi-chain, go:embed Vite assets |
| Graph engine | lux/graph/cmd/graph/ (Go, separate binary) |
working, GraphQL subgraph queries |
| Explorer FE | lux/explore/ (Next.js 16) |
working, stateless SSR (see commit 275285e26) |
| Hanzo Base coupling | 7 files under lux/indexer/explorer/ |
to remove |
| CLI | lux/cli/cmd/explorecmd/explore.go |
wraps the indexer binary |
Plan
1. Rename & relocate
Move lux/indexer/cmd/explorer/ → new repo luxfi/explorer. Keep
lux/indexer/ as the pure indexer library (chain-agnostic ingestion
primitives) that luxfi/explorer depends on.
2. Merge graph engine in-process
lux/graph/engine + lux/graph/indexer become modules imported by
luxfi/explorer main.go. The GraphQL handler mounts on
/v1/graph/{chain}/*. No second binary, no second deploy.
3. Disconnect Hanzo Base
Files importing github.com/hanzoai/base/core:
explorer.go— replacebase/tools/routerwithnet/http+chi/v5.handlers.go— replacecore.Appwith plainhttp.Handler; SSE vianet/http.Flusher.graphql.go— keepgraphql-go, dropbase/corerequest hooks.collections.go,notifications.go,concentration.go— same.graphql_test.go— rewrite against plainhttptest.Server.
Rationale: hanzoai/base is an application framework —
overkill for a stateless per-chain indexer. Adds a 40 MB dep, a DB layer
we don't use (SQLite chain DBs are per-chain, not Base's central DB),
and blocks embedding in CI-built binaries.
4. Embed the real FE
Replace the stub Vite bundle in cmd/explorer/static/ with the output of
next build && next export from lux/explore/. Requires:
- Next.js
output: 'export'innext.config.js(or a build flag). - Ensure every route the FE uses is statically exportable (no SSR-only
data fetching in
/app,/pages). The chainRegistry already runs client-side viawindow.location.hostname— that part is fine. lux/explore/scripts/export-embed.shrunsnext build && next export, stages output intolux/indexer/cmd/explorer/static/, and the Go//go:embeddirective picks it up.
5. Lux CLI orchestration
New subcommand tree under lux dev:
lux dev stack up [--chains N] # spawn N local chains + explorer + bridge + exchange + safe + dao + wallet + faucet
lux dev stack down
lux dev stack status
lux dev stack logs <app>
Implementation: a single stack.yaml in ~/.lux/dev/ lists the apps
and their binaries. lux dev stack up reads it and spawns each with
the right env vars. Ports deconflict automatically (3000-3999 reserved
for the dev stack; +100 per chain instance for the N-chain case).
Default apps:
| App | Repo | Port base |
|---|---|---|
| luxd (chain) | lux/node |
9650 + i |
| explorer | luxfi/explorer |
3001 |
| bridge | lux/bridge |
3002 |
| exchange | liquidity/app |
3003 |
| safe | lux/safe |
3004 |
| dao | lux/dao |
3005 |
| wallet | lux/wallet |
3006 |
| faucet | lux/faucet |
3007 |
Each app reads ~/.lux/dev/chains.json to discover the currently-running
chains. Hot reload: when a chain is added/removed, apps re-read the
registry (no restart needed for the chain-selector dropdown).
6. Production: one deploy, many hostnames
With stateless SSR (already merged in lux/explore@275285e26) and the
merged binary, production is one Deployment in lux-k8s:
- 2+ replicas, HPA 2-8
- Ingress routes
explore.{lux,zoo.network,hanzo.ai,zoo.ngo}→ same Service - chainRegistry auto-brands per-request via the Host header
- Cost: one set of pods for 6+ branded explorers
Migration order
- ✅ FE stateless SSR (
lux/explore@275285e26) - Disconnect
hanzoai/base/core(this repo, 7 files, ~3 days) - Merge
lux/graph/engineintocmd/explorer/main.go(~1 day) - Rename to
luxfi/exploreron GitHub; updatelux/cliimport - Static-export
lux/explore, embed viago:embed lux dev stacksubcommand inlux/cli- Production: swap lux-k8s Deployment to the unified image
What we delete on completion
lux/graph/cmd/graph/(engine code stays inlux/graph/engine/)lux/indexer/cmd/explorer/(moves toluxfi/explorer)hanzoai/base/coredep in indexer- Individual Dockerfiles for each branded explorer (one image covers them all)