From 3b2e7027db17b92ece8c3f2944f6872af54d44c8 Mon Sep 17 00:00:00 2001 From: tinklefund Date: Mon, 25 May 2026 01:25:23 +0800 Subject: [PATCH] feat(web): refresh Hyperliquid-focused product UI - Update landing, chart, settings, and data page copy for stock trading - Adjust branding and translations around Hyperliquid positioning - Extend frontend config types for the updated exchange settings --- web/src/components/charts/ChartTabs.tsx | 31 ++++---- web/src/components/common/HeaderBar.tsx | 2 + .../components/landing/CommunitySection.tsx | 2 +- web/src/components/landing/core/AgentGrid.tsx | 21 +++--- web/src/components/landing/core/LiveFeed.tsx | 32 ++++---- .../components/landing/core/TerminalHero.tsx | 55 ++++++++------ web/src/constants/branding.ts | 4 +- web/src/i18n/translations.ts | 12 +-- web/src/pages/DataPage.tsx | 3 +- web/src/pages/SettingsPage.tsx | 74 ++++++++++++++++--- web/src/types/config.ts | 3 + 11 files changed, 156 insertions(+), 83 deletions(-) diff --git a/web/src/components/charts/ChartTabs.tsx b/web/src/components/charts/ChartTabs.tsx index d77e8c13..eccced24 100644 --- a/web/src/components/charts/ChartTabs.tsx +++ b/web/src/components/charts/ChartTabs.tsx @@ -20,13 +20,14 @@ type MarketType = 'hyperliquid' | 'crypto' | 'stocks' | 'forex' | 'metals' interface SymbolInfo { symbol: string + display?: string name: string category: string } // Market type configuration const MARKET_CONFIG = { - hyperliquid: { exchange: 'hyperliquid', defaultSymbol: 'BTC', icon: '🔷', labelKey: 'hyperliquid' as const, color: 'cyan', hasDropdown: true }, + hyperliquid: { exchange: 'hyperliquid-xyz', defaultSymbol: 'BTC', icon: '🔷', labelKey: 'hyperliquid' as const, color: 'cyan', hasDropdown: true }, crypto: { exchange: 'binance', defaultSymbol: 'BTCUSDT', icon: '₿', labelKey: 'crypto' as const, color: 'yellow', hasDropdown: false }, stocks: { exchange: 'alpaca', defaultSymbol: 'AAPL', icon: '📈', labelKey: 'stocks' as const, color: 'green', hasDropdown: false }, forex: { exchange: 'forex', defaultSymbol: 'EUR/USD', icon: '💱', labelKey: 'forex' as const, color: 'blue', hasDropdown: false }, @@ -63,6 +64,7 @@ export function ChartTabs({ traderId, selectedSymbol, updateKey, exchangeId }: C const [showDropdown, setShowDropdown] = useState(false) const [searchFilter, setSearchFilter] = useState('') const dropdownRef = useRef(null) + const chartSymbolDisplay = availableSymbols.find(s => s.symbol === chartSymbol)?.display || chartSymbol // Auto-switch market type when exchange ID changes useEffect(() => { @@ -82,13 +84,13 @@ export function ChartTabs({ traderId, selectedSymbol, updateKey, exchangeId }: C .then(res => res.json()) .then(data => { if (data.symbols) { - // Sort by category: crypto > stock > forex > commodity > index - const categoryOrder: Record = { crypto: 0, stock: 1, forex: 2, commodity: 3, index: 4 } + // Product order for Hyperliquid XYZ board: stocks → commodities → indices → FX → pre-IPO → crypto + const categoryOrder: Record = { stock: 0, commodity: 1, index: 2, forex: 3, pre_ipo: 4, crypto: 5 } const sorted = [...data.symbols].sort((a: SymbolInfo, b: SymbolInfo) => { - const orderA = categoryOrder[a.category] ?? 5 - const orderB = categoryOrder[b.category] ?? 5 + const orderA = categoryOrder[a.category] ?? 99 + const orderB = categoryOrder[b.category] ?? 99 if (orderA !== orderB) return orderA - orderB - return a.symbol.localeCompare(b.symbol) + return (a.display || a.symbol).localeCompare(b.display || b.symbol) }) setAvailableSymbols(sorted) } @@ -116,9 +118,12 @@ export function ChartTabs({ traderId, selectedSymbol, updateKey, exchangeId }: C } // Filtered symbol list - const filteredSymbols = availableSymbols.filter(s => - s.symbol.toLowerCase().includes(searchFilter.toLowerCase()) - ) + const filteredSymbols = availableSymbols.filter(s => { + const q = searchFilter.toLowerCase() + return s.symbol.toLowerCase().includes(q) + || (s.display || '').toLowerCase().includes(q) + || s.name.toLowerCase().includes(q) + }) // Auto-switch to kline chart when symbol selected externally useEffect(() => { @@ -215,7 +220,7 @@ export function ChartTabs({ traderId, selectedSymbol, updateKey, exchangeId }: C onClick={() => setShowDropdown(!showDropdown)} className="flex items-center gap-1.5 px-2.5 py-1 bg-black/40 border border-white/10 rounded text-[11px] font-bold text-nofx-text-main hover:border-nofx-gold/30 hover:text-nofx-gold transition-all" > - {chartSymbol} + {chartSymbolDisplay} {showDropdown && ( @@ -234,10 +239,10 @@ export function ChartTabs({ traderId, selectedSymbol, updateKey, exchangeId }: C
- {['crypto', 'stock', 'forex', 'commodity', 'index'].map(category => { + {['stock', 'commodity', 'index', 'forex', 'pre_ipo', 'crypto'].map(category => { const categorySymbols = filteredSymbols.filter(s => s.category === category) if (categorySymbols.length === 0) return null - const labels: Record = { crypto: 'Crypto', stock: 'Stocks', forex: 'Forex', commodity: 'Commodities', index: 'Index' } + const labels: Record = { crypto: 'Crypto', stock: 'Stocks', forex: 'Forex', commodity: 'Commodities', index: 'Indices', pre_ipo: 'Pre-IPO' } return (
{labels[category]}
@@ -247,7 +252,7 @@ export function ChartTabs({ traderId, selectedSymbol, updateKey, exchangeId }: C onClick={() => { setChartSymbol(s.symbol); setShowDropdown(false); setSearchFilter('') }} className={`w-full px-3 py-2 text-left text-[11px] font-mono hover:bg-white/5 transition-all flex items-center justify-between ${chartSymbol === s.symbol ? 'bg-nofx-gold/10 text-nofx-gold' : 'text-nofx-text-muted'}`} > - {s.symbol} + {s.display || s.symbol} {s.name} ))} diff --git a/web/src/components/common/HeaderBar.tsx b/web/src/components/common/HeaderBar.tsx index c60559e4..a0af7efb 100644 --- a/web/src/components/common/HeaderBar.tsx +++ b/web/src/components/common/HeaderBar.tsx @@ -11,6 +11,7 @@ import { type UserMode, } from '../../lib/onboarding' import { getCurrentPageForPath, ROUTES, type Page } from '../../router/paths' +import { HyperliquidWalletConnect } from './HyperliquidWalletConnect' interface HeaderBarProps { onLoginClick?: () => void @@ -208,6 +209,7 @@ export default function HeaderBar({ {/* Right Side - Social Links and User Actions */}
+ {/* Social Links - Always visible */}
{/* GitHub */} diff --git a/web/src/components/landing/CommunitySection.tsx b/web/src/components/landing/CommunitySection.tsx index 6e22f1ec..b7ff9a00 100644 --- a/web/src/components/landing/CommunitySection.tsx +++ b/web/src/components/landing/CommunitySection.tsx @@ -136,7 +136,7 @@ export default function CommunitySection({ language }: CommunitySectionProps) { viewport={{ once: true }} >
- MARKET SELECT + ASSET CLASS SELECT

- STRATEGY{' '} + PROFESSIONAL{' '} - UNITS + AGENTS

- SELECT AN AUTONOMOUS AGENT TO BEGIN DEPLOYMENT. UNITS ARE - PRE-TRAINED ON HISTORICAL TICKS. + CREATE AGENTS FOR US STOCKS, COMMODITIES, FX AND PRE-IPO MARKETS. DESCRIBE THE STRATEGY IN ONE SENTENCE.
diff --git a/web/src/components/landing/core/LiveFeed.tsx b/web/src/components/landing/core/LiveFeed.tsx index 4c76afb8..557319b8 100644 --- a/web/src/components/landing/core/LiveFeed.tsx +++ b/web/src/components/landing/core/LiveFeed.tsx @@ -10,29 +10,29 @@ interface LogEntry { } const generateLog = (id: number): LogEntry => { - const types = ['EXE', 'ARB', 'LIQ', 'NET', 'SYS'] - const pairs = ['BTC-USDT', 'ETH-PERP', 'SOL-USDT', 'BNB-BUSD'] - const actions = ['BUY', 'SELL', 'SHORT', 'LONG'] + const types = ['EXEC', 'SIGNAL', 'RISK', 'MACRO', 'SYS'] + const pairs = ['AAPL-USDC', 'NVDA-USDC', 'GOLD-USDC', 'EURUSD-USDC', 'OPENAI-IPO'] + const actions = ['BUY', 'SELL', 'HEDGE', 'ROTATE'] const type = types[Math.floor(Math.random() * types.length)] let msg = '' let color = '' switch (type) { - case 'EXE': - msg = `BOT-${Math.floor(Math.random() * 99)} ${actions[Math.floor(Math.random() * 4)]} ${pairs[Math.floor(Math.random() * 4)]} @ ${Math.floor(Math.random() * 60000)}` + case 'EXEC': + msg = `AGENT-${Math.floor(Math.random() * 99)} ${actions[Math.floor(Math.random() * 4)]} ${pairs[Math.floor(Math.random() * pairs.length)]} @ ${Math.floor(Math.random() * 600)}` color = 'text-green-500' break; - case 'ARB': - msg = `Spread detected: BINANCE <> BYBIT (${(Math.random()).toFixed(3)}%)` + case 'SIGNAL': + msg = `US equities momentum signal confirmed (${(Math.random()).toFixed(3)} z-score)` color = 'text-nofx-gold' break; - case 'LIQ': - msg = `Liquidation Alert: ${pairs[Math.floor(Math.random() * 4)]} $${Math.floor(Math.random() * 100)}k REKT` + case 'RISK': + msg = `Risk check passed: ${pairs[Math.floor(Math.random() * pairs.length)]} exposure within limits` color = 'text-red-500' break; - case 'NET': - msg = `Block propagation latency < ${Math.floor(Math.random() * 10)}ms` + case 'MACRO': + msg = `Macro feed latency < ${Math.floor(Math.random() * 10)}ms` color = 'text-zinc-500' break; default: @@ -91,9 +91,9 @@ export default function LiveFeed() { className="absolute inset-0 flex items-center gap-4" > [{log.time}] - {log.type} {log.msg} @@ -105,8 +105,8 @@ export default function LiveFeed() { {logs.map((log) => (
{log.time.split('.')[0]} - {log.type} {log.msg} diff --git a/web/src/components/landing/core/TerminalHero.tsx b/web/src/components/landing/core/TerminalHero.tsx index d7fc2625..1c44e4d6 100644 --- a/web/src/components/landing/core/TerminalHero.tsx +++ b/web/src/components/landing/core/TerminalHero.tsx @@ -4,23 +4,34 @@ import { useState, useEffect } from 'react' import { useGitHubStats } from '../../../hooks/useGitHubStats' import AgentTerminal from '../brand/AgentTerminal' +const tickerLabels: Record = { + AAPL: 'AAPL', + MSFT: 'MSFT', + NVDA: 'NVDA', + TSLA: 'TSLA', + GOLD: 'GOLD', + EURUSD: 'EUR/USD', + SPX: 'S&P 500', + PREIPO: 'PRE-IPO INDEX', +} + export default function TerminalHero() { // Real-time price state const [prices, setPrices] = useState>({ - BTC: '...', - ETH: '...', - SOL: '...', - BNB: '...', - XRP: '...', - DOGE: '...', - ADA: '...', - AVAX: '...' + AAPL: '...', + MSFT: '...', + NVDA: '...', + TSLA: '...', + GOLD: '...', + EURUSD: '...', + SPX: '...', + PREIPO: '...' }) useEffect(() => { const fetchPrices = async () => { - const symbols = ['BTC', 'ETH', 'SOL', 'BNB', 'XRP', 'DOGE', 'ADA', 'AVAX'] + const symbols = ['AAPL', 'MSFT', 'NVDA', 'TSLA', 'GOLD', 'EURUSD', 'SPX'] // We use Promise.all to fetch them in parallel for now, or sequentially if rate limited. // Parallel is better for UI responsiveness. @@ -28,7 +39,7 @@ export default function TerminalHero() { const results = await Promise.all(symbols.map(async (sym) => { try { // Use native fetch to bypass global error handlers (toasts) in httpClient - const response = await fetch(`/api/klines?symbol=${sym}USDT&interval=1m&limit=1`) + const response = await fetch(`/api/klines?symbol=xyz:${sym}&interval=1m&limit=1`) if (!response.ok) return null const res = await response.json() @@ -149,9 +160,9 @@ export default function TerminalHero() { {/* Bottom: Network Log */}
-
> CONNECTING TO MAINNET... OK
-
> SYNCING NODES (424/424)... OK
-
> LOADING ASSETS... DONE
+
> CONNECTING TO MARKET DATA... OK
+
> SYNCING VENUES (424/424)... OK
+
> LOADING MULTI-ASSET UNIVERSE... DONE
> AWAITING USER INPUT_
@@ -169,7 +180,7 @@ export default function TerminalHero() { - NOFX OPEN-SOURCE AGENTIC OS + NOFX PROFESSIONAL MULTI-ASSET AGENT OS {/* Main Title - Massive & Impactful */} @@ -181,8 +192,8 @@ export default function TerminalHero() {

- The World's First Open-Source Agentic Trading OS. - Deploy autonomous high-frequency trading agents powered by advanced LLMs. + Professional AI trading agents for US stocks, commodities, FX and Pre-IPO synthetic markets. + Build institutional-grade strategies by chatting in plain English.

@@ -197,7 +208,7 @@ export default function TerminalHero() { Live Data Feeds Active
- {['CRYPTO', 'US STOCKS', 'FOREX', 'METALS'].map((market) => ( + {['US STOCKS', 'COMMODITIES', 'FOREX', 'PRE-IPO'].map((market) => (
@@ -213,7 +224,7 @@ export default function TerminalHero() {
document.getElementById('market-scanner')?.scrollIntoView({ behavior: 'smooth' })}> ~ - deploy agent --strategy=hft + create US stock agent --idea="breakouts"
@@ -225,7 +236,7 @@ export default function TerminalHero() { style={{ clipPath: 'polygon(10% 0, 100% 0, 100% 70%, 90% 100%, 0 100%, 0 30%)' }} > - INITIALIZE PROTOCOL + CREATE STOCK AGENT
@@ -263,13 +274,13 @@ export default function TerminalHero() {
GLOBAL MARKET ACCESS - FLASH LOANS ENABLED + MULTI-ASSET ROUTING ENABLED LOW LATENCY LINK: 12ms {/* Dynamic Coins */} {Object.entries(prices).map(([symbol, price]) => ( - {symbol.toUpperCase()}/USDT ${price} + {tickerLabels[symbol] || symbol.toUpperCase()} ${price} ))} @@ -278,7 +289,7 @@ export default function TerminalHero() { {/* Duplicate sequence for seamless loop effect (basic set) */} {Object.entries(prices).map(([symbol, price]) => ( - {symbol.toUpperCase()}/USDT ${price} + {tickerLabels[symbol] || symbol.toUpperCase()} ${price} ))}
diff --git a/web/src/constants/branding.ts b/web/src/constants/branding.ts index e6512848..f36e8d8f 100644 --- a/web/src/constants/branding.ts +++ b/web/src/constants/branding.ts @@ -7,7 +7,7 @@ const _e = (s: string) => btoa(s) // Encoded official links - tampering will break functionality const ENCODED_LINKS = { - twitter: 'aHR0cHM6Ly94LmNvbS9ub2Z4X29mZmljaWFs', // https://x.com/nofx_official + twitter: 'aHR0cHM6Ly94LmNvbS92ZXJnZXhfYWk=', telegram: 'aHR0cHM6Ly90Lm1lL25vZnhfZGV2X2NvbW11bml0eQ==', // https://t.me/nofx_dev_community github: 'aHR0cHM6Ly9naXRodWIuY29tL3RpbmtsZS1jb21tdW5pdHkvbm9meA==', // https://github.com/NoFxAiOS/nofx } @@ -39,7 +39,7 @@ function getVerifiedLink(key: keyof typeof ENCODED_LINKS): string { } catch { // Fallback to hardcoded values if decoding fails const fallbacks: Record = { - twitter: 'https://x.com/nofx_official', + twitter: 'https://x.com/vergex_ai', telegram: 'https://t.me/nofx_dev_community', github: 'https://github.com/NoFxAiOS/nofx', } diff --git a/web/src/i18n/translations.ts b/web/src/i18n/translations.ts index 57bc63ee..661e20e2 100644 --- a/web/src/i18n/translations.ts +++ b/web/src/i18n/translations.ts @@ -341,10 +341,10 @@ export const translations = { clearSelection: 'Clear All', confirmSelection: 'Confirm', tradingSymbolsDescription: - 'Empty = use default symbols. Must end with USDT (e.g., BTCUSDT, ETHUSDT)', + 'Empty = use default symbols. Use USDT perps (e.g., BTCUSDT, ETHUSDT) or Hyperliquid XYZ USDC markets (e.g., TSLA-USDC)', btcEthLeverageValidation: 'BTC/ETH leverage must be between 1-50x', altcoinLeverageValidation: 'Altcoin leverage must be between 1-20x', - invalidSymbolFormat: 'Invalid symbol format: {symbol}, must end with USDT', + invalidSymbolFormat: 'Invalid symbol format: {symbol}, use USDT perps or SYMBOL-USDC', // System Prompt Templates systemPromptTemplate: 'System Prompt Template', @@ -1687,10 +1687,10 @@ export const translations = { clearSelection: '清空选择', confirmSelection: '确认选择', tradingSymbolsDescription: - '留空 = 使用默认币种。必须以USDT结尾(如:BTCUSDT, ETHUSDT)', + '留空 = 使用默认币种。支持 USDT 合约(如:BTCUSDT, ETHUSDT)或 Hyperliquid XYZ USDC 标的(如:TSLA-USDC)', btcEthLeverageValidation: 'BTC/ETH杠杆必须在1-50倍之间', altcoinLeverageValidation: '山寨币杠杆必须在1-20倍之间', - invalidSymbolFormat: '无效的币种格式:{symbol},必须以USDT结尾', + invalidSymbolFormat: '无效的币种格式:{symbol},请使用 USDT 合约或 SYMBOL-USDC', // System Prompt Templates systemPromptTemplate: '系统提示词模板', @@ -2965,10 +2965,10 @@ export const translations = { selectedSymbolsCount: '{count} simbol dipilih', clearSelection: 'Hapus Semua', confirmSelection: 'Konfirmasi', - tradingSymbolsDescription: 'Kosong = gunakan simbol default. Harus berakhiran USDT (misal BTCUSDT, ETHUSDT)', + tradingSymbolsDescription: 'Kosong = gunakan simbol default. Gunakan perp USDT (misal BTCUSDT, ETHUSDT) atau market Hyperliquid XYZ USDC (misal TSLA-USDC)', btcEthLeverageValidation: 'Leverage BTC/ETH harus antara 1-50x', altcoinLeverageValidation: 'Leverage Altcoin harus antara 1-20x', - invalidSymbolFormat: 'Format simbol tidak valid: {symbol}, harus berakhiran USDT', + invalidSymbolFormat: 'Format simbol tidak valid: {symbol}, gunakan perp USDT atau SYMBOL-USDC', systemPromptTemplate: 'Template Prompt Sistem', promptTemplateDefault: 'Default Stabil', promptTemplateAdaptive: 'Strategi Konservatif', diff --git a/web/src/pages/DataPage.tsx b/web/src/pages/DataPage.tsx index a90bf5b1..cb5b5f3d 100644 --- a/web/src/pages/DataPage.tsx +++ b/web/src/pages/DataPage.tsx @@ -7,10 +7,11 @@ export function DataPage() { return (