Files
universe/k8s/lux-mainnet/WHITE-LABEL-API.md
T

4.7 KiB
Raw Blame History

White-Label API Gateway (api-gateway-gateway)

The Lux ecosystem's Gateway at lux-mainnet/api-gateway-gateway:80 is a shared multi-tenant backend. Any white-label app — Zoo, Hanzo, Pars, or third-party — points its api.<their-domain> at the gateway and gets:

  • All Lux-ecosystem chain RPCs (/v1/chain/{C,X,P,zoo,hanzo,spc,pars,Q,Z,T,A,D}/rpc)
  • Indexer endpoints (/api/indexer/indexer-{c,zoo,hanzo,spc,pars})
  • Health, info, and admin endpoints (/v1/health, /v1/info)
  • DAG chain stats (/api/v2/dag/{q,z,t,a}chain/{health,stats})
  • DEX precompile / gateway routes
  • TLS via cert-manager letsencrypt
  • CORS already wide-open (Access-Control-Allow-Origin: *)

Zero per-tenant config needed in the gateway itself.

Onboarding a new white-label app

  1. Pick a hostname: api.<your-app>.<tld> (e.g. api.zoo.exchange, api.hanzo.network, api.pars.market).

  2. Create an Ingress in lux-mainnet ns:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: api-<your-app>
      namespace: lux-mainnet
      annotations:
        cert-manager.io/cluster-issuer: letsencrypt
    spec:
      ingressClassName: ingress
      tls:
      - hosts: [api.<your-app>.<tld>]
        secretName: api-<your-app>-tls
      rules:
      - host: api.<your-app>.<tld>
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: api-gateway-gateway
                port: { number: 80 }
    
  3. Add DNS: A record for api.<your-app>.<tld> → 134.199.138.27 (hanzo-ingress LB on do-sfo3-lux-k8s). Cloudflare-proxied is fine.

  4. Verify:

    curl -X POST -H 'Content-Type: application/json' \
      --data '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' \
      https://api.<your-app>.<tld>/v1/chain/zoo/rpc
    # → {"jsonrpc":"2.0","id":1,"result":"0x30e08"}
    
  5. Point your SPA at the new hostname. With hanzoai/spa runtime, set the env vars:

    - { name: SPA_RPC_HOST,   value: https://api.<your-app>.<tld>/v1/chain/<chain>/rpc }
    - { name: SPA_API_HOST,   value: https://api.<your-app>.<tld> }
    - { name: SPA_GATEWAY_HOST, value: https://api.<your-app>.<tld> }
    

    These get templated into /config.json at pod start; the SPA reads them on boot and uses them for every backend call.

Live deployments

host namespace ingress
api.lux.network lux-mainnet (legacy direct DNS)
api.zoo.exchange lux-mainnet api-zoo-exchange
api.hanzo.network (reserve) (create when needed)
api.pars.market (reserve) (create when needed)
api.liquid.exchange (reserve) (create when needed)

All point to the same api-gateway-gateway service; each just gets its own TLS cert and DNS record.

Endpoints exposed

# Chain RPCs (40+ endpoints across 12 chains × 3 envs each)
POST /v1/chain/C/rpc         # Lux C-Chain (96369)
POST /v1/chain/zoo/rpc       # Zoo (200200)
POST /v1/chain/hanzo/rpc     # Hanzo (36963)
POST /v1/chain/pars/rpc      # Pars (494949)
POST /v1/chain/spc/rpc       # SPC (36911)
POST /v1/chain/{Q,Z,T,A,D}/rpc  # primary network chains
POST /v1/chain/{X,P}         # X-Chain, P-Chain
GET  /v1/info
GET  /v1/health{,/liveness}

# Indexer (block/tx data per chain)
GET  /api/indexer/indexer-{c,zoo,hanzo,spc,pars}/...

# DAG / consensus stats
GET  /api/v2/dag/{q,z,t,a}chain/{health,stats}
GET  /api/chains

Add a new endpoint by editing lux-mainnet/api-gateway-gateway-config ConfigMap (gateway.json endpoints[]) and rolling the deployment.

CORS

Wide-open by default — any browser Origin is allowed:

"security/cors": {
  "allow_origins":     ["*"],
  "allow_methods":     ["GET","POST","OPTIONS"],
  "allow_headers":     ["Content-Type","Authorization"],
  "expose_headers":    ["Content-Length"],
  "max_age":           "12h"
}

To tighten to a specific allow-list, replace ["*"] with the explicit origin list and roll api-gateway-gateway deployment in lux-mainnet.

Backend topology

Browser (zoo.exchange / hanzo.exchange / pars.market / ...)
   │
   │  https://api.<app>.<tld>/v1/chain/zoo/rpc
   ▼
Cloudflare (TLS termination + caching)
   │
   ▼
hanzo-ingress LB  (lux-system, 134.199.138.27)
   │  routes by Host header → matching K8s Ingress
   ▼
api-gateway-gateway  (lux-mainnet, Gateway :80)
   │  matches /v1/chain/<alias>/rpc → looks up backend host
   ▼
luxd-headless.lux-mainnet.svc.cluster.local:9630
   │  StatefulSet: 5 luxd validators on Lux Mainnet
   ▼
EVM plugin (per chain) → on-disk badgerdb state

The SPA never needs to know any of this — it just calls https://api.<their-domain>/v1/chain/<chain>/rpc and Gateway does the rest.