mirror of
https://github.com/luxfi/explore.git
synced 2026-07-27 03:13:50 +00:00
explore v1.1.4: native all-chains wallet-connect, login/menu fixes, correct chain manifest
- wallet: brandFamilyChains derives sibling networks (Lux mainnet/testnet/devnet)
from the multi-tenant chain registry so connect/add presents EVERY registered
network for the brand, not just the env chain; dedupe by id.
- login/menu: useProvider queryFn returns null (react-query v5 forbids undefined)
+ callers switched from '= {}' destructure default to '?? {}' so a null result
no longer crashes the wallet hooks (the busted-menu root cause).
- manifest: fix Pars chainId 7070 -> 494949 (regression) and drop the forbidden
'Subnet' term from sovereign L1 network names (-> '<Brand> Network').
- Validators page + /api/pchain proxy present; rebuild makes the live 5-validator
view visible on explore.lux.network.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
---
|
||||
# Per-env runtime config for Blockscout FE. Loaded into the pod via
|
||||
# Deployment `envFrom: configMapRef:`. Blockscout's `make_envs_script.sh`
|
||||
# at container start renders /assets/envs.js from process env, so any
|
||||
# change here requires a rollout-restart, NOT an image rebuild.
|
||||
#
|
||||
# Brand identity (NETWORK_NAME, OIDC client ID, colors, currency) lives in
|
||||
# the image itself (ghcr.io/{org}/explore:vX.Y.Z); env-specific knobs
|
||||
# (NETWORK_ID, IS_TESTNET, *_HOST, RPC_URL) live here.
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: explore-env-lux
|
||||
namespace: lux-mainnet
|
||||
labels: {app: explore-fe, brand: lux, network: mainnet}
|
||||
data:
|
||||
NEXT_PUBLIC_NETWORK_ID: "96369"
|
||||
NEXT_PUBLIC_IS_TESTNET: "false"
|
||||
NEXT_PUBLIC_API_HOST: api-explore.lux.network
|
||||
NEXT_PUBLIC_APP_HOST: explore.lux.network
|
||||
NEXT_PUBLIC_NETWORK_RPC_URL: https://api.lux.network/ext/bc/C/rpc
|
||||
NEXT_PUBLIC_STATS_API_HOST: https://api-explore.lux.network
|
||||
NEXT_PUBLIC_VISUALIZE_API_HOST: https://api-explore.lux.network
|
||||
NEXT_PUBLIC_CONTRACT_INFO_API_HOST: https://api-explore.lux.network
|
||||
NEXT_PUBLIC_ADMIN_SERVICE_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_ID: "200200"
|
||||
NEXT_PUBLIC_IS_TESTNET: "false"
|
||||
NEXT_PUBLIC_API_HOST: api-explore.zoo.network
|
||||
NEXT_PUBLIC_APP_HOST: explore.zoo.network
|
||||
NEXT_PUBLIC_NETWORK_RPC_URL: https://api.zoo.network/ext/bc/zoo/rpc
|
||||
NEXT_PUBLIC_STATS_API_HOST: https://api-explore.zoo.network
|
||||
NEXT_PUBLIC_VISUALIZE_API_HOST: https://api-explore.zoo.network
|
||||
NEXT_PUBLIC_CONTRACT_INFO_API_HOST: https://api-explore.zoo.network
|
||||
NEXT_PUBLIC_ADMIN_SERVICE_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_ID: "36963"
|
||||
NEXT_PUBLIC_IS_TESTNET: "false"
|
||||
NEXT_PUBLIC_API_HOST: api-explore.hanzo.network
|
||||
NEXT_PUBLIC_APP_HOST: explore.hanzo.network
|
||||
NEXT_PUBLIC_NETWORK_RPC_URL: https://api.hanzo.network/ext/bc/hanzo/rpc
|
||||
NEXT_PUBLIC_STATS_API_HOST: https://api-explore.hanzo.network
|
||||
NEXT_PUBLIC_VISUALIZE_API_HOST: https://api-explore.hanzo.network
|
||||
NEXT_PUBLIC_CONTRACT_INFO_API_HOST: https://api-explore.hanzo.network
|
||||
NEXT_PUBLIC_ADMIN_SERVICE_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_ID: "7070"
|
||||
NEXT_PUBLIC_IS_TESTNET: "false"
|
||||
NEXT_PUBLIC_API_HOST: api-explore.pars.network
|
||||
NEXT_PUBLIC_APP_HOST: explore.pars.network
|
||||
NEXT_PUBLIC_NETWORK_RPC_URL: https://api.pars.network/ext/bc/pars/rpc
|
||||
NEXT_PUBLIC_STATS_API_HOST: https://api-explore.pars.network
|
||||
NEXT_PUBLIC_VISUALIZE_API_HOST: https://api-explore.pars.network
|
||||
NEXT_PUBLIC_CONTRACT_INFO_API_HOST: https://api-explore.pars.network
|
||||
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST: https://api-explore.pars.network
|
||||
@@ -0,0 +1,71 @@
|
||||
---
|
||||
# See configmap-mainnet.yaml for the architecture rationale. This file holds
|
||||
# the testnet runtime overrides for the 4 brand Deployments living in
|
||||
# namespace `lux-testnet`. Same image as mainnet, different env.
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: explore-env-lux
|
||||
namespace: lux-testnet
|
||||
labels: {app: explore-fe, brand: lux, network: testnet}
|
||||
data:
|
||||
NEXT_PUBLIC_NETWORK_ID: "96368"
|
||||
NEXT_PUBLIC_IS_TESTNET: "true"
|
||||
NEXT_PUBLIC_API_HOST: api-explorer.lux-test.network
|
||||
NEXT_PUBLIC_APP_HOST: explorer.lux-test.network
|
||||
NEXT_PUBLIC_NETWORK_RPC_URL: https://api.lux-test.network/ext/bc/C/rpc
|
||||
NEXT_PUBLIC_STATS_API_HOST: https://api-explorer.lux-test.network
|
||||
NEXT_PUBLIC_VISUALIZE_API_HOST: https://api-explorer.lux-test.network
|
||||
NEXT_PUBLIC_CONTRACT_INFO_API_HOST: https://api-explorer.lux-test.network
|
||||
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST: https://api-explorer.lux-test.network
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: explore-env-zoo
|
||||
namespace: lux-testnet
|
||||
labels: {app: explore-fe, brand: zoo, network: testnet}
|
||||
data:
|
||||
NEXT_PUBLIC_NETWORK_ID: "200201"
|
||||
NEXT_PUBLIC_IS_TESTNET: "true"
|
||||
NEXT_PUBLIC_API_HOST: api-explorer.zoo-test.network
|
||||
NEXT_PUBLIC_APP_HOST: explorer.zoo-test.network
|
||||
NEXT_PUBLIC_NETWORK_RPC_URL: https://api.zoo-test.network/ext/bc/zoo/rpc
|
||||
NEXT_PUBLIC_STATS_API_HOST: https://api-explorer.zoo-test.network
|
||||
NEXT_PUBLIC_VISUALIZE_API_HOST: https://api-explorer.zoo-test.network
|
||||
NEXT_PUBLIC_CONTRACT_INFO_API_HOST: https://api-explorer.zoo-test.network
|
||||
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST: https://api-explorer.zoo-test.network
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: explore-env-hanzo
|
||||
namespace: lux-testnet
|
||||
labels: {app: explore-fe, brand: hanzo, network: testnet}
|
||||
data:
|
||||
NEXT_PUBLIC_NETWORK_ID: "36962"
|
||||
NEXT_PUBLIC_IS_TESTNET: "true"
|
||||
NEXT_PUBLIC_API_HOST: api-explorer.hanzo-test.network
|
||||
NEXT_PUBLIC_APP_HOST: explorer.hanzo-test.network
|
||||
NEXT_PUBLIC_NETWORK_RPC_URL: https://api.hanzo-test.network/ext/bc/hanzo/rpc
|
||||
NEXT_PUBLIC_STATS_API_HOST: https://api-explorer.hanzo-test.network
|
||||
NEXT_PUBLIC_VISUALIZE_API_HOST: https://api-explorer.hanzo-test.network
|
||||
NEXT_PUBLIC_CONTRACT_INFO_API_HOST: https://api-explorer.hanzo-test.network
|
||||
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST: https://api-explorer.hanzo-test.network
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: explore-env-pars
|
||||
namespace: lux-testnet
|
||||
labels: {app: explore-fe, brand: pars, network: testnet}
|
||||
data:
|
||||
NEXT_PUBLIC_NETWORK_ID: "7071"
|
||||
NEXT_PUBLIC_IS_TESTNET: "true"
|
||||
NEXT_PUBLIC_API_HOST: api-explorer.pars-test.network
|
||||
NEXT_PUBLIC_APP_HOST: explorer.pars-test.network
|
||||
NEXT_PUBLIC_NETWORK_RPC_URL: https://api.pars-test.network/ext/bc/pars/rpc
|
||||
NEXT_PUBLIC_STATS_API_HOST: https://api-explorer.pars-test.network
|
||||
NEXT_PUBLIC_VISUALIZE_API_HOST: https://api-explorer.pars-test.network
|
||||
NEXT_PUBLIC_CONTRACT_INFO_API_HOST: https://api-explorer.pars-test.network
|
||||
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST: https://api-explorer.pars-test.network
|
||||
@@ -0,0 +1,244 @@
|
||||
---
|
||||
# Lux Mainnet — canonical brand image + env from ConfigMap.
|
||||
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: {maxUnavailable: 1, maxSurge: 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.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports: [{containerPort: 3000, name: ui}]
|
||||
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}]
|
||||
---
|
||||
# Zoo Mainnet
|
||||
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: {maxUnavailable: 1, maxSurge: 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.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports: [{containerPort: 3000, name: ui}]
|
||||
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}]
|
||||
---
|
||||
# Hanzo Mainnet
|
||||
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: {maxUnavailable: 1, maxSurge: 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.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports: [{containerPort: 3000, name: ui}]
|
||||
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}]
|
||||
---
|
||||
# Pars Mainnet
|
||||
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: {maxUnavailable: 1, maxSurge: 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.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports: [{containerPort: 3000, name: ui}]
|
||||
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}]
|
||||
@@ -0,0 +1,244 @@
|
||||
---
|
||||
# Lux Testnet — canonical brand image + env from ConfigMap.
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: explore-fe-lux
|
||||
namespace: lux-testnet
|
||||
labels: {app: explore-fe, brand: lux, network: testnet}
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels: {app: explore-fe, brand: lux, network: testnet}
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate: {maxUnavailable: 1, maxSurge: 1}
|
||||
template:
|
||||
metadata:
|
||||
labels: {app: explore-fe, brand: lux, network: testnet}
|
||||
spec:
|
||||
imagePullSecrets: [{name: ghcr-luxfi}]
|
||||
containers:
|
||||
- name: explore
|
||||
image: ghcr.io/luxfi/explore:v1.0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports: [{containerPort: 3000, name: ui}]
|
||||
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-testnet
|
||||
labels: {app: explore-fe, brand: lux, network: testnet}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector: {app: explore-fe, brand: lux, network: testnet}
|
||||
ports: [{name: http, port: 80, targetPort: 3000, protocol: TCP}]
|
||||
---
|
||||
# Zoo Testnet
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: explore-fe-zoo
|
||||
namespace: lux-testnet
|
||||
labels: {app: explore-fe, brand: zoo, network: testnet}
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels: {app: explore-fe, brand: zoo, network: testnet}
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate: {maxUnavailable: 1, maxSurge: 1}
|
||||
template:
|
||||
metadata:
|
||||
labels: {app: explore-fe, brand: zoo, network: testnet}
|
||||
spec:
|
||||
imagePullSecrets: [{name: ghcr-luxfi}]
|
||||
containers:
|
||||
- name: explore
|
||||
image: ghcr.io/zooai/explore:v1.0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports: [{containerPort: 3000, name: ui}]
|
||||
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-testnet
|
||||
labels: {app: explore-fe, brand: zoo, network: testnet}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector: {app: explore-fe, brand: zoo, network: testnet}
|
||||
ports: [{name: http, port: 80, targetPort: 3000, protocol: TCP}]
|
||||
---
|
||||
# Hanzo Testnet
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: explore-fe-hanzo
|
||||
namespace: lux-testnet
|
||||
labels: {app: explore-fe, brand: hanzo, network: testnet}
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels: {app: explore-fe, brand: hanzo, network: testnet}
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate: {maxUnavailable: 1, maxSurge: 1}
|
||||
template:
|
||||
metadata:
|
||||
labels: {app: explore-fe, brand: hanzo, network: testnet}
|
||||
spec:
|
||||
imagePullSecrets: [{name: ghcr-luxfi}]
|
||||
containers:
|
||||
- name: explore
|
||||
image: ghcr.io/hanzoai/explore:v1.0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports: [{containerPort: 3000, name: ui}]
|
||||
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-testnet
|
||||
labels: {app: explore-fe, brand: hanzo, network: testnet}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector: {app: explore-fe, brand: hanzo, network: testnet}
|
||||
ports: [{name: http, port: 80, targetPort: 3000, protocol: TCP}]
|
||||
---
|
||||
# Pars Testnet
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: explore-fe-pars
|
||||
namespace: lux-testnet
|
||||
labels: {app: explore-fe, brand: pars, network: testnet}
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels: {app: explore-fe, brand: pars, network: testnet}
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate: {maxUnavailable: 1, maxSurge: 1}
|
||||
template:
|
||||
metadata:
|
||||
labels: {app: explore-fe, brand: pars, network: testnet}
|
||||
spec:
|
||||
imagePullSecrets: [{name: ghcr-luxfi}]
|
||||
containers:
|
||||
- name: explore
|
||||
image: ghcr.io/parsdao/explore:v1.0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports: [{containerPort: 3000, name: ui}]
|
||||
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-testnet
|
||||
labels: {app: explore-fe, brand: pars, network: testnet}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector: {app: explore-fe, brand: pars, network: testnet}
|
||||
ports: [{name: http, port: 80, targetPort: 3000, protocol: TCP}]
|
||||
@@ -0,0 +1,13 @@
|
||||
# Per-brand × per-env explore frontend, decomposed.
|
||||
#
|
||||
# Image is brand-only (ghcr.io/{org}/explore:vX.Y.Z); env (NETWORK_ID,
|
||||
# IS_TESTNET, *_HOST, RPC_URL) lives in ConfigMaps mounted via
|
||||
# Deployment.envFrom. Same image runs mainnet+testnet — only the
|
||||
# ConfigMap differs.
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- configmap-mainnet.yaml
|
||||
- configmap-testnet.yaml
|
||||
- deployments-mainnet.yaml
|
||||
- deployments-testnet.yaml
|
||||
@@ -0,0 +1,128 @@
|
||||
---
|
||||
# Lux Mainnet: explore.lux.network + explorer.lux.network → explore-fe-lux + Go binary API
|
||||
apiVersion: hanzo.ai/v1alpha1
|
||||
kind: IngressRoute
|
||||
metadata:
|
||||
name: lux-explorer-mainnet
|
||||
namespace: lux-mainnet
|
||||
labels: {app: lux-explorer, network: mainnet}
|
||||
spec:
|
||||
entryPoints: [websecure]
|
||||
tls: {certResolver: letsencrypt}
|
||||
routes:
|
||||
# API + brand-asset paths → Go binary (port 8090)
|
||||
- kind: Rule
|
||||
priority: 10000
|
||||
match: (Host(`explore.lux.network`) || Host(`explorer.lux.network`)) && (PathPrefix(`/v1/`) || Path(`/health`) || Path(`/envs.js`) || Path(`/icon.svg`) || Path(`/logo.svg`) || Path(`/icon-zoo.svg`) || Path(`/icon-lux.svg`) || Path(`/logo-zoo.svg`) || Path(`/logo-lux.svg`))
|
||||
middlewares: [{name: cors-allow-all}]
|
||||
services: [{name: explorer, port: 8090}]
|
||||
# Catch-all → per-brand Next.js FE (port 80 → 3000)
|
||||
- kind: Rule
|
||||
match: Host(`explore.lux.network`) || Host(`explorer.lux.network`)
|
||||
services: [{name: explore-fe-lux, port: 80}]
|
||||
# api-explore.lux.network — sub-paths
|
||||
- kind: Rule
|
||||
match: (Host(`api-explore.lux.network`) || Host(`api-explorer.lux.network`)) && (PathPrefix(`/v1/graph`) || PathPrefix(`/v1/explorer`) || PathPrefix(`/v1/base/realtime`) || PathPrefix(`/v1/indexer`) || Path(`/health`))
|
||||
middlewares: [{name: cors-allow-all}]
|
||||
services: [{name: explorer, port: 8090}]
|
||||
# api-explore.lux.network — catch-all, rewrite to Blockscout
|
||||
- kind: Rule
|
||||
match: Host(`api-explore.lux.network`) || Host(`api-explorer.lux.network`)
|
||||
middlewares: [{name: mainpage-rewrite}, {name: blockscout-prefix-cchain}, {name: cors-allow-all}]
|
||||
services: [{name: explorer, port: 8090}]
|
||||
---
|
||||
# Lux C-Chain (umbrella → re-uses explore-fe-lux because it IS the Lux primary)
|
||||
apiVersion: hanzo.ai/v1alpha1
|
||||
kind: IngressRoute
|
||||
metadata:
|
||||
name: lux-explorer-cchain
|
||||
namespace: lux-mainnet
|
||||
labels: {app: lux-explorer, chain: cchain, network: mainnet}
|
||||
spec:
|
||||
entryPoints: [websecure]
|
||||
tls: {certResolver: letsencrypt}
|
||||
routes:
|
||||
- kind: Rule
|
||||
priority: 10000
|
||||
match: (Host(`explore-cchain.lux.network`) || Host(`explore-c.lux.network`)) && (PathPrefix(`/v1/`) || Path(`/health`) || Path(`/envs.js`) || Path(`/icon.svg`) || Path(`/logo.svg`))
|
||||
middlewares: [{name: cors-allow-all}]
|
||||
services: [{name: explorer, port: 8090}]
|
||||
- kind: Rule
|
||||
match: Host(`explore-cchain.lux.network`) || Host(`explore-c.lux.network`)
|
||||
services: [{name: explore-fe-lux, port: 80}]
|
||||
- kind: Rule
|
||||
match: Host(`api-explore-cchain.lux.network`) || Host(`api-explore-c.lux.network`)
|
||||
middlewares: [{name: mainpage-rewrite}, {name: blockscout-prefix-cchain}, {name: cors-allow-all}]
|
||||
services: [{name: explorer, port: 8090}]
|
||||
---
|
||||
# Hanzo Mainnet
|
||||
apiVersion: hanzo.ai/v1alpha1
|
||||
kind: IngressRoute
|
||||
metadata:
|
||||
name: lux-explorer-hanzo
|
||||
namespace: lux-mainnet
|
||||
labels: {app: lux-explorer, chain: hanzo, network: mainnet}
|
||||
spec:
|
||||
entryPoints: [websecure]
|
||||
tls: {certResolver: letsencrypt}
|
||||
routes:
|
||||
- kind: Rule
|
||||
priority: 10000
|
||||
match: (Host(`explore-hanzo.lux.network`) || Host(`explore.hanzo.network`) || Host(`explore.hanzo.ai`)) && (PathPrefix(`/v1/`) || Path(`/health`) || Path(`/envs.js`) || Path(`/icon.svg`) || Path(`/logo.svg`))
|
||||
middlewares: [{name: cors-allow-all}]
|
||||
services: [{name: explorer, port: 8090}]
|
||||
- kind: Rule
|
||||
match: Host(`explore-hanzo.lux.network`) || Host(`explore.hanzo.network`) || Host(`explore.hanzo.ai`)
|
||||
services: [{name: explore-fe-hanzo, port: 80}]
|
||||
- kind: Rule
|
||||
match: Host(`api-explore-hanzo.lux.network`) || Host(`api-explore.hanzo.network`) || Host(`api-explore.hanzo.ai`)
|
||||
middlewares: [{name: mainpage-rewrite}, {name: blockscout-prefix-hanzo}, {name: cors-allow-all}]
|
||||
services: [{name: explorer, port: 8090}]
|
||||
---
|
||||
# Zoo Mainnet
|
||||
apiVersion: hanzo.ai/v1alpha1
|
||||
kind: IngressRoute
|
||||
metadata:
|
||||
name: lux-explorer-zoo
|
||||
namespace: lux-mainnet
|
||||
labels: {app: lux-explorer, chain: zoo, network: mainnet}
|
||||
spec:
|
||||
entryPoints: [websecure]
|
||||
tls: {certResolver: letsencrypt}
|
||||
routes:
|
||||
- kind: Rule
|
||||
priority: 10000
|
||||
match: (Host(`explore-zoo.lux.network`) || Host(`explore.zoo.network`) || Host(`explore.zoo.ngo`) || Host(`explorer.zoo.network`) || Host(`explorer-zoo.lux.network`)) && (PathPrefix(`/v1/`) || Path(`/health`) || Path(`/envs.js`) || Path(`/icon.svg`) || Path(`/logo.svg`) || Path(`/icon-zoo.svg`) || Path(`/logo-zoo.svg`))
|
||||
middlewares: [{name: cors-allow-all}]
|
||||
services: [{name: explorer, port: 8090}]
|
||||
- kind: Rule
|
||||
match: Host(`explore-zoo.lux.network`) || Host(`explore.zoo.network`) || Host(`explore.zoo.ngo`) || Host(`explorer.zoo.network`) || Host(`explorer-zoo.lux.network`)
|
||||
services: [{name: explore-fe-zoo, port: 80}]
|
||||
- kind: Rule
|
||||
match: Host(`api-explore-zoo.lux.network`) || Host(`api-explore.zoo.network`) || Host(`api-explore.zoo.ngo`) || Host(`api-explorer.zoo.network`) || Host(`api-explorer-zoo.lux.network`)
|
||||
middlewares: [{name: mainpage-rewrite}, {name: blockscout-prefix-zoo}, {name: cors-allow-all}]
|
||||
services: [{name: explorer, port: 8090}]
|
||||
---
|
||||
# Pars Mainnet
|
||||
apiVersion: hanzo.ai/v1alpha1
|
||||
kind: IngressRoute
|
||||
metadata:
|
||||
name: lux-explorer-pars
|
||||
namespace: lux-mainnet
|
||||
labels: {app: lux-explorer, chain: pars, network: mainnet}
|
||||
spec:
|
||||
entryPoints: [websecure]
|
||||
tls: {certResolver: letsencrypt}
|
||||
routes:
|
||||
- kind: Rule
|
||||
priority: 10000
|
||||
match: (Host(`explore-pars.lux.network`) || Host(`explore.pars.network`)) && (PathPrefix(`/v1/`) || Path(`/health`) || Path(`/envs.js`) || Path(`/icon.svg`) || Path(`/logo.svg`))
|
||||
middlewares: [{name: cors-allow-all}]
|
||||
services: [{name: explorer, port: 8090}]
|
||||
- kind: Rule
|
||||
match: Host(`explore-pars.lux.network`) || Host(`explore.pars.network`)
|
||||
services: [{name: explore-fe-pars, port: 80}]
|
||||
- kind: Rule
|
||||
match: Host(`api-explore-pars.lux.network`) || Host(`api-explore.pars.network`)
|
||||
middlewares: [{name: mainpage-rewrite}, {name: blockscout-prefix-pars}, {name: cors-allow-all}]
|
||||
services: [{name: explorer, port: 8090}]
|
||||
@@ -0,0 +1,124 @@
|
||||
---
|
||||
# Lux Testnet
|
||||
apiVersion: hanzo.ai/v1alpha1
|
||||
kind: IngressRoute
|
||||
metadata:
|
||||
name: lux-explorer-testnet
|
||||
namespace: lux-testnet
|
||||
labels: {app: lux-explorer, network: testnet}
|
||||
spec:
|
||||
entryPoints: [websecure]
|
||||
tls: {certResolver: letsencrypt}
|
||||
routes:
|
||||
- kind: Rule
|
||||
priority: 10000
|
||||
match: (Host(`explore.lux-test.network`) || Host(`explorer.lux-test.network`) || Host(`explore-test.lux.network`)) && (PathPrefix(`/v1/`) || Path(`/health`) || Path(`/envs.js`) || Path(`/icon.svg`) || Path(`/logo.svg`) || Path(`/icon-zoo.svg`) || Path(`/icon-lux.svg`) || Path(`/logo-zoo.svg`) || Path(`/logo-lux.svg`))
|
||||
middlewares: [{name: cors-allow-all}]
|
||||
services: [{name: explorer, port: 8090}]
|
||||
- kind: Rule
|
||||
match: Host(`explore.lux-test.network`) || Host(`explorer.lux-test.network`) || Host(`explore-test.lux.network`)
|
||||
services: [{name: explore-fe-lux, port: 80}]
|
||||
- kind: Rule
|
||||
match: (Host(`api-explore.lux-test.network`) || Host(`api-explorer.lux-test.network`) || Host(`api-explore-test.lux.network`)) && (PathPrefix(`/v1/graph`) || PathPrefix(`/v1/explorer`) || PathPrefix(`/v1/base/realtime`) || PathPrefix(`/v1/indexer`) || Path(`/health`))
|
||||
middlewares: [{name: cors-allow-all}]
|
||||
services: [{name: explorer, port: 8090}]
|
||||
- kind: Rule
|
||||
match: Host(`api-explore.lux-test.network`) || Host(`api-explorer.lux-test.network`) || Host(`api-explore-test.lux.network`)
|
||||
middlewares: [{name: mainpage-rewrite}, {name: blockscout-prefix-cchain}, {name: cors-allow-all}]
|
||||
services: [{name: explorer, port: 8090}]
|
||||
---
|
||||
# C-Chain Testnet (umbrella → lux FE)
|
||||
apiVersion: hanzo.ai/v1alpha1
|
||||
kind: IngressRoute
|
||||
metadata:
|
||||
name: lux-explorer-cchain-testnet
|
||||
namespace: lux-testnet
|
||||
labels: {app: lux-explorer, chain: cchain, network: testnet}
|
||||
spec:
|
||||
entryPoints: [websecure]
|
||||
tls: {certResolver: letsencrypt}
|
||||
routes:
|
||||
- kind: Rule
|
||||
priority: 10000
|
||||
match: (Host(`explore-cchain-test.lux.network`) || Host(`explore-c-test.lux.network`)) && (PathPrefix(`/v1/`) || Path(`/health`) || Path(`/envs.js`) || Path(`/icon.svg`) || Path(`/logo.svg`))
|
||||
middlewares: [{name: cors-allow-all}]
|
||||
services: [{name: explorer, port: 8090}]
|
||||
- kind: Rule
|
||||
match: Host(`explore-cchain-test.lux.network`) || Host(`explore-c-test.lux.network`)
|
||||
services: [{name: explore-fe-lux, port: 80}]
|
||||
- kind: Rule
|
||||
match: Host(`api-explore-cchain-test.lux.network`) || Host(`api-explore-c-test.lux.network`)
|
||||
middlewares: [{name: mainpage-rewrite}, {name: blockscout-prefix-cchain}, {name: cors-allow-all}]
|
||||
services: [{name: explorer, port: 8090}]
|
||||
---
|
||||
# Hanzo Testnet
|
||||
apiVersion: hanzo.ai/v1alpha1
|
||||
kind: IngressRoute
|
||||
metadata:
|
||||
name: lux-explorer-hanzo-testnet
|
||||
namespace: lux-testnet
|
||||
labels: {app: lux-explorer, chain: hanzo, network: testnet}
|
||||
spec:
|
||||
entryPoints: [websecure]
|
||||
tls: {certResolver: letsencrypt}
|
||||
routes:
|
||||
- kind: Rule
|
||||
priority: 10000
|
||||
match: (Host(`explore-hanzo-test.lux.network`) || Host(`explore.hanzo-test.network`) || Host(`explorer.hanzo-test.network`)) && (PathPrefix(`/v1/`) || Path(`/health`) || Path(`/envs.js`) || Path(`/icon.svg`) || Path(`/logo.svg`))
|
||||
middlewares: [{name: cors-allow-all}]
|
||||
services: [{name: explorer, port: 8090}]
|
||||
- kind: Rule
|
||||
match: Host(`explore-hanzo-test.lux.network`) || Host(`explore.hanzo-test.network`) || Host(`explorer.hanzo-test.network`)
|
||||
services: [{name: explore-fe-hanzo, port: 80}]
|
||||
- kind: Rule
|
||||
match: Host(`api-explore-hanzo-test.lux.network`) || Host(`api-explore.hanzo-test.network`) || Host(`api-explorer.hanzo-test.network`)
|
||||
middlewares: [{name: mainpage-rewrite}, {name: blockscout-prefix-hanzo}, {name: cors-allow-all}]
|
||||
services: [{name: explorer, port: 8090}]
|
||||
---
|
||||
# Zoo Testnet
|
||||
apiVersion: hanzo.ai/v1alpha1
|
||||
kind: IngressRoute
|
||||
metadata:
|
||||
name: lux-explorer-zoo-testnet
|
||||
namespace: lux-testnet
|
||||
labels: {app: lux-explorer, chain: zoo, network: testnet}
|
||||
spec:
|
||||
entryPoints: [websecure]
|
||||
tls: {certResolver: letsencrypt}
|
||||
routes:
|
||||
- kind: Rule
|
||||
priority: 10000
|
||||
match: (Host(`explore-zoo-test.lux.network`) || Host(`explore.zoo-test.network`) || Host(`explorer.zoo-test.network`) || Host(`explorer-zoo-test.lux.network`)) && (PathPrefix(`/v1/`) || Path(`/health`) || Path(`/envs.js`) || Path(`/icon.svg`) || Path(`/logo.svg`) || Path(`/icon-zoo.svg`) || Path(`/logo-zoo.svg`))
|
||||
middlewares: [{name: cors-allow-all}]
|
||||
services: [{name: explorer, port: 8090}]
|
||||
- kind: Rule
|
||||
match: Host(`explore-zoo-test.lux.network`) || Host(`explore.zoo-test.network`) || Host(`explorer.zoo-test.network`) || Host(`explorer-zoo-test.lux.network`)
|
||||
services: [{name: explore-fe-zoo, port: 80}]
|
||||
- kind: Rule
|
||||
match: Host(`api-explore-zoo-test.lux.network`) || Host(`api-explore.zoo-test.network`) || Host(`api-explorer.zoo-test.network`) || Host(`api-explorer-zoo-test.lux.network`)
|
||||
middlewares: [{name: mainpage-rewrite}, {name: blockscout-prefix-zoo}, {name: cors-allow-all}]
|
||||
services: [{name: explorer, port: 8090}]
|
||||
---
|
||||
# Pars Testnet
|
||||
apiVersion: hanzo.ai/v1alpha1
|
||||
kind: IngressRoute
|
||||
metadata:
|
||||
name: lux-explorer-pars-testnet
|
||||
namespace: lux-testnet
|
||||
labels: {app: lux-explorer, chain: pars, network: testnet}
|
||||
spec:
|
||||
entryPoints: [websecure]
|
||||
tls: {certResolver: letsencrypt}
|
||||
routes:
|
||||
- kind: Rule
|
||||
priority: 10000
|
||||
match: (Host(`explore-pars-test.lux.network`) || Host(`explore.pars-test.network`)) && (PathPrefix(`/v1/`) || Path(`/health`) || Path(`/envs.js`) || Path(`/icon.svg`) || Path(`/logo.svg`))
|
||||
middlewares: [{name: cors-allow-all}]
|
||||
services: [{name: explorer, port: 8090}]
|
||||
- kind: Rule
|
||||
match: Host(`explore-pars-test.lux.network`) || Host(`explore.pars-test.network`)
|
||||
services: [{name: explore-fe-pars, port: 80}]
|
||||
- kind: Rule
|
||||
match: Host(`api-explore-pars-test.lux.network`) || Host(`api-explore.pars-test.network`)
|
||||
middlewares: [{name: mainpage-rewrite}, {name: blockscout-prefix-pars}, {name: cors-allow-all}]
|
||||
services: [{name: explorer, port: 8090}]
|
||||
Executable
+205
@@ -0,0 +1,205 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build 4 canonical, brand-only Blockscout overlay images. One image per brand —
|
||||
# env-specific config (NETWORK_ID, IS_TESTNET, API_HOST, …) lives in K8s
|
||||
# ConfigMaps and lands on the pod via Deployment `envFrom`. Brand identity
|
||||
# (NETWORK_NAME, OIDC client ID, currency, brand colors) is baked here.
|
||||
#
|
||||
# Outputs:
|
||||
# ghcr.io/luxfi/explore:v1.0.0
|
||||
# ghcr.io/zooai/explore:v1.0.0
|
||||
# ghcr.io/hanzoai/explore:v1.0.0
|
||||
# ghcr.io/parsdao/explore:v1.0.0
|
||||
#
|
||||
# Replaces the older 8-image `explore-{env}` scheme. See env-specific
|
||||
# ConfigMaps under deploy/k8s/explore-fe/configmap-*.yaml.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
VERSION="${VERSION:-v1.0.0}"
|
||||
BASE_IMAGE="${BASE_IMAGE:-ghcr.io/luxfi/explore:latest}"
|
||||
|
||||
TMPDIR_BASE="${TMPDIR:-/tmp}/canonical-build-$$"
|
||||
mkdir -p "$TMPDIR_BASE"
|
||||
trap "rm -rf '$TMPDIR_BASE'" EXIT
|
||||
|
||||
# Per-brand identity. Values that must vary by env (NETWORK_ID, IS_TESTNET,
|
||||
# API_HOST, RPC_URL, APP_HOST) are intentionally OMITTED here — they come
|
||||
# from ConfigMaps at runtime via Deployment `envFrom`.
|
||||
brands() {
|
||||
cat <<'EOF'
|
||||
lux ghcr.io/luxfi/explore
|
||||
zoo ghcr.io/zooai/explore
|
||||
hanzo ghcr.io/hanzoai/explore
|
||||
pars ghcr.io/parsdao/explore
|
||||
EOF
|
||||
}
|
||||
|
||||
brand_args_for() {
|
||||
case "$1" in
|
||||
lux)
|
||||
cat <<'EOF'
|
||||
NEXT_PUBLIC_BRAND=lux
|
||||
NEXT_PUBLIC_NETWORK_NAME=Lux Network
|
||||
NEXT_PUBLIC_NETWORK_SHORT_NAME=LUX
|
||||
NEXT_PUBLIC_NETWORK_CURRENCY_NAME=LUX
|
||||
NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL=LUX
|
||||
NEXT_PUBLIC_NETWORK_ORG_NAME=Lux Industries Inc.
|
||||
NEXT_PUBLIC_NETWORK_WEBSITE_URL=https://lux.network
|
||||
NEXT_PUBLIC_NETWORK_DESCRIPTION=High-performance blockchain for decentralized applications.
|
||||
NEXT_PUBLIC_NETWORK_GITHUB_URL=https://github.com/luxfi
|
||||
NEXT_PUBLIC_NETWORK_TWITTER_URL=https://x.com/luxdefi
|
||||
NEXT_PUBLIC_NETWORK_DISCORD_URL=https://discord.gg/luxnetwork
|
||||
NEXT_PUBLIC_OIDC_SERVER_URL=https://lux.id
|
||||
NEXT_PUBLIC_OIDC_CLIENT_ID=lux-explore-client-id
|
||||
EOF
|
||||
;;
|
||||
zoo)
|
||||
cat <<'EOF'
|
||||
NEXT_PUBLIC_BRAND=zoo
|
||||
NEXT_PUBLIC_NETWORK_NAME=Zoo Network
|
||||
NEXT_PUBLIC_NETWORK_SHORT_NAME=ZOO
|
||||
NEXT_PUBLIC_NETWORK_CURRENCY_NAME=Zoo
|
||||
NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL=ZOO
|
||||
NEXT_PUBLIC_NETWORK_ORG_NAME=Zoo Labs Foundation
|
||||
NEXT_PUBLIC_NETWORK_WEBSITE_URL=https://zoo.network
|
||||
NEXT_PUBLIC_NETWORK_DESCRIPTION=Zoo Network — decentralized AI research blockchain.
|
||||
NEXT_PUBLIC_NETWORK_GITHUB_URL=https://github.com/zooai
|
||||
NEXT_PUBLIC_NETWORK_TWITTER_URL=https://x.com/zoo_network
|
||||
NEXT_PUBLIC_NETWORK_DISCORD_URL=https://discord.gg/zoonetwork
|
||||
NEXT_PUBLIC_OIDC_SERVER_URL=https://zoo.id
|
||||
NEXT_PUBLIC_OIDC_CLIENT_ID=zoo-explore-client-id
|
||||
EOF
|
||||
;;
|
||||
hanzo)
|
||||
cat <<'EOF'
|
||||
NEXT_PUBLIC_BRAND=hanzo
|
||||
NEXT_PUBLIC_NETWORK_NAME=Hanzo Network
|
||||
NEXT_PUBLIC_NETWORK_SHORT_NAME=AI
|
||||
NEXT_PUBLIC_NETWORK_CURRENCY_NAME=AI
|
||||
NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL=AI
|
||||
NEXT_PUBLIC_NETWORK_ORG_NAME=Hanzo AI Inc.
|
||||
NEXT_PUBLIC_NETWORK_WEBSITE_URL=https://hanzo.ai
|
||||
NEXT_PUBLIC_NETWORK_DESCRIPTION=Hanzo Network — AI infrastructure blockchain.
|
||||
NEXT_PUBLIC_NETWORK_GITHUB_URL=https://github.com/hanzoai
|
||||
NEXT_PUBLIC_NETWORK_TWITTER_URL=https://x.com/hanzoai
|
||||
NEXT_PUBLIC_NETWORK_DISCORD_URL=https://discord.gg/hanzoai
|
||||
NEXT_PUBLIC_OIDC_SERVER_URL=https://hanzo.id
|
||||
NEXT_PUBLIC_OIDC_CLIENT_ID=hanzo-explore-client-id
|
||||
EOF
|
||||
;;
|
||||
pars)
|
||||
cat <<'EOF'
|
||||
NEXT_PUBLIC_BRAND=pars
|
||||
NEXT_PUBLIC_NETWORK_NAME=Pars Network
|
||||
NEXT_PUBLIC_NETWORK_SHORT_NAME=PARS
|
||||
NEXT_PUBLIC_NETWORK_CURRENCY_NAME=Pars
|
||||
NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL=PARS
|
||||
NEXT_PUBLIC_NETWORK_ORG_NAME=Pars DAO
|
||||
NEXT_PUBLIC_NETWORK_WEBSITE_URL=https://pars.network
|
||||
NEXT_PUBLIC_NETWORK_DESCRIPTION=Pars Network — Persian community L1 blockchain.
|
||||
NEXT_PUBLIC_NETWORK_GITHUB_URL=https://github.com/parsdao
|
||||
NEXT_PUBLIC_NETWORK_TWITTER_URL=https://x.com/parsdao
|
||||
NEXT_PUBLIC_NETWORK_DISCORD_URL=https://discord.gg/parsdao
|
||||
NEXT_PUBLIC_OIDC_SERVER_URL=https://pars.id
|
||||
NEXT_PUBLIC_OIDC_CLIENT_ID=pars-explore-client-id
|
||||
EOF
|
||||
;;
|
||||
*) echo "unknown brand: $1" >&2; return 1;;
|
||||
esac
|
||||
# Common, brand-invariant runtime defaults that don't vary per env.
|
||||
cat <<'EOF'
|
||||
NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS=18
|
||||
NEXT_PUBLIC_API_PROTOCOL=https
|
||||
NEXT_PUBLIC_API_BASE_PATH=/
|
||||
NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL=wss
|
||||
NEXT_PUBLIC_APP_PROTOCOL=https
|
||||
NEXT_PUBLIC_NETWORK_LOGO=/logo.svg
|
||||
NEXT_PUBLIC_NETWORK_ICON=/icon.svg
|
||||
NEXT_PUBLIC_HOMEPAGE_CHARTS=["daily_txs","coin_price","market_cap"]
|
||||
NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED=true
|
||||
NEXT_PUBLIC_COLOR_THEME_DEFAULT=dark
|
||||
NEXT_PUBLIC_ACCOUNT_AUTH_PROVIDER=oidc
|
||||
NEXT_TELEMETRY_DISABLED=1
|
||||
ENVS_PRESET=none
|
||||
SKIP_ENVS_VALIDATION=true
|
||||
EOF
|
||||
}
|
||||
|
||||
if [ "${1:-}" = "--list" ]; then
|
||||
brands | while read -r brand target; do
|
||||
[ -z "${brand:-}" ] && continue
|
||||
echo "${brand} ${target}:${VERSION}"
|
||||
done
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "${1:-}" = "--brand-args" ] && [ -n "${2:-}" ]; then
|
||||
brand_args_for "$2"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
FAIL=""
|
||||
SUCCESS=""
|
||||
|
||||
while read -r brand target; do
|
||||
[ -z "${brand:-}" ] && continue
|
||||
full="${target}:${VERSION}"
|
||||
echo "=== ${brand} → ${full} ==="
|
||||
|
||||
# Step 1: mutate process env for child processes (Next.js server reads via env).
|
||||
env_flags=()
|
||||
brand_kv="$(brand_args_for "$brand")"
|
||||
while IFS='=' read -r k v; do
|
||||
[ -z "$k" ] && continue
|
||||
env_flags+=("-e" "${k}=${v}")
|
||||
done <<< "$brand_kv"
|
||||
|
||||
# Mutate to a temp tag, then append a /app/.env overlay so Blockscout's
|
||||
# entrypoint `source .env` exports brand identity vars into the shell
|
||||
# before make_envs_script.sh iterates env. ConfigMap-supplied env vars
|
||||
# (NETWORK_ID, IS_TESTNET, *_HOST, RPC_URL) are NOT in .env so they
|
||||
# come from process env at runtime, which the iteration also picks up.
|
||||
tmp_image="ghcr.io/luxfi/explore-tmp:${brand}-$$"
|
||||
if ! crane mutate "$BASE_IMAGE" "${env_flags[@]}" -t "$tmp_image" 2>&1 | tail -1; then
|
||||
FAIL="${FAIL}${full}: mutate-failed
|
||||
"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Step 2: build a layer tar containing /app/.env with brand identity values.
|
||||
tuple_dir="${TMPDIR_BASE}/${brand}"
|
||||
mkdir -p "${tuple_dir}/app"
|
||||
while IFS='=' read -r k v; do
|
||||
[ -z "$k" ] && continue
|
||||
# JSON-array vals like NEXT_PUBLIC_HOMEPAGE_CHARTS need single-quoting
|
||||
# so bash `source` preserves the embedded double quotes.
|
||||
if [[ "$v" == \[* ]]; then
|
||||
echo "$k='$v'"
|
||||
else
|
||||
echo "$k=$v"
|
||||
fi
|
||||
done <<< "$brand_kv" > "${tuple_dir}/app/.env"
|
||||
|
||||
tarfile="${tuple_dir}/layer.tar"
|
||||
tar -C "$tuple_dir" -cf "$tarfile" app
|
||||
|
||||
if ! crane append -b "$tmp_image" -f "$tarfile" -t "$full" 2>&1 | tail -1; then
|
||||
FAIL="${FAIL}${full}: append-failed
|
||||
"
|
||||
continue
|
||||
fi
|
||||
|
||||
digest=$(crane digest "$full" 2>/dev/null || echo "?")
|
||||
SUCCESS="${SUCCESS}${full}@${digest}
|
||||
"
|
||||
echo "OK: ${full}@${digest}"
|
||||
done < <(brands)
|
||||
|
||||
echo
|
||||
echo "=== Canonical brand images ==="
|
||||
printf '%s' "$SUCCESS" | sed 's/^/ + /'
|
||||
if [ -n "$FAIL" ]; then
|
||||
echo "Failed:"
|
||||
printf '%s' "$FAIL" | sed 's/^/ - /'
|
||||
exit 1
|
||||
fi
|
||||
+40
-3
@@ -1,6 +1,7 @@
|
||||
import type { Chain } from 'viem';
|
||||
|
||||
import appConfig from 'configs/app';
|
||||
import { CHAINS as REGISTRY_CHAINS, getCurrentChain } from 'configs/app/chainRegistry';
|
||||
import essentialDappsChainsConfig from 'configs/essential-dapps-chains';
|
||||
import multichainConfig from 'configs/multichain';
|
||||
|
||||
@@ -94,17 +95,53 @@ export const essentialDappsChains: Array<Chain> | undefined = (() => {
|
||||
return config.chains.map(({ app_config: config, contracts, logo }) => getChainInfo(config, contracts, logo)).filter(Boolean);
|
||||
})();
|
||||
|
||||
// Sibling networks of the current brand, sourced from the multi-tenant chain
|
||||
// registry so the wallet-connect flow presents / can add EVERY registered
|
||||
// network for this brand — e.g. Lux mainnet (96369), testnet (96368) and
|
||||
// devnet (96370) — instead of only the single env-configured chain. This is
|
||||
// the "native all-chains" connect: the list is derived from the registry
|
||||
// (the same source of truth as the header chain switcher), never hardcoded to
|
||||
// one chain. Each sibling's read RPC is its brand explorer's Blockscout
|
||||
// eth-rpc proxy (mirrors the read-only transport wagmiConfig builds for the
|
||||
// primary chain); the current chain keeps its own direct RPC from env.
|
||||
export const brandFamilyChains: Array<Chain> = (() => {
|
||||
if (!currentChain) {
|
||||
return [];
|
||||
}
|
||||
const current = getCurrentChain();
|
||||
const titleCase = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);
|
||||
|
||||
return REGISTRY_CHAINS
|
||||
.filter((c) => c.branding.brandName === current.branding.brandName && c.chainId !== currentChain.id)
|
||||
.map((c): Chain => ({
|
||||
id: c.chainId,
|
||||
name: c.network === 'mainnet' ? current.branding.brandName : `${ current.branding.brandName } ${ titleCase(c.network) }`,
|
||||
nativeCurrency: currentChain.nativeCurrency,
|
||||
rpcUrls: {
|
||||
'default': { http: [ `${ c.apiUrl }/api/eth-rpc` ] },
|
||||
},
|
||||
blockExplorers: {
|
||||
'default': { name: `${ current.branding.brandName } Explorer`, url: c.explorerUrl },
|
||||
},
|
||||
testnet: c.network !== 'mainnet',
|
||||
}));
|
||||
})();
|
||||
|
||||
export const chains = (() => {
|
||||
const dedupeById = (list: Array<Chain | undefined>): Array<Chain> =>
|
||||
list.filter(Boolean).filter((chain, index, arr) => arr.findIndex((c) => c?.id === chain?.id) === index) as Array<Chain>;
|
||||
|
||||
if (essentialDappsChains) {
|
||||
const hasCurrentChain = essentialDappsChains.some((chain) => chain.id === currentChain?.id);
|
||||
const hasParentChain = essentialDappsChains.some((chain) => chain.id === parentChain?.id);
|
||||
|
||||
return [
|
||||
return dedupeById([
|
||||
...essentialDappsChains,
|
||||
hasCurrentChain ? undefined : currentChain,
|
||||
hasParentChain ? undefined : parentChain,
|
||||
].filter(Boolean);
|
||||
...brandFamilyChains,
|
||||
]);
|
||||
}
|
||||
|
||||
return [ currentChain, parentChain, ...(clusterChains ?? []) ].filter(Boolean);
|
||||
return dedupeById([ currentChain, ...brandFamilyChains, parentChain, ...(clusterChains ?? []) ]);
|
||||
})();
|
||||
|
||||
@@ -32,7 +32,8 @@ interface Params {
|
||||
}
|
||||
|
||||
export default function useAddChain(params?: Params) {
|
||||
const { data: { wallet, provider } = {} } = useProvider();
|
||||
const { data: providerData } = useProvider();
|
||||
const { wallet, provider } = providerData ?? {};
|
||||
const { trackUsage } = useRewardsActivity();
|
||||
const multichainContext = useMultichainContext();
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { toaster } from '@luxfi/ui/toaster';
|
||||
import React from 'react';
|
||||
|
||||
import * as mixpanel from 'lib/mixpanel/index';
|
||||
import { toaster } from '@luxfi/ui/toaster';
|
||||
|
||||
import useAddChain from './useAddChain';
|
||||
import useProvider from './useProvider';
|
||||
@@ -13,7 +13,8 @@ interface Props {
|
||||
}
|
||||
|
||||
export default function useAddChainClick({ source, onSuccess }: Props) {
|
||||
const { data: { wallet, provider } = {} } = useProvider();
|
||||
const { data: providerData } = useProvider();
|
||||
const { wallet, provider } = providerData ?? {};
|
||||
const addChain = useAddChain();
|
||||
const switchChain = useSwitchChain();
|
||||
|
||||
|
||||
@@ -17,9 +17,11 @@ export default function useProvider() {
|
||||
|
||||
return useQuery({
|
||||
queryKey: [ 'web3-wallet' ],
|
||||
// react-query v5 forbids a queryFn resolving to `undefined` ("Query data
|
||||
// cannot be undefined"). Every no-wallet-found branch returns `null`.
|
||||
queryFn: async() => {
|
||||
if (!feature.isEnabled || !wallets) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!('ethereum' in window && window.ethereum)) {
|
||||
@@ -42,14 +44,14 @@ export default function useProvider() {
|
||||
shouldShimWeb3: true,
|
||||
});
|
||||
} else {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// have to check again in case provider was not set as window.ethereum in the previous step for MM in FF
|
||||
// and also it makes typescript happy
|
||||
if (!('ethereum' in window && window.ethereum)) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
for (const wallet of wallets) {
|
||||
@@ -65,6 +67,8 @@ export default function useProvider() {
|
||||
return detectedWallet;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
enabled: Boolean(feature.isEnabled || !wallets),
|
||||
refetchOnMount: false,
|
||||
|
||||
@@ -19,7 +19,8 @@ interface Params {
|
||||
}
|
||||
|
||||
export default function useSwitchChain(params?: Params) {
|
||||
const { data: { wallet, provider } = {} } = useProvider();
|
||||
const { data: providerData } = useProvider();
|
||||
const { wallet, provider } = providerData ?? {};
|
||||
const multichainContext = useMultichainContext();
|
||||
|
||||
const chainConfig = params?.chainConfig || multichainContext?.chain.app_config || config;
|
||||
|
||||
@@ -13,7 +13,8 @@ interface Params {
|
||||
}
|
||||
|
||||
export default function useSwitchOrAddChain(params?: Params) {
|
||||
const { data: { wallet, provider } = {} } = useProvider();
|
||||
const { data: providerData } = useProvider();
|
||||
const { wallet, provider } = providerData ?? {};
|
||||
const addChain = useAddChain(params);
|
||||
const switchChain = useSwitchChain(params);
|
||||
|
||||
|
||||
+15
-1
@@ -7,10 +7,22 @@ import { createConfig } from 'wagmi';
|
||||
import appConfig from 'configs/app';
|
||||
import essentialDappsChainsConfig from 'configs/essential-dapps-chains';
|
||||
import multichainConfig from 'configs/multichain';
|
||||
import { chains, parentChain } from 'lib/web3/chains';
|
||||
import { brandFamilyChains, chains, parentChain } from 'lib/web3/chains';
|
||||
|
||||
const feature = appConfig.features.blockchainInteraction;
|
||||
|
||||
// Transports for the brand's sibling networks (Lux testnet/devnet, …) added by
|
||||
// lib/web3/chains. wagmi requires a transport per chain; each sibling uses the
|
||||
// Blockscout eth-rpc endpoint carried on its viem chain definition.
|
||||
const getBrandFamilyTransports = (): Record<string, Transport> =>
|
||||
brandFamilyChains.reduce((acc, chain) => {
|
||||
const url = chain.rpcUrls.default.http[0];
|
||||
if (url) {
|
||||
acc[chain.id] = http(url, { batch: { wait: 100, batchSize: 5 } });
|
||||
}
|
||||
return acc;
|
||||
}, {} as Record<string, Transport>);
|
||||
|
||||
const getChainTransportFromConfig = (config: Partial<typeof appConfig> | undefined, readOnly?: boolean): Record<string, Transport> => {
|
||||
if (!config?.chain?.id) {
|
||||
return {};
|
||||
@@ -53,6 +65,7 @@ const wagmi = (() => {
|
||||
transports: {
|
||||
...getChainTransportFromConfig(appConfig, true),
|
||||
...(parentChain ? { [parentChain.id]: http(parentChain.rpcUrls.default.http[0]) } : {}),
|
||||
...getBrandFamilyTransports(),
|
||||
...reduceExternalChainsToTransportConfig(true),
|
||||
},
|
||||
ssr: true,
|
||||
@@ -69,6 +82,7 @@ const wagmi = (() => {
|
||||
transports: {
|
||||
...getChainTransportFromConfig(appConfig, false),
|
||||
...(parentChain ? { [parentChain.id]: http() } : {}),
|
||||
...getBrandFamilyTransports(),
|
||||
...reduceExternalChainsToTransportConfig(false),
|
||||
},
|
||||
projectId: feature.reown.projectId,
|
||||
|
||||
Vendored
+1
-1
@@ -1,6 +1,6 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
import './.next/dev/types/routes.d.ts';
|
||||
import './.next/types/routes.d.ts';
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/pages/api-reference/config/typescript for more information.
|
||||
|
||||
@@ -3,6 +3,22 @@
|
||||
|
||||
@plugin "tailwindcss-animate";
|
||||
|
||||
/*
|
||||
* Scan the @luxfi/ui component library for Tailwind classes.
|
||||
*
|
||||
* @luxfi/ui ships pre-built components whose className strings use arbitrary
|
||||
* Tailwind utilities that resolve design tokens — e.g. the popover / menu /
|
||||
* drawer surfaces are styled with bg-[var(--color-popover-bg)],
|
||||
* bg-[var(--color-drawer-bg)], shadow-[var(--shadow-popover)] and
|
||||
* border-[var(--color-popover-border)]. Tailwind v4 does not scan node_modules
|
||||
* by default, so without this @source those utilities are purged and every
|
||||
* floating panel (Sign-in popover, Blockchain menu, chain/network selectors,
|
||||
* mobile nav drawer) renders with a transparent background — the page bleeds
|
||||
* through and the content is unreadable. Sourcing the package makes Tailwind
|
||||
* emit the utilities so the panels get their solid token-driven backgrounds.
|
||||
*/
|
||||
@source "../node_modules/@luxfi/ui";
|
||||
|
||||
/*
|
||||
* Tailwind v4 theme configuration
|
||||
*
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@luxfi/explore",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.4",
|
||||
"private": false,
|
||||
"homepage": "https://github.com/luxfi/explore#readme",
|
||||
"engines": {
|
||||
|
||||
@@ -20,19 +20,23 @@
|
||||
},
|
||||
{
|
||||
"id": 200200,
|
||||
"name": "Zoo Subnet"
|
||||
"name": "Zoo Network"
|
||||
},
|
||||
{
|
||||
"id": 36963,
|
||||
"name": "Hanzo Subnet"
|
||||
"name": "Hanzo Network"
|
||||
},
|
||||
{
|
||||
"id": 36911,
|
||||
"name": "SPC Subnet"
|
||||
"name": "SPC Network"
|
||||
},
|
||||
{
|
||||
"id": 494949,
|
||||
"name": "Pars Subnet"
|
||||
"name": "Pars Network"
|
||||
},
|
||||
{
|
||||
"id": 1872,
|
||||
"name": "Osage Network"
|
||||
}
|
||||
],
|
||||
"peers": [],
|
||||
|
||||
@@ -185,6 +185,7 @@
|
||||
--color-dialog-bg: #FFFFFF;
|
||||
--color-dialog-fg: rgba(16, 17, 18, 0.80);
|
||||
--color-popover-bg: #FFFFFF;
|
||||
--color-popover-border: rgba(16, 17, 18, 0.10);
|
||||
--color-popover-shadow: rgba(16, 17, 18, 0.08);
|
||||
--color-drawer-bg: #FFFFFF;
|
||||
|
||||
@@ -434,6 +435,7 @@
|
||||
--color-dialog-bg: #171717;
|
||||
--color-dialog-fg: rgba(255, 255, 255, 0.80);
|
||||
--color-popover-bg: #171717;
|
||||
--color-popover-border: rgba(255, 255, 255, 0.12);
|
||||
--color-popover-shadow: rgba(255, 255, 255, 0.16);
|
||||
--color-drawer-bg: #171717;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user