Files
explore/lib/white-label.ts
T
zeekay 608243e03a refactor(pchain): Subnet -> Net; add the mainnet explorer ingress
Drops "subnet" from the P-chain surface, which is not our vocabulary:

    useSubnets          -> useNets      (useSubnets.ts deleted)
    PChainSubnet        -> PChainNet
    GetSubnetsResponse  -> GetNetsResponse

One "subnet" deliberately survives — `subnetID` in lib/api/pchain/wire.spec.ts.
That is the UPSTREAM P-chain wire field, read through a raw
Record<string,string> cast, so renaming it would break response parsing. The
rule is about our own language, not about lying to the wire.

Also adds deploy/k8s/explore-fe/ingress-mainnet.yaml. explore.lux.network is
served by the Next.js deployment explore-fe-lux (ghcr.io/luxfi/explore), not
the Go `explorer` binary, which only backs api-explore.lux.network. This
replaces drift where the plain Ingress pointed explore.lux.network at
explorer:80 — the Go binary's embedded, stale build.

Two pre-commit gates had to be satisfied, both legitimate:
- eslint max-len: three className lines (BridgePage 230 chars, ChainRow 188 x2)
  exceeded the 160 limit; wrapped.
- cspell: `platformvm` flagged unknown. It is the P-chain VM's actual name, so
  it is added to cspell.jsonc `words` rather than renamed in code. (Note for
  the next person: .cspell-words.txt is listed under ignorePaths — it is a file
  excluded from checking, NOT the dictionary. Adding a word there does nothing.)

Verified: tsc --noEmit reports ZERO errors in every file this commit touches and
zero stale-symbol errors, so the rename resolves completely. The project's 223
pre-existing errors are all in untouched files and unchanged by this commit.
2026-07-26 09:11:38 -07:00

53 lines
1.9 KiB
TypeScript

// White-label brand detection.
//
// Source code in this repo is Lux-only. Per-chain identity (Zoo / Hanzo / SPC /
// Pars L1s on Lux primary network) is rendered with each chain's logo and
// name as network metadata — see `configs/app/chainRegistry.ts`. The explorer
// brand itself is always Lux.
//
// External operators running their own EVM chain can deploy this image as an
// unbranded ("other") explorer by setting NEXT_PUBLIC_BRAND=other plus the
// NEXT_PUBLIC_NETWORK_* env vars (see `.env.example.external`). They MUST
// supply their own brand strings at runtime — none are hardcoded here.
import { getEnvValue } from 'configs/app/utils';
export type WhiteLabelBrand = 'lux' | 'other';
const BRAND_HOSTNAME_SUFFIXES: ReadonlyArray<{ readonly suffix: string; readonly brand: WhiteLabelBrand }> = [
{ suffix: '.lux.network', brand: 'lux' },
{ suffix: '.lux.build', brand: 'lux' },
{ suffix: '.lux-test.network', brand: 'lux' },
{ suffix: '.lux-dev.network', brand: 'lux' },
];
export function getWhiteLabelBrand(hostname?: string): WhiteLabelBrand {
// 1. Explicit env var wins (CI/CD, k8s ConfigMap)
const envBrand = getEnvValue('NEXT_PUBLIC_BRAND');
if (envBrand) {
const normalized = envBrand.toLowerCase();
if (normalized === 'lux' || normalized === 'other') {
return normalized;
}
// Any unknown brand string → 'other' (env-driven white-label)
return 'other';
}
// 2. Hostname-based detection
const host = (hostname || (typeof window !== 'undefined' ? window.location.hostname : '')).toLowerCase();
if (host) {
for (const entry of BRAND_HOSTNAME_SUFFIXES) {
if (host === entry.suffix.slice(1) || host.endsWith(entry.suffix)) {
return entry.brand;
}
}
}
// 3. Default
return 'lux';
}
export function isWhiteLabelExternal(brand: WhiteLabelBrand): boolean {
return brand === 'other';
}