The two mains shared no history, so this is a per-file three-way merge:
for each file the 65 forge-only commits touched (by patch-id), the base is
the newest version both histories held. 105 files merged or took one side
cleanly, 48 were already identical, and the 45 true conflicts and 31
modify/delete pairs were resolved by what runs on the cluster:
- The forge wins where it is live: explorer 1.5.56 (digest 45db11ff) and
its archive readers, explore-fe-hanzo's ConfigMap env (AI coin,
/v1/indexer/hanzo, /v1/chain/hanzo/rpc), exchange-api reading
luxd-archive, and explore-fe-{lux,zoo}-testnet, pinned to what they run
(v2.8.5-lux / v2.8.4-lux).
- GitHub wins where it is live: explore-fe-lux v2.8.5-lux, explore-fe-zoo
v2.8.4-lux, bankd v1.0.18, lux-build's routes.
- The forge's retirement of workloads that run nowhere stands: lux-mainnet
dex, lux-hb2, lux-market, traffic, wallet-web; the lux-testnet frontends,
indexer, exchange and gateways; lux-operator. deploy/lux-testnet/luxd.yaml
stays, since roll_luxd.sh reads it.
- GitHub's deletions stand: lux-finance and lux-financial (static sites
now), the k8s/ operator manifests, .hanzo/workflows/cicd.yml.
- Paths are /v1/chain/C/rpc where the forge had written /v1/chain/c. All
four spellings answer; this one is the documented form. The forge's
/{network}/v1 doc lines are dropped: a network is a host, and the prefix
404s.
Dry-run against the running objects (server-side, as CD applies), the
merged explorer shows no change where GitHub's showed 152 lines, and no
other live workload moves further from what runs. Every deploy/*/*.yaml
renders with charts/app; price.yaml, which failed on GitHub, now renders.
Claude-Session: https://claude.ai/code/session_01TzirYkGmD88w4GipqivUtV
396 lines
14 KiB
YAML
396 lines
14 KiB
YAML
# Per-brand block-explorer frontends for MAINNET (Lux / Zoo / Hanzo / Pars).
|
|
#
|
|
# ONE Next.js "explore" image family (luxfi/explore, a Blockscout-frontend
|
|
# fork) white-labeled by hostname: configs/app/chainRegistry.ts resolves the
|
|
# active chain (and its brand logo/name) from the request Host header, so the
|
|
# SAME source serves every brand. The header logo is the per-brand inline-SVG
|
|
# mark from chainRegistry `branding.logoContent` — Hanzo = the real blocky-H
|
|
# (@hanzo/logo, viewBox "0 0 67 67"), Lux = triangle, Zoo = interlocking
|
|
# circles, Pars = 8-pointed star. NO hardcoded logo.
|
|
#
|
|
# Per-(brand x env) image overlay — each brand publishes to its own GHCR org:
|
|
# lux -> ghcr.io/luxfi/explore
|
|
# zoo -> ghcr.io/zooai/explore
|
|
# hanzo -> ghcr.io/hanzoai/explore
|
|
# pars -> ghcr.io/parsdao/explore
|
|
# All built from one source (luxfi/explore@main) by the in-cluster kaniko
|
|
# job (NO GitHub builders): one --context git://...#main, fan-out
|
|
# --destination per org. See universe arcd build pattern.
|
|
#
|
|
# Mainnet user-facing hosts (ingress explore-{brand} in this ns):
|
|
# explore.lux.network (+ canonical explore-lux.lux.network)
|
|
# explore.zoo.network / explore.zoo.ngo (+ explore-zoo.lux.network)
|
|
# explore.hanzo.network / explore.hanzo.ai (+ explore-hanzo.lux.network)
|
|
# explore.pars.network (+ explore-pars.lux.network)
|
|
#
|
|
# image pull secret ghcr-luxfi already present in lux-mainnet (reads all
|
|
# four GHCR orgs).
|
|
#
|
|
# DECLARED STATE — captured from the live cluster (lux-k8s/lux-mainnet)
|
|
# so an operator reconcile / rebuild reproduces exactly what is deployed.
|
|
# Deploy via platform.hanzo.ai (operator reconcile); do not hand-apply ad-hoc.
|
|
---
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: explore-env-lux
|
|
namespace: lux-mainnet
|
|
labels: { app: explore-fe, brand: lux, network: mainnet }
|
|
data:
|
|
NEXT_PUBLIC_ACCOUNT_AUTH_PROVIDER: oidc
|
|
NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED: 'true'
|
|
NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS: '18'
|
|
NEXT_PUBLIC_OIDC_CLIENT_ID: lux-explore-client-id
|
|
NEXT_PUBLIC_OIDC_SERVER_URL: https://lux.id
|
|
NEXT_PUBLIC_STATS_API_HOST: https://api-explore.lux.network
|
|
SKIP_ENVS_VALIDATION: 'true'
|
|
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST: "https://api-explore.lux.network"
|
|
NEXT_PUBLIC_API_HOST: "api-explore.lux.network"
|
|
NEXT_PUBLIC_APP_HOST: "explore.lux.network"
|
|
NEXT_PUBLIC_CONTRACT_INFO_API_HOST: "https://api-explore.lux.network"
|
|
NEXT_PUBLIC_IS_TESTNET: "false"
|
|
NEXT_PUBLIC_NETWORK_CURRENCY_NAME: "LUX"
|
|
NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL: "LUX"
|
|
NEXT_PUBLIC_NETWORK_ID: "96369"
|
|
NEXT_PUBLIC_NETWORK_NAME: "Lux"
|
|
NEXT_PUBLIC_NETWORK_RPC_URL: "https://api.lux.network/v1/chain/C/rpc"
|
|
NEXT_PUBLIC_NETWORK_SHORT_NAME: "Lux"
|
|
NEXT_PUBLIC_VISUALIZE_API_HOST: "https://api-explore.lux.network"
|
|
---
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: explore-env-zoo
|
|
namespace: lux-mainnet
|
|
labels: { app: explore-fe, brand: zoo, network: mainnet }
|
|
data:
|
|
NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS: '18'
|
|
NEXT_PUBLIC_STATS_API_HOST: https://api-explore.zoo.network
|
|
SKIP_ENVS_VALIDATION: 'true'
|
|
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST: "https://api-explore.zoo.network"
|
|
NEXT_PUBLIC_API_HOST: "api-explore.zoo.network"
|
|
NEXT_PUBLIC_APP_HOST: "explore.zoo.network"
|
|
NEXT_PUBLIC_COLOR_THEME_OVERRIDES: '{"light":{"blue.500":"#000000","blue.600":"#000000","blue.700":"#000000","accent":"#000000","primary":"#000000"},"dark":{"blue.500":"#FFFFFF","blue.600":"#FFFFFF","blue.700":"#FFFFFF","accent":"#FFFFFF","primary":"#FFFFFF"}}'
|
|
NEXT_PUBLIC_CONTRACT_INFO_API_HOST: "https://api-explore.zoo.network"
|
|
NEXT_PUBLIC_IS_TESTNET: "false"
|
|
NEXT_PUBLIC_NETWORK_CURRENCY_NAME: "ZOO"
|
|
NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL: "ZOO"
|
|
NEXT_PUBLIC_NETWORK_ID: "200200"
|
|
NEXT_PUBLIC_NETWORK_NAME: "Zoo"
|
|
NEXT_PUBLIC_NETWORK_RPC_URL: "https://api.zoo.network/v1/chain/C/rpc"
|
|
NEXT_PUBLIC_NETWORK_SHORT_NAME: "Zoo"
|
|
NEXT_PUBLIC_VISUALIZE_API_HOST: "https://api-explore.zoo.network"
|
|
---
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: explore-env-hanzo
|
|
namespace: lux-mainnet
|
|
labels: { app: explore-fe, brand: hanzo, network: mainnet }
|
|
data:
|
|
NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS: '18'
|
|
NEXT_PUBLIC_STATS_API_HOST: https://api-explore.hanzo.network
|
|
SKIP_ENVS_VALIDATION: 'true'
|
|
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST: "https://api-explore.hanzo.network"
|
|
NEXT_PUBLIC_API_HOST: "api-explore.hanzo.network"
|
|
# The page is served at explore.hanzo.ai, and this is what it calls itself:
|
|
# canonical URL, og:image, twitter:domain and the CSP self-host all read it.
|
|
NEXT_PUBLIC_APP_HOST: "explore.hanzo.ai"
|
|
NEXT_PUBLIC_CONTRACT_INFO_API_HOST: "https://api-explore.hanzo.network"
|
|
NEXT_PUBLIC_IS_TESTNET: "false"
|
|
NEXT_PUBLIC_NETWORK_CURRENCY_NAME: "AI"
|
|
NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL: "AI"
|
|
NEXT_PUBLIC_NETWORK_ID: "36963"
|
|
NEXT_PUBLIC_NETWORK_NAME: "Hanzo"
|
|
# NOTE: live data backend issue — explorer appends /v1/chain/C/rpc to this
|
|
# base, yielding a doubled path. Fix the indexer/API + this RPC base in a
|
|
# separate data-layer task; it does not affect branding/chrome.
|
|
NEXT_PUBLIC_NETWORK_RPC_URL: "https://api.lux.network/v1/chain/hanzo/rpc"
|
|
NEXT_PUBLIC_NETWORK_SHORT_NAME: "Hanzo"
|
|
NEXT_PUBLIC_VISUALIZE_API_HOST: "https://api-explore.hanzo.network"
|
|
---
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: explore-env-pars
|
|
namespace: lux-mainnet
|
|
labels: { app: explore-fe, brand: pars, network: mainnet }
|
|
data:
|
|
NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS: '18'
|
|
SKIP_ENVS_VALIDATION: 'true'
|
|
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST: "https://api-explore.pars.network"
|
|
NEXT_PUBLIC_API_HOST: "api-explore.pars.network"
|
|
NEXT_PUBLIC_APP_HOST: "explore.pars.network"
|
|
NEXT_PUBLIC_CONTRACT_INFO_API_HOST: "https://api-explore.pars.network"
|
|
NEXT_PUBLIC_IS_TESTNET: "false"
|
|
NEXT_PUBLIC_NETWORK_CURRENCY_NAME: "PARS"
|
|
NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL: "PARS"
|
|
NEXT_PUBLIC_NETWORK_ID: "494949"
|
|
NEXT_PUBLIC_NETWORK_NAME: "Pars"
|
|
NEXT_PUBLIC_NETWORK_RPC_URL: "https://api.pars.network/v1/chain/pars/rpc"
|
|
NEXT_PUBLIC_NETWORK_SHORT_NAME: "Pars"
|
|
NEXT_PUBLIC_STATS_API_HOST: "https://api-explore.pars.network"
|
|
NEXT_PUBLIC_VISUALIZE_API_HOST: "https://api-explore.pars.network"
|
|
---
|
|
# Deployments + Services (one per brand). Per-brand image, envFrom configmap
|
|
# above, svc 80 -> containerPort 3000.
|
|
#
|
|
# Image tags: all four brands pinned to v1.0.14 (luxfi/explore@63df7ac7 — PR #7
|
|
# chain-visibility rule [lux=all, hanzo/zoo/pars=own-only, +Osage, pars 494949] +
|
|
# the 10-VM/DEX handling [D-Chain→DEX UI, all primary VMs registered & gated
|
|
# lux-only]; inherits the v1.0.13 SSE realtime transport). parsdao/explore now
|
|
# built — the kaniko fan-out (ns hanzo, explore-build-v1-0-14) added the parsdao
|
|
# destination, so pars jumps v1.0.4 → v1.0.14 with the rest.
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: explore-fe-lux
|
|
namespace: lux-mainnet
|
|
labels: { app: explore-fe, brand: lux, network: mainnet }
|
|
spec:
|
|
replicas: 2
|
|
selector:
|
|
matchLabels: { app: explore-fe, brand: lux, network: mainnet }
|
|
strategy:
|
|
type: RollingUpdate
|
|
rollingUpdate: { maxSurge: 1, maxUnavailable: 1 }
|
|
template:
|
|
metadata:
|
|
labels: { app: explore-fe, brand: lux, network: mainnet }
|
|
spec:
|
|
imagePullSecrets:
|
|
- name: ghcr-luxfi
|
|
containers:
|
|
- name: explore
|
|
image: ghcr.io/luxfi/explore:v1.0.14
|
|
imagePullPolicy: IfNotPresent
|
|
ports:
|
|
- { name: ui, containerPort: 3000 }
|
|
env:
|
|
- { name: PORT, value: "3000" }
|
|
envFrom:
|
|
- configMapRef: { name: explore-env-lux }
|
|
resources:
|
|
requests: { cpu: 100m, memory: 256Mi }
|
|
limits: { cpu: "1", memory: 2Gi }
|
|
startupProbe:
|
|
httpGet: { path: /, port: ui }
|
|
initialDelaySeconds: 15
|
|
periodSeconds: 10
|
|
timeoutSeconds: 10
|
|
failureThreshold: 30
|
|
readinessProbe:
|
|
httpGet: { path: /, port: ui }
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 15
|
|
timeoutSeconds: 10
|
|
failureThreshold: 6
|
|
livenessProbe:
|
|
httpGet: { path: /, port: ui }
|
|
initialDelaySeconds: 90
|
|
periodSeconds: 60
|
|
timeoutSeconds: 10
|
|
failureThreshold: 5
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: explore-fe-lux
|
|
namespace: lux-mainnet
|
|
labels: { app: explore-fe, brand: lux, network: mainnet }
|
|
spec:
|
|
type: ClusterIP
|
|
selector: { app: explore-fe, brand: lux, network: mainnet }
|
|
ports:
|
|
- { name: http, port: 80, targetPort: 3000, protocol: TCP }
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: explore-fe-zoo
|
|
namespace: lux-mainnet
|
|
labels: { app: explore-fe, brand: zoo, network: mainnet }
|
|
spec:
|
|
replicas: 2
|
|
selector:
|
|
matchLabels: { app: explore-fe, brand: zoo, network: mainnet }
|
|
strategy:
|
|
type: RollingUpdate
|
|
rollingUpdate: { maxSurge: 1, maxUnavailable: 1 }
|
|
template:
|
|
metadata:
|
|
labels: { app: explore-fe, brand: zoo, network: mainnet }
|
|
spec:
|
|
imagePullSecrets:
|
|
- name: ghcr-luxfi
|
|
containers:
|
|
- name: explore
|
|
image: ghcr.io/zooai/explore:v1.0.14
|
|
imagePullPolicy: IfNotPresent
|
|
ports:
|
|
- { name: ui, containerPort: 3000 }
|
|
env:
|
|
- { name: PORT, value: "3000" }
|
|
envFrom:
|
|
- configMapRef: { name: explore-env-zoo }
|
|
resources:
|
|
requests: { cpu: 100m, memory: 256Mi }
|
|
limits: { cpu: "1", memory: 2Gi }
|
|
startupProbe:
|
|
httpGet: { path: /, port: ui }
|
|
initialDelaySeconds: 15
|
|
periodSeconds: 10
|
|
timeoutSeconds: 10
|
|
failureThreshold: 30
|
|
readinessProbe:
|
|
httpGet: { path: /, port: ui }
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 15
|
|
timeoutSeconds: 10
|
|
failureThreshold: 6
|
|
livenessProbe:
|
|
httpGet: { path: /, port: ui }
|
|
initialDelaySeconds: 90
|
|
periodSeconds: 60
|
|
timeoutSeconds: 10
|
|
failureThreshold: 5
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: explore-fe-zoo
|
|
namespace: lux-mainnet
|
|
labels: { app: explore-fe, brand: zoo, network: mainnet }
|
|
spec:
|
|
type: ClusterIP
|
|
selector: { app: explore-fe, brand: zoo, network: mainnet }
|
|
ports:
|
|
- { name: http, port: 80, targetPort: 3000, protocol: TCP }
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: explore-fe-hanzo
|
|
namespace: lux-mainnet
|
|
labels: { app: explore-fe, brand: hanzo, network: mainnet }
|
|
spec:
|
|
replicas: 2
|
|
selector:
|
|
matchLabels: { app: explore-fe, brand: hanzo, network: mainnet }
|
|
strategy:
|
|
type: RollingUpdate
|
|
rollingUpdate: { maxSurge: 1, maxUnavailable: 1 }
|
|
template:
|
|
metadata:
|
|
labels: { app: explore-fe, brand: hanzo, network: mainnet }
|
|
spec:
|
|
imagePullSecrets:
|
|
- name: ghcr-luxfi
|
|
containers:
|
|
- name: explore
|
|
image: ghcr.io/hanzoai/explore:v1.0.14
|
|
imagePullPolicy: IfNotPresent
|
|
ports:
|
|
- { name: ui, containerPort: 3000 }
|
|
env:
|
|
- { name: PORT, value: "3000" }
|
|
envFrom:
|
|
- configMapRef: { name: explore-env-hanzo }
|
|
resources:
|
|
requests: { cpu: 100m, memory: 256Mi }
|
|
limits: { cpu: "1", memory: 2Gi }
|
|
startupProbe:
|
|
httpGet: { path: /, port: ui }
|
|
initialDelaySeconds: 15
|
|
periodSeconds: 10
|
|
timeoutSeconds: 10
|
|
failureThreshold: 30
|
|
readinessProbe:
|
|
httpGet: { path: /, port: ui }
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 15
|
|
timeoutSeconds: 10
|
|
failureThreshold: 6
|
|
livenessProbe:
|
|
httpGet: { path: /, port: ui }
|
|
initialDelaySeconds: 90
|
|
periodSeconds: 60
|
|
timeoutSeconds: 10
|
|
failureThreshold: 5
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: explore-fe-hanzo
|
|
namespace: lux-mainnet
|
|
labels: { app: explore-fe, brand: hanzo, network: mainnet }
|
|
spec:
|
|
type: ClusterIP
|
|
selector: { app: explore-fe, brand: hanzo, network: mainnet }
|
|
ports:
|
|
- { name: http, port: 80, targetPort: 3000, protocol: TCP }
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: explore-fe-pars
|
|
namespace: lux-mainnet
|
|
labels: { app: explore-fe, brand: pars, network: mainnet }
|
|
spec:
|
|
replicas: 2
|
|
selector:
|
|
matchLabels: { app: explore-fe, brand: pars, network: mainnet }
|
|
strategy:
|
|
type: RollingUpdate
|
|
rollingUpdate: { maxSurge: 1, maxUnavailable: 1 }
|
|
template:
|
|
metadata:
|
|
labels: { app: explore-fe, brand: pars, network: mainnet }
|
|
spec:
|
|
imagePullSecrets:
|
|
- name: ghcr-luxfi
|
|
containers:
|
|
- name: explore
|
|
image: ghcr.io/parsdao/explore:v1.0.14
|
|
imagePullPolicy: IfNotPresent
|
|
ports:
|
|
- { name: ui, containerPort: 3000 }
|
|
env:
|
|
- { name: PORT, value: "3000" }
|
|
envFrom:
|
|
- configMapRef: { name: explore-env-pars }
|
|
resources:
|
|
requests: { cpu: 100m, memory: 256Mi }
|
|
limits: { cpu: "1", memory: 2Gi }
|
|
startupProbe:
|
|
httpGet: { path: /, port: ui }
|
|
initialDelaySeconds: 15
|
|
periodSeconds: 10
|
|
timeoutSeconds: 10
|
|
failureThreshold: 30
|
|
readinessProbe:
|
|
httpGet: { path: /, port: ui }
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 15
|
|
timeoutSeconds: 10
|
|
failureThreshold: 6
|
|
livenessProbe:
|
|
httpGet: { path: /, port: ui }
|
|
initialDelaySeconds: 90
|
|
periodSeconds: 60
|
|
timeoutSeconds: 10
|
|
failureThreshold: 5
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: explore-fe-pars
|
|
namespace: lux-mainnet
|
|
labels: { app: explore-fe, brand: pars, network: mainnet }
|
|
spec:
|
|
type: ClusterIP
|
|
selector: { app: explore-fe, brand: pars, network: mainnet }
|
|
ports:
|
|
- { name: http, port: 80, targetPort: 3000, protocol: TCP }
|