* fix(web): use real Casdoor client zoo-console for Zoo brand IAM
The zoo brand preset used clientId "zoo-app-client-id", which is not a
registered Casdoor application — Casdoor's get-app-login returns
"Invalid client_id" for it, so login from zoo.cloud / web3.zoo.ngo via
zoolabs.id never completed.
Switch to "zoo-console" (org "zoo"), the actual registered app whose
redirectUris already include https://zoo.cloud/* and
https://zoolabs.id/callback, so the OAuth round-trip resolves with no
IAM-side changes required.
* web: static-export build for lux.cloud (Lux Cloud) Cloudflare Pages deploy
Deploy the web3 console as lux.cloud (Lux brand). Convert from SSR
(output: standalone) to static export so it serves as static assets on
Cloudflare Pages with no edge/Node runtime.
- next.config.ts: output "export" + images.unoptimized; drop headers()/
redirects() (unsupported in export) — moved to public/_headers and
public/_redirects for Pages.
- app/layout.tsx: bake brand from NEXT_PUBLIC_BRAND/BRAND; remove
force-dynamic + headers() host detection (client still auto-detects brand
from window.location.hostname via lib/brand.ts).
- app/api/health, app/llms.txt: mark route handlers force-static.
- Remove app/dashboard/api/keys route handler (backend proxy unsupported in
export; the dashboard talks to brand.apiUrl directly).
- nodes/[id]: split into a server page.tsx (generateStaticParams) + client
node-detail-client.tsx so the dynamic segment is export-compatible.
- unified-navigation.tsx: fix API Keys link to the real /dashboard/api-keys
page (was pointing at the removed route handler).
- lib/brand.ts: point lux IAM clientId at the real Casdoor app "lux-cloud"
(clientId lux-app-client-id does not exist in IAM).
Built with NEXT_PUBLIC_BRAND=lux, IAM lux.id / client lux-cloud; deployed to
CF Pages project lux-cloud, custom domain lux.cloud.
* web: decomplect brand into runtime white-label config
Remove the hardcoded 5-brand catalog from web/lib/brand.ts; resolve the
active brand at runtime by hostname from an external catalog
(window.__BRAND_CATALOG__ / /config.json), mirroring the @hanzo/id SPA.
Ship one neutral built-in bootnode fallback. Add BrandProvider that loads
the per-deploy catalog client-side after hydration.
---------
Co-authored-by: Antje Worring <[email protected]>
Co-authored-by: hanzo-dev <[email protected]>
Co-authored-by: Hanzo Dev <[email protected]>
* web: static-export build + Zoo/Lux brand IAM clientId fixes
Two source-only changes for the Lux/Zoo Cloud console (web/), with no
committed build output.
next.config.ts (SSR -> static export):
- output "standalone" -> "export" + images.unoptimized for Cloudflare Pages.
- Drop headers()/redirects() (unsupported in export); moved to public/_headers
and public/_redirects for Pages. Keep poweredByHeader: false.
Static-export compatibility (no SSR/server runtime):
- layout.tsx: bake brand from NEXT_PUBLIC_BRAND/BRAND; drop force-dynamic +
headers() host detection (client still auto-detects brand from
window.location.hostname via lib/brand.ts).
- app/api/health, app/llms.txt: mark route handlers force-static.
- Remove app/dashboard/api/keys route handler (backend proxy unsupported in
export; dashboard talks to brand.apiUrl directly).
- nodes/[id]: split into server page.tsx (generateStaticParams) + client
node-detail-client.tsx so the dynamic segment is export-compatible.
- unified-navigation.tsx: point API Keys link at the real /dashboard/api-keys
page (the removed route handler is gone).
IAM clientId fixes (real Casdoor apps):
- lux: "lux-app-client-id" -> "lux-cloud".
- zoo: "zoo-app-client-id" -> "zoo-console" (the old value is not a registered
Casdoor client and returns "Invalid client_id", breaking zoo.cloud login).
* web: restore skillsOrg field on BrandConfig (fixes broken export)
The /agents page references brand.skillsOrg at 4 sites, but the field was
dropped from BrandConfig during the consolidate-bootnode merge (it had been
added in 3ef7773). This broke `next build` (output: export) on this branch
AND on main. Restores the field + each brand's GitHub skills org, exactly as
originally introduced.
---------
Co-authored-by: Antje Worring <[email protected]>
Co-authored-by: Hanzo Dev <[email protected]>
These two repos share root commit 8999f3c3 ("Initial commit") but
diverged long ago — hanzoai/bootnode evolved the recent stack
(api-go, brand package, etc.) while bootnode-org/main retained the
mainline 2026 history (175 commits we don't have).
Brand-leak fix: this work belongs in github.com/bootnode/bootnode,
not github.com/hanzoai/bootnode. Per the no-cross-brand-leak policy,
merge both histories together and push the result back to
bootnode/bootnode as the canonical home.
After this lands:
- bootnode/bootnode is the canonical repo
- hanzoai/bootnode gets archived with a redirect notice
- @bootnode-io/brand npm package's `repository.url` already points at
bootnode/bootnode (set in the earlier package.json scaffold)
# Conflicts:
# .github/workflows/ci.yml
# api/bootnode/api/__init__.py
# api/bootnode/api/billing/__init__.py
# api/bootnode/config.py
# api/bootnode/core/billing/__init__.py
# api/bootnode/db/models.py
# api/bootnode/main.py
# api/tests/test_billing.py
# web/app/dashboard/infrastructure/page.tsx
# web/app/dashboard/organization/billing/page.tsx
# web/app/dashboard/organization/page.tsx
# web/app/dashboard/page.tsx
# web/app/layout.tsx
# web/components/navbar.tsx
# web/components/unified-navigation.tsx
# web/lib/brand.ts
# web/public/logo/zoo-icon.svg
# web/public/logo/zoo-logo-white.svg
# web/public/logo/zoo-logo.svg
# web/tsconfig.tsbuildinfo
- Add Explorer product page with branded block explorer deployment, contract
verification, Etherscan-compatible API, and multi-chain support
- Add MPC product page with deep Lux MPC integration: CGGMP21 (ECDSA),
FROST (EdDSA), LSS resharing, 15+ chain support, threshold signing API
- Update landing page with 6-product grid (Node, Data, Wallets, Explorer,
MPC, Rollups) and 8 API cards including Explorer API and MPC Signing
- Update navbar and command menu with Explorer and MPC products
- Add Lux fleet management dashboard, observability, and services pages
- Add AI chat component and unified navigation with org switcher
- Add Kubernetes operator (Rust) for multi-chain node lifecycle management
- Add Lux Helm charts with genesis configs for devnet/testnet/mainnet
- Add docker-release.yml CI/CD pipeline for automated DOKS deployment
- Add monitoring, network policies, web deployments, and ingress updates
- Refactor API: fleet management, billing tracker, observability endpoints
- Update brand config, API client, and infrastructure manifests
Add external link to vm.hanzo.ai across three surfaces:
- Sidebar: "Deploy Nodes" child under Infrastructure with Cloud icon
- Infrastructure page: highlighted card with Visor badge
- Dashboard: quick action replacing Manage Team (still in sidebar)
- New /agents marketing page for AI agent crypto integration
- Added skillsOrg field to BrandConfig for per-brand skills repos
- Added Agents link to navbar (desktop + mobile)
- Server-side brand detection via Host header in layout
- Create /dashboard/organization/billing page with plan comparison
- Wire up disabled "Manage Subscription" button to new billing page
- Fix analytics nav billing link to point to organization/billing
- Shows current plan, usage stats, and upgrade via Commerce checkout
- All 4 tiers displayed: Free, PAYG, Growth, Enterprise
- Fix Lux brand IAM URL: lux.id → iam.lux.network (matches actual deployment)
- Use getBrand().iam.url for IAM URL in HanzoLoginButton (brand-aware auth)
- Fix missing newline at EOF in unified-navigation.tsx
- Update LLM.md with Commerce billing and IAM documentation
- Fix OAuth login to use per-brand IAM endpoints (lux.id, hanzo.id, zoo.id, iam.bootno.de)
- Correct Casdoor client IDs to match init_data.json
- Add NEXT_PUBLIC_IAM_* env var overrides for K8s chart values
- Centralize getApiUrl() and getAuthHeaders() in lib/api.ts
- Replace emoji chain icons with real PNG logos from Lux exchange
- Add developer workbench component to dashboard layout
- Add network monitoring, billing, and infrastructure pages
- Dashboard and navigation use dark-mode-aware CSS vars (bg-background,
bg-sidebar, border-border) instead of hardcoded bg-gray-50/bg-white
- isProductionMode() now recognizes 127.0.0.1 and private IPs as local
so login no longer redirects to lux.id on localhost
- Add /dashboard/infrastructure/monitoring page with node health
summary cards, CPU/memory/disk usage bars, 15s auto-refresh
- Quick login button uses [email protected] / admin credentials
- Update layout.tsx with brand-aware metadata (title, OG, icons)
- Change default brand from bootnode to hanzo in brand.ts
- Update homepage, product pages with brand-aware text
- Replace api.bootnode.dev URLs with api.hanzo.ai
- Update llms.txt route to use brand system
- Update security, privacy pages with Hanzo branding
- Update code-demo, unified-navigation with brand logos
- Update footer status link to status.hanzo.ai
- Add k8s configs for production deployment
- Use shared postgres/datastore in hanzo namespace
- Fix image registry to ghcr.io/hanzoai/bootnode
- Add deploy script with shared infra support
- Simplify compose.yml for local development