feat(console): one icon set — every glyph comes from @luxfi/ui/icons

74 files imported `lucide-react` directly, pinned ^1.26.0, while @luxfi/ui —
which this console renders alongside — resolves 1.27. Two Lucide copies from two
resolutions in one bundle is how a set stops being one set. Two more glyphs were
not from any icon library at all: the node list drew its network in/out arrows as
the literal characters "↓" and "↑", and the chain onboarding selector drew its
tick as "✓". Those are font glyphs — they take the text metrics, not the icon
box, so they sit on a different baseline and scale with the font, not `size-*`.

One source now: `@luxfi/ui/icons`, Lucide as @hanzo/gui standardises on it and
@luxfi/ui themes it. `lucide-react` is out of package.json, so per-surface drift
is no longer expressible; @luxfi/ui comes in at 7.4.3, which is where `./icons`
lives. The three text glyphs are ArrowDown / ArrowUp / Check.

All 121 distinct icon names this console uses were checked against the 6014
symbols @luxfi/ui/icons exports before the rewrite — zero missing, with a
negative control. `next build` is clean: 78 routes, Next 16.2.11 + Turbopack.

The d3 chart roots (node-globe, node-map, globe-view, donut-chart, fleet-map)
keep their <svg>: those are plots, not glyphs. The command menu's "↑↓" stays —
it is a keyboard legend inside <kbd>, and it means the keys.

Co-authored-by: Hanzo Dev <[email protected]>
This commit is contained in:
2026-07-27 14:57:55 -07:00
co-authored by Hanzo Dev
parent 67150ebda2
commit da98c0de75
78 changed files with 7587 additions and 97 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ import {
Shield,
Users,
Zap,
} from "lucide-react"
} from "@luxfi/ui/icons"
import { getBrand } from "@/lib/brand"
const brand = getBrand()
+1 -1
View File
@@ -12,7 +12,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"
import { useAuth, ProtectedRoute, OrgBadge } from "@/lib/auth"
import { Activity, Server, Globe, Users, Database, Zap, Shield, Network, MapPin, Plus, Settings, Trash2, Eye, BarChart3 } from "lucide-react"
import { Activity, Server, Globe, Users, Database, Zap, Shield, Network, MapPin, Plus, Settings, Trash2, Eye, BarChart3 } from "@luxfi/ui/icons"
import { getBrand } from "@/lib/brand"
// Donut Chart Component (Modern replacement for D3 donut)
+1 -1
View File
@@ -16,7 +16,7 @@ import {
Terminal,
Webhook,
Zap,
} from "lucide-react"
} from "@luxfi/ui/icons"
import { getBrand } from "@/lib/brand"
export const metadata: Metadata = {
+1 -1
View File
@@ -11,7 +11,7 @@ import {
BookOpen,
Calendar,
Clock,
} from "lucide-react"
} from "@luxfi/ui/icons"
import { getBrand } from "@/lib/brand"
export default function BlogPage() {
+1 -1
View File
@@ -13,7 +13,7 @@ import {
MapPin,
Rocket,
Zap,
} from "lucide-react"
} from "@luxfi/ui/icons"
import { getBrand } from "@/lib/brand"
const brand = getBrand()
+1 -1
View File
@@ -16,7 +16,7 @@ import {
Globe,
Network,
Zap,
} from "lucide-react"
} from "@luxfi/ui/icons"
const CHAIN_EXPLORERS: Record<string, string> = {
ethereum: "https://etherscan.io",
+1 -1
View File
@@ -19,7 +19,7 @@ import {
Globe,
Search,
Zap,
} from "lucide-react"
} from "@luxfi/ui/icons"
const CATEGORY_ORDER: ChainCategory[] = [
"ethereum-l1",
+1 -1
View File
@@ -14,7 +14,7 @@ import {
Mail,
MessageSquare,
Send,
} from "lucide-react"
} from "@luxfi/ui/icons"
import { getBrand } from "@/lib/brand"
const brand = getBrand()
+1 -1
View File
@@ -19,7 +19,7 @@ import {
RefreshCcw,
TrendingUp,
Globe
} from "lucide-react"
} from "@luxfi/ui/icons"
interface AnalyticsData {
totalRequests: number
+1 -1
View File
@@ -13,7 +13,7 @@ import {
Check,
X,
Loader2,
} from "lucide-react"
} from "@luxfi/ui/icons"
import { useApiKeys, useCreateApiKey, useDeleteApiKey } from "@/lib/hooks"
function getProjectId(): string {
+1 -1
View File
@@ -6,7 +6,7 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/com
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import { Input } from "@/components/ui/input"
import { Image, Search, ExternalLink, Loader2 } from "lucide-react"
import { Image, Search, ExternalLink, Loader2 } from "@luxfi/ui/icons"
interface NFT {
contract: string
+1 -1
View File
@@ -3,7 +3,7 @@
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import { Coins, Image, Wallet } from "lucide-react"
import { Coins, Image, Wallet } from "@luxfi/ui/icons"
import Link from "next/link"
export default function AssetsPage() {
+1 -1
View File
@@ -6,7 +6,7 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/com
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Badge } from "@/components/ui/badge"
import { Coins, Search, Loader2 } from "lucide-react"
import { Coins, Search, Loader2 } from "@luxfi/ui/icons"
interface TokenMetadata {
contract_address: string
+1 -1
View File
@@ -14,7 +14,7 @@ import {
DollarSign,
Zap,
Settings,
} from "lucide-react"
} from "@luxfi/ui/icons"
import { useGasPolicies, useCreateGasPolicy, useDeleteGasPolicy, useGasPrices } from "@/lib/hooks"
export default function GasPoliciesPage() {
@@ -6,7 +6,7 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/com
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import { Input } from "@/components/ui/input"
import { Box, Plus, Loader2, X, Settings, Download, Scale } from "lucide-react"
import { Box, Plus, Loader2, X, Settings, Download, Scale } from "@luxfi/ui/icons"
interface Cluster {
id: string
@@ -7,7 +7,7 @@ import { DOKS_REGIONS, type LuxFleet } from "@/components/lux/region-data"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Globe, Plus, RefreshCw, Zap } from "lucide-react"
import { Globe, Plus, RefreshCw, Zap } from "@luxfi/ui/icons"
/** Convert LuxFleet[] to FleetRegion[] for the map component */
function fleetsToRegions(fleets: LuxFleet[]): FleetRegion[] {
@@ -39,7 +39,7 @@ import {
ChevronRight,
Circle,
AlertTriangle,
} from "lucide-react"
} from "@luxfi/ui/icons"
// ---------------------------------------------------------------------------
// Types
@@ -4,7 +4,7 @@ import { getApiUrl } from "@/lib/api"
import { useState, useEffect } from "react"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import { Activity, Cpu, HardDrive, MemoryStick, Wifi, WifiOff, Loader2 } from "lucide-react"
import { Activity, Cpu, HardDrive, MemoryStick, Wifi, WifiOff, Loader2 } from "@luxfi/ui/icons"
interface NodeHealth {
id: string
@@ -12,7 +12,7 @@ import {
TableHeader,
TableRow,
} from "@/components/ui/table"
import { Globe, Loader2, RefreshCcw, ExternalLink, Activity, Zap, CheckCircle, AlertTriangle, XCircle, AlertCircle } from "lucide-react"
import { Globe, Loader2, RefreshCcw, ExternalLink, Activity, Zap, CheckCircle, AlertTriangle, XCircle, AlertCircle } from "@luxfi/ui/icons"
import Link from "next/link"
import { getApiUrl, getAuthHeaders, load, loadError } from "@/lib/api"
@@ -10,7 +10,7 @@ import { Input } from "@/components/ui/input"
import {
Server, ArrowLeft, Play, Square, Trash2, RefreshCcw, Copy, Check,
Activity, HardDrive, Cpu, MemoryStick, Network, Loader2, Terminal
} from "lucide-react"
} from "@luxfi/ui/icons"
interface NodeDetails {
id: string
@@ -7,7 +7,7 @@ import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import { Input } from "@/components/ui/input"
import { Select } from "@/components/ui/select"
import { Server, Plus, ExternalLink, Loader2, X, Play, Square, Trash2, RefreshCcw, Activity, AlertTriangle, ChevronRight } from "lucide-react"
import { Server, Plus, ExternalLink, Loader2, X, Play, Square, Trash2, RefreshCcw, Activity, AlertTriangle, ChevronRight, ArrowDown, ArrowUp } from "@luxfi/ui/icons"
import Link from "next/link"
import { getBrand } from "@/lib/brand"
@@ -940,8 +940,8 @@ export default function NodesPage() {
{node.metrics?.network_rx !== undefined && (
<div className="text-right hidden xl:block">
<p className="text-sm font-medium">
<span className="text-green-500">↓</span>{node.metrics.network_rx.toFixed(0)}
<span className="text-blue-500 ml-1">↑</span>{node.metrics.network_tx?.toFixed(0) || 0} MB
<ArrowDown className="inline size-3.5 text-green-500" aria-label="in" />{node.metrics.network_rx.toFixed(0)}
<ArrowUp className="ml-1 inline size-3.5 text-blue-500" aria-label="out" />{node.metrics.network_tx?.toFixed(0) || 0} MB
</p>
<p className="text-xs text-muted-foreground">Network</p>
</div>
@@ -16,7 +16,7 @@ import {
ArrowUpRight,
ArrowDownRight,
Minus,
} from "lucide-react"
} from "@luxfi/ui/icons"
interface HealthOverview {
total_services: number
@@ -5,7 +5,7 @@ import { useState, useEffect } from "react"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import { Server, Box, HardDrive, Copy, Loader2, Shield } from "lucide-react"
import { Server, Box, HardDrive, Copy, Loader2, Shield } from "@luxfi/ui/icons"
import Link from "next/link"
interface InfraStats {
@@ -24,7 +24,7 @@ import {
CheckCircle2,
XCircle,
Minus,
} from "lucide-react"
} from "@luxfi/ui/icons"
interface ServiceInfo {
name: string
@@ -6,7 +6,7 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/com
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import { Input } from "@/components/ui/input"
import { Copy, Loader2, X, HardDrive, Camera, CheckCircle, Clock, AlertCircle } from "lucide-react"
import { Copy, Loader2, X, HardDrive, Camera, CheckCircle, Clock, AlertCircle } from "@luxfi/ui/icons"
interface Volume {
id: string
@@ -6,7 +6,7 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/com
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import { Input } from "@/components/ui/input"
import { HardDrive, Plus, Loader2, X, Camera, Link2, Unlink, ArrowUpRight } from "lucide-react"
import { HardDrive, Plus, Loader2, X, Camera, Link2, Unlink, ArrowUpRight } from "@luxfi/ui/icons"
interface Volume {
id: string
+1 -1
View File
@@ -9,7 +9,7 @@ import { Input } from "@/components/ui/input"
import {
TrendingUp, TrendingDown, Server, Coins, Search, ArrowUpRight,
Loader2, Filter, ChevronRight, Zap, Shield, Globe, Star, Lock
} from "lucide-react"
} from "@luxfi/ui/icons"
import Link from "next/link"
interface StakingData {
+1 -1
View File
@@ -24,7 +24,7 @@ import {
Wifi,
XCircle,
Zap,
} from "lucide-react"
} from "@luxfi/ui/icons"
import { getApiUrl, getAuthHeaders } from "@/lib/api"
interface HealthCheck {
@@ -12,7 +12,7 @@ import {
Loader2,
ArrowUpRight,
AlertCircle,
} from "lucide-react"
} from "@luxfi/ui/icons"
interface Tier {
name: string
+1 -1
View File
@@ -5,7 +5,7 @@ import { useEffect, useState } from "react"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import { Building, Users, Settings, Key, Loader2, CreditCard, AlertCircle } from "lucide-react"
import { Building, Users, Settings, Key, Loader2, CreditCard, AlertCircle } from "@luxfi/ui/icons"
import Link from "next/link"
import { useAuth } from "@/lib/auth"
@@ -6,7 +6,7 @@ import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Badge } from "@/components/ui/badge"
import { Switch } from "@/components/ui/switch"
import { Building, Globe, Bell, Shield, Loader2, CheckCircle2, AlertCircle } from "lucide-react"
import { Building, Globe, Bell, Shield, Loader2, CheckCircle2, AlertCircle } from "@luxfi/ui/icons"
import { useAuth } from "@/lib/auth"
interface OrgSettings {
@@ -13,7 +13,7 @@ import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/u
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { useAuth } from "@/lib/auth"
import { team as teamApi, TeamMember } from "@/lib/api"
import { Users, UserPlus, Mail, Shield, Settings, Trash2, Loader2 } from "lucide-react"
import { Users, UserPlus, Mail, Shield, Settings, Trash2, Loader2 } from "@luxfi/ui/icons"
export default function TeamPage() {
const { user } = useAuth()
+1 -1
View File
@@ -18,7 +18,7 @@ import {
Building,
Loader2,
AlertCircle
} from "lucide-react"
} from "@luxfi/ui/icons"
interface DashboardStats {
api_requests: number
+1 -1
View File
@@ -18,7 +18,7 @@ import {
EyeOff,
LogOut,
User,
} from "lucide-react"
} from "@luxfi/ui/icons"
import { useAuth, OrgBadge } from "@/lib/auth"
import { getApiUrl } from "@/lib/api"
+1 -1
View File
@@ -9,7 +9,7 @@ import { Input } from "@/components/ui/input"
import {
Wallet, Key, Shield, Server, Coins, Lock, Unlock, ExternalLink,
Loader2, ChevronRight, Zap, AlertTriangle, Check, Copy, RefreshCcw
} from "lucide-react"
} from "@luxfi/ui/icons"
import Link from "next/link"
interface Validator {
+1 -1
View File
@@ -8,7 +8,7 @@ import {
Globe,
Database,
Server,
} from "lucide-react"
} from "@luxfi/ui/icons"
import { useChains } from "@/lib/hooks"
import { getBrand } from "@/lib/brand"
+1 -1
View File
@@ -16,7 +16,7 @@ import {
Shield,
Key,
Users,
} from "lucide-react"
} from "@luxfi/ui/icons"
import { useWallets, useCreateWallet } from "@/lib/hooks"
import { getBrand } from "@/lib/brand"
+1 -1
View File
@@ -18,7 +18,7 @@ import {
Send,
ChevronDown,
ChevronUp,
} from "lucide-react"
} from "@luxfi/ui/icons"
import {
useWebhooks,
useCreateWebhook,
+1 -1
View File
@@ -2,7 +2,7 @@ import Link from "next/link"
import { Badge } from "@/components/ui/badge"
import { Card, CardContent } from "@/components/ui/card"
import { DocsLayout } from "@/components/docs-layout"
import { ArrowRight } from "lucide-react"
import { ArrowRight } from "@luxfi/ui/icons"
import { docsConfig } from "@/lib/docs-config"
export const metadata = {
+1 -1
View File
@@ -2,7 +2,7 @@ import Link from "next/link"
import { Badge } from "@/components/ui/badge"
import { Card, CardContent } from "@/components/ui/card"
import { DocsLayout } from "@/components/docs-layout"
import { ArrowRight } from "lucide-react"
import { ArrowRight } from "@luxfi/ui/icons"
import { docsConfig } from "@/lib/docs-config"
export const metadata = {
+1 -1
View File
@@ -2,7 +2,7 @@ import Link from "next/link"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import { DocsLayout } from "@/components/docs-layout"
import { ArrowRight } from "lucide-react"
import { ArrowRight } from "@luxfi/ui/icons"
import { docsConfig } from "@/lib/docs-config"
export const metadata = {
+1 -1
View File
@@ -14,7 +14,7 @@ import {
Terminal,
FileCode,
ArrowRight,
} from "lucide-react"
} from "@luxfi/ui/icons"
import { docsConfig } from "@/lib/docs-config"
const sections = [
+1 -1
View File
@@ -2,7 +2,7 @@ import Link from "next/link"
import { Badge } from "@/components/ui/badge"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { DocsLayout } from "@/components/docs-layout"
import { ArrowRight } from "lucide-react"
import { ArrowRight } from "@luxfi/ui/icons"
import { docsConfig } from "@/lib/docs-config"
export const metadata = {
+1 -1
View File
@@ -2,7 +2,7 @@ import Link from "next/link"
import { Badge } from "@/components/ui/badge"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { DocsLayout } from "@/components/docs-layout"
import { ArrowRight } from "lucide-react"
import { ArrowRight } from "@luxfi/ui/icons"
import { docsConfig } from "@/lib/docs-config"
export const metadata = {
+1 -1
View File
@@ -2,7 +2,7 @@ import Link from "next/link"
import { Badge } from "@/components/ui/badge"
import { Card, CardContent } from "@/components/ui/card"
import { DocsLayout } from "@/components/docs-layout"
import { ArrowRight } from "lucide-react"
import { ArrowRight } from "@luxfi/ui/icons"
import { docsConfig } from "@/lib/docs-config"
export const metadata = {
@@ -2,7 +2,7 @@ import Link from "next/link"
import { Badge } from "@/components/ui/badge"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { DocsLayout } from "@/components/docs-layout"
import { ArrowRight } from "lucide-react"
import { ArrowRight } from "@luxfi/ui/icons"
import { docsConfig } from "@/lib/docs-config"
export const metadata = {
@@ -2,7 +2,7 @@ import Link from "next/link"
import { Badge } from "@/components/ui/badge"
import { Card, CardContent } from "@/components/ui/card"
import { DocsLayout } from "@/components/docs-layout"
import { ArrowRight } from "lucide-react"
import { ArrowRight } from "@luxfi/ui/icons"
import { docsConfig } from "@/lib/docs-config"
export const metadata = {
+1 -1
View File
@@ -2,7 +2,7 @@ import Link from "next/link"
import { Badge } from "@/components/ui/badge"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { DocsLayout } from "@/components/docs-layout"
import { ArrowRight } from "lucide-react"
import { ArrowRight } from "@luxfi/ui/icons"
import { docsConfig } from "@/lib/docs-config"
export const metadata = {
+1 -1
View File
@@ -21,7 +21,7 @@ import {
Wallet,
Webhook,
Zap,
} from "lucide-react"
} from "@luxfi/ui/icons"
export default function HomePage() {
const brand = getBrand()
+1 -1
View File
@@ -20,7 +20,7 @@ import {
HelpCircle,
Minus,
Zap,
} from "lucide-react"
} from "@luxfi/ui/icons"
import { getBrand } from "@/lib/brand"
export const metadata: Metadata = {
+1 -1
View File
@@ -3,7 +3,7 @@ import type { Metadata } from "next"
import { Navbar } from "@/components/navbar"
import { Footer } from "@/components/footer"
import { Badge } from "@/components/ui/badge"
import { Shield } from "lucide-react"
import { Shield } from "@luxfi/ui/icons"
import { getBrand } from "@/lib/brand"
const brand = getBrand()
+1 -1
View File
@@ -19,7 +19,7 @@ import {
Layers,
Search,
Zap,
} from "lucide-react"
} from "@luxfi/ui/icons"
import { getBrand } from "@/lib/brand"
import { docsConfig } from "@/lib/docs-config"
+1 -1
View File
@@ -20,7 +20,7 @@ import {
BarChart3,
Braces,
Palette,
} from "lucide-react"
} from "@luxfi/ui/icons"
import { getBrand } from "@/lib/brand"
export default function ExplorerProductPage() {
+1 -1
View File
@@ -20,7 +20,7 @@ import {
Users,
Wallet,
Zap,
} from "lucide-react"
} from "@luxfi/ui/icons"
import { getBrand } from "@/lib/brand"
export default function MPCProductPage() {
+1 -1
View File
@@ -18,7 +18,7 @@ import {
Shield,
Wifi,
Zap,
} from "lucide-react"
} from "@luxfi/ui/icons"
import { getBrand } from "@/lib/brand"
import { docsConfig } from "@/lib/docs-config"
+1 -1
View File
@@ -21,7 +21,7 @@ import {
Settings,
Wrench,
Zap,
} from "lucide-react"
} from "@luxfi/ui/icons"
import { getBrand } from "@/lib/brand"
import { docsConfig } from "@/lib/docs-config"
+1 -1
View File
@@ -19,7 +19,7 @@ import {
Users,
Wallet,
Zap,
} from "lucide-react"
} from "@luxfi/ui/icons"
import { getBrand } from "@/lib/brand"
import { getSdkPackage } from "@/lib/sdk-package"
import { docsConfig } from "@/lib/docs-config"
+1 -1
View File
@@ -21,7 +21,7 @@ import {
TestTube,
Webhook,
Zap,
} from "lucide-react"
} from "@luxfi/ui/icons"
import { getBrand } from "@/lib/brand"
import { docsConfig } from "@/lib/docs-config"
+55 -3
View File
@@ -1,7 +1,50 @@
"use client"
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
import { useState } from "react"
import { AppProvider, IdentityProvider } from "@luxfi/ui"
import { QueryClient } from "@tanstack/react-query"
import { useEffect, useState } from "react"
import { setReturnUrl } from "@/lib/iam"
// Brand + identity, both from the HOST.
//
// `AppProvider` (@luxfi/ui) mounts the @hanzo/gui engine on the host-resolved
// theme row and carries the white-label — the same resolver lib/brand.ts now
// reads its OIDC triple from, so there is one answer to "which brand is this"
// and not two that can disagree.
//
// `IdentityProvider` reads the signed-in account and its org membership from
// IAM. Credentials stay where they already are: lib/iam owns the PKCE flow and
// localStorage["bootnode_token"] the bearer, so the chrome adds no second token
// store and no second refresh timer — it borrows the bearer and two verbs.
const TOKEN_KEY = "bootnode_token"
const readToken = (): string | null => {
if (typeof window === "undefined") return null
try {
return window.localStorage.getItem(TOKEN_KEY)
} catch {
return null
}
}
/** Sign-in goes through /login, which is what drives the SDK's PKCE redirect. */
const signIn = (): void => {
setReturnUrl(window.location.pathname + window.location.search)
window.location.assign("/login")
}
/** Sign-out drops the bearer and returns to the marketing root. */
const signOut = (): void => {
try {
window.localStorage.removeItem(TOKEN_KEY)
window.localStorage.removeItem("bootnode_project_id")
} catch {
/* storage disabled — the redirect below still ends the session in this tab */
}
window.location.assign("/")
}
export function Providers({ children }: { children: React.ReactNode }) {
const [queryClient] = useState(
@@ -15,8 +58,17 @@ export function Providers({ children }: { children: React.ReactNode }) {
},
})
)
// `output: "export"` prerenders with no Host header, so the first paint is
// the default row and the real host arrives after hydration — deterministic
// on both sides, so there is no mismatch.
const [host, setHost] = useState<string | undefined>(undefined)
useEffect(() => setHost(window.location.host), [])
return (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
<AppProvider host={host} queryClient={queryClient}>
<IdentityProvider auth={{ token: readToken, signIn, signOut }}>
{children}
</IdentityProvider>
</AppProvider>
)
}
+1 -1
View File
@@ -13,7 +13,7 @@ import {
Network,
Shield,
ShieldCheck,
} from "lucide-react"
} from "@luxfi/ui/icons"
import { getBrand } from "@/lib/brand"
const brand = getBrand()
+1 -1
View File
@@ -3,7 +3,7 @@ import type { Metadata } from "next"
import { Navbar } from "@/components/navbar"
import { Footer } from "@/components/footer"
import { Badge } from "@/components/ui/badge"
import { FileText } from "lucide-react"
import { FileText } from "@luxfi/ui/icons"
import { getBrand } from "@/lib/brand"
const brand = getBrand()
+1 -1
View File
@@ -14,7 +14,7 @@ import {
Activity,
Zap,
RotateCw,
} from "lucide-react"
} from "@luxfi/ui/icons"
import { useBrand } from "@/components/brand-logo"
import { getBrandKey } from "@/lib/brand"
@@ -1,6 +1,7 @@
"use client"
import { useMemo, useState } from "react"
import { Check } from "@luxfi/ui/icons"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
@@ -100,7 +101,7 @@ export function ChainOnboardingSelector({
active ? "border-blue-600 bg-blue-600 text-white" : "border-zinc-300"
}`}
>
{active ? "✓" : ""}
{active ? <Check className="size-3" /> : null}
</span>
<span className="inline-flex h-6 w-6 items-center justify-center rounded-full bg-zinc-100 text-sm overflow-hidden">
{item.icon.startsWith("/") ? (
+1 -1
View File
@@ -4,7 +4,7 @@ import { useState } from "react"
import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import { Check, Copy, Play } from "lucide-react"
import { Check, Copy, Play } from "@luxfi/ui/icons"
import { getBrand } from "@/lib/brand"
const CHAINS = ["Ethereum", "Solana", "Base", "Arbitrum", "Polygon"]
+1 -1
View File
@@ -27,7 +27,7 @@ import {
Sparkles,
ArrowUpRight,
Terminal,
} from "lucide-react"
} from "@luxfi/ui/icons"
import { useBrand } from "@/components/brand-logo"
import { AiChat } from "@/components/ai-chat"
@@ -2,7 +2,7 @@
import { useMemo, useState } from "react"
import { useRouter } from "next/navigation"
import { ArrowRight, Search } from "lucide-react"
import { ArrowRight, Search } from "@luxfi/ui/icons"
import {
Dialog,
+1 -1
View File
@@ -20,7 +20,7 @@ import {
Terminal,
X,
XCircle,
} from "lucide-react"
} from "@luxfi/ui/icons"
import { getApiUrl, getAuthHeaders as getAuth } from "@/lib/api"
// ─── Types ─────────────────────────────────────────────
+1 -1
View File
@@ -13,7 +13,7 @@ import {
Package,
FileCode,
Clock,
} from "lucide-react"
} from "@luxfi/ui/icons"
const sidebarNav = [
{ title: "Documentation", href: "/docs", icon: Book },
+1 -1
View File
@@ -2,7 +2,7 @@
import Link from "next/link"
import { BrandLogo, useBrand } from "@/components/brand-logo"
import { ExternalLink } from "lucide-react"
import { ExternalLink } from "@luxfi/ui/icons"
// Footer, in lux.cloud's chrome: no tinted slab, just a hairline rule over the
// page ground with 13px muted type. The four sitemap columns stay — dropping
+1 -1
View File
@@ -26,7 +26,7 @@ import {
RefreshCcw,
Server,
Users,
} from "lucide-react"
} from "@luxfi/ui/icons"
import { FleetMap, type FleetRegion } from "@/components/lux/fleet-map"
import {
CHAIN_LABEL,
+1 -1
View File
@@ -2,7 +2,7 @@
import { useEffect, useState } from "react"
import Link from "next/link"
import { ArrowRight, Circle } from "lucide-react"
import { ArrowRight, Circle } from "@luxfi/ui/icons"
import {
NETWORK_LABEL,
fetchFleetOverview,
+1 -1
View File
@@ -1,7 +1,7 @@
"use client"
import { useState, useEffect, useRef, ReactNode } from "react"
import { ChevronDown } from "lucide-react"
import { ChevronDown } from "@luxfi/ui/icons"
import { useMediaQuery } from "@/hooks/use-media-query"
import { cn } from "@/lib/utils"
+1 -1
View File
@@ -2,7 +2,7 @@
import * as React from "react"
import * as DialogPrimitive from "@radix-ui/react-dialog"
import { X } from "lucide-react"
import { X } from "@luxfi/ui/icons"
import { cn } from "@/lib/utils"
+1 -1
View File
@@ -2,7 +2,7 @@
import * as React from "react"
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
import { Check, ChevronRight, Circle } from "lucide-react"
import { Check, ChevronRight, Circle } from "@luxfi/ui/icons"
import { cn } from "@/lib/utils"
+1 -1
View File
@@ -3,7 +3,7 @@
import * as React from "react"
import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu"
import { cva } from "class-variance-authority"
import { ChevronDown } from "lucide-react"
import { ChevronDown } from "@luxfi/ui/icons"
import { cn } from "@/lib/utils"
const NavigationMenu = React.forwardRef<
+4 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@bootnode/web",
"version": "2.0.0",
"version": "2.0.1",
"packageManager": "[email protected]",
"private": true,
"type": "module",
@@ -13,8 +13,10 @@
"test": "node --test --experimental-strip-types \"lib/**/*.test.ts\""
},
"dependencies": {
"@hanzo/gui": "^7.3.0",
"@hanzo/iam": "^0.13.8",
"@luxfi/logo": "^1.0.7",
"@luxfi/ui": "7.4.3",
"@radix-ui/react-accordion": "^1.2.20",
"@radix-ui/react-alert-dialog": "^1.1.23",
"@radix-ui/react-avatar": "^1.2.6",
@@ -43,12 +45,12 @@
"d3": "^7.9.0",
"date-fns": "^4.4.0",
"geist": "^1.7.2",
"lucide-react": "^1.26.0",
"next": "^16.2.11",
"next-themes": "^0.4.6",
"nuqs": "^2.9.2",
"react": "^19.2.8",
"react-dom": "^19.2.8",
"react-native-web": "^0.21.0",
"recharts": "^3.10.1",
"sonner": "^2.0.7",
"tailwind-merge": "^3.6.0",
+7449 -16
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -13,3 +13,5 @@
# must be allowed to run its install script.
allowBuilds:
sharp: true
minimumReleaseAgeExclude:
- '@luxfi/[email protected] || 7.4.3'