* 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]>
Bootnode
Web3 Backend in a Box - Run locally or deploy to cloud.
Go rewrite (HIP-0106) in progress. The current production service is the Python FastAPI app under
api/. A Go scaffold that mounts intosuperbaseper HIP-0106 lives alongside it —api/,cmd/bootnode/,schema/,zap/. Seedocs/PYTHON_TO_GO_PORT.mdfor the endpoint-by-endpoint port map and the new Go README section below.
Quick Start
docker compose up -d
Done. Your Web3 backend is running:
- API: http://localhost:8000
- Dashboard: http://localhost:3001
- API Docs: http://localhost:8000/docs
Features
| API | Description |
|---|---|
POST /v1/rpc/{chain} |
Multi-chain JSON-RPC proxy |
WS /v1/ws/{chain} |
Real-time blockchain subscriptions |
GET /v1/tokens/{chain}/balances/{address} |
Token balances & metadata |
GET /v1/nfts/{chain}/owned/{address} |
NFT ownership & metadata |
POST /v1/webhooks |
Event-driven notifications |
POST /v1/wallets/create |
ERC-4337 smart wallets |
POST /v1/bundler/{chain} |
UserOp bundling |
POST /v1/gas/sponsor |
Gas sponsorship |
Supported Chains
L1: Ethereum, BNB Chain, Avalanche, Solana, Bitcoin
L2: Arbitrum, Optimism, Base, Polygon, zkSync, Scroll, Linea, Blast
Development
# API (Python 3.12+)
cd api && uv sync && uvicorn bootnode.main:app --reload --port 8000
# Dashboard (Node 22+)
cd web && pnpm install && pnpm dev
Deploy
Self-hosted
docker compose -f docker-compose.prod.yml up -d
# or
kubectl apply -f infra/k8s/
Hanzo Cloud
hanzo deploy
Visit web3.hanzo.ai for managed hosting.
License
Apache-2.0
Go rewrite (HIP-0106)
The Go subsystem mounts into superbase (the unified Hanzo Cloud
binary). It exposes a single Mount(r chi.Router, deps api.Deps) error
entry point and a public ZAP schema (schema/bootnode.zap) covering
every cross-subsystem type.
bootnode/
schema/bootnode.zap # public typed surface (ZAP)
zap/gen/ # zapc-generated Go (hand-stubs today)
api/ # subsystem code (chi handlers + store)
mount.go # HIP-0106 contract
deps.go # IAM/KMS/Base/O11y/Commerce interfaces
handlers/ # one MountXxx per FastAPI route group
middleware/ # auth, telemetry, rate-limit
store/ # per-tenant SQLite via deps.Base
web3/ # chain registry + RPC pool
cmd/bootnode/main.go # standalone dev shim
docs/PYTHON_TO_GO_PORT.md # endpoint-by-endpoint mapping
Build
go build ./...
go vet ./...
go run ./cmd/bootnode # listens on :8100 (BOOTNODE_ADDR to override)
Generate ZAP bindings
cd zap && make gen # no-op if zapc isn't installed
zapc lives at ~/work/hanzo/zap/zapc-rs/. Brand policy: no
.capnp files, no "Cap'n Proto" references on the public surface
(HIP-0106).