494 lines
19 KiB
YAML
494 lines
19 KiB
YAML
# CD applies this file within ~90s, so THIS is the source now, not the cluster.
|
|
# It was generated from the live Deployment by hack/live2values.py back when the
|
|
# reverse was true; regenerating it would undo that and re-import whatever has
|
|
# been applied by hand, so bump the pin here instead.
|
|
cd:
|
|
automated: false
|
|
|
|
#
|
|
# ⚠️ The ports/service block below is deliberate and load-bearing. This workload
|
|
# needs THREE service ports over TWO container ports, with the container port
|
|
# named differently from every service port:
|
|
#
|
|
# live Service http:80->8090, http-v2:8090->8090, ui:3000->3000
|
|
# live containers explorer[api:8090], explore[ui:3000]
|
|
#
|
|
# One `ports[]` entry cannot express that — it yields ONE container port and ONE
|
|
# service port from a single name. Two primitives were added to charts/app for
|
|
# exactly this shape:
|
|
#
|
|
# ports[].expose: false keeps `api` on the POD, where all three probes
|
|
# below reference it by name, and OFF the Service
|
|
# service.extraPorts Service ports with no container behind them
|
|
#
|
|
# Until 2026-07-31 this file declared a single entry named `http-v2`, and a sync
|
|
# would have broken the Application two ways:
|
|
#
|
|
# 1. The Service collapses to [80]. About 55 IngressRoutes and Ingresses
|
|
# across lux-devnet/mainnet/testnet target explorer:8090 BY NUMBER — every
|
|
# api-explore.* host and most explore.* hosts, across lux.network,
|
|
# hanzo.ai, hanzo.network, pars.network, zoo.network and osage.network —
|
|
# and exchange-api dials explorer.<ns>.svc:8090 for SUBGRAPH_URL. Port 3000
|
|
# (the `explore` UI sidecar) goes with it.
|
|
# 2. The pods stop becoming Ready. The probes say `api`; renaming the
|
|
# container port leaves them pointing at a port that is not declared, and
|
|
# kubelet fails `strconv.Atoi: parsing "api"` — the fault that held
|
|
# mpc-node NotReady for 14h.
|
|
#
|
|
# ⚠️ Requires charts/app >= 0.1.2 — `expose` and `service.extraPorts` are schema
|
|
# errors under the 0.1.0 lux-fleet used to pin. The fleet was repointed on
|
|
# 2026-07-31, so this is now safe to sync.
|
|
replicas: 1
|
|
selectorLabels:
|
|
app: explorer
|
|
network: mainnet
|
|
image:
|
|
repository: ghcr.io/luxfi/explorer
|
|
tag: 1.5.49
|
|
# 1.5.39 counts this chain's tables once and holds the answer instead of
|
|
# scanning them again for every caller. The homepage asks for lifetime totals,
|
|
# and none of them can use an index — SQLite keeps no row count, and the day
|
|
# bucket and epoch bound are expressions over a TEXT datetime — so on a
|
|
# million blocks the four headline cards cost seconds each and queued behind
|
|
# one another on this pod's connections. Measured at 300k blocks: 489ms per
|
|
# call, and 32 at once took 47s; now 6µs and 0.2ms. 1.5.40 warms those
|
|
# counts one chain at a time so the eighteen this pod serves do not all scan
|
|
# their index at the same moment on the one disk.
|
|
#
|
|
# The tag is how a human says it; the digest is what the kubelet obeys. With
|
|
# pullPolicy: IfNotPresent a node that has seen a tag keeps those bytes, and
|
|
# ghcr tags are mutable, so the digest is the only exact identity.
|
|
digest: sha256:b23eccfdc705ad0a772dfa49d189e097a582076c8fc7b5dc1cd4f81a8cbda06e
|
|
pullPolicy: IfNotPresent
|
|
labels:
|
|
network: mainnet
|
|
args:
|
|
- --config=/etc/explorer/chains.yaml
|
|
env:
|
|
- name: DATA_DIR
|
|
value: /data
|
|
- name: HTTP_ADDR
|
|
value: :8090
|
|
- name: EXPLORER_STATIC_DIR
|
|
value: /etc/explorer/static
|
|
resources:
|
|
limits:
|
|
cpu: '2'
|
|
memory: 4Gi
|
|
requests:
|
|
cpu: 250m
|
|
memory: 512Mi
|
|
volumeMounts:
|
|
- mountPath: /etc/explorer
|
|
name: config
|
|
readOnly: true
|
|
- mountPath: /etc/explorer/static
|
|
name: static
|
|
readOnly: true
|
|
- mountPath: /data
|
|
name: data
|
|
livenessProbe:
|
|
failureThreshold: 5
|
|
httpGet:
|
|
path: /health
|
|
port: api
|
|
scheme: HTTP
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 30
|
|
successThreshold: 1
|
|
timeoutSeconds: 10
|
|
readinessProbe:
|
|
failureThreshold: 6
|
|
httpGet:
|
|
path: /health
|
|
port: api
|
|
scheme: HTTP
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 10
|
|
successThreshold: 1
|
|
timeoutSeconds: 5
|
|
startupProbe:
|
|
failureThreshold: 30
|
|
httpGet:
|
|
path: /health
|
|
port: api
|
|
scheme: HTTP
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 5
|
|
successThreshold: 1
|
|
timeoutSeconds: 5
|
|
securityContext:
|
|
runAsNonRoot: true
|
|
runAsUser: 65532
|
|
ports:
|
|
- name: api
|
|
containerPort: 8090
|
|
expose: false
|
|
service:
|
|
extraPorts:
|
|
- name: http
|
|
port: 80
|
|
targetPort: 8090
|
|
- name: http-v2
|
|
port: 8090
|
|
targetPort: 8090
|
|
- name: ui
|
|
port: 3000
|
|
targetPort: 3000
|
|
volumes:
|
|
- configMap:
|
|
name: explorer-chains
|
|
name: config
|
|
- configMap:
|
|
name: explorer-static
|
|
name: static
|
|
- name: data
|
|
persistentVolumeClaim:
|
|
claimName: explorer-data
|
|
imagePullSecrets:
|
|
- name: ghcr-luxfi
|
|
sidecars:
|
|
- env:
|
|
- name: PORT
|
|
value: '3000'
|
|
- name: ENVS_PRESET
|
|
value: none
|
|
- name: SKIP_ENVS_VALIDATION
|
|
value: 'true'
|
|
- name: NEXT_TELEMETRY_DISABLED
|
|
value: '1'
|
|
- name: NEXT_PUBLIC_NETWORK_ID
|
|
value: '96369'
|
|
- name: NEXT_PUBLIC_NETWORK_NAME
|
|
value: Lux Network
|
|
- name: NEXT_PUBLIC_NETWORK_SHORT_NAME
|
|
value: LUX
|
|
- name: NEXT_PUBLIC_NETWORK_CURRENCY_NAME
|
|
value: LUX
|
|
- name: NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL
|
|
value: LUX
|
|
- name: NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS
|
|
value: '18'
|
|
- name: NEXT_PUBLIC_NETWORK_RPC_URL
|
|
value: https://api.lux.network/v1/chain/c
|
|
- name: NEXT_PUBLIC_NETWORK_LOGO
|
|
value: /logo.svg
|
|
- name: NEXT_PUBLIC_NETWORK_ICON
|
|
value: /icon.svg
|
|
- name: NEXT_PUBLIC_BRAND
|
|
value: lux
|
|
- name: NEXT_PUBLIC_IS_TESTNET
|
|
value: 'false'
|
|
- name: NEXT_PUBLIC_APP_HOST
|
|
value: explore.lux.network
|
|
- name: NEXT_PUBLIC_APP_PROTOCOL
|
|
value: https
|
|
- name: NEXT_PUBLIC_API_HOST
|
|
value: api-explore.lux.network
|
|
- name: NEXT_PUBLIC_API_PROTOCOL
|
|
value: https
|
|
- name: NEXT_PUBLIC_API_BASE_PATH
|
|
value: /v1/indexer/cchain
|
|
- name: NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL
|
|
value: wss
|
|
- name: NEXT_PUBLIC_NETWORK_ORG_NAME
|
|
value: Lux Industries Inc.
|
|
- name: NEXT_PUBLIC_NETWORK_WEBSITE_URL
|
|
value: https://lux.network
|
|
- name: NEXT_PUBLIC_NETWORK_GITHUB_URL
|
|
value: https://github.com/luxfi
|
|
- name: NEXT_PUBLIC_NETWORK_TWITTER_URL
|
|
value: https://x.com/luxdefi
|
|
- name: NEXT_PUBLIC_NETWORK_DISCORD_URL
|
|
value: https://discord.gg/luxnetwork
|
|
- name: NEXT_PUBLIC_COLOR_THEME_DEFAULT
|
|
value: dark
|
|
- name: NEXT_PUBLIC_ACCOUNT_AUTH_PROVIDER
|
|
value: oidc
|
|
- name: NEXT_PUBLIC_OIDC_SERVER_URL
|
|
value: https://lux.id
|
|
- name: NEXT_PUBLIC_OIDC_CLIENT_ID
|
|
value: lux-explore-client-id
|
|
# v2.8.1-lux: the landing page stops spending its top on a feature that is off
|
|
# (the fee-split panel rendered a status tag, two zero counters and a promise of
|
|
# a chart while the split has never fired), and the Validators page counts EVERY
|
|
# network rather than this chain's share — Zoo and Hanzo run as L2s on the
|
|
# primary network and Pars and Osage as their own L1s, so "how many validators
|
|
# secure Lux" is a question about all of them. The landing page said 21 and the
|
|
# Validators page said 6; both were right and nothing said which was which.
|
|
image: ghcr.io/luxfi/explore:v2.8.1-lux
|
|
imagePullPolicy: IfNotPresent
|
|
livenessProbe:
|
|
failureThreshold: 5
|
|
httpGet:
|
|
path: /
|
|
port: ui
|
|
scheme: HTTP
|
|
initialDelaySeconds: 90
|
|
periodSeconds: 60
|
|
successThreshold: 1
|
|
timeoutSeconds: 10
|
|
name: explore
|
|
ports:
|
|
- containerPort: 3000
|
|
name: ui
|
|
protocol: TCP
|
|
readinessProbe:
|
|
failureThreshold: 6
|
|
httpGet:
|
|
path: /
|
|
port: ui
|
|
scheme: HTTP
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 15
|
|
successThreshold: 1
|
|
timeoutSeconds: 10
|
|
resources:
|
|
limits:
|
|
cpu: '1'
|
|
memory: 2Gi
|
|
requests:
|
|
cpu: 100m
|
|
memory: 256Mi
|
|
startupProbe:
|
|
failureThreshold: 30
|
|
httpGet:
|
|
path: /
|
|
port: ui
|
|
scheme: HTTP
|
|
initialDelaySeconds: 15
|
|
periodSeconds: 10
|
|
successThreshold: 1
|
|
timeoutSeconds: 10
|
|
fsGroup: 65532
|
|
strategy: Recreate
|
|
topologySpread:
|
|
enabled: false
|
|
lifecycle: null
|
|
terminationGracePeriodSeconds: 60
|
|
|
|
# NOT SYNCABLE by this chart, and the reason is precise rather than a mystery.
|
|
# Live Service `explorer` publishes TWO ports over ONE container port:
|
|
# http 80 -> 8090 (browser, via the explore.* Ingresses)
|
|
# http-v2 8090 -> 8090 (dialed in-cluster as
|
|
# explorer.<ns>.svc:8090/v1/graph/... by exchange-api
|
|
# on mainnet, testnet AND devnet — the DEX subgraph)
|
|
# ui 3000 -> 3000
|
|
# A values `ports` entry is one container port AND one Service port with one
|
|
# shared name, so two Service ports over one container port cannot be expressed;
|
|
# declaring only `http` prunes port 8090 and takes the DEX subgraph down in three
|
|
# namespaces. Syncing this needs the chart to accept an explicit extra Service
|
|
# port, not a values edit. Left OutOfSync deliberately — a report is honest, a
|
|
# guess here is an outage.
|
|
|
|
# The chain list this process indexes and serves. It lives here, in the values
|
|
# hanzocd renders, because a ConfigMap the chart does not create is a ConfigMap
|
|
# nothing reconciles: `explorer-chains` was applied by hand and carried no
|
|
# owner, so editing the copy under k8s/ changed a file and nothing else.
|
|
configMaps:
|
|
- name: explorer-chains
|
|
data:
|
|
chains.yaml: |
|
|
data_dir: /data
|
|
http_addr: :8090
|
|
static_dir: /etc/explorer/static
|
|
|
|
brand_default:
|
|
name: Lux Explorer
|
|
coin: LUX
|
|
accent_color: "#5cf"
|
|
icon_file: /etc/explorer/static/icon-lux.svg
|
|
logo_file: /etc/explorer/static/logo-lux.svg
|
|
icon_url: /icon.svg
|
|
logo_url: /logo.svg
|
|
|
|
networks:
|
|
- { label: Mainnet, domain: explore.lux.network, chain_id: 96369 }
|
|
- { label: Testnet, domain: explorer.lux-test.network, chain_id: 96368 }
|
|
- { label: Devnet, domain: explorer.lux-dev.network, chain_id: 96367 }
|
|
|
|
# luxd is /v1-only (all /ext paths 404). Lux native chains resolve via
|
|
# chain.name aliases on the in-cluster luxd; org chains resolve via their
|
|
# own public HTTPS RPC gateways (raw :9630 LBs are firewalled to non-DO
|
|
# sources, so we use ingress/443 hosts the explorer pod can egress to).
|
|
# An indexer reads a height and remembers it, so it must never be handed one
|
|
# from a node below the chain's tip: a lower head reads as a rewind and the
|
|
# cursor either stalls or wipes. luxd-rpc selects on lux.network/rpc=fresh,
|
|
# which is only set while a node serves the tip, so every read is at the tip
|
|
# or the read fails -- luxd-headless answers from any member, tip or not.
|
|
chains:
|
|
- slug: cchain
|
|
name: Lux C-Chain
|
|
chain_id: 96369
|
|
type: evm
|
|
rpc: http://luxd-rpc.lux-mainnet.svc.cluster.local:9630/v1/chain/C/rpc
|
|
# What the BROWSER is told to dial, and it is not optional. `rpc` above is
|
|
# the address this PROCESS dials -- a cluster-internal service name that
|
|
# resolves nowhere outside the mesh. Without public_rpc the binary's
|
|
# browserRPC() falls through to browserReachable(rpc), which is false for
|
|
# a .svc.cluster.local name, and hands the SPA "" -- so every RPC-backed
|
|
# control disappears from explore.lux.network. Live has carried this since
|
|
# before this file did; do not drop it back out.
|
|
public_rpc: https://api.lux.network/v1/chain/c
|
|
coin: LUX
|
|
enabled: true
|
|
default: true
|
|
# This chain's AMM. Stated here because one explorer process indexes
|
|
# every chain in this file, and the graph indexer trusts exactly one
|
|
# factory address per subgraph: whichever chain leaves these blank gets
|
|
# no AMM rather than a neighbour's.
|
|
factory_v2: "0xD173926A10A0C4eCd3A51B1422270b65Df0551c1"
|
|
factory_v3: "0x80bBc7C4C7a59C899D1B37BC14539A22D5830a84"
|
|
# The V3 periphery quoter. A quote off the book is exact for V2 and an
|
|
# estimate for V3, where the answer depends on which ticks the trade
|
|
# crosses; with this the chain prices the V3 leg itself.
|
|
quoter_v2: "0x15C729fdd833Ba675edd466Dfc63E1B737925A4c"
|
|
# SwapRouter02 — the contract a swap is addressed to, and the one an
|
|
# approval is spent on. It must match factory_v3 above or the grant buys
|
|
# nothing: asked directly it answers factory() = 0x80bBc7C4… and WETH9()
|
|
# = 0x4888E4a2…, the addresses these pools actually hold. Unset means
|
|
# /swap and /check_approval are not served for that chain, which is the
|
|
# honest state rather than a swap addressed into the dark.
|
|
router: "0x939bC0Bca6F9B9c52E6e3AD8A3C590b5d9B9D10E"
|
|
native: "0x4888E4a2Ee0F03051c72D2BD3ACf755eD3498B3E"
|
|
# 2T minted at block 0 — confirmed with eth_getBalance at height 0 on
|
|
# this chain, not taken from a spec sheet. The P-Chain's own supply
|
|
# counter reads 13.27B; it is a different number about a different
|
|
# thing, and trusting it priced the token 150x under.
|
|
genesis_supply: "2000000000000"
|
|
# Holds what has not been distributed. Read live, because it falls as
|
|
# tokens reach holders, and what it still holds is not circulating.
|
|
treasury: "0x9011E888251AB053B7bD1cdB598Db4f9DEd94714"
|
|
indexer: { poll_interval: 30s }
|
|
graph:
|
|
enabled: true
|
|
subgraphs:
|
|
- { name: amm, schema: amm, enabled: true }
|
|
- { name: dex , schema: dex, enabled: true }
|
|
brand:
|
|
name: Lux C-Chain
|
|
coin: LUX
|
|
accent_color: "#5cf"
|
|
icon_file: /etc/explorer/static/icon-lux.svg
|
|
logo_file: /etc/explorer/static/logo-lux.svg
|
|
|
|
- slug: pars
|
|
name: Pars
|
|
chain_id: 494949
|
|
type: evm
|
|
rpc: https://api.pars.network/v1/chain/pars
|
|
coin: PARS
|
|
enabled: true
|
|
indexer: { poll_interval: 30s }
|
|
graph:
|
|
enabled: true
|
|
subgraphs:
|
|
- { name: amm, schema: amm, enabled: true }
|
|
brand: { name: Pars, coin: PARS, accent_color: "#15803d" }
|
|
|
|
- slug: zoo
|
|
name: Zoo
|
|
chain_id: 200200
|
|
type: evm
|
|
# zood-rpc:9630 is routed by zoo-ingress on host api.zoo.ngo.
|
|
rpc: https://api.zoo.ngo/v1/chain/C/rpc
|
|
coin: ZOO
|
|
enabled: true
|
|
# Zoo's AMM sits at the SAME addresses as Lux's: one deployer replayed
|
|
# the same nonces on both chains, and CREATE ignores chainId. Asked
|
|
# directly, chain 200200 answers 12 PoolCreated at the V3 factory and
|
|
# one pair at the V2 factory, while the two addresses declared here
|
|
# before -- 0x9378b62f and 0xc65ea888 -- hold no code at all, so Zoo
|
|
# indexed no AMM and every Zoo chart was empty.
|
|
factory_v2: "0xD173926A10A0C4eCd3A51B1422270b65Df0551c1"
|
|
factory_v3: "0x80bBc7C4C7a59C899D1B37BC14539A22D5830a84"
|
|
quoter_v2: "0x15C729fdd833Ba675edd466Dfc63E1B737925A4c"
|
|
# Same router as Lux, for the same reason the factories are: one
|
|
# deployer, the same nonces. Verified on 200200, not assumed.
|
|
router: "0x939bC0Bca6F9B9c52E6e3AD8A3C590b5d9B9D10E"
|
|
# The wrapped native the pools actually hold. It reports symbol WLUX
|
|
# because it is the replayed deployment; the pools are what decides
|
|
# which address is the wrapped native here, not the string it carries.
|
|
native: "0x4888E4a2Ee0F03051c72D2BD3ACf755eD3498B3E"
|
|
# 2T minted at block 0 — confirmed with eth_getBalance at height 0 on
|
|
# this chain, not taken from a spec sheet. The P-Chain's own supply
|
|
# counter reads 13.27B; it is a different number about a different
|
|
# thing, and trusting it priced the token 150x under.
|
|
genesis_supply: "2000000000000"
|
|
# Holds what has not been distributed. Read live, because it falls as
|
|
# tokens reach holders, and what it still holds is not circulating.
|
|
treasury: "0x9011E888251AB053B7bD1cdB598Db4f9DEd94714"
|
|
indexer: { poll_interval: 30s }
|
|
graph:
|
|
enabled: true
|
|
subgraphs:
|
|
- { name: amm, schema: amm, enabled: true }
|
|
brand:
|
|
name: Zoo
|
|
coin: ZOO
|
|
accent_color: "#7c3aed"
|
|
icon_file: /etc/explorer/static/icon-zoo.svg
|
|
logo_file: /etc/explorer/static/logo-zoo.svg
|
|
|
|
- slug: hanzo
|
|
name: Hanzo
|
|
chain_id: 36963
|
|
type: evm
|
|
# BLOCKED until hanzo-mainnet exposes a public RPC ingress
|
|
# (api.hanzo.network -> hanzod:9630, mirroring api.hanzo-dev/test.network).
|
|
# hanzo mainnet is mid-recovery; current tip is only height 5.
|
|
rpc: https://api.hanzo.network/v1/chain/hanzo
|
|
coin: AI
|
|
enabled: true
|
|
indexer: { poll_interval: 30s }
|
|
graph:
|
|
enabled: true
|
|
subgraphs:
|
|
- { name: amm, schema: amm, enabled: true }
|
|
brand: { name: Hanzo, coin: AI, accent_color: "#0b1220" }
|
|
|
|
- slug: spc
|
|
name: SPC
|
|
chain_id: 36911
|
|
type: evm
|
|
# DISABLED: there is no spc chain to index, anywhere. Not on lux-mainnet
|
|
# luxd (K G A Z Q T B D C X), no spc namespace on any of the three
|
|
# clusters, and api.spc.network / spc.network / explore.spc.network are
|
|
# all NXDOMAIN. Unlike osage, there is nothing to repoint at.
|
|
#
|
|
# Left enabled it polled this URL forever and got `404 page not found`
|
|
# as plain text, 199 errors an hour, which is not a placeholder -- it is
|
|
# noise that buries a real indexing failure. Re-enable with a live
|
|
# endpoint the day an spc L1 exists.
|
|
rpc: http://luxd-rpc.lux-mainnet.svc.cluster.local:9630/v1/chain/spc/rpc
|
|
coin: SPC
|
|
enabled: false
|
|
indexer: { poll_interval: 30s }
|
|
graph:
|
|
enabled: true
|
|
subgraphs:
|
|
- { name: amm, schema: amm, enabled: true }
|
|
brand: { name: SPC, coin: SPC, accent_color: "#0ea5e9" }
|
|
|
|
- slug: osage
|
|
name: Osage
|
|
chain_id: 1872
|
|
type: evm
|
|
# osage is NOT a blockchain on lux-mainnet luxd, and never will be: it
|
|
# is a sovereign L1 on its own primary network. Pointed at that network,
|
|
# the same way pars, zoo and hanzo already are. Verified from inside this
|
|
# pod: eth_chainId -> 0x750 = 1872, matching chain_id above, and
|
|
# eth_blockNumber answers. The previous value polled
|
|
# /v1/chain/osage/rpc on lux's luxd, which answers `404 page not found` as
|
|
# PLAIN TEXT -- so the decoder read 404 as a number and died on the 'p'
|
|
# of 'page', 214 times an hour.
|
|
rpc: https://api.osage.network/v1/chain/C/rpc
|
|
coin: OSG
|
|
enabled: true
|
|
indexer: { poll_interval: 30s }
|
|
graph:
|
|
enabled: true
|
|
subgraphs:
|
|
- { name: amm, schema: amm, enabled: true }
|
|
brand: { name: Osage, coin: OSG, accent_color: "#dc2626" }
|