@liberfi.io/ui-perpetuals 0.2.13 → 0.2.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/version.ts","../src/client/hyperliquid/WebSocketManager.ts","../src/client/hyperliquid/HyperliquidPerpetualsClient.ts","../src/client/liberfi/transport.ts","../src/client/liberfi/LiberFiPerpetualsClient.ts","../src/client/liberfi/LiberFiPerpDepositClient.ts","../src/client/liberfi/deposit-types.ts","../src/client/liberfi/deposit-state-machine.ts","../src/context/PerpetualsContext.ts","../src/providers/PerpetualsProvider.tsx","../src/hooks/usePerpetualsClient.ts","../src/hooks/useCoinsQuery.ts","../src/hooks/useMarketQuery.ts","../src/hooks/useMarketsQuery.ts","../src/hooks/useKlinesQuery.ts","../src/hooks/useOrderBookQuery.ts","../src/hooks/useRecentTradesQuery.ts","../src/hooks/usePositionsQuery.ts","../src/hooks/useOrdersQuery.ts","../src/hooks/useTradesQuery.ts","../src/hooks/useCreateOrderMutation.ts","../src/hooks/useCancelOrderMutation.ts","../src/hooks/useMarketDataSubscription.ts","../src/hooks/useCandlesSubscription.ts","../src/hooks/useUserDataSubscription.ts","../src/hooks/usePerpDepositClient.ts","../src/hooks/usePerpDepositQuote.ts","../src/hooks/usePerpDepositExecute.ts","../src/hooks/usePerpDepositStatus.ts","../src/hooks/hyperliquid-setup/setup-state-machine.ts","../src/hooks/hyperliquid-setup/useHyperliquidSetup.ts","../src/components/coin-info/coin-info-notfound.ui.tsx","../src/components/coin-info/coin-info-skeletons.ui.tsx","../src/components/coin-info/coin-info.script.tsx","../src/components/coin-info/coin-info.ui.tsx","../src/components/coin-info/coin-info.widget.tsx","../src/components/search-coins/search-coins.script.tsx","../src/components/search-coins/search-coins.ui.tsx","../src/components/search-coins/search-coins.widget.tsx","../src/components/orderbook/orderbook.script.tsx","../src/components/orderbook/orderbook.ui.tsx","../src/components/orderbook/orderbook.widget.tsx","../src/components/trades/trades.script.tsx","../src/components/trades/trades.ui.tsx","../src/components/trades/trades.widget.tsx","../src/components/place-order/place-order-form.script.tsx","../src/components/place-order/place-order-form.ui.tsx","../src/components/place-order/place-order-form.widget.tsx","../src/components/positions/positions.script.tsx","../src/components/positions/positions.ui.tsx","../src/components/positions/positions.widget.tsx","../src/components/open-orders/open-orders.script.tsx","../src/components/open-orders/open-orders.ui.tsx","../src/components/open-orders/open-orders.widget.tsx","../src/components/trade-history/trade-history.script.tsx","../src/components/trade-history/trade-history.ui.tsx","../src/components/trade-history/trade-history.widget.tsx","../src/components/perp-deposit/format.ts","../src/components/perp-deposit/deposit-confirm.ui.tsx","../src/components/perp-deposit/deposit-form.ui.tsx","../src/components/perp-deposit/deposit-status.ui.tsx","../src/components/perp-deposit/deposit-flow.widget.tsx","../src/components/hyperliquid-init/hyperliquid-init.ui.tsx","../src/components/hyperliquid-init/hyperliquid-init.widget.tsx"],"names":["version_default","WebSocketManager","wsEndpoint","resolve","reject","settled","settle","callback","ws","event","error","delay","message","subscription","data","channel","subscriptionId","transformedData","type","param","expectedCoin","payloadCoin","symbol","ctx","mid","mark","prev","change24h","trade","bids","asks","level","fill","interval","unsubscription","HYPERLIQUID_ENDPOINTS","HyperliquidPerpetualsClient","config","endpoint","body","url","controller","timeoutId","response","HyperliquidApiError","meta","asset","markets","symbols","assetCtxs","allMarkets","index","currentPrice","prevPrice","symbolSet","m","limit","coin","intervalMs","endTime","startTime","candle","maxLevel","_params","params","positions","assetPos","pos","quantity","entryPrice","unrealizedPnl","positionValue","filteredPositions","p","sum","orders","order","origSz","remainingSz","filledSz","filteredOrders","trades","isLong","t","userAddress","subscriptionType","statusCode","responseBody","LiberFiApiError","DEFAULT_TIMEOUT_MS","LiberFiHttpTransport","path","query","key","value","qs","method","opts","timeoutMs","text","safeText","err","DEFAULT_WS_ENDPOINT","LiberFiPerpetualsClient","result","fills","prepared","signature","LiberFiPerpDepositClient","req","intentId","TERMINAL_DEPOSIT_STATUSES","initialDepositState","reduceDepositState","state","mapStatusToPhase","status","isTerminal","isPolling","currentStatus","currentBreakdown","isTerminalLifecycle","PerpetualsContext","createContext","PerpetualsProvider","client","depositClient","children","useMemo","jsx","usePerpetualsClient","context","useContext","coinsQueryKey","fetchCoins","useCoinsQuery","options","useQuery","marketQueryKey","fetchMarket","useMarketQuery","marketsQueryKey","fetchMarkets","useMarketsQuery","klinesQueryKey","fetchKlines","useKlinesQuery","orderBookQueryKey","fetchOrderBook","useOrderBookQuery","recentTradesQueryKey","fetchRecentTrades","useRecentTradesQuery","positionsQueryKey","fetchPositions","usePositionsQuery","enabled","queryParams","ordersQueryKey","fetchOrders","useOrdersQuery","tradesQueryKey","fetchTrades","useTradesQuery","createOrder","useCreateOrderMutation","useMutation","cancelOrder","useCancelOrderMutation","useMarketDataSubscription","setData","useState","isConnected","setIsConnected","setError","handleData","useCallback","newData","useEffect","isSubscribed","useCandlesSubscription","useUserDataSubscription","usePerpDepositClient","usePerpDepositClientMaybe","perpDepositQuoteQueryKey","fetchPerpDepositQuote","usePerpDepositQuote","isQuoteReady","usePerpDepositExecute","signAndBroadcast","dispatch","useReducer","reset","execute","input","quote","solanaTxHash","info","toErrorInfo","submitReq","out","fallbackCode","parsed","parseJsonSafe","perpDepositStatusQueryKey","fetchPerpDepositStatus","usePerpDepositStatus","pollIntervalMs","initialSetupState","classifyStep","step","current","sameAddress","reduceSetupState","action","rec","i","next","mergedAccount","mergeAccountState","s","nextRunnableStep","a","b","base","patch","useHyperliquidSetup","adapter","steps","autoLoad","onComplete","onError","adapterRef","useRef","stepsRef","onCompleteRef","onErrorRef","reload","accountState","records","e","toError","runStep","record","invokeAdapter","runNext","idx","completedRef","CoinInfoNotFoundUI","CoinInfoSkeletonsUI","jsxs","Skeleton","useCoinInfo","marketData","setMarketData","fundingCountdown","setFundingCountdown","initialData","isPending","realtimeData","normalized","normalizeRealtimeTickerPayload","previous","buildMarketData","calculateCountdown","now","eightHours","remainder","timeUntilNext","payload","matched","item","toNumberOr","fallback","formatCountdown","seconds","hours","minutes","secs","formatNumber","num","decimals","formatPrice","price","CoinInfoUI","indexPrice","volume24h","openInterest","fundingRate","safeChange24h","safeFundingRate","isPositiveChange","changePercent","CoinInfoWidget","isLoading","useSearchCoinsScript","onSelectCoin","searchQuery","setSearchQuery","coins","setCoins","coinSymbols","isLoadingSymbols","marketsData","isLoadingMarkets","filteredCoins","SearchCoinsUI","onSearchChange","SearchIcon","fundingPercent","isPositiveFunding","tokenName","target","SearchCoinsWidget","className","handleSelectCoin","aggregateByPrecision","levels","precision","aggregated","roundedPrice","existing","calculateTotalsAndPercentages","total","withTotals","usdAmount","maxTotal","useOrderBookScript","initialPrecision","orderBook","setOrderBook","setPrecision","aggregatedBids","aggregatedAsks","sortedBids","sortedAsks","bestBid","spread","spreadPercentage","formatQuantity","qty","OBRow","percentage","side","onClick","isAsk","OrderBookUI","onPriceClick","ask","bid","OrderBookSkeleton","_","OrderBookEmpty","OrderBookWidget","useTradesScript","setTrades","realtimeTrade","isValidTrade","prevTrades","normalizedTrades","normalizeRealtimeTrades","deduped","nextTrade","formatTime","timestamp","date","TradesUI","onTradeClick","isBuy","TradesSkeleton","TradesEmpty","TradesWidget","usePlaceOrderFormScript","maxLeverageProp","onSuccess","setSide","orderType","setOrderType","form","useForm","isSubmitting","watchedValues","amount","leverage","estimatedFee","estimatedTotal","liquidationPrice","maintenanceMarginRate","positionsData","accountValue","availableMargin","currentPosition","handleSubmit","finalPrice","takeProfitPrice","stopLossPrice","tpPercent","slPercent","LeverageModal","maxLeverage","onLeverageChange","onClose","presets","v","Slider","preset","cn","PlaceOrderFormUI","methods","onSideChange","onOrderTypeChange","onSubmit","onAddFunds","showLeverageModal","setShowLeverageModal","showTpSl","setShowTpSl","tokenSymbol","positionPercent","handlePositionSlider","pct","maxAmount","tab","RHForm","RHNumberInput","PlaceOrderFormWidget","resolvedMaxLeverage","usePositionsScript","onCloseSuccess","onCloseError","setPositions","realtimePosition","isClosing","prevPositions","existingIndex","newPositions","handleClosePosition","position","closeSide","formatPnl","pnl","formatPnlPercent","percent","PositionsUI","onClosePosition","headerRow","pnlColor","Button","PositionsSkeleton","PositionsEmpty","PositionsWidget","useOpenOrdersScript","onCancelSuccess","onCancelError","setOrders","ordersData","realtimeOrder","isCanceling","prevOrders","o","newOrders","handleCancelOrder","OpenOrdersUI","onCancelOrder","OpenOrdersSkeleton","OpenOrdersEmpty","OpenOrdersWidget","getTimeRangeInMs","range","today","useTradeHistoryScript","initialTimeRange","pageSize","timeRange","setTimeRange","currentPage","setCurrentPage","allTrades","setAllTrades","tradesData","totalPages","startIndex","endIndex","page","formatDateTime","month","day","TIME_RANGE_OPTIONS","TradeHistoryUI","onTimeRangeChange","onNextPage","onPreviousPage","onGoToPage","option","selected","Fragment","pageNum","TradeHistorySkeleton","TradeHistoryEmpty","TradeHistoryWidget","goToNextPage","goToPreviousPage","goToPage","LAMPORTS_PER_SOL","HL_USDC_DECIMALS","HL_USDC_DIVISOR","lamportsToSol","n","divToFixed","hlUsdcRawToUsdc","microUsdcToUsdc","solToLamports","whole","frac","fracPadded","combined","numerator","denominator","negative","abs","scale","scaledRemainder","secondsUntil","expiresAtMs","nowMs","shortAddress","addr","head","tail","DepositConfirmUI","isOpen","isExecuting","isExpired","onConfirm","onCancel","onExpire","useTranslation","secondsLeft","setSecondsLeft","id","remaining","Modal","ModalContent","ModalHeader","ModalBody","BreakdownSummary","Spinner","ModalFooter","breakdown","Row","label","highlight","muted","DepositFormUI","onAmountChange","recipient","onRecipientChange","balanceSol","disabled","amountError","recipientError","onMax","Input","ACCENT","DepositStatusUI","phase","solanaExplorerUrl","hyperliquidExplorerUrl","onRetry","errorMessage","variant","phaseToVariant","showRetry","StyledModal","XCloseIcon","PhaseIcon","variantTextClass","TxLink","href","hash","ExternalLinkIcon","AccentSpinner","CheckCircle","AlertCircle","XCircle","props","DepositFlowWidget","userSolanaAddress","userId","source","campaign","defaultRecipient","onMaxClick","validateRecipient","buildSolanaExplorerUrl","buildHyperliquidExplorerUrl","onSettled","setAmount","setRecipient","grossLamports","quoteReq","quoteQ","statusQ","handleContinue","handleConfirm","handleExpire","handleRetry","showConfirm","showStatus","continueDisabled","Card","CardBody","HyperliquidInitUI","onContinue","onRetryStep","onReload","onDismiss","isLoadError","CardHeader","LoadingRow","SetupStepRow","CardFooter","isCurrent","title","stepTitle","description","bps","statusLabel","StepIcon","statusBadgeClass","_id","compute","HyperliquidInitWidget","handleReload"],"mappings":"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","file":"index.mjs","sourcesContent":["declare global {\n interface Window {\n __LIBERFI_VERSION__?: {\n [key: string]: string;\n };\n }\n}\nif (typeof window !== \"undefined\") {\n window.__LIBERFI_VERSION__ = window.__LIBERFI_VERSION__ || {};\n window.__LIBERFI_VERSION__[\"@liberfi.io/ui-perpetuals\"] = \"0.2.13\";\n}\n\nexport default \"0.2.13\";\n","import type { Kline, MarketData } from \"../../types\";\n\n/**\n * WebSocket subscription callback function type\n */\ntype SubscriptionCallback = (data: any) => void;\n\n/**\n * WebSocket subscription metadata\n */\ninterface Subscription {\n type: string;\n param: string;\n callback: SubscriptionCallback;\n}\n\n/**\n * WebSocket Manager for Hyperliquid\n *\n * Handles WebSocket connection lifecycle, including:\n * - Connection management (connect/disconnect)\n * - Automatic reconnection with exponential backoff\n * - Heartbeat to keep connection alive\n * - Subscription management (subscribe/unsubscribe)\n * - Message queue for offline messages\n */\nexport class WebSocketManager {\n private ws: WebSocket | null = null;\n private wsEndpoint: string;\n private subscriptions: Map<string, Subscription> = new Map();\n private reconnectAttempts: number = 0;\n private maxReconnectAttempts: number = 10;\n private reconnectDelay: number = 1000; // Initial reconnect delay: 1 second\n private heartbeatInterval: number | null = null;\n private messageQueue: any[] = []; // Message queue before connection established\n private isConnected: boolean = false;\n private pingInterval: number = 30000; // 30 second heartbeat\n private reconnectTimeout: number | null = null;\n private isReconnecting: boolean = false;\n private connectPromise: Promise<void> | null = null;\n private manuallyDisconnected: boolean = false;\n\n /**\n * Create a new WebSocketManager\n * @param wsEndpoint WebSocket endpoint URL\n */\n constructor(wsEndpoint: string) {\n this.wsEndpoint = wsEndpoint;\n }\n\n /**\n * Connect to WebSocket server\n * @returns Promise that resolves when connection is established\n */\n async connect(): Promise<void> {\n if (this.isConnected && this.ws?.readyState === WebSocket.OPEN) {\n return;\n }\n\n if (this.connectPromise) {\n return this.connectPromise;\n }\n\n this.manuallyDisconnected = false;\n\n this.connectPromise = new Promise((resolve, reject) => {\n let settled = false;\n\n const settle = (callback: () => void) => {\n if (settled) return;\n settled = true;\n this.connectPromise = null;\n callback();\n };\n\n try {\n const ws = new WebSocket(this.wsEndpoint);\n this.ws = ws;\n\n ws.onopen = () => {\n if (this.ws !== ws) return;\n console.log(\"[WebSocket] Connected to Hyperliquid\");\n this.isConnected = true;\n this.reconnectAttempts = 0;\n this.isReconnecting = false;\n this.startHeartbeat();\n this.flushMessageQueue();\n settle(resolve);\n };\n\n ws.onmessage = (event: MessageEvent) => {\n if (this.ws !== ws) return;\n this.handleMessage(event.data);\n };\n\n ws.onerror = (error: Event) => {\n if (this.ws !== ws) return;\n console.error(\"[WebSocket] Error:\", error);\n this.isConnected = false;\n settle(() => reject(new Error(\"WebSocket connection failed\")));\n };\n\n ws.onclose = (event: CloseEvent) => {\n if (this.ws !== ws) return;\n console.log(\n `[WebSocket] Closed: ${event.code} - ${event.reason || \"No reason provided\"}`,\n );\n this.isConnected = false;\n this.stopHeartbeat();\n this.connectPromise = null;\n\n // Only attempt reconnect if not manually disconnected (code 1000 = normal closure)\n if (!settled) {\n settle(() =>\n reject(\n new Error(\n `WebSocket closed before connection was established: ${event.code}`,\n ),\n ),\n );\n }\n\n if (!this.manuallyDisconnected && event.code !== 1000) {\n this.attemptReconnect();\n }\n };\n } catch (error) {\n settle(() => reject(error));\n }\n });\n\n return this.connectPromise;\n }\n\n /**\n * Disconnect from WebSocket server\n */\n disconnect(): void {\n this.manuallyDisconnected = true;\n this.stopHeartbeat();\n this.subscriptions.clear();\n\n // Clear reconnect timeout\n if (this.reconnectTimeout !== null) {\n clearTimeout(this.reconnectTimeout);\n this.reconnectTimeout = null;\n }\n\n if (this.ws) {\n this.ws.close(1000, \"Normal closure\");\n this.ws = null;\n }\n\n this.isConnected = false;\n this.isReconnecting = false;\n this.reconnectAttempts = 0;\n }\n\n /**\n * Attempt to reconnect with exponential backoff\n */\n private attemptReconnect(): void {\n if (this.isReconnecting) {\n return; // Already attempting to reconnect\n }\n\n if (this.reconnectAttempts >= this.maxReconnectAttempts) {\n console.error(\"[WebSocket] Max reconnection attempts reached\");\n return;\n }\n\n this.isReconnecting = true;\n this.reconnectAttempts++;\n\n // Exponential backoff: min(1000 * 2^attempts, 30000)\n const delay = Math.min(\n this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1),\n 30000, // Max 30 seconds\n );\n\n console.log(\n `[WebSocket] Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts})`,\n );\n\n this.reconnectTimeout = window.setTimeout(() => {\n this.connect()\n .then(() => {\n // Resubscribe to all previous subscriptions\n this.resubscribeAll();\n })\n .catch((error) => {\n console.error(\"[WebSocket] Reconnection failed:\", error);\n this.isReconnecting = false;\n // attemptReconnect will be called again by onclose event\n });\n }, delay);\n }\n\n /**\n * Start heartbeat interval to keep connection alive\n */\n private startHeartbeat(): void {\n this.heartbeatInterval = window.setInterval(() => {\n if (\n this.isConnected &&\n this.ws &&\n this.ws.readyState === WebSocket.OPEN\n ) {\n // Send a ping message to keep connection alive\n // Hyperliquid WebSocket accepts JSON messages\n this.send({ method: \"ping\" });\n }\n }, this.pingInterval);\n }\n\n /**\n * Stop heartbeat interval\n */\n private stopHeartbeat(): void {\n if (this.heartbeatInterval !== null) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = null;\n }\n }\n\n /**\n * Send message to WebSocket server\n * @param message Message object to send\n */\n private send(message: any): void {\n if (this.isConnected && this.ws && this.ws.readyState === WebSocket.OPEN) {\n this.ws.send(JSON.stringify(message));\n } else {\n // Connection not established, add to queue\n this.messageQueue.push(message);\n }\n }\n\n /**\n * Flush message queue after connection established\n */\n private flushMessageQueue(): void {\n while (this.messageQueue.length > 0) {\n const message = this.messageQueue.shift();\n if (message) {\n this.send(message);\n }\n }\n }\n\n /**\n * Resubscribe to all subscriptions after reconnection\n */\n private resubscribeAll(): void {\n this.subscriptions.forEach((subscription) => {\n this.sendSubscription(subscription.type, subscription.param);\n });\n }\n\n /**\n * Handle incoming WebSocket message\n * @param data Raw message data\n */\n private handleMessage(data: string): void {\n try {\n const message = JSON.parse(data);\n\n // Handle different message types\n if (message.channel) {\n this.handleChannelMessage(message);\n } else if (message.method === \"pong\") {\n // Heartbeat response\n // No action needed\n }\n } catch (error) {\n console.error(\"[WebSocket] Failed to parse message:\", error, data);\n }\n }\n\n /**\n * Handle channel-specific messages\n * @param message Parsed message object\n */\n private handleChannelMessage(message: any): void {\n const channel = message.channel;\n\n // Find matching subscriptions and trigger callbacks\n this.subscriptions.forEach((subscription, subscriptionId) => {\n if (\n this.isChannelMatch(\n channel,\n subscription.type,\n subscription.param,\n message,\n )\n ) {\n try {\n const transformedData = this.transformData(\n subscription.type,\n message.data,\n subscription.param,\n );\n subscription.callback(transformedData);\n } catch (error) {\n console.error(\n `[WebSocket] Error in subscription callback (${subscriptionId}):`,\n error,\n );\n }\n }\n });\n }\n\n /**\n * Check if channel matches subscription\n *\n * For per-coin channels (ticker via `activeAssetCtx`, trades, orderBook,\n * candle), we additionally match the coin in the payload against the\n * subscription parameter so a single multiplexed connection can feed many\n * subscriptions without cross-talk.\n *\n * @param channel Channel name from message\n * @param type Subscription type\n * @param param Subscription parameter (e.g. \"BTC-USDC\", \"BTC-USDC:1m\")\n * @param message Full parsed message (used to read payload coin)\n * @returns True if channel matches subscription\n */\n private isChannelMatch(\n channel: string,\n type: string,\n param: string,\n message: any,\n ): boolean {\n if (type === \"ticker\") {\n if (channel !== \"activeAssetCtx\") return false;\n const expectedCoin = param.split(\"-\")[0];\n const payloadCoin = message?.data?.coin;\n return typeof payloadCoin === \"string\" && payloadCoin === expectedCoin;\n } else if (type === \"trades\") {\n return channel === \"trades\";\n } else if (type === \"orderBook\") {\n return channel === \"l2Book\";\n } else if (type === \"candle\") {\n return channel === \"candle\";\n } else if (type === \"userFills\") {\n return channel === \"userFills\";\n } else if (type === \"userEvents\") {\n return channel === \"userEvents\";\n }\n\n return false;\n }\n\n /**\n * Transform raw data to standard format\n * @param type Subscription type\n * @param data Raw data from WebSocket\n * @param param Subscription parameter (e.g., symbol, interval)\n * @returns Transformed data\n */\n private transformData(type: string, data: any, param: string): any {\n if (type === \"ticker\") {\n return this.transformTickerData(data, param);\n } else if (type === \"trades\") {\n return this.transformTradesData(data, param);\n } else if (type === \"orderBook\") {\n return this.transformOrderBookData(data, param);\n } else if (type === \"candle\") {\n return this.transformCandleData(data, param);\n } else if (type === \"userFills\") {\n return this.transformUserFillsData(data);\n } else if (type === \"userEvents\") {\n return this.transformUserEventsData(data);\n }\n\n return data;\n }\n\n /**\n * Transform ticker data (Hyperliquid `activeAssetCtx` channel).\n *\n * Each push delivers the full per-coin market context — mark/mid price,\n * `prevDayPx` (so we can compute 24h change client-side), notional volume,\n * funding, open interest, oracle price, etc. We map this into the\n * standard {@link MarketData} shape so consumers (`useCoinInfo`, ticker\n * widgets, etc.) get a real-time, complete snapshot in one shot — no\n * second REST call required to fill in 24h change.\n *\n * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket\n */\n private transformTickerData(data: any, param: string): MarketData {\n const coin: string = data?.coin ?? param.split(\"-\")[0];\n const symbol = `${coin}-USDC`;\n const ctx = data?.ctx ?? {};\n\n const mid = parseFloat(ctx.midPx ?? ctx.markPx ?? \"0\");\n const mark = parseFloat(ctx.markPx ?? ctx.midPx ?? \"0\");\n const prev = ctx.prevDayPx ? parseFloat(ctx.prevDayPx) : mid;\n const change24h = prev > 0 ? ((mid - prev) / prev) * 100 : 0;\n\n return {\n symbol,\n price: mid,\n change24h,\n volume24h: parseFloat(ctx.dayNtlVlm ?? \"0\"),\n fundingRate: parseFloat(ctx.funding ?? \"0\"),\n openInterest: parseFloat(ctx.openInterest ?? \"0\"),\n markPrice: mark,\n indexPrice: parseFloat(ctx.oraclePx ?? ctx.midPx ?? \"0\"),\n };\n }\n\n /**\n * Transform trades data\n */\n private transformTradesData(data: any, symbol: string): any {\n if (!Array.isArray(data)) {\n return [];\n }\n\n return data.map((trade: any) => ({\n symbol,\n side: trade.side === \"B\" ? \"buy\" : \"sell\",\n price: parseFloat(trade.px),\n quantity: parseFloat(trade.sz),\n timestamp: trade.time,\n tradeId: trade.tid,\n }));\n }\n\n /**\n * Transform order book data\n */\n private transformOrderBookData(data: any, symbol: string): any {\n const [bids, asks] = data.levels || [[], []];\n\n return {\n symbol,\n bids: bids.map((level: any) => ({\n price: parseFloat(level.px),\n quantity: parseFloat(level.sz),\n count: level.n,\n })),\n asks: asks.map((level: any) => ({\n price: parseFloat(level.px),\n quantity: parseFloat(level.sz),\n count: level.n,\n })),\n timestamp: data.time || Date.now(),\n };\n }\n\n /**\n * Transform candle data\n */\n private transformCandleData(data: any, param: string): Kline {\n const [symbol] = param.split(\":\");\n\n return {\n symbol,\n open: parseFloat(data.o),\n high: parseFloat(data.h),\n low: parseFloat(data.l),\n close: parseFloat(data.c),\n volume: parseFloat(data.v),\n timestamp: data.t,\n closeTimestamp: data.T,\n };\n }\n\n /**\n * Transform user fills data\n */\n private transformUserFillsData(data: any): any {\n if (!Array.isArray(data)) {\n return [];\n }\n\n return data.map((fill: any) => ({\n tradeId: fill.tid?.toString(),\n orderId: fill.oid?.toString(),\n symbol: `${fill.coin}-USDC`,\n side: fill.dir?.includes(\"Long\") ? \"long\" : \"short\",\n price: parseFloat(fill.px),\n quantity: parseFloat(fill.sz),\n fee: parseFloat(fill.fee || \"0\"),\n feeCurrency: fill.feeToken || \"USDC\",\n isMaker: fill.side === \"M\",\n timestamp: fill.time,\n }));\n }\n\n /**\n * Transform user events data (orders and positions)\n */\n private transformUserEventsData(data: any): any {\n // User events can contain both order updates and position updates\n // Return the data as-is for now, let the callback handle it\n return data;\n }\n\n /**\n * Send subscription message to Hyperliquid WebSocket\n * @param type Subscription type\n * @param param Subscription parameter\n */\n private sendSubscription(type: string, param: string): void {\n let subscription: any;\n\n if (type === \"ticker\") {\n // Subscribe to per-coin `activeAssetCtx` so each push carries a full\n // market snapshot (mark/mid price, prevDayPx for 24h change, volume,\n // funding, open interest). This avoids the limitations of `allMids`,\n // which only streams price.\n const coin = param.split(\"-\")[0]; // \"BTC-USDC\" -> \"BTC\"\n subscription = {\n method: \"subscribe\",\n subscription: {\n type: \"activeAssetCtx\",\n coin,\n },\n };\n } else if (type === \"trades\") {\n // Subscribe to trades for specific coin\n const coin = param.split(\"-\")[0]; // \"BTC-USDC\" -> \"BTC\"\n subscription = {\n method: \"subscribe\",\n subscription: {\n type: \"trades\",\n coin,\n },\n };\n } else if (type === \"orderBook\") {\n // Subscribe to order book for specific coin\n const coin = param.split(\"-\")[0];\n subscription = {\n method: \"subscribe\",\n subscription: {\n type: \"l2Book\",\n coin,\n },\n };\n } else if (type === \"candle\") {\n // Subscribe to candles\n const [symbol, interval] = param.split(\":\");\n const coin = symbol.split(\"-\")[0];\n subscription = {\n method: \"subscribe\",\n subscription: {\n type: \"candle\",\n coin,\n interval,\n },\n };\n } else if (type === \"userFills\") {\n // Subscribe to user fills\n const userAddress = param;\n subscription = {\n method: \"subscribe\",\n subscription: {\n type: \"userFills\",\n user: userAddress,\n },\n };\n } else if (type === \"userEvents\") {\n // Subscribe to user events (orders + positions)\n const userAddress = param;\n subscription = {\n method: \"subscribe\",\n subscription: {\n type: \"userEvents\",\n user: userAddress,\n },\n };\n }\n\n if (subscription) {\n this.send(subscription);\n }\n }\n\n /**\n * Send unsubscription message to Hyperliquid WebSocket\n * @param type Subscription type\n * @param param Subscription parameter\n */\n private sendUnsubscription(type: string, param: string): void {\n let unsubscription: any;\n\n if (type === \"ticker\") {\n const coin = param.split(\"-\")[0];\n unsubscription = {\n method: \"unsubscribe\",\n subscription: {\n type: \"activeAssetCtx\",\n coin,\n },\n };\n } else if (type === \"trades\") {\n const coin = param.split(\"-\")[0];\n unsubscription = {\n method: \"unsubscribe\",\n subscription: {\n type: \"trades\",\n coin,\n },\n };\n } else if (type === \"orderBook\") {\n const coin = param.split(\"-\")[0];\n unsubscription = {\n method: \"unsubscribe\",\n subscription: {\n type: \"l2Book\",\n coin,\n },\n };\n } else if (type === \"candle\") {\n const [symbol, interval] = param.split(\":\");\n const coin = symbol.split(\"-\")[0];\n unsubscription = {\n method: \"unsubscribe\",\n subscription: {\n type: \"candle\",\n coin,\n interval,\n },\n };\n } else if (type === \"userFills\") {\n const userAddress = param;\n unsubscription = {\n method: \"unsubscribe\",\n subscription: {\n type: \"userFills\",\n user: userAddress,\n },\n };\n } else if (type === \"userEvents\") {\n const userAddress = param;\n unsubscription = {\n method: \"unsubscribe\",\n subscription: {\n type: \"userEvents\",\n user: userAddress,\n },\n };\n }\n\n if (unsubscription) {\n this.send(unsubscription);\n }\n }\n\n /**\n * Subscribe to a data stream\n * @param type Subscription type\n * @param param Subscription parameter (symbol, user address, etc.)\n * @param callback Callback function to receive data\n * @returns Subscription ID (for unsubscribing)\n */\n subscribe(\n type: string,\n param: string,\n callback: SubscriptionCallback,\n ): string {\n const subscriptionId = `${type}:${param}`;\n\n // Store subscription\n this.subscriptions.set(subscriptionId, { type, param, callback });\n\n // Send subscription message\n this.sendSubscription(type, param);\n\n return subscriptionId;\n }\n\n /**\n * Unsubscribe from a data stream\n * @param subscriptionId Subscription ID returned from subscribe()\n */\n unsubscribe(subscriptionId: string): void {\n const subscription = this.subscriptions.get(subscriptionId);\n\n if (subscription) {\n // Send unsubscription message\n this.sendUnsubscription(subscription.type, subscription.param);\n\n // Remove subscription\n this.subscriptions.delete(subscriptionId);\n }\n }\n\n /**\n * Check if WebSocket is connected\n * @returns True if connected\n */\n isConnectedNow(): boolean {\n return this.isConnected;\n }\n}\n","import type {\n IPerpetualsClient,\n MarketData,\n Kline,\n KlineInterval,\n OrderBook,\n Trade,\n PlaceOrderParams,\n PlaceOrderResult,\n CancelOrderParams,\n CancelOrderResult,\n GetPositionsParams,\n GetPositionsResult,\n GetOpenOrdersParams,\n GetOpenOrdersResult,\n GetTradesParams,\n GetTradesResult,\n} from \"../../types\";\nimport { WebSocketManager } from \"./WebSocketManager\";\n\n/**\n * Hyperliquid 环境类型\n */\nexport type HyperliquidEnvironment = \"testnet\" | \"mainnet\";\n\n/**\n * Hyperliquid 客户端配置\n */\nexport interface HyperliquidClientConfig {\n /**\n * 环境配置\n * @default \"testnet\"\n */\n environment?: HyperliquidEnvironment;\n\n /**\n * 自定义 API 端点(可选)\n * 如果不提供,将根据 environment 自动选择\n */\n apiEndpoint?: string;\n\n /**\n * 自定义 WebSocket 端点(可选)\n * 如果不提供,将根据 environment 自动选择\n */\n wsEndpoint?: string;\n\n /**\n * 请求超时时间(毫秒)\n * @default 30000\n */\n timeout?: number;\n}\n\n/**\n * Hyperliquid API 端点配置\n */\nconst HYPERLIQUID_ENDPOINTS = {\n testnet: {\n api: \"https://api.hyperliquid-testnet.xyz\",\n ws: \"wss://api.hyperliquid-testnet.xyz/ws\",\n },\n mainnet: {\n api: \"https://api.hyperliquid.xyz\",\n ws: \"wss://api.hyperliquid.xyz/ws\",\n },\n} as const;\n\n/**\n * HyperliquidPerpetualsClient 类\n *\n * 实现 IPerpetualsClient 接口,提供 Hyperliquid 永续合约交易功能\n */\nexport class HyperliquidPerpetualsClient implements IPerpetualsClient {\n private readonly apiEndpoint: string;\n private readonly _wsEndpoint: string;\n private readonly timeout: number;\n private readonly environment: HyperliquidEnvironment;\n private wsManager: WebSocketManager | null = null;\n /**\n * Reference count of active WebSocket consumers. The connection is\n * established on the first `connectWebSocket()` call and torn down\n * only when the last consumer disconnects — see the matching comment\n * on {@link LiberFiPerpetualsClient}.\n */\n private wsRefCount: number = 0;\n\n /**\n * 构造 Hyperliquid 客户端\n *\n * @param config 客户端配置,不传则使用默认配置(testnet)\n */\n constructor(config: HyperliquidClientConfig = {}) {\n // 1. 确定环境\n this.environment = config.environment || \"testnet\";\n\n // 2. 确定 API 端点\n this.apiEndpoint =\n config.apiEndpoint || HYPERLIQUID_ENDPOINTS[this.environment].api;\n\n // 3. 确定 WebSocket 端点\n this._wsEndpoint =\n config.wsEndpoint || HYPERLIQUID_ENDPOINTS[this.environment].ws;\n\n // 4. 设置超时时间\n this.timeout = config.timeout || 30000;\n }\n\n /**\n * 内部 HTTP 请求方法\n *\n * @param endpoint API 端点路径\n * @param body 请求体\n * @returns 响应数据\n * @throws {HyperliquidApiError} API 请求失败\n */\n private async request<T = any>(endpoint: string, body: any): Promise<T> {\n const url = `${this.apiEndpoint}${endpoint}`;\n\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n throw new HyperliquidApiError(\n `HTTP ${response.status}: ${response.statusText}`,\n response.status,\n await response.text(),\n );\n }\n\n const data = await response.json();\n return data;\n } catch (error: any) {\n if (error.name === \"AbortError\") {\n throw new HyperliquidApiError(\n `Request timeout after ${this.timeout}ms`,\n 408,\n \"\",\n );\n }\n\n if (error instanceof HyperliquidApiError) {\n throw error;\n }\n\n throw new HyperliquidApiError(`Network error: ${error.message}`, 0, \"\");\n }\n }\n\n /**\n * 辅助方法:将符号格式转换为 Hyperliquid 币种名称\n * @param symbol 统一格式符号(例如 \"BTC-USDC\")\n * @returns Hyperliquid 币种名称(例如 \"BTC\")\n */\n private symbolToCoin(symbol: string): string {\n return symbol.split(\"-\")[0];\n }\n\n /**\n * 辅助方法:将 KlineInterval 转换为毫秒数\n * @param interval K线时间间隔\n * @returns 毫秒数\n */\n private parseInterval(interval: KlineInterval): number {\n const intervalMap: Record<KlineInterval, number> = {\n \"1m\": 60 * 1000,\n \"5m\": 5 * 60 * 1000,\n \"15m\": 15 * 60 * 1000,\n \"30m\": 30 * 60 * 1000,\n \"1h\": 60 * 60 * 1000,\n \"4h\": 4 * 60 * 60 * 1000,\n \"1d\": 24 * 60 * 60 * 1000,\n \"1w\": 7 * 24 * 60 * 60 * 1000,\n };\n return intervalMap[interval];\n }\n\n // ===================================\n // 市场数据查询接口(6个方法)\n // ===================================\n\n /**\n * 获取所有支持的币种列表\n * @returns 币种符号数组\n * @throws {HyperliquidApiError} API 请求失败\n */\n async getSupportedCoins(): Promise<string[]> {\n const [meta] = await this.request<[{ universe: Array<{ name: string }> }]>(\n \"/info\",\n { type: \"metaAndAssetCtxs\" },\n );\n\n // 转换:coin.name -> \"BTC-USDC\"\n return meta.universe.map((asset) => `${asset.name}-USDC`);\n }\n\n /**\n * 获取指定币种的市场数据\n * @param symbol 币种符号\n * @returns 市场数据,币种不存在时返回 null\n * @throws {HyperliquidApiError} API 请求失败\n */\n async getMarket(symbol: string): Promise<MarketData | null> {\n const markets = await this.getMarkets([symbol]);\n return markets.length > 0 ? markets[0] : null;\n }\n\n /**\n * 获取多个或所有币种的市场数据\n * @param symbols 币种符号数组(可选)\n * @returns 市场数据数组\n * @throws {HyperliquidApiError} API 请求失败\n */\n async getMarkets(symbols?: string[]): Promise<MarketData[]> {\n const [meta, assetCtxs] = await this.request<\n [\n { universe: Array<{ name: string }> },\n Array<{\n funding?: string;\n openInterest?: string;\n prevDayPx?: string;\n dayNtlVlm?: string;\n oraclePx?: string;\n markPx?: string;\n midPx?: string;\n }>,\n ]\n >(\"/info\", { type: \"metaAndAssetCtxs\" });\n\n // 合并 meta 和 assetCtxs 数据\n const allMarkets = meta.universe.map((asset, index) => {\n const ctx = assetCtxs[index];\n const symbol = `${asset.name}-USDC`;\n\n // 使用 midPx 作为当前价格,fallback 到 markPx\n const currentPrice = parseFloat(ctx.midPx || ctx.markPx || \"0\");\n const prevPrice = ctx.prevDayPx\n ? parseFloat(ctx.prevDayPx)\n : currentPrice;\n const change24h =\n prevPrice > 0 ? ((currentPrice - prevPrice) / prevPrice) * 100 : 0;\n\n return {\n symbol,\n price: currentPrice,\n change24h,\n volume24h: parseFloat(ctx.dayNtlVlm || \"0\"),\n fundingRate: parseFloat(ctx.funding || \"0\"),\n openInterest: parseFloat(ctx.openInterest || \"0\"),\n markPrice: parseFloat(ctx.markPx || \"0\"),\n indexPrice: parseFloat(ctx.oraclePx || ctx.midPx || \"0\"),\n } as MarketData;\n });\n\n // 如果指定了 symbols,进行过滤\n if (symbols && symbols.length > 0) {\n const symbolSet = new Set(symbols);\n return allMarkets.filter((m) => symbolSet.has(m.symbol));\n }\n\n return allMarkets;\n }\n\n /**\n * 获取K线数据\n * @param symbol 交易对符号\n * @param interval 时间间隔\n * @param limit 返回K线数量\n * @returns K线数据数组\n * @throws {HyperliquidApiError} API 请求失败\n */\n async getKlines(\n symbol: string,\n interval: KlineInterval,\n limit: number = 100,\n ): Promise<Kline[]> {\n const coin = this.symbolToCoin(symbol);\n\n // 计算时间范围\n const intervalMs = this.parseInterval(interval);\n const endTime = Date.now();\n const startTime = endTime - intervalMs * limit;\n\n const data = await this.request<\n Array<{\n t: number;\n T: number;\n s: string;\n i: string;\n o: string;\n c: string;\n h: string;\n l: string;\n v: string;\n n: number;\n }>\n >(\"/info\", {\n type: \"candleSnapshot\",\n req: { coin, interval, startTime, endTime },\n });\n\n // 转换为统一格式\n return data.map((candle) => ({\n symbol,\n open: parseFloat(candle.o),\n high: parseFloat(candle.h),\n low: parseFloat(candle.l),\n close: parseFloat(candle.c),\n volume: parseFloat(candle.v),\n timestamp: candle.t,\n closeTimestamp: candle.T,\n }));\n }\n\n /**\n * 获取订单簿\n * @param symbol 交易对符号\n * @param maxLevel 最大深度档位\n * @returns 订单簿数据\n * @throws {HyperliquidApiError} API 请求失败\n */\n async getOrderBook(\n symbol: string,\n maxLevel: number = 10,\n ): Promise<OrderBook> {\n const coin = this.symbolToCoin(symbol);\n\n const data = await this.request<{\n coin: string;\n time: number;\n levels: [\n Array<{ px: string; sz: string; n: number }>,\n Array<{ px: string; sz: string; n: number }>,\n ];\n }>(\"/info\", { type: \"l2Book\", coin });\n\n const [bids, asks] = data.levels;\n\n return {\n symbol,\n bids: bids.slice(0, maxLevel).map((level) => ({\n price: parseFloat(level.px),\n quantity: parseFloat(level.sz),\n count: level.n,\n })),\n asks: asks.slice(0, maxLevel).map((level) => ({\n price: parseFloat(level.px),\n quantity: parseFloat(level.sz),\n count: level.n,\n })),\n timestamp: data.time,\n };\n }\n\n /**\n * 获取最近成交记录\n * @param symbol 交易对符号\n * @param limit 最大成交记录数\n * @returns 成交记录数组\n * @throws {HyperliquidApiError} API 请求失败\n */\n async getRecentTrades(symbol: string, limit: number = 50): Promise<Trade[]> {\n const coin = this.symbolToCoin(symbol);\n\n const data = await this.request<\n Array<{\n coin: string;\n side: string;\n px: string;\n sz: string;\n time: number;\n tid: number;\n }>\n >(\"/info\", { type: \"recentTrades\", coin });\n\n return data.slice(0, limit).map((trade) => ({\n symbol,\n side: trade.side === \"B\" ? \"buy\" : \"sell\",\n price: parseFloat(trade.px),\n quantity: parseFloat(trade.sz),\n timestamp: trade.time,\n tradeId: trade.tid,\n }));\n }\n\n // ===================================\n // 交易操作接口(2个方法)\n // ===================================\n\n /**\n * 下单(买入或卖出合约)\n *\n * ⚠️ 注意:此方法需要配置钱包私钥进行 EIP-712 签名认证\n *\n * @param params 下单参数\n * @returns 下单结果\n * @throws {HyperliquidApiError} API 请求失败、余额不足、参数错误等\n * @throws {Error} 未配置认证信息\n *\n * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint\n */\n async placeOrder(_params: PlaceOrderParams): Promise<PlaceOrderResult> {\n throw new Error(\n \"placeOrder() requires wallet private key configuration for EIP-712 signature. \" +\n \"Please configure authentication before calling this method. \" +\n \"See: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint\",\n );\n }\n\n /**\n * 取消订单\n *\n * ⚠️ 注意:此方法需要配置钱包私钥进行 EIP-712 签名认证\n *\n * @param params 取消订单参数\n * @returns 取消订单结果\n * @throws {HyperliquidApiError} API 请求失败、订单不存在等\n * @throws {Error} 未配置认证信息\n *\n * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint\n */\n async cancelOrder(_params: CancelOrderParams): Promise<CancelOrderResult> {\n throw new Error(\n \"cancelOrder() requires wallet private key configuration for EIP-712 signature. \" +\n \"Please configure authentication before calling this method. \" +\n \"See: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint\",\n );\n }\n\n // ===================================\n // 账户查询接口(3个方法)\n // ===================================\n\n /**\n * 获取用户持仓信息\n *\n * ⚠️ Hyperliquid 要求:必须提供 userAddress 参数\n *\n * @param params 查询参数\n * @returns 持仓结果\n * @throws {HyperliquidApiError} API 请求失败\n * @throws {Error} 缺少必需参数\n */\n async getPositions(\n params: GetPositionsParams = {},\n ): Promise<GetPositionsResult> {\n if (!params.userAddress) {\n throw new Error(\n \"Hyperliquid requires userAddress parameter. \" +\n \"Example: { userAddress: '0x...' }\",\n );\n }\n\n const data = await this.request<{\n assetPositions: Array<{\n position: {\n coin: string;\n szi: string;\n leverage: { type: string; value: number };\n entryPx: string;\n positionValue: string;\n unrealizedPnl: string;\n returnOnEquity: string;\n liquidationPx: string | null;\n marginUsed: string;\n };\n }>;\n marginSummary: {\n accountValue: string;\n totalMarginUsed: string;\n totalNtlPos: string;\n totalRawUsd: string;\n };\n crossMarginSummary: {\n accountValue: string;\n totalMarginUsed: string;\n totalNtlPos: string;\n totalRawUsd: string;\n };\n }>(\"/info\", { type: \"clearinghouseState\", user: params.userAddress });\n\n // 转换持仓数据\n const positions = data.assetPositions\n .map((assetPos) => {\n const pos = assetPos.position;\n const symbol = `${pos.coin}-USDC`;\n const quantity = parseFloat(pos.szi);\n\n // 数量为 0 表示没有持仓\n if (quantity === 0) {\n return null;\n }\n\n const entryPrice = parseFloat(pos.entryPx);\n const unrealizedPnl = parseFloat(pos.unrealizedPnl);\n const positionValue = parseFloat(pos.positionValue);\n\n return {\n symbol,\n side: quantity > 0 ? (\"long\" as const) : (\"short\" as const),\n quantity: Math.abs(quantity),\n entryPrice,\n markPrice: entryPrice, // Hyperliquid 不直接提供,可从 assetCtxs 获取\n unrealizedPnl,\n unrealizedPnlPercent: parseFloat(pos.returnOnEquity) * 100,\n leverage: pos.leverage.value,\n liquidationPrice: pos.liquidationPx\n ? parseFloat(pos.liquidationPx)\n : undefined,\n margin: parseFloat(pos.marginUsed),\n notionalValue: Math.abs(positionValue),\n };\n })\n .filter(Boolean) as any[];\n\n // 过滤指定币种\n const filteredPositions = params.symbol\n ? positions.filter((p) => p.symbol === params.symbol)\n : positions;\n\n return {\n positions: filteredPositions,\n totalEquity: parseFloat(data.marginSummary.accountValue),\n availableBalance:\n parseFloat(data.marginSummary.accountValue) -\n parseFloat(data.marginSummary.totalMarginUsed),\n totalUnrealizedPnl: filteredPositions.reduce(\n (sum, p) => sum + p.unrealizedPnl,\n 0,\n ),\n raw: data,\n };\n }\n\n /**\n * 获取用户挂单信息\n *\n * ⚠️ Hyperliquid 要求:必须提供 userAddress 参数\n *\n * @param params 查询参数\n * @returns 挂单结果\n * @throws {HyperliquidApiError} API 请求失败\n * @throws {Error} 缺少必需参数\n */\n async getOpenOrders(\n params: GetOpenOrdersParams = {},\n ): Promise<GetOpenOrdersResult> {\n if (!params.userAddress) {\n throw new Error(\n \"Hyperliquid requires userAddress parameter. \" +\n \"Example: { userAddress: '0x...' }\",\n );\n }\n\n const data = await this.request<\n Array<{\n coin: string;\n side: boolean;\n limitPx: string;\n sz: string;\n origSz: string;\n oid: number;\n cloid?: string;\n timestamp: number;\n orderType: any;\n }>\n >(\"/info\", { type: \"openOrders\", user: params.userAddress });\n\n // 转换订单数据\n const orders = data.map((order) => {\n const symbol = `${order.coin}-USDC`;\n const origSz = parseFloat(order.origSz);\n const remainingSz = parseFloat(order.sz);\n const filledSz = origSz - remainingSz;\n\n return {\n orderId: order.oid.toString(),\n clientOrderId: order.cloid,\n symbol,\n side: order.side ? (\"long\" as const) : (\"short\" as const),\n orderType: \"limit\" as const,\n price: parseFloat(order.limitPx),\n quantity: origSz,\n filledQuantity: filledSz,\n remainingQuantity: remainingSz,\n status: (filledSz > 0 && remainingSz > 0\n ? \"partially_filled\"\n : \"pending\") as any,\n timestamp: order.timestamp,\n updateTimestamp: order.timestamp,\n };\n });\n\n // 过滤指定币种\n const filteredOrders = params.symbol\n ? orders.filter((o) => o.symbol === params.symbol)\n : orders;\n\n return {\n orders: filteredOrders,\n totalCount: filteredOrders.length,\n raw: data,\n };\n }\n\n /**\n * 获取用户交易历史\n *\n * ⚠️ Hyperliquid 要求:必须提供 userAddress 参数\n *\n * @param params 查询参数\n * @returns 交易历史结果\n * @throws {HyperliquidApiError} API 请求失败\n * @throws {Error} 缺少必需参数\n */\n async getTrades(params: GetTradesParams = {}): Promise<GetTradesResult> {\n if (!params.userAddress) {\n throw new Error(\n \"Hyperliquid requires userAddress parameter. \" +\n \"Example: { userAddress: '0x...' }\",\n );\n }\n\n const data = await this.request<\n Array<{\n coin: string;\n side: string;\n px: string;\n sz: string;\n time: number;\n dir: string;\n oid: number;\n tid: number;\n fee?: string;\n feeToken?: string;\n }>\n >(\"/info\", { type: \"userFills\", user: params.userAddress });\n\n // 转换交易数据\n let trades = data.map((fill) => {\n const symbol = `${fill.coin}-USDC`;\n const isLong = fill.dir.includes(\"Long\");\n\n return {\n tradeId: fill.tid.toString(),\n orderId: fill.oid.toString(),\n symbol,\n side: isLong ? (\"long\" as const) : (\"short\" as const),\n price: parseFloat(fill.px),\n quantity: parseFloat(fill.sz),\n fee: parseFloat(fill.fee || \"0\"),\n feeCurrency: fill.feeToken || \"USDC\",\n isMaker: fill.side === \"M\", // \"M\" = Maker, \"T\" = Taker\n timestamp: fill.time,\n };\n });\n\n // 过滤指定币种\n if (params.symbol) {\n trades = trades.filter((t) => t.symbol === params.symbol);\n }\n\n // 过滤时间范围\n if (params.startTime) {\n trades = trades.filter((t) => t.timestamp >= params.startTime!);\n }\n if (params.endTime) {\n trades = trades.filter((t) => t.timestamp <= params.endTime!);\n }\n\n // 限制返回数量\n if (params.limit) {\n trades = trades.slice(0, params.limit);\n }\n\n return {\n trades,\n totalCount: trades.length,\n raw: data,\n };\n }\n\n // ===================================\n // WebSocket 连接管理(2个方法)\n // ===================================\n\n /**\n * Connect to WebSocket server\n *\n * Establishes WebSocket connection for real-time data streaming.\n * Connection will auto-reconnect on disconnect.\n *\n * @throws {Error} Connection failed\n */\n async connectWebSocket(): Promise<void> {\n this.wsRefCount += 1;\n if (!this.wsManager) {\n this.wsManager = new WebSocketManager(this._wsEndpoint);\n }\n\n if (this.wsManager.isConnectedNow()) {\n return;\n }\n\n await this.wsManager.connect();\n }\n\n /**\n * Disconnect from WebSocket server\n *\n * Decrements the consumer ref count. The underlying socket is closed\n * only when the last consumer disconnects, so concurrent widgets\n * (order book, trades, ticker) can mount/unmount independently\n * without stealing each other's stream.\n */\n disconnectWebSocket(): void {\n this.wsRefCount = Math.max(0, this.wsRefCount - 1);\n if (this.wsRefCount === 0 && this.wsManager) {\n this.wsManager.disconnect();\n this.wsManager = null;\n }\n }\n\n // ===================================\n // WebSocket 订阅(4个方法)\n // ===================================\n\n /**\n * Subscribe to market data (price, trades, order book)\n *\n * @param type Subscription type: 'ticker' | 'trades' | 'orderBook'\n * @param symbol Trading pair symbol (e.g., \"BTC-USDC\")\n * @param callback Data callback function\n * @returns Subscription ID (for unsubscribing)\n */\n subscribeMarketData(\n type: \"ticker\" | \"trades\" | \"orderBook\",\n symbol: string,\n callback: (data: any) => void,\n ): string {\n if (!this.wsManager) {\n throw new Error(\n \"WebSocket not connected. Call connectWebSocket() first.\",\n );\n }\n\n return this.wsManager.subscribe(type, symbol, callback);\n }\n\n /**\n * Subscribe to kline (candlestick) data\n *\n * @param symbol Trading pair symbol (e.g., \"BTC-USDC\")\n * @param interval Time interval (e.g., \"1m\", \"1h\", \"1d\")\n * @param callback Data callback function\n * @returns Subscription ID (for unsubscribing)\n */\n subscribeCandles(\n symbol: string,\n interval: KlineInterval,\n callback: (candle: Kline) => void,\n ): string {\n if (!this.wsManager) {\n throw new Error(\n \"WebSocket not connected. Call connectWebSocket() first.\",\n );\n }\n\n // Combine symbol and interval as parameter\n const param = `${symbol}:${interval}`;\n return this.wsManager.subscribe(\"candle\", param, callback);\n }\n\n /**\n * Subscribe to user data (orders, positions, fills)\n *\n * @param type Subscription type: 'orders' | 'positions' | 'fills'\n * @param userAddress User wallet address\n * @param callback Data callback function\n * @returns Subscription ID (for unsubscribing)\n */\n subscribeUserData(\n type: \"orders\" | \"positions\" | \"fills\",\n userAddress: string,\n callback: (data: any) => void,\n ): string {\n if (!this.wsManager) {\n throw new Error(\n \"WebSocket not connected. Call connectWebSocket() first.\",\n );\n }\n\n // Use userEvents for orders and positions, userFills for fills\n const subscriptionType = type === \"fills\" ? \"userFills\" : \"userEvents\";\n\n return this.wsManager.subscribe(subscriptionType, userAddress, callback);\n }\n\n /**\n * Unsubscribe from a data stream\n *\n * @param subscriptionId Subscription ID returned from subscribe methods\n */\n unsubscribe(subscriptionId: string): void {\n if (this.wsManager) {\n this.wsManager.unsubscribe(subscriptionId);\n }\n }\n}\n\n/**\n * Hyperliquid API 错误类\n */\nexport class HyperliquidApiError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number,\n public readonly responseBody: string,\n ) {\n super(message);\n this.name = \"HyperliquidApiError\";\n }\n}\n","/**\n * Shared REST transport for every LiberFi perpetuals-server client.\n *\n * Pulled out of `LiberFiPerpetualsClient` so the deposit client (and any\n * future feature client) can reuse the same fetch-with-timeout, error\n * mapping, and header merging logic without copy-paste.\n *\n * Design choices:\n *\n * - The class is intentionally minimal: build URL → fire fetch →\n * decode JSON → throw a typed error on non-2xx. No retries, no\n * circuit breaker, no caching. That layering belongs to the caller\n * (e.g. TanStack Query handles retries/cache).\n *\n * - Custom query parameters are passed per-request, not per-instance,\n * except for `defaultQuery` which the perpetuals client uses for the\n * `?provider=` selector.\n *\n * - Headers merge in three layers (call > instance > built-in). This\n * lets a caller add a one-off `Authorization` for a single request\n * without leaking it into the rest of the session.\n */\n\n/**\n * Thrown when perpetuals-server returns a non-2xx HTTP status, when the\n * request times out, or when the network call fails outright.\n *\n * `statusCode` is the HTTP status (or `0` for network errors / `408`\n * for client-side timeouts). `responseBody` is the verbatim response\n * text — useful for surfacing backend error codes to the user.\n */\nexport class LiberFiApiError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number,\n public readonly responseBody: string,\n ) {\n super(message);\n this.name = \"LiberFiApiError\";\n }\n}\n\n/** Configuration for {@link LiberFiHttpTransport}. */\nexport interface LiberFiHttpTransportConfig {\n /**\n * REST base URL, with NO trailing slash. The transport strips trailing\n * slashes on construction so callers can pass either form.\n */\n baseUrl: string;\n\n /** Per-request timeout in milliseconds. Defaults to 30 000 ms. */\n timeout?: number;\n\n /**\n * Headers merged into every request. Per-request headers (passed to\n * `request()`) win on key collision, then instance headers, then the\n * built-in `Accept` / `Content-Type`.\n */\n headers?: Record<string, string>;\n\n /**\n * Default query parameters appended to every request URL. Useful for\n * cross-cutting selectors like `?provider=hyperliquid`. Per-request\n * params override on key collision.\n */\n defaultQuery?: Record<string, string | undefined>;\n\n /**\n * Custom `fetch` implementation. Defaults to the global `fetch`.\n * Useful in tests (drop in a jest mock) or in environments where a\n * pre-configured fetch (e.g. with circuit breaker / proxy) is supplied\n * by the host application.\n */\n fetchImpl?: typeof fetch;\n}\n\n/** HTTP method shape — keep narrow; deposit and trading both use these. */\nexport type LiberFiHttpMethod = \"GET\" | \"POST\";\n\n/** Per-request options accepted by {@link LiberFiHttpTransport.request}. */\nexport interface RequestOptions {\n /** Path relative to `baseUrl` (must start with `/`). */\n path: string;\n /** Optional query string parameters. Undefined / empty values are skipped. */\n query?: Record<string, string | undefined>;\n /** JSON body for POST/PUT/etc. */\n body?: unknown;\n /** One-off headers — overrides the instance defaults. */\n headers?: Record<string, string>;\n /**\n * Override the per-instance timeout for this single request.\n * Use for fast-path reads or long-running submits.\n */\n timeoutMs?: number;\n}\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\n/**\n * Stateless HTTP transport shared by every LiberFi perpetuals-server\n * client. Construct one per client (or one shared instance — the class\n * is safe for concurrent use).\n */\nexport class LiberFiHttpTransport {\n private readonly baseUrl: string;\n private readonly timeout: number;\n private readonly headers?: Record<string, string>;\n private readonly defaultQuery?: Record<string, string | undefined>;\n private readonly fetchImpl: typeof fetch;\n\n constructor(config: LiberFiHttpTransportConfig) {\n if (!config.baseUrl) {\n throw new Error(\n \"LiberFiHttpTransport: `baseUrl` is required (e.g. https://api.liberfi.io/perpetuals).\",\n );\n }\n this.baseUrl = config.baseUrl.replace(/\\/+$/, \"\");\n this.timeout = config.timeout ?? DEFAULT_TIMEOUT_MS;\n this.headers = config.headers;\n this.defaultQuery = config.defaultQuery;\n // Bind so `fetch` can be `globalThis.fetch` (which requires `this`\n // to be the realm's globalThis, not the transport instance).\n this.fetchImpl = config.fetchImpl ?? globalThis.fetch.bind(globalThis);\n }\n\n /** Read-only accessor used by the perpetuals client for WebSocket fallback. */\n getBaseUrl(): string {\n return this.baseUrl;\n }\n\n /** Build a fully-qualified URL with merged query string. */\n buildUrl(path: string, query?: Record<string, string | undefined>): string {\n const params = new URLSearchParams();\n if (this.defaultQuery) {\n for (const [key, value] of Object.entries(this.defaultQuery)) {\n if (value === undefined || value === \"\") continue;\n params.set(key, value);\n }\n }\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === \"\") continue;\n params.set(key, value);\n }\n }\n const qs = params.toString();\n return `${this.baseUrl}${path}${qs ? `?${qs}` : \"\"}`;\n }\n\n /**\n * Issue an HTTP request and decode the JSON response. Returns\n * `undefined` (cast to T) for `204 No Content`. Throws\n * {@link LiberFiApiError} on every non-2xx, timeout, or network error.\n */\n async request<T>(\n method: LiberFiHttpMethod,\n opts: RequestOptions,\n ): Promise<T> {\n const url = this.buildUrl(opts.path, opts.query);\n const controller = new AbortController();\n const timeoutMs = opts.timeoutMs ?? this.timeout;\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n const response = await this.fetchImpl(url, {\n method,\n headers: {\n Accept: \"application/json\",\n ...(method === \"POST\" ? { \"Content-Type\": \"application/json\" } : {}),\n ...this.headers,\n ...opts.headers,\n },\n body: method === \"POST\" ? JSON.stringify(opts.body ?? {}) : undefined,\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const text = await safeText(response);\n throw new LiberFiApiError(\n `HTTP ${response.status} ${response.statusText} from ${method} ${url}`,\n response.status,\n text,\n );\n }\n\n if (response.status === 204) return undefined as T;\n return (await response.json()) as T;\n } catch (err: unknown) {\n if (err instanceof LiberFiApiError) throw err;\n if (err instanceof Error && err.name === \"AbortError\") {\n throw new LiberFiApiError(\n `Request timeout after ${timeoutMs}ms: ${method} ${url}`,\n 408,\n \"\",\n );\n }\n const message = err instanceof Error ? err.message : String(err);\n throw new LiberFiApiError(\n `Network error: ${method} ${url}: ${message}`,\n 0,\n \"\",\n );\n } finally {\n clearTimeout(timeoutId);\n }\n }\n}\n\nasync function safeText(response: Response): Promise<string> {\n try {\n return await response.text();\n } catch {\n return \"\";\n }\n}\n","import type {\n IPerpetualsClient,\n MarketData,\n Kline,\n KlineInterval,\n OrderBook,\n Trade,\n PlaceOrderParams,\n PlaceOrderResult,\n CancelOrderParams,\n CancelOrderResult,\n GetPositionsParams,\n GetPositionsResult,\n GetOpenOrdersParams,\n GetOpenOrdersResult,\n GetTradesParams,\n GetTradesResult,\n Position,\n Order,\n TradeHistory,\n} from \"../../types\";\nimport { WebSocketManager } from \"../hyperliquid/WebSocketManager\";\nimport { LiberFiHttpTransport, LiberFiApiError } from \"./transport\";\n\n// Re-export the error so existing consumers continue to import it from\n// the perpetuals-client module.\nexport { LiberFiApiError };\n\n// ===== Public configuration ===================================================\n\n/**\n * `signTypedData` is invoked once per place / cancel during the\n * `prepare → submit` flow. The hosting app injects this so the user's wallet\n * (privy / wagmi / etc.) controls the keys — perpetuals-server never sees them.\n *\n * The `typedData` argument is the EIP-712 envelope returned verbatim by the\n * server. The function must return the resulting compact signature as a\n * `0x`-prefixed hex string.\n */\nexport type SignTypedDataFn = (\n typedData: Record<string, unknown>,\n) => Promise<`0x${string}`>;\n\n/** Configuration for {@link LiberFiPerpetualsClient}. */\nexport interface LiberFiPerpetualsClientConfig {\n /**\n * REST base URL, with NO trailing slash. Examples:\n * - Local dev: `http://localhost:8080`\n * - Staging: `https://api.liberfi.io/staging/perpetuals`\n * - Production: `https://api.liberfi.io/perpetuals`\n *\n * The client appends `/v1/...` paths to this value. Required UNLESS a\n * pre-built {@link LiberFiHttpTransport} is supplied via `transport`,\n * in which case the transport's baseUrl is used.\n */\n baseUrl?: string;\n\n /**\n * Optional WebSocket endpoint. Real-time data is NOT proxied by\n * perpetuals-server today — the WS subscription methods connect directly to\n * the upstream exchange. Defaults to Hyperliquid mainnet.\n */\n wsEndpoint?: string;\n\n /**\n * EIP-712 signer injected by the hosting app. REQUIRED for `placeOrder` /\n * `cancelOrder`; read-only methods work without it.\n */\n signTypedData?: SignTypedDataFn;\n\n /**\n * Per-request timeout in milliseconds. Defaults to 30 000 ms.\n * Ignored when `transport` is provided (the transport carries its own).\n */\n timeout?: number;\n\n /**\n * Optional provider override sent as `?provider=...`. Defaults to the server\n * configuration (currently `hyperliquid`). Only set this when the gateway\n * has multiple providers configured and you want a non-default one.\n */\n provider?: string;\n\n /**\n * Optional extra request headers (auth tokens, tracing, etc.) merged into\n * every fetch. Ignored when `transport` is provided.\n */\n headers?: Record<string, string>;\n\n /**\n * Inject a pre-built transport instead of letting the client construct\n * one from `baseUrl` / `timeout` / `headers`. Required when sharing a\n * single transport with the deposit client to halve the per-call\n * configuration footprint in `PerpetualsProvider`.\n */\n transport?: LiberFiHttpTransport;\n}\n\nconst DEFAULT_WS_ENDPOINT = \"wss://api.hyperliquid.xyz/ws\";\n\n// ===== Server-side wire types (mirror perpetuals-server/internal/domain) =======\n//\n// These intentionally use snake-free camelCase exactly matching the Go\n// `json:\"…\"` tags. They are kept private so consumers depend only on the\n// stable IPerpetualsClient surface above.\n\ninterface CoinDTO {\n symbol: string;\n name: string;\n tickSize?: number;\n stepSize?: number;\n minOrderSize?: number;\n maxLeverage?: number;\n}\n\ntype MarketDTO = MarketData;\ntype OrderBookDTO = OrderBook;\ntype TradeDTO = Trade;\ntype KlineDTO = Kline;\n\ninterface AccountDTO {\n totalEquity: number;\n availableBalance: number;\n totalUnrealizedPnl: number;\n usedMargin?: number;\n accountLeverage?: number;\n}\n\ninterface PositionsResultDTO {\n positions: Position[];\n account?: AccountDTO;\n}\n\ntype OrderDTO = Order;\n\ninterface UserFillDTO {\n tradeId: string;\n orderId: string;\n symbol: string;\n side: \"long\" | \"short\";\n price: number;\n quantity: number;\n fee: number;\n feeCurrency: string;\n isMaker: boolean;\n timestamp: number;\n}\n\ninterface PreparedActionDTO {\n typedData: Record<string, unknown>;\n action: Record<string, unknown>;\n nonce: number;\n vaultAddress?: string;\n}\n\ntype PlaceOrderResultDTO = PlaceOrderResult;\ntype CancelOrderResultDTO = CancelOrderResult;\n\n// ===== Implementation ============================================================\n\n/**\n * REST + injected-signer implementation of {@link IPerpetualsClient} that talks\n * to a deployed `perpetuals-server` instead of Hyperliquid directly.\n *\n * - Read-only methods are plain `fetch GET`s.\n * - `placeOrder` / `cancelOrder` follow the two-phase flow:\n * 1. POST `…/prepare` → server builds upstream action + EIP-712 typed data.\n * 2. Host wallet signs `typedData` via the injected `signTypedData`.\n * 3. POST `…/submit` with the original `action`, the user signature, and\n * the server-issued `nonce`. The server forwards to upstream and\n * normalises the response.\n * - WebSocket subscriptions are NOT proxied through perpetuals-server today.\n * They reuse the existing {@link WebSocketManager} pointed at the upstream\n * exchange (`wsEndpoint`, default Hyperliquid mainnet).\n */\nexport class LiberFiPerpetualsClient implements IPerpetualsClient {\n private readonly transport: LiberFiHttpTransport;\n private readonly wsEndpoint: string;\n private readonly signTypedData?: SignTypedDataFn;\n private wsManager: WebSocketManager | null = null;\n /**\n * Reference count of active WebSocket consumers (one per React hook\n * instance). The underlying connection is opened lazily on the first\n * connect() call and torn down only when the last consumer leaves —\n * this prevents one widget's unmount from killing the live stream\n * other widgets (order book, trades, ticker) still depend on.\n */\n private wsRefCount = 0;\n\n constructor(config: LiberFiPerpetualsClientConfig) {\n // Two construction modes: legacy (baseUrl / timeout / headers) or\n // transport-injected. The deposit client constructor mirrors the\n // same pattern so both share a consistent shape.\n if (config.transport) {\n this.transport = config.transport;\n } else {\n if (!config.baseUrl) {\n throw new Error(\n \"LiberFiPerpetualsClient: either `baseUrl` or a pre-built `transport` is required.\",\n );\n }\n this.transport = new LiberFiHttpTransport({\n baseUrl: config.baseUrl,\n timeout: config.timeout,\n headers: config.headers,\n defaultQuery: config.provider\n ? { provider: config.provider }\n : undefined,\n });\n }\n this.wsEndpoint = config.wsEndpoint ?? DEFAULT_WS_ENDPOINT;\n this.signTypedData = config.signTypedData;\n }\n\n // ── IPerpetualsClient: market data ────────────────────────────────────────\n\n async getSupportedCoins(): Promise<string[]> {\n const coins = await this.transport.request<CoinDTO[]>(\"GET\", {\n path: \"/v1/coins\",\n });\n return coins.map((coin) => coin.symbol);\n }\n\n async getMarket(symbol: string): Promise<MarketData | null> {\n try {\n return await this.transport.request<MarketDTO>(\"GET\", {\n path: `/v1/markets/${encodeURIComponent(symbol)}`,\n });\n } catch (err) {\n if (err instanceof LiberFiApiError && err.statusCode === 404) return null;\n throw err;\n }\n }\n\n async getMarkets(symbols?: string[]): Promise<MarketData[]> {\n return this.transport.request<MarketDTO[]>(\"GET\", {\n path: \"/v1/markets\",\n query:\n symbols && symbols.length > 0\n ? { symbols: symbols.join(\",\") }\n : undefined,\n });\n }\n\n async getKlines(\n symbol: string,\n interval: KlineInterval,\n limit: number = 100,\n ): Promise<Kline[]> {\n return this.transport.request<KlineDTO[]>(\"GET\", {\n path: `/v1/markets/${encodeURIComponent(symbol)}/klines`,\n query: { interval, limit: String(limit) },\n });\n }\n\n async getOrderBook(\n symbol: string,\n maxLevel: number = 10,\n ): Promise<OrderBook> {\n return this.transport.request<OrderBookDTO>(\"GET\", {\n path: `/v1/markets/${encodeURIComponent(symbol)}/orderbook`,\n query: { maxLevel: String(maxLevel) },\n });\n }\n\n async getRecentTrades(symbol: string, limit: number = 50): Promise<Trade[]> {\n return this.transport.request<TradeDTO[]>(\"GET\", {\n path: `/v1/markets/${encodeURIComponent(symbol)}/trades`,\n query: { limit: String(limit) },\n });\n }\n\n // ── IPerpetualsClient: account ────────────────────────────────────────────\n\n async getPositions(\n params: GetPositionsParams = {},\n ): Promise<GetPositionsResult> {\n if (!params.userAddress) {\n throw new Error(\n \"LiberFiPerpetualsClient.getPositions requires `userAddress`.\",\n );\n }\n const result = await this.transport.request<PositionsResultDTO>(\"GET\", {\n path: `/v1/users/${encodeURIComponent(params.userAddress)}/positions`,\n query: { symbol: params.symbol },\n });\n\n return {\n positions: result.positions,\n totalEquity: result.account?.totalEquity,\n availableBalance: result.account?.availableBalance,\n totalUnrealizedPnl: result.account?.totalUnrealizedPnl,\n raw: result,\n };\n }\n\n async getOpenOrders(\n params: GetOpenOrdersParams = {},\n ): Promise<GetOpenOrdersResult> {\n if (!params.userAddress) {\n throw new Error(\n \"LiberFiPerpetualsClient.getOpenOrders requires `userAddress`.\",\n );\n }\n const orders = await this.transport.request<OrderDTO[]>(\"GET\", {\n path: `/v1/users/${encodeURIComponent(params.userAddress)}/orders`,\n query: { symbol: params.symbol },\n });\n return { orders, totalCount: orders.length, raw: orders };\n }\n\n async getTrades(params: GetTradesParams = {}): Promise<GetTradesResult> {\n if (!params.userAddress) {\n throw new Error(\n \"LiberFiPerpetualsClient.getTrades requires `userAddress`.\",\n );\n }\n const fills = await this.transport.request<UserFillDTO[]>(\"GET\", {\n path: `/v1/users/${encodeURIComponent(params.userAddress)}/fills`,\n query: {\n symbol: params.symbol,\n limit: params.limit !== undefined ? String(params.limit) : undefined,\n startTime:\n params.startTime !== undefined ? String(params.startTime) : undefined,\n endTime:\n params.endTime !== undefined ? String(params.endTime) : undefined,\n },\n });\n const trades: TradeHistory[] = fills.map((fill) => ({\n tradeId: fill.tradeId,\n orderId: fill.orderId,\n symbol: fill.symbol,\n side: fill.side,\n price: fill.price,\n quantity: fill.quantity,\n fee: fill.fee,\n feeCurrency: fill.feeCurrency,\n isMaker: fill.isMaker,\n timestamp: fill.timestamp,\n }));\n return { trades, totalCount: trades.length, raw: fills };\n }\n\n // ── IPerpetualsClient: trading (two-phase signing) ────────────────────────\n\n async placeOrder(params: PlaceOrderParams): Promise<PlaceOrderResult> {\n if (!this.signTypedData) {\n throw new Error(\n \"LiberFiPerpetualsClient.placeOrder requires `signTypedData` to be configured.\",\n );\n }\n if (!params.userAddress) {\n throw new Error(\n \"LiberFiPerpetualsClient.placeOrder requires `userAddress` (the signing wallet).\",\n );\n }\n\n const prepared = await this.transport.request<PreparedActionDTO>(\"POST\", {\n path: \"/v1/orders/prepare\",\n body: {\n userAddress: params.userAddress,\n symbol: params.symbol,\n side: params.side,\n orderType: params.orderType,\n amount: params.amount,\n price: params.price,\n leverage: params.leverage,\n reduceOnly: params.reduceOnly,\n takeProfitPrice: params.takeProfitPrice,\n stopLossPrice: params.stopLossPrice,\n clientOrderId: params.clientOrderId,\n },\n });\n\n const signature = await this.signTypedData(prepared.typedData);\n\n return this.transport.request<PlaceOrderResultDTO>(\"POST\", {\n path: \"/v1/orders/submit\",\n body: {\n action: prepared.action,\n signature,\n nonce: prepared.nonce,\n vaultAddress: prepared.vaultAddress,\n },\n });\n }\n\n async cancelOrder(params: CancelOrderParams): Promise<CancelOrderResult> {\n if (!this.signTypedData) {\n throw new Error(\n \"LiberFiPerpetualsClient.cancelOrder requires `signTypedData` to be configured.\",\n );\n }\n if (!params.userAddress) {\n throw new Error(\n \"LiberFiPerpetualsClient.cancelOrder requires `userAddress` (the signing wallet).\",\n );\n }\n\n const prepared = await this.transport.request<PreparedActionDTO>(\"POST\", {\n path: \"/v1/orders/cancel/prepare\",\n body: {\n userAddress: params.userAddress,\n symbol: params.symbol,\n orderId: params.orderId,\n clientOrderId: params.clientOrderId,\n },\n });\n\n const signature = await this.signTypedData(prepared.typedData);\n\n return this.transport.request<CancelOrderResultDTO>(\"POST\", {\n path: \"/v1/orders/cancel/submit\",\n body: {\n action: prepared.action,\n signature,\n nonce: prepared.nonce,\n vaultAddress: prepared.vaultAddress,\n },\n });\n }\n\n // ── IPerpetualsClient: WebSocket (direct upstream, NOT proxied) ───────────\n\n async connectWebSocket(): Promise<void> {\n this.wsRefCount += 1;\n if (!this.wsManager) {\n this.wsManager = new WebSocketManager(this.wsEndpoint);\n }\n if (this.wsManager.isConnectedNow()) return;\n await this.wsManager.connect();\n }\n\n disconnectWebSocket(): void {\n this.wsRefCount = Math.max(0, this.wsRefCount - 1);\n if (this.wsRefCount === 0 && this.wsManager) {\n this.wsManager.disconnect();\n this.wsManager = null;\n }\n }\n\n subscribeMarketData(\n type: \"ticker\" | \"trades\" | \"orderBook\",\n symbol: string,\n callback: (data: unknown) => void,\n ): string {\n return this.requireWS().subscribe(type, symbol, callback);\n }\n\n subscribeCandles(\n symbol: string,\n interval: KlineInterval,\n callback: (candle: Kline) => void,\n ): string {\n return this.requireWS().subscribe(\n \"candle\",\n `${symbol}:${interval}`,\n callback,\n );\n }\n\n subscribeUserData(\n type: \"orders\" | \"positions\" | \"fills\",\n userAddress: string,\n callback: (data: unknown) => void,\n ): string {\n const channel = type === \"fills\" ? \"userFills\" : \"userEvents\";\n return this.requireWS().subscribe(channel, userAddress, callback);\n }\n\n unsubscribe(subscriptionId: string): void {\n if (this.wsManager) {\n this.wsManager.unsubscribe(subscriptionId);\n }\n }\n\n private requireWS(): WebSocketManager {\n if (!this.wsManager) {\n throw new Error(\n \"WebSocket not connected. Call connectWebSocket() first.\",\n );\n }\n return this.wsManager;\n }\n}\n","/**\n * REST client for the Solana → Hyperliquid deposit endpoints exposed by\n * the perpetuals-server (`/v1/deposits/*`).\n *\n * Engineering principles:\n * - Single responsibility: this file knows about /v1/deposits and\n * nothing else. Quote orchestration, fee adapters, status\n * reconciliation, etc. live server-side.\n * - Modularity: the HTTP transport is injected (or built from a\n * baseUrl) so integration tests can drop in a fetch mock; production\n * code shares the same transport instance with `LiberFiPerpetualsClient`.\n * - First principles: three methods (quote / submit / status), no\n * hidden state, no caching. Polling is the caller's concern (the\n * hooks do it via TanStack Query).\n */\nimport type {\n DepositQuoteRequest,\n DepositQuoteResponse,\n DepositStatusResponse,\n DepositSubmitRequest,\n DepositSubmitResponse,\n} from \"./deposit-types\";\nimport {\n LiberFiHttpTransport,\n type LiberFiHttpTransportConfig,\n} from \"./transport\";\n\n/**\n * Options for constructing a `LiberFiPerpDepositClient`.\n *\n * Either provide a pre-built `transport` (preferred — share one with\n * `LiberFiPerpetualsClient` so connection limits, headers and timeouts\n * stay consistent) or pass the raw config and let the client build one.\n */\nexport type LiberFiPerpDepositClientConfig =\n | { transport: LiberFiHttpTransport }\n | LiberFiHttpTransportConfig;\n\n/** Public surface of the deposit client; matches the three handler endpoints. */\nexport interface IPerpDepositClient {\n /** POST /v1/deposits/quote */\n quote(req: DepositQuoteRequest): Promise<DepositQuoteResponse>;\n /** POST /v1/deposits/submit */\n submit(req: DepositSubmitRequest): Promise<DepositSubmitResponse>;\n /** GET /v1/deposits/{id} */\n status(intentId: string): Promise<DepositStatusResponse>;\n /** POST /v1/deposits/{id}/refresh — bypasses any future cache TTL. */\n refresh(intentId: string): Promise<DepositStatusResponse>;\n}\n\n/** Concrete implementation backed by `LiberFiHttpTransport`. */\nexport class LiberFiPerpDepositClient implements IPerpDepositClient {\n private readonly transport: LiberFiHttpTransport;\n\n constructor(config: LiberFiPerpDepositClientConfig) {\n this.transport =\n \"transport\" in config\n ? config.transport\n : new LiberFiHttpTransport(config);\n }\n\n /** Returns the base URL of the underlying transport (mostly for logs/diagnostics). */\n getBaseUrl(): string {\n return this.transport.getBaseUrl();\n }\n\n async quote(req: DepositQuoteRequest): Promise<DepositQuoteResponse> {\n return this.transport.request<DepositQuoteResponse>(\"POST\", {\n path: \"/v1/deposits/quote\",\n body: req,\n });\n }\n\n async submit(req: DepositSubmitRequest): Promise<DepositSubmitResponse> {\n return this.transport.request<DepositSubmitResponse>(\"POST\", {\n path: \"/v1/deposits/submit\",\n body: req,\n });\n }\n\n async status(intentId: string): Promise<DepositStatusResponse> {\n if (!intentId) throw new Error(\"intentId is required\");\n return this.transport.request<DepositStatusResponse>(\"GET\", {\n path: `/v1/deposits/${encodeURIComponent(intentId)}`,\n });\n }\n\n async refresh(intentId: string): Promise<DepositStatusResponse> {\n if (!intentId) throw new Error(\"intentId is required\");\n return this.transport.request<DepositStatusResponse>(\"POST\", {\n path: `/v1/deposits/${encodeURIComponent(intentId)}/refresh`,\n });\n }\n}\n","/**\n * Wire / domain types for the Solana → Hyperliquid USDC deposit flow.\n *\n * These deliberately mirror the perpetuals-server DTOs (see\n * `internal/handler/deposit_handler.go`) so the SDK <-> backend contract\n * stays in sync. When the backend adds a new field, add it here too —\n * the compiler will then point at every place that needs to handle it.\n *\n * All amounts denominated in *smallest unit* (lamports for SOL, USDC's\n * 6-decimal microUSDC for the destination side) are typed as `string` so\n * we never accidentally lose precision on large values.\n */\n\n/** Where the deposit was initiated from. Drives fee attribution server-side. */\nexport type DepositSource = \"dex\" | \"prediction\" | \"launchpad\" | \"channel\";\n\n/** Lifecycle states a deposit can be in. */\nexport type DepositStatus =\n | \"broadcasted\" // user signed + broadcast on Solana, server has not seen Relay yet\n | \"relay_waiting\" // Relay observed the deposit but hasn't started forwarding\n | \"relay_pending\" // Relay is forwarding the deposit cross-chain\n | \"settled\" // funds delivered to Hyperliquid\n | \"refunded\" // Relay refunded — funds returned to user wallet\n | \"failed\" // terminal failure\n | \"stuck\"; // observed > stuckAfter without Relay seeing it; ops review\n\n/** True for status values that never transition further. */\nexport const TERMINAL_DEPOSIT_STATUSES: ReadonlySet<DepositStatus> =\n new Set<DepositStatus>([\"settled\", \"refunded\", \"failed\"]);\n\n/** A single state transition in the status history. */\nexport interface DepositStatusTransition {\n from: DepositStatus | \"\";\n to: DepositStatus;\n at: string; // ISO 8601 timestamp\n source: \"handler\" | \"status_pull\" | \"reconciliation\" | string;\n reason?: string;\n}\n\n/** Surfaced when the upstream produced an unrecoverable error. */\nexport interface DepositErrorInfo {\n code: string;\n message: string;\n recoverable: boolean;\n}\n\n/** Exact-decimal breakdown returned by the quote endpoint. */\nexport interface DepositBreakdown {\n /** Total lamports the user is paying in (gross). */\n grossLamports: string;\n /** Platform fee transferred to the LiberFi treasury (lamports). */\n platformFeeLamports: string;\n /** Net amount Relay bridges (= gross − platformFee), in lamports. */\n relayDepositLamports: string;\n /** SOL pubkey the platform fee is sent to. May be empty when fee = 0. */\n treasuryAddress: string;\n /** Expected destination output, in microUSDC (6-decimal). May be empty. */\n expectedOutputUSDC?: string;\n /** Origin chain id (Solana mainnet on Relay = 792703809). */\n originChainId: number;\n /** Destination chain id (Hyperliquid). */\n destinationChainId: number;\n /** Origin currency. SOL is encoded as the SystemProgram pseudo-pubkey. */\n originCurrency: string;\n /** Destination currency contract. */\n destinationCurrency: string;\n /** Relay-issued depository address — the program/wallet receiving SOL. */\n depository?: string;\n /** Relay request id; populated once Relay returns a quote. */\n relayRequestId?: string;\n}\n\n/** Body of POST /v1/deposits/quote. */\nexport interface DepositQuoteRequest {\n userSolanaAddress: string;\n hyperliquidRecipient: string;\n /** Smallest-unit amount the user is paying in. */\n grossLamports: string;\n /** Fee attribution source. Defaults to `dex` server-side when empty. */\n source: DepositSource;\n}\n\n/** Response of POST /v1/deposits/quote. */\nexport interface DepositQuoteResponse {\n /** Base64 SOL transaction the user signs in their wallet. */\n serializedTxBase64: string;\n /** Transaction size on the wire (used by client-side guards). */\n sizeBytes: number;\n /** True for v0 transactions (legacy = false). */\n isVersioned: boolean;\n breakdown: DepositBreakdown;\n /** ISO 8601 timestamp the quote was issued at. */\n issuedAt: string;\n /** ISO 8601 timestamp the quote expires at. */\n expiresAt: string;\n}\n\n/** Body of POST /v1/deposits/submit. */\nexport interface DepositSubmitRequest {\n userSolanaAddress: string;\n hyperliquidRecipient: string;\n /** The signed transaction's hash, returned by the wallet on broadcast. */\n solanaTxHash: string;\n breakdown: DepositBreakdown;\n /** Stable user identifier (LiberFi user id, NOT the wallet address). */\n userId: string;\n source: DepositSource;\n /** Optional marketing campaign / referral code passed through to attribution. */\n campaign?: string;\n /** Mirror back the issuedAt from /quote so the server can guard freshness. */\n quoteIssuedAt: string;\n}\n\n/** Response of POST /v1/deposits/submit. */\nexport interface DepositSubmitResponse {\n intentId: string;\n /** True the first time a unique solanaTxHash is seen; idempotent retries return false. */\n created: boolean;\n}\n\n/** Response of GET /v1/deposits/{id}. */\nexport interface DepositStatusResponse {\n intentId: string;\n status: DepositStatus;\n userSolanaAddress: string;\n hyperliquidRecipient: string;\n solanaTxHash: string;\n relayRequestId?: string;\n hyperliquidTxHash?: string;\n breakdown: DepositBreakdown;\n statusHistory: DepositStatusTransition[];\n lastError?: DepositErrorInfo;\n userId: string;\n source: DepositSource;\n campaign?: string;\n createdAt: string;\n updatedAt: string;\n}\n","/**\n * Pure state machine for the deposit UI.\n *\n * The backend owns the *authoritative* lifecycle (broadcasted → relay_*\n * → settled / refunded / failed / stuck). The frontend has a few extra\n * states *before* we can call /submit (idle, quoting, ready_to_sign,\n * signing, broadcasting). We model both halves here as a single FSM so\n * presentational components can switch on a single tag.\n *\n * Engineering principles applied:\n * - First principles: a state is a *type*, transitions are pure\n * functions over (state, event) → state. No timers, no fetch, no\n * setState — those live in hooks.\n * - Single responsibility: this file knows nothing about HTTP, React,\n * or wallets. It is unit-testable in isolation.\n * - Extensibility: add a new event by extending DepositEvent + a case\n * in `reduceDepositState`. The compiler enforces exhaustiveness.\n */\nimport {\n type DepositBreakdown,\n type DepositErrorInfo,\n type DepositQuoteResponse,\n type DepositStatus,\n type DepositStatusResponse,\n TERMINAL_DEPOSIT_STATUSES,\n} from \"./deposit-types\";\n\n/** UI-only state tags. Server-driven tags are a subset of DepositStatus. */\nexport type DepositPhase =\n | \"idle\" // user hasn't requested a quote yet\n | \"quoting\" // /quote in flight\n | \"ready_to_sign\" // quote received, awaiting wallet signature\n | \"signing\" // wallet is signing\n | \"broadcasting\" // signed tx submitted to RPC, waiting for hash\n | \"submitted\" // /submit called, intentId returned\n | \"tracking\" // polling /status with a non-terminal lifecycle status\n | \"succeeded\" // terminal: settled\n | \"refunded\" // terminal: refunded\n | \"failed\" // terminal: failed | stuck (or any local error)\n | \"expired\"; // quote expired before user signed\n\n/** Discriminated union representing the entire deposit flow at any moment. */\nexport type DepositState =\n | { phase: \"idle\" }\n | { phase: \"quoting\" }\n | {\n phase: \"ready_to_sign\";\n quote: DepositQuoteResponse;\n /** Epoch ms — caller pre-computes for stable comparisons. */\n expiresAtMs: number;\n }\n | { phase: \"signing\"; quote: DepositQuoteResponse }\n | { phase: \"broadcasting\"; quote: DepositQuoteResponse }\n | {\n phase: \"submitted\";\n quote: DepositQuoteResponse;\n intentId: string;\n solanaTxHash: string;\n }\n | {\n phase: \"tracking\";\n intentId: string;\n status: DepositStatusResponse;\n }\n | {\n phase: \"succeeded\";\n intentId: string;\n status: DepositStatusResponse;\n }\n | {\n phase: \"refunded\";\n intentId: string;\n status: DepositStatusResponse;\n }\n | {\n phase: \"failed\";\n error: DepositErrorInfo;\n /** Populated when the failure happened post-submit. */\n intentId?: string;\n status?: DepositStatusResponse;\n }\n | { phase: \"expired\"; quote: DepositQuoteResponse };\n\n/** Events the FSM can react to. Driven by hooks/components. */\nexport type DepositEvent =\n | { type: \"RESET\" }\n | { type: \"QUOTE_REQUEST\" }\n | { type: \"QUOTE_RECEIVED\"; quote: DepositQuoteResponse }\n | { type: \"QUOTE_FAILED\"; error: DepositErrorInfo }\n | { type: \"QUOTE_EXPIRED\" }\n | { type: \"SIGN_START\" }\n | { type: \"SIGN_FAILED\"; error: DepositErrorInfo }\n | { type: \"BROADCAST_START\" }\n | { type: \"BROADCAST_FAILED\"; error: DepositErrorInfo }\n | {\n type: \"SUBMIT_OK\";\n intentId: string;\n solanaTxHash: string;\n }\n | { type: \"SUBMIT_FAILED\"; error: DepositErrorInfo }\n | { type: \"STATUS_UPDATE\"; status: DepositStatusResponse };\n\nexport const initialDepositState: DepositState = { phase: \"idle\" };\n\n/**\n * Transition function. Pure, total — every (state, event) pair is\n * handled. Unknown transitions are no-ops (return current state); we\n * don't throw because hooks may fan out events optimistically (e.g. a\n * stale STATUS_UPDATE arriving after RESET).\n */\nexport function reduceDepositState(\n state: DepositState,\n event: DepositEvent,\n): DepositState {\n switch (event.type) {\n case \"RESET\":\n return initialDepositState;\n\n case \"QUOTE_REQUEST\":\n // Allowed from idle, ready_to_sign (re-quote), expired, failed (retry).\n if (\n state.phase === \"idle\" ||\n state.phase === \"ready_to_sign\" ||\n state.phase === \"expired\" ||\n state.phase === \"failed\"\n ) {\n return { phase: \"quoting\" };\n }\n return state;\n\n case \"QUOTE_RECEIVED\":\n if (state.phase === \"quoting\") {\n return {\n phase: \"ready_to_sign\",\n quote: event.quote,\n expiresAtMs: Date.parse(event.quote.expiresAt),\n };\n }\n return state;\n\n case \"QUOTE_FAILED\":\n if (state.phase === \"quoting\") {\n return { phase: \"failed\", error: event.error };\n }\n return state;\n\n case \"QUOTE_EXPIRED\":\n if (state.phase === \"ready_to_sign\") {\n return { phase: \"expired\", quote: state.quote };\n }\n return state;\n\n case \"SIGN_START\":\n if (state.phase === \"ready_to_sign\") {\n return { phase: \"signing\", quote: state.quote };\n }\n return state;\n\n case \"SIGN_FAILED\":\n if (state.phase === \"signing\") {\n // Keep the quote so the UI can offer a retry without re-quoting.\n return { phase: \"failed\", error: event.error };\n }\n return state;\n\n case \"BROADCAST_START\":\n if (state.phase === \"signing\") {\n return { phase: \"broadcasting\", quote: state.quote };\n }\n return state;\n\n case \"BROADCAST_FAILED\":\n if (state.phase === \"broadcasting\" || state.phase === \"signing\") {\n return { phase: \"failed\", error: event.error };\n }\n return state;\n\n case \"SUBMIT_OK\":\n if (state.phase === \"broadcasting\") {\n return {\n phase: \"submitted\",\n quote: state.quote,\n intentId: event.intentId,\n solanaTxHash: event.solanaTxHash,\n };\n }\n return state;\n\n case \"SUBMIT_FAILED\":\n if (state.phase === \"broadcasting\") {\n return { phase: \"failed\", error: event.error };\n }\n return state;\n\n case \"STATUS_UPDATE\": {\n // /status is polled after submit. Map the backend status to the UI phase.\n if (state.phase !== \"submitted\" && state.phase !== \"tracking\") {\n return state;\n }\n const intentId =\n state.phase === \"submitted\" ? state.intentId : state.intentId;\n const next = mapStatusToPhase(event.status, intentId);\n return next;\n }\n }\n}\n\nfunction mapStatusToPhase(\n status: DepositStatusResponse,\n intentId: string,\n): DepositState {\n switch (status.status) {\n case \"settled\":\n return { phase: \"succeeded\", intentId, status };\n case \"refunded\":\n return { phase: \"refunded\", intentId, status };\n case \"failed\":\n case \"stuck\":\n return {\n phase: \"failed\",\n error: status.lastError ?? {\n code: status.status === \"stuck\" ? \"STUCK\" : \"FAILED\",\n message:\n status.status === \"stuck\"\n ? \"Deposit hasn't been observed by Relay yet — please contact support if this persists.\"\n : \"Deposit failed. Funds will be refunded to your wallet shortly.\",\n recoverable: false,\n },\n intentId,\n status,\n };\n case \"broadcasted\":\n case \"relay_waiting\":\n case \"relay_pending\":\n default:\n return { phase: \"tracking\", intentId, status };\n }\n}\n\n// =====================================================================\n// Selectors — the same data, but in a shape components can render.\n// Defining them here keeps the UI free of `if (state.phase === \"...\" )`\n// branching.\n// =====================================================================\n\n/** True when the FSM has reached a terminal phase. */\nexport function isTerminal(state: DepositState): boolean {\n return (\n state.phase === \"succeeded\" ||\n state.phase === \"refunded\" ||\n state.phase === \"failed\"\n );\n}\n\n/** True when the UI should keep polling /status. */\nexport function isPolling(state: DepositState): boolean {\n return state.phase === \"submitted\" || state.phase === \"tracking\";\n}\n\n/** Returns the current backend lifecycle status, if any. */\nexport function currentStatus(state: DepositState): DepositStatus | undefined {\n if (\n state.phase === \"tracking\" ||\n state.phase === \"succeeded\" ||\n state.phase === \"refunded\"\n ) {\n return state.status.status;\n }\n if (state.phase === \"failed\" && state.status) {\n return state.status.status;\n }\n return undefined;\n}\n\n/** Returns the breakdown the UI should display, if any. */\nexport function currentBreakdown(\n state: DepositState,\n): DepositBreakdown | undefined {\n if (\n state.phase === \"ready_to_sign\" ||\n state.phase === \"signing\" ||\n state.phase === \"broadcasting\" ||\n state.phase === \"submitted\" ||\n state.phase === \"expired\"\n ) {\n return state.quote.breakdown;\n }\n if (\n state.phase === \"tracking\" ||\n state.phase === \"succeeded\" ||\n state.phase === \"refunded\"\n ) {\n return state.status.breakdown;\n }\n if (state.phase === \"failed\" && state.status) {\n return state.status.breakdown;\n }\n return undefined;\n}\n\n/**\n * Returns true when the phase is terminal *and* corresponds to one of\n * the known DepositStatus terminal values. Useful for analytics fan-out\n * (only emit the funnel-end event once per intent).\n */\nexport function isTerminalLifecycle(\n status: DepositStatus | undefined,\n): boolean {\n return status !== undefined && TERMINAL_DEPOSIT_STATUSES.has(status);\n}\n","import { createContext } from \"react\";\nimport type { IPerpDepositClient } from \"../client/liberfi/LiberFiPerpDepositClient\";\nimport type { IPerpetualsClient } from \"../types\";\n\n/**\n * Perpetuals context value type\n *\n * Provides access to the perpetuals trading client and (optionally) the\n * deposit client. The deposit client is optional because not every\n * surface that consumes this provider also needs the deposit flow — a\n * portfolio view that only renders positions can omit it without\n * pulling the deposit dependency along.\n */\nexport interface PerpetualsContextValue {\n /**\n * Perpetuals client instance for trading operations.\n */\n client: IPerpetualsClient;\n\n /**\n * Deposit client instance for the Solana → Hyperliquid funding flow.\n *\n * Optional: surfaces that don't render the deposit UI can omit it.\n * Hooks that need it (e.g. `usePerpDepositQuote`) will throw a clear\n * error pointing at the missing prop.\n */\n depositClient?: IPerpDepositClient;\n}\n\n/**\n * Perpetuals Context\n *\n * React context for accessing perpetuals trading + deposit functionality\n * throughout the app.\n */\nexport const PerpetualsContext = createContext<PerpetualsContextValue>(\n {} as PerpetualsContextValue,\n);\n","import { PropsWithChildren, useMemo } from \"react\";\nimport {\n PerpetualsContext,\n PerpetualsContextValue,\n} from \"../context/PerpetualsContext\";\n\n/**\n * Perpetuals provider props type.\n *\n * `client` is required; `depositClient` is optional and only needed by\n * surfaces that render the cross-chain deposit flow.\n */\nexport type PerpetualsProviderProps = PropsWithChildren<PerpetualsContextValue>;\n\n/**\n * Perpetuals Provider Component.\n *\n * Wraps the perpetuals trading client and (optionally) the deposit\n * client into a single context value. The value is memoised on the\n * client identities so re-renders of the consumer app do not break\n * referential equality for downstream `useContext` consumers.\n *\n * @param props Provider props containing client(s) and children\n * @returns Provider component wrapping children\n */\nexport function PerpetualsProvider({\n client,\n depositClient,\n children,\n}: PerpetualsProviderProps) {\n const value = useMemo<PerpetualsContextValue>(\n () => ({ client, depositClient }),\n [client, depositClient],\n );\n return (\n <PerpetualsContext.Provider value={value}>\n {children}\n </PerpetualsContext.Provider>\n );\n}\n","import { useContext } from \"react\";\nimport {\n PerpetualsContext,\n PerpetualsContextValue,\n} from \"../context/PerpetualsContext\";\n\n/**\n * Hook to access perpetuals client from context\n *\n * Must be used within a PerpetualsProvider component\n *\n * @returns Perpetuals context value containing the client instance\n * @throws Error if used outside of PerpetualsProvider\n */\nexport function usePerpetualsClient(): PerpetualsContextValue {\n const context = useContext(PerpetualsContext);\n\n if (!context || !context.client) {\n throw new Error(\n \"usePerpetualsClient must be used within a PerpetualsProvider\",\n );\n }\n\n return context;\n}\n","import { useQuery, UseQueryOptions } from \"@tanstack/react-query\";\nimport type { IPerpetualsClient } from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport function coinsQueryKey(): string[] {\n return [\"perps\", \"coins\"];\n}\n\nexport async function fetchCoins(client: IPerpetualsClient): Promise<string[]> {\n return await client.getSupportedCoins();\n}\n\nexport function useCoinsQuery(\n options: Omit<\n UseQueryOptions<string[], Error, string[], string[]>,\n \"queryKey\" | \"queryFn\"\n > = {},\n) {\n const { client } = usePerpetualsClient();\n return useQuery({\n queryKey: coinsQueryKey(),\n queryFn: async () => fetchCoins(client),\n staleTime: 5 * 60 * 1000,\n ...options,\n });\n}\n","import { useQuery, UseQueryOptions } from \"@tanstack/react-query\";\nimport type { IPerpetualsClient, MarketData } from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport interface UseMarketQueryParams {\n symbol: string;\n}\n\nexport function marketQueryKey(params: UseMarketQueryParams): string[] {\n return [\"perps\", \"market\", params.symbol];\n}\n\nexport async function fetchMarket(\n client: IPerpetualsClient,\n { symbol }: UseMarketQueryParams,\n): Promise<MarketData | null> {\n return await client.getMarket(symbol);\n}\n\nexport function useMarketQuery(\n params: UseMarketQueryParams,\n options: Omit<\n UseQueryOptions<MarketData | null, Error, MarketData | null, string[]>,\n \"queryKey\" | \"queryFn\"\n > = {},\n) {\n const { client } = usePerpetualsClient();\n return useQuery({\n queryKey: marketQueryKey(params),\n queryFn: async () => fetchMarket(client, params),\n staleTime: 10 * 1000,\n ...options,\n });\n}\n","import { useQuery, UseQueryOptions } from \"@tanstack/react-query\";\nimport type { IPerpetualsClient, MarketData } from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport interface UseMarketsQueryParams {\n symbols?: string[];\n}\n\nexport function marketsQueryKey(params: UseMarketsQueryParams = {}): string[] {\n return [\"perps\", \"markets\", JSON.stringify((params.symbols ?? []).sort())];\n}\n\nexport async function fetchMarkets(\n client: IPerpetualsClient,\n { symbols }: UseMarketsQueryParams = {},\n): Promise<MarketData[]> {\n return await client.getMarkets(symbols);\n}\n\nexport function useMarketsQuery(\n params: UseMarketsQueryParams = {},\n options: Omit<\n UseQueryOptions<MarketData[], Error, MarketData[], string[]>,\n \"queryKey\" | \"queryFn\"\n > = {},\n) {\n const { client } = usePerpetualsClient();\n return useQuery({\n queryKey: marketsQueryKey(params),\n queryFn: async () => fetchMarkets(client, params),\n staleTime: 10 * 1000,\n ...options,\n });\n}\n","import { useQuery, UseQueryOptions } from \"@tanstack/react-query\";\nimport type { IPerpetualsClient, Kline, KlineInterval } from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport interface UseKlinesQueryParams {\n symbol: string;\n interval: KlineInterval;\n limit?: number;\n}\n\nexport function klinesQueryKey(params: UseKlinesQueryParams): string[] {\n return [\n \"perps\",\n \"klines\",\n params.symbol,\n params.interval,\n String(params.limit ?? 100),\n ];\n}\n\nexport async function fetchKlines(\n client: IPerpetualsClient,\n { symbol, interval, limit }: UseKlinesQueryParams,\n): Promise<Kline[]> {\n return await client.getKlines(symbol, interval, limit);\n}\n\nexport function useKlinesQuery(\n params: UseKlinesQueryParams,\n options: Omit<\n UseQueryOptions<Kline[], Error, Kline[], string[]>,\n \"queryKey\" | \"queryFn\"\n > = {},\n) {\n const { client } = usePerpetualsClient();\n return useQuery({\n queryKey: klinesQueryKey(params),\n queryFn: async () => fetchKlines(client, params),\n staleTime: 30 * 1000,\n ...options,\n });\n}\n","import { useQuery, UseQueryOptions } from \"@tanstack/react-query\";\nimport type { IPerpetualsClient, OrderBook } from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport interface UseOrderBookQueryParams {\n symbol: string;\n maxLevel?: number;\n}\n\nexport function orderBookQueryKey(params: UseOrderBookQueryParams): string[] {\n return [\"perps\", \"orderBook\", params.symbol, String(params.maxLevel ?? 20)];\n}\n\nexport async function fetchOrderBook(\n client: IPerpetualsClient,\n { symbol, maxLevel }: UseOrderBookQueryParams,\n): Promise<OrderBook> {\n return await client.getOrderBook(symbol, maxLevel);\n}\n\nexport function useOrderBookQuery(\n params: UseOrderBookQueryParams,\n options: Omit<\n UseQueryOptions<OrderBook, Error, OrderBook, string[]>,\n \"queryKey\" | \"queryFn\"\n > = {},\n) {\n const { client } = usePerpetualsClient();\n return useQuery({\n queryKey: orderBookQueryKey(params),\n queryFn: async () => fetchOrderBook(client, params),\n staleTime: 5 * 1000,\n ...options,\n });\n}\n","import { useQuery, UseQueryOptions } from \"@tanstack/react-query\";\nimport type { IPerpetualsClient, Trade } from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport interface UseRecentTradesQueryParams {\n symbol: string;\n limit?: number;\n}\n\nexport function recentTradesQueryKey(\n params: UseRecentTradesQueryParams,\n): string[] {\n return [\"perps\", \"recentTrades\", params.symbol, String(params.limit ?? 50)];\n}\n\nexport async function fetchRecentTrades(\n client: IPerpetualsClient,\n { symbol, limit }: UseRecentTradesQueryParams,\n): Promise<Trade[]> {\n return await client.getRecentTrades(symbol, limit);\n}\n\nexport function useRecentTradesQuery(\n params: UseRecentTradesQueryParams,\n options: Omit<\n UseQueryOptions<Trade[], Error, Trade[], string[]>,\n \"queryKey\" | \"queryFn\"\n > = {},\n) {\n const { client } = usePerpetualsClient();\n return useQuery({\n queryKey: recentTradesQueryKey(params),\n queryFn: async () => fetchRecentTrades(client, params),\n staleTime: 5 * 1000,\n ...options,\n });\n}\n","import { useQuery, UseQueryOptions } from \"@tanstack/react-query\";\nimport type {\n IPerpetualsClient,\n GetPositionsResult,\n GetPositionsParams,\n} from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport interface UsePositionsQueryParams extends GetPositionsParams {\n enabled?: boolean;\n}\n\nexport function positionsQueryKey(\n params: Omit<UsePositionsQueryParams, \"enabled\">,\n): string[] {\n return [\"perps\", \"positions\", params.userAddress ?? \"\", params.symbol ?? \"\"];\n}\n\nexport async function fetchPositions(\n client: IPerpetualsClient,\n params: GetPositionsParams,\n): Promise<GetPositionsResult> {\n return await client.getPositions(params);\n}\n\nexport function usePositionsQuery(\n params: UsePositionsQueryParams,\n options: Omit<\n UseQueryOptions<GetPositionsResult, Error, GetPositionsResult, string[]>,\n \"queryKey\" | \"queryFn\"\n > = {},\n) {\n const { client } = usePerpetualsClient();\n const { enabled = true, ...queryParams } = params;\n\n return useQuery({\n queryKey: positionsQueryKey(queryParams),\n queryFn: async () => fetchPositions(client, queryParams),\n enabled: enabled && !!queryParams.userAddress,\n staleTime: 10 * 1000,\n ...options,\n });\n}\n","import { useQuery, UseQueryOptions } from \"@tanstack/react-query\";\nimport type {\n IPerpetualsClient,\n GetOpenOrdersResult,\n GetOpenOrdersParams,\n} from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport interface UseOrdersQueryParams extends GetOpenOrdersParams {\n enabled?: boolean;\n}\n\nexport function ordersQueryKey(\n params: Omit<UseOrdersQueryParams, \"enabled\">,\n): string[] {\n return [\"perps\", \"orders\", params.userAddress ?? \"\", params.symbol ?? \"\"];\n}\n\nexport async function fetchOrders(\n client: IPerpetualsClient,\n params: GetOpenOrdersParams,\n): Promise<GetOpenOrdersResult> {\n return await client.getOpenOrders(params);\n}\n\nexport function useOrdersQuery(\n params: UseOrdersQueryParams,\n options: Omit<\n UseQueryOptions<GetOpenOrdersResult, Error, GetOpenOrdersResult, string[]>,\n \"queryKey\" | \"queryFn\"\n > = {},\n) {\n const { client } = usePerpetualsClient();\n const { enabled = true, ...queryParams } = params;\n\n return useQuery({\n queryKey: ordersQueryKey(queryParams),\n queryFn: async () => fetchOrders(client, queryParams),\n enabled: enabled && !!queryParams.userAddress,\n staleTime: 5 * 1000,\n ...options,\n });\n}\n","import { useQuery, UseQueryOptions } from \"@tanstack/react-query\";\nimport type {\n IPerpetualsClient,\n GetTradesResult,\n GetTradesParams,\n} from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport interface UseTradesQueryParams extends GetTradesParams {\n enabled?: boolean;\n}\n\nexport function tradesQueryKey(\n params: Omit<UseTradesQueryParams, \"enabled\">,\n): string[] {\n return [\n \"perps\",\n \"trades\",\n params.userAddress ?? \"\",\n params.symbol ?? \"\",\n String(params.limit ?? 50),\n String(params.startTime ?? \"\"),\n String(params.endTime ?? \"\"),\n ];\n}\n\nexport async function fetchTrades(\n client: IPerpetualsClient,\n params: GetTradesParams,\n): Promise<GetTradesResult> {\n return await client.getTrades(params);\n}\n\nexport function useTradesQuery(\n params: UseTradesQueryParams,\n options: Omit<\n UseQueryOptions<GetTradesResult, Error, GetTradesResult, string[]>,\n \"queryKey\" | \"queryFn\"\n > = {},\n) {\n const { client } = usePerpetualsClient();\n const { enabled = true, ...queryParams } = params;\n\n return useQuery({\n queryKey: tradesQueryKey(queryParams),\n queryFn: async () => fetchTrades(client, queryParams),\n enabled: enabled && !!queryParams.userAddress,\n staleTime: 30 * 1000,\n ...options,\n });\n}\n","import { useMutation, UseMutationOptions } from \"@tanstack/react-query\";\nimport type {\n IPerpetualsClient,\n PlaceOrderParams,\n PlaceOrderResult,\n} from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport type UseCreateOrderMutationParams = PlaceOrderParams;\n\nexport async function createOrder(\n client: IPerpetualsClient,\n params: UseCreateOrderMutationParams,\n): Promise<PlaceOrderResult> {\n return await client.placeOrder(params);\n}\n\nexport function useCreateOrderMutation(\n options: Omit<\n UseMutationOptions<PlaceOrderResult, Error, UseCreateOrderMutationParams>,\n \"mutationFn\"\n > = {},\n) {\n const { client } = usePerpetualsClient();\n return useMutation({\n mutationFn: async (params: UseCreateOrderMutationParams) =>\n createOrder(client, params),\n ...options,\n });\n}\n","import { useMutation, UseMutationOptions } from \"@tanstack/react-query\";\nimport type {\n IPerpetualsClient,\n CancelOrderParams,\n CancelOrderResult,\n} from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport type UseCancelOrderMutationParams = CancelOrderParams;\n\nexport async function cancelOrder(\n client: IPerpetualsClient,\n params: UseCancelOrderMutationParams,\n): Promise<CancelOrderResult> {\n return await client.cancelOrder(params);\n}\n\nexport function useCancelOrderMutation(\n options: Omit<\n UseMutationOptions<CancelOrderResult, Error, UseCancelOrderMutationParams>,\n \"mutationFn\"\n > = {},\n) {\n const { client } = usePerpetualsClient();\n return useMutation({\n mutationFn: async (params: UseCancelOrderMutationParams) =>\n cancelOrder(client, params),\n ...options,\n });\n}\n","import { useEffect, useState, useCallback } from \"react\";\nimport type { MarketData, Trade, OrderBook } from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport type MarketDataType = \"ticker\" | \"trades\" | \"orderBook\";\n\nexport interface UseMarketDataSubscriptionParams {\n type: MarketDataType;\n symbol: string;\n enabled?: boolean;\n}\n\nexport interface UseMarketDataSubscriptionResult<T> {\n data: T | null;\n isConnected: boolean;\n error: Error | null;\n}\n\nexport function useMarketDataSubscription<\n T = MarketDataType extends \"ticker\"\n ? MarketData\n : MarketDataType extends \"trades\"\n ? Trade\n : OrderBook,\n>(params: UseMarketDataSubscriptionParams): UseMarketDataSubscriptionResult<T> {\n const { type, symbol, enabled = true } = params;\n const { client } = usePerpetualsClient();\n const [data, setData] = useState<T | null>(null);\n const [isConnected, setIsConnected] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const handleData = useCallback((newData: T) => {\n setData(newData);\n }, []);\n\n useEffect(() => {\n if (!enabled) {\n return;\n }\n\n let subscriptionId: string | null = null;\n let isSubscribed = true;\n\n const connect = async () => {\n try {\n await client.connectWebSocket();\n\n if (!isSubscribed) return;\n\n setIsConnected(true);\n setError(null);\n\n subscriptionId = client.subscribeMarketData(type, symbol, handleData);\n } catch (err) {\n if (isSubscribed) {\n setError(err instanceof Error ? err : new Error(\"Connection failed\"));\n setIsConnected(false);\n }\n }\n };\n\n connect();\n\n return () => {\n isSubscribed = false;\n if (subscriptionId) {\n try {\n client.unsubscribe(subscriptionId);\n } catch (err) {\n console.error(\"Failed to unsubscribe:\", err);\n }\n }\n client.disconnectWebSocket();\n setIsConnected(false);\n setData(null);\n };\n }, [client, type, symbol, enabled, handleData]);\n\n return { data, isConnected, error };\n}\n","import { useEffect, useState, useCallback } from \"react\";\nimport type { Kline, KlineInterval } from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport interface UseCandlesSubscriptionParams {\n symbol: string;\n interval: KlineInterval;\n enabled?: boolean;\n}\n\nexport interface UseCandlesSubscriptionResult {\n data: Kline | null;\n isConnected: boolean;\n error: Error | null;\n}\n\nexport function useCandlesSubscription(\n params: UseCandlesSubscriptionParams,\n): UseCandlesSubscriptionResult {\n const { symbol, interval, enabled = true } = params;\n const { client } = usePerpetualsClient();\n const [data, setData] = useState<Kline | null>(null);\n const [isConnected, setIsConnected] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const handleData = useCallback((newData: Kline) => {\n setData(newData);\n }, []);\n\n useEffect(() => {\n if (!enabled) {\n return;\n }\n\n let subscriptionId: string | null = null;\n let isSubscribed = true;\n\n const connect = async () => {\n try {\n await client.connectWebSocket();\n\n if (!isSubscribed) return;\n\n setIsConnected(true);\n setError(null);\n\n subscriptionId = client.subscribeCandles(symbol, interval, handleData);\n } catch (err) {\n if (isSubscribed) {\n setError(err instanceof Error ? err : new Error(\"Connection failed\"));\n setIsConnected(false);\n }\n }\n };\n\n connect();\n\n return () => {\n isSubscribed = false;\n if (subscriptionId) {\n try {\n client.unsubscribe(subscriptionId);\n } catch (err) {\n console.error(\"Failed to unsubscribe:\", err);\n }\n }\n client.disconnectWebSocket();\n setIsConnected(false);\n setData(null);\n };\n }, [client, symbol, interval, enabled, handleData]);\n\n return { data, isConnected, error };\n}\n","import { useEffect, useState, useCallback } from \"react\";\nimport type { Order, Position, TradeHistory } from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport type UserDataType = \"orders\" | \"positions\" | \"fills\";\n\nexport interface UseUserDataSubscriptionParams {\n type: UserDataType;\n userAddress: string;\n enabled?: boolean;\n}\n\nexport interface UseUserDataSubscriptionResult<T> {\n data: T | null;\n isConnected: boolean;\n error: Error | null;\n}\n\nexport function useUserDataSubscription<\n T = UserDataType extends \"orders\"\n ? Order\n : UserDataType extends \"positions\"\n ? Position\n : TradeHistory,\n>(params: UseUserDataSubscriptionParams): UseUserDataSubscriptionResult<T> {\n const { type, userAddress, enabled = true } = params;\n const { client } = usePerpetualsClient();\n const [data, setData] = useState<T | null>(null);\n const [isConnected, setIsConnected] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const handleData = useCallback((newData: T) => {\n setData(newData);\n }, []);\n\n useEffect(() => {\n if (!enabled || !userAddress) {\n return;\n }\n\n let subscriptionId: string | null = null;\n let isSubscribed = true;\n\n const connect = async () => {\n try {\n await client.connectWebSocket();\n\n if (!isSubscribed) return;\n\n setIsConnected(true);\n setError(null);\n\n subscriptionId = client.subscribeUserData(\n type,\n userAddress,\n handleData,\n );\n } catch (err) {\n if (isSubscribed) {\n setError(err instanceof Error ? err : new Error(\"Connection failed\"));\n setIsConnected(false);\n }\n }\n };\n\n connect();\n\n return () => {\n isSubscribed = false;\n if (subscriptionId) {\n try {\n client.unsubscribe(subscriptionId);\n } catch (err) {\n console.error(\"Failed to unsubscribe:\", err);\n }\n }\n client.disconnectWebSocket();\n setIsConnected(false);\n setData(null);\n };\n }, [client, type, userAddress, enabled, handleData]);\n\n return { data, isConnected, error };\n}\n","import { useContext } from \"react\";\nimport type { IPerpDepositClient } from \"../client/liberfi/LiberFiPerpDepositClient\";\nimport { PerpetualsContext } from \"../context/PerpetualsContext\";\n\n/**\n * Hook to access the deposit client from `PerpetualsProvider`.\n *\n * Throws if the provider is missing OR if the host app forgot to pass\n * `depositClient`. The thrown message tells the consumer exactly what\n * to fix — preferring an explicit error to a silent runtime crash deep\n * inside a useQuery hook.\n *\n * @returns The deposit client instance.\n */\nexport function usePerpDepositClient(): IPerpDepositClient {\n const ctx = useContext(PerpetualsContext);\n if (!ctx || !ctx.client) {\n throw new Error(\n \"usePerpDepositClient must be used within a <PerpetualsProvider>.\",\n );\n }\n if (!ctx.depositClient) {\n throw new Error(\n \"usePerpDepositClient: <PerpetualsProvider> was rendered without a `depositClient` prop. \" +\n \"Pass a `LiberFiPerpDepositClient` instance to enable the deposit flow.\",\n );\n }\n return ctx.depositClient;\n}\n\n/**\n * Safe variant — returns `undefined` instead of throwing when\n * `depositClient` is not configured. Use this in hooks that should\n * degrade gracefully (e.g. query hooks that gate on `enabled`) rather\n * than crash when the deposit flow is not wired up.\n */\nexport function usePerpDepositClientMaybe(): IPerpDepositClient | undefined {\n const ctx = useContext(PerpetualsContext);\n return ctx?.depositClient;\n}\n","import { useQuery, UseQueryOptions } from \"@tanstack/react-query\";\nimport type { IPerpDepositClient } from \"../client/liberfi/LiberFiPerpDepositClient\";\nimport type {\n DepositQuoteRequest,\n DepositQuoteResponse,\n} from \"../client/liberfi/deposit-types\";\nimport { usePerpDepositClientMaybe } from \"./usePerpDepositClient\";\n\n/**\n * Stable query key shape for the deposit quote.\n *\n * The amount is part of the key so re-quoting on amount change does not\n * leak across users; the user/recipient pair is included so two users\n * sharing the same browser session don't see each other's quotes in the\n * cache.\n */\nexport function perpDepositQuoteQueryKey(\n req?: DepositQuoteRequest | null,\n): readonly unknown[] {\n return [\"perps\", \"deposit\", \"quote\", req] as const;\n}\n\n/** Pure fetcher — useful for SSR or for invoking outside React. */\nexport async function fetchPerpDepositQuote(\n client: IPerpDepositClient,\n req: DepositQuoteRequest,\n): Promise<DepositQuoteResponse> {\n return client.quote(req);\n}\n\nexport interface UsePerpDepositQuoteOptions extends Omit<\n UseQueryOptions<\n DepositQuoteResponse,\n Error,\n DepositQuoteResponse,\n ReturnType<typeof perpDepositQuoteQueryKey>\n >,\n \"queryKey\" | \"queryFn\" | \"enabled\"\n> {\n /**\n * Override automatic gating. By default the query runs when `req` is\n * fully populated. Pass `enabled: false` to defer firing while the\n * user is still typing the amount.\n */\n enabled?: boolean;\n}\n\n/**\n * Re-quotes on every parameter change, with TanStack Query handling\n * dedupe / refetch / cancellation. Caller is responsible for surfacing\n * `data.expiresAt` to the UI; the FSM will move to `expired` if the\n * user lingers past the deadline.\n *\n * Engineering note: the hook deliberately does NOT auto-refresh on a\n * timer. Re-quoting silently behind the user would erase the “Confirm”\n * button mid-action; the form should re-call `refetch()` on its own\n * cadence (e.g. when `expiresAt` is < 5 s from now).\n */\nexport function usePerpDepositQuote(\n req: DepositQuoteRequest | null | undefined,\n options: UsePerpDepositQuoteOptions = {},\n) {\n const client = usePerpDepositClientMaybe();\n const enabled =\n (options.enabled ?? Boolean(isQuoteReady(req))) && Boolean(client);\n return useQuery({\n queryKey: perpDepositQuoteQueryKey(req ?? null),\n queryFn: async () =>\n fetchPerpDepositQuote(client!, req as DepositQuoteRequest),\n enabled,\n staleTime: 0, // quotes are short-lived; never reuse silently\n gcTime: 30_000,\n refetchOnWindowFocus: false,\n ...options,\n });\n}\n\nfunction isQuoteReady(\n req: DepositQuoteRequest | null | undefined,\n): req is DepositQuoteRequest {\n return Boolean(\n req &&\n req.userSolanaAddress &&\n req.hyperliquidRecipient &&\n req.grossLamports &&\n req.source,\n );\n}\n","import { useCallback, useReducer } from \"react\";\nimport {\n type DepositEvent,\n type DepositState,\n initialDepositState,\n reduceDepositState,\n} from \"../client/liberfi/deposit-state-machine\";\nimport type {\n DepositErrorInfo,\n DepositQuoteResponse,\n DepositSource,\n DepositSubmitRequest,\n} from \"../client/liberfi/deposit-types\";\nimport { LiberFiApiError } from \"../client/liberfi/transport\";\nimport { usePerpDepositClientMaybe } from \"./usePerpDepositClient\";\n\n/**\n * Adapter the host app must provide. Lives on the consumer side so the\n * SDK never has to know how a particular wallet (Phantom / Backpack /\n * Privy / Solflare / …) signs and broadcasts a Solana transaction.\n *\n * Contract:\n * - Decode the `serializedTxBase64` produced by /quote.\n * - Have the user sign it (this is when the wallet UI shows up).\n * - Broadcast it. Return the resulting tx hash.\n * - Throw on user rejection or RPC failure.\n *\n * The SDK keeps things narrow: signature, broadcast, and \"did the wallet\n * succeed\" are the only outputs we care about. Everything else (RPC\n * endpoint, commitment, simulation pre-checks) is an implementation\n * detail the host already owns.\n */\nexport type SignAndBroadcastSolanaTx = (\n serializedTxBase64: string,\n ctx: { isVersioned: boolean; sizeBytes: number },\n) => Promise<string>;\n\n/** Inputs every deposit attempt needs. */\nexport interface ExecuteDepositInput {\n /** The quote previously returned by `/v1/deposits/quote`. */\n quote: DepositQuoteResponse;\n /** User-facing identifiers; must match what was sent to /quote. */\n userSolanaAddress: string;\n hyperliquidRecipient: string;\n /** LiberFi user id (NOT the wallet). Stable for fee attribution. */\n userId: string;\n source: DepositSource;\n /** Optional marketing / referral code. */\n campaign?: string;\n}\n\n/** Hook return shape — exposes the full FSM and a single trigger. */\nexport interface UsePerpDepositExecuteResult {\n state: DepositState;\n /**\n * Kick off the sign → broadcast → submit chain. Returns the eventual\n * `intentId` on success, throws on failure (the FSM will already be\n * in the `failed` phase with a descriptive `error`).\n */\n execute: (input: ExecuteDepositInput) => Promise<string>;\n /** Force back to `idle`. Use when the user dismisses the modal. */\n reset: () => void;\n /** Manually push an event into the FSM (advanced). */\n dispatch: (event: DepositEvent) => void;\n}\n\n/**\n * Orchestrates the full deposit flow:\n *\n * 1. SIGN_START → wallet signs (host adapter)\n * 2. BROADCAST_START → wallet broadcasts (host adapter)\n * 3. SUBMIT_OK → POST /v1/deposits/submit (this hook)\n * 4. STATUS_UPDATE ← `usePerpDepositStatus` polls and forwards\n *\n * Each stage emits a typed event into the same reducer used by the\n * presentational components. The hook itself never renders anything —\n * components consume `state.phase` and react accordingly.\n */\nexport function usePerpDepositExecute(\n signAndBroadcast: SignAndBroadcastSolanaTx,\n): UsePerpDepositExecuteResult {\n const client = usePerpDepositClientMaybe();\n const [state, dispatch] = useReducer(reduceDepositState, initialDepositState);\n\n const reset = useCallback(() => {\n dispatch({ type: \"RESET\" });\n }, []);\n\n const execute = useCallback<UsePerpDepositExecuteResult[\"execute\"]>(\n async (input) => {\n const { quote } = input;\n dispatch({ type: \"SIGN_START\" });\n let solanaTxHash: string;\n try {\n solanaTxHash = await signAndBroadcast(quote.serializedTxBase64, {\n isVersioned: quote.isVersioned,\n sizeBytes: quote.sizeBytes,\n });\n if (!solanaTxHash) {\n throw new Error(\"wallet returned an empty tx hash\");\n }\n } catch (err) {\n const info = toErrorInfo(err, \"WALLET_SIGN_OR_BROADCAST_FAILED\");\n // Distinguish sign vs broadcast: the FSM treats them the same\n // (both transition into `failed`) but we keep the original\n // event name for analytics correlation.\n dispatch({ type: \"SIGN_FAILED\", error: info });\n throw err;\n }\n\n // Optimistic broadcast → submit handshake. The FSM expects the\n // broadcast event before SUBMIT_OK so the phase stays consistent\n // across retries; the wallet adapter has already broadcasted by\n // the time we reach this line, so we fire both events back-to-back.\n dispatch({ type: \"BROADCAST_START\" });\n\n const submitReq: DepositSubmitRequest = {\n userSolanaAddress: input.userSolanaAddress,\n hyperliquidRecipient: input.hyperliquidRecipient,\n solanaTxHash,\n breakdown: quote.breakdown,\n userId: input.userId,\n source: input.source,\n campaign: input.campaign,\n quoteIssuedAt: quote.issuedAt,\n };\n\n if (!client) {\n dispatch({\n type: \"SUBMIT_FAILED\",\n error: {\n code: \"DEPOSIT_CLIENT_NOT_CONFIGURED\",\n message: \"Deposit client is not configured.\",\n recoverable: false,\n },\n });\n throw new Error(\"Deposit client is not configured.\");\n }\n try {\n const out = await client.submit(submitReq);\n dispatch({\n type: \"SUBMIT_OK\",\n intentId: out.intentId,\n solanaTxHash,\n });\n return out.intentId;\n } catch (err) {\n const info = toErrorInfo(err, \"DEPOSIT_SUBMIT_FAILED\");\n dispatch({ type: \"SUBMIT_FAILED\", error: info });\n throw err;\n }\n },\n [client, signAndBroadcast],\n );\n\n return { state, execute, reset, dispatch };\n}\n\nfunction toErrorInfo(err: unknown, fallbackCode: string): DepositErrorInfo {\n if (err instanceof LiberFiApiError) {\n // Try to extract the backend's typed { code, message } from the body.\n const parsed = parseJsonSafe(err.responseBody) as\n | { code?: string; message?: string }\n | undefined;\n return {\n code: parsed?.code ?? fallbackCode,\n message: parsed?.message ?? err.message,\n recoverable: err.statusCode >= 500 || err.statusCode === 408,\n };\n }\n if (err instanceof Error) {\n return { code: fallbackCode, message: err.message, recoverable: true };\n }\n return { code: fallbackCode, message: String(err), recoverable: true };\n}\n\nfunction parseJsonSafe(text: string): unknown {\n if (!text) return undefined;\n try {\n return JSON.parse(text);\n } catch {\n return undefined;\n }\n}\n","import { useQuery, UseQueryOptions } from \"@tanstack/react-query\";\nimport type { IPerpDepositClient } from \"../client/liberfi/LiberFiPerpDepositClient\";\nimport {\n TERMINAL_DEPOSIT_STATUSES,\n type DepositStatusResponse,\n} from \"../client/liberfi/deposit-types\";\nimport { usePerpDepositClientMaybe } from \"./usePerpDepositClient\";\n\nexport function perpDepositStatusQueryKey(\n intentId?: string,\n): readonly unknown[] {\n return [\"perps\", \"deposit\", \"status\", intentId ?? null] as const;\n}\n\nexport async function fetchPerpDepositStatus(\n client: IPerpDepositClient,\n intentId: string,\n): Promise<DepositStatusResponse> {\n return client.status(intentId);\n}\n\nexport interface UsePerpDepositStatusOptions extends Omit<\n UseQueryOptions<\n DepositStatusResponse,\n Error,\n DepositStatusResponse,\n ReturnType<typeof perpDepositStatusQueryKey>\n >,\n \"queryKey\" | \"queryFn\" | \"refetchInterval\" | \"enabled\"\n> {\n enabled?: boolean;\n /**\n * Polling interval in milliseconds while the deposit is non-terminal.\n * Defaults to 3 000 ms — matches the backend's reconciliation cadence\n * with a small safety margin.\n */\n pollIntervalMs?: number;\n}\n\n/**\n * Polls /v1/deposits/{id} until the deposit reaches a terminal status,\n * then stops the timer automatically. The component is responsible for\n * forwarding `data` into the deposit FSM via STATUS_UPDATE events.\n *\n * Engineering principle (single responsibility): this hook owns the\n * \"when to ask the server\" question; the FSM owns the \"what does the\n * answer mean\" question. They communicate through plain typed values.\n */\nexport function usePerpDepositStatus(\n intentId: string | undefined | null,\n options: UsePerpDepositStatusOptions = {},\n) {\n const client = usePerpDepositClientMaybe();\n const enabled = (options.enabled ?? Boolean(intentId)) && Boolean(client);\n // `client!` is safe here because `enabled` is false when `client` is undefined,\n // so the queryFn will never execute without a valid client.\n const pollIntervalMs = options.pollIntervalMs ?? 3_000;\n return useQuery({\n queryKey: perpDepositStatusQueryKey(intentId ?? undefined),\n queryFn: async () => fetchPerpDepositStatus(client!, intentId as string),\n enabled,\n refetchInterval: (query) => {\n const data = query.state.data;\n if (!data) return pollIntervalMs;\n return TERMINAL_DEPOSIT_STATUSES.has(data.status)\n ? false\n : pollIntervalMs;\n },\n refetchOnWindowFocus: false,\n staleTime: 0,\n ...options,\n });\n}\n","/**\n * Pure state machine for the Hyperliquid initialisation flow.\n *\n * Driven by `useReducer` — kept as a separate module so the transition\n * logic is unit-testable without React. The states cover the full\n * lifecycle:\n *\n * idle\n * → loading (caller pressed \"init\", reading current state)\n * → ready (we know which steps remain)\n * → executing (one step is in flight)\n * → done | error\n *\n * `error` is recoverable — `RETRY_STEP` returns the FSM to `executing`.\n * `RESET` always rewinds to `idle` so the caller can re-check status.\n */\nimport type {\n ApproveBuilderFeeParams,\n HyperliquidAccountState,\n SetReferrerParams,\n UpdateLeverageParams,\n} from \"../../client/hyperliquid/HyperliquidSetupAdapter\";\n\n/** Identifier for each setup step — drives the UI checklist. */\nexport type SetupStepId =\n | \"approveBuilderFee\"\n | \"setReferrer\"\n | \"updateLeverage\";\n\n/**\n * A single step in the setup checklist. `params` carry exactly the\n * information the adapter needs to perform the action — the FSM never\n * inspects them; it only routes them to the adapter.\n */\nexport type SetupStep =\n | { id: \"approveBuilderFee\"; params: ApproveBuilderFeeParams }\n | { id: \"setReferrer\"; params: SetReferrerParams }\n | { id: \"updateLeverage\"; params: UpdateLeverageParams };\n\n/** Per-step status tracked across the checklist. */\nexport type StepStatus =\n | \"pending\" // not yet attempted in this session\n | \"skipped\" // already done on-chain — no action needed\n | \"running\"\n | \"done\"\n | \"error\";\n\nexport interface StepRecord {\n step: SetupStep;\n status: StepStatus;\n /** Last error message captured for the step. */\n error?: string;\n /** Optional tx hash returned by the adapter. */\n txHash?: string;\n}\n\nexport type SetupPhase =\n | \"idle\"\n | \"loading\" // refreshing account state\n | \"ready\" // checklist computed, awaiting user action\n | \"executing\"\n | \"done\"\n | \"error\";\n\nexport interface SetupState {\n phase: SetupPhase;\n /** Snapshot of the on-chain state captured during `loading`. */\n accountState?: HyperliquidAccountState;\n /** All steps requested by the caller, in order. */\n steps: StepRecord[];\n /** Index of the step currently executing (only valid in `executing`). */\n currentIndex?: number;\n /** Top-level error — typically from `getAccountState`. */\n error?: string;\n}\n\nexport type SetupAction =\n | { type: \"START_LOADING\" }\n | {\n type: \"LOAD_SUCCESS\";\n accountState: HyperliquidAccountState;\n steps: StepRecord[];\n }\n | { type: \"LOAD_ERROR\"; error: string }\n | { type: \"RUN_STEP\"; index: number }\n | {\n type: \"STEP_SUCCESS\";\n index: number;\n txHash?: string;\n accountState?: HyperliquidAccountState;\n }\n | { type: \"STEP_ERROR\"; index: number; error: string }\n | { type: \"RESET\" };\n\nexport const initialSetupState: SetupState = {\n phase: \"idle\",\n steps: [],\n};\n\n/**\n * Determine the initial status of a step given the current on-chain\n * state. `done` (sometimes called `skipped` to the user) means the\n * action has already happened and we can elide it.\n *\n * Encapsulated as a pure function so the same logic is exercised by\n * both the loader (when `LOAD_SUCCESS` constructs the checklist) and\n * the adapter result handler (when an action reports a partial state\n * update).\n */\nexport function classifyStep(\n step: SetupStep,\n state: HyperliquidAccountState,\n): StepStatus {\n switch (step.id) {\n case \"approveBuilderFee\": {\n const current = state.builderApproval;\n if (\n current &&\n sameAddress(current.builder, step.params.builder) &&\n current.maxFeeRate >= step.params.maxFeeRate\n ) {\n return \"skipped\";\n }\n return \"pending\";\n }\n case \"setReferrer\": {\n // Referrer is a one-shot — any non-null value means done. We do\n // not try to \"fix\" a different referrer because Hyperliquid\n // rejects rebinding.\n return state.referrer ? \"skipped\" : \"pending\";\n }\n case \"updateLeverage\": {\n const current = state.leverage[step.params.asset];\n if (current === step.params.leverage) {\n return \"skipped\";\n }\n return \"pending\";\n }\n }\n}\n\nexport function reduceSetupState(\n state: SetupState,\n action: SetupAction,\n): SetupState {\n switch (action.type) {\n case \"START_LOADING\":\n return {\n phase: \"loading\",\n steps: state.steps,\n accountState: state.accountState,\n };\n case \"LOAD_SUCCESS\": {\n const allDone = action.steps.every(\n (s) => s.status === \"skipped\" || s.status === \"done\",\n );\n return {\n phase: allDone ? \"done\" : \"ready\",\n accountState: action.accountState,\n steps: action.steps,\n };\n }\n case \"LOAD_ERROR\":\n return {\n phase: \"error\",\n steps: state.steps,\n error: action.error,\n };\n case \"RUN_STEP\": {\n const next = state.steps.map((rec, i) =>\n i === action.index\n ? { ...rec, status: \"running\" as StepStatus, error: undefined }\n : rec,\n );\n return {\n phase: \"executing\",\n steps: next,\n accountState: state.accountState,\n currentIndex: action.index,\n };\n }\n case \"STEP_SUCCESS\": {\n const next = state.steps.map((rec, i) =>\n i === action.index\n ? {\n ...rec,\n status: \"done\" as StepStatus,\n txHash: action.txHash,\n error: undefined,\n }\n : rec,\n );\n const mergedAccount: HyperliquidAccountState | undefined =\n action.accountState && state.accountState\n ? mergeAccountState(state.accountState, action.accountState)\n : ((action.accountState as HyperliquidAccountState | undefined) ??\n state.accountState);\n const allDone = next.every(\n (s) => s.status === \"skipped\" || s.status === \"done\",\n );\n return {\n phase: allDone ? \"done\" : \"ready\",\n steps: next,\n accountState: mergedAccount,\n currentIndex: undefined,\n };\n }\n case \"STEP_ERROR\": {\n const next = state.steps.map((rec, i) =>\n i === action.index\n ? { ...rec, status: \"error\" as StepStatus, error: action.error }\n : rec,\n );\n return {\n phase: \"ready\",\n steps: next,\n accountState: state.accountState,\n currentIndex: undefined,\n };\n }\n case \"RESET\":\n return initialSetupState;\n }\n}\n\n/**\n * Find the next step that still needs to run. Returns `null` when the\n * checklist is complete — the caller should treat the FSM as `done`.\n */\nexport function nextRunnableStep(state: SetupState): number | null {\n for (let i = 0; i < state.steps.length; i++) {\n const status = state.steps[i].status;\n if (status === \"pending\" || status === \"error\") return i;\n }\n return null;\n}\n\nfunction sameAddress(a: string, b: string): boolean {\n return a.toLowerCase() === b.toLowerCase();\n}\n\nfunction mergeAccountState(\n base: HyperliquidAccountState,\n patch: Partial<HyperliquidAccountState>,\n): HyperliquidAccountState {\n return {\n builderApproval:\n patch.builderApproval !== undefined\n ? patch.builderApproval\n : base.builderApproval,\n referrer: patch.referrer !== undefined ? patch.referrer : base.referrer,\n leverage: { ...base.leverage, ...(patch.leverage ?? {}) },\n };\n}\n","import { useCallback, useEffect, useReducer, useRef } from \"react\";\nimport type {\n HyperliquidAccountState,\n IHyperliquidSetupAdapter,\n HyperliquidSetupActionResult,\n} from \"../../client/hyperliquid/HyperliquidSetupAdapter\";\nimport {\n classifyStep,\n initialSetupState,\n nextRunnableStep,\n reduceSetupState,\n type SetupState,\n type SetupStep,\n type StepRecord,\n} from \"./setup-state-machine\";\n\n/**\n * Configuration for the Hyperliquid setup orchestrator.\n *\n * The hook is intentionally adapter-agnostic — it does not import any\n * Hyperliquid signing code. The consumer wires in an adapter (typically\n * built around their wallet integration) plus the list of steps they\n * want to run.\n */\nexport interface UseHyperliquidSetupOptions {\n /** Adapter that knows how to read state and submit signed actions. */\n adapter: IHyperliquidSetupAdapter;\n /** EVM address of the user (required to read account state). */\n userAddress: string | undefined;\n /**\n * The steps the consumer wants the user to complete. Order is\n * preserved in the UI, and the orchestrator advances strictly in\n * sequence so failures don't strand the user mid-checklist.\n */\n steps: SetupStep[];\n /**\n * If true, the hook performs an initial state read on mount /\n * adapter change. Defaults to `true`.\n */\n autoLoad?: boolean;\n /** Optional callback invoked once every step is `done` or `skipped`. */\n onComplete?: (state: SetupState) => void;\n /** Optional callback for diagnostic logging. */\n onError?: (err: Error, context: { stepId?: SetupStep[\"id\"] }) => void;\n}\n\nexport interface UseHyperliquidSetupResult {\n state: SetupState;\n /** Re-fetch the on-chain state. Idempotent — safe to call repeatedly. */\n reload: () => Promise<void>;\n /** Run the next pending / error step. No-op when the checklist is done. */\n runNext: () => Promise<void>;\n /** Run a specific step by index — used by per-row \"Retry\" buttons. */\n runStep: (index: number) => Promise<void>;\n /** Reset the FSM to `idle` (e.g. when the user closes the wizard). */\n reset: () => void;\n}\n\n/**\n * Orchestrates the Hyperliquid first-run setup checklist.\n *\n * Responsibilities:\n * - Read the user's account state via the adapter.\n * - Classify each requested step against that state, marking ones\n * already done as `skipped`.\n * - Advance through the remaining steps, calling the appropriate\n * adapter method and merging the returned partial state back.\n * - Surface errors per-step so the UI can show a precise retry CTA.\n *\n * Out of scope:\n * - Signing — adapter does it.\n * - Persistence — Hyperliquid is the source of truth; we re-read on\n * reload instead of caching across sessions.\n */\nexport function useHyperliquidSetup(\n opts: UseHyperliquidSetupOptions,\n): UseHyperliquidSetupResult {\n const {\n adapter,\n userAddress,\n steps,\n autoLoad = true,\n onComplete,\n onError,\n } = opts;\n const [state, dispatch] = useReducer(reduceSetupState, initialSetupState);\n\n // Refs for stable closures inside async work.\n const adapterRef = useRef(adapter);\n const stepsRef = useRef(steps);\n const onCompleteRef = useRef(onComplete);\n const onErrorRef = useRef(onError);\n adapterRef.current = adapter;\n stepsRef.current = steps;\n onCompleteRef.current = onComplete;\n onErrorRef.current = onError;\n\n const reload = useCallback(async () => {\n if (!userAddress) return;\n dispatch({ type: \"START_LOADING\" });\n try {\n const accountState =\n await adapterRef.current.getAccountState(userAddress);\n const records: StepRecord[] = stepsRef.current.map((step) => ({\n step,\n status: classifyStep(step, accountState),\n }));\n dispatch({ type: \"LOAD_SUCCESS\", accountState, steps: records });\n } catch (e) {\n const err = toError(e);\n dispatch({ type: \"LOAD_ERROR\", error: err.message });\n onErrorRef.current?.(err, {});\n }\n }, [userAddress]);\n\n // Auto-load on first mount or when the user / adapter changes.\n useEffect(() => {\n if (autoLoad && userAddress) {\n void reload();\n }\n }, [autoLoad, userAddress, reload]);\n\n const runStep = useCallback(\n async (index: number) => {\n const record = state.steps[index];\n if (!record) return;\n dispatch({ type: \"RUN_STEP\", index });\n try {\n const result = await invokeAdapter(adapterRef.current, record.step);\n dispatch({\n type: \"STEP_SUCCESS\",\n index,\n txHash: result.txHash,\n accountState: result.state as HyperliquidAccountState | undefined,\n });\n } catch (e) {\n const err = toError(e);\n dispatch({ type: \"STEP_ERROR\", index, error: err.message });\n onErrorRef.current?.(err, { stepId: record.step.id });\n }\n },\n [state.steps],\n );\n\n const runNext = useCallback(async () => {\n const idx = nextRunnableStep(state);\n if (idx == null) return;\n await runStep(idx);\n }, [state, runStep]);\n\n const reset = useCallback(() => dispatch({ type: \"RESET\" }), []);\n\n // Fire `onComplete` exactly once when we transition into `done`.\n const completedRef = useRef(false);\n useEffect(() => {\n if (state.phase === \"done\" && !completedRef.current) {\n completedRef.current = true;\n onCompleteRef.current?.(state);\n } else if (state.phase !== \"done\") {\n completedRef.current = false;\n }\n }, [state]);\n\n return { state, reload, runNext, runStep, reset };\n}\n\nfunction invokeAdapter(\n adapter: IHyperliquidSetupAdapter,\n step: SetupStep,\n): Promise<HyperliquidSetupActionResult> {\n switch (step.id) {\n case \"approveBuilderFee\":\n return adapter.approveBuilderFee(step.params);\n case \"setReferrer\":\n return adapter.setReferrer(step.params);\n case \"updateLeverage\":\n return adapter.updateLeverage(step.params);\n }\n}\n\nfunction toError(e: unknown): Error {\n if (e instanceof Error) return e;\n return new Error(typeof e === \"string\" ? e : \"Unknown error\");\n}\n","export function CoinInfoNotFoundUI() {\n return (\n <div className=\"flex items-center justify-center px-4 py-3 bg-neutral-900 border-b border-neutral-800\">\n <span className=\"text-neutral-400 text-sm\">\n Market data not available\n </span>\n </div>\n );\n}\n","import { Skeleton } from \"@liberfi.io/ui\";\n\nexport function CoinInfoSkeletonsUI() {\n return (\n <div className=\"flex items-center gap-6 px-4 py-3 bg-neutral-900 border-b border-neutral-800\">\n <div className=\"flex items-center gap-3\">\n <Skeleton className=\"h-6 w-20 rounded\" />\n <div className=\"flex items-center gap-2\">\n <Skeleton className=\"h-8 w-28 rounded\" />\n <Skeleton className=\"h-5 w-16 rounded\" />\n </div>\n </div>\n\n <div className=\"h-8 w-px bg-neutral-800\" />\n\n <div className=\"flex items-center gap-6 text-sm\">\n <div className=\"flex flex-col gap-1\">\n <Skeleton className=\"h-3 w-20 rounded\" />\n <Skeleton className=\"h-5 w-16 rounded\" />\n </div>\n\n <div className=\"flex flex-col gap-1\">\n <Skeleton className=\"h-3 w-20 rounded\" />\n <Skeleton className=\"h-5 w-16 rounded\" />\n </div>\n\n <div className=\"flex flex-col gap-1\">\n <Skeleton className=\"h-3 w-24 rounded\" />\n <Skeleton className=\"h-5 w-16 rounded\" />\n </div>\n\n <div className=\"flex flex-col gap-1\">\n <Skeleton className=\"h-3 w-32 rounded\" />\n <div className=\"flex items-center gap-2\">\n <Skeleton className=\"h-5 w-16 rounded\" />\n <Skeleton className=\"h-5 w-20 rounded\" />\n </div>\n </div>\n </div>\n </div>\n );\n}\n","import { useEffect, useState } from \"react\";\nimport { useMarketDataSubscription } from \"../../hooks/useMarketDataSubscription\";\nimport { useMarketQuery } from \"../../hooks/useMarketQuery\";\nimport type { MarketData } from \"../../types\";\n\nexport type UseCoinInfoReturnType = {\n marketData?: MarketData;\n isLoading: boolean;\n fundingCountdown: number;\n};\n\nexport function useCoinInfo(symbol: string): UseCoinInfoReturnType {\n const [marketData, setMarketData] = useState<MarketData | undefined>();\n const [fundingCountdown, setFundingCountdown] = useState<number>(0);\n\n const { data: initialData, isPending } = useMarketQuery({ symbol });\n\n const { data: realtimeData, isConnected } =\n useMarketDataSubscription<MarketData>({\n type: \"ticker\",\n symbol,\n enabled: !!initialData,\n });\n\n useEffect(() => {\n if (!initialData) return;\n setMarketData(initialData);\n }, [initialData]);\n\n useEffect(() => {\n if (!realtimeData) return;\n\n const normalized = normalizeRealtimeTickerPayload(realtimeData, symbol);\n if (!normalized) return;\n\n setMarketData((previous) =>\n buildMarketData(previous ?? initialData ?? undefined, normalized, symbol),\n );\n }, [realtimeData, initialData, symbol]);\n\n useEffect(() => {\n const calculateCountdown = () => {\n const now = Date.now();\n const eightHours = 8 * 60 * 60 * 1000;\n const remainder = now % eightHours;\n const timeUntilNext = eightHours - remainder;\n return Math.floor(timeUntilNext / 1000);\n };\n\n setFundingCountdown(calculateCountdown());\n\n const interval = setInterval(() => {\n setFundingCountdown(calculateCountdown());\n }, 1000);\n\n return () => clearInterval(interval);\n }, []);\n\n return {\n marketData,\n isLoading: isPending,\n fundingCountdown,\n };\n}\n\nfunction normalizeRealtimeTickerPayload(\n payload: unknown,\n symbol: string,\n): Partial<MarketData> | null {\n if (Array.isArray(payload)) {\n const matched = payload.find((item) => {\n if (!item || typeof item !== \"object\") return false;\n return (item as { symbol?: string }).symbol === symbol;\n });\n return matched && typeof matched === \"object\"\n ? (matched as Partial<MarketData>)\n : null;\n }\n\n if (payload && typeof payload === \"object\") {\n return payload as Partial<MarketData>;\n }\n\n return null;\n}\n\nfunction toNumberOr(value: unknown, fallback: number): number {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return value;\n }\n return fallback;\n}\n\nfunction buildMarketData(\n base: MarketData | undefined,\n patch: Partial<MarketData>,\n symbol: string,\n): MarketData {\n return {\n symbol: patch.symbol ?? base?.symbol ?? symbol,\n price: toNumberOr(patch.price, base?.price ?? 0),\n change24h: toNumberOr(patch.change24h, base?.change24h ?? 0),\n volume24h: toNumberOr(patch.volume24h, base?.volume24h ?? 0),\n fundingRate: toNumberOr(patch.fundingRate, base?.fundingRate ?? 0),\n openInterest: toNumberOr(patch.openInterest, base?.openInterest ?? 0),\n markPrice: toNumberOr(patch.markPrice, base?.markPrice ?? 0),\n indexPrice:\n typeof patch.indexPrice === \"number\" && Number.isFinite(patch.indexPrice)\n ? patch.indexPrice\n : base?.indexPrice,\n high24h:\n typeof patch.high24h === \"number\" && Number.isFinite(patch.high24h)\n ? patch.high24h\n : base?.high24h,\n low24h:\n typeof patch.low24h === \"number\" && Number.isFinite(patch.low24h)\n ? patch.low24h\n : base?.low24h,\n };\n}\n","import { cn } from \"@liberfi.io/ui\";\nimport type { MarketData } from \"../../types\";\n\nexport type CoinInfoUIProps = {\n marketData: MarketData;\n fundingCountdown: number;\n};\n\nfunction formatCountdown(seconds: number): string {\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const secs = seconds % 60;\n return `${String(hours).padStart(2, \"0\")}:${String(minutes).padStart(2, \"0\")}:${String(secs).padStart(2, \"0\")}`;\n}\n\nfunction formatNumber(num: number | undefined, decimals: number = 2): string {\n if (typeof num !== \"number\" || !Number.isFinite(num)) {\n return \"-\";\n }\n if (num >= 1e9) {\n return `$${(num / 1e9).toFixed(decimals)}B`;\n }\n if (num >= 1e6) {\n return `$${(num / 1e6).toFixed(decimals)}M`;\n }\n if (num >= 1e3) {\n return `$${(num / 1e3).toFixed(decimals)}K`;\n }\n return `$${num.toFixed(decimals)}`;\n}\n\nfunction formatPrice(price: number | undefined): string {\n if (typeof price !== \"number\" || !Number.isFinite(price)) {\n return \"-\";\n }\n if (price >= 1000) {\n return price.toLocaleString(\"en-US\", {\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n });\n }\n if (price >= 1) {\n return price.toLocaleString(\"en-US\", {\n minimumFractionDigits: 2,\n maximumFractionDigits: 4,\n });\n }\n return price.toFixed(6);\n}\n\nexport function CoinInfoUI({ marketData, fundingCountdown }: CoinInfoUIProps) {\n const {\n symbol,\n price,\n change24h,\n indexPrice,\n volume24h,\n openInterest,\n fundingRate,\n } = marketData;\n\n const safeChange24h =\n typeof change24h === \"number\" && Number.isFinite(change24h) ? change24h : 0;\n const safeFundingRate =\n typeof fundingRate === \"number\" && Number.isFinite(fundingRate)\n ? fundingRate\n : 0;\n const isPositiveChange = safeChange24h >= 0;\n const changePercent = safeChange24h.toFixed(2);\n\n return (\n <div\n className=\"flex items-center px-4\"\n style={{ minHeight: 64, maxHeight: 64, gap: 24 }}\n >\n <div className=\"flex items-baseline\" style={{ gap: 8 }}>\n <span\n style={{\n fontSize: 18,\n fontWeight: 500,\n lineHeight: \"23px\",\n letterSpacing: \"-0.36px\",\n color: \"#ffffff\",\n }}\n >\n {formatPrice(price)}\n </span>\n <span\n style={{\n fontSize: 12,\n fontWeight: 400,\n lineHeight: \"16px\",\n color: isPositiveChange ? \"#C7FF2E\" : \"#F76816\",\n }}\n >\n {isPositiveChange ? \"+\" : \"\"}\n {changePercent}%\n </span>\n </div>\n\n <div className=\"flex items-center\" style={{ gap: 24 }}>\n <div className=\"flex flex-col\">\n <span\n style={{\n fontSize: 12,\n color: \"#b5b5b5\",\n lineHeight: \"16px\",\n letterSpacing: \"-0.12px\",\n }}\n >\n Oracle Price\n </span>\n <span\n style={{\n fontSize: 13,\n fontWeight: 400,\n lineHeight: \"17px\",\n color: \"#ffffff\",\n }}\n >\n {indexPrice ? formatPrice(indexPrice) : \"-\"}\n </span>\n </div>\n\n <div className=\"flex flex-col\">\n <span\n style={{\n fontSize: 12,\n color: \"#b5b5b5\",\n lineHeight: \"16px\",\n letterSpacing: \"-0.12px\",\n }}\n >\n 24h Volume\n </span>\n <span\n style={{\n fontSize: 13,\n fontWeight: 400,\n lineHeight: \"17px\",\n color: \"#ffffff\",\n }}\n >\n {formatNumber(volume24h, 0)}\n </span>\n </div>\n\n <div className=\"flex flex-col\">\n <span\n style={{\n fontSize: 12,\n color: \"#b5b5b5\",\n lineHeight: \"16px\",\n letterSpacing: \"-0.12px\",\n }}\n >\n Open Interest\n </span>\n <span\n style={{\n fontSize: 13,\n fontWeight: 400,\n lineHeight: \"17px\",\n color: \"#ffffff\",\n }}\n >\n {formatNumber(openInterest * (marketData.markPrice || price))}\n </span>\n </div>\n\n <div className=\"flex flex-col\">\n <span\n style={{\n fontSize: 12,\n color: \"#b5b5b5\",\n lineHeight: \"16px\",\n letterSpacing: \"-0.12px\",\n }}\n >\n Funding / Countdown\n </span>\n <div className=\"flex items-center\" style={{ gap: 8 }}>\n <span\n style={{\n fontSize: 13,\n lineHeight: \"17px\",\n color: safeFundingRate >= 0 ? \"#C7FF2E\" : \"#F76816\",\n }}\n >\n {(safeFundingRate * 100).toFixed(5)}%\n </span>\n <span\n style={{\n fontSize: 13,\n lineHeight: \"17px\",\n color: \"#ffffff\",\n }}\n >\n {formatCountdown(fundingCountdown)}\n </span>\n </div>\n </div>\n </div>\n </div>\n );\n}\n","import { CoinInfoNotFoundUI } from \"./coin-info-notfound.ui\";\nimport { CoinInfoSkeletonsUI } from \"./coin-info-skeletons.ui\";\nimport { useCoinInfo } from \"./coin-info.script\";\nimport { CoinInfoUI } from \"./coin-info.ui\";\n\nexport type CoinInfoWidgetProps = {\n symbol: string;\n};\n\nexport function CoinInfoWidget({ symbol }: CoinInfoWidgetProps) {\n const { marketData, isLoading, fundingCountdown } = useCoinInfo(symbol);\n\n if (isLoading) {\n return <CoinInfoSkeletonsUI />;\n }\n\n if (!marketData) {\n return <CoinInfoNotFoundUI />;\n }\n\n return (\n <CoinInfoUI marketData={marketData} fundingCountdown={fundingCountdown} />\n );\n}\n","import { useEffect, useMemo, useState } from \"react\";\nimport { useCoinsQuery } from \"../../hooks/useCoinsQuery\";\nimport { useMarketsQuery } from \"../../hooks/useMarketsQuery\";\nimport type { MarketData } from \"../../types\";\n\nexport type UseSearchCoinsScriptParams = {\n onSelectCoin?: (symbol: string) => void;\n};\n\nexport type UseSearchCoinsScriptResult = {\n coins: MarketData[];\n isLoading: boolean;\n searchQuery: string;\n setSearchQuery: (query: string) => void;\n filteredCoins: MarketData[];\n handleSelectCoin: (symbol: string) => void;\n};\n\nexport function useSearchCoinsScript({\n onSelectCoin,\n}: UseSearchCoinsScriptParams = {}): UseSearchCoinsScriptResult {\n const [searchQuery, setSearchQuery] = useState<string>(\"\");\n const [coins, setCoins] = useState<MarketData[]>([]);\n\n const { data: coinSymbols, isPending: isLoadingSymbols } = useCoinsQuery();\n\n const { data: marketsData, isPending: isLoadingMarkets } = useMarketsQuery(\n { symbols: coinSymbols },\n { enabled: !!coinSymbols && coinSymbols.length > 0 },\n );\n\n useEffect(() => {\n if (marketsData) {\n setCoins(marketsData);\n }\n }, [marketsData]);\n\n const filteredCoins = useMemo(() => {\n if (!searchQuery.trim()) {\n return coins;\n }\n\n const query = searchQuery.toLowerCase().trim();\n return coins.filter((coin) => coin.symbol.toLowerCase().includes(query));\n }, [coins, searchQuery]);\n\n const handleSelectCoin = (symbol: string) => {\n onSelectCoin?.(symbol);\n };\n\n return {\n coins,\n isLoading: isLoadingSymbols || isLoadingMarkets,\n searchQuery,\n setSearchQuery,\n filteredCoins,\n handleSelectCoin,\n };\n}\n","import { SearchIcon } from \"@liberfi.io/ui\";\nimport type { MarketData } from \"../../types\";\n\nexport type SearchCoinsUIProps = {\n coins: MarketData[];\n searchQuery: string;\n onSearchChange: (query: string) => void;\n onSelectCoin: (symbol: string) => void;\n isLoading?: boolean;\n};\n\nfunction formatNumber(num: number, decimals: number = 2): string {\n if (num >= 1e9) {\n return `$${(num / 1e9).toFixed(decimals)}B`;\n }\n if (num >= 1e6) {\n return `$${(num / 1e6).toFixed(decimals)}M`;\n }\n if (num >= 1e3) {\n return `$${(num / 1e3).toFixed(decimals)}K`;\n }\n return `$${num.toFixed(decimals)}`;\n}\n\nfunction formatPrice(price: number): string {\n if (price >= 1000) {\n return price.toFixed(2);\n }\n if (price >= 1) {\n return price.toFixed(4);\n }\n return price.toFixed(6);\n}\n\nexport function SearchCoinsUI({\n coins,\n searchQuery,\n onSearchChange,\n onSelectCoin,\n isLoading,\n}: SearchCoinsUIProps) {\n return (\n <div\n className=\"flex flex-col\"\n style={{ backgroundColor: \"#1A1A1A\", flex: \"1 1 0\", minHeight: 0 }}\n >\n <div style={{ padding: \"16px 16px 12px\" }}>\n <div\n className=\"flex items-center\"\n style={{\n height: 32,\n border: \"1px solid #2a2a2a\",\n borderRadius: 4,\n padding: \"0 6px 0 12px\",\n gap: 8,\n }}\n >\n <SearchIcon\n className=\"flex-shrink-0\"\n style={{ width: 14, height: 14, color: \"#6b6b6b\" }}\n />\n <input\n type=\"text\"\n placeholder=\"Search coins...\"\n value={searchQuery}\n onChange={(e) => onSearchChange(e.target.value)}\n className=\"flex-1 bg-transparent outline-none\"\n style={{ fontSize: 12, color: \"#ffffff\", border: \"none\" }}\n />\n </div>\n </div>\n\n <div className=\"flex-1 overflow-auto\">\n {/* Header */}\n <div\n className=\"flex items-center\"\n style={{\n height: 28,\n padding: \"0 16px\",\n borderBottom: \"1px solid rgba(42,42,42,0.5)\",\n position: \"sticky\",\n top: 0,\n backgroundColor: \"#1A1A1A\",\n zIndex: 1,\n }}\n >\n <span style={{ flex: \"0 0 140px\", fontSize: 12, color: \"#6b6b6b\" }}>\n Token\n </span>\n <span\n style={{\n flex: \"0 0 100px\",\n fontSize: 12,\n color: \"#6b6b6b\",\n textAlign: \"right\",\n }}\n >\n Last Price\n </span>\n <span\n style={{\n flex: \"0 0 120px\",\n fontSize: 12,\n color: \"#6b6b6b\",\n textAlign: \"right\",\n }}\n >\n 24h Change\n </span>\n <span\n style={{\n flex: \"0 0 100px\",\n fontSize: 12,\n color: \"#6b6b6b\",\n textAlign: \"right\",\n }}\n >\n 8h Funding\n </span>\n <span\n style={{\n flex: \"0 0 100px\",\n fontSize: 12,\n color: \"#6b6b6b\",\n textAlign: \"right\",\n }}\n >\n 24h Volume\n </span>\n <span\n style={{\n flex: \"1\",\n fontSize: 12,\n color: \"#6b6b6b\",\n textAlign: \"right\",\n }}\n >\n Open Interest\n </span>\n </div>\n\n {/* Rows */}\n {isLoading ? (\n <div\n className=\"flex items-center justify-center\"\n style={{ height: 100 }}\n >\n <span style={{ fontSize: 12, color: \"#6b6b6b\" }}>Loading...</span>\n </div>\n ) : coins.length === 0 ? (\n <div\n className=\"flex items-center justify-center\"\n style={{ height: 100 }}\n >\n <span style={{ fontSize: 12, color: \"#6b6b6b\" }}>\n {searchQuery ? \"No coins found\" : \"No coins available\"}\n </span>\n </div>\n ) : (\n coins.map((coin) => {\n const isPositiveChange = coin.change24h >= 0;\n const changePercent = coin.change24h.toFixed(2);\n const fundingPercent = (coin.fundingRate * 100).toFixed(4);\n const isPositiveFunding = coin.fundingRate >= 0;\n const tokenName = coin.symbol.split(\"-\")[0];\n\n return (\n <div\n key={coin.symbol}\n className=\"flex items-center cursor-pointer transition-colors\"\n style={{\n height: 36,\n padding: \"0 16px\",\n borderBottom: \"1px solid rgba(42,42,42,0.5)\",\n }}\n onClick={() => onSelectCoin(coin.symbol)}\n onMouseEnter={(e) => {\n (e.currentTarget as HTMLDivElement).style.backgroundColor =\n \"rgba(255,255,255,0.03)\";\n }}\n onMouseLeave={(e) => {\n (e.currentTarget as HTMLDivElement).style.backgroundColor =\n \"transparent\";\n }}\n >\n <div\n className=\"flex items-center\"\n style={{ flex: \"0 0 140px\", gap: 8 }}\n >\n <img\n src={`https://app.hyperliquid.xyz/coins/${tokenName}.svg`}\n alt={tokenName}\n className=\"rounded-full\"\n style={{ width: 20, height: 20 }}\n onError={(e) => {\n const target = e.target as HTMLImageElement;\n target.style.display = \"none\";\n }}\n />\n <span\n style={{ fontSize: 12, fontWeight: 500, color: \"#ffffff\" }}\n >\n {tokenName}\n </span>\n </div>\n <span\n style={{\n flex: \"0 0 100px\",\n fontSize: 12,\n color: \"#ffffff\",\n textAlign: \"right\",\n }}\n >\n {formatPrice(coin.price)}\n </span>\n <span\n style={{\n flex: \"0 0 120px\",\n fontSize: 12,\n fontWeight: 500,\n color: isPositiveChange ? \"#C7FF2E\" : \"#F76816\",\n textAlign: \"right\",\n }}\n >\n {isPositiveChange ? \"+\" : \"\"}\n {changePercent}%\n </span>\n <span\n style={{\n flex: \"0 0 100px\",\n fontSize: 12,\n color: isPositiveFunding ? \"#C7FF2E\" : \"#F76816\",\n textAlign: \"right\",\n }}\n >\n {fundingPercent}%\n </span>\n <span\n style={{\n flex: \"0 0 100px\",\n fontSize: 12,\n color: \"#b5b5b5\",\n textAlign: \"right\",\n }}\n >\n {formatNumber(coin.volume24h)}\n </span>\n <span\n style={{\n flex: \"1\",\n fontSize: 12,\n color: \"#b5b5b5\",\n textAlign: \"right\",\n }}\n >\n {formatNumber(coin.openInterest * coin.price)}\n </span>\n </div>\n );\n })\n )}\n </div>\n </div>\n );\n}\n","import { useSearchCoinsScript } from \"./search-coins.script\";\nimport { SearchCoinsUI } from \"./search-coins.ui\";\n\nexport type SearchCoinsWidgetProps = {\n onSelectCoin?: (symbol: string) => void;\n className?: string;\n};\n\nexport function SearchCoinsWidget({\n onSelectCoin,\n className,\n}: SearchCoinsWidgetProps) {\n const {\n filteredCoins,\n isLoading,\n searchQuery,\n setSearchQuery,\n handleSelectCoin,\n } = useSearchCoinsScript({ onSelectCoin });\n\n return (\n <div\n className={className}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n flex: \"1 1 0\",\n minHeight: 0,\n overflow: \"hidden\",\n }}\n >\n <SearchCoinsUI\n coins={filteredCoins}\n searchQuery={searchQuery}\n onSearchChange={setSearchQuery}\n onSelectCoin={handleSelectCoin}\n isLoading={isLoading}\n />\n </div>\n );\n}\n","import { useEffect, useMemo, useState } from \"react\";\nimport { useMarketDataSubscription } from \"../../hooks/useMarketDataSubscription\";\nimport { useOrderBookQuery } from \"../../hooks/useOrderBookQuery\";\nimport type { OrderBook, OrderBookLevel } from \"../../types\";\n\nexport type PriceLevel = OrderBookLevel & {\n total: number;\n percentage: number;\n};\n\nexport type UseOrderBookScriptParams = {\n symbol: string;\n maxLevel?: number;\n precision?: number;\n};\n\nexport type UseOrderBookScriptResult = {\n bids: PriceLevel[];\n asks: PriceLevel[];\n spread: number;\n spreadPercentage: number;\n isLoading: boolean;\n precision: number;\n setPrecision: (precision: number) => void;\n};\n\nfunction aggregateByPrecision(\n levels: OrderBookLevel[],\n precision: number,\n): OrderBookLevel[] {\n if (precision <= 0) return levels;\n\n const aggregated = new Map<number, OrderBookLevel>();\n\n levels.forEach((level) => {\n const roundedPrice = Math.floor(level.price / precision) * precision;\n\n const existing = aggregated.get(roundedPrice);\n if (existing) {\n existing.quantity += level.quantity;\n if (level.count) {\n existing.count = (existing.count || 0) + level.count;\n }\n } else {\n aggregated.set(roundedPrice, {\n price: roundedPrice,\n quantity: level.quantity,\n count: level.count,\n });\n }\n });\n\n return Array.from(aggregated.values());\n}\n\nfunction calculateTotalsAndPercentages(levels: OrderBookLevel[]): PriceLevel[] {\n let total = 0;\n const withTotals = levels.map((level) => {\n const usdAmount = level.quantity * level.price;\n total += usdAmount;\n return {\n ...level,\n quantity: usdAmount,\n total,\n percentage: 0,\n };\n });\n\n const maxTotal = total;\n return withTotals.map((level) => ({\n ...level,\n percentage: maxTotal > 0 ? (level.total / maxTotal) * 100 : 0,\n }));\n}\n\nexport function useOrderBookScript({\n symbol,\n maxLevel = 20,\n precision: initialPrecision = 0.01,\n}: UseOrderBookScriptParams): UseOrderBookScriptResult {\n const [orderBook, setOrderBook] = useState<OrderBook | null>(null);\n const [precision, setPrecision] = useState<number>(initialPrecision);\n\n const { data: initialData, isPending } = useOrderBookQuery({\n symbol,\n maxLevel,\n });\n\n const { data: realtimeData } = useMarketDataSubscription<OrderBook>({\n type: \"orderBook\",\n symbol,\n enabled: !!initialData,\n });\n\n useEffect(() => {\n if (realtimeData) {\n setOrderBook(realtimeData);\n } else if (initialData) {\n setOrderBook(initialData);\n }\n }, [realtimeData, initialData]);\n\n const processedData = useMemo(() => {\n if (!orderBook) {\n return {\n bids: [],\n asks: [],\n spread: 0,\n spreadPercentage: 0,\n };\n }\n\n const aggregatedBids = aggregateByPrecision(orderBook.bids, precision);\n const aggregatedAsks = aggregateByPrecision(orderBook.asks, precision);\n\n const sortedBids = aggregatedBids\n .sort((a, b) => b.price - a.price)\n .slice(0, maxLevel);\n\n const sortedAsks = aggregatedAsks\n .sort((a, b) => a.price - b.price)\n .slice(0, maxLevel);\n\n const bids = calculateTotalsAndPercentages(sortedBids);\n const asks = calculateTotalsAndPercentages(sortedAsks);\n\n const bestBid = bids[0]?.price || 0;\n const bestAsk = asks[0]?.price || 0;\n const spread = bestAsk - bestBid;\n const spreadPercentage = bestBid > 0 ? (spread / bestBid) * 100 : 0;\n\n return {\n bids,\n asks,\n spread,\n spreadPercentage,\n };\n }, [orderBook, precision, maxLevel]);\n\n return {\n ...processedData,\n isLoading: isPending,\n precision,\n setPrecision,\n };\n}\n","import type { PriceLevel } from \"./orderbook.script\";\n\nexport type OrderBookUIProps = {\n bids: PriceLevel[];\n asks: PriceLevel[];\n spread: number;\n spreadPercentage: number;\n onPriceClick?: (price: number) => void;\n};\n\nfunction formatPrice(price: number): string {\n if (price >= 1000) {\n return price.toLocaleString(\"en-US\", {\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n });\n }\n if (price >= 1) {\n return price.toLocaleString(\"en-US\", {\n minimumFractionDigits: 2,\n maximumFractionDigits: 4,\n });\n }\n return price.toFixed(6);\n}\n\nfunction formatQuantity(qty: number): string {\n return Math.round(qty).toLocaleString(\"en-US\");\n}\n\nfunction OBRow({\n price,\n quantity,\n total,\n percentage,\n side,\n onClick,\n}: {\n price: number;\n quantity: number;\n total: number;\n percentage: number;\n side: \"ask\" | \"bid\";\n onClick?: () => void;\n}) {\n const isAsk = side === \"ask\";\n return (\n <div\n className=\"relative flex items-center cursor-pointer hover:bg-white/5 transition-colors\"\n style={{\n height: 22,\n minHeight: 22,\n maxHeight: 22,\n padding: \"0 16px\",\n gap: 16,\n fontSize: 11,\n }}\n onClick={onClick}\n >\n <div\n className=\"absolute left-0 top-0\"\n style={{\n height: 20,\n width: `${percentage}%`,\n background: isAsk\n ? \"linear-gradient(to right, rgba(247,104,22,0), #F76816)\"\n : \"linear-gradient(to right, rgba(199,255,46,0), #C7FF2E)\",\n opacity: 0.15,\n }}\n />\n <div\n className=\"relative z-10 flex items-center\"\n style={{ flex: \"1 1 0%\" }}\n >\n <span style={{ color: isAsk ? \"#F76816\" : \"#C7FF2E\", fontWeight: 400 }}>\n {formatPrice(price)}\n </span>\n </div>\n <div\n className=\"relative z-10 flex items-center justify-end\"\n style={{ flex: \"1 1 0%\", color: \"#ffffff\" }}\n >\n {formatQuantity(quantity)}\n </div>\n <div\n className=\"relative z-10 flex items-center justify-end\"\n style={{ flex: \"1 1 0%\", color: \"#ffffff\" }}\n >\n {formatQuantity(total)}\n </div>\n </div>\n );\n}\n\nexport function OrderBookUI({\n bids,\n asks,\n spread,\n spreadPercentage,\n onPriceClick,\n}: OrderBookUIProps) {\n // `asks` is sorted ascending by price (best ask = lowest = first item).\n // We render with `flex-col-reverse` so items pile up against the spread\n // bar (top of the asks block visually shows the highest, bottom shows\n // the best ask — the level closest to the spread).\n return (\n <div\n className=\"flex flex-col h-full\"\n style={{ backgroundColor: \"#000000\", fontSize: 11 }}\n >\n {/* Header */}\n <div\n className=\"flex items-center\"\n style={{\n height: 28,\n minHeight: 28,\n padding: \"0 16px\",\n gap: 16,\n color: \"#6b6b6b\",\n fontSize: 11,\n }}\n >\n <div className=\"flex items-center\" style={{ flex: \"1 1 0%\" }}>\n Price\n </div>\n <div\n className=\"flex items-center justify-end\"\n style={{ flex: \"1 1 0%\" }}\n >\n Amount (USD)\n </div>\n <div\n className=\"flex items-center justify-end\"\n style={{ flex: \"1 1 0%\" }}\n >\n Total (USD)\n </div>\n </div>\n\n {/* Asks — best ask (lowest price) is rendered closest to the spread bar */}\n <div className=\"flex-1 flex flex-col-reverse overflow-hidden\">\n {asks.map((ask, index) => (\n <OBRow\n key={`ask-${ask.price}-${index}`}\n price={ask.price}\n quantity={ask.quantity}\n total={ask.total}\n percentage={ask.percentage}\n side=\"ask\"\n onClick={() => onPriceClick?.(ask.price)}\n />\n ))}\n </div>\n\n {/* Spread bar */}\n <div\n className=\"flex items-center justify-center\"\n style={{\n height: 24,\n minHeight: 24,\n padding: \"0 16px\",\n backgroundColor: \"rgba(26,26,26,0.5)\",\n }}\n >\n <div\n className=\"flex items-center\"\n style={{ gap: 12, fontSize: 12, color: \"#ffffff\" }}\n >\n <span style={{ color: \"#ffffff\" }}>Spread:</span>\n <button\n type=\"button\"\n className=\"hover:text-white transition-colors cursor-pointer\"\n style={{\n color: \"#ffffff\",\n fontWeight: 400,\n background: \"none\",\n border: \"none\",\n padding: 0,\n }}\n onClick={() => onPriceClick?.(spread)}\n >\n {spread >= 1\n ? Math.round(spread).toLocaleString(\"en-US\")\n : spread.toFixed(4)}\n </button>\n <span style={{ color: \"#ffffff\", fontWeight: 500 }}>\n {spreadPercentage.toFixed(3)}%\n </span>\n </div>\n </div>\n\n {/* Bids */}\n <div className=\"flex-1 overflow-hidden\">\n {bids.map((bid, index) => (\n <OBRow\n key={`bid-${bid.price}-${index}`}\n price={bid.price}\n quantity={bid.quantity}\n total={bid.total}\n percentage={bid.percentage}\n side=\"bid\"\n onClick={() => onPriceClick?.(bid.price)}\n />\n ))}\n </div>\n </div>\n );\n}\n","import { Skeleton } from \"@liberfi.io/ui\";\nimport { useOrderBookScript } from \"./orderbook.script\";\nimport { OrderBookUI } from \"./orderbook.ui\";\n\nexport type OrderBookWidgetProps = {\n symbol: string;\n maxLevel?: number;\n onPriceClick?: (price: number) => void;\n className?: string;\n};\n\nfunction OrderBookSkeleton() {\n return (\n <div className=\"flex flex-col h-full\" style={{ padding: \"0 16px\" }}>\n <div\n className=\"flex justify-between items-center\"\n style={{ height: 28, marginBottom: 4 }}\n >\n <Skeleton className=\"h-3 w-12 rounded\" />\n <Skeleton className=\"h-3 w-14 rounded\" />\n <Skeleton className=\"h-3 w-14 rounded\" />\n </div>\n {Array.from({ length: 10 }).map((_, i) => (\n <div\n key={`ask-skeleton-${i}`}\n className=\"flex justify-between items-center\"\n style={{ height: 22 }}\n >\n <Skeleton className=\"h-3 w-14 rounded\" />\n <Skeleton className=\"h-3 w-14 rounded\" />\n <Skeleton className=\"h-3 w-14 rounded\" />\n </div>\n ))}\n <div className=\"flex justify-center items-center\" style={{ height: 28 }}>\n <Skeleton className=\"h-4 w-32 rounded\" />\n </div>\n {Array.from({ length: 10 }).map((_, i) => (\n <div\n key={`bid-skeleton-${i}`}\n className=\"flex justify-between items-center\"\n style={{ height: 22 }}\n >\n <Skeleton className=\"h-3 w-14 rounded\" />\n <Skeleton className=\"h-3 w-14 rounded\" />\n <Skeleton className=\"h-3 w-14 rounded\" />\n </div>\n ))}\n </div>\n );\n}\n\nfunction OrderBookEmpty() {\n return (\n <div className=\"flex items-center justify-center h-full\">\n <span className=\"text-neutral-400 text-sm\">\n No order book data available\n </span>\n </div>\n );\n}\n\nexport function OrderBookWidget({\n symbol,\n maxLevel = 20,\n onPriceClick,\n className,\n}: OrderBookWidgetProps) {\n const { bids, asks, spread, spreadPercentage, isLoading } =\n useOrderBookScript({\n symbol,\n maxLevel,\n });\n\n if (isLoading) {\n return <OrderBookSkeleton />;\n }\n\n if (bids.length === 0 && asks.length === 0) {\n return <OrderBookEmpty />;\n }\n\n return (\n <div className={className}>\n <OrderBookUI\n bids={bids}\n asks={asks}\n spread={spread}\n spreadPercentage={spreadPercentage}\n onPriceClick={onPriceClick}\n />\n </div>\n );\n}\n","import { useEffect, useState } from \"react\";\nimport { useMarketDataSubscription } from \"../../hooks/useMarketDataSubscription\";\nimport { useRecentTradesQuery } from \"../../hooks/useRecentTradesQuery\";\nimport type { Trade } from \"../../types\";\n\nexport type UseTradesScriptParams = {\n symbol: string;\n limit?: number;\n};\n\nexport type UseTradesScriptResult = {\n trades: Trade[];\n isLoading: boolean;\n};\n\nexport function useTradesScript({\n symbol,\n limit = 50,\n}: UseTradesScriptParams): UseTradesScriptResult {\n const [trades, setTrades] = useState<Trade[]>([]);\n\n const { data: initialData, isPending } = useRecentTradesQuery({\n symbol,\n limit,\n });\n\n const { data: realtimeTrade } = useMarketDataSubscription<Trade | Trade[]>({\n type: \"trades\",\n symbol,\n enabled: !!initialData,\n });\n\n useEffect(() => {\n if (initialData) {\n setTrades(initialData.filter(isValidTrade));\n }\n }, [initialData]);\n\n useEffect(() => {\n if (realtimeTrade) {\n setTrades((prevTrades) => {\n const normalizedTrades = normalizeRealtimeTrades(realtimeTrade);\n if (normalizedTrades.length === 0) return prevTrades;\n\n const deduped = normalizedTrades.filter((nextTrade) => {\n return !prevTrades.some(\n (existing) =>\n existing.timestamp === nextTrade.timestamp &&\n existing.price === nextTrade.price &&\n existing.quantity === nextTrade.quantity,\n );\n });\n\n if (deduped.length === 0) return prevTrades;\n\n const newTrades = [...deduped, ...prevTrades];\n return newTrades.slice(0, limit);\n });\n }\n }, [realtimeTrade, limit]);\n\n return {\n trades,\n isLoading: isPending,\n };\n}\n\nfunction normalizeRealtimeTrades(payload: Trade | Trade[]): Trade[] {\n const list = Array.isArray(payload) ? payload : [payload];\n return list.filter(isValidTrade);\n}\n\nfunction isValidTrade(trade: Partial<Trade> | undefined): trade is Trade {\n if (!trade) return false;\n return (\n typeof trade.symbol === \"string\" &&\n (trade.side === \"buy\" || trade.side === \"sell\") &&\n typeof trade.price === \"number\" &&\n Number.isFinite(trade.price) &&\n typeof trade.quantity === \"number\" &&\n Number.isFinite(trade.quantity) &&\n typeof trade.timestamp === \"number\" &&\n Number.isFinite(trade.timestamp)\n );\n}\n","import type { Trade } from \"../../types\";\n\nexport type TradesUIProps = {\n trades: Trade[];\n onTradeClick?: (trade: Trade) => void;\n};\n\nfunction formatPrice(price: number | undefined): string {\n if (typeof price !== \"number\" || !Number.isFinite(price)) {\n return \"-\";\n }\n if (price >= 1000) {\n return price.toFixed(2);\n }\n if (price >= 1) {\n return price.toFixed(4);\n }\n return price.toFixed(6);\n}\n\nfunction formatQuantity(qty: number | undefined): string {\n if (typeof qty !== \"number\" || !Number.isFinite(qty)) {\n return \"-\";\n }\n if (qty >= 1000000) {\n return (qty / 1000000).toFixed(2) + \"M\";\n }\n if (qty >= 1000) {\n return (qty / 1000).toFixed(2) + \"K\";\n }\n return qty.toFixed(2);\n}\n\nfunction formatTime(timestamp: number | undefined): string {\n if (typeof timestamp !== \"number\" || !Number.isFinite(timestamp)) {\n return \"-\";\n }\n const date = new Date(timestamp);\n const hours = String(date.getHours()).padStart(2, \"0\");\n const minutes = String(date.getMinutes()).padStart(2, \"0\");\n const seconds = String(date.getSeconds()).padStart(2, \"0\");\n return `${hours}:${minutes}:${seconds}`;\n}\n\nexport function TradesUI({ trades, onTradeClick }: TradesUIProps) {\n return (\n <div\n className=\"flex flex-col h-full overflow-auto\"\n style={{ backgroundColor: \"#000000\", fontSize: 11 }}\n >\n {/* Header */}\n <div\n className=\"sticky top-0 z-10 flex items-center\"\n style={{\n height: 28,\n minHeight: 28,\n padding: \"0 16px\",\n gap: 16,\n color: \"#6b6b6b\",\n fontSize: 11,\n }}\n >\n <div className=\"flex-1\" style={{ maxWidth: 100 }}>\n Price\n </div>\n <div className=\"flex-1 text-right\">Amount</div>\n <div className=\"flex-1 text-right\" style={{ maxWidth: 100 }}>\n Total\n </div>\n <div className=\"flex-1 text-right\" style={{ maxWidth: 70 }}>\n Time\n </div>\n </div>\n\n {/* Rows */}\n <div className=\"flex-1\">\n {trades.map((trade, index) => {\n const isBuy = trade.side === \"buy\";\n const total =\n typeof trade.price === \"number\" &&\n Number.isFinite(trade.price) &&\n typeof trade.quantity === \"number\" &&\n Number.isFinite(trade.quantity)\n ? trade.price * trade.quantity\n : undefined;\n\n return (\n <div\n key={`${trade.timestamp}-${trade.price}-${index}`}\n className=\"flex items-center cursor-pointer hover:bg-white/5 transition-colors\"\n style={{\n height: 22,\n minHeight: 22,\n maxHeight: 22,\n padding: \"0 16px\",\n gap: 16,\n fontSize: 11,\n }}\n onClick={() => onTradeClick?.(trade)}\n >\n <div className=\"flex-1\" style={{ maxWidth: 100 }}>\n <span\n style={{\n color: isBuy ? \"#C7FF2E\" : \"#F76816\",\n fontWeight: 400,\n }}\n >\n {formatPrice(trade.price)}\n </span>\n </div>\n <div className=\"flex-1 text-right\" style={{ color: \"#ffffff\" }}>\n {formatQuantity(trade.quantity)}\n </div>\n <div\n className=\"flex-1 text-right\"\n style={{ maxWidth: 100, color: \"#ffffff\" }}\n >\n {formatQuantity(total)}\n </div>\n <div\n className=\"flex-1 text-right\"\n style={{ maxWidth: 70, color: \"#b5b5b5\" }}\n >\n {formatTime(trade.timestamp)}\n </div>\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n","import { Skeleton } from \"@liberfi.io/ui\";\nimport type { Trade } from \"../../types\";\nimport { useTradesScript } from \"./trades.script\";\nimport { TradesUI } from \"./trades.ui\";\n\nexport type TradesWidgetProps = {\n symbol: string;\n limit?: number;\n onTradeClick?: (trade: Trade) => void;\n className?: string;\n};\n\nfunction TradesSkeleton() {\n return (\n <div className=\"flex flex-col h-full\" style={{ padding: \"0 16px\" }}>\n <div\n className=\"flex justify-between items-center\"\n style={{ height: 28, marginBottom: 4 }}\n >\n <Skeleton className=\"h-3 w-12 rounded\" />\n <Skeleton className=\"h-3 w-10 rounded\" />\n <Skeleton className=\"h-3 w-10 rounded\" />\n <Skeleton className=\"h-3 w-12 rounded\" />\n </div>\n {Array.from({ length: 12 }).map((_, i) => (\n <div\n key={`trade-skeleton-${i}`}\n className=\"flex justify-between items-center\"\n style={{ height: 22 }}\n >\n <Skeleton className=\"h-3 w-14 rounded\" />\n <Skeleton className=\"h-3 w-10 rounded\" />\n <Skeleton className=\"h-3 w-10 rounded\" />\n <Skeleton className=\"h-3 w-12 rounded\" />\n </div>\n ))}\n </div>\n );\n}\n\nfunction TradesEmpty() {\n return (\n <div className=\"flex items-center justify-center h-full\">\n <span className=\"text-neutral-400 text-sm\">No recent trades</span>\n </div>\n );\n}\n\nexport function TradesWidget({\n symbol,\n limit = 50,\n onTradeClick,\n className,\n}: TradesWidgetProps) {\n const { trades, isLoading } = useTradesScript({ symbol, limit });\n\n if (isLoading) {\n return <TradesSkeleton />;\n }\n\n if (trades.length === 0) {\n return <TradesEmpty />;\n }\n\n return (\n <div className={className}>\n <TradesUI trades={trades} onTradeClick={onTradeClick} />\n </div>\n );\n}\n","import { useState, useMemo, useCallback } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { useCreateOrderMutation } from \"../../hooks/useCreateOrderMutation\";\nimport { useMarketQuery } from \"../../hooks/useMarketQuery\";\nimport { usePositionsQuery } from \"../../hooks/usePositionsQuery\";\nimport type { OrderSide, OrderType } from \"../../types\";\n\nexport type PlaceOrderFormData = {\n price?: number;\n amount: number;\n leverage: number;\n takeProfitPrice?: number;\n takeProfitPercent?: number;\n stopLossPrice?: number;\n stopLossPercent?: number;\n};\n\nexport type UsePlaceOrderFormScriptParams = {\n symbol: string;\n userAddress?: string;\n maxLeverage?: number;\n onSuccess?: () => void;\n onError?: (error: Error) => void;\n};\n\nexport type UsePlaceOrderFormScriptResult = {\n form: ReturnType<typeof useForm<PlaceOrderFormData>>;\n side: OrderSide;\n orderType: OrderType;\n setSide: (side: OrderSide) => void;\n setOrderType: (type: OrderType) => void;\n handleSubmit: (data: PlaceOrderFormData) => Promise<void>;\n isSubmitting: boolean;\n currentPrice?: number;\n estimatedFee: number;\n estimatedTotal: number;\n liquidationPrice?: number;\n availableMargin: number;\n accountValue: number;\n currentPosition?: number;\n maxLeverage: number;\n};\n\nexport function usePlaceOrderFormScript({\n symbol,\n userAddress,\n maxLeverage: maxLeverageProp = 150,\n onSuccess,\n onError,\n}: UsePlaceOrderFormScriptParams): UsePlaceOrderFormScriptResult {\n const [side, setSide] = useState<OrderSide>(\"long\");\n const [orderType, setOrderType] = useState<OrderType>(\"market\");\n const form = useForm<PlaceOrderFormData>({\n defaultValues: {\n amount: 0,\n leverage: 20,\n takeProfitPrice: undefined,\n takeProfitPercent: undefined,\n stopLossPrice: undefined,\n stopLossPercent: undefined,\n },\n });\n\n const { data: marketData } = useMarketQuery({ symbol });\n\n const { mutateAsync: createOrder, isPending: isSubmitting } =\n useCreateOrderMutation({\n onSuccess: () => {\n form.reset();\n onSuccess?.();\n },\n onError: (error) => {\n onError?.(error);\n },\n });\n\n const watchedValues = form.watch();\n const { amount, leverage, price } = watchedValues;\n\n const currentPrice = useMemo(() => {\n if (orderType === \"limit\" && price) {\n return price;\n }\n return marketData?.price || 0;\n }, [orderType, price, marketData?.price]);\n\n const estimatedFee = useMemo(() => {\n if (!amount || !currentPrice) return 0;\n const feeRate = 0.0005;\n return amount * currentPrice * feeRate;\n }, [amount, currentPrice]);\n\n const estimatedTotal = useMemo(() => {\n if (!amount || !currentPrice) return 0;\n return amount * currentPrice + estimatedFee;\n }, [amount, currentPrice, estimatedFee]);\n\n const liquidationPrice = useMemo(() => {\n if (!amount || !currentPrice || !leverage || leverage === 1)\n return undefined;\n\n const maintenanceMarginRate = 0.005;\n const entryPrice = currentPrice;\n\n if (side === \"long\") {\n return entryPrice * (1 - (1 / leverage - maintenanceMarginRate));\n } else {\n return entryPrice * (1 + (1 / leverage - maintenanceMarginRate));\n }\n }, [amount, currentPrice, leverage, side]);\n\n // Real account / position data sourced from Hyperliquid `clearinghouseState`.\n // Falls back to 0 when the wallet isn't connected (the query stays disabled\n // until `userAddress` is set; see `usePositionsQuery`'s internal guard).\n const { data: positionsData } = usePositionsQuery({\n userAddress,\n symbol,\n });\n\n const accountValue = positionsData?.totalEquity ?? 0;\n const availableMargin = positionsData?.availableBalance ?? 0;\n const currentPosition = useMemo(() => {\n const pos = positionsData?.positions?.[0];\n if (!pos) return 0;\n return pos.side === \"short\" ? -pos.quantity : pos.quantity;\n }, [positionsData?.positions]);\n\n const handleSubmit = useCallback(\n async (data: PlaceOrderFormData) => {\n if (!userAddress) {\n throw new Error(\"User address is required\");\n }\n\n const finalPrice = orderType === \"limit\" ? data.price : undefined;\n\n let takeProfitPrice = data.takeProfitPrice;\n let stopLossPrice = data.stopLossPrice;\n\n if (\n !takeProfitPrice &&\n data.takeProfitPercent &&\n data.takeProfitPercent > 0 &&\n currentPrice\n ) {\n const tpPercent = data.takeProfitPercent / 100;\n takeProfitPrice =\n side === \"long\"\n ? currentPrice * (1 + tpPercent)\n : currentPrice * (1 - tpPercent);\n }\n\n if (\n !stopLossPrice &&\n data.stopLossPercent &&\n data.stopLossPercent > 0 &&\n currentPrice\n ) {\n const slPercent = data.stopLossPercent / 100;\n stopLossPrice =\n side === \"long\"\n ? currentPrice * (1 - slPercent)\n : currentPrice * (1 + slPercent);\n }\n\n await createOrder({\n symbol,\n side,\n orderType,\n amount: data.amount,\n price: finalPrice,\n leverage: data.leverage,\n takeProfitPrice,\n stopLossPrice,\n userAddress,\n });\n },\n [symbol, side, orderType, currentPrice, userAddress, createOrder],\n );\n\n return {\n form,\n side,\n orderType,\n setSide,\n setOrderType,\n handleSubmit,\n isSubmitting,\n currentPrice,\n estimatedFee,\n estimatedTotal,\n liquidationPrice,\n availableMargin,\n accountValue,\n currentPosition,\n maxLeverage: maxLeverageProp,\n };\n}\n","import { useState } from \"react\";\nimport type { UseFormReturn } from \"react-hook-form\";\nimport { cn, RHForm, RHNumberInput, Slider } from \"@liberfi.io/ui\";\nimport type { OrderSide, OrderType } from \"../../types\";\nimport type { PlaceOrderFormData } from \"./place-order-form.script\";\n\nexport type PlaceOrderFormUIProps = {\n methods: UseFormReturn<PlaceOrderFormData>;\n side: OrderSide;\n orderType: OrderType;\n onSideChange: (side: OrderSide) => void;\n onOrderTypeChange: (type: OrderType) => void;\n onSubmit: (data: PlaceOrderFormData) => Promise<void>;\n isSubmitting: boolean;\n symbol: string;\n currentPrice?: number;\n estimatedFee: number;\n estimatedTotal: number;\n liquidationPrice?: number;\n availableMargin: number;\n accountValue: number;\n currentPosition?: number;\n maxLeverage: number;\n /**\n * Optional callback fired when the user clicks the \"Add More Funds\"\n * button (typically wired by the host app to open a deposit dialog).\n * The button is hidden when this prop is omitted, so consumers that\n * don't support a deposit flow don't render a dead control.\n */\n onAddFunds?: () => void;\n};\n\nfunction formatNumber(num: number, decimals: number = 2): string {\n return num.toFixed(decimals);\n}\n\nfunction LeverageModal({\n leverage,\n maxLeverage,\n onLeverageChange,\n onClose,\n}: {\n leverage: number;\n maxLeverage: number;\n onLeverageChange: (v: number) => void;\n onClose: () => void;\n}) {\n const presets = [1, 2, 3, 5, 10, 20, 25, 50, 100].filter(\n (v) => v <= maxLeverage,\n );\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n <div\n className=\"absolute inset-0 bg-black/60\"\n onClick={onClose}\n onKeyDown={(e) => e.key === \"Escape\" && onClose()}\n role=\"button\"\n tabIndex={-1}\n aria-label=\"Close\"\n />\n <div className=\"relative z-10 w-72 bg-neutral-900 border border-neutral-700 rounded-lg p-4 shadow-2xl\">\n <div className=\"flex items-center justify-between mb-4\">\n <h3 className=\"text-sm font-medium text-white\">Adjust Leverage</h3>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"text-neutral-400 hover:text-white\"\n >\n <svg\n className=\"w-4 h-4\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n </div>\n\n <div className=\"text-center text-2xl font-bold text-white mb-4\">\n {leverage}x\n </div>\n\n <Slider\n value={[leverage]}\n onChange={(value: number | number[]) =>\n onLeverageChange(Array.isArray(value) ? value[0] : value)\n }\n minValue={1}\n maxValue={maxLeverage}\n step={1}\n className=\"w-full mb-3\"\n />\n\n <div className=\"flex flex-wrap gap-1.5\">\n {presets.map((preset) => (\n <button\n key={preset}\n type=\"button\"\n className={cn(\n \"px-2.5 py-1 text-xs rounded transition-colors\",\n leverage === preset\n ? \"bg-green-600 text-white\"\n : \"bg-neutral-800 text-neutral-400 hover:bg-neutral-700\",\n )}\n onClick={() => onLeverageChange(preset)}\n >\n {preset}x\n </button>\n ))}\n </div>\n\n <button\n type=\"button\"\n className=\"w-full mt-4 text-white h-9 rounded cursor-pointer transition-colors\"\n style={{ backgroundColor: \"#C7FF2E\" }}\n onClick={onClose}\n >\n Confirm\n </button>\n </div>\n </div>\n );\n}\n\nexport function PlaceOrderFormUI({\n methods,\n side,\n orderType,\n onSideChange,\n onOrderTypeChange,\n onSubmit,\n isSubmitting,\n symbol,\n currentPrice,\n estimatedFee,\n liquidationPrice,\n availableMargin,\n accountValue,\n currentPosition,\n maxLeverage,\n onAddFunds,\n}: PlaceOrderFormUIProps) {\n const [showLeverageModal, setShowLeverageModal] = useState(false);\n const [showTpSl, setShowTpSl] = useState(false);\n const leverage = methods.watch(\"leverage\") || 20;\n const amount = methods.watch(\"amount\") || 0;\n const tokenSymbol = symbol.split(\"-\")[0];\n\n const positionPercent =\n availableMargin > 0 && currentPrice\n ? Math.min(\n ((amount * currentPrice) / (availableMargin * leverage)) * 100,\n 100,\n )\n : 0;\n\n const handlePositionSlider = (value: number | number[]) => {\n const pct = (Array.isArray(value) ? value[0] : value) / 100;\n if (currentPrice && currentPrice > 0) {\n const maxAmount = (availableMargin * leverage * pct) / currentPrice;\n methods.setValue(\"amount\", Number(maxAmount.toFixed(6)));\n }\n };\n\n return (\n <div\n className=\"flex flex-col h-full\"\n style={{ backgroundColor: \"#000000\" }}\n >\n <div\n className=\"perp-order-form flex-1 overflow-y-auto\"\n style={{\n padding: \"16px 16px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: 16,\n }}\n >\n {/* Long / Short */}\n <div\n className=\"flex\"\n style={{\n border: \"1px solid rgba(26,26,26,0.5)\",\n borderRadius: 8,\n padding: 4,\n gap: 4,\n }}\n >\n <button\n type=\"button\"\n className=\"flex-1 cursor-pointer transition-colors\"\n style={{\n height: 32,\n fontSize: 16,\n borderRadius: 4,\n backgroundColor: side === \"long\" ? \"#C7FF2E\" : \"transparent\",\n color: side === \"long\" ? \"#000000\" : \"#b5b5b5\",\n fontWeight: side === \"long\" ? 700 : 500,\n }}\n onClick={() => onSideChange(\"long\")}\n >\n Long\n </button>\n <button\n type=\"button\"\n className=\"flex-1 cursor-pointer transition-colors\"\n style={{\n height: 32,\n fontSize: 16,\n borderRadius: 4,\n backgroundColor: side === \"short\" ? \"#F76816\" : \"transparent\",\n color: side === \"short\" ? \"#000000\" : \"#b5b5b5\",\n fontWeight: side === \"short\" ? 700 : 500,\n }}\n onClick={() => onSideChange(\"short\")}\n >\n Short\n </button>\n </div>\n\n {/* Market / Limit + Leverage button */}\n <div className=\"flex items-center\" style={{ gap: 8 }}>\n <div className=\"flex\">\n {[\n { key: \"market\" as const, label: \"Market\" },\n { key: \"limit\" as const, label: \"Limit\" },\n ].map((tab) => (\n <div\n key={tab.key}\n style={{\n height: 32,\n display: \"flex\",\n alignItems: \"center\",\n borderBottom:\n orderType === tab.key\n ? \"2px solid #ffffff\"\n : \"2px solid transparent\",\n padding: \"2px 0 0\",\n cursor: \"pointer\",\n }}\n >\n <button\n type=\"button\"\n className=\"cursor-pointer transition-colors\"\n style={{\n padding: \"0 8px\",\n fontSize: 12,\n fontWeight: 500,\n backgroundColor: \"transparent\",\n color: orderType === tab.key ? \"#ffffff\" : \"#b5b5b5\",\n border: \"none\",\n }}\n onClick={() => onOrderTypeChange(tab.key)}\n >\n {tab.label}\n </button>\n </div>\n ))}\n </div>\n <div className=\"flex-1\" />\n <button\n type=\"button\"\n className=\"cursor-pointer transition-colors\"\n style={{\n height: 24,\n padding: \"0 5px\",\n fontSize: 12,\n borderRadius: 4,\n backgroundColor: \"rgba(26,26,26,0.5)\",\n color: \"#ffffff\",\n fontWeight: 400,\n border: \"1px solid rgba(26,26,26,0.5)\",\n }}\n onClick={() => setShowLeverageModal(true)}\n >\n Leverage: {leverage}x\n </button>\n </div>\n\n <RHForm methods={methods} onSubmit={onSubmit}>\n <div className=\"space-y-3 w-full\">\n {/* Limit price input */}\n {orderType === \"limit\" && (\n <div\n className=\"perp-price-box\"\n style={{\n borderRadius: 4,\n padding: 8,\n backgroundColor: \"rgba(26,26,26,0.5)\",\n border: \"1px solid #1c1c1c\",\n height: 64,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n }}\n >\n <div className=\"flex justify-between items-center\">\n <span style={{ fontSize: 12, color: \"#6b6b6b\" }}>Price</span>\n <span style={{ fontSize: 12, color: \"#6b6b6b\" }}>USDC</span>\n </div>\n <RHNumberInput\n name=\"price\"\n placeholder=\"0.0 USDC\"\n className=\"w-full\"\n />\n </div>\n )}\n\n {/* Buy Amount */}\n <div\n className=\"perp-buy-amt\"\n style={{\n borderRadius: 4,\n padding: 8,\n backgroundColor: \"rgba(26,26,26,0.5)\",\n border: \"1px solid #1c1c1c\",\n height: 64,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n }}\n >\n <div className=\"flex justify-between items-center\">\n <span style={{ fontSize: 12, color: \"#6b6b6b\" }}>\n Buy Amount\n </span>\n <span style={{ fontSize: 12, color: \"#6b6b6b\" }}>\n {tokenSymbol}\n </span>\n </div>\n <RHNumberInput\n name=\"amount\"\n placeholder=\"0.0 USDC\"\n className=\"w-full\"\n />\n </div>\n\n {/* Position size slider */}\n <div>\n <style>{`\n .perp-buy-amt input, .perp-price-box input { font-size: 18px !important; line-height: 23px !important; }\n .perp-order-form .group,\n .perp-order-form .group div { background: transparent !important; border: none !important; padding: 0 !important; border-radius: 0 !important; min-height: 0 !important; height: auto !important; }\n .perp-order-form .group input { color: #ffffff !important; }\n .perp-slider { -webkit-appearance: none; appearance: none; background: transparent; cursor: pointer; width: 100%; height: 16px; }\n .perp-slider::-webkit-slider-runnable-track { height: 4px; border-radius: 2px; background: #1c1c1c; }\n .perp-slider::-webkit-slider-thumb { -webkit-appearance: none; width: 12px; height: 12px; border-radius: 50%; background: #C7FF2E; margin-top: -4px; border: none; }\n .perp-slider::-moz-range-track { height: 4px; border-radius: 2px; background: #1c1c1c; border: none; }\n .perp-slider::-moz-range-thumb { width: 12px; height: 12px; border-radius: 50%; background: #C7FF2E; border: none; }\n `}</style>\n <input\n type=\"range\"\n value={Math.round(positionPercent)}\n onChange={(e) => handlePositionSlider(Number(e.target.value))}\n min={0}\n max={100}\n step={1}\n className=\"perp-slider\"\n />\n <div\n className=\"flex justify-between\"\n style={{ fontSize: 10, color: \"#b5b5b5\", marginTop: 4 }}\n >\n <span>0%</span>\n <span>25%</span>\n <span>50%</span>\n <span>75%</span>\n <span>100%</span>\n </div>\n </div>\n\n {/* TP/SL + Est. Liq. Price */}\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center\" style={{ gap: 6 }}>\n <div\n onClick={() => setShowTpSl((v) => !v)}\n style={{\n width: 16,\n height: 16,\n borderRadius: 4,\n border: \"1px solid #2a2a2a\",\n backgroundColor: showTpSl ? \"#C7FF2E\" : \"transparent\",\n flexShrink: 0,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n {showTpSl && (\n <svg width=\"10\" height=\"8\" viewBox=\"0 0 10 8\" fill=\"none\">\n <path\n d=\"M1 4L3.5 6.5L9 1\"\n stroke=\"#000000\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )}\n </div>\n <span\n style={{ fontSize: 12, fontWeight: 500, color: \"#b5b5b5\" }}\n >\n TP/SL\n </span>\n </div>\n <div style={{ fontSize: 12, color: \"#6b6b6b\" }}>\n <span>Est. Liq. Price: </span>\n <span style={{ color: \"#b5b5b5\" }}>\n {liquidationPrice ? formatNumber(liquidationPrice, 2) : \"--\"}\n </span>\n </div>\n </div>\n\n {/* TP Price inputs (visible when TP/SL checked) */}\n {showTpSl && (\n <div className=\"flex\" style={{ gap: 8 }}>\n <div className=\"flex-1\">\n <span\n style={{\n fontSize: 12,\n color: \"#6b6b6b\",\n marginBottom: 2,\n display: \"block\",\n }}\n >\n TP Price\n </span>\n <RHNumberInput\n name=\"takeProfitPrice\"\n placeholder=\"Enter TP price\"\n className=\"w-full\"\n style={{\n fontSize: 12,\n height: 32,\n padding: \"0 8px\",\n border: \"1px solid #1c1c1c\",\n borderRadius: 4,\n }}\n />\n </div>\n <div style={{ width: 70 }}>\n <span\n style={{\n fontSize: 12,\n color: \"#6b6b6b\",\n marginBottom: 2,\n display: \"block\",\n }}\n >\n TP %\n </span>\n <RHNumberInput\n name=\"takeProfitPercent\"\n placeholder=\"0.0\"\n className=\"w-full\"\n style={{\n fontSize: 12,\n height: 32,\n padding: \"0 8px\",\n border: \"1px solid #1c1c1c\",\n borderRadius: 4,\n }}\n />\n </div>\n </div>\n )}\n\n {/* Add More Funds — only rendered when the host wires a handler */}\n {onAddFunds && (\n <button\n type=\"button\"\n onClick={onAddFunds}\n className=\"w-full cursor-pointer transition-colors\"\n style={{\n height: 36,\n fontSize: 14,\n fontWeight: 700,\n color: \"#000000\",\n backgroundColor: \"#C7FF2E\",\n borderRadius: 9999,\n border: \"none\",\n }}\n >\n Add More Funds\n </button>\n )}\n\n {/* SL Price inputs (visible when TP/SL checked) */}\n {showTpSl && (\n <div className=\"flex\" style={{ gap: 8 }}>\n <div className=\"flex-1\">\n <span\n style={{\n fontSize: 12,\n color: \"#6b6b6b\",\n marginBottom: 2,\n display: \"block\",\n }}\n >\n SL Price\n </span>\n <RHNumberInput\n name=\"stopLossPrice\"\n placeholder=\"Enter SL price\"\n className=\"w-full\"\n style={{\n fontSize: 12,\n height: 32,\n padding: \"0 8px\",\n border: \"1px solid #1c1c1c\",\n borderRadius: 4,\n }}\n />\n </div>\n <div style={{ width: 70 }}>\n <span\n style={{\n fontSize: 12,\n color: \"#6b6b6b\",\n marginBottom: 2,\n display: \"block\",\n }}\n >\n SL %\n </span>\n <RHNumberInput\n name=\"stopLossPercent\"\n placeholder=\"0.0\"\n className=\"w-full\"\n style={{\n fontSize: 12,\n height: 32,\n padding: \"0 8px\",\n border: \"1px solid #1c1c1c\",\n borderRadius: 4,\n }}\n />\n </div>\n </div>\n )}\n </div>\n </RHForm>\n </div>\n\n {/* Account info + branding footer */}\n <div\n style={{\n padding: \"10px 16px\",\n fontSize: 12,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 6,\n }}\n >\n <div className=\"flex justify-between items-center\">\n <span style={{ color: \"#6b6b6b\" }}>Available Margin</span>\n <span style={{ color: \"#C7FF2E\", fontSize: 12, fontWeight: 500 }}>\n {formatNumber(availableMargin)} USDC\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span style={{ color: \"#6b6b6b\" }}>Perps Account Value</span>\n <span style={{ color: \"#b5b5b5\", fontSize: 12 }}>\n {formatNumber(accountValue)} USDC\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span style={{ color: \"#6b6b6b\" }}>Current Position</span>\n <span style={{ color: \"#b5b5b5\", fontSize: 12 }}>\n {currentPosition ? formatNumber(currentPosition) : \"--\"}\n </span>\n </div>\n <div\n className=\"flex items-center justify-end\"\n style={{ gap: 6, paddingTop: 8 }}\n >\n <span style={{ fontSize: 11, color: \"#6b6b6b\" }}>powered by</span>\n <img\n src=\"https://axiom-assets.sfo3.cdn.digitaloceanspaces.com/images/hyperliquid-logo.svg\"\n alt=\"Hyperliquid\"\n className=\"h-3 opacity-60\"\n onError={(e) => {\n const target = e.target as HTMLImageElement;\n target.style.display = \"none\";\n }}\n />\n </div>\n </div>\n\n {/* Leverage modal */}\n {showLeverageModal && (\n <LeverageModal\n leverage={leverage}\n maxLeverage={maxLeverage}\n onLeverageChange={(v) => methods.setValue(\"leverage\", v)}\n onClose={() => setShowLeverageModal(false)}\n />\n )}\n </div>\n );\n}\n","import { usePlaceOrderFormScript } from \"./place-order-form.script\";\nimport { PlaceOrderFormUI } from \"./place-order-form.ui\";\n\nexport type PlaceOrderFormWidgetProps = {\n symbol: string;\n userAddress?: string;\n maxLeverage?: number;\n onSuccess?: () => void;\n onError?: (error: Error) => void;\n /**\n * Optional callback fired when the user clicks \"Add More Funds\".\n * The host app typically opens its deposit dialog here. When omitted,\n * the button is hidden so the form doesn't expose a non-functional\n * control.\n */\n onAddFunds?: () => void;\n className?: string;\n};\n\nexport function PlaceOrderFormWidget({\n symbol,\n userAddress,\n maxLeverage,\n onSuccess,\n onError,\n onAddFunds,\n className,\n}: PlaceOrderFormWidgetProps) {\n const {\n form,\n side,\n orderType,\n setSide,\n setOrderType,\n handleSubmit,\n isSubmitting,\n currentPrice,\n estimatedFee,\n estimatedTotal,\n liquidationPrice,\n availableMargin,\n accountValue,\n currentPosition,\n maxLeverage: resolvedMaxLeverage,\n } = usePlaceOrderFormScript({\n symbol,\n userAddress,\n maxLeverage,\n onSuccess,\n onError,\n });\n\n return (\n <div className={className}>\n <PlaceOrderFormUI\n methods={form}\n side={side}\n orderType={orderType}\n onSideChange={setSide}\n onOrderTypeChange={setOrderType}\n onSubmit={handleSubmit}\n isSubmitting={isSubmitting}\n symbol={symbol}\n currentPrice={currentPrice}\n estimatedFee={estimatedFee}\n estimatedTotal={estimatedTotal}\n liquidationPrice={liquidationPrice}\n availableMargin={availableMargin}\n accountValue={accountValue}\n currentPosition={currentPosition}\n maxLeverage={resolvedMaxLeverage}\n onAddFunds={onAddFunds}\n />\n </div>\n );\n}\n","import { useState, useEffect, useCallback } from \"react\";\nimport { useCreateOrderMutation } from \"../../hooks/useCreateOrderMutation\";\nimport { usePositionsQuery } from \"../../hooks/usePositionsQuery\";\nimport { useUserDataSubscription } from \"../../hooks/useUserDataSubscription\";\nimport type { Position } from \"../../types\";\n\nexport type UsePositionsScriptParams = {\n userAddress?: string;\n symbol?: string;\n onCloseSuccess?: () => void;\n onCloseError?: (error: Error) => void;\n};\n\nexport type UsePositionsScriptResult = {\n positions: Position[];\n isLoading: boolean;\n error: Error | null;\n handleClosePosition: (position: Position) => Promise<void>;\n isClosing: boolean;\n};\n\nexport function usePositionsScript({\n userAddress,\n symbol,\n onCloseSuccess,\n onCloseError,\n}: UsePositionsScriptParams): UsePositionsScriptResult {\n const [positions, setPositions] = useState<Position[]>([]);\n\n // Fetch initial positions data\n const {\n data: positionsData,\n isLoading,\n error,\n } = usePositionsQuery({ userAddress, symbol }, { enabled: !!userAddress });\n\n // Subscribe to realtime position updates\n const { data: realtimePosition } = useUserDataSubscription<Position>({\n type: \"positions\",\n userAddress: userAddress || \"\",\n enabled: !!userAddress,\n });\n\n // Mutation for closing position (by placing opposite order)\n const { mutateAsync: createOrder, isPending: isClosing } =\n useCreateOrderMutation({\n onSuccess: () => {\n onCloseSuccess?.();\n },\n onError: (error) => {\n onCloseError?.(error);\n },\n });\n\n // Initialize positions data\n useEffect(() => {\n if (positionsData?.positions) {\n setPositions(positionsData.positions);\n }\n }, [positionsData]);\n\n // Handle realtime position updates\n useEffect(() => {\n if (realtimePosition) {\n setPositions((prevPositions) => {\n const existingIndex = prevPositions.findIndex(\n (p) => p.symbol === realtimePosition.symbol,\n );\n\n // If position quantity is 0, remove the position\n if (realtimePosition.quantity === 0) {\n if (existingIndex !== -1) {\n return prevPositions.filter((_, i) => i !== existingIndex);\n }\n return prevPositions;\n }\n\n // Update existing position\n if (existingIndex !== -1) {\n const newPositions = [...prevPositions];\n newPositions[existingIndex] = realtimePosition;\n return newPositions;\n }\n\n // Add new position\n return [...prevPositions, realtimePosition];\n });\n }\n }, [realtimePosition]);\n\n // Close position by placing opposite market order\n const handleClosePosition = useCallback(\n async (position: Position) => {\n if (!userAddress) {\n throw new Error(\"User address is required\");\n }\n\n // Close = place opposite side market order\n const closeSide = position.side === \"long\" ? \"short\" : \"long\";\n\n await createOrder({\n symbol: position.symbol,\n side: closeSide,\n orderType: \"market\",\n amount: Math.abs(position.quantity),\n leverage: position.leverage,\n userAddress,\n });\n },\n [userAddress, createOrder],\n );\n\n return {\n positions,\n isLoading,\n error,\n handleClosePosition,\n isClosing,\n };\n}\n","import { Button, cn } from \"@liberfi.io/ui\";\nimport type { Position } from \"../../types\";\n\nexport type PositionsUIProps = {\n positions: Position[];\n onClosePosition: (position: Position) => void;\n isClosing: boolean;\n};\n\nfunction formatNumber(num: number, decimals: number = 2): string {\n return num.toFixed(decimals);\n}\n\nfunction formatPrice(price: number): string {\n return formatNumber(price, 4);\n}\n\nfunction formatQuantity(quantity: number): string {\n return formatNumber(Math.abs(quantity), 4);\n}\n\nfunction formatPnl(pnl: number): string {\n const sign = pnl >= 0 ? \"+\" : \"\";\n return `${sign}${formatNumber(pnl, 2)}`;\n}\n\nfunction formatPnlPercent(percent: number): string {\n const sign = percent >= 0 ? \"+\" : \"\";\n return `${sign}${formatNumber(percent, 2)}%`;\n}\n\nexport function PositionsUI({\n positions,\n onClosePosition,\n isClosing,\n}: PositionsUIProps) {\n const headerRow = (\n <tr style={{ borderBottom: \"1px solid #1c1c1c\" }}>\n <th\n className=\"text-left py-1.5 px-3 font-normal\"\n style={{ fontSize: 12, color: \"#6b6b6b\" }}\n >\n Asset\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 12, color: \"#6b6b6b\" }}\n >\n Position\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 12, color: \"#6b6b6b\" }}\n >\n Position Value\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 12, color: \"#6b6b6b\" }}\n >\n Entry Price\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 12, color: \"#6b6b6b\" }}\n >\n Mark Price\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 12, color: \"#6b6b6b\" }}\n >\n Liquidation\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 12, color: \"#6b6b6b\" }}\n >\n {\"Margin Used (PNL) \\u2193\"}\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 12, color: \"#6b6b6b\" }}\n >\n TP\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 12, color: \"#6b6b6b\" }}\n >\n SL\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 12, color: \"#6b6b6b\" }}\n >\n Close\n </th>\n </tr>\n );\n\n if (positions.length === 0) {\n return (\n <div className=\"w-full overflow-x-auto bg-transparent\">\n <table className=\"w-full\" style={{ fontSize: 12 }}>\n <thead>{headerRow}</thead>\n </table>\n <div\n className=\"flex items-center justify-center\"\n style={{ fontSize: 14, color: \"#b5b5b5\", padding: \"24px 0\" }}\n >\n No open positions\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"w-full overflow-x-auto bg-transparent\">\n <table className=\"w-full\" style={{ fontSize: 12 }}>\n <thead>{headerRow}</thead>\n <tbody>\n {positions.map((position) => {\n const isProfitable = position.unrealizedPnl >= 0;\n const pnlColor = isProfitable ? \"text-bullish\" : \"text-bearish\";\n\n return (\n <tr\n key={position.symbol}\n className=\"hover:bg-neutral-900/50\"\n style={{ borderBottom: \"1px solid #1c1c1c\" }}\n >\n {/* Asset */}\n <td className=\"py-1.5 px-3\">\n <div className=\"flex flex-col\">\n <span className=\"font-medium\" style={{ color: \"#ffffff\" }}>\n {position.symbol.split(\"-\")[0]}\n </span>\n <span\n className={cn(\n position.side === \"long\"\n ? \"text-bullish\"\n : \"text-bearish\",\n )}\n >\n {position.leverage}x {position.side.toUpperCase()}\n </span>\n </div>\n </td>\n\n {/* Position */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#ffffff\" }}\n >\n {formatQuantity(position.quantity)}\n </td>\n\n {/* Position Value */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#ffffff\" }}\n >\n ${formatNumber(position.notionalValue)}\n </td>\n\n {/* Entry Price */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#ffffff\" }}\n >\n ${formatPrice(position.entryPrice)}\n </td>\n\n {/* Mark Price */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#ffffff\" }}\n >\n ${formatPrice(position.markPrice)}\n </td>\n\n {/* Liquidation Price */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#ffffff\" }}\n >\n {position.liquidationPrice\n ? `$${formatPrice(position.liquidationPrice)}`\n : \"-\"}\n </td>\n\n {/* Margin Used (PnL) */}\n <td className=\"py-1.5 px-3 text-right\">\n <div className=\"flex flex-col items-end\">\n <span style={{ color: \"#ffffff\" }}>\n ${formatNumber(position.margin)}\n </span>\n <span className={pnlColor}>\n {formatPnl(position.unrealizedPnl)} (\n {formatPnlPercent(position.unrealizedPnlPercent)})\n </span>\n </div>\n </td>\n\n {/* TP */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#b5b5b5\" }}\n >\n -\n </td>\n\n {/* SL */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#b5b5b5\" }}\n >\n -\n </td>\n\n {/* Close */}\n <td className=\"py-1.5 px-3 text-right\">\n <Button\n size=\"sm\"\n onClick={() => onClosePosition(position)}\n isLoading={isClosing}\n className=\"bg-red-600 hover:bg-red-700 text-white text-xs px-3 py-1\"\n >\n Close\n </Button>\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n );\n}\n\n/** Loading skeleton for positions panel */\nexport function PositionsSkeleton() {\n return (\n <div className=\"w-full space-y-4 p-4\">\n <div className=\"h-4 bg-neutral-800 rounded w-full animate-pulse\" />\n <div className=\"h-4 bg-neutral-800 rounded w-full animate-pulse\" />\n <div className=\"h-4 bg-neutral-800 rounded w-full animate-pulse\" />\n </div>\n );\n}\n\n/** Empty state when there are no open positions */\nexport function PositionsEmpty() {\n return (\n <div\n className=\"flex items-center justify-center h-24\"\n style={{ fontSize: 14, color: \"#b5b5b5\" }}\n >\n No open positions\n </div>\n );\n}\n","import { usePositionsScript } from \"./positions.script\";\nimport { PositionsUI, PositionsSkeleton, PositionsEmpty } from \"./positions.ui\";\n\nexport type PositionsWidgetProps = {\n userAddress?: string;\n symbol?: string;\n onCloseSuccess?: () => void;\n onCloseError?: (error: Error) => void;\n className?: string;\n};\n\nexport function PositionsWidget({\n userAddress,\n symbol,\n onCloseSuccess,\n onCloseError,\n className,\n}: PositionsWidgetProps) {\n const { positions, isLoading, handleClosePosition, isClosing } =\n usePositionsScript({\n userAddress,\n symbol,\n onCloseSuccess,\n onCloseError,\n });\n\n if (isLoading) {\n return (\n <div className={className}>\n <PositionsSkeleton />\n </div>\n );\n }\n\n return (\n <div className={className}>\n <PositionsUI\n positions={positions}\n onClosePosition={handleClosePosition}\n isClosing={isClosing}\n />\n </div>\n );\n}\n","import { useState, useEffect, useCallback } from \"react\";\nimport { useCancelOrderMutation } from \"../../hooks/useCancelOrderMutation\";\nimport { useOrdersQuery } from \"../../hooks/useOrdersQuery\";\nimport { useUserDataSubscription } from \"../../hooks/useUserDataSubscription\";\nimport type { Order } from \"../../types\";\n\nexport type UseOpenOrdersScriptParams = {\n userAddress?: string;\n symbol?: string;\n onCancelSuccess?: () => void;\n onCancelError?: (error: Error) => void;\n};\n\nexport type UseOpenOrdersScriptResult = {\n orders: Order[];\n isLoading: boolean;\n error: Error | null;\n handleCancelOrder: (order: Order) => Promise<void>;\n isCanceling: boolean;\n};\n\nexport function useOpenOrdersScript({\n userAddress,\n symbol,\n onCancelSuccess,\n onCancelError,\n}: UseOpenOrdersScriptParams): UseOpenOrdersScriptResult {\n const [orders, setOrders] = useState<Order[]>([]);\n\n // Fetch initial orders data\n const {\n data: ordersData,\n isLoading,\n error,\n } = useOrdersQuery({ userAddress, symbol }, { enabled: !!userAddress });\n\n // Subscribe to realtime order updates\n const { data: realtimeOrder } = useUserDataSubscription<Order>({\n type: \"orders\",\n userAddress: userAddress || \"\",\n enabled: !!userAddress,\n });\n\n // Cancel order mutation\n const { mutateAsync: cancelOrder, isPending: isCanceling } =\n useCancelOrderMutation({\n onSuccess: () => {\n onCancelSuccess?.();\n },\n onError: (error) => {\n onCancelError?.(error);\n },\n });\n\n // Initialize orders data\n useEffect(() => {\n if (ordersData?.orders) {\n setOrders(ordersData.orders);\n }\n }, [ordersData]);\n\n // Handle realtime order updates\n useEffect(() => {\n if (realtimeOrder) {\n setOrders((prevOrders) => {\n const existingIndex = prevOrders.findIndex(\n (o) => o.orderId === realtimeOrder.orderId,\n );\n\n // If order is cancelled, filled or rejected, remove from list\n if (\n realtimeOrder.status === \"cancelled\" ||\n realtimeOrder.status === \"filled\" ||\n realtimeOrder.status === \"rejected\"\n ) {\n if (existingIndex !== -1) {\n return prevOrders.filter((_, i) => i !== existingIndex);\n }\n return prevOrders;\n }\n\n // Update existing order\n if (existingIndex !== -1) {\n const newOrders = [...prevOrders];\n newOrders[existingIndex] = realtimeOrder;\n return newOrders;\n }\n\n // Add new order\n return [realtimeOrder, ...prevOrders];\n });\n }\n }, [realtimeOrder]);\n\n // Handle cancel order\n const handleCancelOrder = useCallback(\n async (order: Order) => {\n if (!userAddress) {\n throw new Error(\"User address is required\");\n }\n\n await cancelOrder({\n orderId: order.orderId,\n symbol: order.symbol,\n userAddress,\n });\n },\n [userAddress, cancelOrder],\n );\n\n return {\n orders,\n isLoading,\n error,\n handleCancelOrder,\n isCanceling,\n };\n}\n","import { Button, cn } from \"@liberfi.io/ui\";\nimport type { Order } from \"../../types\";\n\nexport type OpenOrdersUIProps = {\n orders: Order[];\n onCancelOrder: (order: Order) => void;\n isCanceling: boolean;\n};\n\nfunction formatNumber(num: number, decimals: number = 2): string {\n return num.toFixed(decimals);\n}\n\nfunction formatPrice(price: number): string {\n return formatNumber(price, 4);\n}\n\nfunction formatQuantity(quantity: number): string {\n return formatNumber(quantity, 4);\n}\n\nfunction formatTime(timestamp: number): string {\n const date = new Date(timestamp);\n const hours = String(date.getHours()).padStart(2, \"0\");\n const minutes = String(date.getMinutes()).padStart(2, \"0\");\n const seconds = String(date.getSeconds()).padStart(2, \"0\");\n return `${hours}:${minutes}:${seconds}`;\n}\n\nexport function OpenOrdersUI({\n orders,\n onCancelOrder,\n isCanceling,\n}: OpenOrdersUIProps) {\n if (orders.length === 0) {\n return (\n <div\n className=\"flex items-center justify-center h-24\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n No open orders\n </div>\n );\n }\n\n return (\n <div className=\"w-full overflow-x-auto bg-transparent\">\n <table className=\"w-full\" style={{ fontSize: 11 }}>\n <thead>\n <tr style={{ borderBottom: \"1px solid #1c1c1c\" }}>\n <th\n className=\"text-left py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Asset\n </th>\n <th\n className=\"text-left py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Type\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Price\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Amount\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Filled\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Remaining\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Status\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Time\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Action\n </th>\n </tr>\n </thead>\n <tbody>\n {orders.map((order) => {\n return (\n <tr\n key={order.orderId}\n className=\"hover:bg-neutral-900/50\"\n style={{ borderBottom: \"1px solid #1c1c1c\" }}\n >\n {/* Asset */}\n <td className=\"py-1.5 px-3\">\n <div className=\"flex flex-col\">\n <span className=\"font-medium\" style={{ color: \"#ffffff\" }}>\n {order.symbol.split(\"-\")[0]}\n </span>\n <span\n className={cn(\n order.side === \"long\" ? \"text-bullish\" : \"text-bearish\",\n )}\n >\n {order.side.toUpperCase()}\n {order.leverage ? ` ${order.leverage}x` : \"\"}\n </span>\n </div>\n </td>\n\n {/* Type */}\n <td\n className=\"py-1.5 px-3 capitalize\"\n style={{ color: \"#ffffff\" }}\n >\n {order.orderType}\n </td>\n\n {/* Price */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#ffffff\" }}\n >\n {order.orderType === \"market\" ? (\n <span style={{ color: \"#b5b5b5\" }}>Market</span>\n ) : (\n `$${formatPrice(order.price)}`\n )}\n </td>\n\n {/* Amount */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#ffffff\" }}\n >\n {formatQuantity(order.quantity)}\n </td>\n\n {/* Filled */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#ffffff\" }}\n >\n {formatQuantity(order.filledQuantity)}\n </td>\n\n {/* Remaining */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#ffffff\" }}\n >\n {formatQuantity(order.remainingQuantity)}\n </td>\n\n {/* Status */}\n <td className=\"py-1.5 px-3 text-right\">\n <span\n className={cn(\n \"px-2 py-0.5 rounded\",\n \"text-[11px]\",\n order.status === \"pending\" &&\n \"bg-yellow-600/20 text-yellow-500\",\n order.status === \"partially_filled\" &&\n \"bg-blue-600/20 text-blue-500\",\n order.status === \"filled\" &&\n \"bg-green-600/20 text-green-500\",\n order.status === \"cancelled\" &&\n \"bg-neutral-600/20 text-neutral-400\",\n order.status === \"rejected\" &&\n \"bg-red-600/20 text-red-500\",\n )}\n >\n {order.status.replace(\"_\", \" \")}\n </span>\n </td>\n\n {/* Time */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#b5b5b5\" }}\n >\n {formatTime(order.timestamp)}\n </td>\n\n {/* Action */}\n <td className=\"py-1.5 px-3 text-right\">\n {order.status === \"pending\" ||\n order.status === \"partially_filled\" ? (\n <Button\n size=\"sm\"\n onClick={() => onCancelOrder(order)}\n isLoading={isCanceling}\n className=\"bg-red-600 hover:bg-red-700 text-white text-xs px-3 py-1\"\n >\n Cancel\n </Button>\n ) : (\n <span className=\"text-[11px]\" style={{ color: \"#6b6d7a\" }}>\n -\n </span>\n )}\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n );\n}\n\n// Loading skeleton component\nexport function OpenOrdersSkeleton() {\n return (\n <div className=\"w-full space-y-4 p-4\">\n <div className=\"h-4 bg-neutral-800 rounded w-full animate-pulse\" />\n <div className=\"h-4 bg-neutral-800 rounded w-full animate-pulse\" />\n <div className=\"h-4 bg-neutral-800 rounded w-full animate-pulse\" />\n </div>\n );\n}\n\n// Empty state component\nexport function OpenOrdersEmpty() {\n return (\n <div\n className=\"flex items-center justify-center h-24\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n No open orders\n </div>\n );\n}\n","import { useOpenOrdersScript } from \"./open-orders.script\";\nimport {\n OpenOrdersUI,\n OpenOrdersSkeleton,\n OpenOrdersEmpty,\n} from \"./open-orders.ui\";\n\nexport type OpenOrdersWidgetProps = {\n userAddress?: string;\n symbol?: string;\n onCancelSuccess?: () => void;\n onCancelError?: (error: Error) => void;\n className?: string;\n};\n\nexport function OpenOrdersWidget({\n userAddress,\n symbol,\n onCancelSuccess,\n onCancelError,\n className,\n}: OpenOrdersWidgetProps) {\n const { orders, isLoading, handleCancelOrder, isCanceling } =\n useOpenOrdersScript({\n userAddress,\n symbol,\n onCancelSuccess,\n onCancelError,\n });\n\n if (isLoading) {\n return (\n <div className={className}>\n <OpenOrdersSkeleton />\n </div>\n );\n }\n\n if (orders.length === 0) {\n return (\n <div className={className}>\n <OpenOrdersEmpty />\n </div>\n );\n }\n\n return (\n <div className={className}>\n <OpenOrdersUI\n orders={orders}\n onCancelOrder={handleCancelOrder}\n isCanceling={isCanceling}\n />\n </div>\n );\n}\n","import { useState, useEffect } from \"react\";\nimport { useTradesQuery } from \"../../hooks/useTradesQuery\";\nimport type { TradeHistory } from \"../../types\";\n\nexport type TimeRange = \"today\" | \"7d\" | \"30d\" | \"all\";\n\nexport type UseTradeHistoryScriptParams = {\n userAddress?: string;\n symbol?: string;\n initialTimeRange?: TimeRange;\n pageSize?: number;\n};\n\nexport type UseTradeHistoryScriptResult = {\n trades: TradeHistory[];\n isLoading: boolean;\n error: Error | null;\n timeRange: TimeRange;\n setTimeRange: (range: TimeRange) => void;\n currentPage: number;\n totalPages: number;\n goToNextPage: () => void;\n goToPreviousPage: () => void;\n goToPage: (page: number) => void;\n};\n\nfunction getTimeRangeInMs(range: TimeRange): {\n startTime?: number;\n endTime?: number;\n} {\n const now = Date.now();\n const endTime = now;\n\n switch (range) {\n case \"today\":\n const today = new Date();\n today.setHours(0, 0, 0, 0);\n return { startTime: today.getTime(), endTime };\n case \"7d\":\n return { startTime: now - 7 * 24 * 60 * 60 * 1000, endTime };\n case \"30d\":\n return { startTime: now - 30 * 24 * 60 * 60 * 1000, endTime };\n case \"all\":\n default:\n return {};\n }\n}\n\nexport function useTradeHistoryScript({\n userAddress,\n symbol,\n initialTimeRange = \"7d\",\n pageSize = 50,\n}: UseTradeHistoryScriptParams): UseTradeHistoryScriptResult {\n const [timeRange, setTimeRange] = useState<TimeRange>(initialTimeRange);\n const [currentPage, setCurrentPage] = useState(1);\n const [allTrades, setAllTrades] = useState<TradeHistory[]>([]);\n\n const { startTime, endTime } = getTimeRangeInMs(timeRange);\n\n // Fetch trades with time range filter\n const {\n data: tradesData,\n isLoading,\n error,\n } = useTradesQuery(\n {\n userAddress,\n symbol,\n startTime,\n endTime,\n limit: 1000, // Fetch more data for client-side pagination\n },\n { enabled: !!userAddress },\n );\n\n // Update all trades when data changes\n useEffect(() => {\n if (tradesData?.trades) {\n setAllTrades(tradesData.trades);\n setCurrentPage(1); // Reset to first page when data changes\n }\n }, [tradesData]);\n\n // Reset page when time range changes\n useEffect(() => {\n setCurrentPage(1);\n }, [timeRange]);\n\n // Calculate pagination\n const totalPages = Math.ceil(allTrades.length / pageSize);\n const startIndex = (currentPage - 1) * pageSize;\n const endIndex = startIndex + pageSize;\n const trades = allTrades.slice(startIndex, endIndex);\n\n const goToNextPage = () => {\n if (currentPage < totalPages) {\n setCurrentPage(currentPage + 1);\n }\n };\n\n const goToPreviousPage = () => {\n if (currentPage > 1) {\n setCurrentPage(currentPage - 1);\n }\n };\n\n const goToPage = (page: number) => {\n if (page >= 1 && page <= totalPages) {\n setCurrentPage(page);\n }\n };\n\n return {\n trades,\n isLoading,\n error,\n timeRange,\n setTimeRange,\n currentPage,\n totalPages,\n goToNextPage,\n goToPreviousPage,\n goToPage,\n };\n}\n","import { Button, cn } from \"@liberfi.io/ui\";\nimport type { TradeHistory } from \"../../types\";\nimport type { TimeRange } from \"./trade-history.script\";\n\nexport type TradeHistoryUIProps = {\n trades: TradeHistory[];\n timeRange: TimeRange;\n onTimeRangeChange: (range: TimeRange) => void;\n currentPage: number;\n totalPages: number;\n onNextPage: () => void;\n onPreviousPage: () => void;\n onGoToPage: (page: number) => void;\n};\n\nfunction formatNumber(num: number, decimals: number = 2): string {\n return num.toFixed(decimals);\n}\n\nfunction formatPrice(price: number): string {\n return formatNumber(price, 4);\n}\n\nfunction formatQuantity(quantity: number): string {\n return formatNumber(quantity, 4);\n}\n\nfunction formatDateTime(timestamp: number): string {\n const date = new Date(timestamp);\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\n const day = String(date.getDate()).padStart(2, \"0\");\n const hours = String(date.getHours()).padStart(2, \"0\");\n const minutes = String(date.getMinutes()).padStart(2, \"0\");\n const seconds = String(date.getSeconds()).padStart(2, \"0\");\n return `${month}/${day} ${hours}:${minutes}:${seconds}`;\n}\n\nconst TIME_RANGE_OPTIONS: { label: string; value: TimeRange }[] = [\n { label: \"Today\", value: \"today\" },\n { label: \"7 Days\", value: \"7d\" },\n { label: \"30 Days\", value: \"30d\" },\n { label: \"All\", value: \"all\" },\n];\n\nexport function TradeHistoryUI({\n trades,\n timeRange,\n onTimeRangeChange,\n currentPage,\n totalPages,\n onNextPage,\n onPreviousPage,\n onGoToPage,\n}: TradeHistoryUIProps) {\n return (\n <div className=\"w-full flex flex-col gap-4\">\n {/* Time range filter */}\n <div className=\"flex gap-2\">\n {TIME_RANGE_OPTIONS.map((option) => {\n const selected = timeRange === option.value;\n return (\n <button\n key={option.value}\n type=\"button\"\n className={cn(\n \"rounded px-3 transition-colors\",\n !selected && \"hover:bg-[#1A1A1A]\",\n )}\n style={{\n height: 24,\n fontSize: 11,\n border: \"1px solid #1c1c1c\",\n backgroundColor: selected ? \"#1c1c1c\" : \"transparent\",\n color: selected ? \"#ffffff\" : \"#b5b5b5\",\n }}\n onClick={() => onTimeRangeChange(option.value)}\n >\n {option.label}\n </button>\n );\n })}\n </div>\n\n {/* Trade history table */}\n {trades.length === 0 ? (\n <div\n className=\"flex items-center justify-center h-24\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n No trade history\n </div>\n ) : (\n <>\n <div className=\"w-full overflow-x-auto bg-transparent\">\n <table className=\"w-full\" style={{ fontSize: 11 }}>\n <thead>\n <tr style={{ borderBottom: \"1px solid #1c1c1c\" }}>\n <th\n className=\"text-left py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Asset\n </th>\n <th\n className=\"text-left py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Side\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Price\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Quantity\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Fee\n </th>\n <th\n className=\"text-center py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Maker/Taker\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Time\n </th>\n </tr>\n </thead>\n <tbody>\n {trades.map((trade) => (\n <tr\n key={trade.tradeId}\n className=\"hover:bg-neutral-900/50\"\n style={{ borderBottom: \"1px solid #1c1c1c\" }}\n >\n {/* Asset */}\n <td\n className=\"py-1.5 px-3 font-medium\"\n style={{ color: \"#ffffff\" }}\n >\n {trade.symbol.split(\"-\")[0]}\n </td>\n\n {/* Side */}\n <td className=\"py-1.5 px-3\">\n <span\n className={cn(\n \"px-2 py-0.5 rounded text-[11px]\",\n trade.side === \"long\"\n ? \"bg-bullish/20 text-bullish\"\n : \"bg-bearish/20 text-bearish\",\n )}\n >\n {trade.side.toUpperCase()}\n </span>\n </td>\n\n {/* Price */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#ffffff\" }}\n >\n ${formatPrice(trade.price)}\n </td>\n\n {/* Quantity */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#ffffff\" }}\n >\n {formatQuantity(trade.quantity)}\n </td>\n\n {/* Fee */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#ffffff\" }}\n >\n {formatNumber(trade.fee, 4)} {trade.feeCurrency}\n </td>\n\n {/* Maker/Taker */}\n <td className=\"py-1.5 px-3 text-center\">\n <span\n className={cn(\n \"px-2 py-0.5 rounded text-[11px]\",\n trade.isMaker\n ? \"bg-blue-600/20 text-blue-500\"\n : \"bg-purple-600/20 text-purple-500\",\n )}\n >\n {trade.isMaker ? \"Maker\" : \"Taker\"}\n </span>\n </td>\n\n {/* Time */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#b5b5b5\" }}\n >\n {formatDateTime(trade.timestamp)}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n\n {/* Pagination */}\n {totalPages > 1 && (\n <div className=\"flex items-center justify-between\">\n <div className=\"text-sm text-neutral-400\">\n Page {currentPage} of {totalPages}\n </div>\n <div className=\"flex gap-2\">\n <Button\n size=\"sm\"\n onClick={onPreviousPage}\n disabled={currentPage === 1}\n className=\"bg-neutral-800 hover:bg-neutral-700 text-white disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n Previous\n </Button>\n {/* Page numbers */}\n <div className=\"flex gap-1\">\n {Array.from({ length: Math.min(5, totalPages) }, (_, i) => {\n let pageNum: number;\n if (totalPages <= 5) {\n pageNum = i + 1;\n } else if (currentPage <= 3) {\n pageNum = i + 1;\n } else if (currentPage >= totalPages - 2) {\n pageNum = totalPages - 4 + i;\n } else {\n pageNum = currentPage - 2 + i;\n }\n\n return (\n <button\n key={pageNum}\n type=\"button\"\n className={cn(\n \"w-8 h-8 text-sm rounded transition-colors\",\n currentPage === pageNum\n ? \"bg-neutral-700 text-white\"\n : \"text-neutral-400 hover:bg-neutral-800 hover:text-white\",\n )}\n onClick={() => onGoToPage(pageNum)}\n >\n {pageNum}\n </button>\n );\n })}\n </div>\n <Button\n size=\"sm\"\n onClick={onNextPage}\n disabled={currentPage === totalPages}\n className=\"bg-neutral-800 hover:bg-neutral-700 text-white disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n Next\n </Button>\n </div>\n </div>\n )}\n </>\n )}\n </div>\n );\n}\n\n// Loading skeleton component\nexport function TradeHistorySkeleton() {\n return (\n <div className=\"w-full space-y-4 p-4\">\n <div className=\"h-4 bg-neutral-800 rounded w-full animate-pulse\" />\n <div className=\"h-4 bg-neutral-800 rounded w-full animate-pulse\" />\n <div className=\"h-4 bg-neutral-800 rounded w-full animate-pulse\" />\n </div>\n );\n}\n\n// Empty state component\nexport function TradeHistoryEmpty() {\n return (\n <div\n className=\"flex items-center justify-center h-24\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n No trade history\n </div>\n );\n}\n","import { useTradeHistoryScript } from \"./trade-history.script\";\nimport type { TimeRange } from \"./trade-history.script\";\nimport {\n TradeHistoryUI,\n TradeHistorySkeleton,\n TradeHistoryEmpty,\n} from \"./trade-history.ui\";\n\nexport type TradeHistoryWidgetProps = {\n userAddress?: string;\n symbol?: string;\n initialTimeRange?: TimeRange;\n pageSize?: number;\n className?: string;\n};\n\nexport function TradeHistoryWidget({\n userAddress,\n symbol,\n initialTimeRange = \"7d\",\n pageSize = 50,\n className,\n}: TradeHistoryWidgetProps) {\n const {\n trades,\n isLoading,\n timeRange,\n setTimeRange,\n currentPage,\n totalPages,\n goToNextPage,\n goToPreviousPage,\n goToPage,\n } = useTradeHistoryScript({\n userAddress,\n symbol,\n initialTimeRange,\n pageSize,\n });\n\n if (isLoading) {\n return (\n <div className={className}>\n <TradeHistorySkeleton />\n </div>\n );\n }\n\n if (trades.length === 0) {\n return (\n <div className={className}>\n <TradeHistoryEmpty />\n </div>\n );\n }\n\n return (\n <div className={className}>\n <TradeHistoryUI\n trades={trades}\n timeRange={timeRange}\n onTimeRangeChange={setTimeRange}\n currentPage={currentPage}\n totalPages={totalPages}\n onNextPage={goToNextPage}\n onPreviousPage={goToPreviousPage}\n onGoToPage={goToPage}\n />\n </div>\n );\n}\n","/**\n * Tiny number-formatting helpers shared by the deposit UI.\n *\n * We use plain `bigint` arithmetic here — never `Number(...)` on a\n * lamport / microUSDC value — so we never silently lose precision on\n * deposits that exceed `Number.MAX_SAFE_INTEGER` lamports.\n */\n\nconst LAMPORTS_PER_SOL = 1_000_000_000n;\n\n/**\n * Hyperliquid credits perp USDC at 8-decimal granularity (NOT the 6\n * decimals used by ERC-20 USDC on Arbitrum). Relay's `currencyOut.amount`\n * for a Hyperliquid bridge quote is therefore expressed in HL perp units\n * — divide by 1e8 to get the human-readable USDC amount.\n */\nexport const HL_USDC_DECIMALS = 8;\nconst HL_USDC_DIVISOR = 10n ** BigInt(HL_USDC_DECIMALS);\n\n/**\n * Convert a lamport amount (string bigint) to a SOL-denominated string\n * with `precision` decimals and trailing zeros stripped.\n */\nexport function lamportsToSol(value: string, precision = 4): string {\n if (!value) return \"0\";\n let n: bigint;\n try {\n n = BigInt(value);\n } catch {\n return \"0\";\n }\n return divToFixed(n, LAMPORTS_PER_SOL, precision);\n}\n\n/**\n * Convert a raw Hyperliquid USDC amount (8 decimals) to a USDC display\n * string with `precision` decimals and trailing zeros stripped.\n *\n * This is the unit returned by the perpetuals-server `/deposits/quote`\n * endpoint in `breakdown.expectedOutputUSDC` — it mirrors Hyperliquid's\n * internal perp-account precision, NOT the 6-decimal USDC token on\n * Arbitrum.\n */\nexport function hlUsdcRawToUsdc(\n value: string | undefined,\n precision = 2,\n): string {\n if (!value) return \"0\";\n let n: bigint;\n try {\n n = BigInt(value);\n } catch {\n return \"0\";\n }\n return divToFixed(n, HL_USDC_DIVISOR, precision);\n}\n\n/**\n * @deprecated Use {@link hlUsdcRawToUsdc} instead. The previous name\n * implied a 6-decimal microUSDC unit, but the Hyperliquid bridge actually\n * returns amounts at 8-decimal precision. Kept as a thin alias to avoid\n * a hard break for downstream callers; remove after consumers migrate.\n */\nexport const microUsdcToUsdc = hlUsdcRawToUsdc;\n\n/** Convert a SOL-denominated decimal string to a lamport `string` (bigint). */\nexport function solToLamports(value: string): string {\n if (!value) return \"0\";\n const [whole, frac = \"\"] = value.replace(/[\\s,]/g, \"\").split(\".\");\n if (!/^\\d*$/.test(whole) || !/^\\d*$/.test(frac)) return \"0\";\n // Pad / truncate the fractional component to 9 digits to match SOL.\n const fracPadded = (frac + \"000000000\").slice(0, 9);\n const combined = `${whole || \"0\"}${fracPadded}`.replace(/^0+(?=\\d)/, \"\");\n return combined === \"\" ? \"0\" : combined;\n}\n\nfunction divToFixed(\n numerator: bigint,\n denominator: bigint,\n precision: number,\n): string {\n const negative = numerator < 0n;\n const abs = negative ? -numerator : numerator;\n let whole = abs / denominator;\n const remainder = abs % denominator;\n if (precision <= 0) {\n // Round to nearest integer when precision is 0.\n if (remainder * 2n >= denominator) whole += 1n;\n return `${negative ? \"-\" : \"\"}${whole.toString()}`;\n }\n const scale = 10n ** BigInt(precision);\n let scaledRemainder = (remainder * scale + denominator / 2n) / denominator;\n // Carry over to the whole part when half-rounding pushed the fractional\n // component to or above `scale` (e.g. 0.999999 with precision 2 -> 1.00).\n if (scaledRemainder >= scale) {\n whole += 1n;\n scaledRemainder = 0n;\n }\n let frac = scaledRemainder.toString().padStart(precision, \"0\");\n // Trim trailing zeros for nicer display.\n frac = frac.replace(/0+$/, \"\");\n if (!frac) return `${negative ? \"-\" : \"\"}${whole.toString()}`;\n return `${negative ? \"-\" : \"\"}${whole.toString()}.${frac}`;\n}\n\n/** Returns whole-second countdown until `expiresAtMs`. Negative -> 0. */\nexport function secondsUntil(\n expiresAtMs: number,\n nowMs: number = Date.now(),\n): number {\n return Math.max(0, Math.floor((expiresAtMs - nowMs) / 1000));\n}\n\n/** Truncate an address to `head…tail` for display. */\nexport function shortAddress(addr: string, head = 6, tail = 4): string {\n if (!addr) return \"\";\n if (addr.length <= head + tail + 1) return addr;\n return `${addr.slice(0, head)}…${addr.slice(-tail)}`;\n}\n","import { useEffect, useState } from \"react\";\nimport { useTranslation } from \"@liberfi.io/i18n\";\nimport {\n Button,\n Modal,\n ModalBody,\n ModalContent,\n ModalFooter,\n ModalHeader,\n Spinner,\n} from \"@liberfi.io/ui\";\nimport type {\n DepositBreakdown,\n DepositQuoteResponse,\n} from \"../../client/liberfi/deposit-types\";\nimport { lamportsToSol, hlUsdcRawToUsdc, secondsUntil } from \"./format\";\n\n/**\n * Pure presentational confirm modal for the deposit flow.\n *\n * Owns no fetching or signing — it just renders the breakdown and\n * fires `onConfirm` / `onCancel`. The expiry countdown ticks locally\n * via setInterval and re-renders once a second; when it hits 0 the\n * `onExpire` callback fires (the parent should refetch the quote).\n */\nexport interface DepositConfirmUIProps {\n isOpen: boolean;\n /** Quote currently being shown to the user. Required when `isOpen`. */\n quote: DepositQuoteResponse | undefined;\n /** True while `/submit` (or wallet sign) is in flight. Disables the CTA. */\n isExecuting?: boolean;\n /** True when the displayed quote has already expired. */\n isExpired?: boolean;\n onConfirm: () => void;\n onCancel: () => void;\n /** Fires when the local countdown reaches zero. */\n onExpire?: () => void;\n /** Optional inline error to surface inside the modal. */\n error?: string;\n}\n\nexport function DepositConfirmUI({\n isOpen,\n quote,\n isExecuting,\n isExpired,\n onConfirm,\n onCancel,\n onExpire,\n error,\n}: DepositConfirmUIProps) {\n const { t } = useTranslation();\n\n const expiresAtMs = quote ? Date.parse(quote.expiresAt) : 0;\n const [secondsLeft, setSecondsLeft] = useState(() =>\n expiresAtMs ? secondsUntil(expiresAtMs) : 0,\n );\n\n useEffect(() => {\n if (!isOpen || !expiresAtMs) return;\n setSecondsLeft(secondsUntil(expiresAtMs));\n const id = setInterval(() => {\n const remaining = secondsUntil(expiresAtMs);\n setSecondsLeft(remaining);\n if (remaining === 0) {\n onExpire?.();\n clearInterval(id);\n }\n }, 1000);\n return () => clearInterval(id);\n }, [isOpen, expiresAtMs, onExpire]);\n\n return (\n <Modal\n isOpen={isOpen}\n onOpenChange={(next) => !next && onCancel()}\n hideCloseButton\n backdrop=\"blur\"\n >\n <ModalContent className=\"bg-content2 rounded-lg\">\n <ModalHeader>{t(\"perpDeposit.confirm.title\")}</ModalHeader>\n <ModalBody>\n {!quote ? (\n <div className=\"flex h-32 items-center justify-center\">\n <Spinner />\n </div>\n ) : (\n <BreakdownSummary breakdown={quote.breakdown} />\n )}\n\n {quote && !isExpired && (\n <div className=\"text-default-500 mt-4 text-xs\">\n {t(\"perpDeposit.confirm.expiresIn\", { seconds: secondsLeft })}\n </div>\n )}\n {isExpired && (\n <div className=\"text-warning-500 mt-4 text-xs\">\n {t(\"perpDeposit.confirm.expired\")}\n </div>\n )}\n {error && <div className=\"text-danger mt-4 text-xs\">{error}</div>}\n </ModalBody>\n <ModalFooter className=\"flex justify-between gap-2\">\n <Button\n variant=\"flat\"\n color=\"default\"\n onPress={onCancel}\n isDisabled={isExecuting}\n >\n {t(\"perpDeposit.confirm.cancel\")}\n </Button>\n <Button\n color=\"primary\"\n onPress={onConfirm}\n isDisabled={!quote || isExecuting || isExpired}\n isLoading={isExecuting}\n >\n {t(\"perpDeposit.confirm.cta\")}\n </Button>\n </ModalFooter>\n </ModalContent>\n </Modal>\n );\n}\n\ninterface BreakdownSummaryProps {\n breakdown: DepositBreakdown;\n}\n\nfunction BreakdownSummary({ breakdown }: BreakdownSummaryProps) {\n const { t } = useTranslation();\n return (\n <dl className=\"flex flex-col gap-2 text-sm\">\n <Row\n label={t(\"perpDeposit.confirm.send\")}\n value={`${lamportsToSol(breakdown.grossLamports)} SOL`}\n />\n <Row\n label={t(\"perpDeposit.confirm.receive\")}\n value={`${hlUsdcRawToUsdc(breakdown.expectedOutputUSDC)} USDC`}\n highlight\n />\n <Row\n label={t(\"perpDeposit.confirm.platformFee\")}\n value={`${lamportsToSol(breakdown.platformFeeLamports, 6)} SOL`}\n muted\n />\n <Row\n label={t(\"perpDeposit.confirm.relayFee\")}\n value={`${lamportsToSol(breakdown.relayDepositLamports, 6)} SOL`}\n muted\n />\n </dl>\n );\n}\n\ninterface RowProps {\n label: string;\n value: string;\n highlight?: boolean;\n muted?: boolean;\n}\n\nfunction Row({ label, value, highlight, muted }: RowProps) {\n return (\n <div className=\"flex items-center justify-between\">\n <dt className=\"text-default-500\">{label}</dt>\n <dd\n className={\n highlight\n ? \"text-foreground text-base font-semibold\"\n : muted\n ? \"text-default-500 text-xs\"\n : \"text-foreground\"\n }\n >\n {value}\n </dd>\n </div>\n );\n}\n","import { useTranslation } from \"@liberfi.io/i18n\";\nimport { Button, Input, cn } from \"@liberfi.io/ui\";\n\n/**\n * Pure presentational form for collecting the deposit amount + the\n * Hyperliquid recipient address.\n *\n * No data fetching, no state — every input is controlled from above.\n * Lets the host app decide when to show the wallet's connected SOL\n * balance (or omit it entirely).\n */\nexport interface DepositFormUIProps {\n amount: string;\n onAmountChange: (value: string) => void;\n recipient: string;\n onRecipientChange: (value: string) => void;\n /** Optional: shown as the \"Balance: …\" hint above the amount input. */\n balanceSol?: string;\n /** Disables every interactive control (e.g. while quoting). */\n disabled?: boolean;\n /** Inline error to render under the amount input. */\n amountError?: string;\n /** Inline error to render under the recipient input. */\n recipientError?: string;\n /** Click handler for \"Max\" — only rendered when `balanceSol` is set. */\n onMax?: () => void;\n className?: string;\n}\n\nexport function DepositFormUI({\n amount,\n onAmountChange,\n recipient,\n onRecipientChange,\n balanceSol,\n disabled,\n amountError,\n recipientError,\n onMax,\n className,\n}: DepositFormUIProps) {\n const { t } = useTranslation();\n return (\n <div className={cn(\"flex flex-col gap-4\", className)}>\n <div>\n <div className=\"flex items-center justify-between mb-1.5\">\n <label\n htmlFor=\"perp-deposit-amount\"\n className=\"text-sm font-medium text-foreground\"\n >\n {t(\"perpDeposit.amount\")}\n </label>\n {balanceSol && (\n <span className=\"text-xs text-default-500\">\n {t(\"perpDeposit.amount.balance\", { balance: balanceSol })}\n </span>\n )}\n </div>\n <div className=\"relative\">\n <Input\n id=\"perp-deposit-amount\"\n type=\"text\"\n inputMode=\"decimal\"\n placeholder={t(\"perpDeposit.amount.placeholder\")}\n value={amount}\n onValueChange={onAmountChange}\n isDisabled={disabled}\n isInvalid={Boolean(amountError)}\n errorMessage={amountError}\n endContent={\n <div className=\"flex items-center gap-2\">\n <span className=\"text-default-500 text-sm\">\n {t(\"perpDeposit.amount.unit\")}\n </span>\n {balanceSol && onMax && (\n <Button\n size=\"sm\"\n variant=\"flat\"\n color=\"primary\"\n onPress={onMax}\n isDisabled={disabled}\n >\n {t(\"perpDeposit.amount.max\")}\n </Button>\n )}\n </div>\n }\n />\n </div>\n </div>\n\n <div>\n <label\n htmlFor=\"perp-deposit-recipient\"\n className=\"text-sm font-medium text-foreground mb-1.5 block\"\n >\n {t(\"perpDeposit.recipient\")}\n </label>\n <Input\n id=\"perp-deposit-recipient\"\n type=\"text\"\n placeholder={t(\"perpDeposit.recipient.placeholder\")}\n value={recipient}\n onValueChange={onRecipientChange}\n isDisabled={disabled}\n isInvalid={Boolean(recipientError)}\n errorMessage={recipientError}\n autoComplete=\"off\"\n spellCheck=\"false\"\n />\n </div>\n </div>\n );\n}\n","import { useTranslation } from \"@liberfi.io/i18n\";\nimport { ModalContent, StyledModal, XCloseIcon, cn } from \"@liberfi.io/ui\";\nimport type { DepositPhase } from \"../../client/liberfi/deposit-state-machine\";\nimport type { DepositStatusResponse } from \"../../client/liberfi/deposit-types\";\nimport { shortAddress } from \"./format\";\n\n/**\n * Polished progress / result panel for the SOL → Hyperliquid USDC\n * deposit flow.\n *\n * Visual design intentionally mirrors the swap-style deposit form\n * modal (dark surface, 14 px radius, accent-color spinner / icons,\n * pill-style transaction links) so the in-flight, success and failure\n * states all feel like the same product surface rather than a generic\n * HeroUI dialog.\n *\n * Renders one of four visual states based on the FSM phase:\n * - in-progress (broadcasting / submitted / tracking)\n * - succeeded\n * - refunded\n * - failed\n *\n * Explorer URLs are caller-provided so the SDK never has to know which\n * RPC / explorer the host wants (Solscan vs Solana Beach, etc.).\n */\nexport interface DepositStatusUIProps {\n isOpen: boolean;\n /** The current FSM phase — drives the visual treatment. */\n phase: DepositPhase;\n /** Backend status record (may be unavailable on first frame). */\n status?: DepositStatusResponse;\n /** Optional Solana explorer URL (caller decides the network). */\n solanaExplorerUrl?: string;\n /** Optional Hyperliquid explorer URL. */\n hyperliquidExplorerUrl?: string;\n /** \"Try again\" handler — only rendered when `phase === \"failed\"`. */\n onRetry?: () => void;\n onClose: () => void;\n /** Optional override for the human-readable message. */\n errorMessage?: string;\n}\n\ntype Variant = \"progress\" | \"success\" | \"warning\" | \"error\";\n\nconst ACCENT = \"#C7FF2E\";\n\nexport function DepositStatusUI({\n isOpen,\n phase,\n status,\n solanaExplorerUrl,\n hyperliquidExplorerUrl,\n onRetry,\n onClose,\n errorMessage,\n}: DepositStatusUIProps) {\n const { t } = useTranslation();\n\n const variant = phaseToVariant(phase);\n const message = ((): string => {\n if (phase === \"failed\") {\n if (errorMessage) return errorMessage;\n if (status?.lastError?.message) {\n return t(\"perpDeposit.status.failed\", {\n message: status.lastError.message,\n });\n }\n return t(\"perpDeposit.status.failed\", { message: \"\" });\n }\n if (phase === \"succeeded\") return t(\"perpDeposit.status.settled\");\n if (phase === \"refunded\") return t(\"perpDeposit.status.refunded\");\n if (status?.status === \"broadcasted\")\n return t(\"perpDeposit.status.broadcasted\");\n if (status?.status === \"relay_waiting\")\n return t(\"perpDeposit.status.relay_waiting\");\n if (status?.status === \"relay_pending\")\n return t(\"perpDeposit.status.relay_pending\");\n if (status?.status === \"stuck\") return t(\"perpDeposit.status.stuck\");\n return t(\"perpDeposit.status.broadcasted\");\n })();\n\n const showRetry = phase === \"failed\" && !!onRetry;\n\n return (\n <StyledModal\n isOpen={isOpen}\n onOpenChange={(next) => !next && onClose()}\n size=\"md\"\n hideCloseButton\n backdrop=\"blur\"\n classNames={{\n base: \"!bg-[#18181b] !rounded-[14px] !border !border-[rgba(39,39,42,1)] !shadow-[0_25px_50px_-12px_rgba(0,0,0,0.5)] max-w-[420px]\",\n body: \"!p-0\",\n }}\n >\n <ModalContent>\n <div className=\"flex flex-col\">\n {/* Header */}\n <div className=\"flex items-start justify-between px-5 pt-5 pb-2\">\n <div className=\"flex items-center gap-2.5\">\n <h3 className=\"text-base font-semibold text-white\">\n {t(\"perpDeposit.status.title\")}\n </h3>\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"cursor-pointer p-1 rounded-[10px] hover:bg-[rgba(39,39,42,0.5)] text-zinc-400 hover:text-white transition-colors\"\n aria-label={t(\"perpDeposit.status.close\")}\n >\n <XCloseIcon width={16} height={16} />\n </button>\n </div>\n\n {/* Body */}\n <div className=\"px-5 pb-3 pt-2\">\n <div className=\"rounded-[12px] bg-[#0a0a0b] border border-[#27272a] px-4 py-6 flex flex-col items-center text-center gap-4\">\n <PhaseIcon variant={variant} />\n <p\n className={cn(\n \"text-sm leading-relaxed max-w-[320px]\",\n variantTextClass(variant),\n )}\n >\n {message}\n </p>\n </div>\n\n {/* Transaction links */}\n {(status?.solanaTxHash || status?.hyperliquidTxHash) && (\n <div className=\"mt-3 flex flex-col gap-2\">\n {status?.solanaTxHash && solanaExplorerUrl && (\n <TxLink\n href={solanaExplorerUrl}\n label={t(\"perpDeposit.status.viewSolanaTx\")}\n hash={status.solanaTxHash}\n />\n )}\n {status?.hyperliquidTxHash && hyperliquidExplorerUrl && (\n <TxLink\n href={hyperliquidExplorerUrl}\n label={t(\"perpDeposit.status.viewHyperliquidTx\")}\n hash={status.hyperliquidTxHash}\n />\n )}\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div\n className={cn(\n \"px-5 pb-5 pt-2 flex gap-2\",\n showRetry ? \"justify-between\" : \"justify-end\",\n )}\n >\n {showRetry && (\n <button\n type=\"button\"\n onClick={onRetry}\n className=\"cursor-pointer flex-1 h-10 rounded-[10px] font-medium text-black bg-[#C7FF2E] hover:bg-[#b6ed1c] active:bg-[#a6d913] transition-colors flex items-center justify-center\"\n >\n {t(\"perpDeposit.status.tryAgain\")}\n </button>\n )}\n <button\n type=\"button\"\n onClick={onClose}\n className={cn(\n \"cursor-pointer h-10 rounded-[10px] font-medium transition-colors flex items-center justify-center\",\n showRetry\n ? \"flex-1 bg-[rgba(39,39,42,1)] hover:bg-[rgba(63,63,70,1)] text-white\"\n : \"px-6 bg-[rgba(39,39,42,1)] hover:bg-[rgba(63,63,70,1)] text-white\",\n )}\n >\n {t(\"perpDeposit.status.close\")}\n </button>\n </div>\n </div>\n </ModalContent>\n </StyledModal>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Sub-components\n// ---------------------------------------------------------------------------\n\nfunction TxLink({\n href,\n label,\n hash,\n}: {\n href: string;\n label: string;\n hash: string;\n}) {\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"group flex items-center justify-between gap-2 px-3 py-2 rounded-[10px] bg-[#0a0a0b] border border-[#27272a] hover:border-[rgba(199,255,46,0.4)] transition-colors\"\n >\n <span className=\"text-xs text-zinc-400 group-hover:text-white transition-colors\">\n {label}\n </span>\n <span className=\"flex items-center gap-1.5 text-xs tabular-nums text-zinc-300 group-hover:text-[#C7FF2E] transition-colors\">\n {shortAddress(hash, 6, 4)}\n <ExternalLinkIcon />\n </span>\n </a>\n );\n}\n\nfunction PhaseIcon({ variant }: { variant: Variant }) {\n if (variant === \"progress\") {\n return (\n <div className=\"relative w-14 h-14 flex items-center justify-center\">\n <AccentSpinner />\n </div>\n );\n }\n if (variant === \"success\") {\n return (\n <div className=\"w-14 h-14 rounded-full flex items-center justify-center bg-[rgba(199,255,46,0.12)]\">\n <CheckCircle className=\"w-8 h-8\" style={{ color: ACCENT }} />\n </div>\n );\n }\n if (variant === \"warning\") {\n return (\n <div className=\"w-14 h-14 rounded-full flex items-center justify-center bg-[rgba(245,158,11,0.12)]\">\n <AlertCircle className=\"w-8 h-8 text-amber-400\" />\n </div>\n );\n }\n return (\n <div className=\"w-14 h-14 rounded-full flex items-center justify-center bg-[rgba(239,68,68,0.12)]\">\n <XCircle className=\"w-8 h-8 text-rose-400\" />\n </div>\n );\n}\n\n/**\n * Accent-coloured circular spinner matching the deposit form's theme.\n *\n * Implemented as an inline SVG with a CSS keyframe rotation rather than\n * pulling HeroUI's `Spinner` (which doesn't expose a clean way to set\n * the active arc colour to our brand `#C7FF2E`).\n */\nfunction AccentSpinner() {\n return (\n <>\n <svg\n className=\"lfi-perp-deposit-spinner\"\n viewBox=\"0 0 50 50\"\n width={48}\n height={48}\n aria-hidden=\"true\"\n >\n <circle\n cx=\"25\"\n cy=\"25\"\n r=\"20\"\n fill=\"none\"\n stroke=\"rgba(255,255,255,0.08)\"\n strokeWidth=\"4\"\n />\n <circle\n cx=\"25\"\n cy=\"25\"\n r=\"20\"\n fill=\"none\"\n stroke={ACCENT}\n strokeWidth=\"4\"\n strokeLinecap=\"round\"\n strokeDasharray=\"90 60\"\n />\n </svg>\n <style>{`\n .lfi-perp-deposit-spinner {\n animation: lfi-perp-deposit-spin 0.9s linear infinite;\n transform-origin: center;\n }\n @keyframes lfi-perp-deposit-spin {\n to { transform: rotate(360deg); }\n }\n `}</style>\n </>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction phaseToVariant(phase: DepositPhase): Variant {\n switch (phase) {\n case \"succeeded\":\n return \"success\";\n case \"refunded\":\n return \"warning\";\n case \"failed\":\n return \"error\";\n default:\n return \"progress\";\n }\n}\n\nfunction variantTextClass(variant: Variant): string {\n switch (variant) {\n case \"success\":\n return \"text-white\";\n case \"warning\":\n return \"text-amber-200\";\n case \"error\":\n return \"text-rose-300\";\n default:\n return \"text-zinc-200\";\n }\n}\n\n// Inline icons — kept tiny so we don't pull a heavy icon dep into the bundle.\nfunction CheckCircle(props: {\n className?: string;\n style?: React.CSSProperties;\n}) {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2.5}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n className={props.className}\n style={props.style}\n >\n <path d=\"M20 6L9 17l-5-5\" />\n </svg>\n );\n}\n\nfunction AlertCircle(props: { className?: string }) {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n className={props.className}\n >\n <path d=\"M12 2a10 10 0 100 20 10 10 0 000-20zm0 4c.6 0 1 .4 1 1v6c0 .6-.4 1-1 1s-1-.4-1-1V7c0-.6.4-1 1-1zm0 12c-.7 0-1.2-.5-1.2-1.2s.5-1.2 1.2-1.2 1.2.5 1.2 1.2-.5 1.2-1.2 1.2z\" />\n </svg>\n );\n}\n\nfunction XCircle(props: { className?: string }) {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2.5}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n className={props.className}\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M15 9l-6 6M9 9l6 6\" />\n </svg>\n );\n}\n\nfunction ExternalLinkIcon() {\n return (\n <svg\n width=\"11\"\n height=\"11\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\n <polyline points=\"15 3 21 3 21 9\" />\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />\n </svg>\n );\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useTranslation } from \"@liberfi.io/i18n\";\nimport { Button, Card, CardBody } from \"@liberfi.io/ui\";\nimport type {\n DepositQuoteRequest,\n DepositSource,\n} from \"../../client/liberfi/deposit-types\";\nimport {\n type SignAndBroadcastSolanaTx,\n usePerpDepositExecute,\n} from \"../../hooks/usePerpDepositExecute\";\nimport { usePerpDepositQuote } from \"../../hooks/usePerpDepositQuote\";\nimport { usePerpDepositStatus } from \"../../hooks/usePerpDepositStatus\";\nimport { DepositConfirmUI } from \"./deposit-confirm.ui\";\nimport { DepositFormUI } from \"./deposit-form.ui\";\nimport { DepositStatusUI } from \"./deposit-status.ui\";\nimport { solToLamports } from \"./format\";\n\n/**\n * Highest-level deposit widget. Wires the three presentational\n * components (form / confirm / status) to the deposit hooks +\n * state machine.\n *\n * Engineering principles:\n * - Single responsibility: this file is the *only* place that knows\n * how the three components compose. Anything richer (e.g. embedded\n * FAQ panel, support links) belongs to the host application.\n * - Inversion of control: every side effect the host might want to\n * own (sign + broadcast, success / failure callbacks, explorer\n * URLs, balance fetch, address validation) is a prop. The widget\n * never imports a wallet adapter directly.\n */\nexport interface DepositFlowWidgetProps {\n /** Connected Solana wallet — used as `userSolanaAddress` in /quote. */\n userSolanaAddress: string;\n /** Stable LiberFi user id (for fee attribution). */\n userId: string;\n /** Where the deposit was initiated from. */\n source: DepositSource;\n /** Optional referral / campaign code propagated to the backend. */\n campaign?: string;\n\n /** Initial Hyperliquid recipient (e.g. derived from the user's EVM wallet). */\n defaultRecipient?: string;\n\n /**\n * Wallet adapter — sign and broadcast a Solana transaction. The host\n * app supplies its own wallet integration (Phantom, Privy, Backpack,\n * …) and returns the resulting tx hash. See `SignAndBroadcastSolanaTx`.\n */\n signAndBroadcast: SignAndBroadcastSolanaTx;\n\n /** Optional balance display (in SOL units, e.g. \"12.345\"). */\n balanceSol?: string;\n /** Click handler for \"Max\" — only rendered when `balanceSol` is set. */\n onMaxClick?: () => void;\n /** Validates the recipient string. Return undefined when valid. */\n validateRecipient?: (value: string) => string | undefined;\n\n /** Build a Solana explorer URL from a tx hash. */\n buildSolanaExplorerUrl?: (txHash: string) => string;\n /** Build a Hyperliquid explorer URL from a tx hash. */\n buildHyperliquidExplorerUrl?: (txHash: string) => string;\n\n /** Fired when a deposit reaches `settled`. */\n onSettled?: (intentId: string) => void;\n /** Fired when a deposit fails (after the wallet signed). */\n onError?: (intentId: string | undefined, message: string) => void;\n\n className?: string;\n}\n\nexport function DepositFlowWidget({\n userSolanaAddress,\n userId,\n source,\n campaign,\n defaultRecipient,\n signAndBroadcast,\n balanceSol,\n onMaxClick,\n validateRecipient,\n buildSolanaExplorerUrl,\n buildHyperliquidExplorerUrl,\n onSettled,\n onError,\n className,\n}: DepositFlowWidgetProps) {\n const { t } = useTranslation();\n\n const [amount, setAmount] = useState(\"\");\n const [recipient, setRecipient] = useState(defaultRecipient ?? \"\");\n\n // Local validation. Backend re-validates everything; these only\n // gate the \"Continue\" button and surface inline errors.\n const amountError = useMemo<string | undefined>(() => {\n if (!amount) return undefined;\n if (!/^\\d+(\\.\\d+)?$/.test(amount.trim())) {\n return t(\"perpDeposit.error.amountInvalid\");\n }\n if (Number(amount) <= 0) return t(\"perpDeposit.error.amountInvalid\");\n return undefined;\n }, [amount, t]);\n\n const recipientError = useMemo<string | undefined>(() => {\n if (!recipient) return undefined;\n return validateRecipient ? validateRecipient(recipient) : undefined;\n }, [recipient, validateRecipient]);\n\n const grossLamports = useMemo(\n () => (amountError ? \"\" : solToLamports(amount)),\n [amount, amountError],\n );\n\n const quoteReq = useMemo<DepositQuoteRequest | null>(() => {\n if (!grossLamports || grossLamports === \"0\") return null;\n if (recipientError) return null;\n if (!recipient) return null;\n return {\n userSolanaAddress,\n hyperliquidRecipient: recipient,\n grossLamports,\n source,\n };\n }, [grossLamports, recipient, recipientError, source, userSolanaAddress]);\n\n const quoteQ = usePerpDepositQuote(quoteReq, {\n enabled: Boolean(quoteReq),\n });\n\n const { state, execute, reset, dispatch } =\n usePerpDepositExecute(signAndBroadcast);\n const intentId =\n state.phase === \"submitted\" ||\n state.phase === \"tracking\" ||\n state.phase === \"succeeded\" ||\n state.phase === \"refunded\"\n ? state.intentId\n : state.phase === \"failed\"\n ? state.intentId\n : undefined;\n\n const statusQ = usePerpDepositStatus(intentId, {\n enabled:\n Boolean(intentId) &&\n state.phase !== \"succeeded\" &&\n state.phase !== \"refunded\" &&\n state.phase !== \"failed\",\n });\n\n // Forward backend status into the FSM so the UI advances.\n useEffect(() => {\n if (statusQ.data) {\n dispatch({ type: \"STATUS_UPDATE\", status: statusQ.data });\n }\n }, [statusQ.data, dispatch]);\n\n // Funnel-end side effects.\n useEffect(() => {\n if (state.phase === \"succeeded\") {\n onSettled?.(state.intentId);\n } else if (state.phase === \"failed\") {\n onError?.(state.intentId, state.error.message);\n }\n }, [state, onSettled, onError]);\n\n const handleContinue = useCallback(() => {\n if (!quoteQ.data) return;\n dispatch({ type: \"QUOTE_REQUEST\" });\n dispatch({ type: \"QUOTE_RECEIVED\", quote: quoteQ.data });\n }, [dispatch, quoteQ.data]);\n\n const handleConfirm = useCallback(async () => {\n if (state.phase !== \"ready_to_sign\") return;\n try {\n await execute({\n quote: state.quote,\n userSolanaAddress,\n hyperliquidRecipient: recipient,\n userId,\n source,\n campaign,\n });\n } catch {\n // Hook already advanced FSM into `failed`; nothing to do here.\n }\n }, [state, execute, userSolanaAddress, recipient, userId, source, campaign]);\n\n const handleExpire = useCallback(() => {\n dispatch({ type: \"QUOTE_EXPIRED\" });\n }, [dispatch]);\n\n const handleRetry = useCallback(async () => {\n dispatch({ type: \"RESET\" });\n await quoteQ.refetch();\n }, [dispatch, quoteQ]);\n\n const showConfirm =\n state.phase === \"ready_to_sign\" ||\n state.phase === \"signing\" ||\n state.phase === \"broadcasting\" ||\n state.phase === \"expired\";\n\n const showStatus =\n state.phase === \"submitted\" ||\n state.phase === \"tracking\" ||\n state.phase === \"succeeded\" ||\n state.phase === \"refunded\" ||\n (state.phase === \"failed\" && Boolean(state.intentId));\n\n const status =\n state.phase === \"tracking\" ||\n state.phase === \"succeeded\" ||\n state.phase === \"refunded\"\n ? state.status\n : state.phase === \"failed\"\n ? state.status\n : undefined;\n\n const continueDisabled =\n !quoteQ.data ||\n quoteQ.isFetching ||\n Boolean(amountError) ||\n Boolean(recipientError) ||\n !quoteReq;\n\n return (\n <Card className={className}>\n <CardBody className=\"flex flex-col gap-4 p-6\">\n <div>\n <h3 className=\"text-lg font-semibold\">{t(\"perpDeposit.title\")}</h3>\n <p className=\"text-default-500 text-sm\">\n {t(\"perpDeposit.description\")}\n </p>\n </div>\n\n <DepositFormUI\n amount={amount}\n onAmountChange={setAmount}\n recipient={recipient}\n onRecipientChange={setRecipient}\n balanceSol={balanceSol}\n onMax={onMaxClick}\n amountError={amountError}\n recipientError={recipientError}\n disabled={\n state.phase !== \"idle\" &&\n state.phase !== \"expired\" &&\n state.phase !== \"failed\"\n }\n />\n\n <Button\n color=\"primary\"\n isDisabled={continueDisabled}\n isLoading={quoteQ.isFetching}\n onPress={handleContinue}\n >\n {quoteQ.isFetching\n ? t(\"perpDeposit.gettingQuote\")\n : t(\"perpDeposit.confirmQuote\")}\n </Button>\n\n {quoteQ.error && (\n <div className=\"text-danger text-xs\">\n {t(\"perpDeposit.error.quoteFailed\")}\n </div>\n )}\n </CardBody>\n\n <DepositConfirmUI\n isOpen={showConfirm}\n quote={\n state.phase === \"ready_to_sign\" ||\n state.phase === \"signing\" ||\n state.phase === \"broadcasting\" ||\n state.phase === \"expired\"\n ? state.quote\n : undefined\n }\n isExecuting={\n state.phase === \"signing\" || state.phase === \"broadcasting\"\n }\n isExpired={state.phase === \"expired\"}\n onConfirm={handleConfirm}\n onCancel={reset}\n onExpire={handleExpire}\n />\n\n <DepositStatusUI\n isOpen={showStatus}\n phase={state.phase}\n status={status}\n solanaExplorerUrl={\n status?.solanaTxHash && buildSolanaExplorerUrl\n ? buildSolanaExplorerUrl(status.solanaTxHash)\n : undefined\n }\n hyperliquidExplorerUrl={\n status?.hyperliquidTxHash && buildHyperliquidExplorerUrl\n ? buildHyperliquidExplorerUrl(status.hyperliquidTxHash)\n : undefined\n }\n onRetry={state.phase === \"failed\" ? handleRetry : undefined}\n onClose={reset}\n errorMessage={\n state.phase === \"failed\" ? state.error.message : undefined\n }\n />\n </Card>\n );\n}\n","import { useTranslation } from \"@liberfi.io/i18n\";\nimport {\n Button,\n Card,\n CardBody,\n CardFooter,\n CardHeader,\n Spinner,\n cn,\n} from \"@liberfi.io/ui\";\nimport type {\n SetupState,\n SetupStep,\n StepRecord,\n StepStatus,\n} from \"../../hooks/hyperliquid-setup/setup-state-machine\";\n\n/**\n * Pure presentational card for the Hyperliquid first-run setup flow.\n *\n * The component is fully driven by the FSM state from\n * `useHyperliquidSetup` plus a couple of action callbacks, so consumers\n * can wire it into either a modal, a sidebar panel, or an inline card\n * without forking the markup.\n */\nexport interface HyperliquidInitUIProps {\n /** FSM snapshot rendered as the checklist. */\n state: SetupState;\n /** Trigger the next runnable step (sequential default). */\n onContinue: () => void;\n /** Retry a specific step (used by per-row error recovery). */\n onRetryStep?: (index: number) => void;\n /** Refresh the on-chain state — typically rendered when the load failed. */\n onReload?: () => void;\n /** Optional dismiss handler — show a \"Skip for now\" CTA when set. */\n onDismiss?: () => void;\n /** Optional className override for embedding inside other cards. */\n className?: string;\n}\n\nexport function HyperliquidInitUI({\n state,\n onContinue,\n onRetryStep,\n onReload,\n onDismiss,\n className,\n}: HyperliquidInitUIProps) {\n const { t } = useTranslation();\n const phase = state.phase;\n const isExecuting = phase === \"executing\";\n const isLoading = phase === \"loading\";\n const isLoadError = phase === \"error\" && state.steps.length === 0;\n\n return (\n <Card className={cn(\"w-full max-w-md\", className)}>\n <CardHeader className=\"flex flex-col items-start gap-1\">\n <h3 className=\"text-lg font-semibold\">\n {t(\"perpDeposit.setup.title\")}\n </h3>\n <p className=\"text-foreground-500 text-sm\">\n {t(\"perpDeposit.setup.description\")}\n </p>\n </CardHeader>\n <CardBody className=\"gap-3\">\n {isLoading && <LoadingRow />}\n {isLoadError && (\n <p className=\"text-danger text-sm\">\n {t(\"perpDeposit.setup.loadFailed\", { message: state.error ?? \"\" })}\n </p>\n )}\n {!isLoading &&\n !isLoadError &&\n state.steps.map((rec, idx) => (\n <SetupStepRow\n key={`${rec.step.id}-${idx}`}\n rec={rec}\n index={idx}\n isCurrent={state.currentIndex === idx}\n onRetry={onRetryStep}\n />\n ))}\n {phase === \"done\" && (\n <p className=\"text-success text-sm\">\n {t(\"perpDeposit.setup.alreadyActive\")}\n </p>\n )}\n </CardBody>\n <CardFooter className=\"flex justify-between gap-2\">\n {onDismiss && (\n <Button variant=\"light\" onPress={onDismiss} isDisabled={isExecuting}>\n {phase === \"done\"\n ? t(\"perpDeposit.setup.dismiss\")\n : t(\"perpDeposit.setup.skip\")}\n </Button>\n )}\n <div className=\"flex-1\" />\n {isLoadError && onReload && (\n <Button color=\"primary\" onPress={onReload}>\n {t(\"perpDeposit.setup.retry\")}\n </Button>\n )}\n {!isLoadError && phase !== \"done\" && (\n <Button\n color=\"primary\"\n onPress={onContinue}\n isLoading={isExecuting}\n isDisabled={isExecuting || isLoading}\n >\n {state.steps.some((s) => s.status === \"done\")\n ? t(\"perpDeposit.setup.continue\")\n : t(\"perpDeposit.setup.cta\")}\n </Button>\n )}\n </CardFooter>\n </Card>\n );\n}\n\ninterface SetupStepRowProps {\n rec: StepRecord;\n index: number;\n isCurrent: boolean;\n onRetry?: (index: number) => void;\n}\n\nfunction SetupStepRow({ rec, index, isCurrent, onRetry }: SetupStepRowProps) {\n const { t } = useTranslation();\n const title = stepTitle(rec.step.id, () => {\n switch (rec.step.id) {\n case \"approveBuilderFee\":\n return t(\"perpDeposit.setup.builderFee.label\");\n case \"setReferrer\":\n return t(\"perpDeposit.setup.referrer.label\");\n case \"updateLeverage\":\n return t(\"perpDeposit.setup.leverage.label\");\n }\n });\n const description = ((): string => {\n switch (rec.step.id) {\n case \"approveBuilderFee\": {\n const bps = (rec.step.params.maxFeeRate / 10).toFixed(1);\n return t(\"perpDeposit.setup.builderFee.description\", { bps });\n }\n case \"setReferrer\":\n return t(\"perpDeposit.setup.referrer.description\", {\n code: rec.step.params.code,\n });\n case \"updateLeverage\":\n return t(\"perpDeposit.setup.leverage.description\");\n }\n })();\n const statusLabel = ((): string => {\n switch (rec.status) {\n case \"pending\":\n return t(\"perpDeposit.setup.step.pending\");\n case \"skipped\":\n return t(\"perpDeposit.setup.step.skipped\");\n case \"running\":\n return t(\"perpDeposit.setup.step.running\");\n case \"done\":\n return t(\"perpDeposit.setup.step.done\");\n case \"error\":\n return t(\"perpDeposit.setup.step.error\");\n }\n })();\n return (\n <div\n className={cn(\n \"border-divider flex items-start justify-between gap-3 rounded-md border p-3\",\n rec.status === \"error\" && \"border-danger\",\n rec.status === \"done\" && \"border-success/40 bg-success/5\",\n rec.status === \"skipped\" && \"border-default bg-default-100/40\",\n )}\n >\n <div className=\"flex-1\">\n <div className=\"flex items-center gap-2 text-sm font-medium\">\n <StepIcon status={rec.status} isCurrent={isCurrent} />\n <span>{title}</span>\n </div>\n <p className=\"text-foreground-500 mt-1 text-xs\">{description}</p>\n {rec.status === \"error\" && rec.error && (\n <p className=\"text-danger mt-1 text-xs\">{rec.error}</p>\n )}\n </div>\n <div className=\"flex flex-col items-end gap-1 text-xs\">\n <span className={cn(statusBadgeClass(rec.status))}>{statusLabel}</span>\n {rec.status === \"error\" && onRetry && (\n <Button\n size=\"sm\"\n variant=\"flat\"\n color=\"danger\"\n onPress={() => onRetry(index)}\n >\n {t(\"perpDeposit.setup.retry\")}\n </Button>\n )}\n </div>\n </div>\n );\n}\n\nfunction LoadingRow() {\n const { t } = useTranslation();\n return (\n <div className=\"flex items-center gap-2 py-2 text-sm\">\n <Spinner size=\"sm\" />\n <span>{t(\"perpDeposit.setup.loading\")}</span>\n </div>\n );\n}\n\nfunction StepIcon({\n status,\n isCurrent,\n}: {\n status: StepStatus;\n isCurrent: boolean;\n}) {\n if (status === \"running\" || isCurrent) {\n return <Spinner size=\"sm\" />;\n }\n if (status === \"done\" || status === \"skipped\") {\n return (\n <span aria-hidden className=\"text-success\">\n ✓\n </span>\n );\n }\n if (status === \"error\") {\n return (\n <span aria-hidden className=\"text-danger\">\n !\n </span>\n );\n }\n return (\n <span\n aria-hidden\n className=\"border-foreground-400 inline-block h-3 w-3 rounded-full border\"\n />\n );\n}\n\nfunction statusBadgeClass(status: StepStatus): string {\n switch (status) {\n case \"done\":\n return \"text-success\";\n case \"skipped\":\n return \"text-foreground-500\";\n case \"running\":\n return \"text-primary\";\n case \"error\":\n return \"text-danger\";\n default:\n return \"text-foreground-500\";\n }\n}\n\n/**\n * Tiny indirection to keep `SetupStepRow` flat — invokes a closure\n * the caller wrote inline so we don't pass `t` across function\n * boundaries (which would defeat its strict-key inference).\n */\nfunction stepTitle(_id: SetupStep[\"id\"], compute: () => string): string {\n return compute();\n}\n","import { useCallback } from \"react\";\nimport {\n useHyperliquidSetup,\n type UseHyperliquidSetupOptions,\n type SetupState,\n} from \"../../hooks/hyperliquid-setup\";\nimport { HyperliquidInitUI } from \"./hyperliquid-init.ui\";\n\n/**\n * Highest-level Hyperliquid setup widget.\n *\n * Wraps `useHyperliquidSetup` with the presentational card so consumers\n * can drop in a single component:\n *\n * <HyperliquidInitWidget\n * adapter={mySetupAdapter}\n * userAddress={evmAddress}\n * steps={[ ... ]}\n * onComplete={() => navigate(\"/perp\")}\n * onDismiss={() => closeModal()}\n * />\n *\n * The widget is a thin coordinator — all logic lives in the hook and\n * all presentation lives in `HyperliquidInitUI`. This split keeps the\n * UI testable in isolation (Storybook just hands it a `state` prop).\n */\nexport interface HyperliquidInitWidgetProps extends Pick<\n UseHyperliquidSetupOptions,\n \"adapter\" | \"userAddress\" | \"steps\" | \"autoLoad\" | \"onError\"\n> {\n /** Invoked once every step is `done` or `skipped`. */\n onComplete?: (state: SetupState) => void;\n /**\n * Optional dismiss callback — when supplied the card renders a\n * \"Skip for now\" / \"Close\" CTA so the user can leave the wizard.\n */\n onDismiss?: () => void;\n /** Optional className passthrough to the rendered card. */\n className?: string;\n}\n\nexport function HyperliquidInitWidget({\n adapter,\n userAddress,\n steps,\n autoLoad,\n onComplete,\n onError,\n onDismiss,\n className,\n}: HyperliquidInitWidgetProps) {\n const { state, runNext, runStep, reload } = useHyperliquidSetup({\n adapter,\n userAddress,\n steps,\n autoLoad,\n onComplete,\n onError,\n });\n\n const handleContinue = useCallback(() => {\n void runNext();\n }, [runNext]);\n\n const handleRetry = useCallback(\n (index: number) => {\n void runStep(index);\n },\n [runStep],\n );\n\n const handleReload = useCallback(() => {\n void reload();\n }, [reload]);\n\n return (\n <HyperliquidInitUI\n state={state}\n onContinue={handleContinue}\n onRetryStep={handleRetry}\n onReload={handleReload}\n onDismiss={onDismiss}\n className={className}\n />\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/version.ts","../src/client/hyperliquid/WebSocketManager.ts","../src/client/hyperliquid/HyperliquidPerpetualsClient.ts","../src/client/liberfi/transport.ts","../src/client/liberfi/LiberFiPerpetualsClient.ts","../src/client/liberfi/LiberFiPerpDepositClient.ts","../src/client/liberfi/deposit-types.ts","../src/client/liberfi/deposit-state-machine.ts","../src/context/PerpetualsContext.ts","../src/providers/PerpetualsProvider.tsx","../src/hooks/usePerpetualsClient.ts","../src/hooks/useCoinsQuery.ts","../src/hooks/useMarketQuery.ts","../src/hooks/useMarketsQuery.ts","../src/hooks/useKlinesQuery.ts","../src/hooks/useOrderBookQuery.ts","../src/hooks/useRecentTradesQuery.ts","../src/hooks/usePositionsQuery.ts","../src/hooks/useOrdersQuery.ts","../src/hooks/useTradesQuery.ts","../src/hooks/useCreateOrderMutation.ts","../src/hooks/useCancelOrderMutation.ts","../src/hooks/useMarketDataSubscription.ts","../src/hooks/useCandlesSubscription.ts","../src/hooks/useUserDataSubscription.ts","../src/hooks/usePerpDepositClient.ts","../src/hooks/usePerpDepositQuote.ts","../src/hooks/usePerpDepositExecute.ts","../src/hooks/usePerpDepositStatus.ts","../src/hooks/hyperliquid-setup/setup-state-machine.ts","../src/hooks/hyperliquid-setup/useHyperliquidSetup.ts","../src/components/coin-info/coin-info-notfound.ui.tsx","../src/components/coin-info/coin-info-skeletons.ui.tsx","../src/components/coin-info/coin-info.script.tsx","../src/components/coin-info/coin-info.ui.tsx","../src/components/coin-info/coin-info.widget.tsx","../src/components/search-coins/search-coins.script.tsx","../src/components/search-coins/search-coins.ui.tsx","../src/components/search-coins/search-coins.widget.tsx","../src/components/orderbook/orderbook.script.tsx","../src/components/orderbook/orderbook.ui.tsx","../src/components/orderbook/orderbook.widget.tsx","../src/components/trades/trades.script.tsx","../src/components/trades/trades.ui.tsx","../src/components/trades/trades.widget.tsx","../src/components/place-order/place-order-form.script.tsx","../src/components/place-order/place-order-form.ui.tsx","../src/components/place-order/place-order-form.widget.tsx","../src/components/positions/positions.script.tsx","../src/components/positions/positions.ui.tsx","../src/components/positions/positions.widget.tsx","../src/components/open-orders/open-orders.script.tsx","../src/components/open-orders/open-orders.ui.tsx","../src/components/open-orders/open-orders.widget.tsx","../src/components/trade-history/trade-history.script.tsx","../src/components/trade-history/trade-history.ui.tsx","../src/components/trade-history/trade-history.widget.tsx","../src/components/perp-deposit/format.ts","../src/components/perp-deposit/deposit-confirm.ui.tsx","../src/components/perp-deposit/deposit-form.ui.tsx","../src/components/perp-deposit/deposit-status.ui.tsx","../src/components/perp-deposit/deposit-flow.widget.tsx","../src/components/hyperliquid-init/hyperliquid-init.ui.tsx","../src/components/hyperliquid-init/hyperliquid-init.widget.tsx"],"names":["version_default","aggregationKey","type","param","aggregation","m","WebSocketManager","wsEndpoint","resolve","reject","settled","settle","callback","ws","event","error","delay","message","subscription","data","channel","subscriptionId","transformedData","expectedCoin","payloadCoin","symbol","ctx","mid","mark","prev","change24h","trade","bids","asks","level","fill","sub","interval","unsubscription","HYPERLIQUID_ENDPOINTS","HyperliquidPerpetualsClient","config","endpoint","body","url","controller","timeoutId","response","HyperliquidApiError","meta","asset","markets","symbols","assetCtxs","allMarkets","index","currentPrice","prevPrice","symbolSet","limitOrOptions","coin","options","intervalMs","limit","startTime","endTime","bars","candle","maxLevel","_params","params","positions","assetPos","pos","quantity","entryPrice","unrealizedPnl","positionValue","filteredPositions","p","sum","orders","order","origSz","remainingSz","filledSz","filteredOrders","trades","isLong","t","userAddress","subscriptionType","statusCode","responseBody","LiberFiApiError","DEFAULT_TIMEOUT_MS","LiberFiHttpTransport","path","query","key","value","qs","method","opts","timeoutMs","text","safeText","err","DEFAULT_WS_ENDPOINT","LiberFiPerpetualsClient","result","fills","prepared","signature","LiberFiPerpDepositClient","req","intentId","TERMINAL_DEPOSIT_STATUSES","initialDepositState","reduceDepositState","state","mapStatusToPhase","status","isTerminal","isPolling","currentStatus","currentBreakdown","isTerminalLifecycle","PerpetualsContext","createContext","PerpetualsProvider","client","depositClient","children","useMemo","jsx","usePerpetualsClient","context","useContext","coinsQueryKey","fetchCoins","useCoinsQuery","useQuery","marketQueryKey","fetchMarket","useMarketQuery","marketsQueryKey","fetchMarkets","useMarketsQuery","klinesQueryKey","fetchKlines","useKlinesQuery","orderBookQueryKey","agg","aggKey","fetchOrderBook","useOrderBookQuery","recentTradesQueryKey","fetchRecentTrades","useRecentTradesQuery","positionsQueryKey","fetchPositions","usePositionsQuery","enabled","queryParams","ordersQueryKey","fetchOrders","useOrdersQuery","tradesQueryKey","fetchTrades","useTradesQuery","createOrder","useCreateOrderMutation","useMutation","cancelOrder","useCancelOrderMutation","useMarketDataSubscription","throttleMs","setData","useState","isConnected","setIsConnected","setError","pendingDataRef","useRef","flushTimerRef","throttleMsRef","handleData","useCallback","newData","next","useEffect","isSubscribed","useCandlesSubscription","useUserDataSubscription","usePerpDepositClient","usePerpDepositClientMaybe","perpDepositQuoteQueryKey","fetchPerpDepositQuote","usePerpDepositQuote","isQuoteReady","usePerpDepositExecute","signAndBroadcast","dispatch","useReducer","reset","execute","input","quote","solanaTxHash","info","toErrorInfo","submitReq","out","fallbackCode","parsed","parseJsonSafe","perpDepositStatusQueryKey","fetchPerpDepositStatus","usePerpDepositStatus","pollIntervalMs","initialSetupState","classifyStep","step","current","sameAddress","reduceSetupState","action","rec","i","mergedAccount","mergeAccountState","s","nextRunnableStep","a","b","base","patch","useHyperliquidSetup","adapter","steps","autoLoad","onComplete","onError","adapterRef","stepsRef","onCompleteRef","onErrorRef","reload","accountState","records","e","toError","runStep","record","invokeAdapter","runNext","idx","completedRef","CoinInfoNotFoundUI","CoinInfoSkeletonsUI","jsxs","Skeleton","useCoinInfo","marketData","setMarketData","fundingCountdown","setFundingCountdown","initialData","isPending","realtimeData","normalized","normalizeRealtimeTickerPayload","previous","buildMarketData","calculateCountdown","now","eightHours","remainder","timeUntilNext","payload","matched","item","toNumberOr","fallback","formatCountdown","seconds","hours","minutes","secs","formatNumber","num","decimals","formatPrice","price","CoinInfoUI","indexPrice","volume24h","openInterest","fundingRate","safeChange24h","safeFundingRate","isPositiveChange","changePercent","CoinInfoWidget","isLoading","useSearchCoinsScript","onSelectCoin","searchQuery","setSearchQuery","coins","setCoins","coinSymbols","isLoadingSymbols","marketsData","isLoadingMarkets","filteredCoins","SearchCoinsUI","onSearchChange","SearchIcon","fundingPercent","isPositiveFunding","tokenName","target","SearchCoinsWidget","className","handleSelectCoin","aggregationFromStep","k","candidates","eps","best","c","aggregateByPrecision","levels","precision","side","aggregated","round","roundedPrice","existing","calculateTotalsAndPercentages","total","withTotals","usdAmount","maxTotal","useOrderBookScript","initialPrecision","orderBook","setOrderBook","setPrecision","priceMagnitude","bestBid","bestAsk","ref","referencePrice","aggregatedBids","aggregatedAsks","sortedBids","sortedAsks","spread","spreadPercentage","ORDERBOOK_SCROLL_STYLE","CONTAINER_STYLE","HEADER_STYLE","HEADER_CELL_STYLE","ROW_STYLE","ASK_BAR_STYLE_BASE","BID_BAR_STYLE_BASE","ASK_PRICE_STYLE","BID_PRICE_STYLE","ROW_CELL_STYLE","ROW_PRICE_CELL_STYLE","SPREAD_BAR_STYLE","SPREAD_BAR_INNER_STYLE","SPREAD_LABEL_STYLE","SPREAD_VALUE_STYLE","SPREAD_BUTTON_STYLE","SPREAD_DROPDOWN_STYLE","SPREAD_OPTION_STYLE","SPREAD_OPTION_SELECTED_STYLE","formatQuantity","qty","formatPrecision","OBRow","memo","percentage","onPriceClick","isAsk","barStyle","handleClick","SpreadBar","precisionOptions","onPrecisionChange","open","setOpen","wrapperRef","handler","chevronStyle","v","opt","selected","OrderBookUI","asksScrollRef","bidsScrollRef","asksStuckRef","bidsStuckRef","renderedAsks","el","handleAsksScroll","distanceFromBottom","handleBidsScroll","ask","bid","DEFAULT_ORDER_BOOK_PRECISION_OPTIONS","OrderBookSkeleton","_","OrderBookEmpty","OrderBookWidget","defaultPrecision","BATCH_FLUSH_MS","useTradesScript","setTrades","realtimeTrade","isValidTrade","pendingRef","limitRef","incoming","normalizeRealtimeTrades","batch","deduped","ROW_HEIGHT","HEADER_HEIGHT","PRICE_COL_MAX_W","AGE_COL_MAX_W","HEADER_PRICE_CELL","HEADER_SIZE_CELL","HEADER_AGE_CELL","ROW_INNER_STYLE","ROW_PRICE_CELL","ROW_SIZE_CELL","ROW_AGE_CELL","BUY_BAR_STYLE_BASE","SELL_BAR_STYLE_BASE","formatUsd","usd","formatAge","ageMs","barWidth","TradeRow","style","onTradeClick","birthday","useTickAge","isBuy","TradesUI","listContainerRef","height","useResizeObserver","rowProps","List","TradesSkeleton","TradesEmpty","TradesWidget","usePlaceOrderFormScript","maxLeverageProp","onSuccess","setSide","orderType","setOrderType","form","useForm","isSubmitting","watchedValues","amount","leverage","estimatedFee","estimatedTotal","liquidationPrice","maintenanceMarginRate","positionsData","accountValue","availableMargin","currentPosition","handleSubmit","finalPrice","takeProfitPrice","stopLossPrice","tpPercent","slPercent","LeverageModal","maxLeverage","onLeverageChange","onClose","presets","Slider","preset","cn","PlaceOrderFormUI","methods","onSideChange","onOrderTypeChange","onSubmit","onAddFunds","showLeverageModal","setShowLeverageModal","showTpSl","setShowTpSl","tokenSymbol","positionPercent","handlePositionSlider","pct","maxAmount","tab","RHForm","RHNumberInput","PlaceOrderFormWidget","resolvedMaxLeverage","usePositionsScript","onCloseSuccess","onCloseError","setPositions","realtimePosition","isClosing","prevPositions","existingIndex","newPositions","handleClosePosition","position","closeSide","formatPnl","pnl","formatPnlPercent","percent","PositionsUI","onClosePosition","headerRow","pnlColor","Button","PositionsSkeleton","PositionsEmpty","PositionsWidget","useOpenOrdersScript","onCancelSuccess","onCancelError","setOrders","ordersData","realtimeOrder","isCanceling","prevOrders","o","newOrders","handleCancelOrder","formatTime","timestamp","date","OpenOrdersUI","onCancelOrder","OpenOrdersSkeleton","OpenOrdersEmpty","OpenOrdersWidget","getTimeRangeInMs","range","today","useTradeHistoryScript","initialTimeRange","pageSize","timeRange","setTimeRange","currentPage","setCurrentPage","allTrades","setAllTrades","tradesData","totalPages","startIndex","endIndex","page","formatDateTime","month","day","TIME_RANGE_OPTIONS","TradeHistoryUI","onTimeRangeChange","onNextPage","onPreviousPage","onGoToPage","option","Fragment","pageNum","TradeHistorySkeleton","TradeHistoryEmpty","TradeHistoryWidget","goToNextPage","goToPreviousPage","goToPage","LAMPORTS_PER_SOL","HL_USDC_DECIMALS","HL_USDC_DIVISOR","lamportsToSol","n","divToFixed","hlUsdcRawToUsdc","microUsdcToUsdc","solToLamports","whole","frac","fracPadded","combined","numerator","denominator","negative","abs","scale","scaledRemainder","secondsUntil","expiresAtMs","nowMs","shortAddress","addr","head","tail","DepositConfirmUI","isOpen","isExecuting","isExpired","onConfirm","onCancel","onExpire","useTranslation","secondsLeft","setSecondsLeft","id","remaining","Modal","ModalContent","ModalHeader","ModalBody","BreakdownSummary","Spinner","ModalFooter","breakdown","Row","label","highlight","muted","DepositFormUI","onAmountChange","recipient","onRecipientChange","balanceSol","disabled","amountError","recipientError","onMax","Input","ACCENT","DepositStatusUI","phase","solanaExplorerUrl","hyperliquidExplorerUrl","onRetry","errorMessage","variant","phaseToVariant","showRetry","StyledModal","XCloseIcon","PhaseIcon","variantTextClass","TxLink","href","hash","ExternalLinkIcon","AccentSpinner","CheckCircle","AlertCircle","XCircle","props","DepositFlowWidget","userSolanaAddress","userId","source","campaign","defaultRecipient","onMaxClick","validateRecipient","buildSolanaExplorerUrl","buildHyperliquidExplorerUrl","onSettled","setAmount","setRecipient","grossLamports","quoteReq","quoteQ","statusQ","handleContinue","handleConfirm","handleExpire","handleRetry","showConfirm","showStatus","continueDisabled","Card","CardBody","HyperliquidInitUI","onContinue","onRetryStep","onReload","onDismiss","isLoadError","CardHeader","LoadingRow","SetupStepRow","CardFooter","isCurrent","title","stepTitle","description","bps","statusLabel","StepIcon","statusBadgeClass","_id","compute","HyperliquidInitWidget","handleReload"],"mappings":"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","file":"index.mjs","sourcesContent":["declare global {\n interface Window {\n __LIBERFI_VERSION__?: {\n [key: string]: string;\n };\n }\n}\nif (typeof window !== \"undefined\") {\n window.__LIBERFI_VERSION__ = window.__LIBERFI_VERSION__ || {};\n window.__LIBERFI_VERSION__[\"@liberfi.io/ui-perpetuals\"] = \"0.2.15\";\n}\n\nexport default \"0.2.15\";\n","import type { Kline, MarketData } from \"../../types\";\n\n/**\n * WebSocket subscription callback function type\n */\ntype SubscriptionCallback = (data: any) => void;\n\n/**\n * Hyperliquid `l2Book` aggregation parameters.\n *\n * Sending these on the `subscribe` payload causes Hyperliquid to pre-aggregate\n * raw price levels into discrete buckets server-side, so a single 20-level\n * snapshot covers a much wider price range than at native tick resolution.\n *\n * - `nSigFigs`: number of significant figures (2..5) to round prices to.\n * `undefined` (or `null`) means full native precision.\n * - `mantissa`: only valid when `nSigFigs === 5`. Allowed values: 1, 2, 5.\n * At BTC ~$80k with `nSigFigs=5`, mantissa controls the smallest digit:\n * 1 → step $1, 2 → step $2, 5 → step $5.\n *\n * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint\n */\nexport interface OrderBookAggregation {\n nSigFigs?: 2 | 3 | 4 | 5;\n mantissa?: 1 | 2 | 5;\n}\n\n/**\n * WebSocket subscription metadata\n */\ninterface Subscription {\n type: string;\n param: string;\n callback: SubscriptionCallback;\n aggregation?: OrderBookAggregation;\n}\n\n/**\n * Build a stable map key for a (type, param, aggregation) triple. Different\n * aggregations of the same coin are separate subscriptions because Hyperliquid\n * pushes a different stream for each — they must not share storage.\n */\nfunction aggregationKey(\n type: string,\n param: string,\n aggregation?: OrderBookAggregation,\n): string {\n if (\n type !== \"orderBook\" ||\n !aggregation ||\n aggregation.nSigFigs === undefined\n ) {\n return `${type}:${param}`;\n }\n const m =\n aggregation.nSigFigs === 5 &&\n aggregation.mantissa &&\n aggregation.mantissa !== 1\n ? `:m${aggregation.mantissa}`\n : \"\";\n return `${type}:${param}:n${aggregation.nSigFigs}${m}`;\n}\n\n/**\n * WebSocket Manager for Hyperliquid\n *\n * Handles WebSocket connection lifecycle, including:\n * - Connection management (connect/disconnect)\n * - Automatic reconnection with exponential backoff\n * - Heartbeat to keep connection alive\n * - Subscription management (subscribe/unsubscribe)\n * - Message queue for offline messages\n */\nexport class WebSocketManager {\n private ws: WebSocket | null = null;\n private wsEndpoint: string;\n private subscriptions: Map<string, Subscription> = new Map();\n private reconnectAttempts: number = 0;\n private maxReconnectAttempts: number = 10;\n private reconnectDelay: number = 1000; // Initial reconnect delay: 1 second\n private heartbeatInterval: number | null = null;\n private messageQueue: any[] = []; // Message queue before connection established\n private isConnected: boolean = false;\n private pingInterval: number = 30000; // 30 second heartbeat\n private reconnectTimeout: number | null = null;\n private isReconnecting: boolean = false;\n private connectPromise: Promise<void> | null = null;\n private manuallyDisconnected: boolean = false;\n\n /**\n * Create a new WebSocketManager\n * @param wsEndpoint WebSocket endpoint URL\n */\n constructor(wsEndpoint: string) {\n this.wsEndpoint = wsEndpoint;\n }\n\n /**\n * Connect to WebSocket server\n * @returns Promise that resolves when connection is established\n */\n async connect(): Promise<void> {\n if (this.isConnected && this.ws?.readyState === WebSocket.OPEN) {\n return;\n }\n\n if (this.connectPromise) {\n return this.connectPromise;\n }\n\n this.manuallyDisconnected = false;\n\n this.connectPromise = new Promise((resolve, reject) => {\n let settled = false;\n\n const settle = (callback: () => void) => {\n if (settled) return;\n settled = true;\n this.connectPromise = null;\n callback();\n };\n\n try {\n const ws = new WebSocket(this.wsEndpoint);\n this.ws = ws;\n\n ws.onopen = () => {\n if (this.ws !== ws) return;\n console.log(\"[WebSocket] Connected to Hyperliquid\");\n this.isConnected = true;\n this.reconnectAttempts = 0;\n this.isReconnecting = false;\n this.startHeartbeat();\n this.flushMessageQueue();\n settle(resolve);\n };\n\n ws.onmessage = (event: MessageEvent) => {\n if (this.ws !== ws) return;\n this.handleMessage(event.data);\n };\n\n ws.onerror = (error: Event) => {\n if (this.ws !== ws) return;\n console.error(\"[WebSocket] Error:\", error);\n this.isConnected = false;\n settle(() => reject(new Error(\"WebSocket connection failed\")));\n };\n\n ws.onclose = (event: CloseEvent) => {\n if (this.ws !== ws) return;\n console.log(\n `[WebSocket] Closed: ${event.code} - ${event.reason || \"No reason provided\"}`,\n );\n this.isConnected = false;\n this.stopHeartbeat();\n this.connectPromise = null;\n\n // Only attempt reconnect if not manually disconnected (code 1000 = normal closure)\n if (!settled) {\n settle(() =>\n reject(\n new Error(\n `WebSocket closed before connection was established: ${event.code}`,\n ),\n ),\n );\n }\n\n if (!this.manuallyDisconnected && event.code !== 1000) {\n this.attemptReconnect();\n }\n };\n } catch (error) {\n settle(() => reject(error));\n }\n });\n\n return this.connectPromise;\n }\n\n /**\n * Disconnect from WebSocket server\n */\n disconnect(): void {\n this.manuallyDisconnected = true;\n this.stopHeartbeat();\n this.subscriptions.clear();\n\n // Clear reconnect timeout\n if (this.reconnectTimeout !== null) {\n clearTimeout(this.reconnectTimeout);\n this.reconnectTimeout = null;\n }\n\n if (this.ws) {\n this.ws.close(1000, \"Normal closure\");\n this.ws = null;\n }\n\n this.isConnected = false;\n this.isReconnecting = false;\n this.reconnectAttempts = 0;\n }\n\n /**\n * Attempt to reconnect with exponential backoff\n */\n private attemptReconnect(): void {\n if (this.isReconnecting) {\n return; // Already attempting to reconnect\n }\n\n if (this.reconnectAttempts >= this.maxReconnectAttempts) {\n console.error(\"[WebSocket] Max reconnection attempts reached\");\n return;\n }\n\n this.isReconnecting = true;\n this.reconnectAttempts++;\n\n // Exponential backoff: min(1000 * 2^attempts, 30000)\n const delay = Math.min(\n this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1),\n 30000, // Max 30 seconds\n );\n\n console.log(\n `[WebSocket] Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts})`,\n );\n\n this.reconnectTimeout = window.setTimeout(() => {\n this.connect()\n .then(() => {\n // Resubscribe to all previous subscriptions\n this.resubscribeAll();\n })\n .catch((error) => {\n console.error(\"[WebSocket] Reconnection failed:\", error);\n this.isReconnecting = false;\n // attemptReconnect will be called again by onclose event\n });\n }, delay);\n }\n\n /**\n * Start heartbeat interval to keep connection alive\n */\n private startHeartbeat(): void {\n this.heartbeatInterval = window.setInterval(() => {\n if (\n this.isConnected &&\n this.ws &&\n this.ws.readyState === WebSocket.OPEN\n ) {\n // Send a ping message to keep connection alive\n // Hyperliquid WebSocket accepts JSON messages\n this.send({ method: \"ping\" });\n }\n }, this.pingInterval);\n }\n\n /**\n * Stop heartbeat interval\n */\n private stopHeartbeat(): void {\n if (this.heartbeatInterval !== null) {\n clearInterval(this.heartbeatInterval);\n this.heartbeatInterval = null;\n }\n }\n\n /**\n * Send message to WebSocket server\n * @param message Message object to send\n */\n private send(message: any): void {\n if (this.isConnected && this.ws && this.ws.readyState === WebSocket.OPEN) {\n this.ws.send(JSON.stringify(message));\n } else {\n // Connection not established, add to queue\n this.messageQueue.push(message);\n }\n }\n\n /**\n * Flush message queue after connection established\n */\n private flushMessageQueue(): void {\n while (this.messageQueue.length > 0) {\n const message = this.messageQueue.shift();\n if (message) {\n this.send(message);\n }\n }\n }\n\n /**\n * Resubscribe to all subscriptions after reconnection\n */\n private resubscribeAll(): void {\n this.subscriptions.forEach((subscription) => {\n this.sendSubscription(\n subscription.type,\n subscription.param,\n subscription.aggregation,\n );\n });\n }\n\n /**\n * Handle incoming WebSocket message\n * @param data Raw message data\n */\n private handleMessage(data: string): void {\n try {\n const message = JSON.parse(data);\n\n // Handle different message types\n if (message.channel) {\n this.handleChannelMessage(message);\n } else if (message.method === \"pong\") {\n // Heartbeat response\n // No action needed\n }\n } catch (error) {\n console.error(\"[WebSocket] Failed to parse message:\", error, data);\n }\n }\n\n /**\n * Handle channel-specific messages\n * @param message Parsed message object\n */\n private handleChannelMessage(message: any): void {\n const channel = message.channel;\n\n // Find matching subscriptions and trigger callbacks\n this.subscriptions.forEach((subscription, subscriptionId) => {\n if (\n this.isChannelMatch(\n channel,\n subscription.type,\n subscription.param,\n message,\n )\n ) {\n try {\n const transformedData = this.transformData(\n subscription.type,\n message.data,\n subscription.param,\n );\n subscription.callback(transformedData);\n } catch (error) {\n console.error(\n `[WebSocket] Error in subscription callback (${subscriptionId}):`,\n error,\n );\n }\n }\n });\n }\n\n /**\n * Check if channel matches subscription\n *\n * For per-coin channels (ticker via `activeAssetCtx`, trades, orderBook,\n * candle), we additionally match the coin in the payload against the\n * subscription parameter so a single multiplexed connection can feed many\n * subscriptions without cross-talk.\n *\n * @param channel Channel name from message\n * @param type Subscription type\n * @param param Subscription parameter (e.g. \"BTC-USDC\", \"BTC-USDC:1m\")\n * @param message Full parsed message (used to read payload coin)\n * @returns True if channel matches subscription\n */\n private isChannelMatch(\n channel: string,\n type: string,\n param: string,\n message: any,\n ): boolean {\n if (type === \"ticker\") {\n if (channel !== \"activeAssetCtx\") return false;\n const expectedCoin = param.split(\"-\")[0];\n const payloadCoin = message?.data?.coin;\n return typeof payloadCoin === \"string\" && payloadCoin === expectedCoin;\n } else if (type === \"trades\") {\n if (channel !== \"trades\") return false;\n const expectedCoin = param.split(\"-\")[0];\n // `trades` payload is an array; check the first element's coin if any.\n const payloadCoin = Array.isArray(message?.data)\n ? message.data[0]?.coin\n : undefined;\n return typeof payloadCoin !== \"string\" || payloadCoin === expectedCoin;\n } else if (type === \"orderBook\") {\n if (channel !== \"l2Book\") return false;\n const expectedCoin = param.split(\"-\")[0];\n const payloadCoin = message?.data?.coin;\n return typeof payloadCoin === \"string\" && payloadCoin === expectedCoin;\n } else if (type === \"candle\") {\n return channel === \"candle\";\n } else if (type === \"userFills\") {\n return channel === \"userFills\";\n } else if (type === \"userEvents\") {\n return channel === \"userEvents\";\n }\n\n return false;\n }\n\n /**\n * Transform raw data to standard format\n * @param type Subscription type\n * @param data Raw data from WebSocket\n * @param param Subscription parameter (e.g., symbol, interval)\n * @returns Transformed data\n */\n private transformData(type: string, data: any, param: string): any {\n if (type === \"ticker\") {\n return this.transformTickerData(data, param);\n } else if (type === \"trades\") {\n return this.transformTradesData(data, param);\n } else if (type === \"orderBook\") {\n return this.transformOrderBookData(data, param);\n } else if (type === \"candle\") {\n return this.transformCandleData(data, param);\n } else if (type === \"userFills\") {\n return this.transformUserFillsData(data);\n } else if (type === \"userEvents\") {\n return this.transformUserEventsData(data);\n }\n\n return data;\n }\n\n /**\n * Transform ticker data (Hyperliquid `activeAssetCtx` channel).\n *\n * Each push delivers the full per-coin market context — mark/mid price,\n * `prevDayPx` (so we can compute 24h change client-side), notional volume,\n * funding, open interest, oracle price, etc. We map this into the\n * standard {@link MarketData} shape so consumers (`useCoinInfo`, ticker\n * widgets, etc.) get a real-time, complete snapshot in one shot — no\n * second REST call required to fill in 24h change.\n *\n * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket\n */\n private transformTickerData(data: any, param: string): MarketData {\n const coin: string = data?.coin ?? param.split(\"-\")[0];\n const symbol = `${coin}-USDC`;\n const ctx = data?.ctx ?? {};\n\n const mid = parseFloat(ctx.midPx ?? ctx.markPx ?? \"0\");\n const mark = parseFloat(ctx.markPx ?? ctx.midPx ?? \"0\");\n const prev = ctx.prevDayPx ? parseFloat(ctx.prevDayPx) : mid;\n const change24h = prev > 0 ? ((mid - prev) / prev) * 100 : 0;\n\n return {\n symbol,\n price: mid,\n change24h,\n volume24h: parseFloat(ctx.dayNtlVlm ?? \"0\"),\n fundingRate: parseFloat(ctx.funding ?? \"0\"),\n openInterest: parseFloat(ctx.openInterest ?? \"0\"),\n markPrice: mark,\n indexPrice: parseFloat(ctx.oraclePx ?? ctx.midPx ?? \"0\"),\n };\n }\n\n /**\n * Transform trades data\n */\n private transformTradesData(data: any, symbol: string): any {\n if (!Array.isArray(data)) {\n return [];\n }\n\n return data.map((trade: any) => ({\n symbol,\n side: trade.side === \"B\" ? \"buy\" : \"sell\",\n price: parseFloat(trade.px),\n quantity: parseFloat(trade.sz),\n timestamp: trade.time,\n tradeId: trade.tid,\n }));\n }\n\n /**\n * Transform order book data\n */\n private transformOrderBookData(data: any, symbol: string): any {\n const [bids, asks] = data.levels || [[], []];\n\n return {\n symbol,\n bids: bids.map((level: any) => ({\n price: parseFloat(level.px),\n quantity: parseFloat(level.sz),\n count: level.n,\n })),\n asks: asks.map((level: any) => ({\n price: parseFloat(level.px),\n quantity: parseFloat(level.sz),\n count: level.n,\n })),\n timestamp: data.time || Date.now(),\n };\n }\n\n /**\n * Transform candle data\n */\n private transformCandleData(data: any, param: string): Kline {\n const [symbol] = param.split(\":\");\n\n return {\n symbol,\n open: parseFloat(data.o),\n high: parseFloat(data.h),\n low: parseFloat(data.l),\n close: parseFloat(data.c),\n volume: parseFloat(data.v),\n timestamp: data.t,\n closeTimestamp: data.T,\n };\n }\n\n /**\n * Transform user fills data\n */\n private transformUserFillsData(data: any): any {\n if (!Array.isArray(data)) {\n return [];\n }\n\n return data.map((fill: any) => ({\n tradeId: fill.tid?.toString(),\n orderId: fill.oid?.toString(),\n symbol: `${fill.coin}-USDC`,\n side: fill.dir?.includes(\"Long\") ? \"long\" : \"short\",\n price: parseFloat(fill.px),\n quantity: parseFloat(fill.sz),\n fee: parseFloat(fill.fee || \"0\"),\n feeCurrency: fill.feeToken || \"USDC\",\n isMaker: fill.side === \"M\",\n timestamp: fill.time,\n }));\n }\n\n /**\n * Transform user events data (orders and positions)\n */\n private transformUserEventsData(data: any): any {\n // User events can contain both order updates and position updates\n // Return the data as-is for now, let the callback handle it\n return data;\n }\n\n /**\n * Send subscription message to Hyperliquid WebSocket\n * @param type Subscription type\n * @param param Subscription parameter\n * @param aggregation Optional orderBook aggregation params (nSigFigs/mantissa)\n */\n private sendSubscription(\n type: string,\n param: string,\n aggregation?: OrderBookAggregation,\n ): void {\n let subscription: any;\n\n if (type === \"ticker\") {\n // Subscribe to per-coin `activeAssetCtx` so each push carries a full\n // market snapshot (mark/mid price, prevDayPx for 24h change, volume,\n // funding, open interest). This avoids the limitations of `allMids`,\n // which only streams price.\n const coin = param.split(\"-\")[0]; // \"BTC-USDC\" -> \"BTC\"\n subscription = {\n method: \"subscribe\",\n subscription: {\n type: \"activeAssetCtx\",\n coin,\n },\n };\n } else if (type === \"trades\") {\n // Subscribe to trades for specific coin\n const coin = param.split(\"-\")[0]; // \"BTC-USDC\" -> \"BTC\"\n subscription = {\n method: \"subscribe\",\n subscription: {\n type: \"trades\",\n coin,\n },\n };\n } else if (type === \"orderBook\") {\n // Subscribe to order book for specific coin. nSigFigs/mantissa let\n // Hyperliquid pre-aggregate the 20-level snapshot to a coarser grid,\n // dramatically widening the price range covered by a single payload.\n const coin = param.split(\"-\")[0];\n const sub: Record<string, unknown> = {\n type: \"l2Book\",\n coin,\n };\n if (aggregation?.nSigFigs !== undefined) {\n sub.nSigFigs = aggregation.nSigFigs;\n if (\n aggregation.nSigFigs === 5 &&\n aggregation.mantissa !== undefined &&\n aggregation.mantissa !== 1\n ) {\n sub.mantissa = aggregation.mantissa;\n }\n }\n subscription = {\n method: \"subscribe\",\n subscription: sub,\n };\n } else if (type === \"candle\") {\n // Subscribe to candles\n const [symbol, interval] = param.split(\":\");\n const coin = symbol.split(\"-\")[0];\n subscription = {\n method: \"subscribe\",\n subscription: {\n type: \"candle\",\n coin,\n interval,\n },\n };\n } else if (type === \"userFills\") {\n // Subscribe to user fills\n const userAddress = param;\n subscription = {\n method: \"subscribe\",\n subscription: {\n type: \"userFills\",\n user: userAddress,\n },\n };\n } else if (type === \"userEvents\") {\n // Subscribe to user events (orders + positions)\n const userAddress = param;\n subscription = {\n method: \"subscribe\",\n subscription: {\n type: \"userEvents\",\n user: userAddress,\n },\n };\n }\n\n if (subscription) {\n this.send(subscription);\n }\n }\n\n /**\n * Send unsubscription message to Hyperliquid WebSocket\n * @param type Subscription type\n * @param param Subscription parameter\n * @param aggregation Aggregation params used at subscribe time. Hyperliquid\n * matches subscriptions by full payload, so unsubscribe must echo the\n * same nSigFigs/mantissa.\n */\n private sendUnsubscription(\n type: string,\n param: string,\n aggregation?: OrderBookAggregation,\n ): void {\n let unsubscription: any;\n\n if (type === \"ticker\") {\n const coin = param.split(\"-\")[0];\n unsubscription = {\n method: \"unsubscribe\",\n subscription: {\n type: \"activeAssetCtx\",\n coin,\n },\n };\n } else if (type === \"trades\") {\n const coin = param.split(\"-\")[0];\n unsubscription = {\n method: \"unsubscribe\",\n subscription: {\n type: \"trades\",\n coin,\n },\n };\n } else if (type === \"orderBook\") {\n const coin = param.split(\"-\")[0];\n const sub: Record<string, unknown> = {\n type: \"l2Book\",\n coin,\n };\n if (aggregation?.nSigFigs !== undefined) {\n sub.nSigFigs = aggregation.nSigFigs;\n if (\n aggregation.nSigFigs === 5 &&\n aggregation.mantissa !== undefined &&\n aggregation.mantissa !== 1\n ) {\n sub.mantissa = aggregation.mantissa;\n }\n }\n unsubscription = {\n method: \"unsubscribe\",\n subscription: sub,\n };\n } else if (type === \"candle\") {\n const [symbol, interval] = param.split(\":\");\n const coin = symbol.split(\"-\")[0];\n unsubscription = {\n method: \"unsubscribe\",\n subscription: {\n type: \"candle\",\n coin,\n interval,\n },\n };\n } else if (type === \"userFills\") {\n const userAddress = param;\n unsubscription = {\n method: \"unsubscribe\",\n subscription: {\n type: \"userFills\",\n user: userAddress,\n },\n };\n } else if (type === \"userEvents\") {\n const userAddress = param;\n unsubscription = {\n method: \"unsubscribe\",\n subscription: {\n type: \"userEvents\",\n user: userAddress,\n },\n };\n }\n\n if (unsubscription) {\n this.send(unsubscription);\n }\n }\n\n /**\n * Subscribe to a data stream\n * @param type Subscription type\n * @param param Subscription parameter (symbol, user address, etc.)\n * @param callback Callback function to receive data\n * @param aggregation Optional `l2Book` aggregation params (only meaningful\n * when `type === \"orderBook\"`). The same params are echoed back in the\n * unsubscribe payload.\n * @returns Subscription ID (for unsubscribing). Aggregation is encoded in\n * the id so multiple aggregations of the same coin can coexist.\n */\n subscribe(\n type: string,\n param: string,\n callback: SubscriptionCallback,\n aggregation?: OrderBookAggregation,\n ): string {\n const subscriptionId = aggregationKey(type, param, aggregation);\n\n // Store subscription\n this.subscriptions.set(subscriptionId, {\n type,\n param,\n callback,\n aggregation,\n });\n\n // Send subscription message\n this.sendSubscription(type, param, aggregation);\n\n return subscriptionId;\n }\n\n /**\n * Unsubscribe from a data stream\n * @param subscriptionId Subscription ID returned from subscribe()\n */\n unsubscribe(subscriptionId: string): void {\n const subscription = this.subscriptions.get(subscriptionId);\n\n if (subscription) {\n // Send unsubscription message\n this.sendUnsubscription(\n subscription.type,\n subscription.param,\n subscription.aggregation,\n );\n\n // Remove subscription\n this.subscriptions.delete(subscriptionId);\n }\n }\n\n /**\n * Check if WebSocket is connected\n * @returns True if connected\n */\n isConnectedNow(): boolean {\n return this.isConnected;\n }\n}\n","import type {\n IPerpetualsClient,\n MarketData,\n Kline,\n KlineInterval,\n KlineQueryOptions,\n OrderBook,\n Trade,\n PlaceOrderParams,\n PlaceOrderResult,\n CancelOrderParams,\n CancelOrderResult,\n GetPositionsParams,\n GetPositionsResult,\n GetOpenOrdersParams,\n GetOpenOrdersResult,\n GetTradesParams,\n GetTradesResult,\n} from \"../../types\";\nimport {\n WebSocketManager,\n type OrderBookAggregation,\n} from \"./WebSocketManager\";\n\nexport type { OrderBookAggregation };\n\n/**\n * Hyperliquid 环境类型\n */\nexport type HyperliquidEnvironment = \"testnet\" | \"mainnet\";\n\n/**\n * Hyperliquid 客户端配置\n */\nexport interface HyperliquidClientConfig {\n /**\n * 环境配置\n * @default \"testnet\"\n */\n environment?: HyperliquidEnvironment;\n\n /**\n * 自定义 API 端点(可选)\n * 如果不提供,将根据 environment 自动选择\n */\n apiEndpoint?: string;\n\n /**\n * 自定义 WebSocket 端点(可选)\n * 如果不提供,将根据 environment 自动选择\n */\n wsEndpoint?: string;\n\n /**\n * 请求超时时间(毫秒)\n * @default 30000\n */\n timeout?: number;\n}\n\n/**\n * Hyperliquid API 端点配置\n */\nconst HYPERLIQUID_ENDPOINTS = {\n testnet: {\n api: \"https://api.hyperliquid-testnet.xyz\",\n ws: \"wss://api.hyperliquid-testnet.xyz/ws\",\n },\n mainnet: {\n api: \"https://api.hyperliquid.xyz\",\n ws: \"wss://api.hyperliquid.xyz/ws\",\n },\n} as const;\n\n/**\n * HyperliquidPerpetualsClient 类\n *\n * 实现 IPerpetualsClient 接口,提供 Hyperliquid 永续合约交易功能\n */\nexport class HyperliquidPerpetualsClient implements IPerpetualsClient {\n private readonly apiEndpoint: string;\n private readonly _wsEndpoint: string;\n private readonly timeout: number;\n private readonly environment: HyperliquidEnvironment;\n private wsManager: WebSocketManager | null = null;\n /**\n * Reference count of active WebSocket consumers. The connection is\n * established on the first `connectWebSocket()` call and torn down\n * only when the last consumer disconnects — see the matching comment\n * on {@link LiberFiPerpetualsClient}.\n */\n private wsRefCount: number = 0;\n\n /**\n * 构造 Hyperliquid 客户端\n *\n * @param config 客户端配置,不传则使用默认配置(testnet)\n */\n constructor(config: HyperliquidClientConfig = {}) {\n // 1. 确定环境\n this.environment = config.environment || \"testnet\";\n\n // 2. 确定 API 端点\n this.apiEndpoint =\n config.apiEndpoint || HYPERLIQUID_ENDPOINTS[this.environment].api;\n\n // 3. 确定 WebSocket 端点\n this._wsEndpoint =\n config.wsEndpoint || HYPERLIQUID_ENDPOINTS[this.environment].ws;\n\n // 4. 设置超时时间\n this.timeout = config.timeout || 30000;\n }\n\n /**\n * 内部 HTTP 请求方法\n *\n * @param endpoint API 端点路径\n * @param body 请求体\n * @returns 响应数据\n * @throws {HyperliquidApiError} API 请求失败\n */\n private async request<T = any>(endpoint: string, body: any): Promise<T> {\n const url = `${this.apiEndpoint}${endpoint}`;\n\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n throw new HyperliquidApiError(\n `HTTP ${response.status}: ${response.statusText}`,\n response.status,\n await response.text(),\n );\n }\n\n const data = await response.json();\n return data;\n } catch (error: any) {\n if (error.name === \"AbortError\") {\n throw new HyperliquidApiError(\n `Request timeout after ${this.timeout}ms`,\n 408,\n \"\",\n );\n }\n\n if (error instanceof HyperliquidApiError) {\n throw error;\n }\n\n throw new HyperliquidApiError(`Network error: ${error.message}`, 0, \"\");\n }\n }\n\n /**\n * 辅助方法:将符号格式转换为 Hyperliquid 币种名称\n * @param symbol 统一格式符号(例如 \"BTC-USDC\")\n * @returns Hyperliquid 币种名称(例如 \"BTC\")\n */\n private symbolToCoin(symbol: string): string {\n return symbol.split(\"-\")[0];\n }\n\n /**\n * 辅助方法:将 KlineInterval 转换为毫秒数\n * @param interval K线时间间隔\n * @returns 毫秒数\n */\n private parseInterval(interval: KlineInterval): number {\n const intervalMap: Record<KlineInterval, number> = {\n \"1m\": 60 * 1000,\n \"5m\": 5 * 60 * 1000,\n \"15m\": 15 * 60 * 1000,\n \"30m\": 30 * 60 * 1000,\n \"1h\": 60 * 60 * 1000,\n \"4h\": 4 * 60 * 60 * 1000,\n \"1d\": 24 * 60 * 60 * 1000,\n \"1w\": 7 * 24 * 60 * 60 * 1000,\n };\n return intervalMap[interval];\n }\n\n // ===================================\n // 市场数据查询接口(6个方法)\n // ===================================\n\n /**\n * 获取所有支持的币种列表\n * @returns 币种符号数组\n * @throws {HyperliquidApiError} API 请求失败\n */\n async getSupportedCoins(): Promise<string[]> {\n const [meta] = await this.request<[{ universe: Array<{ name: string }> }]>(\n \"/info\",\n { type: \"metaAndAssetCtxs\" },\n );\n\n // 转换:coin.name -> \"BTC-USDC\"\n return meta.universe.map((asset) => `${asset.name}-USDC`);\n }\n\n /**\n * 获取指定币种的市场数据\n * @param symbol 币种符号\n * @returns 市场数据,币种不存在时返回 null\n * @throws {HyperliquidApiError} API 请求失败\n */\n async getMarket(symbol: string): Promise<MarketData | null> {\n const markets = await this.getMarkets([symbol]);\n return markets.length > 0 ? markets[0] : null;\n }\n\n /**\n * 获取多个或所有币种的市场数据\n * @param symbols 币种符号数组(可选)\n * @returns 市场数据数组\n * @throws {HyperliquidApiError} API 请求失败\n */\n async getMarkets(symbols?: string[]): Promise<MarketData[]> {\n const [meta, assetCtxs] = await this.request<\n [\n { universe: Array<{ name: string }> },\n Array<{\n funding?: string;\n openInterest?: string;\n prevDayPx?: string;\n dayNtlVlm?: string;\n oraclePx?: string;\n markPx?: string;\n midPx?: string;\n }>,\n ]\n >(\"/info\", { type: \"metaAndAssetCtxs\" });\n\n // 合并 meta 和 assetCtxs 数据\n const allMarkets = meta.universe.map((asset, index) => {\n const ctx = assetCtxs[index];\n const symbol = `${asset.name}-USDC`;\n\n // 使用 midPx 作为当前价格,fallback 到 markPx\n const currentPrice = parseFloat(ctx.midPx || ctx.markPx || \"0\");\n const prevPrice = ctx.prevDayPx\n ? parseFloat(ctx.prevDayPx)\n : currentPrice;\n const change24h =\n prevPrice > 0 ? ((currentPrice - prevPrice) / prevPrice) * 100 : 0;\n\n return {\n symbol,\n price: currentPrice,\n change24h,\n volume24h: parseFloat(ctx.dayNtlVlm || \"0\"),\n fundingRate: parseFloat(ctx.funding || \"0\"),\n openInterest: parseFloat(ctx.openInterest || \"0\"),\n markPrice: parseFloat(ctx.markPx || \"0\"),\n indexPrice: parseFloat(ctx.oraclePx || ctx.midPx || \"0\"),\n } as MarketData;\n });\n\n // 如果指定了 symbols,进行过滤\n if (symbols && symbols.length > 0) {\n const symbolSet = new Set(symbols);\n return allMarkets.filter((m) => symbolSet.has(m.symbol));\n }\n\n return allMarkets;\n }\n\n /**\n * Fetch kline / candlestick data.\n *\n * Supports both shapes documented on\n * {@link IPerpetualsClient.getKlines}:\n *\n * - `getKlines(symbol, interval, limit)` — last `limit` candles ending now.\n * - `getKlines(symbol, interval, { from, to, limit? })` — explicit window\n * for backward history pagination (TradingView pan).\n *\n * Maps to Hyperliquid's `candleSnapshot` which natively accepts\n * `startTime` / `endTime` (ms epochs).\n *\n * @throws {HyperliquidApiError}\n */\n async getKlines(\n symbol: string,\n interval: KlineInterval,\n limitOrOptions: number | KlineQueryOptions = 100,\n ): Promise<Kline[]> {\n const coin = this.symbolToCoin(symbol);\n const options: KlineQueryOptions =\n typeof limitOrOptions === \"number\"\n ? { limit: limitOrOptions }\n : limitOrOptions;\n\n const intervalMs = this.parseInterval(interval);\n const limit = options.limit;\n\n // Resolve the [startTime, endTime] window:\n // - Range mode: caller provides from/to → use them directly.\n // - Legacy mode: derive a [now - limit*interval, now] window.\n // - Mixed: range with limit → honor the explicit window, slice to limit.\n let startTime: number;\n let endTime: number;\n if (options.from !== undefined && options.to !== undefined) {\n startTime = options.from;\n endTime = options.to;\n } else if (options.to !== undefined && limit) {\n endTime = options.to;\n startTime = endTime - intervalMs * limit;\n } else if (options.from !== undefined && limit) {\n startTime = options.from;\n endTime = startTime + intervalMs * limit;\n } else {\n endTime = Date.now();\n startTime = endTime - intervalMs * (limit ?? 100);\n }\n\n const data = await this.request<\n Array<{\n t: number;\n T: number;\n s: string;\n i: string;\n o: string;\n c: string;\n h: string;\n l: string;\n v: string;\n n: number;\n }>\n >(\"/info\", {\n type: \"candleSnapshot\",\n req: { coin, interval, startTime, endTime },\n });\n\n let bars: Kline[] = data.map((candle) => ({\n symbol,\n open: parseFloat(candle.o),\n high: parseFloat(candle.h),\n low: parseFloat(candle.l),\n close: parseFloat(candle.c),\n volume: parseFloat(candle.v),\n timestamp: candle.t,\n closeTimestamp: candle.T,\n }));\n\n // When the caller asked for a hard cap (limit), keep the most recent N.\n if (limit && bars.length > limit) {\n bars = bars.slice(bars.length - limit);\n }\n return bars;\n }\n\n /**\n * Get the order book.\n *\n * @param symbol Trading pair symbol (e.g. `BTC-USDC`)\n * @param maxLevel Max number of levels to keep per side (post-slice)\n * @param options Optional Hyperliquid `l2Book` aggregation params. When\n * provided, Hyperliquid pre-aggregates raw levels into discrete buckets\n * server-side, so a single 20-level snapshot covers a much wider price\n * range than at native tick resolution. See {@link OrderBookAggregation}.\n * @returns Order book data\n * @throws {HyperliquidApiError} API 请求失败\n */\n async getOrderBook(\n symbol: string,\n maxLevel: number = 10,\n options?: OrderBookAggregation,\n ): Promise<OrderBook> {\n const coin = this.symbolToCoin(symbol);\n\n const body: Record<string, unknown> = { type: \"l2Book\", coin };\n if (options?.nSigFigs !== undefined) {\n body.nSigFigs = options.nSigFigs;\n if (\n options.nSigFigs === 5 &&\n options.mantissa !== undefined &&\n options.mantissa !== 1\n ) {\n body.mantissa = options.mantissa;\n }\n }\n\n const data = await this.request<{\n coin: string;\n time: number;\n levels: [\n Array<{ px: string; sz: string; n: number }>,\n Array<{ px: string; sz: string; n: number }>,\n ];\n }>(\"/info\", body);\n\n const [bids, asks] = data.levels;\n\n return {\n symbol,\n bids: bids.slice(0, maxLevel).map((level) => ({\n price: parseFloat(level.px),\n quantity: parseFloat(level.sz),\n count: level.n,\n })),\n asks: asks.slice(0, maxLevel).map((level) => ({\n price: parseFloat(level.px),\n quantity: parseFloat(level.sz),\n count: level.n,\n })),\n timestamp: data.time,\n };\n }\n\n /**\n * 获取最近成交记录\n * @param symbol 交易对符号\n * @param limit 最大成交记录数\n * @returns 成交记录数组\n * @throws {HyperliquidApiError} API 请求失败\n */\n async getRecentTrades(symbol: string, limit: number = 50): Promise<Trade[]> {\n const coin = this.symbolToCoin(symbol);\n\n const data = await this.request<\n Array<{\n coin: string;\n side: string;\n px: string;\n sz: string;\n time: number;\n tid: number;\n }>\n >(\"/info\", { type: \"recentTrades\", coin });\n\n return data.slice(0, limit).map((trade) => ({\n symbol,\n side: trade.side === \"B\" ? \"buy\" : \"sell\",\n price: parseFloat(trade.px),\n quantity: parseFloat(trade.sz),\n timestamp: trade.time,\n tradeId: trade.tid,\n }));\n }\n\n // ===================================\n // 交易操作接口(2个方法)\n // ===================================\n\n /**\n * 下单(买入或卖出合约)\n *\n * ⚠️ 注意:此方法需要配置钱包私钥进行 EIP-712 签名认证\n *\n * @param params 下单参数\n * @returns 下单结果\n * @throws {HyperliquidApiError} API 请求失败、余额不足、参数错误等\n * @throws {Error} 未配置认证信息\n *\n * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint\n */\n async placeOrder(_params: PlaceOrderParams): Promise<PlaceOrderResult> {\n throw new Error(\n \"placeOrder() requires wallet private key configuration for EIP-712 signature. \" +\n \"Please configure authentication before calling this method. \" +\n \"See: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint\",\n );\n }\n\n /**\n * 取消订单\n *\n * ⚠️ 注意:此方法需要配置钱包私钥进行 EIP-712 签名认证\n *\n * @param params 取消订单参数\n * @returns 取消订单结果\n * @throws {HyperliquidApiError} API 请求失败、订单不存在等\n * @throws {Error} 未配置认证信息\n *\n * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint\n */\n async cancelOrder(_params: CancelOrderParams): Promise<CancelOrderResult> {\n throw new Error(\n \"cancelOrder() requires wallet private key configuration for EIP-712 signature. \" +\n \"Please configure authentication before calling this method. \" +\n \"See: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint\",\n );\n }\n\n // ===================================\n // 账户查询接口(3个方法)\n // ===================================\n\n /**\n * 获取用户持仓信息\n *\n * ⚠️ Hyperliquid 要求:必须提供 userAddress 参数\n *\n * @param params 查询参数\n * @returns 持仓结果\n * @throws {HyperliquidApiError} API 请求失败\n * @throws {Error} 缺少必需参数\n */\n async getPositions(\n params: GetPositionsParams = {},\n ): Promise<GetPositionsResult> {\n if (!params.userAddress) {\n throw new Error(\n \"Hyperliquid requires userAddress parameter. \" +\n \"Example: { userAddress: '0x...' }\",\n );\n }\n\n const data = await this.request<{\n assetPositions: Array<{\n position: {\n coin: string;\n szi: string;\n leverage: { type: string; value: number };\n entryPx: string;\n positionValue: string;\n unrealizedPnl: string;\n returnOnEquity: string;\n liquidationPx: string | null;\n marginUsed: string;\n };\n }>;\n marginSummary: {\n accountValue: string;\n totalMarginUsed: string;\n totalNtlPos: string;\n totalRawUsd: string;\n };\n crossMarginSummary: {\n accountValue: string;\n totalMarginUsed: string;\n totalNtlPos: string;\n totalRawUsd: string;\n };\n }>(\"/info\", { type: \"clearinghouseState\", user: params.userAddress });\n\n // 转换持仓数据\n const positions = data.assetPositions\n .map((assetPos) => {\n const pos = assetPos.position;\n const symbol = `${pos.coin}-USDC`;\n const quantity = parseFloat(pos.szi);\n\n // 数量为 0 表示没有持仓\n if (quantity === 0) {\n return null;\n }\n\n const entryPrice = parseFloat(pos.entryPx);\n const unrealizedPnl = parseFloat(pos.unrealizedPnl);\n const positionValue = parseFloat(pos.positionValue);\n\n return {\n symbol,\n side: quantity > 0 ? (\"long\" as const) : (\"short\" as const),\n quantity: Math.abs(quantity),\n entryPrice,\n markPrice: entryPrice, // Hyperliquid 不直接提供,可从 assetCtxs 获取\n unrealizedPnl,\n unrealizedPnlPercent: parseFloat(pos.returnOnEquity) * 100,\n leverage: pos.leverage.value,\n liquidationPrice: pos.liquidationPx\n ? parseFloat(pos.liquidationPx)\n : undefined,\n margin: parseFloat(pos.marginUsed),\n notionalValue: Math.abs(positionValue),\n };\n })\n .filter(Boolean) as any[];\n\n // 过滤指定币种\n const filteredPositions = params.symbol\n ? positions.filter((p) => p.symbol === params.symbol)\n : positions;\n\n return {\n positions: filteredPositions,\n totalEquity: parseFloat(data.marginSummary.accountValue),\n availableBalance:\n parseFloat(data.marginSummary.accountValue) -\n parseFloat(data.marginSummary.totalMarginUsed),\n totalUnrealizedPnl: filteredPositions.reduce(\n (sum, p) => sum + p.unrealizedPnl,\n 0,\n ),\n raw: data,\n };\n }\n\n /**\n * 获取用户挂单信息\n *\n * ⚠️ Hyperliquid 要求:必须提供 userAddress 参数\n *\n * @param params 查询参数\n * @returns 挂单结果\n * @throws {HyperliquidApiError} API 请求失败\n * @throws {Error} 缺少必需参数\n */\n async getOpenOrders(\n params: GetOpenOrdersParams = {},\n ): Promise<GetOpenOrdersResult> {\n if (!params.userAddress) {\n throw new Error(\n \"Hyperliquid requires userAddress parameter. \" +\n \"Example: { userAddress: '0x...' }\",\n );\n }\n\n const data = await this.request<\n Array<{\n coin: string;\n side: boolean;\n limitPx: string;\n sz: string;\n origSz: string;\n oid: number;\n cloid?: string;\n timestamp: number;\n orderType: any;\n }>\n >(\"/info\", { type: \"openOrders\", user: params.userAddress });\n\n // 转换订单数据\n const orders = data.map((order) => {\n const symbol = `${order.coin}-USDC`;\n const origSz = parseFloat(order.origSz);\n const remainingSz = parseFloat(order.sz);\n const filledSz = origSz - remainingSz;\n\n return {\n orderId: order.oid.toString(),\n clientOrderId: order.cloid,\n symbol,\n side: order.side ? (\"long\" as const) : (\"short\" as const),\n orderType: \"limit\" as const,\n price: parseFloat(order.limitPx),\n quantity: origSz,\n filledQuantity: filledSz,\n remainingQuantity: remainingSz,\n status: (filledSz > 0 && remainingSz > 0\n ? \"partially_filled\"\n : \"pending\") as any,\n timestamp: order.timestamp,\n updateTimestamp: order.timestamp,\n };\n });\n\n // 过滤指定币种\n const filteredOrders = params.symbol\n ? orders.filter((o) => o.symbol === params.symbol)\n : orders;\n\n return {\n orders: filteredOrders,\n totalCount: filteredOrders.length,\n raw: data,\n };\n }\n\n /**\n * 获取用户交易历史\n *\n * ⚠️ Hyperliquid 要求:必须提供 userAddress 参数\n *\n * @param params 查询参数\n * @returns 交易历史结果\n * @throws {HyperliquidApiError} API 请求失败\n * @throws {Error} 缺少必需参数\n */\n async getTrades(params: GetTradesParams = {}): Promise<GetTradesResult> {\n if (!params.userAddress) {\n throw new Error(\n \"Hyperliquid requires userAddress parameter. \" +\n \"Example: { userAddress: '0x...' }\",\n );\n }\n\n const data = await this.request<\n Array<{\n coin: string;\n side: string;\n px: string;\n sz: string;\n time: number;\n dir: string;\n oid: number;\n tid: number;\n fee?: string;\n feeToken?: string;\n }>\n >(\"/info\", { type: \"userFills\", user: params.userAddress });\n\n // 转换交易数据\n let trades = data.map((fill) => {\n const symbol = `${fill.coin}-USDC`;\n const isLong = fill.dir.includes(\"Long\");\n\n return {\n tradeId: fill.tid.toString(),\n orderId: fill.oid.toString(),\n symbol,\n side: isLong ? (\"long\" as const) : (\"short\" as const),\n price: parseFloat(fill.px),\n quantity: parseFloat(fill.sz),\n fee: parseFloat(fill.fee || \"0\"),\n feeCurrency: fill.feeToken || \"USDC\",\n isMaker: fill.side === \"M\", // \"M\" = Maker, \"T\" = Taker\n timestamp: fill.time,\n };\n });\n\n // 过滤指定币种\n if (params.symbol) {\n trades = trades.filter((t) => t.symbol === params.symbol);\n }\n\n // 过滤时间范围\n if (params.startTime) {\n trades = trades.filter((t) => t.timestamp >= params.startTime!);\n }\n if (params.endTime) {\n trades = trades.filter((t) => t.timestamp <= params.endTime!);\n }\n\n // 限制返回数量\n if (params.limit) {\n trades = trades.slice(0, params.limit);\n }\n\n return {\n trades,\n totalCount: trades.length,\n raw: data,\n };\n }\n\n // ===================================\n // WebSocket 连接管理(2个方法)\n // ===================================\n\n /**\n * Connect to WebSocket server\n *\n * Establishes WebSocket connection for real-time data streaming.\n * Connection will auto-reconnect on disconnect.\n *\n * @throws {Error} Connection failed\n */\n async connectWebSocket(): Promise<void> {\n this.wsRefCount += 1;\n if (!this.wsManager) {\n this.wsManager = new WebSocketManager(this._wsEndpoint);\n }\n\n if (this.wsManager.isConnectedNow()) {\n return;\n }\n\n await this.wsManager.connect();\n }\n\n /**\n * Disconnect from WebSocket server\n *\n * Decrements the consumer ref count. The underlying socket is closed\n * only when the last consumer disconnects, so concurrent widgets\n * (order book, trades, ticker) can mount/unmount independently\n * without stealing each other's stream.\n */\n disconnectWebSocket(): void {\n this.wsRefCount = Math.max(0, this.wsRefCount - 1);\n if (this.wsRefCount === 0 && this.wsManager) {\n this.wsManager.disconnect();\n this.wsManager = null;\n }\n }\n\n // ===================================\n // WebSocket 订阅(4个方法)\n // ===================================\n\n /**\n * Subscribe to market data (price, trades, order book)\n *\n * @param type Subscription type: 'ticker' | 'trades' | 'orderBook'\n * @param symbol Trading pair symbol (e.g., \"BTC-USDC\")\n * @param callback Data callback function\n * @param options Optional subscription options. For `orderBook`, provide\n * `aggregation` (Hyperliquid `nSigFigs` / `mantissa`) so the server\n * pre-aggregates levels into discrete price buckets — required to render\n * wide-range books at coarse aggregation steps (e.g. $1000 buckets).\n * @returns Subscription ID (for unsubscribing)\n */\n subscribeMarketData(\n type: \"ticker\" | \"trades\" | \"orderBook\",\n symbol: string,\n callback: (data: any) => void,\n options?: { aggregation?: OrderBookAggregation },\n ): string {\n if (!this.wsManager) {\n throw new Error(\n \"WebSocket not connected. Call connectWebSocket() first.\",\n );\n }\n\n return this.wsManager.subscribe(\n type,\n symbol,\n callback,\n options?.aggregation,\n );\n }\n\n /**\n * Subscribe to kline (candlestick) data\n *\n * @param symbol Trading pair symbol (e.g., \"BTC-USDC\")\n * @param interval Time interval (e.g., \"1m\", \"1h\", \"1d\")\n * @param callback Data callback function\n * @returns Subscription ID (for unsubscribing)\n */\n subscribeCandles(\n symbol: string,\n interval: KlineInterval,\n callback: (candle: Kline) => void,\n ): string {\n if (!this.wsManager) {\n throw new Error(\n \"WebSocket not connected. Call connectWebSocket() first.\",\n );\n }\n\n // Combine symbol and interval as parameter\n const param = `${symbol}:${interval}`;\n return this.wsManager.subscribe(\"candle\", param, callback);\n }\n\n /**\n * Subscribe to user data (orders, positions, fills)\n *\n * @param type Subscription type: 'orders' | 'positions' | 'fills'\n * @param userAddress User wallet address\n * @param callback Data callback function\n * @returns Subscription ID (for unsubscribing)\n */\n subscribeUserData(\n type: \"orders\" | \"positions\" | \"fills\",\n userAddress: string,\n callback: (data: any) => void,\n ): string {\n if (!this.wsManager) {\n throw new Error(\n \"WebSocket not connected. Call connectWebSocket() first.\",\n );\n }\n\n // Use userEvents for orders and positions, userFills for fills\n const subscriptionType = type === \"fills\" ? \"userFills\" : \"userEvents\";\n\n return this.wsManager.subscribe(subscriptionType, userAddress, callback);\n }\n\n /**\n * Unsubscribe from a data stream\n *\n * @param subscriptionId Subscription ID returned from subscribe methods\n */\n unsubscribe(subscriptionId: string): void {\n if (this.wsManager) {\n this.wsManager.unsubscribe(subscriptionId);\n }\n }\n}\n\n/**\n * Hyperliquid API 错误类\n */\nexport class HyperliquidApiError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number,\n public readonly responseBody: string,\n ) {\n super(message);\n this.name = \"HyperliquidApiError\";\n }\n}\n","/**\n * Shared REST transport for every LiberFi perpetuals-server client.\n *\n * Pulled out of `LiberFiPerpetualsClient` so the deposit client (and any\n * future feature client) can reuse the same fetch-with-timeout, error\n * mapping, and header merging logic without copy-paste.\n *\n * Design choices:\n *\n * - The class is intentionally minimal: build URL → fire fetch →\n * decode JSON → throw a typed error on non-2xx. No retries, no\n * circuit breaker, no caching. That layering belongs to the caller\n * (e.g. TanStack Query handles retries/cache).\n *\n * - Custom query parameters are passed per-request, not per-instance,\n * except for `defaultQuery` which the perpetuals client uses for the\n * `?provider=` selector.\n *\n * - Headers merge in three layers (call > instance > built-in). This\n * lets a caller add a one-off `Authorization` for a single request\n * without leaking it into the rest of the session.\n */\n\n/**\n * Thrown when perpetuals-server returns a non-2xx HTTP status, when the\n * request times out, or when the network call fails outright.\n *\n * `statusCode` is the HTTP status (or `0` for network errors / `408`\n * for client-side timeouts). `responseBody` is the verbatim response\n * text — useful for surfacing backend error codes to the user.\n */\nexport class LiberFiApiError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number,\n public readonly responseBody: string,\n ) {\n super(message);\n this.name = \"LiberFiApiError\";\n }\n}\n\n/** Configuration for {@link LiberFiHttpTransport}. */\nexport interface LiberFiHttpTransportConfig {\n /**\n * REST base URL, with NO trailing slash. The transport strips trailing\n * slashes on construction so callers can pass either form.\n */\n baseUrl: string;\n\n /** Per-request timeout in milliseconds. Defaults to 30 000 ms. */\n timeout?: number;\n\n /**\n * Headers merged into every request. Per-request headers (passed to\n * `request()`) win on key collision, then instance headers, then the\n * built-in `Accept` / `Content-Type`.\n */\n headers?: Record<string, string>;\n\n /**\n * Default query parameters appended to every request URL. Useful for\n * cross-cutting selectors like `?provider=hyperliquid`. Per-request\n * params override on key collision.\n */\n defaultQuery?: Record<string, string | undefined>;\n\n /**\n * Custom `fetch` implementation. Defaults to the global `fetch`.\n * Useful in tests (drop in a jest mock) or in environments where a\n * pre-configured fetch (e.g. with circuit breaker / proxy) is supplied\n * by the host application.\n */\n fetchImpl?: typeof fetch;\n}\n\n/** HTTP method shape — keep narrow; deposit and trading both use these. */\nexport type LiberFiHttpMethod = \"GET\" | \"POST\";\n\n/** Per-request options accepted by {@link LiberFiHttpTransport.request}. */\nexport interface RequestOptions {\n /** Path relative to `baseUrl` (must start with `/`). */\n path: string;\n /** Optional query string parameters. Undefined / empty values are skipped. */\n query?: Record<string, string | undefined>;\n /** JSON body for POST/PUT/etc. */\n body?: unknown;\n /** One-off headers — overrides the instance defaults. */\n headers?: Record<string, string>;\n /**\n * Override the per-instance timeout for this single request.\n * Use for fast-path reads or long-running submits.\n */\n timeoutMs?: number;\n}\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\n/**\n * Stateless HTTP transport shared by every LiberFi perpetuals-server\n * client. Construct one per client (or one shared instance — the class\n * is safe for concurrent use).\n */\nexport class LiberFiHttpTransport {\n private readonly baseUrl: string;\n private readonly timeout: number;\n private readonly headers?: Record<string, string>;\n private readonly defaultQuery?: Record<string, string | undefined>;\n private readonly fetchImpl: typeof fetch;\n\n constructor(config: LiberFiHttpTransportConfig) {\n if (!config.baseUrl) {\n throw new Error(\n \"LiberFiHttpTransport: `baseUrl` is required (e.g. https://api.liberfi.io/perpetuals).\",\n );\n }\n this.baseUrl = config.baseUrl.replace(/\\/+$/, \"\");\n this.timeout = config.timeout ?? DEFAULT_TIMEOUT_MS;\n this.headers = config.headers;\n this.defaultQuery = config.defaultQuery;\n // Bind so `fetch` can be `globalThis.fetch` (which requires `this`\n // to be the realm's globalThis, not the transport instance).\n this.fetchImpl = config.fetchImpl ?? globalThis.fetch.bind(globalThis);\n }\n\n /** Read-only accessor used by the perpetuals client for WebSocket fallback. */\n getBaseUrl(): string {\n return this.baseUrl;\n }\n\n /** Build a fully-qualified URL with merged query string. */\n buildUrl(path: string, query?: Record<string, string | undefined>): string {\n const params = new URLSearchParams();\n if (this.defaultQuery) {\n for (const [key, value] of Object.entries(this.defaultQuery)) {\n if (value === undefined || value === \"\") continue;\n params.set(key, value);\n }\n }\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === \"\") continue;\n params.set(key, value);\n }\n }\n const qs = params.toString();\n return `${this.baseUrl}${path}${qs ? `?${qs}` : \"\"}`;\n }\n\n /**\n * Issue an HTTP request and decode the JSON response. Returns\n * `undefined` (cast to T) for `204 No Content`. Throws\n * {@link LiberFiApiError} on every non-2xx, timeout, or network error.\n */\n async request<T>(\n method: LiberFiHttpMethod,\n opts: RequestOptions,\n ): Promise<T> {\n const url = this.buildUrl(opts.path, opts.query);\n const controller = new AbortController();\n const timeoutMs = opts.timeoutMs ?? this.timeout;\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n const response = await this.fetchImpl(url, {\n method,\n headers: {\n Accept: \"application/json\",\n ...(method === \"POST\" ? { \"Content-Type\": \"application/json\" } : {}),\n ...this.headers,\n ...opts.headers,\n },\n body: method === \"POST\" ? JSON.stringify(opts.body ?? {}) : undefined,\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const text = await safeText(response);\n throw new LiberFiApiError(\n `HTTP ${response.status} ${response.statusText} from ${method} ${url}`,\n response.status,\n text,\n );\n }\n\n if (response.status === 204) return undefined as T;\n return (await response.json()) as T;\n } catch (err: unknown) {\n if (err instanceof LiberFiApiError) throw err;\n if (err instanceof Error && err.name === \"AbortError\") {\n throw new LiberFiApiError(\n `Request timeout after ${timeoutMs}ms: ${method} ${url}`,\n 408,\n \"\",\n );\n }\n const message = err instanceof Error ? err.message : String(err);\n throw new LiberFiApiError(\n `Network error: ${method} ${url}: ${message}`,\n 0,\n \"\",\n );\n } finally {\n clearTimeout(timeoutId);\n }\n }\n}\n\nasync function safeText(response: Response): Promise<string> {\n try {\n return await response.text();\n } catch {\n return \"\";\n }\n}\n","import type {\n IPerpetualsClient,\n MarketData,\n Kline,\n KlineInterval,\n KlineQueryOptions,\n OrderBook,\n Trade,\n PlaceOrderParams,\n PlaceOrderResult,\n CancelOrderParams,\n CancelOrderResult,\n GetPositionsParams,\n GetPositionsResult,\n GetOpenOrdersParams,\n GetOpenOrdersResult,\n GetTradesParams,\n GetTradesResult,\n Position,\n Order,\n TradeHistory,\n} from \"../../types\";\nimport { WebSocketManager } from \"../hyperliquid/WebSocketManager\";\nimport { LiberFiHttpTransport, LiberFiApiError } from \"./transport\";\n\n// Re-export the error so existing consumers continue to import it from\n// the perpetuals-client module.\nexport { LiberFiApiError };\n\n// ===== Public configuration ===================================================\n\n/**\n * `signTypedData` is invoked once per place / cancel during the\n * `prepare → submit` flow. The hosting app injects this so the user's wallet\n * (privy / wagmi / etc.) controls the keys — perpetuals-server never sees them.\n *\n * The `typedData` argument is the EIP-712 envelope returned verbatim by the\n * server. The function must return the resulting compact signature as a\n * `0x`-prefixed hex string.\n */\nexport type SignTypedDataFn = (\n typedData: Record<string, unknown>,\n) => Promise<`0x${string}`>;\n\n/** Configuration for {@link LiberFiPerpetualsClient}. */\nexport interface LiberFiPerpetualsClientConfig {\n /**\n * REST base URL, with NO trailing slash. Examples:\n * - Local dev: `http://localhost:8080`\n * - Staging: `https://api.liberfi.io/staging/perpetuals`\n * - Production: `https://api.liberfi.io/perpetuals`\n *\n * The client appends `/v1/...` paths to this value. Required UNLESS a\n * pre-built {@link LiberFiHttpTransport} is supplied via `transport`,\n * in which case the transport's baseUrl is used.\n */\n baseUrl?: string;\n\n /**\n * Optional WebSocket endpoint. Real-time data is NOT proxied by\n * perpetuals-server today — the WS subscription methods connect directly to\n * the upstream exchange. Defaults to Hyperliquid mainnet.\n */\n wsEndpoint?: string;\n\n /**\n * EIP-712 signer injected by the hosting app. REQUIRED for `placeOrder` /\n * `cancelOrder`; read-only methods work without it.\n */\n signTypedData?: SignTypedDataFn;\n\n /**\n * Per-request timeout in milliseconds. Defaults to 30 000 ms.\n * Ignored when `transport` is provided (the transport carries its own).\n */\n timeout?: number;\n\n /**\n * Optional provider override sent as `?provider=...`. Defaults to the server\n * configuration (currently `hyperliquid`). Only set this when the gateway\n * has multiple providers configured and you want a non-default one.\n */\n provider?: string;\n\n /**\n * Optional extra request headers (auth tokens, tracing, etc.) merged into\n * every fetch. Ignored when `transport` is provided.\n */\n headers?: Record<string, string>;\n\n /**\n * Inject a pre-built transport instead of letting the client construct\n * one from `baseUrl` / `timeout` / `headers`. Required when sharing a\n * single transport with the deposit client to halve the per-call\n * configuration footprint in `PerpetualsProvider`.\n */\n transport?: LiberFiHttpTransport;\n}\n\nconst DEFAULT_WS_ENDPOINT = \"wss://api.hyperliquid.xyz/ws\";\n\n// ===== Server-side wire types (mirror perpetuals-server/internal/domain) =======\n//\n// These intentionally use snake-free camelCase exactly matching the Go\n// `json:\"…\"` tags. They are kept private so consumers depend only on the\n// stable IPerpetualsClient surface above.\n\ninterface CoinDTO {\n symbol: string;\n name: string;\n tickSize?: number;\n stepSize?: number;\n minOrderSize?: number;\n maxLeverage?: number;\n}\n\ntype MarketDTO = MarketData;\ntype OrderBookDTO = OrderBook;\ntype TradeDTO = Trade;\ntype KlineDTO = Kline;\n\ninterface AccountDTO {\n totalEquity: number;\n availableBalance: number;\n totalUnrealizedPnl: number;\n usedMargin?: number;\n accountLeverage?: number;\n}\n\ninterface PositionsResultDTO {\n positions: Position[];\n account?: AccountDTO;\n}\n\ntype OrderDTO = Order;\n\ninterface UserFillDTO {\n tradeId: string;\n orderId: string;\n symbol: string;\n side: \"long\" | \"short\";\n price: number;\n quantity: number;\n fee: number;\n feeCurrency: string;\n isMaker: boolean;\n timestamp: number;\n}\n\ninterface PreparedActionDTO {\n typedData: Record<string, unknown>;\n action: Record<string, unknown>;\n nonce: number;\n vaultAddress?: string;\n}\n\ntype PlaceOrderResultDTO = PlaceOrderResult;\ntype CancelOrderResultDTO = CancelOrderResult;\n\n// ===== Implementation ============================================================\n\n/**\n * REST + injected-signer implementation of {@link IPerpetualsClient} that talks\n * to a deployed `perpetuals-server` instead of Hyperliquid directly.\n *\n * - Read-only methods are plain `fetch GET`s.\n * - `placeOrder` / `cancelOrder` follow the two-phase flow:\n * 1. POST `…/prepare` → server builds upstream action + EIP-712 typed data.\n * 2. Host wallet signs `typedData` via the injected `signTypedData`.\n * 3. POST `…/submit` with the original `action`, the user signature, and\n * the server-issued `nonce`. The server forwards to upstream and\n * normalises the response.\n * - WebSocket subscriptions are NOT proxied through perpetuals-server today.\n * They reuse the existing {@link WebSocketManager} pointed at the upstream\n * exchange (`wsEndpoint`, default Hyperliquid mainnet).\n */\nexport class LiberFiPerpetualsClient implements IPerpetualsClient {\n private readonly transport: LiberFiHttpTransport;\n private readonly wsEndpoint: string;\n private readonly signTypedData?: SignTypedDataFn;\n private wsManager: WebSocketManager | null = null;\n /**\n * Reference count of active WebSocket consumers (one per React hook\n * instance). The underlying connection is opened lazily on the first\n * connect() call and torn down only when the last consumer leaves —\n * this prevents one widget's unmount from killing the live stream\n * other widgets (order book, trades, ticker) still depend on.\n */\n private wsRefCount = 0;\n\n constructor(config: LiberFiPerpetualsClientConfig) {\n // Two construction modes: legacy (baseUrl / timeout / headers) or\n // transport-injected. The deposit client constructor mirrors the\n // same pattern so both share a consistent shape.\n if (config.transport) {\n this.transport = config.transport;\n } else {\n if (!config.baseUrl) {\n throw new Error(\n \"LiberFiPerpetualsClient: either `baseUrl` or a pre-built `transport` is required.\",\n );\n }\n this.transport = new LiberFiHttpTransport({\n baseUrl: config.baseUrl,\n timeout: config.timeout,\n headers: config.headers,\n defaultQuery: config.provider\n ? { provider: config.provider }\n : undefined,\n });\n }\n this.wsEndpoint = config.wsEndpoint ?? DEFAULT_WS_ENDPOINT;\n this.signTypedData = config.signTypedData;\n }\n\n // ── IPerpetualsClient: market data ────────────────────────────────────────\n\n async getSupportedCoins(): Promise<string[]> {\n const coins = await this.transport.request<CoinDTO[]>(\"GET\", {\n path: \"/v1/coins\",\n });\n return coins.map((coin) => coin.symbol);\n }\n\n async getMarket(symbol: string): Promise<MarketData | null> {\n try {\n return await this.transport.request<MarketDTO>(\"GET\", {\n path: `/v1/markets/${encodeURIComponent(symbol)}`,\n });\n } catch (err) {\n if (err instanceof LiberFiApiError && err.statusCode === 404) return null;\n throw err;\n }\n }\n\n async getMarkets(symbols?: string[]): Promise<MarketData[]> {\n return this.transport.request<MarketDTO[]>(\"GET\", {\n path: \"/v1/markets\",\n query:\n symbols && symbols.length > 0\n ? { symbols: symbols.join(\",\") }\n : undefined,\n });\n }\n\n async getKlines(\n symbol: string,\n interval: KlineInterval,\n limitOrOptions: number | KlineQueryOptions = 100,\n ): Promise<Kline[]> {\n const options: KlineQueryOptions =\n typeof limitOrOptions === \"number\"\n ? { limit: limitOrOptions }\n : limitOrOptions;\n\n const query: Record<string, string> = { interval };\n if (options.limit !== undefined) {\n query.limit = String(options.limit);\n }\n // Forward time-range parameters as `start` / `end` (ms epochs) — matches\n // the openapi-server `KlineParams` contract. Required for TradingView\n // backward history pagination.\n if (options.from !== undefined) {\n query.start = String(options.from);\n }\n if (options.to !== undefined) {\n query.end = String(options.to);\n }\n\n return this.transport.request<KlineDTO[]>(\"GET\", {\n path: `/v1/markets/${encodeURIComponent(symbol)}/klines`,\n query,\n });\n }\n\n async getOrderBook(\n symbol: string,\n maxLevel: number = 10,\n options?: { nSigFigs?: number; mantissa?: number },\n ): Promise<OrderBook> {\n const query: Record<string, string> = { maxLevel: String(maxLevel) };\n if (options?.nSigFigs !== undefined) {\n query.nSigFigs = String(options.nSigFigs);\n if (\n options.nSigFigs === 5 &&\n options.mantissa &&\n options.mantissa !== 1\n ) {\n query.mantissa = String(options.mantissa);\n }\n }\n return this.transport.request<OrderBookDTO>(\"GET\", {\n path: `/v1/markets/${encodeURIComponent(symbol)}/orderbook`,\n query,\n });\n }\n\n async getRecentTrades(symbol: string, limit: number = 50): Promise<Trade[]> {\n return this.transport.request<TradeDTO[]>(\"GET\", {\n path: `/v1/markets/${encodeURIComponent(symbol)}/trades`,\n query: { limit: String(limit) },\n });\n }\n\n // ── IPerpetualsClient: account ────────────────────────────────────────────\n\n async getPositions(\n params: GetPositionsParams = {},\n ): Promise<GetPositionsResult> {\n if (!params.userAddress) {\n throw new Error(\n \"LiberFiPerpetualsClient.getPositions requires `userAddress`.\",\n );\n }\n const result = await this.transport.request<PositionsResultDTO>(\"GET\", {\n path: `/v1/users/${encodeURIComponent(params.userAddress)}/positions`,\n query: { symbol: params.symbol },\n });\n\n return {\n positions: result.positions,\n totalEquity: result.account?.totalEquity,\n availableBalance: result.account?.availableBalance,\n totalUnrealizedPnl: result.account?.totalUnrealizedPnl,\n raw: result,\n };\n }\n\n async getOpenOrders(\n params: GetOpenOrdersParams = {},\n ): Promise<GetOpenOrdersResult> {\n if (!params.userAddress) {\n throw new Error(\n \"LiberFiPerpetualsClient.getOpenOrders requires `userAddress`.\",\n );\n }\n const orders = await this.transport.request<OrderDTO[]>(\"GET\", {\n path: `/v1/users/${encodeURIComponent(params.userAddress)}/orders`,\n query: { symbol: params.symbol },\n });\n return { orders, totalCount: orders.length, raw: orders };\n }\n\n async getTrades(params: GetTradesParams = {}): Promise<GetTradesResult> {\n if (!params.userAddress) {\n throw new Error(\n \"LiberFiPerpetualsClient.getTrades requires `userAddress`.\",\n );\n }\n const fills = await this.transport.request<UserFillDTO[]>(\"GET\", {\n path: `/v1/users/${encodeURIComponent(params.userAddress)}/fills`,\n query: {\n symbol: params.symbol,\n limit: params.limit !== undefined ? String(params.limit) : undefined,\n startTime:\n params.startTime !== undefined ? String(params.startTime) : undefined,\n endTime:\n params.endTime !== undefined ? String(params.endTime) : undefined,\n },\n });\n const trades: TradeHistory[] = fills.map((fill) => ({\n tradeId: fill.tradeId,\n orderId: fill.orderId,\n symbol: fill.symbol,\n side: fill.side,\n price: fill.price,\n quantity: fill.quantity,\n fee: fill.fee,\n feeCurrency: fill.feeCurrency,\n isMaker: fill.isMaker,\n timestamp: fill.timestamp,\n }));\n return { trades, totalCount: trades.length, raw: fills };\n }\n\n // ── IPerpetualsClient: trading (two-phase signing) ────────────────────────\n\n async placeOrder(params: PlaceOrderParams): Promise<PlaceOrderResult> {\n if (!this.signTypedData) {\n throw new Error(\n \"LiberFiPerpetualsClient.placeOrder requires `signTypedData` to be configured.\",\n );\n }\n if (!params.userAddress) {\n throw new Error(\n \"LiberFiPerpetualsClient.placeOrder requires `userAddress` (the signing wallet).\",\n );\n }\n\n const prepared = await this.transport.request<PreparedActionDTO>(\"POST\", {\n path: \"/v1/orders/prepare\",\n body: {\n userAddress: params.userAddress,\n symbol: params.symbol,\n side: params.side,\n orderType: params.orderType,\n amount: params.amount,\n price: params.price,\n leverage: params.leverage,\n reduceOnly: params.reduceOnly,\n takeProfitPrice: params.takeProfitPrice,\n stopLossPrice: params.stopLossPrice,\n clientOrderId: params.clientOrderId,\n },\n });\n\n const signature = await this.signTypedData(prepared.typedData);\n\n return this.transport.request<PlaceOrderResultDTO>(\"POST\", {\n path: \"/v1/orders/submit\",\n body: {\n action: prepared.action,\n signature,\n nonce: prepared.nonce,\n vaultAddress: prepared.vaultAddress,\n },\n });\n }\n\n async cancelOrder(params: CancelOrderParams): Promise<CancelOrderResult> {\n if (!this.signTypedData) {\n throw new Error(\n \"LiberFiPerpetualsClient.cancelOrder requires `signTypedData` to be configured.\",\n );\n }\n if (!params.userAddress) {\n throw new Error(\n \"LiberFiPerpetualsClient.cancelOrder requires `userAddress` (the signing wallet).\",\n );\n }\n\n const prepared = await this.transport.request<PreparedActionDTO>(\"POST\", {\n path: \"/v1/orders/cancel/prepare\",\n body: {\n userAddress: params.userAddress,\n symbol: params.symbol,\n orderId: params.orderId,\n clientOrderId: params.clientOrderId,\n },\n });\n\n const signature = await this.signTypedData(prepared.typedData);\n\n return this.transport.request<CancelOrderResultDTO>(\"POST\", {\n path: \"/v1/orders/cancel/submit\",\n body: {\n action: prepared.action,\n signature,\n nonce: prepared.nonce,\n vaultAddress: prepared.vaultAddress,\n },\n });\n }\n\n // ── IPerpetualsClient: WebSocket (direct upstream, NOT proxied) ───────────\n\n async connectWebSocket(): Promise<void> {\n this.wsRefCount += 1;\n if (!this.wsManager) {\n this.wsManager = new WebSocketManager(this.wsEndpoint);\n }\n if (this.wsManager.isConnectedNow()) return;\n await this.wsManager.connect();\n }\n\n disconnectWebSocket(): void {\n this.wsRefCount = Math.max(0, this.wsRefCount - 1);\n if (this.wsRefCount === 0 && this.wsManager) {\n this.wsManager.disconnect();\n this.wsManager = null;\n }\n }\n\n subscribeMarketData(\n type: \"ticker\" | \"trades\" | \"orderBook\",\n symbol: string,\n callback: (data: unknown) => void,\n options?: {\n aggregation?: { nSigFigs?: 2 | 3 | 4 | 5; mantissa?: 1 | 2 | 5 };\n },\n ): string {\n // The shared {@link WebSocketManager} speaks Hyperliquid's protocol, so\n // when the aggregation hint is provided we forward it as nSigFigs/mantissa\n // regardless of which client we're behind.\n return this.requireWS().subscribe(\n type,\n symbol,\n callback,\n options?.aggregation,\n );\n }\n\n subscribeCandles(\n symbol: string,\n interval: KlineInterval,\n callback: (candle: Kline) => void,\n ): string {\n return this.requireWS().subscribe(\n \"candle\",\n `${symbol}:${interval}`,\n callback,\n );\n }\n\n subscribeUserData(\n type: \"orders\" | \"positions\" | \"fills\",\n userAddress: string,\n callback: (data: unknown) => void,\n ): string {\n const channel = type === \"fills\" ? \"userFills\" : \"userEvents\";\n return this.requireWS().subscribe(channel, userAddress, callback);\n }\n\n unsubscribe(subscriptionId: string): void {\n if (this.wsManager) {\n this.wsManager.unsubscribe(subscriptionId);\n }\n }\n\n private requireWS(): WebSocketManager {\n if (!this.wsManager) {\n throw new Error(\n \"WebSocket not connected. Call connectWebSocket() first.\",\n );\n }\n return this.wsManager;\n }\n}\n","/**\n * REST client for the Solana → Hyperliquid deposit endpoints exposed by\n * the perpetuals-server (`/v1/deposits/*`).\n *\n * Engineering principles:\n * - Single responsibility: this file knows about /v1/deposits and\n * nothing else. Quote orchestration, fee adapters, status\n * reconciliation, etc. live server-side.\n * - Modularity: the HTTP transport is injected (or built from a\n * baseUrl) so integration tests can drop in a fetch mock; production\n * code shares the same transport instance with `LiberFiPerpetualsClient`.\n * - First principles: three methods (quote / submit / status), no\n * hidden state, no caching. Polling is the caller's concern (the\n * hooks do it via TanStack Query).\n */\nimport type {\n DepositQuoteRequest,\n DepositQuoteResponse,\n DepositStatusResponse,\n DepositSubmitRequest,\n DepositSubmitResponse,\n} from \"./deposit-types\";\nimport {\n LiberFiHttpTransport,\n type LiberFiHttpTransportConfig,\n} from \"./transport\";\n\n/**\n * Options for constructing a `LiberFiPerpDepositClient`.\n *\n * Either provide a pre-built `transport` (preferred — share one with\n * `LiberFiPerpetualsClient` so connection limits, headers and timeouts\n * stay consistent) or pass the raw config and let the client build one.\n */\nexport type LiberFiPerpDepositClientConfig =\n | { transport: LiberFiHttpTransport }\n | LiberFiHttpTransportConfig;\n\n/** Public surface of the deposit client; matches the three handler endpoints. */\nexport interface IPerpDepositClient {\n /** POST /v1/deposits/quote */\n quote(req: DepositQuoteRequest): Promise<DepositQuoteResponse>;\n /** POST /v1/deposits/submit */\n submit(req: DepositSubmitRequest): Promise<DepositSubmitResponse>;\n /** GET /v1/deposits/{id} */\n status(intentId: string): Promise<DepositStatusResponse>;\n /** POST /v1/deposits/{id}/refresh — bypasses any future cache TTL. */\n refresh(intentId: string): Promise<DepositStatusResponse>;\n}\n\n/** Concrete implementation backed by `LiberFiHttpTransport`. */\nexport class LiberFiPerpDepositClient implements IPerpDepositClient {\n private readonly transport: LiberFiHttpTransport;\n\n constructor(config: LiberFiPerpDepositClientConfig) {\n this.transport =\n \"transport\" in config\n ? config.transport\n : new LiberFiHttpTransport(config);\n }\n\n /** Returns the base URL of the underlying transport (mostly for logs/diagnostics). */\n getBaseUrl(): string {\n return this.transport.getBaseUrl();\n }\n\n async quote(req: DepositQuoteRequest): Promise<DepositQuoteResponse> {\n return this.transport.request<DepositQuoteResponse>(\"POST\", {\n path: \"/v1/deposits/quote\",\n body: req,\n });\n }\n\n async submit(req: DepositSubmitRequest): Promise<DepositSubmitResponse> {\n return this.transport.request<DepositSubmitResponse>(\"POST\", {\n path: \"/v1/deposits/submit\",\n body: req,\n });\n }\n\n async status(intentId: string): Promise<DepositStatusResponse> {\n if (!intentId) throw new Error(\"intentId is required\");\n return this.transport.request<DepositStatusResponse>(\"GET\", {\n path: `/v1/deposits/${encodeURIComponent(intentId)}`,\n });\n }\n\n async refresh(intentId: string): Promise<DepositStatusResponse> {\n if (!intentId) throw new Error(\"intentId is required\");\n return this.transport.request<DepositStatusResponse>(\"POST\", {\n path: `/v1/deposits/${encodeURIComponent(intentId)}/refresh`,\n });\n }\n}\n","/**\n * Wire / domain types for the Solana → Hyperliquid USDC deposit flow.\n *\n * These deliberately mirror the perpetuals-server DTOs (see\n * `internal/handler/deposit_handler.go`) so the SDK <-> backend contract\n * stays in sync. When the backend adds a new field, add it here too —\n * the compiler will then point at every place that needs to handle it.\n *\n * All amounts denominated in *smallest unit* (lamports for SOL, USDC's\n * 6-decimal microUSDC for the destination side) are typed as `string` so\n * we never accidentally lose precision on large values.\n */\n\n/** Where the deposit was initiated from. Drives fee attribution server-side. */\nexport type DepositSource = \"dex\" | \"prediction\" | \"launchpad\" | \"channel\";\n\n/** Lifecycle states a deposit can be in. */\nexport type DepositStatus =\n | \"broadcasted\" // user signed + broadcast on Solana, server has not seen Relay yet\n | \"relay_waiting\" // Relay observed the deposit but hasn't started forwarding\n | \"relay_pending\" // Relay is forwarding the deposit cross-chain\n | \"settled\" // funds delivered to Hyperliquid\n | \"refunded\" // Relay refunded — funds returned to user wallet\n | \"failed\" // terminal failure\n | \"stuck\"; // observed > stuckAfter without Relay seeing it; ops review\n\n/** True for status values that never transition further. */\nexport const TERMINAL_DEPOSIT_STATUSES: ReadonlySet<DepositStatus> =\n new Set<DepositStatus>([\"settled\", \"refunded\", \"failed\"]);\n\n/** A single state transition in the status history. */\nexport interface DepositStatusTransition {\n from: DepositStatus | \"\";\n to: DepositStatus;\n at: string; // ISO 8601 timestamp\n source: \"handler\" | \"status_pull\" | \"reconciliation\" | string;\n reason?: string;\n}\n\n/** Surfaced when the upstream produced an unrecoverable error. */\nexport interface DepositErrorInfo {\n code: string;\n message: string;\n recoverable: boolean;\n}\n\n/** Exact-decimal breakdown returned by the quote endpoint. */\nexport interface DepositBreakdown {\n /** Total lamports the user is paying in (gross). */\n grossLamports: string;\n /** Platform fee transferred to the LiberFi treasury (lamports). */\n platformFeeLamports: string;\n /** Net amount Relay bridges (= gross − platformFee), in lamports. */\n relayDepositLamports: string;\n /** SOL pubkey the platform fee is sent to. May be empty when fee = 0. */\n treasuryAddress: string;\n /** Expected destination output, in microUSDC (6-decimal). May be empty. */\n expectedOutputUSDC?: string;\n /** Origin chain id (Solana mainnet on Relay = 792703809). */\n originChainId: number;\n /** Destination chain id (Hyperliquid). */\n destinationChainId: number;\n /** Origin currency. SOL is encoded as the SystemProgram pseudo-pubkey. */\n originCurrency: string;\n /** Destination currency contract. */\n destinationCurrency: string;\n /** Relay-issued depository address — the program/wallet receiving SOL. */\n depository?: string;\n /** Relay request id; populated once Relay returns a quote. */\n relayRequestId?: string;\n}\n\n/** Body of POST /v1/deposits/quote. */\nexport interface DepositQuoteRequest {\n userSolanaAddress: string;\n hyperliquidRecipient: string;\n /** Smallest-unit amount the user is paying in. */\n grossLamports: string;\n /** Fee attribution source. Defaults to `dex` server-side when empty. */\n source: DepositSource;\n}\n\n/** Response of POST /v1/deposits/quote. */\nexport interface DepositQuoteResponse {\n /** Base64 SOL transaction the user signs in their wallet. */\n serializedTxBase64: string;\n /** Transaction size on the wire (used by client-side guards). */\n sizeBytes: number;\n /** True for v0 transactions (legacy = false). */\n isVersioned: boolean;\n breakdown: DepositBreakdown;\n /** ISO 8601 timestamp the quote was issued at. */\n issuedAt: string;\n /** ISO 8601 timestamp the quote expires at. */\n expiresAt: string;\n}\n\n/** Body of POST /v1/deposits/submit. */\nexport interface DepositSubmitRequest {\n userSolanaAddress: string;\n hyperliquidRecipient: string;\n /** The signed transaction's hash, returned by the wallet on broadcast. */\n solanaTxHash: string;\n breakdown: DepositBreakdown;\n /** Stable user identifier (LiberFi user id, NOT the wallet address). */\n userId: string;\n source: DepositSource;\n /** Optional marketing campaign / referral code passed through to attribution. */\n campaign?: string;\n /** Mirror back the issuedAt from /quote so the server can guard freshness. */\n quoteIssuedAt: string;\n}\n\n/** Response of POST /v1/deposits/submit. */\nexport interface DepositSubmitResponse {\n intentId: string;\n /** True the first time a unique solanaTxHash is seen; idempotent retries return false. */\n created: boolean;\n}\n\n/** Response of GET /v1/deposits/{id}. */\nexport interface DepositStatusResponse {\n intentId: string;\n status: DepositStatus;\n userSolanaAddress: string;\n hyperliquidRecipient: string;\n solanaTxHash: string;\n relayRequestId?: string;\n hyperliquidTxHash?: string;\n breakdown: DepositBreakdown;\n statusHistory: DepositStatusTransition[];\n lastError?: DepositErrorInfo;\n userId: string;\n source: DepositSource;\n campaign?: string;\n createdAt: string;\n updatedAt: string;\n}\n","/**\n * Pure state machine for the deposit UI.\n *\n * The backend owns the *authoritative* lifecycle (broadcasted → relay_*\n * → settled / refunded / failed / stuck). The frontend has a few extra\n * states *before* we can call /submit (idle, quoting, ready_to_sign,\n * signing, broadcasting). We model both halves here as a single FSM so\n * presentational components can switch on a single tag.\n *\n * Engineering principles applied:\n * - First principles: a state is a *type*, transitions are pure\n * functions over (state, event) → state. No timers, no fetch, no\n * setState — those live in hooks.\n * - Single responsibility: this file knows nothing about HTTP, React,\n * or wallets. It is unit-testable in isolation.\n * - Extensibility: add a new event by extending DepositEvent + a case\n * in `reduceDepositState`. The compiler enforces exhaustiveness.\n */\nimport {\n type DepositBreakdown,\n type DepositErrorInfo,\n type DepositQuoteResponse,\n type DepositStatus,\n type DepositStatusResponse,\n TERMINAL_DEPOSIT_STATUSES,\n} from \"./deposit-types\";\n\n/** UI-only state tags. Server-driven tags are a subset of DepositStatus. */\nexport type DepositPhase =\n | \"idle\" // user hasn't requested a quote yet\n | \"quoting\" // /quote in flight\n | \"ready_to_sign\" // quote received, awaiting wallet signature\n | \"signing\" // wallet is signing\n | \"broadcasting\" // signed tx submitted to RPC, waiting for hash\n | \"submitted\" // /submit called, intentId returned\n | \"tracking\" // polling /status with a non-terminal lifecycle status\n | \"succeeded\" // terminal: settled\n | \"refunded\" // terminal: refunded\n | \"failed\" // terminal: failed | stuck (or any local error)\n | \"expired\"; // quote expired before user signed\n\n/** Discriminated union representing the entire deposit flow at any moment. */\nexport type DepositState =\n | { phase: \"idle\" }\n | { phase: \"quoting\" }\n | {\n phase: \"ready_to_sign\";\n quote: DepositQuoteResponse;\n /** Epoch ms — caller pre-computes for stable comparisons. */\n expiresAtMs: number;\n }\n | { phase: \"signing\"; quote: DepositQuoteResponse }\n | { phase: \"broadcasting\"; quote: DepositQuoteResponse }\n | {\n phase: \"submitted\";\n quote: DepositQuoteResponse;\n intentId: string;\n solanaTxHash: string;\n }\n | {\n phase: \"tracking\";\n intentId: string;\n status: DepositStatusResponse;\n }\n | {\n phase: \"succeeded\";\n intentId: string;\n status: DepositStatusResponse;\n }\n | {\n phase: \"refunded\";\n intentId: string;\n status: DepositStatusResponse;\n }\n | {\n phase: \"failed\";\n error: DepositErrorInfo;\n /** Populated when the failure happened post-submit. */\n intentId?: string;\n status?: DepositStatusResponse;\n }\n | { phase: \"expired\"; quote: DepositQuoteResponse };\n\n/** Events the FSM can react to. Driven by hooks/components. */\nexport type DepositEvent =\n | { type: \"RESET\" }\n | { type: \"QUOTE_REQUEST\" }\n | { type: \"QUOTE_RECEIVED\"; quote: DepositQuoteResponse }\n | { type: \"QUOTE_FAILED\"; error: DepositErrorInfo }\n | { type: \"QUOTE_EXPIRED\" }\n | { type: \"SIGN_START\" }\n | { type: \"SIGN_FAILED\"; error: DepositErrorInfo }\n | { type: \"BROADCAST_START\" }\n | { type: \"BROADCAST_FAILED\"; error: DepositErrorInfo }\n | {\n type: \"SUBMIT_OK\";\n intentId: string;\n solanaTxHash: string;\n }\n | { type: \"SUBMIT_FAILED\"; error: DepositErrorInfo }\n | { type: \"STATUS_UPDATE\"; status: DepositStatusResponse };\n\nexport const initialDepositState: DepositState = { phase: \"idle\" };\n\n/**\n * Transition function. Pure, total — every (state, event) pair is\n * handled. Unknown transitions are no-ops (return current state); we\n * don't throw because hooks may fan out events optimistically (e.g. a\n * stale STATUS_UPDATE arriving after RESET).\n */\nexport function reduceDepositState(\n state: DepositState,\n event: DepositEvent,\n): DepositState {\n switch (event.type) {\n case \"RESET\":\n return initialDepositState;\n\n case \"QUOTE_REQUEST\":\n // Allowed from idle, ready_to_sign (re-quote), expired, failed (retry).\n if (\n state.phase === \"idle\" ||\n state.phase === \"ready_to_sign\" ||\n state.phase === \"expired\" ||\n state.phase === \"failed\"\n ) {\n return { phase: \"quoting\" };\n }\n return state;\n\n case \"QUOTE_RECEIVED\":\n if (state.phase === \"quoting\") {\n return {\n phase: \"ready_to_sign\",\n quote: event.quote,\n expiresAtMs: Date.parse(event.quote.expiresAt),\n };\n }\n return state;\n\n case \"QUOTE_FAILED\":\n if (state.phase === \"quoting\") {\n return { phase: \"failed\", error: event.error };\n }\n return state;\n\n case \"QUOTE_EXPIRED\":\n if (state.phase === \"ready_to_sign\") {\n return { phase: \"expired\", quote: state.quote };\n }\n return state;\n\n case \"SIGN_START\":\n if (state.phase === \"ready_to_sign\") {\n return { phase: \"signing\", quote: state.quote };\n }\n return state;\n\n case \"SIGN_FAILED\":\n if (state.phase === \"signing\") {\n // Keep the quote so the UI can offer a retry without re-quoting.\n return { phase: \"failed\", error: event.error };\n }\n return state;\n\n case \"BROADCAST_START\":\n if (state.phase === \"signing\") {\n return { phase: \"broadcasting\", quote: state.quote };\n }\n return state;\n\n case \"BROADCAST_FAILED\":\n if (state.phase === \"broadcasting\" || state.phase === \"signing\") {\n return { phase: \"failed\", error: event.error };\n }\n return state;\n\n case \"SUBMIT_OK\":\n if (state.phase === \"broadcasting\") {\n return {\n phase: \"submitted\",\n quote: state.quote,\n intentId: event.intentId,\n solanaTxHash: event.solanaTxHash,\n };\n }\n return state;\n\n case \"SUBMIT_FAILED\":\n if (state.phase === \"broadcasting\") {\n return { phase: \"failed\", error: event.error };\n }\n return state;\n\n case \"STATUS_UPDATE\": {\n // /status is polled after submit. Map the backend status to the UI phase.\n if (state.phase !== \"submitted\" && state.phase !== \"tracking\") {\n return state;\n }\n const intentId =\n state.phase === \"submitted\" ? state.intentId : state.intentId;\n const next = mapStatusToPhase(event.status, intentId);\n return next;\n }\n }\n}\n\nfunction mapStatusToPhase(\n status: DepositStatusResponse,\n intentId: string,\n): DepositState {\n switch (status.status) {\n case \"settled\":\n return { phase: \"succeeded\", intentId, status };\n case \"refunded\":\n return { phase: \"refunded\", intentId, status };\n case \"failed\":\n case \"stuck\":\n return {\n phase: \"failed\",\n error: status.lastError ?? {\n code: status.status === \"stuck\" ? \"STUCK\" : \"FAILED\",\n message:\n status.status === \"stuck\"\n ? \"Deposit hasn't been observed by Relay yet — please contact support if this persists.\"\n : \"Deposit failed. Funds will be refunded to your wallet shortly.\",\n recoverable: false,\n },\n intentId,\n status,\n };\n case \"broadcasted\":\n case \"relay_waiting\":\n case \"relay_pending\":\n default:\n return { phase: \"tracking\", intentId, status };\n }\n}\n\n// =====================================================================\n// Selectors — the same data, but in a shape components can render.\n// Defining them here keeps the UI free of `if (state.phase === \"...\" )`\n// branching.\n// =====================================================================\n\n/** True when the FSM has reached a terminal phase. */\nexport function isTerminal(state: DepositState): boolean {\n return (\n state.phase === \"succeeded\" ||\n state.phase === \"refunded\" ||\n state.phase === \"failed\"\n );\n}\n\n/** True when the UI should keep polling /status. */\nexport function isPolling(state: DepositState): boolean {\n return state.phase === \"submitted\" || state.phase === \"tracking\";\n}\n\n/** Returns the current backend lifecycle status, if any. */\nexport function currentStatus(state: DepositState): DepositStatus | undefined {\n if (\n state.phase === \"tracking\" ||\n state.phase === \"succeeded\" ||\n state.phase === \"refunded\"\n ) {\n return state.status.status;\n }\n if (state.phase === \"failed\" && state.status) {\n return state.status.status;\n }\n return undefined;\n}\n\n/** Returns the breakdown the UI should display, if any. */\nexport function currentBreakdown(\n state: DepositState,\n): DepositBreakdown | undefined {\n if (\n state.phase === \"ready_to_sign\" ||\n state.phase === \"signing\" ||\n state.phase === \"broadcasting\" ||\n state.phase === \"submitted\" ||\n state.phase === \"expired\"\n ) {\n return state.quote.breakdown;\n }\n if (\n state.phase === \"tracking\" ||\n state.phase === \"succeeded\" ||\n state.phase === \"refunded\"\n ) {\n return state.status.breakdown;\n }\n if (state.phase === \"failed\" && state.status) {\n return state.status.breakdown;\n }\n return undefined;\n}\n\n/**\n * Returns true when the phase is terminal *and* corresponds to one of\n * the known DepositStatus terminal values. Useful for analytics fan-out\n * (only emit the funnel-end event once per intent).\n */\nexport function isTerminalLifecycle(\n status: DepositStatus | undefined,\n): boolean {\n return status !== undefined && TERMINAL_DEPOSIT_STATUSES.has(status);\n}\n","import { createContext } from \"react\";\nimport type { IPerpDepositClient } from \"../client/liberfi/LiberFiPerpDepositClient\";\nimport type { IPerpetualsClient } from \"../types\";\n\n/**\n * Perpetuals context value type\n *\n * Provides access to the perpetuals trading client and (optionally) the\n * deposit client. The deposit client is optional because not every\n * surface that consumes this provider also needs the deposit flow — a\n * portfolio view that only renders positions can omit it without\n * pulling the deposit dependency along.\n */\nexport interface PerpetualsContextValue {\n /**\n * Perpetuals client instance for trading operations.\n */\n client: IPerpetualsClient;\n\n /**\n * Deposit client instance for the Solana → Hyperliquid funding flow.\n *\n * Optional: surfaces that don't render the deposit UI can omit it.\n * Hooks that need it (e.g. `usePerpDepositQuote`) will throw a clear\n * error pointing at the missing prop.\n */\n depositClient?: IPerpDepositClient;\n}\n\n/**\n * Perpetuals Context\n *\n * React context for accessing perpetuals trading + deposit functionality\n * throughout the app.\n */\nexport const PerpetualsContext = createContext<PerpetualsContextValue>(\n {} as PerpetualsContextValue,\n);\n","import { PropsWithChildren, useMemo } from \"react\";\nimport {\n PerpetualsContext,\n PerpetualsContextValue,\n} from \"../context/PerpetualsContext\";\n\n/**\n * Perpetuals provider props type.\n *\n * `client` is required; `depositClient` is optional and only needed by\n * surfaces that render the cross-chain deposit flow.\n */\nexport type PerpetualsProviderProps = PropsWithChildren<PerpetualsContextValue>;\n\n/**\n * Perpetuals Provider Component.\n *\n * Wraps the perpetuals trading client and (optionally) the deposit\n * client into a single context value. The value is memoised on the\n * client identities so re-renders of the consumer app do not break\n * referential equality for downstream `useContext` consumers.\n *\n * @param props Provider props containing client(s) and children\n * @returns Provider component wrapping children\n */\nexport function PerpetualsProvider({\n client,\n depositClient,\n children,\n}: PerpetualsProviderProps) {\n const value = useMemo<PerpetualsContextValue>(\n () => ({ client, depositClient }),\n [client, depositClient],\n );\n return (\n <PerpetualsContext.Provider value={value}>\n {children}\n </PerpetualsContext.Provider>\n );\n}\n","import { useContext } from \"react\";\nimport {\n PerpetualsContext,\n PerpetualsContextValue,\n} from \"../context/PerpetualsContext\";\n\n/**\n * Hook to access perpetuals client from context\n *\n * Must be used within a PerpetualsProvider component\n *\n * @returns Perpetuals context value containing the client instance\n * @throws Error if used outside of PerpetualsProvider\n */\nexport function usePerpetualsClient(): PerpetualsContextValue {\n const context = useContext(PerpetualsContext);\n\n if (!context || !context.client) {\n throw new Error(\n \"usePerpetualsClient must be used within a PerpetualsProvider\",\n );\n }\n\n return context;\n}\n","import { useQuery, UseQueryOptions } from \"@tanstack/react-query\";\nimport type { IPerpetualsClient } from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport function coinsQueryKey(): string[] {\n return [\"perps\", \"coins\"];\n}\n\nexport async function fetchCoins(client: IPerpetualsClient): Promise<string[]> {\n return await client.getSupportedCoins();\n}\n\nexport function useCoinsQuery(\n options: Omit<\n UseQueryOptions<string[], Error, string[], string[]>,\n \"queryKey\" | \"queryFn\"\n > = {},\n) {\n const { client } = usePerpetualsClient();\n return useQuery({\n queryKey: coinsQueryKey(),\n queryFn: async () => fetchCoins(client),\n staleTime: 5 * 60 * 1000,\n ...options,\n });\n}\n","import { useQuery, UseQueryOptions } from \"@tanstack/react-query\";\nimport type { IPerpetualsClient, MarketData } from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport interface UseMarketQueryParams {\n symbol: string;\n}\n\nexport function marketQueryKey(params: UseMarketQueryParams): string[] {\n return [\"perps\", \"market\", params.symbol];\n}\n\nexport async function fetchMarket(\n client: IPerpetualsClient,\n { symbol }: UseMarketQueryParams,\n): Promise<MarketData | null> {\n return await client.getMarket(symbol);\n}\n\nexport function useMarketQuery(\n params: UseMarketQueryParams,\n options: Omit<\n UseQueryOptions<MarketData | null, Error, MarketData | null, string[]>,\n \"queryKey\" | \"queryFn\"\n > = {},\n) {\n const { client } = usePerpetualsClient();\n return useQuery({\n queryKey: marketQueryKey(params),\n queryFn: async () => fetchMarket(client, params),\n staleTime: 10 * 1000,\n ...options,\n });\n}\n","import { useQuery, UseQueryOptions } from \"@tanstack/react-query\";\nimport type { IPerpetualsClient, MarketData } from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport interface UseMarketsQueryParams {\n symbols?: string[];\n}\n\nexport function marketsQueryKey(params: UseMarketsQueryParams = {}): string[] {\n return [\"perps\", \"markets\", JSON.stringify((params.symbols ?? []).sort())];\n}\n\nexport async function fetchMarkets(\n client: IPerpetualsClient,\n { symbols }: UseMarketsQueryParams = {},\n): Promise<MarketData[]> {\n return await client.getMarkets(symbols);\n}\n\nexport function useMarketsQuery(\n params: UseMarketsQueryParams = {},\n options: Omit<\n UseQueryOptions<MarketData[], Error, MarketData[], string[]>,\n \"queryKey\" | \"queryFn\"\n > = {},\n) {\n const { client } = usePerpetualsClient();\n return useQuery({\n queryKey: marketsQueryKey(params),\n queryFn: async () => fetchMarkets(client, params),\n staleTime: 10 * 1000,\n ...options,\n });\n}\n","import { useQuery, UseQueryOptions } from \"@tanstack/react-query\";\nimport type { IPerpetualsClient, Kline, KlineInterval } from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport interface UseKlinesQueryParams {\n symbol: string;\n interval: KlineInterval;\n limit?: number;\n}\n\nexport function klinesQueryKey(params: UseKlinesQueryParams): string[] {\n return [\n \"perps\",\n \"klines\",\n params.symbol,\n params.interval,\n String(params.limit ?? 100),\n ];\n}\n\nexport async function fetchKlines(\n client: IPerpetualsClient,\n { symbol, interval, limit }: UseKlinesQueryParams,\n): Promise<Kline[]> {\n return await client.getKlines(symbol, interval, limit);\n}\n\nexport function useKlinesQuery(\n params: UseKlinesQueryParams,\n options: Omit<\n UseQueryOptions<Kline[], Error, Kline[], string[]>,\n \"queryKey\" | \"queryFn\"\n > = {},\n) {\n const { client } = usePerpetualsClient();\n return useQuery({\n queryKey: klinesQueryKey(params),\n queryFn: async () => fetchKlines(client, params),\n staleTime: 30 * 1000,\n ...options,\n });\n}\n","import { useQuery, UseQueryOptions } from \"@tanstack/react-query\";\nimport type {\n IPerpetualsClient,\n OrderBook,\n OrderBookAggregationOptions,\n} from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport interface UseOrderBookQueryParams {\n symbol: string;\n maxLevel?: number;\n /**\n * Optional venue aggregation params (e.g. Hyperliquid `nSigFigs` /\n * `mantissa`). When set, the request key includes these so different\n * aggregations cache independently.\n */\n aggregation?: OrderBookAggregationOptions;\n}\n\nexport function orderBookQueryKey(params: UseOrderBookQueryParams): string[] {\n const agg = params.aggregation;\n const aggKey =\n agg?.nSigFigs !== undefined\n ? `n${agg.nSigFigs}${\n agg.nSigFigs === 5 && agg.mantissa && agg.mantissa !== 1\n ? `m${agg.mantissa}`\n : \"\"\n }`\n : \"raw\";\n return [\n \"perps\",\n \"orderBook\",\n params.symbol,\n String(params.maxLevel ?? 20),\n aggKey,\n ];\n}\n\nexport async function fetchOrderBook(\n client: IPerpetualsClient,\n { symbol, maxLevel, aggregation }: UseOrderBookQueryParams,\n): Promise<OrderBook> {\n return await client.getOrderBook(symbol, maxLevel, aggregation);\n}\n\nexport function useOrderBookQuery(\n params: UseOrderBookQueryParams,\n options: Omit<\n UseQueryOptions<OrderBook, Error, OrderBook, string[]>,\n \"queryKey\" | \"queryFn\"\n > = {},\n) {\n const { client } = usePerpetualsClient();\n return useQuery({\n queryKey: orderBookQueryKey(params),\n queryFn: async () => fetchOrderBook(client, params),\n staleTime: 5 * 1000,\n ...options,\n });\n}\n","import { useQuery, UseQueryOptions } from \"@tanstack/react-query\";\nimport type { IPerpetualsClient, Trade } from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport interface UseRecentTradesQueryParams {\n symbol: string;\n limit?: number;\n}\n\nexport function recentTradesQueryKey(\n params: UseRecentTradesQueryParams,\n): string[] {\n return [\"perps\", \"recentTrades\", params.symbol, String(params.limit ?? 50)];\n}\n\nexport async function fetchRecentTrades(\n client: IPerpetualsClient,\n { symbol, limit }: UseRecentTradesQueryParams,\n): Promise<Trade[]> {\n return await client.getRecentTrades(symbol, limit);\n}\n\nexport function useRecentTradesQuery(\n params: UseRecentTradesQueryParams,\n options: Omit<\n UseQueryOptions<Trade[], Error, Trade[], string[]>,\n \"queryKey\" | \"queryFn\"\n > = {},\n) {\n const { client } = usePerpetualsClient();\n return useQuery({\n queryKey: recentTradesQueryKey(params),\n queryFn: async () => fetchRecentTrades(client, params),\n staleTime: 5 * 1000,\n ...options,\n });\n}\n","import { useQuery, UseQueryOptions } from \"@tanstack/react-query\";\nimport type {\n IPerpetualsClient,\n GetPositionsResult,\n GetPositionsParams,\n} from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport interface UsePositionsQueryParams extends GetPositionsParams {\n enabled?: boolean;\n}\n\nexport function positionsQueryKey(\n params: Omit<UsePositionsQueryParams, \"enabled\">,\n): string[] {\n return [\"perps\", \"positions\", params.userAddress ?? \"\", params.symbol ?? \"\"];\n}\n\nexport async function fetchPositions(\n client: IPerpetualsClient,\n params: GetPositionsParams,\n): Promise<GetPositionsResult> {\n return await client.getPositions(params);\n}\n\nexport function usePositionsQuery(\n params: UsePositionsQueryParams,\n options: Omit<\n UseQueryOptions<GetPositionsResult, Error, GetPositionsResult, string[]>,\n \"queryKey\" | \"queryFn\"\n > = {},\n) {\n const { client } = usePerpetualsClient();\n const { enabled = true, ...queryParams } = params;\n\n return useQuery({\n queryKey: positionsQueryKey(queryParams),\n queryFn: async () => fetchPositions(client, queryParams),\n enabled: enabled && !!queryParams.userAddress,\n staleTime: 10 * 1000,\n ...options,\n });\n}\n","import { useQuery, UseQueryOptions } from \"@tanstack/react-query\";\nimport type {\n IPerpetualsClient,\n GetOpenOrdersResult,\n GetOpenOrdersParams,\n} from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport interface UseOrdersQueryParams extends GetOpenOrdersParams {\n enabled?: boolean;\n}\n\nexport function ordersQueryKey(\n params: Omit<UseOrdersQueryParams, \"enabled\">,\n): string[] {\n return [\"perps\", \"orders\", params.userAddress ?? \"\", params.symbol ?? \"\"];\n}\n\nexport async function fetchOrders(\n client: IPerpetualsClient,\n params: GetOpenOrdersParams,\n): Promise<GetOpenOrdersResult> {\n return await client.getOpenOrders(params);\n}\n\nexport function useOrdersQuery(\n params: UseOrdersQueryParams,\n options: Omit<\n UseQueryOptions<GetOpenOrdersResult, Error, GetOpenOrdersResult, string[]>,\n \"queryKey\" | \"queryFn\"\n > = {},\n) {\n const { client } = usePerpetualsClient();\n const { enabled = true, ...queryParams } = params;\n\n return useQuery({\n queryKey: ordersQueryKey(queryParams),\n queryFn: async () => fetchOrders(client, queryParams),\n enabled: enabled && !!queryParams.userAddress,\n staleTime: 5 * 1000,\n ...options,\n });\n}\n","import { useQuery, UseQueryOptions } from \"@tanstack/react-query\";\nimport type {\n IPerpetualsClient,\n GetTradesResult,\n GetTradesParams,\n} from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport interface UseTradesQueryParams extends GetTradesParams {\n enabled?: boolean;\n}\n\nexport function tradesQueryKey(\n params: Omit<UseTradesQueryParams, \"enabled\">,\n): string[] {\n return [\n \"perps\",\n \"trades\",\n params.userAddress ?? \"\",\n params.symbol ?? \"\",\n String(params.limit ?? 50),\n String(params.startTime ?? \"\"),\n String(params.endTime ?? \"\"),\n ];\n}\n\nexport async function fetchTrades(\n client: IPerpetualsClient,\n params: GetTradesParams,\n): Promise<GetTradesResult> {\n return await client.getTrades(params);\n}\n\nexport function useTradesQuery(\n params: UseTradesQueryParams,\n options: Omit<\n UseQueryOptions<GetTradesResult, Error, GetTradesResult, string[]>,\n \"queryKey\" | \"queryFn\"\n > = {},\n) {\n const { client } = usePerpetualsClient();\n const { enabled = true, ...queryParams } = params;\n\n return useQuery({\n queryKey: tradesQueryKey(queryParams),\n queryFn: async () => fetchTrades(client, queryParams),\n enabled: enabled && !!queryParams.userAddress,\n staleTime: 30 * 1000,\n ...options,\n });\n}\n","import { useMutation, UseMutationOptions } from \"@tanstack/react-query\";\nimport type {\n IPerpetualsClient,\n PlaceOrderParams,\n PlaceOrderResult,\n} from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport type UseCreateOrderMutationParams = PlaceOrderParams;\n\nexport async function createOrder(\n client: IPerpetualsClient,\n params: UseCreateOrderMutationParams,\n): Promise<PlaceOrderResult> {\n return await client.placeOrder(params);\n}\n\nexport function useCreateOrderMutation(\n options: Omit<\n UseMutationOptions<PlaceOrderResult, Error, UseCreateOrderMutationParams>,\n \"mutationFn\"\n > = {},\n) {\n const { client } = usePerpetualsClient();\n return useMutation({\n mutationFn: async (params: UseCreateOrderMutationParams) =>\n createOrder(client, params),\n ...options,\n });\n}\n","import { useMutation, UseMutationOptions } from \"@tanstack/react-query\";\nimport type {\n IPerpetualsClient,\n CancelOrderParams,\n CancelOrderResult,\n} from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport type UseCancelOrderMutationParams = CancelOrderParams;\n\nexport async function cancelOrder(\n client: IPerpetualsClient,\n params: UseCancelOrderMutationParams,\n): Promise<CancelOrderResult> {\n return await client.cancelOrder(params);\n}\n\nexport function useCancelOrderMutation(\n options: Omit<\n UseMutationOptions<CancelOrderResult, Error, UseCancelOrderMutationParams>,\n \"mutationFn\"\n > = {},\n) {\n const { client } = usePerpetualsClient();\n return useMutation({\n mutationFn: async (params: UseCancelOrderMutationParams) =>\n cancelOrder(client, params),\n ...options,\n });\n}\n","import { useEffect, useState, useCallback, useRef } from \"react\";\nimport type {\n MarketData,\n Trade,\n OrderBook,\n OrderBookAggregationOptions,\n} from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport type MarketDataType = \"ticker\" | \"trades\" | \"orderBook\";\n\nexport interface UseMarketDataSubscriptionParams {\n type: MarketDataType;\n symbol: string;\n enabled?: boolean;\n /**\n * Optional venue aggregation hint (only meaningful when\n * `type === \"orderBook\"`). Changing it tears down and re-creates the\n * subscription so the upstream stream is re-keyed with the new\n * `nSigFigs` / `mantissa`.\n */\n aggregation?: OrderBookAggregationOptions;\n /**\n * If set, coalesce upstream pushes into a single React `setData` call no\n * more than once every `throttleMs` milliseconds. The latest payload\n * always wins; intermediate pushes are dropped. Use this for high-rate\n * streams (e.g. orderBook on active markets) where the human eye can't\n * tell the difference between 30 Hz and 10 Hz but React reconciliation\n * cost scales linearly.\n *\n * Leave undefined to forward every push immediately (default).\n */\n throttleMs?: number;\n}\n\nexport interface UseMarketDataSubscriptionResult<T> {\n data: T | null;\n isConnected: boolean;\n error: Error | null;\n}\n\nexport function useMarketDataSubscription<\n T = MarketDataType extends \"ticker\"\n ? MarketData\n : MarketDataType extends \"trades\"\n ? Trade\n : OrderBook,\n>(params: UseMarketDataSubscriptionParams): UseMarketDataSubscriptionResult<T> {\n const { type, symbol, enabled = true, aggregation, throttleMs } = params;\n const { client } = usePerpetualsClient();\n const [data, setData] = useState<T | null>(null);\n const [isConnected, setIsConnected] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n // Throttling state. We keep the most-recent payload in a ref and flush it\n // through `setData` on a trailing-edge timer. Refs (not state) so updating\n // them never triggers a render.\n const pendingDataRef = useRef<T | null>(null);\n const flushTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const throttleMsRef = useRef<number | undefined>(throttleMs);\n // Keep the ref in sync without re-creating `handleData` every render —\n // changing the throttle interval shouldn't tear down the WS subscription.\n throttleMsRef.current = throttleMs;\n\n const handleData = useCallback((newData: T) => {\n const interval = throttleMsRef.current;\n if (!interval || interval <= 0) {\n setData(newData);\n return;\n }\n // Always remember the latest payload; the trailing flush will pick it up.\n pendingDataRef.current = newData;\n if (flushTimerRef.current === null) {\n flushTimerRef.current = setTimeout(() => {\n flushTimerRef.current = null;\n if (pendingDataRef.current !== null) {\n const next = pendingDataRef.current;\n pendingDataRef.current = null;\n setData(next);\n }\n }, interval);\n }\n }, []);\n\n // Stable string key derived from aggregation. Effect re-runs only when this\n // changes (not on every parent render that produces a fresh object).\n const aggregationKey =\n aggregation?.nSigFigs !== undefined\n ? `n${aggregation.nSigFigs}${\n aggregation.nSigFigs === 5 &&\n aggregation.mantissa &&\n aggregation.mantissa !== 1\n ? `m${aggregation.mantissa}`\n : \"\"\n }`\n : \"\";\n\n useEffect(() => {\n if (!enabled) {\n return;\n }\n\n let subscriptionId: string | null = null;\n let isSubscribed = true;\n\n const connect = async () => {\n try {\n await client.connectWebSocket();\n\n if (!isSubscribed) return;\n\n setIsConnected(true);\n setError(null);\n\n subscriptionId = client.subscribeMarketData(\n type,\n symbol,\n handleData,\n type === \"orderBook\" && aggregation ? { aggregation } : undefined,\n );\n } catch (err) {\n if (isSubscribed) {\n setError(err instanceof Error ? err : new Error(\"Connection failed\"));\n setIsConnected(false);\n }\n }\n };\n\n connect();\n\n return () => {\n isSubscribed = false;\n if (subscriptionId) {\n try {\n client.unsubscribe(subscriptionId);\n } catch (err) {\n console.error(\"Failed to unsubscribe:\", err);\n }\n }\n client.disconnectWebSocket();\n // Drop any pending throttled payload so it can't land after the\n // subscription is torn down.\n if (flushTimerRef.current !== null) {\n clearTimeout(flushTimerRef.current);\n flushTimerRef.current = null;\n }\n pendingDataRef.current = null;\n setIsConnected(false);\n setData(null);\n };\n // aggregationKey is intentionally part of deps so re-subscribing on\n // precision change tears down the old stream and starts a new one with\n // the new nSigFigs/mantissa.\n }, [client, type, symbol, enabled, handleData, aggregationKey]);\n\n return { data, isConnected, error };\n}\n","import { useEffect, useState, useCallback } from \"react\";\nimport type { Kline, KlineInterval } from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport interface UseCandlesSubscriptionParams {\n symbol: string;\n interval: KlineInterval;\n enabled?: boolean;\n}\n\nexport interface UseCandlesSubscriptionResult {\n data: Kline | null;\n isConnected: boolean;\n error: Error | null;\n}\n\nexport function useCandlesSubscription(\n params: UseCandlesSubscriptionParams,\n): UseCandlesSubscriptionResult {\n const { symbol, interval, enabled = true } = params;\n const { client } = usePerpetualsClient();\n const [data, setData] = useState<Kline | null>(null);\n const [isConnected, setIsConnected] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const handleData = useCallback((newData: Kline) => {\n setData(newData);\n }, []);\n\n useEffect(() => {\n if (!enabled) {\n return;\n }\n\n let subscriptionId: string | null = null;\n let isSubscribed = true;\n\n const connect = async () => {\n try {\n await client.connectWebSocket();\n\n if (!isSubscribed) return;\n\n setIsConnected(true);\n setError(null);\n\n subscriptionId = client.subscribeCandles(symbol, interval, handleData);\n } catch (err) {\n if (isSubscribed) {\n setError(err instanceof Error ? err : new Error(\"Connection failed\"));\n setIsConnected(false);\n }\n }\n };\n\n connect();\n\n return () => {\n isSubscribed = false;\n if (subscriptionId) {\n try {\n client.unsubscribe(subscriptionId);\n } catch (err) {\n console.error(\"Failed to unsubscribe:\", err);\n }\n }\n client.disconnectWebSocket();\n setIsConnected(false);\n setData(null);\n };\n }, [client, symbol, interval, enabled, handleData]);\n\n return { data, isConnected, error };\n}\n","import { useEffect, useState, useCallback } from \"react\";\nimport type { Order, Position, TradeHistory } from \"../types\";\nimport { usePerpetualsClient } from \"./usePerpetualsClient\";\n\nexport type UserDataType = \"orders\" | \"positions\" | \"fills\";\n\nexport interface UseUserDataSubscriptionParams {\n type: UserDataType;\n userAddress: string;\n enabled?: boolean;\n}\n\nexport interface UseUserDataSubscriptionResult<T> {\n data: T | null;\n isConnected: boolean;\n error: Error | null;\n}\n\nexport function useUserDataSubscription<\n T = UserDataType extends \"orders\"\n ? Order\n : UserDataType extends \"positions\"\n ? Position\n : TradeHistory,\n>(params: UseUserDataSubscriptionParams): UseUserDataSubscriptionResult<T> {\n const { type, userAddress, enabled = true } = params;\n const { client } = usePerpetualsClient();\n const [data, setData] = useState<T | null>(null);\n const [isConnected, setIsConnected] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const handleData = useCallback((newData: T) => {\n setData(newData);\n }, []);\n\n useEffect(() => {\n if (!enabled || !userAddress) {\n return;\n }\n\n let subscriptionId: string | null = null;\n let isSubscribed = true;\n\n const connect = async () => {\n try {\n await client.connectWebSocket();\n\n if (!isSubscribed) return;\n\n setIsConnected(true);\n setError(null);\n\n subscriptionId = client.subscribeUserData(\n type,\n userAddress,\n handleData,\n );\n } catch (err) {\n if (isSubscribed) {\n setError(err instanceof Error ? err : new Error(\"Connection failed\"));\n setIsConnected(false);\n }\n }\n };\n\n connect();\n\n return () => {\n isSubscribed = false;\n if (subscriptionId) {\n try {\n client.unsubscribe(subscriptionId);\n } catch (err) {\n console.error(\"Failed to unsubscribe:\", err);\n }\n }\n client.disconnectWebSocket();\n setIsConnected(false);\n setData(null);\n };\n }, [client, type, userAddress, enabled, handleData]);\n\n return { data, isConnected, error };\n}\n","import { useContext } from \"react\";\nimport type { IPerpDepositClient } from \"../client/liberfi/LiberFiPerpDepositClient\";\nimport { PerpetualsContext } from \"../context/PerpetualsContext\";\n\n/**\n * Hook to access the deposit client from `PerpetualsProvider`.\n *\n * Throws if the provider is missing OR if the host app forgot to pass\n * `depositClient`. The thrown message tells the consumer exactly what\n * to fix — preferring an explicit error to a silent runtime crash deep\n * inside a useQuery hook.\n *\n * @returns The deposit client instance.\n */\nexport function usePerpDepositClient(): IPerpDepositClient {\n const ctx = useContext(PerpetualsContext);\n if (!ctx || !ctx.client) {\n throw new Error(\n \"usePerpDepositClient must be used within a <PerpetualsProvider>.\",\n );\n }\n if (!ctx.depositClient) {\n throw new Error(\n \"usePerpDepositClient: <PerpetualsProvider> was rendered without a `depositClient` prop. \" +\n \"Pass a `LiberFiPerpDepositClient` instance to enable the deposit flow.\",\n );\n }\n return ctx.depositClient;\n}\n\n/**\n * Safe variant — returns `undefined` instead of throwing when\n * `depositClient` is not configured. Use this in hooks that should\n * degrade gracefully (e.g. query hooks that gate on `enabled`) rather\n * than crash when the deposit flow is not wired up.\n */\nexport function usePerpDepositClientMaybe(): IPerpDepositClient | undefined {\n const ctx = useContext(PerpetualsContext);\n return ctx?.depositClient;\n}\n","import { useQuery, UseQueryOptions } from \"@tanstack/react-query\";\nimport type { IPerpDepositClient } from \"../client/liberfi/LiberFiPerpDepositClient\";\nimport type {\n DepositQuoteRequest,\n DepositQuoteResponse,\n} from \"../client/liberfi/deposit-types\";\nimport { usePerpDepositClientMaybe } from \"./usePerpDepositClient\";\n\n/**\n * Stable query key shape for the deposit quote.\n *\n * The amount is part of the key so re-quoting on amount change does not\n * leak across users; the user/recipient pair is included so two users\n * sharing the same browser session don't see each other's quotes in the\n * cache.\n */\nexport function perpDepositQuoteQueryKey(\n req?: DepositQuoteRequest | null,\n): readonly unknown[] {\n return [\"perps\", \"deposit\", \"quote\", req] as const;\n}\n\n/** Pure fetcher — useful for SSR or for invoking outside React. */\nexport async function fetchPerpDepositQuote(\n client: IPerpDepositClient,\n req: DepositQuoteRequest,\n): Promise<DepositQuoteResponse> {\n return client.quote(req);\n}\n\nexport interface UsePerpDepositQuoteOptions extends Omit<\n UseQueryOptions<\n DepositQuoteResponse,\n Error,\n DepositQuoteResponse,\n ReturnType<typeof perpDepositQuoteQueryKey>\n >,\n \"queryKey\" | \"queryFn\" | \"enabled\"\n> {\n /**\n * Override automatic gating. By default the query runs when `req` is\n * fully populated. Pass `enabled: false` to defer firing while the\n * user is still typing the amount.\n */\n enabled?: boolean;\n}\n\n/**\n * Re-quotes on every parameter change, with TanStack Query handling\n * dedupe / refetch / cancellation. Caller is responsible for surfacing\n * `data.expiresAt` to the UI; the FSM will move to `expired` if the\n * user lingers past the deadline.\n *\n * Engineering note: the hook deliberately does NOT auto-refresh on a\n * timer. Re-quoting silently behind the user would erase the “Confirm”\n * button mid-action; the form should re-call `refetch()` on its own\n * cadence (e.g. when `expiresAt` is < 5 s from now).\n */\nexport function usePerpDepositQuote(\n req: DepositQuoteRequest | null | undefined,\n options: UsePerpDepositQuoteOptions = {},\n) {\n const client = usePerpDepositClientMaybe();\n const enabled =\n (options.enabled ?? Boolean(isQuoteReady(req))) && Boolean(client);\n return useQuery({\n queryKey: perpDepositQuoteQueryKey(req ?? null),\n queryFn: async () =>\n fetchPerpDepositQuote(client!, req as DepositQuoteRequest),\n enabled,\n staleTime: 0, // quotes are short-lived; never reuse silently\n gcTime: 30_000,\n refetchOnWindowFocus: false,\n ...options,\n });\n}\n\nfunction isQuoteReady(\n req: DepositQuoteRequest | null | undefined,\n): req is DepositQuoteRequest {\n return Boolean(\n req &&\n req.userSolanaAddress &&\n req.hyperliquidRecipient &&\n req.grossLamports &&\n req.source,\n );\n}\n","import { useCallback, useReducer } from \"react\";\nimport {\n type DepositEvent,\n type DepositState,\n initialDepositState,\n reduceDepositState,\n} from \"../client/liberfi/deposit-state-machine\";\nimport type {\n DepositErrorInfo,\n DepositQuoteResponse,\n DepositSource,\n DepositSubmitRequest,\n} from \"../client/liberfi/deposit-types\";\nimport { LiberFiApiError } from \"../client/liberfi/transport\";\nimport { usePerpDepositClientMaybe } from \"./usePerpDepositClient\";\n\n/**\n * Adapter the host app must provide. Lives on the consumer side so the\n * SDK never has to know how a particular wallet (Phantom / Backpack /\n * Privy / Solflare / …) signs and broadcasts a Solana transaction.\n *\n * Contract:\n * - Decode the `serializedTxBase64` produced by /quote.\n * - Have the user sign it (this is when the wallet UI shows up).\n * - Broadcast it. Return the resulting tx hash.\n * - Throw on user rejection or RPC failure.\n *\n * The SDK keeps things narrow: signature, broadcast, and \"did the wallet\n * succeed\" are the only outputs we care about. Everything else (RPC\n * endpoint, commitment, simulation pre-checks) is an implementation\n * detail the host already owns.\n */\nexport type SignAndBroadcastSolanaTx = (\n serializedTxBase64: string,\n ctx: { isVersioned: boolean; sizeBytes: number },\n) => Promise<string>;\n\n/** Inputs every deposit attempt needs. */\nexport interface ExecuteDepositInput {\n /** The quote previously returned by `/v1/deposits/quote`. */\n quote: DepositQuoteResponse;\n /** User-facing identifiers; must match what was sent to /quote. */\n userSolanaAddress: string;\n hyperliquidRecipient: string;\n /** LiberFi user id (NOT the wallet). Stable for fee attribution. */\n userId: string;\n source: DepositSource;\n /** Optional marketing / referral code. */\n campaign?: string;\n}\n\n/** Hook return shape — exposes the full FSM and a single trigger. */\nexport interface UsePerpDepositExecuteResult {\n state: DepositState;\n /**\n * Kick off the sign → broadcast → submit chain. Returns the eventual\n * `intentId` on success, throws on failure (the FSM will already be\n * in the `failed` phase with a descriptive `error`).\n */\n execute: (input: ExecuteDepositInput) => Promise<string>;\n /** Force back to `idle`. Use when the user dismisses the modal. */\n reset: () => void;\n /** Manually push an event into the FSM (advanced). */\n dispatch: (event: DepositEvent) => void;\n}\n\n/**\n * Orchestrates the full deposit flow:\n *\n * 1. SIGN_START → wallet signs (host adapter)\n * 2. BROADCAST_START → wallet broadcasts (host adapter)\n * 3. SUBMIT_OK → POST /v1/deposits/submit (this hook)\n * 4. STATUS_UPDATE ← `usePerpDepositStatus` polls and forwards\n *\n * Each stage emits a typed event into the same reducer used by the\n * presentational components. The hook itself never renders anything —\n * components consume `state.phase` and react accordingly.\n */\nexport function usePerpDepositExecute(\n signAndBroadcast: SignAndBroadcastSolanaTx,\n): UsePerpDepositExecuteResult {\n const client = usePerpDepositClientMaybe();\n const [state, dispatch] = useReducer(reduceDepositState, initialDepositState);\n\n const reset = useCallback(() => {\n dispatch({ type: \"RESET\" });\n }, []);\n\n const execute = useCallback<UsePerpDepositExecuteResult[\"execute\"]>(\n async (input) => {\n const { quote } = input;\n dispatch({ type: \"SIGN_START\" });\n let solanaTxHash: string;\n try {\n solanaTxHash = await signAndBroadcast(quote.serializedTxBase64, {\n isVersioned: quote.isVersioned,\n sizeBytes: quote.sizeBytes,\n });\n if (!solanaTxHash) {\n throw new Error(\"wallet returned an empty tx hash\");\n }\n } catch (err) {\n const info = toErrorInfo(err, \"WALLET_SIGN_OR_BROADCAST_FAILED\");\n // Distinguish sign vs broadcast: the FSM treats them the same\n // (both transition into `failed`) but we keep the original\n // event name for analytics correlation.\n dispatch({ type: \"SIGN_FAILED\", error: info });\n throw err;\n }\n\n // Optimistic broadcast → submit handshake. The FSM expects the\n // broadcast event before SUBMIT_OK so the phase stays consistent\n // across retries; the wallet adapter has already broadcasted by\n // the time we reach this line, so we fire both events back-to-back.\n dispatch({ type: \"BROADCAST_START\" });\n\n const submitReq: DepositSubmitRequest = {\n userSolanaAddress: input.userSolanaAddress,\n hyperliquidRecipient: input.hyperliquidRecipient,\n solanaTxHash,\n breakdown: quote.breakdown,\n userId: input.userId,\n source: input.source,\n campaign: input.campaign,\n quoteIssuedAt: quote.issuedAt,\n };\n\n if (!client) {\n dispatch({\n type: \"SUBMIT_FAILED\",\n error: {\n code: \"DEPOSIT_CLIENT_NOT_CONFIGURED\",\n message: \"Deposit client is not configured.\",\n recoverable: false,\n },\n });\n throw new Error(\"Deposit client is not configured.\");\n }\n try {\n const out = await client.submit(submitReq);\n dispatch({\n type: \"SUBMIT_OK\",\n intentId: out.intentId,\n solanaTxHash,\n });\n return out.intentId;\n } catch (err) {\n const info = toErrorInfo(err, \"DEPOSIT_SUBMIT_FAILED\");\n dispatch({ type: \"SUBMIT_FAILED\", error: info });\n throw err;\n }\n },\n [client, signAndBroadcast],\n );\n\n return { state, execute, reset, dispatch };\n}\n\nfunction toErrorInfo(err: unknown, fallbackCode: string): DepositErrorInfo {\n if (err instanceof LiberFiApiError) {\n // Try to extract the backend's typed { code, message } from the body.\n const parsed = parseJsonSafe(err.responseBody) as\n | { code?: string; message?: string }\n | undefined;\n return {\n code: parsed?.code ?? fallbackCode,\n message: parsed?.message ?? err.message,\n recoverable: err.statusCode >= 500 || err.statusCode === 408,\n };\n }\n if (err instanceof Error) {\n return { code: fallbackCode, message: err.message, recoverable: true };\n }\n return { code: fallbackCode, message: String(err), recoverable: true };\n}\n\nfunction parseJsonSafe(text: string): unknown {\n if (!text) return undefined;\n try {\n return JSON.parse(text);\n } catch {\n return undefined;\n }\n}\n","import { useQuery, UseQueryOptions } from \"@tanstack/react-query\";\nimport type { IPerpDepositClient } from \"../client/liberfi/LiberFiPerpDepositClient\";\nimport {\n TERMINAL_DEPOSIT_STATUSES,\n type DepositStatusResponse,\n} from \"../client/liberfi/deposit-types\";\nimport { usePerpDepositClientMaybe } from \"./usePerpDepositClient\";\n\nexport function perpDepositStatusQueryKey(\n intentId?: string,\n): readonly unknown[] {\n return [\"perps\", \"deposit\", \"status\", intentId ?? null] as const;\n}\n\nexport async function fetchPerpDepositStatus(\n client: IPerpDepositClient,\n intentId: string,\n): Promise<DepositStatusResponse> {\n return client.status(intentId);\n}\n\nexport interface UsePerpDepositStatusOptions extends Omit<\n UseQueryOptions<\n DepositStatusResponse,\n Error,\n DepositStatusResponse,\n ReturnType<typeof perpDepositStatusQueryKey>\n >,\n \"queryKey\" | \"queryFn\" | \"refetchInterval\" | \"enabled\"\n> {\n enabled?: boolean;\n /**\n * Polling interval in milliseconds while the deposit is non-terminal.\n * Defaults to 3 000 ms — matches the backend's reconciliation cadence\n * with a small safety margin.\n */\n pollIntervalMs?: number;\n}\n\n/**\n * Polls /v1/deposits/{id} until the deposit reaches a terminal status,\n * then stops the timer automatically. The component is responsible for\n * forwarding `data` into the deposit FSM via STATUS_UPDATE events.\n *\n * Engineering principle (single responsibility): this hook owns the\n * \"when to ask the server\" question; the FSM owns the \"what does the\n * answer mean\" question. They communicate through plain typed values.\n */\nexport function usePerpDepositStatus(\n intentId: string | undefined | null,\n options: UsePerpDepositStatusOptions = {},\n) {\n const client = usePerpDepositClientMaybe();\n const enabled = (options.enabled ?? Boolean(intentId)) && Boolean(client);\n // `client!` is safe here because `enabled` is false when `client` is undefined,\n // so the queryFn will never execute without a valid client.\n const pollIntervalMs = options.pollIntervalMs ?? 3_000;\n return useQuery({\n queryKey: perpDepositStatusQueryKey(intentId ?? undefined),\n queryFn: async () => fetchPerpDepositStatus(client!, intentId as string),\n enabled,\n refetchInterval: (query) => {\n const data = query.state.data;\n if (!data) return pollIntervalMs;\n return TERMINAL_DEPOSIT_STATUSES.has(data.status)\n ? false\n : pollIntervalMs;\n },\n refetchOnWindowFocus: false,\n staleTime: 0,\n ...options,\n });\n}\n","/**\n * Pure state machine for the Hyperliquid initialisation flow.\n *\n * Driven by `useReducer` — kept as a separate module so the transition\n * logic is unit-testable without React. The states cover the full\n * lifecycle:\n *\n * idle\n * → loading (caller pressed \"init\", reading current state)\n * → ready (we know which steps remain)\n * → executing (one step is in flight)\n * → done | error\n *\n * `error` is recoverable — `RETRY_STEP` returns the FSM to `executing`.\n * `RESET` always rewinds to `idle` so the caller can re-check status.\n */\nimport type {\n ApproveBuilderFeeParams,\n HyperliquidAccountState,\n SetReferrerParams,\n UpdateLeverageParams,\n} from \"../../client/hyperliquid/HyperliquidSetupAdapter\";\n\n/** Identifier for each setup step — drives the UI checklist. */\nexport type SetupStepId =\n | \"approveBuilderFee\"\n | \"setReferrer\"\n | \"updateLeverage\";\n\n/**\n * A single step in the setup checklist. `params` carry exactly the\n * information the adapter needs to perform the action — the FSM never\n * inspects them; it only routes them to the adapter.\n */\nexport type SetupStep =\n | { id: \"approveBuilderFee\"; params: ApproveBuilderFeeParams }\n | { id: \"setReferrer\"; params: SetReferrerParams }\n | { id: \"updateLeverage\"; params: UpdateLeverageParams };\n\n/** Per-step status tracked across the checklist. */\nexport type StepStatus =\n | \"pending\" // not yet attempted in this session\n | \"skipped\" // already done on-chain — no action needed\n | \"running\"\n | \"done\"\n | \"error\";\n\nexport interface StepRecord {\n step: SetupStep;\n status: StepStatus;\n /** Last error message captured for the step. */\n error?: string;\n /** Optional tx hash returned by the adapter. */\n txHash?: string;\n}\n\nexport type SetupPhase =\n | \"idle\"\n | \"loading\" // refreshing account state\n | \"ready\" // checklist computed, awaiting user action\n | \"executing\"\n | \"done\"\n | \"error\";\n\nexport interface SetupState {\n phase: SetupPhase;\n /** Snapshot of the on-chain state captured during `loading`. */\n accountState?: HyperliquidAccountState;\n /** All steps requested by the caller, in order. */\n steps: StepRecord[];\n /** Index of the step currently executing (only valid in `executing`). */\n currentIndex?: number;\n /** Top-level error — typically from `getAccountState`. */\n error?: string;\n}\n\nexport type SetupAction =\n | { type: \"START_LOADING\" }\n | {\n type: \"LOAD_SUCCESS\";\n accountState: HyperliquidAccountState;\n steps: StepRecord[];\n }\n | { type: \"LOAD_ERROR\"; error: string }\n | { type: \"RUN_STEP\"; index: number }\n | {\n type: \"STEP_SUCCESS\";\n index: number;\n txHash?: string;\n accountState?: HyperliquidAccountState;\n }\n | { type: \"STEP_ERROR\"; index: number; error: string }\n | { type: \"RESET\" };\n\nexport const initialSetupState: SetupState = {\n phase: \"idle\",\n steps: [],\n};\n\n/**\n * Determine the initial status of a step given the current on-chain\n * state. `done` (sometimes called `skipped` to the user) means the\n * action has already happened and we can elide it.\n *\n * Encapsulated as a pure function so the same logic is exercised by\n * both the loader (when `LOAD_SUCCESS` constructs the checklist) and\n * the adapter result handler (when an action reports a partial state\n * update).\n */\nexport function classifyStep(\n step: SetupStep,\n state: HyperliquidAccountState,\n): StepStatus {\n switch (step.id) {\n case \"approveBuilderFee\": {\n const current = state.builderApproval;\n if (\n current &&\n sameAddress(current.builder, step.params.builder) &&\n current.maxFeeRate >= step.params.maxFeeRate\n ) {\n return \"skipped\";\n }\n return \"pending\";\n }\n case \"setReferrer\": {\n // Referrer is a one-shot — any non-null value means done. We do\n // not try to \"fix\" a different referrer because Hyperliquid\n // rejects rebinding.\n return state.referrer ? \"skipped\" : \"pending\";\n }\n case \"updateLeverage\": {\n const current = state.leverage[step.params.asset];\n if (current === step.params.leverage) {\n return \"skipped\";\n }\n return \"pending\";\n }\n }\n}\n\nexport function reduceSetupState(\n state: SetupState,\n action: SetupAction,\n): SetupState {\n switch (action.type) {\n case \"START_LOADING\":\n return {\n phase: \"loading\",\n steps: state.steps,\n accountState: state.accountState,\n };\n case \"LOAD_SUCCESS\": {\n const allDone = action.steps.every(\n (s) => s.status === \"skipped\" || s.status === \"done\",\n );\n return {\n phase: allDone ? \"done\" : \"ready\",\n accountState: action.accountState,\n steps: action.steps,\n };\n }\n case \"LOAD_ERROR\":\n return {\n phase: \"error\",\n steps: state.steps,\n error: action.error,\n };\n case \"RUN_STEP\": {\n const next = state.steps.map((rec, i) =>\n i === action.index\n ? { ...rec, status: \"running\" as StepStatus, error: undefined }\n : rec,\n );\n return {\n phase: \"executing\",\n steps: next,\n accountState: state.accountState,\n currentIndex: action.index,\n };\n }\n case \"STEP_SUCCESS\": {\n const next = state.steps.map((rec, i) =>\n i === action.index\n ? {\n ...rec,\n status: \"done\" as StepStatus,\n txHash: action.txHash,\n error: undefined,\n }\n : rec,\n );\n const mergedAccount: HyperliquidAccountState | undefined =\n action.accountState && state.accountState\n ? mergeAccountState(state.accountState, action.accountState)\n : ((action.accountState as HyperliquidAccountState | undefined) ??\n state.accountState);\n const allDone = next.every(\n (s) => s.status === \"skipped\" || s.status === \"done\",\n );\n return {\n phase: allDone ? \"done\" : \"ready\",\n steps: next,\n accountState: mergedAccount,\n currentIndex: undefined,\n };\n }\n case \"STEP_ERROR\": {\n const next = state.steps.map((rec, i) =>\n i === action.index\n ? { ...rec, status: \"error\" as StepStatus, error: action.error }\n : rec,\n );\n return {\n phase: \"ready\",\n steps: next,\n accountState: state.accountState,\n currentIndex: undefined,\n };\n }\n case \"RESET\":\n return initialSetupState;\n }\n}\n\n/**\n * Find the next step that still needs to run. Returns `null` when the\n * checklist is complete — the caller should treat the FSM as `done`.\n */\nexport function nextRunnableStep(state: SetupState): number | null {\n for (let i = 0; i < state.steps.length; i++) {\n const status = state.steps[i].status;\n if (status === \"pending\" || status === \"error\") return i;\n }\n return null;\n}\n\nfunction sameAddress(a: string, b: string): boolean {\n return a.toLowerCase() === b.toLowerCase();\n}\n\nfunction mergeAccountState(\n base: HyperliquidAccountState,\n patch: Partial<HyperliquidAccountState>,\n): HyperliquidAccountState {\n return {\n builderApproval:\n patch.builderApproval !== undefined\n ? patch.builderApproval\n : base.builderApproval,\n referrer: patch.referrer !== undefined ? patch.referrer : base.referrer,\n leverage: { ...base.leverage, ...(patch.leverage ?? {}) },\n };\n}\n","import { useCallback, useEffect, useReducer, useRef } from \"react\";\nimport type {\n HyperliquidAccountState,\n IHyperliquidSetupAdapter,\n HyperliquidSetupActionResult,\n} from \"../../client/hyperliquid/HyperliquidSetupAdapter\";\nimport {\n classifyStep,\n initialSetupState,\n nextRunnableStep,\n reduceSetupState,\n type SetupState,\n type SetupStep,\n type StepRecord,\n} from \"./setup-state-machine\";\n\n/**\n * Configuration for the Hyperliquid setup orchestrator.\n *\n * The hook is intentionally adapter-agnostic — it does not import any\n * Hyperliquid signing code. The consumer wires in an adapter (typically\n * built around their wallet integration) plus the list of steps they\n * want to run.\n */\nexport interface UseHyperliquidSetupOptions {\n /** Adapter that knows how to read state and submit signed actions. */\n adapter: IHyperliquidSetupAdapter;\n /** EVM address of the user (required to read account state). */\n userAddress: string | undefined;\n /**\n * The steps the consumer wants the user to complete. Order is\n * preserved in the UI, and the orchestrator advances strictly in\n * sequence so failures don't strand the user mid-checklist.\n */\n steps: SetupStep[];\n /**\n * If true, the hook performs an initial state read on mount /\n * adapter change. Defaults to `true`.\n */\n autoLoad?: boolean;\n /** Optional callback invoked once every step is `done` or `skipped`. */\n onComplete?: (state: SetupState) => void;\n /** Optional callback for diagnostic logging. */\n onError?: (err: Error, context: { stepId?: SetupStep[\"id\"] }) => void;\n}\n\nexport interface UseHyperliquidSetupResult {\n state: SetupState;\n /** Re-fetch the on-chain state. Idempotent — safe to call repeatedly. */\n reload: () => Promise<void>;\n /** Run the next pending / error step. No-op when the checklist is done. */\n runNext: () => Promise<void>;\n /** Run a specific step by index — used by per-row \"Retry\" buttons. */\n runStep: (index: number) => Promise<void>;\n /** Reset the FSM to `idle` (e.g. when the user closes the wizard). */\n reset: () => void;\n}\n\n/**\n * Orchestrates the Hyperliquid first-run setup checklist.\n *\n * Responsibilities:\n * - Read the user's account state via the adapter.\n * - Classify each requested step against that state, marking ones\n * already done as `skipped`.\n * - Advance through the remaining steps, calling the appropriate\n * adapter method and merging the returned partial state back.\n * - Surface errors per-step so the UI can show a precise retry CTA.\n *\n * Out of scope:\n * - Signing — adapter does it.\n * - Persistence — Hyperliquid is the source of truth; we re-read on\n * reload instead of caching across sessions.\n */\nexport function useHyperliquidSetup(\n opts: UseHyperliquidSetupOptions,\n): UseHyperliquidSetupResult {\n const {\n adapter,\n userAddress,\n steps,\n autoLoad = true,\n onComplete,\n onError,\n } = opts;\n const [state, dispatch] = useReducer(reduceSetupState, initialSetupState);\n\n // Refs for stable closures inside async work.\n const adapterRef = useRef(adapter);\n const stepsRef = useRef(steps);\n const onCompleteRef = useRef(onComplete);\n const onErrorRef = useRef(onError);\n adapterRef.current = adapter;\n stepsRef.current = steps;\n onCompleteRef.current = onComplete;\n onErrorRef.current = onError;\n\n const reload = useCallback(async () => {\n if (!userAddress) return;\n dispatch({ type: \"START_LOADING\" });\n try {\n const accountState =\n await adapterRef.current.getAccountState(userAddress);\n const records: StepRecord[] = stepsRef.current.map((step) => ({\n step,\n status: classifyStep(step, accountState),\n }));\n dispatch({ type: \"LOAD_SUCCESS\", accountState, steps: records });\n } catch (e) {\n const err = toError(e);\n dispatch({ type: \"LOAD_ERROR\", error: err.message });\n onErrorRef.current?.(err, {});\n }\n }, [userAddress]);\n\n // Auto-load on first mount or when the user / adapter changes.\n useEffect(() => {\n if (autoLoad && userAddress) {\n void reload();\n }\n }, [autoLoad, userAddress, reload]);\n\n const runStep = useCallback(\n async (index: number) => {\n const record = state.steps[index];\n if (!record) return;\n dispatch({ type: \"RUN_STEP\", index });\n try {\n const result = await invokeAdapter(adapterRef.current, record.step);\n dispatch({\n type: \"STEP_SUCCESS\",\n index,\n txHash: result.txHash,\n accountState: result.state as HyperliquidAccountState | undefined,\n });\n } catch (e) {\n const err = toError(e);\n dispatch({ type: \"STEP_ERROR\", index, error: err.message });\n onErrorRef.current?.(err, { stepId: record.step.id });\n }\n },\n [state.steps],\n );\n\n const runNext = useCallback(async () => {\n const idx = nextRunnableStep(state);\n if (idx == null) return;\n await runStep(idx);\n }, [state, runStep]);\n\n const reset = useCallback(() => dispatch({ type: \"RESET\" }), []);\n\n // Fire `onComplete` exactly once when we transition into `done`.\n const completedRef = useRef(false);\n useEffect(() => {\n if (state.phase === \"done\" && !completedRef.current) {\n completedRef.current = true;\n onCompleteRef.current?.(state);\n } else if (state.phase !== \"done\") {\n completedRef.current = false;\n }\n }, [state]);\n\n return { state, reload, runNext, runStep, reset };\n}\n\nfunction invokeAdapter(\n adapter: IHyperliquidSetupAdapter,\n step: SetupStep,\n): Promise<HyperliquidSetupActionResult> {\n switch (step.id) {\n case \"approveBuilderFee\":\n return adapter.approveBuilderFee(step.params);\n case \"setReferrer\":\n return adapter.setReferrer(step.params);\n case \"updateLeverage\":\n return adapter.updateLeverage(step.params);\n }\n}\n\nfunction toError(e: unknown): Error {\n if (e instanceof Error) return e;\n return new Error(typeof e === \"string\" ? e : \"Unknown error\");\n}\n","export function CoinInfoNotFoundUI() {\n return (\n <div className=\"flex items-center justify-center px-4 py-3 bg-neutral-900 border-b border-neutral-800\">\n <span className=\"text-neutral-400 text-sm\">\n Market data not available\n </span>\n </div>\n );\n}\n","import { Skeleton } from \"@liberfi.io/ui\";\n\nexport function CoinInfoSkeletonsUI() {\n return (\n <div className=\"flex items-center gap-6 px-4 py-3 bg-neutral-900 border-b border-neutral-800\">\n <div className=\"flex items-center gap-3\">\n <Skeleton className=\"h-6 w-20 rounded\" />\n <div className=\"flex items-center gap-2\">\n <Skeleton className=\"h-8 w-28 rounded\" />\n <Skeleton className=\"h-5 w-16 rounded\" />\n </div>\n </div>\n\n <div className=\"h-8 w-px bg-neutral-800\" />\n\n <div className=\"flex items-center gap-6 text-sm\">\n <div className=\"flex flex-col gap-1\">\n <Skeleton className=\"h-3 w-20 rounded\" />\n <Skeleton className=\"h-5 w-16 rounded\" />\n </div>\n\n <div className=\"flex flex-col gap-1\">\n <Skeleton className=\"h-3 w-20 rounded\" />\n <Skeleton className=\"h-5 w-16 rounded\" />\n </div>\n\n <div className=\"flex flex-col gap-1\">\n <Skeleton className=\"h-3 w-24 rounded\" />\n <Skeleton className=\"h-5 w-16 rounded\" />\n </div>\n\n <div className=\"flex flex-col gap-1\">\n <Skeleton className=\"h-3 w-32 rounded\" />\n <div className=\"flex items-center gap-2\">\n <Skeleton className=\"h-5 w-16 rounded\" />\n <Skeleton className=\"h-5 w-20 rounded\" />\n </div>\n </div>\n </div>\n </div>\n );\n}\n","import { useEffect, useState } from \"react\";\nimport { useMarketDataSubscription } from \"../../hooks/useMarketDataSubscription\";\nimport { useMarketQuery } from \"../../hooks/useMarketQuery\";\nimport type { MarketData } from \"../../types\";\n\nexport type UseCoinInfoReturnType = {\n marketData?: MarketData;\n isLoading: boolean;\n fundingCountdown: number;\n};\n\nexport function useCoinInfo(symbol: string): UseCoinInfoReturnType {\n const [marketData, setMarketData] = useState<MarketData | undefined>();\n const [fundingCountdown, setFundingCountdown] = useState<number>(0);\n\n const { data: initialData, isPending } = useMarketQuery({ symbol });\n\n const { data: realtimeData, isConnected } =\n useMarketDataSubscription<MarketData>({\n type: \"ticker\",\n symbol,\n enabled: !!initialData,\n });\n\n useEffect(() => {\n if (!initialData) return;\n setMarketData(initialData);\n }, [initialData]);\n\n useEffect(() => {\n if (!realtimeData) return;\n\n const normalized = normalizeRealtimeTickerPayload(realtimeData, symbol);\n if (!normalized) return;\n\n setMarketData((previous) =>\n buildMarketData(previous ?? initialData ?? undefined, normalized, symbol),\n );\n }, [realtimeData, initialData, symbol]);\n\n useEffect(() => {\n const calculateCountdown = () => {\n const now = Date.now();\n const eightHours = 8 * 60 * 60 * 1000;\n const remainder = now % eightHours;\n const timeUntilNext = eightHours - remainder;\n return Math.floor(timeUntilNext / 1000);\n };\n\n setFundingCountdown(calculateCountdown());\n\n const interval = setInterval(() => {\n setFundingCountdown(calculateCountdown());\n }, 1000);\n\n return () => clearInterval(interval);\n }, []);\n\n return {\n marketData,\n isLoading: isPending,\n fundingCountdown,\n };\n}\n\nfunction normalizeRealtimeTickerPayload(\n payload: unknown,\n symbol: string,\n): Partial<MarketData> | null {\n if (Array.isArray(payload)) {\n const matched = payload.find((item) => {\n if (!item || typeof item !== \"object\") return false;\n return (item as { symbol?: string }).symbol === symbol;\n });\n return matched && typeof matched === \"object\"\n ? (matched as Partial<MarketData>)\n : null;\n }\n\n if (payload && typeof payload === \"object\") {\n return payload as Partial<MarketData>;\n }\n\n return null;\n}\n\nfunction toNumberOr(value: unknown, fallback: number): number {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return value;\n }\n return fallback;\n}\n\nfunction buildMarketData(\n base: MarketData | undefined,\n patch: Partial<MarketData>,\n symbol: string,\n): MarketData {\n return {\n symbol: patch.symbol ?? base?.symbol ?? symbol,\n price: toNumberOr(patch.price, base?.price ?? 0),\n change24h: toNumberOr(patch.change24h, base?.change24h ?? 0),\n volume24h: toNumberOr(patch.volume24h, base?.volume24h ?? 0),\n fundingRate: toNumberOr(patch.fundingRate, base?.fundingRate ?? 0),\n openInterest: toNumberOr(patch.openInterest, base?.openInterest ?? 0),\n markPrice: toNumberOr(patch.markPrice, base?.markPrice ?? 0),\n indexPrice:\n typeof patch.indexPrice === \"number\" && Number.isFinite(patch.indexPrice)\n ? patch.indexPrice\n : base?.indexPrice,\n high24h:\n typeof patch.high24h === \"number\" && Number.isFinite(patch.high24h)\n ? patch.high24h\n : base?.high24h,\n low24h:\n typeof patch.low24h === \"number\" && Number.isFinite(patch.low24h)\n ? patch.low24h\n : base?.low24h,\n };\n}\n","import { cn } from \"@liberfi.io/ui\";\nimport type { MarketData } from \"../../types\";\n\nexport type CoinInfoUIProps = {\n marketData: MarketData;\n fundingCountdown: number;\n};\n\nfunction formatCountdown(seconds: number): string {\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const secs = seconds % 60;\n return `${String(hours).padStart(2, \"0\")}:${String(minutes).padStart(2, \"0\")}:${String(secs).padStart(2, \"0\")}`;\n}\n\nfunction formatNumber(num: number | undefined, decimals: number = 2): string {\n if (typeof num !== \"number\" || !Number.isFinite(num)) {\n return \"-\";\n }\n if (num >= 1e9) {\n return `$${(num / 1e9).toFixed(decimals)}B`;\n }\n if (num >= 1e6) {\n return `$${(num / 1e6).toFixed(decimals)}M`;\n }\n if (num >= 1e3) {\n return `$${(num / 1e3).toFixed(decimals)}K`;\n }\n return `$${num.toFixed(decimals)}`;\n}\n\nfunction formatPrice(price: number | undefined): string {\n if (typeof price !== \"number\" || !Number.isFinite(price)) {\n return \"-\";\n }\n if (price >= 1000) {\n return price.toLocaleString(\"en-US\", {\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n });\n }\n if (price >= 1) {\n return price.toLocaleString(\"en-US\", {\n minimumFractionDigits: 2,\n maximumFractionDigits: 4,\n });\n }\n return price.toFixed(6);\n}\n\nexport function CoinInfoUI({ marketData, fundingCountdown }: CoinInfoUIProps) {\n const {\n symbol,\n price,\n change24h,\n indexPrice,\n volume24h,\n openInterest,\n fundingRate,\n } = marketData;\n\n const safeChange24h =\n typeof change24h === \"number\" && Number.isFinite(change24h) ? change24h : 0;\n const safeFundingRate =\n typeof fundingRate === \"number\" && Number.isFinite(fundingRate)\n ? fundingRate\n : 0;\n const isPositiveChange = safeChange24h >= 0;\n const changePercent = safeChange24h.toFixed(2);\n\n return (\n <div\n className=\"flex items-center px-4\"\n style={{ minHeight: 64, maxHeight: 64, gap: 24 }}\n >\n <div className=\"flex items-baseline\" style={{ gap: 8 }}>\n <span\n style={{\n fontSize: 18,\n fontWeight: 500,\n lineHeight: \"23px\",\n letterSpacing: \"-0.36px\",\n color: \"#ffffff\",\n }}\n >\n {formatPrice(price)}\n </span>\n <span\n style={{\n fontSize: 12,\n fontWeight: 400,\n lineHeight: \"16px\",\n color: isPositiveChange ? \"#C7FF2E\" : \"#F76816\",\n }}\n >\n {isPositiveChange ? \"+\" : \"\"}\n {changePercent}%\n </span>\n </div>\n\n <div className=\"flex items-center\" style={{ gap: 24 }}>\n <div className=\"flex flex-col\">\n <span\n style={{\n fontSize: 12,\n color: \"#b5b5b5\",\n lineHeight: \"16px\",\n letterSpacing: \"-0.12px\",\n }}\n >\n Oracle Price\n </span>\n <span\n style={{\n fontSize: 13,\n fontWeight: 400,\n lineHeight: \"17px\",\n color: \"#ffffff\",\n }}\n >\n {indexPrice ? formatPrice(indexPrice) : \"-\"}\n </span>\n </div>\n\n <div className=\"flex flex-col\">\n <span\n style={{\n fontSize: 12,\n color: \"#b5b5b5\",\n lineHeight: \"16px\",\n letterSpacing: \"-0.12px\",\n }}\n >\n 24h Volume\n </span>\n <span\n style={{\n fontSize: 13,\n fontWeight: 400,\n lineHeight: \"17px\",\n color: \"#ffffff\",\n }}\n >\n {formatNumber(volume24h, 0)}\n </span>\n </div>\n\n <div className=\"flex flex-col\">\n <span\n style={{\n fontSize: 12,\n color: \"#b5b5b5\",\n lineHeight: \"16px\",\n letterSpacing: \"-0.12px\",\n }}\n >\n Open Interest\n </span>\n <span\n style={{\n fontSize: 13,\n fontWeight: 400,\n lineHeight: \"17px\",\n color: \"#ffffff\",\n }}\n >\n {formatNumber(openInterest * (marketData.markPrice || price))}\n </span>\n </div>\n\n <div className=\"flex flex-col\">\n <span\n style={{\n fontSize: 12,\n color: \"#b5b5b5\",\n lineHeight: \"16px\",\n letterSpacing: \"-0.12px\",\n }}\n >\n Funding / Countdown\n </span>\n <div className=\"flex items-center\" style={{ gap: 8 }}>\n <span\n style={{\n fontSize: 13,\n lineHeight: \"17px\",\n color: safeFundingRate >= 0 ? \"#C7FF2E\" : \"#F76816\",\n }}\n >\n {(safeFundingRate * 100).toFixed(5)}%\n </span>\n <span\n style={{\n fontSize: 13,\n lineHeight: \"17px\",\n color: \"#ffffff\",\n }}\n >\n {formatCountdown(fundingCountdown)}\n </span>\n </div>\n </div>\n </div>\n </div>\n );\n}\n","import { CoinInfoNotFoundUI } from \"./coin-info-notfound.ui\";\nimport { CoinInfoSkeletonsUI } from \"./coin-info-skeletons.ui\";\nimport { useCoinInfo } from \"./coin-info.script\";\nimport { CoinInfoUI } from \"./coin-info.ui\";\n\nexport type CoinInfoWidgetProps = {\n symbol: string;\n};\n\nexport function CoinInfoWidget({ symbol }: CoinInfoWidgetProps) {\n const { marketData, isLoading, fundingCountdown } = useCoinInfo(symbol);\n\n if (isLoading) {\n return <CoinInfoSkeletonsUI />;\n }\n\n if (!marketData) {\n return <CoinInfoNotFoundUI />;\n }\n\n return (\n <CoinInfoUI marketData={marketData} fundingCountdown={fundingCountdown} />\n );\n}\n","import { useEffect, useMemo, useState } from \"react\";\nimport { useCoinsQuery } from \"../../hooks/useCoinsQuery\";\nimport { useMarketsQuery } from \"../../hooks/useMarketsQuery\";\nimport type { MarketData } from \"../../types\";\n\nexport type UseSearchCoinsScriptParams = {\n onSelectCoin?: (symbol: string) => void;\n};\n\nexport type UseSearchCoinsScriptResult = {\n coins: MarketData[];\n isLoading: boolean;\n searchQuery: string;\n setSearchQuery: (query: string) => void;\n filteredCoins: MarketData[];\n handleSelectCoin: (symbol: string) => void;\n};\n\nexport function useSearchCoinsScript({\n onSelectCoin,\n}: UseSearchCoinsScriptParams = {}): UseSearchCoinsScriptResult {\n const [searchQuery, setSearchQuery] = useState<string>(\"\");\n const [coins, setCoins] = useState<MarketData[]>([]);\n\n const { data: coinSymbols, isPending: isLoadingSymbols } = useCoinsQuery();\n\n const { data: marketsData, isPending: isLoadingMarkets } = useMarketsQuery(\n { symbols: coinSymbols },\n { enabled: !!coinSymbols && coinSymbols.length > 0 },\n );\n\n useEffect(() => {\n if (marketsData) {\n setCoins(marketsData);\n }\n }, [marketsData]);\n\n const filteredCoins = useMemo(() => {\n if (!searchQuery.trim()) {\n return coins;\n }\n\n const query = searchQuery.toLowerCase().trim();\n return coins.filter((coin) => coin.symbol.toLowerCase().includes(query));\n }, [coins, searchQuery]);\n\n const handleSelectCoin = (symbol: string) => {\n onSelectCoin?.(symbol);\n };\n\n return {\n coins,\n isLoading: isLoadingSymbols || isLoadingMarkets,\n searchQuery,\n setSearchQuery,\n filteredCoins,\n handleSelectCoin,\n };\n}\n","import { SearchIcon } from \"@liberfi.io/ui\";\nimport type { MarketData } from \"../../types\";\n\nexport type SearchCoinsUIProps = {\n coins: MarketData[];\n searchQuery: string;\n onSearchChange: (query: string) => void;\n onSelectCoin: (symbol: string) => void;\n isLoading?: boolean;\n};\n\nfunction formatNumber(num: number, decimals: number = 2): string {\n if (num >= 1e9) {\n return `$${(num / 1e9).toFixed(decimals)}B`;\n }\n if (num >= 1e6) {\n return `$${(num / 1e6).toFixed(decimals)}M`;\n }\n if (num >= 1e3) {\n return `$${(num / 1e3).toFixed(decimals)}K`;\n }\n return `$${num.toFixed(decimals)}`;\n}\n\nfunction formatPrice(price: number): string {\n if (price >= 1000) {\n return price.toFixed(2);\n }\n if (price >= 1) {\n return price.toFixed(4);\n }\n return price.toFixed(6);\n}\n\nexport function SearchCoinsUI({\n coins,\n searchQuery,\n onSearchChange,\n onSelectCoin,\n isLoading,\n}: SearchCoinsUIProps) {\n return (\n <div\n className=\"flex flex-col\"\n style={{ backgroundColor: \"#1A1A1A\", flex: \"1 1 0\", minHeight: 0 }}\n >\n <div style={{ padding: \"16px 16px 12px\" }}>\n <div\n className=\"flex items-center\"\n style={{\n height: 32,\n border: \"1px solid #2a2a2a\",\n borderRadius: 4,\n padding: \"0 6px 0 12px\",\n gap: 8,\n }}\n >\n <SearchIcon\n className=\"flex-shrink-0\"\n style={{ width: 14, height: 14, color: \"#6b6b6b\" }}\n />\n <input\n type=\"text\"\n placeholder=\"Search coins...\"\n value={searchQuery}\n onChange={(e) => onSearchChange(e.target.value)}\n className=\"flex-1 bg-transparent outline-none\"\n style={{ fontSize: 12, color: \"#ffffff\", border: \"none\" }}\n />\n </div>\n </div>\n\n <div className=\"flex-1 overflow-auto\">\n {/* Header */}\n <div\n className=\"flex items-center\"\n style={{\n height: 28,\n padding: \"0 16px\",\n borderBottom: \"1px solid rgba(42,42,42,0.5)\",\n position: \"sticky\",\n top: 0,\n backgroundColor: \"#1A1A1A\",\n zIndex: 1,\n }}\n >\n <span style={{ flex: \"0 0 140px\", fontSize: 12, color: \"#6b6b6b\" }}>\n Token\n </span>\n <span\n style={{\n flex: \"0 0 100px\",\n fontSize: 12,\n color: \"#6b6b6b\",\n textAlign: \"right\",\n }}\n >\n Last Price\n </span>\n <span\n style={{\n flex: \"0 0 120px\",\n fontSize: 12,\n color: \"#6b6b6b\",\n textAlign: \"right\",\n }}\n >\n 24h Change\n </span>\n <span\n style={{\n flex: \"0 0 100px\",\n fontSize: 12,\n color: \"#6b6b6b\",\n textAlign: \"right\",\n }}\n >\n 8h Funding\n </span>\n <span\n style={{\n flex: \"0 0 100px\",\n fontSize: 12,\n color: \"#6b6b6b\",\n textAlign: \"right\",\n }}\n >\n 24h Volume\n </span>\n <span\n style={{\n flex: \"1\",\n fontSize: 12,\n color: \"#6b6b6b\",\n textAlign: \"right\",\n }}\n >\n Open Interest\n </span>\n </div>\n\n {/* Rows */}\n {isLoading ? (\n <div\n className=\"flex items-center justify-center\"\n style={{ height: 100 }}\n >\n <span style={{ fontSize: 12, color: \"#6b6b6b\" }}>Loading...</span>\n </div>\n ) : coins.length === 0 ? (\n <div\n className=\"flex items-center justify-center\"\n style={{ height: 100 }}\n >\n <span style={{ fontSize: 12, color: \"#6b6b6b\" }}>\n {searchQuery ? \"No coins found\" : \"No coins available\"}\n </span>\n </div>\n ) : (\n coins.map((coin) => {\n const isPositiveChange = coin.change24h >= 0;\n const changePercent = coin.change24h.toFixed(2);\n const fundingPercent = (coin.fundingRate * 100).toFixed(4);\n const isPositiveFunding = coin.fundingRate >= 0;\n const tokenName = coin.symbol.split(\"-\")[0];\n\n return (\n <div\n key={coin.symbol}\n className=\"flex items-center cursor-pointer transition-colors\"\n style={{\n height: 36,\n padding: \"0 16px\",\n borderBottom: \"1px solid rgba(42,42,42,0.5)\",\n }}\n onClick={() => onSelectCoin(coin.symbol)}\n onMouseEnter={(e) => {\n (e.currentTarget as HTMLDivElement).style.backgroundColor =\n \"rgba(255,255,255,0.03)\";\n }}\n onMouseLeave={(e) => {\n (e.currentTarget as HTMLDivElement).style.backgroundColor =\n \"transparent\";\n }}\n >\n <div\n className=\"flex items-center\"\n style={{ flex: \"0 0 140px\", gap: 8 }}\n >\n <img\n src={`https://app.hyperliquid.xyz/coins/${tokenName}.svg`}\n alt={tokenName}\n className=\"rounded-full\"\n style={{ width: 20, height: 20 }}\n onError={(e) => {\n const target = e.target as HTMLImageElement;\n target.style.display = \"none\";\n }}\n />\n <span\n style={{ fontSize: 12, fontWeight: 500, color: \"#ffffff\" }}\n >\n {tokenName}\n </span>\n </div>\n <span\n style={{\n flex: \"0 0 100px\",\n fontSize: 12,\n color: \"#ffffff\",\n textAlign: \"right\",\n }}\n >\n {formatPrice(coin.price)}\n </span>\n <span\n style={{\n flex: \"0 0 120px\",\n fontSize: 12,\n fontWeight: 500,\n color: isPositiveChange ? \"#C7FF2E\" : \"#F76816\",\n textAlign: \"right\",\n }}\n >\n {isPositiveChange ? \"+\" : \"\"}\n {changePercent}%\n </span>\n <span\n style={{\n flex: \"0 0 100px\",\n fontSize: 12,\n color: isPositiveFunding ? \"#C7FF2E\" : \"#F76816\",\n textAlign: \"right\",\n }}\n >\n {fundingPercent}%\n </span>\n <span\n style={{\n flex: \"0 0 100px\",\n fontSize: 12,\n color: \"#b5b5b5\",\n textAlign: \"right\",\n }}\n >\n {formatNumber(coin.volume24h)}\n </span>\n <span\n style={{\n flex: \"1\",\n fontSize: 12,\n color: \"#b5b5b5\",\n textAlign: \"right\",\n }}\n >\n {formatNumber(coin.openInterest * coin.price)}\n </span>\n </div>\n );\n })\n )}\n </div>\n </div>\n );\n}\n","import { useSearchCoinsScript } from \"./search-coins.script\";\nimport { SearchCoinsUI } from \"./search-coins.ui\";\n\nexport type SearchCoinsWidgetProps = {\n onSelectCoin?: (symbol: string) => void;\n className?: string;\n};\n\nexport function SearchCoinsWidget({\n onSelectCoin,\n className,\n}: SearchCoinsWidgetProps) {\n const {\n filteredCoins,\n isLoading,\n searchQuery,\n setSearchQuery,\n handleSelectCoin,\n } = useSearchCoinsScript({ onSelectCoin });\n\n return (\n <div\n className={className}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n flex: \"1 1 0\",\n minHeight: 0,\n overflow: \"hidden\",\n }}\n >\n <SearchCoinsUI\n coins={filteredCoins}\n searchQuery={searchQuery}\n onSearchChange={setSearchQuery}\n onSelectCoin={handleSelectCoin}\n isLoading={isLoading}\n />\n </div>\n );\n}\n","import { useEffect, useMemo, useState } from \"react\";\nimport { useMarketDataSubscription } from \"../../hooks/useMarketDataSubscription\";\nimport { useOrderBookQuery } from \"../../hooks/useOrderBookQuery\";\nimport type {\n OrderBook,\n OrderBookAggregationOptions,\n OrderBookLevel,\n} from \"../../types\";\n\nexport type PriceLevel = OrderBookLevel & {\n total: number;\n percentage: number;\n};\n\nexport type UseOrderBookScriptParams = {\n symbol: string;\n maxLevel?: number;\n /**\n * Initial price-bucket size. Defaults to `1` which matches major perpetual\n * pairs like BTC-USDC. Callers can change it dynamically via the returned\n * `setPrecision`.\n */\n precision?: number;\n};\n\n/**\n * Map a desired bucket step (in quote currency, e.g. USD) to the closest\n * Hyperliquid `l2Book` aggregation params at the given reference price.\n *\n * Hyperliquid only emits 20 levels per side per snapshot. To make those 20\n * levels span a wide enough range (e.g. ±$20k for a $1000 step), we ask the\n * server to pre-aggregate via `nSigFigs` / `mantissa`. This function picks the\n * coarsest server step that is still ≤ the user's chosen step, so any\n * remaining mismatch is corrected by client-side `aggregateByPrecision`\n * (which is idempotent when the steps already match).\n *\n * Examples (BTC, price ≈ $80,740):\n * step $1 → { nSigFigs: 5 } (Hyperliquid step $1)\n * step $2 → { nSigFigs: 5, mantissa: 2 } (Hyperliquid step $2)\n * step $5 → { nSigFigs: 5, mantissa: 5 } (Hyperliquid step $5)\n * step $10 → { nSigFigs: 4 } (Hyperliquid step $10)\n * step $100 → { nSigFigs: 3 } (Hyperliquid step $100)\n * step $1000 → { nSigFigs: 2 } (Hyperliquid step $1000)\n *\n * Examples (ETH, price ≈ $4,000):\n * step $1 → { nSigFigs: 4 } (Hyperliquid step $1)\n * step $2 → { nSigFigs: 4 } + client agg (server $1, client → $2)\n * step $10 → { nSigFigs: 3 } (Hyperliquid step $10)\n *\n * @param price Reference price (mid / mark) used to compute the magnitude.\n * @param step Desired bucket size in the same quote currency as `price`.\n * @returns Aggregation hint, or empty object when inputs are invalid.\n */\nexport function aggregationFromStep(\n price: number,\n step: number,\n): OrderBookAggregationOptions {\n if (\n !Number.isFinite(price) ||\n !Number.isFinite(step) ||\n price <= 0 ||\n step <= 0\n ) {\n return {};\n }\n\n // 10^k is the place value of `price`'s most-significant digit.\n // E.g. price=80740 → log10≈4.907 → k=4 (price sits in the 10^4 = \"tens of\n // thousands\" decade).\n const k = Math.floor(Math.log10(price));\n\n // Step produced by Hyperliquid for nSigFigs=n at this price magnitude:\n // server step = mantissa * 10^(k - n + 1) (mantissa defaults to 1)\n // We enumerate the supported (n, mantissa) tuples and pick the one whose\n // server step is the largest value ≤ user step.\n const candidates: Array<{\n nSigFigs: 2 | 3 | 4 | 5;\n mantissa?: 1 | 2 | 5;\n step: number;\n }> = [\n { nSigFigs: 2, step: Math.pow(10, k - 1) },\n { nSigFigs: 3, step: Math.pow(10, k - 2) },\n { nSigFigs: 4, step: Math.pow(10, k - 3) },\n { nSigFigs: 5, mantissa: 5, step: 5 * Math.pow(10, k - 4) },\n { nSigFigs: 5, mantissa: 2, step: 2 * Math.pow(10, k - 4) },\n { nSigFigs: 5, step: Math.pow(10, k - 4) },\n ];\n\n // Tolerance to absorb floating-point error from log10 / pow.\n const eps = 1e-9;\n\n let best: (typeof candidates)[number] | null = null;\n for (const c of candidates) {\n if (c.step <= step + eps && (!best || c.step > best.step)) {\n best = c;\n }\n }\n\n // If even nSigFigs=5 (the finest server bucket) is still coarser than the\n // user's requested step, fall back to it — we cannot ask Hyperliquid for a\n // finer grid, but the client will still aggregate further if needed.\n if (!best) {\n return { nSigFigs: 5 };\n }\n\n if (best.mantissa && best.mantissa !== 1) {\n return { nSigFigs: best.nSigFigs, mantissa: best.mantissa };\n }\n return { nSigFigs: best.nSigFigs };\n}\n\nexport type UseOrderBookScriptResult = {\n bids: PriceLevel[];\n asks: PriceLevel[];\n /** Raw `bestAsk - bestBid` after aggregation. */\n spread: number;\n /** `spread / bestBid * 100`. */\n spreadPercentage: number;\n isLoading: boolean;\n precision: number;\n setPrecision: (precision: number) => void;\n};\n\n/**\n * Aggregate raw order-book levels into discrete price buckets of size\n * `precision`.\n *\n * To keep the spread visually consistent with the chosen aggregation step we\n * round in opposite directions for the two sides:\n *\n * - ask (sell) levels round UP (`ceil`) → bucket >= raw price\n * - bid (buy) levels round DOWN (`floor`) → bucket <= raw price\n *\n * This is the standard convention used by Hyperliquid / dYdX / Axiom and\n * guarantees `bestAsk - bestBid >= step`, i.e. the visible spread never\n * collapses into a single bucket where the two sides would overlap.\n */\nfunction aggregateByPrecision(\n levels: OrderBookLevel[],\n precision: number,\n side: \"ask\" | \"bid\",\n): OrderBookLevel[] {\n if (precision <= 0) return levels;\n\n const aggregated = new Map<number, OrderBookLevel>();\n const round = side === \"ask\" ? Math.ceil : Math.floor;\n\n levels.forEach((level) => {\n const roundedPrice = round(level.price / precision) * precision;\n\n const existing = aggregated.get(roundedPrice);\n if (existing) {\n existing.quantity += level.quantity;\n if (level.count) {\n existing.count = (existing.count || 0) + level.count;\n }\n } else {\n aggregated.set(roundedPrice, {\n price: roundedPrice,\n quantity: level.quantity,\n count: level.count,\n });\n }\n });\n\n return Array.from(aggregated.values());\n}\n\nfunction calculateTotalsAndPercentages(levels: OrderBookLevel[]): PriceLevel[] {\n let total = 0;\n const withTotals = levels.map((level) => {\n const usdAmount = level.quantity * level.price;\n total += usdAmount;\n return {\n ...level,\n quantity: usdAmount,\n total,\n percentage: 0,\n };\n });\n\n const maxTotal = total;\n return withTotals.map((level) => ({\n ...level,\n percentage: maxTotal > 0 ? (level.total / maxTotal) * 100 : 0,\n }));\n}\n\nexport function useOrderBookScript({\n symbol,\n maxLevel = 20,\n precision: initialPrecision = 1,\n}: UseOrderBookScriptParams): UseOrderBookScriptResult {\n const [orderBook, setOrderBook] = useState<OrderBook | null>(null);\n const [precision, setPrecision] = useState<number>(initialPrecision);\n\n // Keep precision in sync if the caller changes the controlled prop.\n useEffect(() => {\n setPrecision(initialPrecision);\n }, [initialPrecision]);\n\n // First REST call seeds the book without venue aggregation. Its only role\n // here is to give us a reference price so we can compute the right\n // (nSigFigs, mantissa) for the live subscription.\n const { data: initialData, isPending } = useOrderBookQuery({\n symbol,\n maxLevel,\n });\n\n // Reference price ≈ mid of best bid / best ask. Falls back to whichever\n // side is available. Locked to the price *magnitude* (decade) so it stays\n // stable across price ticks — re-subscribing on every $1 move would be\n // catastrophic.\n const priceMagnitude = useMemo(() => {\n const bestBid = orderBook?.bids[0]?.price ?? initialData?.bids[0]?.price;\n const bestAsk = orderBook?.asks[0]?.price ?? initialData?.asks[0]?.price;\n const ref =\n bestBid && bestAsk ? (bestBid + bestAsk) / 2 : (bestAsk ?? bestBid ?? 0);\n return ref > 0 ? Math.floor(Math.log10(ref)) : null;\n }, [orderBook, initialData]);\n\n // Aggregation hint sent to the WS subscription. Only depends on the chosen\n // step + price magnitude, so it's stable and re-subscribes only on real\n // changes.\n const aggregation = useMemo<OrderBookAggregationOptions | undefined>(() => {\n if (priceMagnitude === null) return undefined;\n const referencePrice = Math.pow(10, priceMagnitude);\n return aggregationFromStep(referencePrice, precision);\n }, [precision, priceMagnitude]);\n\n // Throttle pushes to ~10 Hz. Hyperliquid emits l2Book updates faster than\n // that on active markets, but the human eye can't tell the difference and\n // React reconciliation of 40 rows per push at 30 Hz wastes CPU. The\n // trailing-edge throttle in {@link useMarketDataSubscription} keeps the\n // latest snapshot, so users still see the freshest data on each tick —\n // just less often.\n const { data: realtimeData } = useMarketDataSubscription<OrderBook>({\n type: \"orderBook\",\n symbol,\n enabled: !!initialData,\n aggregation,\n throttleMs: 100,\n });\n\n useEffect(() => {\n if (realtimeData) {\n setOrderBook(realtimeData);\n } else if (initialData) {\n setOrderBook(initialData);\n }\n }, [realtimeData, initialData]);\n\n const processedData = useMemo(() => {\n if (!orderBook) {\n return {\n bids: [],\n asks: [],\n spread: 0,\n spreadPercentage: 0,\n };\n }\n\n const aggregatedBids = aggregateByPrecision(\n orderBook.bids,\n precision,\n \"bid\",\n );\n const aggregatedAsks = aggregateByPrecision(\n orderBook.asks,\n precision,\n \"ask\",\n );\n\n const sortedBids = aggregatedBids\n .sort((a, b) => b.price - a.price)\n .slice(0, maxLevel);\n\n const sortedAsks = aggregatedAsks\n .sort((a, b) => a.price - b.price)\n .slice(0, maxLevel);\n\n const bids = calculateTotalsAndPercentages(sortedBids);\n const asks = calculateTotalsAndPercentages(sortedAsks);\n\n const bestBid = bids[0]?.price || 0;\n const bestAsk = asks[0]?.price || 0;\n const spread = bestAsk - bestBid;\n const spreadPercentage = bestBid > 0 ? (spread / bestBid) * 100 : 0;\n\n return {\n bids,\n asks,\n spread,\n spreadPercentage,\n };\n }, [orderBook, precision, maxLevel]);\n\n return {\n ...processedData,\n isLoading: isPending,\n precision,\n setPrecision,\n };\n}\n","import type { CSSProperties } from \"react\";\nimport { memo, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { PriceLevel } from \"./orderbook.script\";\n\n// ---------------------------------------------------------------------------\n// Static styles hoisted to module scope so they are NOT reallocated on every\n// render. The order book re-renders at the WebSocket push rate (~10–30 Hz),\n// so allocating fresh style objects per render is wasted GC pressure and\n// breaks shallow-equality optimisations like React.memo.\n// ---------------------------------------------------------------------------\n\n/**\n * Thin, subtle scrollbar for the asks/bids panes. Firefox uses the\n * standard properties; Chromium/Safari fall back to their default scrollbar\n * which is already unobtrusive on a dark background. We avoid `::-webkit-`\n * pseudo selectors here so the file stays a pure inline-style component\n * (no global CSS leakage into consumer apps).\n */\nconst ORDERBOOK_SCROLL_STYLE: CSSProperties = {\n scrollbarWidth: \"thin\",\n scrollbarColor: \"rgba(63,63,70,0.6) transparent\",\n};\n\nconst CONTAINER_STYLE: CSSProperties = {\n backgroundColor: \"#000000\",\n fontSize: 11,\n};\n\nconst HEADER_STYLE: CSSProperties = {\n height: 28,\n minHeight: 28,\n padding: \"0 16px\",\n gap: 16,\n color: \"#6b6b6b\",\n fontSize: 11,\n};\n\nconst HEADER_CELL_STYLE: CSSProperties = { flex: \"1 1 0%\" };\n\nconst ROW_STYLE: CSSProperties = {\n height: 22,\n minHeight: 22,\n maxHeight: 22,\n padding: \"0 16px\",\n gap: 16,\n fontSize: 11,\n};\n\n// Per-side row decoration (background gradient + price color) is constant.\n// Pre-compute both branches so the render path just picks one by reference.\nconst ASK_BAR_STYLE_BASE: CSSProperties = {\n height: 20,\n background: \"linear-gradient(to right, rgba(247,104,22,0), #F76816)\",\n opacity: 0.15,\n};\nconst BID_BAR_STYLE_BASE: CSSProperties = {\n height: 20,\n background: \"linear-gradient(to right, rgba(199,255,46,0), #C7FF2E)\",\n opacity: 0.15,\n};\nconst ASK_PRICE_STYLE: CSSProperties = { color: \"#F76816\", fontWeight: 400 };\nconst BID_PRICE_STYLE: CSSProperties = { color: \"#C7FF2E\", fontWeight: 400 };\nconst ROW_CELL_STYLE: CSSProperties = { flex: \"1 1 0%\", color: \"#ffffff\" };\nconst ROW_PRICE_CELL_STYLE: CSSProperties = { flex: \"1 1 0%\" };\n\nconst SPREAD_BAR_STYLE: CSSProperties = {\n height: 24,\n minHeight: 24,\n padding: \"0 16px\",\n backgroundColor: \"rgba(26,26,26,0.5)\",\n};\nconst SPREAD_BAR_INNER_STYLE: CSSProperties = {\n gap: 12,\n fontSize: 12,\n color: \"#ffffff\",\n};\nconst SPREAD_LABEL_STYLE: CSSProperties = { color: \"#ffffff\" };\nconst SPREAD_VALUE_STYLE: CSSProperties = {\n color: \"#ffffff\",\n fontWeight: 500,\n};\nconst SPREAD_BUTTON_STYLE: CSSProperties = {\n color: \"#ffffff\",\n fontWeight: 400,\n background: \"none\",\n border: \"none\",\n padding: 0,\n gap: 4,\n};\nconst SPREAD_DROPDOWN_STYLE: CSSProperties = {\n top: \"calc(100% + 4px)\",\n minWidth: 64,\n backgroundColor: \"#0a0a0a\",\n border: \"1px solid rgba(63,63,70,0.6)\",\n borderRadius: 6,\n padding: 4,\n boxShadow: \"0 4px 16px rgba(0,0,0,0.5)\",\n};\n\nconst SPREAD_OPTION_STYLE: CSSProperties = {\n padding: \"4px 10px\",\n fontSize: 12,\n color: \"#ffffff\",\n background: \"transparent\",\n border: \"none\",\n borderRadius: 4,\n textAlign: \"left\",\n};\nconst SPREAD_OPTION_SELECTED_STYLE: CSSProperties = {\n ...SPREAD_OPTION_STYLE,\n color: \"#C7FF2E\",\n};\n\nexport type OrderBookUIProps = {\n bids: PriceLevel[];\n asks: PriceLevel[];\n /** `(bestAsk - bestBid) / bestBid * 100`, rendered next to the precision dropdown. */\n spreadPercentage: number;\n /** Currently selected aggregation step. */\n precision: number;\n /** Available steps shown in the dropdown. */\n precisionOptions: readonly number[];\n /** Notify parent when the user picks a new step. */\n onPrecisionChange: (precision: number) => void;\n onPriceClick?: (price: number) => void;\n};\n\nfunction formatPrice(price: number): string {\n if (price >= 1000) {\n return price.toLocaleString(\"en-US\", {\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n });\n }\n if (price >= 1) {\n return price.toLocaleString(\"en-US\", {\n minimumFractionDigits: 2,\n maximumFractionDigits: 4,\n });\n }\n return price.toFixed(6);\n}\n\nfunction formatQuantity(qty: number): string {\n return Math.round(qty).toLocaleString(\"en-US\");\n}\n\n/** Format the precision step shown in the dropdown trigger and items. */\nfunction formatPrecision(value: number): string {\n if (value >= 1) {\n return value.toLocaleString(\"en-US\", {\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n });\n }\n return value.toString();\n}\n\ntype OBRowProps = {\n price: number;\n quantity: number;\n total: number;\n percentage: number;\n side: \"ask\" | \"bid\";\n /**\n * Forwarded from `OrderBookUI`. Passing the raw callback (instead of a\n * `() => onPriceClick(price)` wrapper from the parent) lets the parent's\n * function reference stay stable across renders, which in turn lets\n * {@link React.memo} on this component skip re-renders for rows whose\n * price/quantity/total/percentage have not changed.\n */\n onPriceClick?: (price: number) => void;\n};\n\nconst OBRow = memo(\n function OBRow({\n price,\n quantity,\n total,\n percentage,\n side,\n onPriceClick,\n }: OBRowProps) {\n const isAsk = side === \"ask\";\n\n // Per-render allocation is unavoidable here because `width` depends on\n // the row's percentage. Keeping every other style static (see\n // ASK_BAR_STYLE_BASE / BID_BAR_STYLE_BASE) limits the cost to one tiny\n // object per visible row per push.\n const barStyle: CSSProperties = useMemo(\n () =>\n isAsk\n ? { ...ASK_BAR_STYLE_BASE, width: `${percentage}%` }\n : { ...BID_BAR_STYLE_BASE, width: `${percentage}%` },\n [isAsk, percentage],\n );\n\n const handleClick = useMemo(\n () => (onPriceClick ? () => onPriceClick(price) : undefined),\n [onPriceClick, price],\n );\n\n return (\n <div\n className=\"relative flex items-center cursor-pointer hover:bg-white/5 transition-colors\"\n style={ROW_STYLE}\n onClick={handleClick}\n >\n <div className=\"absolute left-0 top-0\" style={barStyle} />\n <div\n className=\"relative z-10 flex items-center\"\n style={ROW_PRICE_CELL_STYLE}\n >\n <span style={isAsk ? ASK_PRICE_STYLE : BID_PRICE_STYLE}>\n {formatPrice(price)}\n </span>\n </div>\n <div\n className=\"relative z-10 flex items-center justify-end\"\n style={ROW_CELL_STYLE}\n >\n {formatQuantity(quantity)}\n </div>\n <div\n className=\"relative z-10 flex items-center justify-end\"\n style={ROW_CELL_STYLE}\n >\n {formatQuantity(total)}\n </div>\n </div>\n );\n },\n // Custom equality: ignore object identity, compare the data fields React\n // actually renders. `onPriceClick` is treated as stable by reference (the\n // parent should `useCallback`/pass a stable handler).\n (prev, next) =>\n prev.price === next.price &&\n prev.quantity === next.quantity &&\n prev.total === next.total &&\n prev.percentage === next.percentage &&\n prev.side === next.side &&\n prev.onPriceClick === next.onPriceClick,\n);\n\n/**\n * Spread bar with precision step dropdown. Mirrors Axiom's design:\n *\n * Spread: [ 1 ▾ ] 0.001%\n *\n * Clicking the dropdown opens a vertical list of available steps. The actual\n * spread value is implicit (best ask - best bid is one step after\n * aggregation) so we only show the percentage on the right.\n */\nfunction SpreadBar({\n spreadPercentage,\n precision,\n precisionOptions,\n onPrecisionChange,\n}: {\n spreadPercentage: number;\n precision: number;\n precisionOptions: readonly number[];\n onPrecisionChange: (precision: number) => void;\n}) {\n const [open, setOpen] = useState(false);\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n\n // Close on outside click.\n useEffect(() => {\n if (!open) return;\n const handler = (e: MouseEvent) => {\n if (!wrapperRef.current?.contains(e.target as Node)) {\n setOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, [open]);\n\n // Chevron rotates on open. The transform is dynamic, the rest is static.\n const chevronStyle: CSSProperties = useMemo(\n () => ({\n color: \"#6b6b6b\",\n transform: open ? \"rotate(180deg)\" : \"rotate(0deg)\",\n transition: \"transform 0.15s\",\n }),\n [open],\n );\n\n return (\n <div className=\"flex items-center justify-center\" style={SPREAD_BAR_STYLE}>\n <div className=\"flex items-center\" style={SPREAD_BAR_INNER_STYLE}>\n <span style={SPREAD_LABEL_STYLE}>Spread:</span>\n <div ref={wrapperRef} className=\"relative\">\n <button\n type=\"button\"\n className=\"flex items-center cursor-pointer hover:text-white/80 transition-colors\"\n style={SPREAD_BUTTON_STYLE}\n onClick={() => setOpen((v) => !v)}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n >\n <span>{formatPrecision(precision)}</span>\n {/* Neutral grey chevron — kept independent of the precision\n value's text color so the affordance reads as \"decoration\",\n not as part of the active value. */}\n <svg\n width=\"8\"\n height=\"8\"\n viewBox=\"0 0 8 8\"\n fill=\"none\"\n style={chevronStyle}\n >\n <path\n d=\"M1 2.5L4 5.5L7 2.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </button>\n {open && (\n <div\n role=\"listbox\"\n className=\"absolute left-1/2 -translate-x-1/2 z-20 flex flex-col\"\n style={SPREAD_DROPDOWN_STYLE}\n >\n {precisionOptions.map((opt) => {\n const selected = opt === precision;\n return (\n <button\n key={opt}\n type=\"button\"\n role=\"option\"\n aria-selected={selected}\n className=\"cursor-pointer transition-colors\"\n style={\n selected\n ? SPREAD_OPTION_SELECTED_STYLE\n : SPREAD_OPTION_STYLE\n }\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor =\n \"rgba(255,255,255,0.06)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"transparent\";\n }}\n onClick={() => {\n onPrecisionChange(opt);\n setOpen(false);\n }}\n >\n {formatPrecision(opt)}\n </button>\n );\n })}\n </div>\n )}\n </div>\n <span style={SPREAD_VALUE_STYLE}>{spreadPercentage.toFixed(3)}%</span>\n </div>\n </div>\n );\n}\n\n/**\n * Order book layout (top to bottom):\n *\n * ┌─ Header (Price / Amount / Total) ────┐ fixed height\n * ├─ Asks scroll region ─────────────────┤ flex-1, independent scroll\n * │ highest ask │\n * │ ... │\n * │ best ask ◄── default visible │\n * ├─ Spread bar with precision dropdown ─┤ fixed height\n * ├─ Bids scroll region ─────────────────┤ flex-1, independent scroll\n * │ best bid ◄── default visible │\n * │ ... │\n * │ lowest bid │\n * └──────────────────────────────────────┘\n *\n * Both scroll regions consume any leftover container height equally; if the\n * widget is short, each side scrolls on its own without dragging the other.\n *\n * Asks come in sorted ascending (best ask = lowest price = `asks[0]`). To\n * pin the best ask flush against the spread bar we render asks reversed\n * (highest first → best last in DOM order) inside a normal column scroll\n * container, then default-scroll to the bottom on mount. We re-stick the\n * scroll position to the bottom whenever the user is already near it, so\n * websocket updates don't bounce the view off the best ask.\n *\n * Bids are sorted descending (`bids[0]` = best) and rendered top-down,\n * so the best bid sits at `scrollTop = 0` flush against the spread bar\n * by default.\n */\nexport function OrderBookUI({\n bids,\n asks,\n spreadPercentage,\n precision,\n precisionOptions,\n onPrecisionChange,\n onPriceClick,\n}: OrderBookUIProps) {\n const asksScrollRef = useRef<HTMLDivElement | null>(null);\n const bidsScrollRef = useRef<HTMLDivElement | null>(null);\n // Track whether the user has scrolled away from the spread-bar edge of\n // each side. While they are still \"stuck\" near the spread, we keep that\n // edge in view across data updates; once they scroll away, we leave the\n // scroll position alone so they can browse deeper levels in peace.\n const asksStuckRef = useRef(true);\n const bidsStuckRef = useRef(true);\n\n // Render-order helper: highest ask first, best ask last (closest to\n // spread bar). Memoised so the array reference is stable when `asks` is\n // — otherwise the asks `useEffect` below would fire on every render,\n // not just on actual data updates.\n const renderedAsks = useMemo(() => [...asks].reverse(), [asks]);\n\n // Whenever asks update and the user is still pinned near the spread bar,\n // re-anchor the scroll position to the bottom (where the best ask lives).\n // Skip the assignment when scrollTop is already at the target to avoid\n // gratuitous layout work on every WebSocket push.\n useEffect(() => {\n const el = asksScrollRef.current;\n if (!el || !asksStuckRef.current) return;\n const target = el.scrollHeight;\n if (el.scrollTop !== target) {\n el.scrollTop = target;\n }\n }, [renderedAsks]);\n\n // Same idea for bids: keep the best bid (top) glued to the spread bar\n // until the user scrolls away.\n useEffect(() => {\n const el = bidsScrollRef.current;\n if (!el || !bidsStuckRef.current) return;\n if (el.scrollTop !== 0) {\n el.scrollTop = 0;\n }\n }, [bids]);\n\n const handleAsksScroll = useCallback(() => {\n const el = asksScrollRef.current;\n if (!el) return;\n // For asks the spread-bar edge is the *bottom* of the scroll region.\n // Allow a small tolerance (one row) so flicker from updates doesn't\n // un-stick the view.\n const distanceFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight;\n asksStuckRef.current = distanceFromBottom <= 24;\n }, []);\n\n const handleBidsScroll = useCallback(() => {\n const el = bidsScrollRef.current;\n if (!el) return;\n // For bids the spread-bar edge is the *top* of the scroll region.\n bidsStuckRef.current = el.scrollTop <= 24;\n }, []);\n\n return (\n <div className=\"flex flex-col h-full min-h-0\" style={CONTAINER_STYLE}>\n {/* Header */}\n <div className=\"flex items-center flex-none\" style={HEADER_STYLE}>\n <div className=\"flex items-center\" style={HEADER_CELL_STYLE}>\n Price\n </div>\n <div\n className=\"flex items-center justify-end\"\n style={HEADER_CELL_STYLE}\n >\n Amount (USD)\n </div>\n <div\n className=\"flex items-center justify-end\"\n style={HEADER_CELL_STYLE}\n >\n Total (USD)\n </div>\n </div>\n\n {/* Asks — independent scroll. Reversed so best ask lives at the\n DOM bottom; we default-scroll to the bottom to surface it. */}\n <div\n ref={asksScrollRef}\n onScroll={handleAsksScroll}\n className=\"flex-1 min-h-0 overflow-y-auto\"\n style={ORDERBOOK_SCROLL_STYLE}\n >\n {renderedAsks.map((ask, index) => (\n <OBRow\n key={`ask-${ask.price}-${index}`}\n price={ask.price}\n quantity={ask.quantity}\n total={ask.total}\n percentage={ask.percentage}\n side=\"ask\"\n onPriceClick={onPriceClick}\n />\n ))}\n </div>\n\n {/* Spread bar */}\n <div className=\"flex-none\">\n <SpreadBar\n spreadPercentage={spreadPercentage}\n precision={precision}\n precisionOptions={precisionOptions}\n onPrecisionChange={onPrecisionChange}\n />\n </div>\n\n {/* Bids — independent scroll. Best bid is at the top so it sits\n flush against the spread bar at scrollTop=0. */}\n <div\n ref={bidsScrollRef}\n onScroll={handleBidsScroll}\n className=\"flex-1 min-h-0 overflow-y-auto\"\n style={ORDERBOOK_SCROLL_STYLE}\n >\n {bids.map((bid, index) => (\n <OBRow\n key={`bid-${bid.price}-${index}`}\n price={bid.price}\n quantity={bid.quantity}\n total={bid.total}\n percentage={bid.percentage}\n side=\"bid\"\n onPriceClick={onPriceClick}\n />\n ))}\n </div>\n </div>\n );\n}\n","import { Skeleton } from \"@liberfi.io/ui\";\nimport { useOrderBookScript } from \"./orderbook.script\";\nimport { OrderBookUI } from \"./orderbook.ui\";\n\n/**\n * Default tick-aggregation steps offered to the user via the spread dropdown.\n *\n * Mirrors Axiom / Hyperliquid's perpetuals UI for major USD-quoted pairs\n * (BTC, ETH, SOL): users can collapse the book into 1, 2, 5, 10, 100, or\n * 1000-USD buckets to see liquidity at coarser granularities.\n */\nexport const DEFAULT_ORDER_BOOK_PRECISION_OPTIONS = [\n 1, 2, 5, 10, 100, 1000,\n] as const;\n\nexport type OrderBookWidgetProps = {\n symbol: string;\n /**\n * How many price levels to fetch + render per side. Defaults to `40` so\n * that asks and bids always have enough rows to overflow their containers\n * and show their independent scroll bars.\n */\n maxLevel?: number;\n /**\n * Steps shown in the \"Spread\" dropdown. Defaults to\n * `[1, 2, 5, 10, 100, 1000]` (Axiom's BTC perpetuals options).\n */\n precisionOptions?: readonly number[];\n /**\n * Initial selected step. Defaults to the first entry in `precisionOptions`.\n */\n defaultPrecision?: number;\n onPriceClick?: (price: number) => void;\n className?: string;\n};\n\nfunction OrderBookSkeleton() {\n return (\n <div className=\"flex flex-col h-full\" style={{ padding: \"0 16px\" }}>\n <div\n className=\"flex justify-between items-center\"\n style={{ height: 28, marginBottom: 4 }}\n >\n <Skeleton className=\"h-3 w-12 rounded\" />\n <Skeleton className=\"h-3 w-14 rounded\" />\n <Skeleton className=\"h-3 w-14 rounded\" />\n </div>\n {Array.from({ length: 10 }).map((_, i) => (\n <div\n key={`ask-skeleton-${i}`}\n className=\"flex justify-between items-center\"\n style={{ height: 22 }}\n >\n <Skeleton className=\"h-3 w-14 rounded\" />\n <Skeleton className=\"h-3 w-14 rounded\" />\n <Skeleton className=\"h-3 w-14 rounded\" />\n </div>\n ))}\n <div className=\"flex justify-center items-center\" style={{ height: 28 }}>\n <Skeleton className=\"h-4 w-32 rounded\" />\n </div>\n {Array.from({ length: 10 }).map((_, i) => (\n <div\n key={`bid-skeleton-${i}`}\n className=\"flex justify-between items-center\"\n style={{ height: 22 }}\n >\n <Skeleton className=\"h-3 w-14 rounded\" />\n <Skeleton className=\"h-3 w-14 rounded\" />\n <Skeleton className=\"h-3 w-14 rounded\" />\n </div>\n ))}\n </div>\n );\n}\n\nfunction OrderBookEmpty() {\n return (\n <div className=\"flex items-center justify-center h-full\">\n <span className=\"text-neutral-400 text-sm\">\n No order book data available\n </span>\n </div>\n );\n}\n\nexport function OrderBookWidget({\n symbol,\n maxLevel = 40,\n precisionOptions = DEFAULT_ORDER_BOOK_PRECISION_OPTIONS,\n defaultPrecision,\n onPriceClick,\n className,\n}: OrderBookWidgetProps) {\n const initialPrecision = defaultPrecision ?? precisionOptions[0] ?? 1;\n\n const { bids, asks, spreadPercentage, isLoading, precision, setPrecision } =\n useOrderBookScript({\n symbol,\n maxLevel,\n precision: initialPrecision,\n });\n\n if (isLoading) {\n return <OrderBookSkeleton />;\n }\n\n if (bids.length === 0 && asks.length === 0) {\n return <OrderBookEmpty />;\n }\n\n return (\n <div className={className}>\n <OrderBookUI\n bids={bids}\n asks={asks}\n spreadPercentage={spreadPercentage}\n precision={precision}\n precisionOptions={precisionOptions}\n onPrecisionChange={setPrecision}\n onPriceClick={onPriceClick}\n />\n </div>\n );\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport { useMarketDataSubscription } from \"../../hooks/useMarketDataSubscription\";\nimport { useRecentTradesQuery } from \"../../hooks/useRecentTradesQuery\";\nimport type { Trade } from \"../../types\";\n\nexport type UseTradesScriptParams = {\n symbol: string;\n limit?: number;\n};\n\nexport type UseTradesScriptResult = {\n trades: Trade[];\n isLoading: boolean;\n};\n\n/**\n * Trailing-edge flush interval for incoming WebSocket trade pushes. Hyperliquid\n * can fire 5–30 fills per second on active markets like BTC perp. Calling\n * `setTrades` for every push triggers React reconciliation per push; coalescing\n * into one setState every `BATCH_FLUSH_MS` caps the reconcile rate at 5 Hz\n * without losing trades (we *append* — see {@link normalizeRealtimeTrades}).\n *\n * 200 ms is small enough that the latest trade is on screen \"instantly\" from\n * the user's perspective, and large enough to absorb the typical burst rate.\n */\nconst BATCH_FLUSH_MS = 200;\n\nexport function useTradesScript({\n symbol,\n limit = 50,\n}: UseTradesScriptParams): UseTradesScriptResult {\n const [trades, setTrades] = useState<Trade[]>([]);\n\n const { data: initialData, isPending } = useRecentTradesQuery({\n symbol,\n limit,\n });\n\n const { data: realtimeTrade } = useMarketDataSubscription<Trade | Trade[]>({\n type: \"trades\",\n symbol,\n enabled: !!initialData,\n });\n\n // Seed the in-memory trade list from the REST snapshot once it arrives.\n // After this point the websocket subscription owns updates.\n useEffect(() => {\n if (initialData) {\n setTrades(initialData.filter(isValidTrade));\n }\n }, [initialData]);\n\n // ---- Trailing-edge batch flush --------------------------------------\n // We accumulate incoming pushes in a ref and flush them through a single\n // `setTrades` no more than once every BATCH_FLUSH_MS. This is *append*\n // semantics (so we keep every fill), unlike `useMarketDataSubscription`'s\n // built-in `throttleMs` which is \"drop intermediate values\".\n const pendingRef = useRef<Trade[]>([]);\n const flushTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const limitRef = useRef(limit);\n limitRef.current = limit;\n\n useEffect(() => {\n if (!realtimeTrade) return;\n\n const incoming = normalizeRealtimeTrades(realtimeTrade);\n if (incoming.length === 0) return;\n pendingRef.current.push(...incoming);\n\n if (flushTimerRef.current !== null) return;\n\n flushTimerRef.current = setTimeout(() => {\n flushTimerRef.current = null;\n const batch = pendingRef.current;\n pendingRef.current = [];\n if (batch.length === 0) return;\n\n setTrades((prev) => {\n // Drop fills already present (Hyperliquid occasionally re-sends the\n // same trade across a reconnect). Match on (timestamp, price, qty)\n // tuple — `tradeId` is not always set.\n const deduped = batch.filter(\n (next) =>\n !prev.some(\n (existing) =>\n existing.timestamp === next.timestamp &&\n existing.price === next.price &&\n existing.quantity === next.quantity,\n ),\n );\n if (deduped.length === 0) return prev;\n\n // The batch arrives in chronological order from the WS feed; we\n // reverse it so the *latest* fill in the batch ends up at index 0\n // of the merged list (newest-first).\n return [...deduped.reverse(), ...prev].slice(0, limitRef.current);\n });\n }, BATCH_FLUSH_MS);\n }, [realtimeTrade]);\n\n // Reset on symbol change (or unmount). Drop any pending payload so it\n // can't land after the subscription is torn down.\n useEffect(() => {\n return () => {\n if (flushTimerRef.current !== null) {\n clearTimeout(flushTimerRef.current);\n flushTimerRef.current = null;\n }\n pendingRef.current = [];\n };\n }, [symbol]);\n\n return {\n trades,\n isLoading: isPending,\n };\n}\n\nfunction normalizeRealtimeTrades(payload: Trade | Trade[]): Trade[] {\n const list = Array.isArray(payload) ? payload : [payload];\n return list.filter(isValidTrade);\n}\n\nfunction isValidTrade(trade: Partial<Trade> | undefined): trade is Trade {\n if (!trade) return false;\n return (\n typeof trade.symbol === \"string\" &&\n (trade.side === \"buy\" || trade.side === \"sell\") &&\n typeof trade.price === \"number\" &&\n Number.isFinite(trade.price) &&\n typeof trade.quantity === \"number\" &&\n Number.isFinite(trade.quantity) &&\n typeof trade.timestamp === \"number\" &&\n Number.isFinite(trade.timestamp)\n );\n}\n","import type { CSSProperties, ReactElement } from \"react\";\nimport { useMemo, useRef } from \"react\";\nimport { List, type RowComponentProps } from \"react-window\";\nimport { useResizeObserver, useTickAge } from \"@liberfi.io/hooks\";\nimport type { Trade } from \"../../types\";\n\n// ---------------------------------------------------------------------------\n// Static styles hoisted to module scope so they are NOT reallocated on every\n// render. The trades list re-renders at the WS push rate and the age tick\n// rate, so allocating fresh style objects per render is wasted GC pressure\n// and breaks shallow-equality optimisations like React.memo.\n// ---------------------------------------------------------------------------\n\nconst ROW_HEIGHT = 22;\nconst HEADER_HEIGHT = 28;\nconst PRICE_COL_MAX_W = 100;\nconst AGE_COL_MAX_W = 120;\n\nconst CONTAINER_STYLE: CSSProperties = {\n backgroundColor: \"#000000\",\n fontSize: 11,\n};\n\nconst HEADER_STYLE: CSSProperties = {\n height: HEADER_HEIGHT,\n minHeight: HEADER_HEIGHT,\n padding: \"0 16px\",\n color: \"#6b6b6b\",\n fontSize: 11,\n};\n\nconst HEADER_PRICE_CELL: CSSProperties = {\n flex: \"1 1 0%\",\n maxWidth: PRICE_COL_MAX_W,\n};\nconst HEADER_SIZE_CELL: CSSProperties = { flex: \"1 1 0%\", marginLeft: 20 };\nconst HEADER_AGE_CELL: CSSProperties = {\n flex: \"1 1 0%\",\n maxWidth: AGE_COL_MAX_W,\n textAlign: \"right\",\n};\n\nconst ROW_INNER_STYLE: CSSProperties = {\n height: ROW_HEIGHT,\n minHeight: ROW_HEIGHT,\n maxHeight: ROW_HEIGHT,\n padding: \"0 16px\",\n};\n\nconst ROW_PRICE_CELL: CSSProperties = {\n flex: \"1 1 0%\",\n maxWidth: PRICE_COL_MAX_W,\n};\nconst ROW_SIZE_CELL: CSSProperties = {\n flex: \"1 1 0%\",\n marginLeft: 20,\n color: \"#FCFCFC\",\n};\nconst ROW_AGE_CELL: CSSProperties = {\n flex: \"1 1 0%\",\n maxWidth: AGE_COL_MAX_W,\n textAlign: \"right\",\n color: \"#777A8C\",\n};\n\n// Per-side row decoration. The colour comes from the project's semantic\n// theme tokens (declared in the consumer's `theme.css` as\n// `--color-bullish` / `--color-bearish`, which themselves resolve to\n// `hsl(var(--heroui-primary))` / `hsl(var(--heroui-secondary))`). Using\n// CSS variables instead of hard-coded hex keeps the bars in lock-step\n// with the active HeroUI theme — including future light-mode variants.\n//\n// Width is data-dependent (see `barWidth`), so we keep it out of the base.\nconst BUY_BAR_STYLE_BASE: CSSProperties = {\n position: \"absolute\",\n left: 0,\n top: 0,\n height: 20,\n background: \"linear-gradient(to right, transparent, var(--color-bullish))\",\n opacity: 0.15,\n pointerEvents: \"none\",\n};\nconst SELL_BAR_STYLE_BASE: CSSProperties = {\n position: \"absolute\",\n left: 0,\n top: 0,\n height: 20,\n background: \"linear-gradient(to right, transparent, var(--color-bearish))\",\n opacity: 0.15,\n pointerEvents: \"none\",\n};\n\n// ---------------------------------------------------------------------------\n// Formatting utilities\n// ---------------------------------------------------------------------------\n\n/**\n * Format the trade price. Mirrors `orderbook.ui.tsx`:\n * ≥ 1000 → integer with thousands separator (e.g. `80,646`)\n * ≥ 1 → 2–4 fraction digits (e.g. `84.62`)\n * < 1 → 6 fraction digits (e.g. `0.0457`)\n */\nfunction formatPrice(price: number): string {\n if (!Number.isFinite(price)) return \"-\";\n if (price >= 1000) {\n return price.toLocaleString(\"en-US\", {\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n });\n }\n if (price >= 1) {\n return price.toLocaleString(\"en-US\", {\n minimumFractionDigits: 2,\n maximumFractionDigits: 4,\n });\n }\n return price.toFixed(6);\n}\n\n/**\n * Format the USD notional size. Always 2 fraction digits with a `$` prefix\n * and thousands separators, e.g. `$83.85`, `$8,365.65`. No K/M abbreviation\n * (Axiom uses full digits and so do we — easier to parse at a glance).\n */\nfunction formatUsd(usd: number): string {\n if (!Number.isFinite(usd)) return \"-\";\n return (\n \"$\" +\n usd.toLocaleString(\"en-US\", {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n })\n );\n}\n\n/**\n * Format the trade age. Receives milliseconds (the `useTickAge` return\n * value) to avoid a per-row second conversion. Steps:\n * < 60 s → `${n}s`\n * < 60 min → `${n}m`\n * < 24 h → `${n}h`\n * else → `${n}d`\n */\nfunction formatAge(ageMs: number): string {\n const seconds = Math.max(0, Math.floor(ageMs / 1000));\n if (seconds < 60) return `${seconds}s`;\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h`;\n return `${Math.floor(hours / 24)}d`;\n}\n\n/**\n * Map a USD notional value to a 0-100 percentage for the row's background\n * bar width. We reverse-engineered Axiom's relationship from observed DOM\n * samples (e.g. $12.09 → 11.24%, $83.85 → 23.85%, $8,365.65 → 53.84%) and\n * found a near-perfect fit:\n *\n * width(%) = 15 × log10(usd) − 5\n *\n * Logarithmic scale keeps small trades visible without letting whales\n * flatten everything to a sliver. Clamped to [0, 100].\n */\nfunction barWidth(usd: number): number {\n if (!Number.isFinite(usd) || usd <= 0) return 0;\n return Math.max(0, Math.min(100, 15 * Math.log10(usd) - 5));\n}\n\n// ---------------------------------------------------------------------------\n// Row component\n// ---------------------------------------------------------------------------\n\ntype TradeRowData = {\n trades: Trade[];\n onTradeClick?: (trade: Trade) => void;\n};\n\n/**\n * react-window v2 row component. Note: we deliberately do NOT wrap this in\n * `React.memo`. The age is driven by `useTickAge`'s internal `setAge`, which\n * only re-renders this single row — never the parent — so wrapping with\n * `memo` would not save any cascaded reconciliations. Parent re-renders\n * (caused by `trades` array changes from the 200ms batch flush) shift every\n * row's `trades[index]` reference anyway, defeating shallow equality.\n *\n * react-window itself already short-circuits off-screen rows by simply not\n * mounting them, so we get virtualization benefits without manual memo.\n */\nfunction TradeRow({\n index,\n style,\n trades,\n onTradeClick,\n}: RowComponentProps<TradeRowData>): ReactElement | null {\n const trade = trades[index];\n\n // Subscribe to the global 1 Hz timer for this row's age. `useTickAge` is a\n // thin wrapper over `useTick`, which itself uses a `GlobalTimer`\n // singleton — there is exactly one `setTimeout` for the entire app, all\n // rows share it via an internal Map. `setAge` fires only inside this row,\n // so age-tick reconciliation is bounded to *one* row per tick.\n const birthday = trade?.timestamp ?? Date.now();\n const ageMs = useTickAge(birthday);\n\n const usd = useMemo(() => {\n if (!trade) return 0;\n if (!Number.isFinite(trade.price) || !Number.isFinite(trade.quantity)) {\n return 0;\n }\n return trade.price * trade.quantity;\n }, [trade]);\n\n // Per-render allocation is unavoidable here because `width` depends on\n // `usd`. Keeping every other style static (see *_BAR_STYLE_BASE) limits\n // the cost to one tiny object per visible row per WS push.\n const barStyle: CSSProperties = useMemo(() => {\n const isBuy = trade?.side === \"buy\";\n const base = isBuy ? BUY_BAR_STYLE_BASE : SELL_BAR_STYLE_BASE;\n return { ...base, width: `${barWidth(usd)}%` };\n }, [trade, usd]);\n\n if (!trade) return null;\n\n const isBuy = trade.side === \"buy\";\n\n return (\n <div style={style}>\n <div\n className=\"relative flex items-center cursor-pointer hover:bg-white/5 transition-colors\"\n style={ROW_INNER_STYLE}\n onClick={onTradeClick ? () => onTradeClick(trade) : undefined}\n >\n <div style={barStyle} />\n <div className=\"relative z-10 flex items-center\" style={ROW_PRICE_CELL}>\n <span className={isBuy ? \"text-bullish\" : \"text-bearish\"}>\n {formatPrice(trade.price)}\n </span>\n </div>\n <div className=\"relative z-10 flex items-center\" style={ROW_SIZE_CELL}>\n {formatUsd(usd)}\n </div>\n <div\n className=\"relative z-10 flex items-center justify-end\"\n style={ROW_AGE_CELL}\n >\n {formatAge(ageMs)}\n </div>\n </div>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// List component\n// ---------------------------------------------------------------------------\n\nexport type TradesUIProps = {\n trades: Trade[];\n onTradeClick?: (trade: Trade) => void;\n};\n\nexport function TradesUI({\n trades,\n onTradeClick,\n}: TradesUIProps): ReactElement {\n // Resize observation: react-window v2 needs an explicit `height` prop on\n // `<List>`. We measure the wrapping div with the shared `useResizeObserver`\n // hook (same pattern used in `ui-tokens` SearchResultListWidget).\n const listContainerRef = useRef<HTMLDivElement | null>(null);\n const { height = 0 } = useResizeObserver<HTMLDivElement>({\n ref: listContainerRef,\n });\n\n // `rowProps` is the parameter object react-window passes (alongside\n // `index` / `style`) into our `rowComponent`. Memoise so the reference\n // is stable when neither `trades` nor `onTradeClick` change — keeps\n // react-window's own bailouts effective.\n const rowProps = useMemo<TradeRowData>(\n () => ({ trades, onTradeClick }),\n [trades, onTradeClick],\n );\n\n return (\n <div className=\"flex flex-col h-full\" style={CONTAINER_STYLE}>\n <div className=\"flex items-center flex-none\" style={HEADER_STYLE}>\n <div style={HEADER_PRICE_CELL}>Price</div>\n <div style={HEADER_SIZE_CELL}>Size (USD)</div>\n <div style={HEADER_AGE_CELL}>Age</div>\n </div>\n <div ref={listContainerRef} className=\"flex-1 min-h-0\">\n {height > 0 && (\n <List\n style={{ height }}\n rowComponent={TradeRow}\n rowCount={trades.length}\n rowHeight={ROW_HEIGHT}\n rowProps={rowProps}\n overscanCount={4}\n />\n )}\n </div>\n </div>\n );\n}\n","import { Skeleton } from \"@liberfi.io/ui\";\nimport type { Trade } from \"../../types\";\nimport { useTradesScript } from \"./trades.script\";\nimport { TradesUI } from \"./trades.ui\";\n\nexport type TradesWidgetProps = {\n symbol: string;\n limit?: number;\n onTradeClick?: (trade: Trade) => void;\n className?: string;\n};\n\nfunction TradesSkeleton() {\n return (\n <div className=\"flex flex-col h-full\" style={{ padding: \"0 16px\" }}>\n <div\n className=\"flex justify-between items-center\"\n style={{ height: 28, marginBottom: 4 }}\n >\n <Skeleton className=\"h-3 w-12 rounded\" />\n <Skeleton className=\"h-3 w-16 rounded\" />\n <Skeleton className=\"h-3 w-8 rounded\" />\n </div>\n {Array.from({ length: 12 }).map((_, i) => (\n <div\n key={`trade-skeleton-${i}`}\n className=\"flex justify-between items-center\"\n style={{ height: 22 }}\n >\n <Skeleton className=\"h-3 w-14 rounded\" />\n <Skeleton className=\"h-3 w-12 rounded\" />\n <Skeleton className=\"h-3 w-8 rounded\" />\n </div>\n ))}\n </div>\n );\n}\n\nfunction TradesEmpty() {\n return (\n <div className=\"flex items-center justify-center h-full\">\n <span className=\"text-neutral-400 text-sm\">No recent trades</span>\n </div>\n );\n}\n\nexport function TradesWidget({\n symbol,\n limit = 100,\n onTradeClick,\n className,\n}: TradesWidgetProps) {\n const { trades, isLoading } = useTradesScript({ symbol, limit });\n\n if (isLoading) {\n return <TradesSkeleton />;\n }\n\n if (trades.length === 0) {\n return <TradesEmpty />;\n }\n\n return (\n <div className={className}>\n <TradesUI trades={trades} onTradeClick={onTradeClick} />\n </div>\n );\n}\n","import { useState, useMemo, useCallback } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { useCreateOrderMutation } from \"../../hooks/useCreateOrderMutation\";\nimport { useMarketQuery } from \"../../hooks/useMarketQuery\";\nimport { usePositionsQuery } from \"../../hooks/usePositionsQuery\";\nimport type { OrderSide, OrderType } from \"../../types\";\n\nexport type PlaceOrderFormData = {\n price?: number;\n amount: number;\n leverage: number;\n takeProfitPrice?: number;\n takeProfitPercent?: number;\n stopLossPrice?: number;\n stopLossPercent?: number;\n};\n\nexport type UsePlaceOrderFormScriptParams = {\n symbol: string;\n userAddress?: string;\n maxLeverage?: number;\n onSuccess?: () => void;\n onError?: (error: Error) => void;\n};\n\nexport type UsePlaceOrderFormScriptResult = {\n form: ReturnType<typeof useForm<PlaceOrderFormData>>;\n side: OrderSide;\n orderType: OrderType;\n setSide: (side: OrderSide) => void;\n setOrderType: (type: OrderType) => void;\n handleSubmit: (data: PlaceOrderFormData) => Promise<void>;\n isSubmitting: boolean;\n currentPrice?: number;\n estimatedFee: number;\n estimatedTotal: number;\n liquidationPrice?: number;\n availableMargin: number;\n accountValue: number;\n currentPosition?: number;\n maxLeverage: number;\n};\n\nexport function usePlaceOrderFormScript({\n symbol,\n userAddress,\n maxLeverage: maxLeverageProp = 150,\n onSuccess,\n onError,\n}: UsePlaceOrderFormScriptParams): UsePlaceOrderFormScriptResult {\n const [side, setSide] = useState<OrderSide>(\"long\");\n const [orderType, setOrderType] = useState<OrderType>(\"market\");\n const form = useForm<PlaceOrderFormData>({\n defaultValues: {\n amount: 0,\n leverage: 20,\n takeProfitPrice: undefined,\n takeProfitPercent: undefined,\n stopLossPrice: undefined,\n stopLossPercent: undefined,\n },\n });\n\n const { data: marketData } = useMarketQuery({ symbol });\n\n const { mutateAsync: createOrder, isPending: isSubmitting } =\n useCreateOrderMutation({\n onSuccess: () => {\n form.reset();\n onSuccess?.();\n },\n onError: (error) => {\n onError?.(error);\n },\n });\n\n const watchedValues = form.watch();\n const { amount, leverage, price } = watchedValues;\n\n const currentPrice = useMemo(() => {\n if (orderType === \"limit\" && price) {\n return price;\n }\n return marketData?.price || 0;\n }, [orderType, price, marketData?.price]);\n\n const estimatedFee = useMemo(() => {\n if (!amount || !currentPrice) return 0;\n const feeRate = 0.0005;\n return amount * currentPrice * feeRate;\n }, [amount, currentPrice]);\n\n const estimatedTotal = useMemo(() => {\n if (!amount || !currentPrice) return 0;\n return amount * currentPrice + estimatedFee;\n }, [amount, currentPrice, estimatedFee]);\n\n const liquidationPrice = useMemo(() => {\n if (!amount || !currentPrice || !leverage || leverage === 1)\n return undefined;\n\n const maintenanceMarginRate = 0.005;\n const entryPrice = currentPrice;\n\n if (side === \"long\") {\n return entryPrice * (1 - (1 / leverage - maintenanceMarginRate));\n } else {\n return entryPrice * (1 + (1 / leverage - maintenanceMarginRate));\n }\n }, [amount, currentPrice, leverage, side]);\n\n // Real account / position data sourced from Hyperliquid `clearinghouseState`.\n // Falls back to 0 when the wallet isn't connected (the query stays disabled\n // until `userAddress` is set; see `usePositionsQuery`'s internal guard).\n const { data: positionsData } = usePositionsQuery({\n userAddress,\n symbol,\n });\n\n const accountValue = positionsData?.totalEquity ?? 0;\n const availableMargin = positionsData?.availableBalance ?? 0;\n const currentPosition = useMemo(() => {\n const pos = positionsData?.positions?.[0];\n if (!pos) return 0;\n return pos.side === \"short\" ? -pos.quantity : pos.quantity;\n }, [positionsData?.positions]);\n\n const handleSubmit = useCallback(\n async (data: PlaceOrderFormData) => {\n if (!userAddress) {\n throw new Error(\"User address is required\");\n }\n\n const finalPrice = orderType === \"limit\" ? data.price : undefined;\n\n let takeProfitPrice = data.takeProfitPrice;\n let stopLossPrice = data.stopLossPrice;\n\n if (\n !takeProfitPrice &&\n data.takeProfitPercent &&\n data.takeProfitPercent > 0 &&\n currentPrice\n ) {\n const tpPercent = data.takeProfitPercent / 100;\n takeProfitPrice =\n side === \"long\"\n ? currentPrice * (1 + tpPercent)\n : currentPrice * (1 - tpPercent);\n }\n\n if (\n !stopLossPrice &&\n data.stopLossPercent &&\n data.stopLossPercent > 0 &&\n currentPrice\n ) {\n const slPercent = data.stopLossPercent / 100;\n stopLossPrice =\n side === \"long\"\n ? currentPrice * (1 - slPercent)\n : currentPrice * (1 + slPercent);\n }\n\n await createOrder({\n symbol,\n side,\n orderType,\n amount: data.amount,\n price: finalPrice,\n leverage: data.leverage,\n takeProfitPrice,\n stopLossPrice,\n userAddress,\n });\n },\n [symbol, side, orderType, currentPrice, userAddress, createOrder],\n );\n\n return {\n form,\n side,\n orderType,\n setSide,\n setOrderType,\n handleSubmit,\n isSubmitting,\n currentPrice,\n estimatedFee,\n estimatedTotal,\n liquidationPrice,\n availableMargin,\n accountValue,\n currentPosition,\n maxLeverage: maxLeverageProp,\n };\n}\n","import { useState } from \"react\";\nimport type { UseFormReturn } from \"react-hook-form\";\nimport { cn, RHForm, RHNumberInput, Slider } from \"@liberfi.io/ui\";\nimport type { OrderSide, OrderType } from \"../../types\";\nimport type { PlaceOrderFormData } from \"./place-order-form.script\";\n\nexport type PlaceOrderFormUIProps = {\n methods: UseFormReturn<PlaceOrderFormData>;\n side: OrderSide;\n orderType: OrderType;\n onSideChange: (side: OrderSide) => void;\n onOrderTypeChange: (type: OrderType) => void;\n onSubmit: (data: PlaceOrderFormData) => Promise<void>;\n isSubmitting: boolean;\n symbol: string;\n currentPrice?: number;\n estimatedFee: number;\n estimatedTotal: number;\n liquidationPrice?: number;\n availableMargin: number;\n accountValue: number;\n currentPosition?: number;\n maxLeverage: number;\n /**\n * Optional callback fired when the user clicks the \"Add More Funds\"\n * button (typically wired by the host app to open a deposit dialog).\n * The button is hidden when this prop is omitted, so consumers that\n * don't support a deposit flow don't render a dead control.\n */\n onAddFunds?: () => void;\n};\n\nfunction formatNumber(num: number, decimals: number = 2): string {\n return num.toFixed(decimals);\n}\n\nfunction LeverageModal({\n leverage,\n maxLeverage,\n onLeverageChange,\n onClose,\n}: {\n leverage: number;\n maxLeverage: number;\n onLeverageChange: (v: number) => void;\n onClose: () => void;\n}) {\n const presets = [1, 2, 3, 5, 10, 20, 25, 50, 100].filter(\n (v) => v <= maxLeverage,\n );\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n <div\n className=\"absolute inset-0 bg-black/60\"\n onClick={onClose}\n onKeyDown={(e) => e.key === \"Escape\" && onClose()}\n role=\"button\"\n tabIndex={-1}\n aria-label=\"Close\"\n />\n <div className=\"relative z-10 w-72 bg-neutral-900 border border-neutral-700 rounded-lg p-4 shadow-2xl\">\n <div className=\"flex items-center justify-between mb-4\">\n <h3 className=\"text-sm font-medium text-white\">Adjust Leverage</h3>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"text-neutral-400 hover:text-white\"\n >\n <svg\n className=\"w-4 h-4\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n </div>\n\n <div className=\"text-center text-2xl font-bold text-white mb-4\">\n {leverage}x\n </div>\n\n <Slider\n value={[leverage]}\n onChange={(value: number | number[]) =>\n onLeverageChange(Array.isArray(value) ? value[0] : value)\n }\n minValue={1}\n maxValue={maxLeverage}\n step={1}\n className=\"w-full mb-3\"\n />\n\n <div className=\"flex flex-wrap gap-1.5\">\n {presets.map((preset) => (\n <button\n key={preset}\n type=\"button\"\n className={cn(\n \"px-2.5 py-1 text-xs rounded transition-colors\",\n leverage === preset\n ? \"bg-green-600 text-white\"\n : \"bg-neutral-800 text-neutral-400 hover:bg-neutral-700\",\n )}\n onClick={() => onLeverageChange(preset)}\n >\n {preset}x\n </button>\n ))}\n </div>\n\n <button\n type=\"button\"\n className=\"w-full mt-4 text-white h-9 rounded cursor-pointer transition-colors\"\n style={{ backgroundColor: \"#C7FF2E\" }}\n onClick={onClose}\n >\n Confirm\n </button>\n </div>\n </div>\n );\n}\n\nexport function PlaceOrderFormUI({\n methods,\n side,\n orderType,\n onSideChange,\n onOrderTypeChange,\n onSubmit,\n isSubmitting,\n symbol,\n currentPrice,\n estimatedFee,\n liquidationPrice,\n availableMargin,\n accountValue,\n currentPosition,\n maxLeverage,\n onAddFunds,\n}: PlaceOrderFormUIProps) {\n const [showLeverageModal, setShowLeverageModal] = useState(false);\n const [showTpSl, setShowTpSl] = useState(false);\n const leverage = methods.watch(\"leverage\") || 20;\n const amount = methods.watch(\"amount\") || 0;\n const tokenSymbol = symbol.split(\"-\")[0];\n\n const positionPercent =\n availableMargin > 0 && currentPrice\n ? Math.min(\n ((amount * currentPrice) / (availableMargin * leverage)) * 100,\n 100,\n )\n : 0;\n\n const handlePositionSlider = (value: number | number[]) => {\n const pct = (Array.isArray(value) ? value[0] : value) / 100;\n if (currentPrice && currentPrice > 0) {\n const maxAmount = (availableMargin * leverage * pct) / currentPrice;\n methods.setValue(\"amount\", Number(maxAmount.toFixed(6)));\n }\n };\n\n return (\n <div\n className=\"flex flex-col h-full\"\n style={{ backgroundColor: \"#000000\" }}\n >\n <div\n className=\"perp-order-form flex-1 overflow-y-auto\"\n style={{\n padding: \"16px 16px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: 16,\n }}\n >\n {/* Long / Short */}\n <div\n className=\"flex\"\n style={{\n border: \"1px solid rgba(26,26,26,0.5)\",\n borderRadius: 8,\n padding: 4,\n gap: 4,\n }}\n >\n <button\n type=\"button\"\n className=\"flex-1 cursor-pointer transition-colors\"\n style={{\n height: 32,\n fontSize: 16,\n borderRadius: 4,\n backgroundColor: side === \"long\" ? \"#C7FF2E\" : \"transparent\",\n color: side === \"long\" ? \"#000000\" : \"#b5b5b5\",\n fontWeight: side === \"long\" ? 700 : 500,\n }}\n onClick={() => onSideChange(\"long\")}\n >\n Long\n </button>\n <button\n type=\"button\"\n className=\"flex-1 cursor-pointer transition-colors\"\n style={{\n height: 32,\n fontSize: 16,\n borderRadius: 4,\n backgroundColor: side === \"short\" ? \"#F76816\" : \"transparent\",\n color: side === \"short\" ? \"#000000\" : \"#b5b5b5\",\n fontWeight: side === \"short\" ? 700 : 500,\n }}\n onClick={() => onSideChange(\"short\")}\n >\n Short\n </button>\n </div>\n\n {/* Market / Limit + Leverage button */}\n <div className=\"flex items-center\" style={{ gap: 8 }}>\n <div className=\"flex\">\n {[\n { key: \"market\" as const, label: \"Market\" },\n { key: \"limit\" as const, label: \"Limit\" },\n ].map((tab) => (\n <div\n key={tab.key}\n style={{\n height: 32,\n display: \"flex\",\n alignItems: \"center\",\n borderBottom:\n orderType === tab.key\n ? \"2px solid #ffffff\"\n : \"2px solid transparent\",\n padding: \"2px 0 0\",\n cursor: \"pointer\",\n }}\n >\n <button\n type=\"button\"\n className=\"cursor-pointer transition-colors\"\n style={{\n padding: \"0 8px\",\n fontSize: 12,\n fontWeight: 500,\n backgroundColor: \"transparent\",\n color: orderType === tab.key ? \"#ffffff\" : \"#b5b5b5\",\n border: \"none\",\n }}\n onClick={() => onOrderTypeChange(tab.key)}\n >\n {tab.label}\n </button>\n </div>\n ))}\n </div>\n <div className=\"flex-1\" />\n <button\n type=\"button\"\n className=\"cursor-pointer transition-colors\"\n style={{\n height: 24,\n padding: \"0 5px\",\n fontSize: 12,\n borderRadius: 4,\n backgroundColor: \"rgba(26,26,26,0.5)\",\n color: \"#ffffff\",\n fontWeight: 400,\n border: \"1px solid rgba(26,26,26,0.5)\",\n }}\n onClick={() => setShowLeverageModal(true)}\n >\n Leverage: {leverage}x\n </button>\n </div>\n\n <RHForm methods={methods} onSubmit={onSubmit}>\n <div className=\"space-y-3 w-full\">\n {/* Limit price input */}\n {orderType === \"limit\" && (\n <div\n className=\"perp-price-box\"\n style={{\n borderRadius: 4,\n padding: 8,\n backgroundColor: \"rgba(26,26,26,0.5)\",\n border: \"1px solid #1c1c1c\",\n height: 64,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n }}\n >\n <div className=\"flex justify-between items-center\">\n <span style={{ fontSize: 12, color: \"#6b6b6b\" }}>Price</span>\n <span style={{ fontSize: 12, color: \"#6b6b6b\" }}>USDC</span>\n </div>\n <RHNumberInput\n name=\"price\"\n placeholder=\"0.0 USDC\"\n className=\"w-full\"\n />\n </div>\n )}\n\n {/* Buy Amount */}\n <div\n className=\"perp-buy-amt\"\n style={{\n borderRadius: 4,\n padding: 8,\n backgroundColor: \"rgba(26,26,26,0.5)\",\n border: \"1px solid #1c1c1c\",\n height: 64,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n }}\n >\n <div className=\"flex justify-between items-center\">\n <span style={{ fontSize: 12, color: \"#6b6b6b\" }}>\n Buy Amount\n </span>\n <span style={{ fontSize: 12, color: \"#6b6b6b\" }}>\n {tokenSymbol}\n </span>\n </div>\n <RHNumberInput\n name=\"amount\"\n placeholder=\"0.0 USDC\"\n className=\"w-full\"\n />\n </div>\n\n {/* Position size slider */}\n <div>\n <style>{`\n .perp-buy-amt input, .perp-price-box input { font-size: 18px !important; line-height: 23px !important; }\n .perp-order-form .group,\n .perp-order-form .group div { background: transparent !important; border: none !important; padding: 0 !important; border-radius: 0 !important; min-height: 0 !important; height: auto !important; }\n .perp-order-form .group input { color: #ffffff !important; }\n .perp-slider { -webkit-appearance: none; appearance: none; background: transparent; cursor: pointer; width: 100%; height: 16px; }\n .perp-slider::-webkit-slider-runnable-track { height: 4px; border-radius: 2px; background: #1c1c1c; }\n .perp-slider::-webkit-slider-thumb { -webkit-appearance: none; width: 12px; height: 12px; border-radius: 50%; background: #C7FF2E; margin-top: -4px; border: none; }\n .perp-slider::-moz-range-track { height: 4px; border-radius: 2px; background: #1c1c1c; border: none; }\n .perp-slider::-moz-range-thumb { width: 12px; height: 12px; border-radius: 50%; background: #C7FF2E; border: none; }\n `}</style>\n <input\n type=\"range\"\n value={Math.round(positionPercent)}\n onChange={(e) => handlePositionSlider(Number(e.target.value))}\n min={0}\n max={100}\n step={1}\n className=\"perp-slider\"\n />\n <div\n className=\"flex justify-between\"\n style={{ fontSize: 10, color: \"#b5b5b5\", marginTop: 4 }}\n >\n <span>0%</span>\n <span>25%</span>\n <span>50%</span>\n <span>75%</span>\n <span>100%</span>\n </div>\n </div>\n\n {/* TP/SL + Est. Liq. Price */}\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center\" style={{ gap: 6 }}>\n <div\n onClick={() => setShowTpSl((v) => !v)}\n style={{\n width: 16,\n height: 16,\n borderRadius: 4,\n border: \"1px solid #2a2a2a\",\n backgroundColor: showTpSl ? \"#C7FF2E\" : \"transparent\",\n flexShrink: 0,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n {showTpSl && (\n <svg width=\"10\" height=\"8\" viewBox=\"0 0 10 8\" fill=\"none\">\n <path\n d=\"M1 4L3.5 6.5L9 1\"\n stroke=\"#000000\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )}\n </div>\n <span\n style={{ fontSize: 12, fontWeight: 500, color: \"#b5b5b5\" }}\n >\n TP/SL\n </span>\n </div>\n <div style={{ fontSize: 12, color: \"#6b6b6b\" }}>\n <span>Est. Liq. Price: </span>\n <span style={{ color: \"#b5b5b5\" }}>\n {liquidationPrice ? formatNumber(liquidationPrice, 2) : \"--\"}\n </span>\n </div>\n </div>\n\n {/* TP Price inputs (visible when TP/SL checked) */}\n {showTpSl && (\n <div className=\"flex\" style={{ gap: 8 }}>\n <div className=\"flex-1\">\n <span\n style={{\n fontSize: 12,\n color: \"#6b6b6b\",\n marginBottom: 2,\n display: \"block\",\n }}\n >\n TP Price\n </span>\n <RHNumberInput\n name=\"takeProfitPrice\"\n placeholder=\"Enter TP price\"\n className=\"w-full\"\n style={{\n fontSize: 12,\n height: 32,\n padding: \"0 8px\",\n border: \"1px solid #1c1c1c\",\n borderRadius: 4,\n }}\n />\n </div>\n <div style={{ width: 70 }}>\n <span\n style={{\n fontSize: 12,\n color: \"#6b6b6b\",\n marginBottom: 2,\n display: \"block\",\n }}\n >\n TP %\n </span>\n <RHNumberInput\n name=\"takeProfitPercent\"\n placeholder=\"0.0\"\n className=\"w-full\"\n style={{\n fontSize: 12,\n height: 32,\n padding: \"0 8px\",\n border: \"1px solid #1c1c1c\",\n borderRadius: 4,\n }}\n />\n </div>\n </div>\n )}\n\n {/* Add More Funds — only rendered when the host wires a handler */}\n {onAddFunds && (\n <button\n type=\"button\"\n onClick={onAddFunds}\n className=\"w-full cursor-pointer transition-colors\"\n style={{\n height: 36,\n fontSize: 14,\n fontWeight: 700,\n color: \"#000000\",\n backgroundColor: \"#C7FF2E\",\n borderRadius: 9999,\n border: \"none\",\n }}\n >\n Add More Funds\n </button>\n )}\n\n {/* SL Price inputs (visible when TP/SL checked) */}\n {showTpSl && (\n <div className=\"flex\" style={{ gap: 8 }}>\n <div className=\"flex-1\">\n <span\n style={{\n fontSize: 12,\n color: \"#6b6b6b\",\n marginBottom: 2,\n display: \"block\",\n }}\n >\n SL Price\n </span>\n <RHNumberInput\n name=\"stopLossPrice\"\n placeholder=\"Enter SL price\"\n className=\"w-full\"\n style={{\n fontSize: 12,\n height: 32,\n padding: \"0 8px\",\n border: \"1px solid #1c1c1c\",\n borderRadius: 4,\n }}\n />\n </div>\n <div style={{ width: 70 }}>\n <span\n style={{\n fontSize: 12,\n color: \"#6b6b6b\",\n marginBottom: 2,\n display: \"block\",\n }}\n >\n SL %\n </span>\n <RHNumberInput\n name=\"stopLossPercent\"\n placeholder=\"0.0\"\n className=\"w-full\"\n style={{\n fontSize: 12,\n height: 32,\n padding: \"0 8px\",\n border: \"1px solid #1c1c1c\",\n borderRadius: 4,\n }}\n />\n </div>\n </div>\n )}\n </div>\n </RHForm>\n </div>\n\n {/* Account info + branding footer */}\n <div\n style={{\n padding: \"10px 16px\",\n fontSize: 12,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 6,\n }}\n >\n <div className=\"flex justify-between items-center\">\n <span style={{ color: \"#6b6b6b\" }}>Available Margin</span>\n <span style={{ color: \"#C7FF2E\", fontSize: 12, fontWeight: 500 }}>\n {formatNumber(availableMargin)} USDC\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span style={{ color: \"#6b6b6b\" }}>Perps Account Value</span>\n <span style={{ color: \"#b5b5b5\", fontSize: 12 }}>\n {formatNumber(accountValue)} USDC\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span style={{ color: \"#6b6b6b\" }}>Current Position</span>\n <span style={{ color: \"#b5b5b5\", fontSize: 12 }}>\n {currentPosition ? formatNumber(currentPosition) : \"--\"}\n </span>\n </div>\n <div\n className=\"flex items-center justify-end\"\n style={{ gap: 6, paddingTop: 8 }}\n >\n <span style={{ fontSize: 11, color: \"#6b6b6b\" }}>powered by</span>\n <img\n src=\"https://axiom-assets.sfo3.cdn.digitaloceanspaces.com/images/hyperliquid-logo.svg\"\n alt=\"Hyperliquid\"\n className=\"h-3 opacity-60\"\n onError={(e) => {\n const target = e.target as HTMLImageElement;\n target.style.display = \"none\";\n }}\n />\n </div>\n </div>\n\n {/* Leverage modal */}\n {showLeverageModal && (\n <LeverageModal\n leverage={leverage}\n maxLeverage={maxLeverage}\n onLeverageChange={(v) => methods.setValue(\"leverage\", v)}\n onClose={() => setShowLeverageModal(false)}\n />\n )}\n </div>\n );\n}\n","import { usePlaceOrderFormScript } from \"./place-order-form.script\";\nimport { PlaceOrderFormUI } from \"./place-order-form.ui\";\n\nexport type PlaceOrderFormWidgetProps = {\n symbol: string;\n userAddress?: string;\n maxLeverage?: number;\n onSuccess?: () => void;\n onError?: (error: Error) => void;\n /**\n * Optional callback fired when the user clicks \"Add More Funds\".\n * The host app typically opens its deposit dialog here. When omitted,\n * the button is hidden so the form doesn't expose a non-functional\n * control.\n */\n onAddFunds?: () => void;\n className?: string;\n};\n\nexport function PlaceOrderFormWidget({\n symbol,\n userAddress,\n maxLeverage,\n onSuccess,\n onError,\n onAddFunds,\n className,\n}: PlaceOrderFormWidgetProps) {\n const {\n form,\n side,\n orderType,\n setSide,\n setOrderType,\n handleSubmit,\n isSubmitting,\n currentPrice,\n estimatedFee,\n estimatedTotal,\n liquidationPrice,\n availableMargin,\n accountValue,\n currentPosition,\n maxLeverage: resolvedMaxLeverage,\n } = usePlaceOrderFormScript({\n symbol,\n userAddress,\n maxLeverage,\n onSuccess,\n onError,\n });\n\n return (\n <div className={className}>\n <PlaceOrderFormUI\n methods={form}\n side={side}\n orderType={orderType}\n onSideChange={setSide}\n onOrderTypeChange={setOrderType}\n onSubmit={handleSubmit}\n isSubmitting={isSubmitting}\n symbol={symbol}\n currentPrice={currentPrice}\n estimatedFee={estimatedFee}\n estimatedTotal={estimatedTotal}\n liquidationPrice={liquidationPrice}\n availableMargin={availableMargin}\n accountValue={accountValue}\n currentPosition={currentPosition}\n maxLeverage={resolvedMaxLeverage}\n onAddFunds={onAddFunds}\n />\n </div>\n );\n}\n","import { useState, useEffect, useCallback } from \"react\";\nimport { useCreateOrderMutation } from \"../../hooks/useCreateOrderMutation\";\nimport { usePositionsQuery } from \"../../hooks/usePositionsQuery\";\nimport { useUserDataSubscription } from \"../../hooks/useUserDataSubscription\";\nimport type { Position } from \"../../types\";\n\nexport type UsePositionsScriptParams = {\n userAddress?: string;\n symbol?: string;\n onCloseSuccess?: () => void;\n onCloseError?: (error: Error) => void;\n};\n\nexport type UsePositionsScriptResult = {\n positions: Position[];\n isLoading: boolean;\n error: Error | null;\n handleClosePosition: (position: Position) => Promise<void>;\n isClosing: boolean;\n};\n\nexport function usePositionsScript({\n userAddress,\n symbol,\n onCloseSuccess,\n onCloseError,\n}: UsePositionsScriptParams): UsePositionsScriptResult {\n const [positions, setPositions] = useState<Position[]>([]);\n\n // Fetch initial positions data\n const {\n data: positionsData,\n isLoading,\n error,\n } = usePositionsQuery({ userAddress, symbol }, { enabled: !!userAddress });\n\n // Subscribe to realtime position updates\n const { data: realtimePosition } = useUserDataSubscription<Position>({\n type: \"positions\",\n userAddress: userAddress || \"\",\n enabled: !!userAddress,\n });\n\n // Mutation for closing position (by placing opposite order)\n const { mutateAsync: createOrder, isPending: isClosing } =\n useCreateOrderMutation({\n onSuccess: () => {\n onCloseSuccess?.();\n },\n onError: (error) => {\n onCloseError?.(error);\n },\n });\n\n // Initialize positions data\n useEffect(() => {\n if (positionsData?.positions) {\n setPositions(positionsData.positions);\n }\n }, [positionsData]);\n\n // Handle realtime position updates\n useEffect(() => {\n if (realtimePosition) {\n setPositions((prevPositions) => {\n const existingIndex = prevPositions.findIndex(\n (p) => p.symbol === realtimePosition.symbol,\n );\n\n // If position quantity is 0, remove the position\n if (realtimePosition.quantity === 0) {\n if (existingIndex !== -1) {\n return prevPositions.filter((_, i) => i !== existingIndex);\n }\n return prevPositions;\n }\n\n // Update existing position\n if (existingIndex !== -1) {\n const newPositions = [...prevPositions];\n newPositions[existingIndex] = realtimePosition;\n return newPositions;\n }\n\n // Add new position\n return [...prevPositions, realtimePosition];\n });\n }\n }, [realtimePosition]);\n\n // Close position by placing opposite market order\n const handleClosePosition = useCallback(\n async (position: Position) => {\n if (!userAddress) {\n throw new Error(\"User address is required\");\n }\n\n // Close = place opposite side market order\n const closeSide = position.side === \"long\" ? \"short\" : \"long\";\n\n await createOrder({\n symbol: position.symbol,\n side: closeSide,\n orderType: \"market\",\n amount: Math.abs(position.quantity),\n leverage: position.leverage,\n userAddress,\n });\n },\n [userAddress, createOrder],\n );\n\n return {\n positions,\n isLoading,\n error,\n handleClosePosition,\n isClosing,\n };\n}\n","import { Button, cn } from \"@liberfi.io/ui\";\nimport type { Position } from \"../../types\";\n\nexport type PositionsUIProps = {\n positions: Position[];\n onClosePosition: (position: Position) => void;\n isClosing: boolean;\n};\n\nfunction formatNumber(num: number, decimals: number = 2): string {\n return num.toFixed(decimals);\n}\n\nfunction formatPrice(price: number): string {\n return formatNumber(price, 4);\n}\n\nfunction formatQuantity(quantity: number): string {\n return formatNumber(Math.abs(quantity), 4);\n}\n\nfunction formatPnl(pnl: number): string {\n const sign = pnl >= 0 ? \"+\" : \"\";\n return `${sign}${formatNumber(pnl, 2)}`;\n}\n\nfunction formatPnlPercent(percent: number): string {\n const sign = percent >= 0 ? \"+\" : \"\";\n return `${sign}${formatNumber(percent, 2)}%`;\n}\n\nexport function PositionsUI({\n positions,\n onClosePosition,\n isClosing,\n}: PositionsUIProps) {\n const headerRow = (\n <tr style={{ borderBottom: \"1px solid #1c1c1c\" }}>\n <th\n className=\"text-left py-1.5 px-3 font-normal\"\n style={{ fontSize: 12, color: \"#6b6b6b\" }}\n >\n Asset\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 12, color: \"#6b6b6b\" }}\n >\n Position\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 12, color: \"#6b6b6b\" }}\n >\n Position Value\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 12, color: \"#6b6b6b\" }}\n >\n Entry Price\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 12, color: \"#6b6b6b\" }}\n >\n Mark Price\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 12, color: \"#6b6b6b\" }}\n >\n Liquidation\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 12, color: \"#6b6b6b\" }}\n >\n {\"Margin Used (PNL) \\u2193\"}\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 12, color: \"#6b6b6b\" }}\n >\n TP\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 12, color: \"#6b6b6b\" }}\n >\n SL\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 12, color: \"#6b6b6b\" }}\n >\n Close\n </th>\n </tr>\n );\n\n if (positions.length === 0) {\n return (\n <div className=\"w-full overflow-x-auto bg-transparent\">\n <table className=\"w-full\" style={{ fontSize: 12 }}>\n <thead>{headerRow}</thead>\n </table>\n <div\n className=\"flex items-center justify-center\"\n style={{ fontSize: 14, color: \"#b5b5b5\", padding: \"24px 0\" }}\n >\n No open positions\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"w-full overflow-x-auto bg-transparent\">\n <table className=\"w-full\" style={{ fontSize: 12 }}>\n <thead>{headerRow}</thead>\n <tbody>\n {positions.map((position) => {\n const isProfitable = position.unrealizedPnl >= 0;\n const pnlColor = isProfitable ? \"text-bullish\" : \"text-bearish\";\n\n return (\n <tr\n key={position.symbol}\n className=\"hover:bg-neutral-900/50\"\n style={{ borderBottom: \"1px solid #1c1c1c\" }}\n >\n {/* Asset */}\n <td className=\"py-1.5 px-3\">\n <div className=\"flex flex-col\">\n <span className=\"font-medium\" style={{ color: \"#ffffff\" }}>\n {position.symbol.split(\"-\")[0]}\n </span>\n <span\n className={cn(\n position.side === \"long\"\n ? \"text-bullish\"\n : \"text-bearish\",\n )}\n >\n {position.leverage}x {position.side.toUpperCase()}\n </span>\n </div>\n </td>\n\n {/* Position */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#ffffff\" }}\n >\n {formatQuantity(position.quantity)}\n </td>\n\n {/* Position Value */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#ffffff\" }}\n >\n ${formatNumber(position.notionalValue)}\n </td>\n\n {/* Entry Price */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#ffffff\" }}\n >\n ${formatPrice(position.entryPrice)}\n </td>\n\n {/* Mark Price */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#ffffff\" }}\n >\n ${formatPrice(position.markPrice)}\n </td>\n\n {/* Liquidation Price */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#ffffff\" }}\n >\n {position.liquidationPrice\n ? `$${formatPrice(position.liquidationPrice)}`\n : \"-\"}\n </td>\n\n {/* Margin Used (PnL) */}\n <td className=\"py-1.5 px-3 text-right\">\n <div className=\"flex flex-col items-end\">\n <span style={{ color: \"#ffffff\" }}>\n ${formatNumber(position.margin)}\n </span>\n <span className={pnlColor}>\n {formatPnl(position.unrealizedPnl)} (\n {formatPnlPercent(position.unrealizedPnlPercent)})\n </span>\n </div>\n </td>\n\n {/* TP */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#b5b5b5\" }}\n >\n -\n </td>\n\n {/* SL */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#b5b5b5\" }}\n >\n -\n </td>\n\n {/* Close */}\n <td className=\"py-1.5 px-3 text-right\">\n <Button\n size=\"sm\"\n onClick={() => onClosePosition(position)}\n isLoading={isClosing}\n className=\"bg-red-600 hover:bg-red-700 text-white text-xs px-3 py-1\"\n >\n Close\n </Button>\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n );\n}\n\n/** Loading skeleton for positions panel */\nexport function PositionsSkeleton() {\n return (\n <div className=\"w-full space-y-4 p-4\">\n <div className=\"h-4 bg-neutral-800 rounded w-full animate-pulse\" />\n <div className=\"h-4 bg-neutral-800 rounded w-full animate-pulse\" />\n <div className=\"h-4 bg-neutral-800 rounded w-full animate-pulse\" />\n </div>\n );\n}\n\n/** Empty state when there are no open positions */\nexport function PositionsEmpty() {\n return (\n <div\n className=\"flex items-center justify-center h-24\"\n style={{ fontSize: 14, color: \"#b5b5b5\" }}\n >\n No open positions\n </div>\n );\n}\n","import { usePositionsScript } from \"./positions.script\";\nimport { PositionsUI, PositionsSkeleton, PositionsEmpty } from \"./positions.ui\";\n\nexport type PositionsWidgetProps = {\n userAddress?: string;\n symbol?: string;\n onCloseSuccess?: () => void;\n onCloseError?: (error: Error) => void;\n className?: string;\n};\n\nexport function PositionsWidget({\n userAddress,\n symbol,\n onCloseSuccess,\n onCloseError,\n className,\n}: PositionsWidgetProps) {\n const { positions, isLoading, handleClosePosition, isClosing } =\n usePositionsScript({\n userAddress,\n symbol,\n onCloseSuccess,\n onCloseError,\n });\n\n if (isLoading) {\n return (\n <div className={className}>\n <PositionsSkeleton />\n </div>\n );\n }\n\n return (\n <div className={className}>\n <PositionsUI\n positions={positions}\n onClosePosition={handleClosePosition}\n isClosing={isClosing}\n />\n </div>\n );\n}\n","import { useState, useEffect, useCallback } from \"react\";\nimport { useCancelOrderMutation } from \"../../hooks/useCancelOrderMutation\";\nimport { useOrdersQuery } from \"../../hooks/useOrdersQuery\";\nimport { useUserDataSubscription } from \"../../hooks/useUserDataSubscription\";\nimport type { Order } from \"../../types\";\n\nexport type UseOpenOrdersScriptParams = {\n userAddress?: string;\n symbol?: string;\n onCancelSuccess?: () => void;\n onCancelError?: (error: Error) => void;\n};\n\nexport type UseOpenOrdersScriptResult = {\n orders: Order[];\n isLoading: boolean;\n error: Error | null;\n handleCancelOrder: (order: Order) => Promise<void>;\n isCanceling: boolean;\n};\n\nexport function useOpenOrdersScript({\n userAddress,\n symbol,\n onCancelSuccess,\n onCancelError,\n}: UseOpenOrdersScriptParams): UseOpenOrdersScriptResult {\n const [orders, setOrders] = useState<Order[]>([]);\n\n // Fetch initial orders data\n const {\n data: ordersData,\n isLoading,\n error,\n } = useOrdersQuery({ userAddress, symbol }, { enabled: !!userAddress });\n\n // Subscribe to realtime order updates\n const { data: realtimeOrder } = useUserDataSubscription<Order>({\n type: \"orders\",\n userAddress: userAddress || \"\",\n enabled: !!userAddress,\n });\n\n // Cancel order mutation\n const { mutateAsync: cancelOrder, isPending: isCanceling } =\n useCancelOrderMutation({\n onSuccess: () => {\n onCancelSuccess?.();\n },\n onError: (error) => {\n onCancelError?.(error);\n },\n });\n\n // Initialize orders data\n useEffect(() => {\n if (ordersData?.orders) {\n setOrders(ordersData.orders);\n }\n }, [ordersData]);\n\n // Handle realtime order updates\n useEffect(() => {\n if (realtimeOrder) {\n setOrders((prevOrders) => {\n const existingIndex = prevOrders.findIndex(\n (o) => o.orderId === realtimeOrder.orderId,\n );\n\n // If order is cancelled, filled or rejected, remove from list\n if (\n realtimeOrder.status === \"cancelled\" ||\n realtimeOrder.status === \"filled\" ||\n realtimeOrder.status === \"rejected\"\n ) {\n if (existingIndex !== -1) {\n return prevOrders.filter((_, i) => i !== existingIndex);\n }\n return prevOrders;\n }\n\n // Update existing order\n if (existingIndex !== -1) {\n const newOrders = [...prevOrders];\n newOrders[existingIndex] = realtimeOrder;\n return newOrders;\n }\n\n // Add new order\n return [realtimeOrder, ...prevOrders];\n });\n }\n }, [realtimeOrder]);\n\n // Handle cancel order\n const handleCancelOrder = useCallback(\n async (order: Order) => {\n if (!userAddress) {\n throw new Error(\"User address is required\");\n }\n\n await cancelOrder({\n orderId: order.orderId,\n symbol: order.symbol,\n userAddress,\n });\n },\n [userAddress, cancelOrder],\n );\n\n return {\n orders,\n isLoading,\n error,\n handleCancelOrder,\n isCanceling,\n };\n}\n","import { Button, cn } from \"@liberfi.io/ui\";\nimport type { Order } from \"../../types\";\n\nexport type OpenOrdersUIProps = {\n orders: Order[];\n onCancelOrder: (order: Order) => void;\n isCanceling: boolean;\n};\n\nfunction formatNumber(num: number, decimals: number = 2): string {\n return num.toFixed(decimals);\n}\n\nfunction formatPrice(price: number): string {\n return formatNumber(price, 4);\n}\n\nfunction formatQuantity(quantity: number): string {\n return formatNumber(quantity, 4);\n}\n\nfunction formatTime(timestamp: number): string {\n const date = new Date(timestamp);\n const hours = String(date.getHours()).padStart(2, \"0\");\n const minutes = String(date.getMinutes()).padStart(2, \"0\");\n const seconds = String(date.getSeconds()).padStart(2, \"0\");\n return `${hours}:${minutes}:${seconds}`;\n}\n\nexport function OpenOrdersUI({\n orders,\n onCancelOrder,\n isCanceling,\n}: OpenOrdersUIProps) {\n if (orders.length === 0) {\n return (\n <div\n className=\"flex items-center justify-center h-24\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n No open orders\n </div>\n );\n }\n\n return (\n <div className=\"w-full overflow-x-auto bg-transparent\">\n <table className=\"w-full\" style={{ fontSize: 11 }}>\n <thead>\n <tr style={{ borderBottom: \"1px solid #1c1c1c\" }}>\n <th\n className=\"text-left py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Asset\n </th>\n <th\n className=\"text-left py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Type\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Price\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Amount\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Filled\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Remaining\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Status\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Time\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Action\n </th>\n </tr>\n </thead>\n <tbody>\n {orders.map((order) => {\n return (\n <tr\n key={order.orderId}\n className=\"hover:bg-neutral-900/50\"\n style={{ borderBottom: \"1px solid #1c1c1c\" }}\n >\n {/* Asset */}\n <td className=\"py-1.5 px-3\">\n <div className=\"flex flex-col\">\n <span className=\"font-medium\" style={{ color: \"#ffffff\" }}>\n {order.symbol.split(\"-\")[0]}\n </span>\n <span\n className={cn(\n order.side === \"long\" ? \"text-bullish\" : \"text-bearish\",\n )}\n >\n {order.side.toUpperCase()}\n {order.leverage ? ` ${order.leverage}x` : \"\"}\n </span>\n </div>\n </td>\n\n {/* Type */}\n <td\n className=\"py-1.5 px-3 capitalize\"\n style={{ color: \"#ffffff\" }}\n >\n {order.orderType}\n </td>\n\n {/* Price */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#ffffff\" }}\n >\n {order.orderType === \"market\" ? (\n <span style={{ color: \"#b5b5b5\" }}>Market</span>\n ) : (\n `$${formatPrice(order.price)}`\n )}\n </td>\n\n {/* Amount */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#ffffff\" }}\n >\n {formatQuantity(order.quantity)}\n </td>\n\n {/* Filled */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#ffffff\" }}\n >\n {formatQuantity(order.filledQuantity)}\n </td>\n\n {/* Remaining */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#ffffff\" }}\n >\n {formatQuantity(order.remainingQuantity)}\n </td>\n\n {/* Status */}\n <td className=\"py-1.5 px-3 text-right\">\n <span\n className={cn(\n \"px-2 py-0.5 rounded\",\n \"text-[11px]\",\n order.status === \"pending\" &&\n \"bg-yellow-600/20 text-yellow-500\",\n order.status === \"partially_filled\" &&\n \"bg-blue-600/20 text-blue-500\",\n order.status === \"filled\" &&\n \"bg-green-600/20 text-green-500\",\n order.status === \"cancelled\" &&\n \"bg-neutral-600/20 text-neutral-400\",\n order.status === \"rejected\" &&\n \"bg-red-600/20 text-red-500\",\n )}\n >\n {order.status.replace(\"_\", \" \")}\n </span>\n </td>\n\n {/* Time */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#b5b5b5\" }}\n >\n {formatTime(order.timestamp)}\n </td>\n\n {/* Action */}\n <td className=\"py-1.5 px-3 text-right\">\n {order.status === \"pending\" ||\n order.status === \"partially_filled\" ? (\n <Button\n size=\"sm\"\n onClick={() => onCancelOrder(order)}\n isLoading={isCanceling}\n className=\"bg-red-600 hover:bg-red-700 text-white text-xs px-3 py-1\"\n >\n Cancel\n </Button>\n ) : (\n <span className=\"text-[11px]\" style={{ color: \"#6b6d7a\" }}>\n -\n </span>\n )}\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n );\n}\n\n// Loading skeleton component\nexport function OpenOrdersSkeleton() {\n return (\n <div className=\"w-full space-y-4 p-4\">\n <div className=\"h-4 bg-neutral-800 rounded w-full animate-pulse\" />\n <div className=\"h-4 bg-neutral-800 rounded w-full animate-pulse\" />\n <div className=\"h-4 bg-neutral-800 rounded w-full animate-pulse\" />\n </div>\n );\n}\n\n// Empty state component\nexport function OpenOrdersEmpty() {\n return (\n <div\n className=\"flex items-center justify-center h-24\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n No open orders\n </div>\n );\n}\n","import { useOpenOrdersScript } from \"./open-orders.script\";\nimport {\n OpenOrdersUI,\n OpenOrdersSkeleton,\n OpenOrdersEmpty,\n} from \"./open-orders.ui\";\n\nexport type OpenOrdersWidgetProps = {\n userAddress?: string;\n symbol?: string;\n onCancelSuccess?: () => void;\n onCancelError?: (error: Error) => void;\n className?: string;\n};\n\nexport function OpenOrdersWidget({\n userAddress,\n symbol,\n onCancelSuccess,\n onCancelError,\n className,\n}: OpenOrdersWidgetProps) {\n const { orders, isLoading, handleCancelOrder, isCanceling } =\n useOpenOrdersScript({\n userAddress,\n symbol,\n onCancelSuccess,\n onCancelError,\n });\n\n if (isLoading) {\n return (\n <div className={className}>\n <OpenOrdersSkeleton />\n </div>\n );\n }\n\n if (orders.length === 0) {\n return (\n <div className={className}>\n <OpenOrdersEmpty />\n </div>\n );\n }\n\n return (\n <div className={className}>\n <OpenOrdersUI\n orders={orders}\n onCancelOrder={handleCancelOrder}\n isCanceling={isCanceling}\n />\n </div>\n );\n}\n","import { useState, useEffect } from \"react\";\nimport { useTradesQuery } from \"../../hooks/useTradesQuery\";\nimport type { TradeHistory } from \"../../types\";\n\nexport type TimeRange = \"today\" | \"7d\" | \"30d\" | \"all\";\n\nexport type UseTradeHistoryScriptParams = {\n userAddress?: string;\n symbol?: string;\n initialTimeRange?: TimeRange;\n pageSize?: number;\n};\n\nexport type UseTradeHistoryScriptResult = {\n trades: TradeHistory[];\n isLoading: boolean;\n error: Error | null;\n timeRange: TimeRange;\n setTimeRange: (range: TimeRange) => void;\n currentPage: number;\n totalPages: number;\n goToNextPage: () => void;\n goToPreviousPage: () => void;\n goToPage: (page: number) => void;\n};\n\nfunction getTimeRangeInMs(range: TimeRange): {\n startTime?: number;\n endTime?: number;\n} {\n const now = Date.now();\n const endTime = now;\n\n switch (range) {\n case \"today\":\n const today = new Date();\n today.setHours(0, 0, 0, 0);\n return { startTime: today.getTime(), endTime };\n case \"7d\":\n return { startTime: now - 7 * 24 * 60 * 60 * 1000, endTime };\n case \"30d\":\n return { startTime: now - 30 * 24 * 60 * 60 * 1000, endTime };\n case \"all\":\n default:\n return {};\n }\n}\n\nexport function useTradeHistoryScript({\n userAddress,\n symbol,\n initialTimeRange = \"7d\",\n pageSize = 50,\n}: UseTradeHistoryScriptParams): UseTradeHistoryScriptResult {\n const [timeRange, setTimeRange] = useState<TimeRange>(initialTimeRange);\n const [currentPage, setCurrentPage] = useState(1);\n const [allTrades, setAllTrades] = useState<TradeHistory[]>([]);\n\n const { startTime, endTime } = getTimeRangeInMs(timeRange);\n\n // Fetch trades with time range filter\n const {\n data: tradesData,\n isLoading,\n error,\n } = useTradesQuery(\n {\n userAddress,\n symbol,\n startTime,\n endTime,\n limit: 1000, // Fetch more data for client-side pagination\n },\n { enabled: !!userAddress },\n );\n\n // Update all trades when data changes\n useEffect(() => {\n if (tradesData?.trades) {\n setAllTrades(tradesData.trades);\n setCurrentPage(1); // Reset to first page when data changes\n }\n }, [tradesData]);\n\n // Reset page when time range changes\n useEffect(() => {\n setCurrentPage(1);\n }, [timeRange]);\n\n // Calculate pagination\n const totalPages = Math.ceil(allTrades.length / pageSize);\n const startIndex = (currentPage - 1) * pageSize;\n const endIndex = startIndex + pageSize;\n const trades = allTrades.slice(startIndex, endIndex);\n\n const goToNextPage = () => {\n if (currentPage < totalPages) {\n setCurrentPage(currentPage + 1);\n }\n };\n\n const goToPreviousPage = () => {\n if (currentPage > 1) {\n setCurrentPage(currentPage - 1);\n }\n };\n\n const goToPage = (page: number) => {\n if (page >= 1 && page <= totalPages) {\n setCurrentPage(page);\n }\n };\n\n return {\n trades,\n isLoading,\n error,\n timeRange,\n setTimeRange,\n currentPage,\n totalPages,\n goToNextPage,\n goToPreviousPage,\n goToPage,\n };\n}\n","import { Button, cn } from \"@liberfi.io/ui\";\nimport type { TradeHistory } from \"../../types\";\nimport type { TimeRange } from \"./trade-history.script\";\n\nexport type TradeHistoryUIProps = {\n trades: TradeHistory[];\n timeRange: TimeRange;\n onTimeRangeChange: (range: TimeRange) => void;\n currentPage: number;\n totalPages: number;\n onNextPage: () => void;\n onPreviousPage: () => void;\n onGoToPage: (page: number) => void;\n};\n\nfunction formatNumber(num: number, decimals: number = 2): string {\n return num.toFixed(decimals);\n}\n\nfunction formatPrice(price: number): string {\n return formatNumber(price, 4);\n}\n\nfunction formatQuantity(quantity: number): string {\n return formatNumber(quantity, 4);\n}\n\nfunction formatDateTime(timestamp: number): string {\n const date = new Date(timestamp);\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\n const day = String(date.getDate()).padStart(2, \"0\");\n const hours = String(date.getHours()).padStart(2, \"0\");\n const minutes = String(date.getMinutes()).padStart(2, \"0\");\n const seconds = String(date.getSeconds()).padStart(2, \"0\");\n return `${month}/${day} ${hours}:${minutes}:${seconds}`;\n}\n\nconst TIME_RANGE_OPTIONS: { label: string; value: TimeRange }[] = [\n { label: \"Today\", value: \"today\" },\n { label: \"7 Days\", value: \"7d\" },\n { label: \"30 Days\", value: \"30d\" },\n { label: \"All\", value: \"all\" },\n];\n\nexport function TradeHistoryUI({\n trades,\n timeRange,\n onTimeRangeChange,\n currentPage,\n totalPages,\n onNextPage,\n onPreviousPage,\n onGoToPage,\n}: TradeHistoryUIProps) {\n return (\n <div className=\"w-full flex flex-col gap-4\">\n {/* Time range filter */}\n <div className=\"flex gap-2\">\n {TIME_RANGE_OPTIONS.map((option) => {\n const selected = timeRange === option.value;\n return (\n <button\n key={option.value}\n type=\"button\"\n className={cn(\n \"rounded px-3 transition-colors\",\n !selected && \"hover:bg-[#1A1A1A]\",\n )}\n style={{\n height: 24,\n fontSize: 11,\n border: \"1px solid #1c1c1c\",\n backgroundColor: selected ? \"#1c1c1c\" : \"transparent\",\n color: selected ? \"#ffffff\" : \"#b5b5b5\",\n }}\n onClick={() => onTimeRangeChange(option.value)}\n >\n {option.label}\n </button>\n );\n })}\n </div>\n\n {/* Trade history table */}\n {trades.length === 0 ? (\n <div\n className=\"flex items-center justify-center h-24\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n No trade history\n </div>\n ) : (\n <>\n <div className=\"w-full overflow-x-auto bg-transparent\">\n <table className=\"w-full\" style={{ fontSize: 11 }}>\n <thead>\n <tr style={{ borderBottom: \"1px solid #1c1c1c\" }}>\n <th\n className=\"text-left py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Asset\n </th>\n <th\n className=\"text-left py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Side\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Price\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Quantity\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Fee\n </th>\n <th\n className=\"text-center py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Maker/Taker\n </th>\n <th\n className=\"text-right py-1.5 px-3 font-normal\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n Time\n </th>\n </tr>\n </thead>\n <tbody>\n {trades.map((trade) => (\n <tr\n key={trade.tradeId}\n className=\"hover:bg-neutral-900/50\"\n style={{ borderBottom: \"1px solid #1c1c1c\" }}\n >\n {/* Asset */}\n <td\n className=\"py-1.5 px-3 font-medium\"\n style={{ color: \"#ffffff\" }}\n >\n {trade.symbol.split(\"-\")[0]}\n </td>\n\n {/* Side */}\n <td className=\"py-1.5 px-3\">\n <span\n className={cn(\n \"px-2 py-0.5 rounded text-[11px]\",\n trade.side === \"long\"\n ? \"bg-bullish/20 text-bullish\"\n : \"bg-bearish/20 text-bearish\",\n )}\n >\n {trade.side.toUpperCase()}\n </span>\n </td>\n\n {/* Price */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#ffffff\" }}\n >\n ${formatPrice(trade.price)}\n </td>\n\n {/* Quantity */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#ffffff\" }}\n >\n {formatQuantity(trade.quantity)}\n </td>\n\n {/* Fee */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#ffffff\" }}\n >\n {formatNumber(trade.fee, 4)} {trade.feeCurrency}\n </td>\n\n {/* Maker/Taker */}\n <td className=\"py-1.5 px-3 text-center\">\n <span\n className={cn(\n \"px-2 py-0.5 rounded text-[11px]\",\n trade.isMaker\n ? \"bg-blue-600/20 text-blue-500\"\n : \"bg-purple-600/20 text-purple-500\",\n )}\n >\n {trade.isMaker ? \"Maker\" : \"Taker\"}\n </span>\n </td>\n\n {/* Time */}\n <td\n className=\"py-1.5 px-3 text-right\"\n style={{ color: \"#b5b5b5\" }}\n >\n {formatDateTime(trade.timestamp)}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n\n {/* Pagination */}\n {totalPages > 1 && (\n <div className=\"flex items-center justify-between\">\n <div className=\"text-sm text-neutral-400\">\n Page {currentPage} of {totalPages}\n </div>\n <div className=\"flex gap-2\">\n <Button\n size=\"sm\"\n onClick={onPreviousPage}\n disabled={currentPage === 1}\n className=\"bg-neutral-800 hover:bg-neutral-700 text-white disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n Previous\n </Button>\n {/* Page numbers */}\n <div className=\"flex gap-1\">\n {Array.from({ length: Math.min(5, totalPages) }, (_, i) => {\n let pageNum: number;\n if (totalPages <= 5) {\n pageNum = i + 1;\n } else if (currentPage <= 3) {\n pageNum = i + 1;\n } else if (currentPage >= totalPages - 2) {\n pageNum = totalPages - 4 + i;\n } else {\n pageNum = currentPage - 2 + i;\n }\n\n return (\n <button\n key={pageNum}\n type=\"button\"\n className={cn(\n \"w-8 h-8 text-sm rounded transition-colors\",\n currentPage === pageNum\n ? \"bg-neutral-700 text-white\"\n : \"text-neutral-400 hover:bg-neutral-800 hover:text-white\",\n )}\n onClick={() => onGoToPage(pageNum)}\n >\n {pageNum}\n </button>\n );\n })}\n </div>\n <Button\n size=\"sm\"\n onClick={onNextPage}\n disabled={currentPage === totalPages}\n className=\"bg-neutral-800 hover:bg-neutral-700 text-white disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n Next\n </Button>\n </div>\n </div>\n )}\n </>\n )}\n </div>\n );\n}\n\n// Loading skeleton component\nexport function TradeHistorySkeleton() {\n return (\n <div className=\"w-full space-y-4 p-4\">\n <div className=\"h-4 bg-neutral-800 rounded w-full animate-pulse\" />\n <div className=\"h-4 bg-neutral-800 rounded w-full animate-pulse\" />\n <div className=\"h-4 bg-neutral-800 rounded w-full animate-pulse\" />\n </div>\n );\n}\n\n// Empty state component\nexport function TradeHistoryEmpty() {\n return (\n <div\n className=\"flex items-center justify-center h-24\"\n style={{ fontSize: 11, color: \"#b5b5b5\" }}\n >\n No trade history\n </div>\n );\n}\n","import { useTradeHistoryScript } from \"./trade-history.script\";\nimport type { TimeRange } from \"./trade-history.script\";\nimport {\n TradeHistoryUI,\n TradeHistorySkeleton,\n TradeHistoryEmpty,\n} from \"./trade-history.ui\";\n\nexport type TradeHistoryWidgetProps = {\n userAddress?: string;\n symbol?: string;\n initialTimeRange?: TimeRange;\n pageSize?: number;\n className?: string;\n};\n\nexport function TradeHistoryWidget({\n userAddress,\n symbol,\n initialTimeRange = \"7d\",\n pageSize = 50,\n className,\n}: TradeHistoryWidgetProps) {\n const {\n trades,\n isLoading,\n timeRange,\n setTimeRange,\n currentPage,\n totalPages,\n goToNextPage,\n goToPreviousPage,\n goToPage,\n } = useTradeHistoryScript({\n userAddress,\n symbol,\n initialTimeRange,\n pageSize,\n });\n\n if (isLoading) {\n return (\n <div className={className}>\n <TradeHistorySkeleton />\n </div>\n );\n }\n\n if (trades.length === 0) {\n return (\n <div className={className}>\n <TradeHistoryEmpty />\n </div>\n );\n }\n\n return (\n <div className={className}>\n <TradeHistoryUI\n trades={trades}\n timeRange={timeRange}\n onTimeRangeChange={setTimeRange}\n currentPage={currentPage}\n totalPages={totalPages}\n onNextPage={goToNextPage}\n onPreviousPage={goToPreviousPage}\n onGoToPage={goToPage}\n />\n </div>\n );\n}\n","/**\n * Tiny number-formatting helpers shared by the deposit UI.\n *\n * We use plain `bigint` arithmetic here — never `Number(...)` on a\n * lamport / microUSDC value — so we never silently lose precision on\n * deposits that exceed `Number.MAX_SAFE_INTEGER` lamports.\n */\n\nconst LAMPORTS_PER_SOL = 1_000_000_000n;\n\n/**\n * Hyperliquid credits perp USDC at 8-decimal granularity (NOT the 6\n * decimals used by ERC-20 USDC on Arbitrum). Relay's `currencyOut.amount`\n * for a Hyperliquid bridge quote is therefore expressed in HL perp units\n * — divide by 1e8 to get the human-readable USDC amount.\n */\nexport const HL_USDC_DECIMALS = 8;\nconst HL_USDC_DIVISOR = 10n ** BigInt(HL_USDC_DECIMALS);\n\n/**\n * Convert a lamport amount (string bigint) to a SOL-denominated string\n * with `precision` decimals and trailing zeros stripped.\n */\nexport function lamportsToSol(value: string, precision = 4): string {\n if (!value) return \"0\";\n let n: bigint;\n try {\n n = BigInt(value);\n } catch {\n return \"0\";\n }\n return divToFixed(n, LAMPORTS_PER_SOL, precision);\n}\n\n/**\n * Convert a raw Hyperliquid USDC amount (8 decimals) to a USDC display\n * string with `precision` decimals and trailing zeros stripped.\n *\n * This is the unit returned by the perpetuals-server `/deposits/quote`\n * endpoint in `breakdown.expectedOutputUSDC` — it mirrors Hyperliquid's\n * internal perp-account precision, NOT the 6-decimal USDC token on\n * Arbitrum.\n */\nexport function hlUsdcRawToUsdc(\n value: string | undefined,\n precision = 2,\n): string {\n if (!value) return \"0\";\n let n: bigint;\n try {\n n = BigInt(value);\n } catch {\n return \"0\";\n }\n return divToFixed(n, HL_USDC_DIVISOR, precision);\n}\n\n/**\n * @deprecated Use {@link hlUsdcRawToUsdc} instead. The previous name\n * implied a 6-decimal microUSDC unit, but the Hyperliquid bridge actually\n * returns amounts at 8-decimal precision. Kept as a thin alias to avoid\n * a hard break for downstream callers; remove after consumers migrate.\n */\nexport const microUsdcToUsdc = hlUsdcRawToUsdc;\n\n/** Convert a SOL-denominated decimal string to a lamport `string` (bigint). */\nexport function solToLamports(value: string): string {\n if (!value) return \"0\";\n const [whole, frac = \"\"] = value.replace(/[\\s,]/g, \"\").split(\".\");\n if (!/^\\d*$/.test(whole) || !/^\\d*$/.test(frac)) return \"0\";\n // Pad / truncate the fractional component to 9 digits to match SOL.\n const fracPadded = (frac + \"000000000\").slice(0, 9);\n const combined = `${whole || \"0\"}${fracPadded}`.replace(/^0+(?=\\d)/, \"\");\n return combined === \"\" ? \"0\" : combined;\n}\n\nfunction divToFixed(\n numerator: bigint,\n denominator: bigint,\n precision: number,\n): string {\n const negative = numerator < 0n;\n const abs = negative ? -numerator : numerator;\n let whole = abs / denominator;\n const remainder = abs % denominator;\n if (precision <= 0) {\n // Round to nearest integer when precision is 0.\n if (remainder * 2n >= denominator) whole += 1n;\n return `${negative ? \"-\" : \"\"}${whole.toString()}`;\n }\n const scale = 10n ** BigInt(precision);\n let scaledRemainder = (remainder * scale + denominator / 2n) / denominator;\n // Carry over to the whole part when half-rounding pushed the fractional\n // component to or above `scale` (e.g. 0.999999 with precision 2 -> 1.00).\n if (scaledRemainder >= scale) {\n whole += 1n;\n scaledRemainder = 0n;\n }\n let frac = scaledRemainder.toString().padStart(precision, \"0\");\n // Trim trailing zeros for nicer display.\n frac = frac.replace(/0+$/, \"\");\n if (!frac) return `${negative ? \"-\" : \"\"}${whole.toString()}`;\n return `${negative ? \"-\" : \"\"}${whole.toString()}.${frac}`;\n}\n\n/** Returns whole-second countdown until `expiresAtMs`. Negative -> 0. */\nexport function secondsUntil(\n expiresAtMs: number,\n nowMs: number = Date.now(),\n): number {\n return Math.max(0, Math.floor((expiresAtMs - nowMs) / 1000));\n}\n\n/** Truncate an address to `head…tail` for display. */\nexport function shortAddress(addr: string, head = 6, tail = 4): string {\n if (!addr) return \"\";\n if (addr.length <= head + tail + 1) return addr;\n return `${addr.slice(0, head)}…${addr.slice(-tail)}`;\n}\n","import { useEffect, useState } from \"react\";\nimport { useTranslation } from \"@liberfi.io/i18n\";\nimport {\n Button,\n Modal,\n ModalBody,\n ModalContent,\n ModalFooter,\n ModalHeader,\n Spinner,\n} from \"@liberfi.io/ui\";\nimport type {\n DepositBreakdown,\n DepositQuoteResponse,\n} from \"../../client/liberfi/deposit-types\";\nimport { lamportsToSol, hlUsdcRawToUsdc, secondsUntil } from \"./format\";\n\n/**\n * Pure presentational confirm modal for the deposit flow.\n *\n * Owns no fetching or signing — it just renders the breakdown and\n * fires `onConfirm` / `onCancel`. The expiry countdown ticks locally\n * via setInterval and re-renders once a second; when it hits 0 the\n * `onExpire` callback fires (the parent should refetch the quote).\n */\nexport interface DepositConfirmUIProps {\n isOpen: boolean;\n /** Quote currently being shown to the user. Required when `isOpen`. */\n quote: DepositQuoteResponse | undefined;\n /** True while `/submit` (or wallet sign) is in flight. Disables the CTA. */\n isExecuting?: boolean;\n /** True when the displayed quote has already expired. */\n isExpired?: boolean;\n onConfirm: () => void;\n onCancel: () => void;\n /** Fires when the local countdown reaches zero. */\n onExpire?: () => void;\n /** Optional inline error to surface inside the modal. */\n error?: string;\n}\n\nexport function DepositConfirmUI({\n isOpen,\n quote,\n isExecuting,\n isExpired,\n onConfirm,\n onCancel,\n onExpire,\n error,\n}: DepositConfirmUIProps) {\n const { t } = useTranslation();\n\n const expiresAtMs = quote ? Date.parse(quote.expiresAt) : 0;\n const [secondsLeft, setSecondsLeft] = useState(() =>\n expiresAtMs ? secondsUntil(expiresAtMs) : 0,\n );\n\n useEffect(() => {\n if (!isOpen || !expiresAtMs) return;\n setSecondsLeft(secondsUntil(expiresAtMs));\n const id = setInterval(() => {\n const remaining = secondsUntil(expiresAtMs);\n setSecondsLeft(remaining);\n if (remaining === 0) {\n onExpire?.();\n clearInterval(id);\n }\n }, 1000);\n return () => clearInterval(id);\n }, [isOpen, expiresAtMs, onExpire]);\n\n return (\n <Modal\n isOpen={isOpen}\n onOpenChange={(next) => !next && onCancel()}\n hideCloseButton\n backdrop=\"blur\"\n >\n <ModalContent className=\"bg-content2 rounded-lg\">\n <ModalHeader>{t(\"perpDeposit.confirm.title\")}</ModalHeader>\n <ModalBody>\n {!quote ? (\n <div className=\"flex h-32 items-center justify-center\">\n <Spinner />\n </div>\n ) : (\n <BreakdownSummary breakdown={quote.breakdown} />\n )}\n\n {quote && !isExpired && (\n <div className=\"text-default-500 mt-4 text-xs\">\n {t(\"perpDeposit.confirm.expiresIn\", { seconds: secondsLeft })}\n </div>\n )}\n {isExpired && (\n <div className=\"text-warning-500 mt-4 text-xs\">\n {t(\"perpDeposit.confirm.expired\")}\n </div>\n )}\n {error && <div className=\"text-danger mt-4 text-xs\">{error}</div>}\n </ModalBody>\n <ModalFooter className=\"flex justify-between gap-2\">\n <Button\n variant=\"flat\"\n color=\"default\"\n onPress={onCancel}\n isDisabled={isExecuting}\n >\n {t(\"perpDeposit.confirm.cancel\")}\n </Button>\n <Button\n color=\"primary\"\n onPress={onConfirm}\n isDisabled={!quote || isExecuting || isExpired}\n isLoading={isExecuting}\n >\n {t(\"perpDeposit.confirm.cta\")}\n </Button>\n </ModalFooter>\n </ModalContent>\n </Modal>\n );\n}\n\ninterface BreakdownSummaryProps {\n breakdown: DepositBreakdown;\n}\n\nfunction BreakdownSummary({ breakdown }: BreakdownSummaryProps) {\n const { t } = useTranslation();\n return (\n <dl className=\"flex flex-col gap-2 text-sm\">\n <Row\n label={t(\"perpDeposit.confirm.send\")}\n value={`${lamportsToSol(breakdown.grossLamports)} SOL`}\n />\n <Row\n label={t(\"perpDeposit.confirm.receive\")}\n value={`${hlUsdcRawToUsdc(breakdown.expectedOutputUSDC)} USDC`}\n highlight\n />\n <Row\n label={t(\"perpDeposit.confirm.platformFee\")}\n value={`${lamportsToSol(breakdown.platformFeeLamports, 6)} SOL`}\n muted\n />\n <Row\n label={t(\"perpDeposit.confirm.relayFee\")}\n value={`${lamportsToSol(breakdown.relayDepositLamports, 6)} SOL`}\n muted\n />\n </dl>\n );\n}\n\ninterface RowProps {\n label: string;\n value: string;\n highlight?: boolean;\n muted?: boolean;\n}\n\nfunction Row({ label, value, highlight, muted }: RowProps) {\n return (\n <div className=\"flex items-center justify-between\">\n <dt className=\"text-default-500\">{label}</dt>\n <dd\n className={\n highlight\n ? \"text-foreground text-base font-semibold\"\n : muted\n ? \"text-default-500 text-xs\"\n : \"text-foreground\"\n }\n >\n {value}\n </dd>\n </div>\n );\n}\n","import { useTranslation } from \"@liberfi.io/i18n\";\nimport { Button, Input, cn } from \"@liberfi.io/ui\";\n\n/**\n * Pure presentational form for collecting the deposit amount + the\n * Hyperliquid recipient address.\n *\n * No data fetching, no state — every input is controlled from above.\n * Lets the host app decide when to show the wallet's connected SOL\n * balance (or omit it entirely).\n */\nexport interface DepositFormUIProps {\n amount: string;\n onAmountChange: (value: string) => void;\n recipient: string;\n onRecipientChange: (value: string) => void;\n /** Optional: shown as the \"Balance: …\" hint above the amount input. */\n balanceSol?: string;\n /** Disables every interactive control (e.g. while quoting). */\n disabled?: boolean;\n /** Inline error to render under the amount input. */\n amountError?: string;\n /** Inline error to render under the recipient input. */\n recipientError?: string;\n /** Click handler for \"Max\" — only rendered when `balanceSol` is set. */\n onMax?: () => void;\n className?: string;\n}\n\nexport function DepositFormUI({\n amount,\n onAmountChange,\n recipient,\n onRecipientChange,\n balanceSol,\n disabled,\n amountError,\n recipientError,\n onMax,\n className,\n}: DepositFormUIProps) {\n const { t } = useTranslation();\n return (\n <div className={cn(\"flex flex-col gap-4\", className)}>\n <div>\n <div className=\"flex items-center justify-between mb-1.5\">\n <label\n htmlFor=\"perp-deposit-amount\"\n className=\"text-sm font-medium text-foreground\"\n >\n {t(\"perpDeposit.amount\")}\n </label>\n {balanceSol && (\n <span className=\"text-xs text-default-500\">\n {t(\"perpDeposit.amount.balance\", { balance: balanceSol })}\n </span>\n )}\n </div>\n <div className=\"relative\">\n <Input\n id=\"perp-deposit-amount\"\n type=\"text\"\n inputMode=\"decimal\"\n placeholder={t(\"perpDeposit.amount.placeholder\")}\n value={amount}\n onValueChange={onAmountChange}\n isDisabled={disabled}\n isInvalid={Boolean(amountError)}\n errorMessage={amountError}\n endContent={\n <div className=\"flex items-center gap-2\">\n <span className=\"text-default-500 text-sm\">\n {t(\"perpDeposit.amount.unit\")}\n </span>\n {balanceSol && onMax && (\n <Button\n size=\"sm\"\n variant=\"flat\"\n color=\"primary\"\n onPress={onMax}\n isDisabled={disabled}\n >\n {t(\"perpDeposit.amount.max\")}\n </Button>\n )}\n </div>\n }\n />\n </div>\n </div>\n\n <div>\n <label\n htmlFor=\"perp-deposit-recipient\"\n className=\"text-sm font-medium text-foreground mb-1.5 block\"\n >\n {t(\"perpDeposit.recipient\")}\n </label>\n <Input\n id=\"perp-deposit-recipient\"\n type=\"text\"\n placeholder={t(\"perpDeposit.recipient.placeholder\")}\n value={recipient}\n onValueChange={onRecipientChange}\n isDisabled={disabled}\n isInvalid={Boolean(recipientError)}\n errorMessage={recipientError}\n autoComplete=\"off\"\n spellCheck=\"false\"\n />\n </div>\n </div>\n );\n}\n","import { useTranslation } from \"@liberfi.io/i18n\";\nimport { ModalContent, StyledModal, XCloseIcon, cn } from \"@liberfi.io/ui\";\nimport type { DepositPhase } from \"../../client/liberfi/deposit-state-machine\";\nimport type { DepositStatusResponse } from \"../../client/liberfi/deposit-types\";\nimport { shortAddress } from \"./format\";\n\n/**\n * Polished progress / result panel for the SOL → Hyperliquid USDC\n * deposit flow.\n *\n * Visual design intentionally mirrors the swap-style deposit form\n * modal (dark surface, 14 px radius, accent-color spinner / icons,\n * pill-style transaction links) so the in-flight, success and failure\n * states all feel like the same product surface rather than a generic\n * HeroUI dialog.\n *\n * Renders one of four visual states based on the FSM phase:\n * - in-progress (broadcasting / submitted / tracking)\n * - succeeded\n * - refunded\n * - failed\n *\n * Explorer URLs are caller-provided so the SDK never has to know which\n * RPC / explorer the host wants (Solscan vs Solana Beach, etc.).\n */\nexport interface DepositStatusUIProps {\n isOpen: boolean;\n /** The current FSM phase — drives the visual treatment. */\n phase: DepositPhase;\n /** Backend status record (may be unavailable on first frame). */\n status?: DepositStatusResponse;\n /** Optional Solana explorer URL (caller decides the network). */\n solanaExplorerUrl?: string;\n /** Optional Hyperliquid explorer URL. */\n hyperliquidExplorerUrl?: string;\n /** \"Try again\" handler — only rendered when `phase === \"failed\"`. */\n onRetry?: () => void;\n onClose: () => void;\n /** Optional override for the human-readable message. */\n errorMessage?: string;\n}\n\ntype Variant = \"progress\" | \"success\" | \"warning\" | \"error\";\n\nconst ACCENT = \"#C7FF2E\";\n\nexport function DepositStatusUI({\n isOpen,\n phase,\n status,\n solanaExplorerUrl,\n hyperliquidExplorerUrl,\n onRetry,\n onClose,\n errorMessage,\n}: DepositStatusUIProps) {\n const { t } = useTranslation();\n\n const variant = phaseToVariant(phase);\n const message = ((): string => {\n if (phase === \"failed\") {\n if (errorMessage) return errorMessage;\n if (status?.lastError?.message) {\n return t(\"perpDeposit.status.failed\", {\n message: status.lastError.message,\n });\n }\n return t(\"perpDeposit.status.failed\", { message: \"\" });\n }\n if (phase === \"succeeded\") return t(\"perpDeposit.status.settled\");\n if (phase === \"refunded\") return t(\"perpDeposit.status.refunded\");\n if (status?.status === \"broadcasted\")\n return t(\"perpDeposit.status.broadcasted\");\n if (status?.status === \"relay_waiting\")\n return t(\"perpDeposit.status.relay_waiting\");\n if (status?.status === \"relay_pending\")\n return t(\"perpDeposit.status.relay_pending\");\n if (status?.status === \"stuck\") return t(\"perpDeposit.status.stuck\");\n return t(\"perpDeposit.status.broadcasted\");\n })();\n\n const showRetry = phase === \"failed\" && !!onRetry;\n\n return (\n <StyledModal\n isOpen={isOpen}\n onOpenChange={(next) => !next && onClose()}\n size=\"md\"\n hideCloseButton\n backdrop=\"blur\"\n classNames={{\n base: \"!bg-[#18181b] !rounded-[14px] !border !border-[rgba(39,39,42,1)] !shadow-[0_25px_50px_-12px_rgba(0,0,0,0.5)] max-w-[420px]\",\n body: \"!p-0\",\n }}\n >\n <ModalContent>\n <div className=\"flex flex-col\">\n {/* Header */}\n <div className=\"flex items-start justify-between px-5 pt-5 pb-2\">\n <div className=\"flex items-center gap-2.5\">\n <h3 className=\"text-base font-semibold text-white\">\n {t(\"perpDeposit.status.title\")}\n </h3>\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"cursor-pointer p-1 rounded-[10px] hover:bg-[rgba(39,39,42,0.5)] text-zinc-400 hover:text-white transition-colors\"\n aria-label={t(\"perpDeposit.status.close\")}\n >\n <XCloseIcon width={16} height={16} />\n </button>\n </div>\n\n {/* Body */}\n <div className=\"px-5 pb-3 pt-2\">\n <div className=\"rounded-[12px] bg-[#0a0a0b] border border-[#27272a] px-4 py-6 flex flex-col items-center text-center gap-4\">\n <PhaseIcon variant={variant} />\n <p\n className={cn(\n \"text-sm leading-relaxed max-w-[320px]\",\n variantTextClass(variant),\n )}\n >\n {message}\n </p>\n </div>\n\n {/* Transaction links */}\n {(status?.solanaTxHash || status?.hyperliquidTxHash) && (\n <div className=\"mt-3 flex flex-col gap-2\">\n {status?.solanaTxHash && solanaExplorerUrl && (\n <TxLink\n href={solanaExplorerUrl}\n label={t(\"perpDeposit.status.viewSolanaTx\")}\n hash={status.solanaTxHash}\n />\n )}\n {status?.hyperliquidTxHash && hyperliquidExplorerUrl && (\n <TxLink\n href={hyperliquidExplorerUrl}\n label={t(\"perpDeposit.status.viewHyperliquidTx\")}\n hash={status.hyperliquidTxHash}\n />\n )}\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div\n className={cn(\n \"px-5 pb-5 pt-2 flex gap-2\",\n showRetry ? \"justify-between\" : \"justify-end\",\n )}\n >\n {showRetry && (\n <button\n type=\"button\"\n onClick={onRetry}\n className=\"cursor-pointer flex-1 h-10 rounded-[10px] font-medium text-black bg-[#C7FF2E] hover:bg-[#b6ed1c] active:bg-[#a6d913] transition-colors flex items-center justify-center\"\n >\n {t(\"perpDeposit.status.tryAgain\")}\n </button>\n )}\n <button\n type=\"button\"\n onClick={onClose}\n className={cn(\n \"cursor-pointer h-10 rounded-[10px] font-medium transition-colors flex items-center justify-center\",\n showRetry\n ? \"flex-1 bg-[rgba(39,39,42,1)] hover:bg-[rgba(63,63,70,1)] text-white\"\n : \"px-6 bg-[rgba(39,39,42,1)] hover:bg-[rgba(63,63,70,1)] text-white\",\n )}\n >\n {t(\"perpDeposit.status.close\")}\n </button>\n </div>\n </div>\n </ModalContent>\n </StyledModal>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Sub-components\n// ---------------------------------------------------------------------------\n\nfunction TxLink({\n href,\n label,\n hash,\n}: {\n href: string;\n label: string;\n hash: string;\n}) {\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"group flex items-center justify-between gap-2 px-3 py-2 rounded-[10px] bg-[#0a0a0b] border border-[#27272a] hover:border-[rgba(199,255,46,0.4)] transition-colors\"\n >\n <span className=\"text-xs text-zinc-400 group-hover:text-white transition-colors\">\n {label}\n </span>\n <span className=\"flex items-center gap-1.5 text-xs tabular-nums text-zinc-300 group-hover:text-[#C7FF2E] transition-colors\">\n {shortAddress(hash, 6, 4)}\n <ExternalLinkIcon />\n </span>\n </a>\n );\n}\n\nfunction PhaseIcon({ variant }: { variant: Variant }) {\n if (variant === \"progress\") {\n return (\n <div className=\"relative w-14 h-14 flex items-center justify-center\">\n <AccentSpinner />\n </div>\n );\n }\n if (variant === \"success\") {\n return (\n <div className=\"w-14 h-14 rounded-full flex items-center justify-center bg-[rgba(199,255,46,0.12)]\">\n <CheckCircle className=\"w-8 h-8\" style={{ color: ACCENT }} />\n </div>\n );\n }\n if (variant === \"warning\") {\n return (\n <div className=\"w-14 h-14 rounded-full flex items-center justify-center bg-[rgba(245,158,11,0.12)]\">\n <AlertCircle className=\"w-8 h-8 text-amber-400\" />\n </div>\n );\n }\n return (\n <div className=\"w-14 h-14 rounded-full flex items-center justify-center bg-[rgba(239,68,68,0.12)]\">\n <XCircle className=\"w-8 h-8 text-rose-400\" />\n </div>\n );\n}\n\n/**\n * Accent-coloured circular spinner matching the deposit form's theme.\n *\n * Implemented as an inline SVG with a CSS keyframe rotation rather than\n * pulling HeroUI's `Spinner` (which doesn't expose a clean way to set\n * the active arc colour to our brand `#C7FF2E`).\n */\nfunction AccentSpinner() {\n return (\n <>\n <svg\n className=\"lfi-perp-deposit-spinner\"\n viewBox=\"0 0 50 50\"\n width={48}\n height={48}\n aria-hidden=\"true\"\n >\n <circle\n cx=\"25\"\n cy=\"25\"\n r=\"20\"\n fill=\"none\"\n stroke=\"rgba(255,255,255,0.08)\"\n strokeWidth=\"4\"\n />\n <circle\n cx=\"25\"\n cy=\"25\"\n r=\"20\"\n fill=\"none\"\n stroke={ACCENT}\n strokeWidth=\"4\"\n strokeLinecap=\"round\"\n strokeDasharray=\"90 60\"\n />\n </svg>\n <style>{`\n .lfi-perp-deposit-spinner {\n animation: lfi-perp-deposit-spin 0.9s linear infinite;\n transform-origin: center;\n }\n @keyframes lfi-perp-deposit-spin {\n to { transform: rotate(360deg); }\n }\n `}</style>\n </>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction phaseToVariant(phase: DepositPhase): Variant {\n switch (phase) {\n case \"succeeded\":\n return \"success\";\n case \"refunded\":\n return \"warning\";\n case \"failed\":\n return \"error\";\n default:\n return \"progress\";\n }\n}\n\nfunction variantTextClass(variant: Variant): string {\n switch (variant) {\n case \"success\":\n return \"text-white\";\n case \"warning\":\n return \"text-amber-200\";\n case \"error\":\n return \"text-rose-300\";\n default:\n return \"text-zinc-200\";\n }\n}\n\n// Inline icons — kept tiny so we don't pull a heavy icon dep into the bundle.\nfunction CheckCircle(props: {\n className?: string;\n style?: React.CSSProperties;\n}) {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2.5}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n className={props.className}\n style={props.style}\n >\n <path d=\"M20 6L9 17l-5-5\" />\n </svg>\n );\n}\n\nfunction AlertCircle(props: { className?: string }) {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n className={props.className}\n >\n <path d=\"M12 2a10 10 0 100 20 10 10 0 000-20zm0 4c.6 0 1 .4 1 1v6c0 .6-.4 1-1 1s-1-.4-1-1V7c0-.6.4-1 1-1zm0 12c-.7 0-1.2-.5-1.2-1.2s.5-1.2 1.2-1.2 1.2.5 1.2 1.2-.5 1.2-1.2 1.2z\" />\n </svg>\n );\n}\n\nfunction XCircle(props: { className?: string }) {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2.5}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n className={props.className}\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M15 9l-6 6M9 9l6 6\" />\n </svg>\n );\n}\n\nfunction ExternalLinkIcon() {\n return (\n <svg\n width=\"11\"\n height=\"11\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\n <polyline points=\"15 3 21 3 21 9\" />\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />\n </svg>\n );\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useTranslation } from \"@liberfi.io/i18n\";\nimport { Button, Card, CardBody } from \"@liberfi.io/ui\";\nimport type {\n DepositQuoteRequest,\n DepositSource,\n} from \"../../client/liberfi/deposit-types\";\nimport {\n type SignAndBroadcastSolanaTx,\n usePerpDepositExecute,\n} from \"../../hooks/usePerpDepositExecute\";\nimport { usePerpDepositQuote } from \"../../hooks/usePerpDepositQuote\";\nimport { usePerpDepositStatus } from \"../../hooks/usePerpDepositStatus\";\nimport { DepositConfirmUI } from \"./deposit-confirm.ui\";\nimport { DepositFormUI } from \"./deposit-form.ui\";\nimport { DepositStatusUI } from \"./deposit-status.ui\";\nimport { solToLamports } from \"./format\";\n\n/**\n * Highest-level deposit widget. Wires the three presentational\n * components (form / confirm / status) to the deposit hooks +\n * state machine.\n *\n * Engineering principles:\n * - Single responsibility: this file is the *only* place that knows\n * how the three components compose. Anything richer (e.g. embedded\n * FAQ panel, support links) belongs to the host application.\n * - Inversion of control: every side effect the host might want to\n * own (sign + broadcast, success / failure callbacks, explorer\n * URLs, balance fetch, address validation) is a prop. The widget\n * never imports a wallet adapter directly.\n */\nexport interface DepositFlowWidgetProps {\n /** Connected Solana wallet — used as `userSolanaAddress` in /quote. */\n userSolanaAddress: string;\n /** Stable LiberFi user id (for fee attribution). */\n userId: string;\n /** Where the deposit was initiated from. */\n source: DepositSource;\n /** Optional referral / campaign code propagated to the backend. */\n campaign?: string;\n\n /** Initial Hyperliquid recipient (e.g. derived from the user's EVM wallet). */\n defaultRecipient?: string;\n\n /**\n * Wallet adapter — sign and broadcast a Solana transaction. The host\n * app supplies its own wallet integration (Phantom, Privy, Backpack,\n * …) and returns the resulting tx hash. See `SignAndBroadcastSolanaTx`.\n */\n signAndBroadcast: SignAndBroadcastSolanaTx;\n\n /** Optional balance display (in SOL units, e.g. \"12.345\"). */\n balanceSol?: string;\n /** Click handler for \"Max\" — only rendered when `balanceSol` is set. */\n onMaxClick?: () => void;\n /** Validates the recipient string. Return undefined when valid. */\n validateRecipient?: (value: string) => string | undefined;\n\n /** Build a Solana explorer URL from a tx hash. */\n buildSolanaExplorerUrl?: (txHash: string) => string;\n /** Build a Hyperliquid explorer URL from a tx hash. */\n buildHyperliquidExplorerUrl?: (txHash: string) => string;\n\n /** Fired when a deposit reaches `settled`. */\n onSettled?: (intentId: string) => void;\n /** Fired when a deposit fails (after the wallet signed). */\n onError?: (intentId: string | undefined, message: string) => void;\n\n className?: string;\n}\n\nexport function DepositFlowWidget({\n userSolanaAddress,\n userId,\n source,\n campaign,\n defaultRecipient,\n signAndBroadcast,\n balanceSol,\n onMaxClick,\n validateRecipient,\n buildSolanaExplorerUrl,\n buildHyperliquidExplorerUrl,\n onSettled,\n onError,\n className,\n}: DepositFlowWidgetProps) {\n const { t } = useTranslation();\n\n const [amount, setAmount] = useState(\"\");\n const [recipient, setRecipient] = useState(defaultRecipient ?? \"\");\n\n // Local validation. Backend re-validates everything; these only\n // gate the \"Continue\" button and surface inline errors.\n const amountError = useMemo<string | undefined>(() => {\n if (!amount) return undefined;\n if (!/^\\d+(\\.\\d+)?$/.test(amount.trim())) {\n return t(\"perpDeposit.error.amountInvalid\");\n }\n if (Number(amount) <= 0) return t(\"perpDeposit.error.amountInvalid\");\n return undefined;\n }, [amount, t]);\n\n const recipientError = useMemo<string | undefined>(() => {\n if (!recipient) return undefined;\n return validateRecipient ? validateRecipient(recipient) : undefined;\n }, [recipient, validateRecipient]);\n\n const grossLamports = useMemo(\n () => (amountError ? \"\" : solToLamports(amount)),\n [amount, amountError],\n );\n\n const quoteReq = useMemo<DepositQuoteRequest | null>(() => {\n if (!grossLamports || grossLamports === \"0\") return null;\n if (recipientError) return null;\n if (!recipient) return null;\n return {\n userSolanaAddress,\n hyperliquidRecipient: recipient,\n grossLamports,\n source,\n };\n }, [grossLamports, recipient, recipientError, source, userSolanaAddress]);\n\n const quoteQ = usePerpDepositQuote(quoteReq, {\n enabled: Boolean(quoteReq),\n });\n\n const { state, execute, reset, dispatch } =\n usePerpDepositExecute(signAndBroadcast);\n const intentId =\n state.phase === \"submitted\" ||\n state.phase === \"tracking\" ||\n state.phase === \"succeeded\" ||\n state.phase === \"refunded\"\n ? state.intentId\n : state.phase === \"failed\"\n ? state.intentId\n : undefined;\n\n const statusQ = usePerpDepositStatus(intentId, {\n enabled:\n Boolean(intentId) &&\n state.phase !== \"succeeded\" &&\n state.phase !== \"refunded\" &&\n state.phase !== \"failed\",\n });\n\n // Forward backend status into the FSM so the UI advances.\n useEffect(() => {\n if (statusQ.data) {\n dispatch({ type: \"STATUS_UPDATE\", status: statusQ.data });\n }\n }, [statusQ.data, dispatch]);\n\n // Funnel-end side effects.\n useEffect(() => {\n if (state.phase === \"succeeded\") {\n onSettled?.(state.intentId);\n } else if (state.phase === \"failed\") {\n onError?.(state.intentId, state.error.message);\n }\n }, [state, onSettled, onError]);\n\n const handleContinue = useCallback(() => {\n if (!quoteQ.data) return;\n dispatch({ type: \"QUOTE_REQUEST\" });\n dispatch({ type: \"QUOTE_RECEIVED\", quote: quoteQ.data });\n }, [dispatch, quoteQ.data]);\n\n const handleConfirm = useCallback(async () => {\n if (state.phase !== \"ready_to_sign\") return;\n try {\n await execute({\n quote: state.quote,\n userSolanaAddress,\n hyperliquidRecipient: recipient,\n userId,\n source,\n campaign,\n });\n } catch {\n // Hook already advanced FSM into `failed`; nothing to do here.\n }\n }, [state, execute, userSolanaAddress, recipient, userId, source, campaign]);\n\n const handleExpire = useCallback(() => {\n dispatch({ type: \"QUOTE_EXPIRED\" });\n }, [dispatch]);\n\n const handleRetry = useCallback(async () => {\n dispatch({ type: \"RESET\" });\n await quoteQ.refetch();\n }, [dispatch, quoteQ]);\n\n const showConfirm =\n state.phase === \"ready_to_sign\" ||\n state.phase === \"signing\" ||\n state.phase === \"broadcasting\" ||\n state.phase === \"expired\";\n\n const showStatus =\n state.phase === \"submitted\" ||\n state.phase === \"tracking\" ||\n state.phase === \"succeeded\" ||\n state.phase === \"refunded\" ||\n (state.phase === \"failed\" && Boolean(state.intentId));\n\n const status =\n state.phase === \"tracking\" ||\n state.phase === \"succeeded\" ||\n state.phase === \"refunded\"\n ? state.status\n : state.phase === \"failed\"\n ? state.status\n : undefined;\n\n const continueDisabled =\n !quoteQ.data ||\n quoteQ.isFetching ||\n Boolean(amountError) ||\n Boolean(recipientError) ||\n !quoteReq;\n\n return (\n <Card className={className}>\n <CardBody className=\"flex flex-col gap-4 p-6\">\n <div>\n <h3 className=\"text-lg font-semibold\">{t(\"perpDeposit.title\")}</h3>\n <p className=\"text-default-500 text-sm\">\n {t(\"perpDeposit.description\")}\n </p>\n </div>\n\n <DepositFormUI\n amount={amount}\n onAmountChange={setAmount}\n recipient={recipient}\n onRecipientChange={setRecipient}\n balanceSol={balanceSol}\n onMax={onMaxClick}\n amountError={amountError}\n recipientError={recipientError}\n disabled={\n state.phase !== \"idle\" &&\n state.phase !== \"expired\" &&\n state.phase !== \"failed\"\n }\n />\n\n <Button\n color=\"primary\"\n isDisabled={continueDisabled}\n isLoading={quoteQ.isFetching}\n onPress={handleContinue}\n >\n {quoteQ.isFetching\n ? t(\"perpDeposit.gettingQuote\")\n : t(\"perpDeposit.confirmQuote\")}\n </Button>\n\n {quoteQ.error && (\n <div className=\"text-danger text-xs\">\n {t(\"perpDeposit.error.quoteFailed\")}\n </div>\n )}\n </CardBody>\n\n <DepositConfirmUI\n isOpen={showConfirm}\n quote={\n state.phase === \"ready_to_sign\" ||\n state.phase === \"signing\" ||\n state.phase === \"broadcasting\" ||\n state.phase === \"expired\"\n ? state.quote\n : undefined\n }\n isExecuting={\n state.phase === \"signing\" || state.phase === \"broadcasting\"\n }\n isExpired={state.phase === \"expired\"}\n onConfirm={handleConfirm}\n onCancel={reset}\n onExpire={handleExpire}\n />\n\n <DepositStatusUI\n isOpen={showStatus}\n phase={state.phase}\n status={status}\n solanaExplorerUrl={\n status?.solanaTxHash && buildSolanaExplorerUrl\n ? buildSolanaExplorerUrl(status.solanaTxHash)\n : undefined\n }\n hyperliquidExplorerUrl={\n status?.hyperliquidTxHash && buildHyperliquidExplorerUrl\n ? buildHyperliquidExplorerUrl(status.hyperliquidTxHash)\n : undefined\n }\n onRetry={state.phase === \"failed\" ? handleRetry : undefined}\n onClose={reset}\n errorMessage={\n state.phase === \"failed\" ? state.error.message : undefined\n }\n />\n </Card>\n );\n}\n","import { useTranslation } from \"@liberfi.io/i18n\";\nimport {\n Button,\n Card,\n CardBody,\n CardFooter,\n CardHeader,\n Spinner,\n cn,\n} from \"@liberfi.io/ui\";\nimport type {\n SetupState,\n SetupStep,\n StepRecord,\n StepStatus,\n} from \"../../hooks/hyperliquid-setup/setup-state-machine\";\n\n/**\n * Pure presentational card for the Hyperliquid first-run setup flow.\n *\n * The component is fully driven by the FSM state from\n * `useHyperliquidSetup` plus a couple of action callbacks, so consumers\n * can wire it into either a modal, a sidebar panel, or an inline card\n * without forking the markup.\n */\nexport interface HyperliquidInitUIProps {\n /** FSM snapshot rendered as the checklist. */\n state: SetupState;\n /** Trigger the next runnable step (sequential default). */\n onContinue: () => void;\n /** Retry a specific step (used by per-row error recovery). */\n onRetryStep?: (index: number) => void;\n /** Refresh the on-chain state — typically rendered when the load failed. */\n onReload?: () => void;\n /** Optional dismiss handler — show a \"Skip for now\" CTA when set. */\n onDismiss?: () => void;\n /** Optional className override for embedding inside other cards. */\n className?: string;\n}\n\nexport function HyperliquidInitUI({\n state,\n onContinue,\n onRetryStep,\n onReload,\n onDismiss,\n className,\n}: HyperliquidInitUIProps) {\n const { t } = useTranslation();\n const phase = state.phase;\n const isExecuting = phase === \"executing\";\n const isLoading = phase === \"loading\";\n const isLoadError = phase === \"error\" && state.steps.length === 0;\n\n return (\n <Card className={cn(\"w-full max-w-md\", className)}>\n <CardHeader className=\"flex flex-col items-start gap-1\">\n <h3 className=\"text-lg font-semibold\">\n {t(\"perpDeposit.setup.title\")}\n </h3>\n <p className=\"text-foreground-500 text-sm\">\n {t(\"perpDeposit.setup.description\")}\n </p>\n </CardHeader>\n <CardBody className=\"gap-3\">\n {isLoading && <LoadingRow />}\n {isLoadError && (\n <p className=\"text-danger text-sm\">\n {t(\"perpDeposit.setup.loadFailed\", { message: state.error ?? \"\" })}\n </p>\n )}\n {!isLoading &&\n !isLoadError &&\n state.steps.map((rec, idx) => (\n <SetupStepRow\n key={`${rec.step.id}-${idx}`}\n rec={rec}\n index={idx}\n isCurrent={state.currentIndex === idx}\n onRetry={onRetryStep}\n />\n ))}\n {phase === \"done\" && (\n <p className=\"text-success text-sm\">\n {t(\"perpDeposit.setup.alreadyActive\")}\n </p>\n )}\n </CardBody>\n <CardFooter className=\"flex justify-between gap-2\">\n {onDismiss && (\n <Button variant=\"light\" onPress={onDismiss} isDisabled={isExecuting}>\n {phase === \"done\"\n ? t(\"perpDeposit.setup.dismiss\")\n : t(\"perpDeposit.setup.skip\")}\n </Button>\n )}\n <div className=\"flex-1\" />\n {isLoadError && onReload && (\n <Button color=\"primary\" onPress={onReload}>\n {t(\"perpDeposit.setup.retry\")}\n </Button>\n )}\n {!isLoadError && phase !== \"done\" && (\n <Button\n color=\"primary\"\n onPress={onContinue}\n isLoading={isExecuting}\n isDisabled={isExecuting || isLoading}\n >\n {state.steps.some((s) => s.status === \"done\")\n ? t(\"perpDeposit.setup.continue\")\n : t(\"perpDeposit.setup.cta\")}\n </Button>\n )}\n </CardFooter>\n </Card>\n );\n}\n\ninterface SetupStepRowProps {\n rec: StepRecord;\n index: number;\n isCurrent: boolean;\n onRetry?: (index: number) => void;\n}\n\nfunction SetupStepRow({ rec, index, isCurrent, onRetry }: SetupStepRowProps) {\n const { t } = useTranslation();\n const title = stepTitle(rec.step.id, () => {\n switch (rec.step.id) {\n case \"approveBuilderFee\":\n return t(\"perpDeposit.setup.builderFee.label\");\n case \"setReferrer\":\n return t(\"perpDeposit.setup.referrer.label\");\n case \"updateLeverage\":\n return t(\"perpDeposit.setup.leverage.label\");\n }\n });\n const description = ((): string => {\n switch (rec.step.id) {\n case \"approveBuilderFee\": {\n const bps = (rec.step.params.maxFeeRate / 10).toFixed(1);\n return t(\"perpDeposit.setup.builderFee.description\", { bps });\n }\n case \"setReferrer\":\n return t(\"perpDeposit.setup.referrer.description\", {\n code: rec.step.params.code,\n });\n case \"updateLeverage\":\n return t(\"perpDeposit.setup.leverage.description\");\n }\n })();\n const statusLabel = ((): string => {\n switch (rec.status) {\n case \"pending\":\n return t(\"perpDeposit.setup.step.pending\");\n case \"skipped\":\n return t(\"perpDeposit.setup.step.skipped\");\n case \"running\":\n return t(\"perpDeposit.setup.step.running\");\n case \"done\":\n return t(\"perpDeposit.setup.step.done\");\n case \"error\":\n return t(\"perpDeposit.setup.step.error\");\n }\n })();\n return (\n <div\n className={cn(\n \"border-divider flex items-start justify-between gap-3 rounded-md border p-3\",\n rec.status === \"error\" && \"border-danger\",\n rec.status === \"done\" && \"border-success/40 bg-success/5\",\n rec.status === \"skipped\" && \"border-default bg-default-100/40\",\n )}\n >\n <div className=\"flex-1\">\n <div className=\"flex items-center gap-2 text-sm font-medium\">\n <StepIcon status={rec.status} isCurrent={isCurrent} />\n <span>{title}</span>\n </div>\n <p className=\"text-foreground-500 mt-1 text-xs\">{description}</p>\n {rec.status === \"error\" && rec.error && (\n <p className=\"text-danger mt-1 text-xs\">{rec.error}</p>\n )}\n </div>\n <div className=\"flex flex-col items-end gap-1 text-xs\">\n <span className={cn(statusBadgeClass(rec.status))}>{statusLabel}</span>\n {rec.status === \"error\" && onRetry && (\n <Button\n size=\"sm\"\n variant=\"flat\"\n color=\"danger\"\n onPress={() => onRetry(index)}\n >\n {t(\"perpDeposit.setup.retry\")}\n </Button>\n )}\n </div>\n </div>\n );\n}\n\nfunction LoadingRow() {\n const { t } = useTranslation();\n return (\n <div className=\"flex items-center gap-2 py-2 text-sm\">\n <Spinner size=\"sm\" />\n <span>{t(\"perpDeposit.setup.loading\")}</span>\n </div>\n );\n}\n\nfunction StepIcon({\n status,\n isCurrent,\n}: {\n status: StepStatus;\n isCurrent: boolean;\n}) {\n if (status === \"running\" || isCurrent) {\n return <Spinner size=\"sm\" />;\n }\n if (status === \"done\" || status === \"skipped\") {\n return (\n <span aria-hidden className=\"text-success\">\n ✓\n </span>\n );\n }\n if (status === \"error\") {\n return (\n <span aria-hidden className=\"text-danger\">\n !\n </span>\n );\n }\n return (\n <span\n aria-hidden\n className=\"border-foreground-400 inline-block h-3 w-3 rounded-full border\"\n />\n );\n}\n\nfunction statusBadgeClass(status: StepStatus): string {\n switch (status) {\n case \"done\":\n return \"text-success\";\n case \"skipped\":\n return \"text-foreground-500\";\n case \"running\":\n return \"text-primary\";\n case \"error\":\n return \"text-danger\";\n default:\n return \"text-foreground-500\";\n }\n}\n\n/**\n * Tiny indirection to keep `SetupStepRow` flat — invokes a closure\n * the caller wrote inline so we don't pass `t` across function\n * boundaries (which would defeat its strict-key inference).\n */\nfunction stepTitle(_id: SetupStep[\"id\"], compute: () => string): string {\n return compute();\n}\n","import { useCallback } from \"react\";\nimport {\n useHyperliquidSetup,\n type UseHyperliquidSetupOptions,\n type SetupState,\n} from \"../../hooks/hyperliquid-setup\";\nimport { HyperliquidInitUI } from \"./hyperliquid-init.ui\";\n\n/**\n * Highest-level Hyperliquid setup widget.\n *\n * Wraps `useHyperliquidSetup` with the presentational card so consumers\n * can drop in a single component:\n *\n * <HyperliquidInitWidget\n * adapter={mySetupAdapter}\n * userAddress={evmAddress}\n * steps={[ ... ]}\n * onComplete={() => navigate(\"/perp\")}\n * onDismiss={() => closeModal()}\n * />\n *\n * The widget is a thin coordinator — all logic lives in the hook and\n * all presentation lives in `HyperliquidInitUI`. This split keeps the\n * UI testable in isolation (Storybook just hands it a `state` prop).\n */\nexport interface HyperliquidInitWidgetProps extends Pick<\n UseHyperliquidSetupOptions,\n \"adapter\" | \"userAddress\" | \"steps\" | \"autoLoad\" | \"onError\"\n> {\n /** Invoked once every step is `done` or `skipped`. */\n onComplete?: (state: SetupState) => void;\n /**\n * Optional dismiss callback — when supplied the card renders a\n * \"Skip for now\" / \"Close\" CTA so the user can leave the wizard.\n */\n onDismiss?: () => void;\n /** Optional className passthrough to the rendered card. */\n className?: string;\n}\n\nexport function HyperliquidInitWidget({\n adapter,\n userAddress,\n steps,\n autoLoad,\n onComplete,\n onError,\n onDismiss,\n className,\n}: HyperliquidInitWidgetProps) {\n const { state, runNext, runStep, reload } = useHyperliquidSetup({\n adapter,\n userAddress,\n steps,\n autoLoad,\n onComplete,\n onError,\n });\n\n const handleContinue = useCallback(() => {\n void runNext();\n }, [runNext]);\n\n const handleRetry = useCallback(\n (index: number) => {\n void runStep(index);\n },\n [runStep],\n );\n\n const handleReload = useCallback(() => {\n void reload();\n }, [reload]);\n\n return (\n <HyperliquidInitUI\n state={state}\n onContinue={handleContinue}\n onRetryStep={handleRetry}\n onReload={handleReload}\n onDismiss={onDismiss}\n className={className}\n />\n );\n}\n"]}