@liberfi.io/ui-perpetuals 0.1.112 → 0.1.113
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.
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -7
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {createContext,useContext,useState,useCallback,useEffect,useMemo}from'react';import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {useQuery,useMutation}from'@tanstack/react-query';import {Skeleton,SearchIcon,RHForm,RHNumberInput,cn,Button,Slider}from'@liberfi.io/ui';import {useForm}from'react-hook-form';typeof window<"u"&&(window.__LIBERFI_VERSION__=window.__LIBERFI_VERSION__||{},window.__LIBERFI_VERSION__["@liberfi.io/ui-perpetuals"]="0.1.112");var Jt="0.1.112";var ae=class{ws=null;wsEndpoint;subscriptions=new Map;reconnectAttempts=0;maxReconnectAttempts=10;reconnectDelay=1e3;heartbeatInterval=null;messageQueue=[];isConnected=false;pingInterval=3e4;reconnectTimeout=null;isReconnecting=false;constructor(e){this.wsEndpoint=e;}async connect(){return new Promise((e,r)=>{try{this.ws&&this.ws.close(),this.ws=new WebSocket(this.wsEndpoint),this.ws.onopen=()=>{console.log("[WebSocket] Connected to Hyperliquid"),this.isConnected=!0,this.reconnectAttempts=0,this.isReconnecting=!1,this.startHeartbeat(),this.flushMessageQueue(),e();},this.ws.onmessage=s=>{this.handleMessage(s.data);},this.ws.onerror=s=>{console.error("[WebSocket] Error:",s),this.isConnected=!1,this.isReconnecting||r(new Error("WebSocket connection failed"));},this.ws.onclose=s=>{console.log(`[WebSocket] Closed: ${s.code} - ${s.reason||"No reason provided"}`),this.isConnected=!1,this.stopHeartbeat(),s.code!==1e3&&this.attemptReconnect();};}catch(s){r(s);}})}disconnect(){this.stopHeartbeat(),this.subscriptions.clear(),this.reconnectTimeout!==null&&(clearTimeout(this.reconnectTimeout),this.reconnectTimeout=null),this.ws&&(this.ws.close(1e3,"Normal closure"),this.ws=null),this.isConnected=false,this.isReconnecting=false,this.reconnectAttempts=0;}attemptReconnect(){if(this.isReconnecting)return;if(this.reconnectAttempts>=this.maxReconnectAttempts){console.error("[WebSocket] Max reconnection attempts reached");return}this.isReconnecting=true,this.reconnectAttempts++;let e=Math.min(this.reconnectDelay*Math.pow(2,this.reconnectAttempts-1),3e4);console.log(`[WebSocket] Reconnecting in ${e}ms (attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts})`),this.reconnectTimeout=window.setTimeout(()=>{this.connect().then(()=>{this.resubscribeAll();}).catch(r=>{console.error("[WebSocket] Reconnection failed:",r),this.isReconnecting=false;});},e);}startHeartbeat(){this.heartbeatInterval=window.setInterval(()=>{this.isConnected&&this.ws&&this.ws.readyState===WebSocket.OPEN&&this.send({method:"ping"});},this.pingInterval);}stopHeartbeat(){this.heartbeatInterval!==null&&(clearInterval(this.heartbeatInterval),this.heartbeatInterval=null);}send(e){this.isConnected&&this.ws&&this.ws.readyState===WebSocket.OPEN?this.ws.send(JSON.stringify(e)):this.messageQueue.push(e);}flushMessageQueue(){for(;this.messageQueue.length>0;){let e=this.messageQueue.shift();e&&this.send(e);}}resubscribeAll(){this.subscriptions.forEach(e=>{this.sendSubscription(e.type,e.param);});}handleMessage(e){try{let r=JSON.parse(e);r.channel?this.handleChannelMessage(r):r.method;}catch(r){console.error("[WebSocket] Failed to parse message:",r,e);}}handleChannelMessage(e){let r=e.channel;this.subscriptions.forEach((s,n)=>{if(this.isChannelMatch(r,s.type,s.param))try{let o=this.transformData(s.type,e.data,s.param);s.callback(o);}catch(o){console.error(`[WebSocket] Error in subscription callback (${n}):`,o);}});}isChannelMatch(e,r,s){return r==="ticker"?e==="allMids":r==="trades"?e==="trades":r==="orderBook"?e==="l2Book":r==="candle"?e==="candle":r==="userFills"?e==="userFills":r==="userEvents"?e==="userEvents":false}transformData(e,r,s){return e==="ticker"?this.transformTickerData(r):e==="trades"?this.transformTradesData(r,s):e==="orderBook"?this.transformOrderBookData(r,s):e==="candle"?this.transformCandleData(r,s):e==="userFills"?this.transformUserFillsData(r):e==="userEvents"?this.transformUserEventsData(r):r}transformTickerData(e){let r=e.mids||{};return Object.entries(r).map(([s,n])=>({symbol:`${s}-USDC`,price:parseFloat(n),timestamp:Date.now()}))}transformTradesData(e,r){return Array.isArray(e)?e.map(s=>({symbol:r,side:s.side==="B"?"buy":"sell",price:parseFloat(s.px),quantity:parseFloat(s.sz),timestamp:s.time,tradeId:s.tid})):[]}transformOrderBookData(e,r){let[s,n]=e.levels||[[],[]];return {symbol:r,bids:s.map(o=>({price:parseFloat(o.px),quantity:parseFloat(o.sz),count:o.n})),asks:n.map(o=>({price:parseFloat(o.px),quantity:parseFloat(o.sz),count:o.n})),timestamp:e.time||Date.now()}}transformCandleData(e,r){let[s]=r.split(":");return {symbol:s,open:parseFloat(e.o),high:parseFloat(e.h),low:parseFloat(e.l),close:parseFloat(e.c),volume:parseFloat(e.v),timestamp:e.t,closeTimestamp:e.T}}transformUserFillsData(e){return Array.isArray(e)?e.map(r=>({tradeId:r.tid?.toString(),orderId:r.oid?.toString(),symbol:`${r.coin}-USDC`,side:r.dir?.includes("Long")?"long":"short",price:parseFloat(r.px),quantity:parseFloat(r.sz),fee:parseFloat(r.fee||"0"),feeCurrency:r.feeToken||"USDC",isMaker:r.side==="M",timestamp:r.time})):[]}transformUserEventsData(e){return e}sendSubscription(e,r){let s;if(e==="ticker")s={method:"subscribe",subscription:{type:"allMids"}};else if(e==="trades")s={method:"subscribe",subscription:{type:"trades",coin:r.split("-")[0]}};else if(e==="orderBook")s={method:"subscribe",subscription:{type:"l2Book",coin:r.split("-")[0]}};else if(e==="candle"){let[n,o]=r.split(":");s={method:"subscribe",subscription:{type:"candle",coin:n.split("-")[0],interval:o}};}else e==="userFills"?s={method:"subscribe",subscription:{type:"userFills",user:r}}:e==="userEvents"&&(s={method:"subscribe",subscription:{type:"userEvents",user:r}});s&&this.send(s);}sendUnsubscription(e,r){let s;if(e==="ticker")s={method:"unsubscribe",subscription:{type:"allMids"}};else if(e==="trades")s={method:"unsubscribe",subscription:{type:"trades",coin:r.split("-")[0]}};else if(e==="orderBook")s={method:"unsubscribe",subscription:{type:"l2Book",coin:r.split("-")[0]}};else if(e==="candle"){let[n,o]=r.split(":");s={method:"unsubscribe",subscription:{type:"candle",coin:n.split("-")[0],interval:o}};}else e==="userFills"?s={method:"unsubscribe",subscription:{type:"userFills",user:r}}:e==="userEvents"&&(s={method:"unsubscribe",subscription:{type:"userEvents",user:r}});s&&this.send(s);}subscribe(e,r,s){let n=`${e}:${r}`;return this.subscriptions.set(n,{type:e,param:r,callback:s}),this.sendSubscription(e,r),n}unsubscribe(e){let r=this.subscriptions.get(e);r&&(this.sendUnsubscription(r.type,r.param),this.subscriptions.delete(e));}isConnectedNow(){return this.isConnected}};var ot={testnet:{api:"https://api.hyperliquid-testnet.xyz",ws:"wss://api.hyperliquid-testnet.xyz/ws"},mainnet:{api:"https://api.hyperliquid.xyz",ws:"wss://api.hyperliquid.xyz/ws"}},ge=class{apiEndpoint;_wsEndpoint;timeout;environment;wsManager=null;constructor(e={}){this.environment=e.environment||"testnet",this.apiEndpoint=e.apiEndpoint||ot[this.environment].api,this._wsEndpoint=e.wsEndpoint||ot[this.environment].ws,this.timeout=e.timeout||3e4;}async request(e,r){let s=`${this.apiEndpoint}${e}`;try{let n=new AbortController,o=setTimeout(()=>n.abort(),this.timeout),i=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r),signal:n.signal});if(clearTimeout(o),!i.ok)throw new V(`HTTP ${i.status}: ${i.statusText}`,i.status,await i.text());return await i.json()}catch(n){throw n.name==="AbortError"?new V(`Request timeout after ${this.timeout}ms`,408,""):n instanceof V?n:new V(`Network error: ${n.message}`,0,"")}}symbolToCoin(e){return e.split("-")[0]}parseInterval(e){return {"1m":6e4,"5m":3e5,"15m":9e5,"30m":18e5,"1h":36e5,"4h":144e5,"1d":864e5,"1w":6048e5}[e]}async getSupportedCoins(){let[e]=await this.request("/info",{type:"metaAndAssetCtxs"});return e.universe.map(r=>`${r.name}-USDC`)}async getMarket(e){let r=await this.getMarkets([e]);return r.length>0?r[0]:null}async getMarkets(e){let[r,s]=await this.request("/info",{type:"metaAndAssetCtxs"}),n=r.universe.map((o,i)=>{let a=s[i],l=`${o.name}-USDC`,c=parseFloat(a.midPx||a.markPx||"0"),d=a.prevDayPx?parseFloat(a.prevDayPx):c,u=d>0?(c-d)/d*100:0;return {symbol:l,price:c,change24h:u,volume24h:parseFloat(a.dayNtlVlm||"0"),fundingRate:parseFloat(a.funding||"0"),openInterest:parseFloat(a.openInterest||"0"),markPrice:parseFloat(a.markPx||"0"),indexPrice:parseFloat(a.oraclePx||a.midPx||"0")}});if(e&&e.length>0){let o=new Set(e);return n.filter(i=>o.has(i.symbol))}return n}async getKlines(e,r,s=100){let n=this.symbolToCoin(e),o=this.parseInterval(r),i=Date.now(),a=i-o*s;return (await this.request("/info",{type:"candleSnapshot",req:{coin:n,interval:r,startTime:a,endTime:i}})).map(c=>({symbol:e,open:parseFloat(c.o),high:parseFloat(c.h),low:parseFloat(c.l),close:parseFloat(c.c),volume:parseFloat(c.v),timestamp:c.t,closeTimestamp:c.T}))}async getOrderBook(e,r=10){let s=this.symbolToCoin(e),n=await this.request("/info",{type:"l2Book",coin:s}),[o,i]=n.levels;return {symbol:e,bids:o.slice(0,r).map(a=>({price:parseFloat(a.px),quantity:parseFloat(a.sz),count:a.n})),asks:i.slice(0,r).map(a=>({price:parseFloat(a.px),quantity:parseFloat(a.sz),count:a.n})),timestamp:n.time}}async getRecentTrades(e,r=50){let s=this.symbolToCoin(e);return (await this.request("/info",{type:"recentTrades",coin:s})).slice(0,r).map(o=>({symbol:e,side:o.side==="B"?"buy":"sell",price:parseFloat(o.px),quantity:parseFloat(o.sz),timestamp:o.time,tradeId:o.tid}))}async placeOrder(e){throw new Error("placeOrder() requires wallet private key configuration for EIP-712 signature. Please configure authentication before calling this method. See: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint")}async cancelOrder(e){throw new Error("cancelOrder() requires wallet private key configuration for EIP-712 signature. Please configure authentication before calling this method. See: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint")}async getPositions(e={}){if(!e.userAddress)throw new Error("Hyperliquid requires userAddress parameter. Example: { userAddress: '0x...' }");let r=await this.request("/info",{type:"clearinghouseState",user:e.userAddress}),s=r.assetPositions.map(o=>{let i=o.position,a=`${i.coin}-USDC`,l=parseFloat(i.szi);if(l===0)return null;let c=parseFloat(i.entryPx),d=parseFloat(i.unrealizedPnl),u=parseFloat(i.positionValue);return {symbol:a,side:l>0?"long":"short",quantity:Math.abs(l),entryPrice:c,markPrice:c,unrealizedPnl:d,unrealizedPnlPercent:parseFloat(i.returnOnEquity)*100,leverage:i.leverage.value,liquidationPrice:i.liquidationPx?parseFloat(i.liquidationPx):void 0,margin:parseFloat(i.marginUsed),notionalValue:Math.abs(u)}}).filter(Boolean),n=e.symbol?s.filter(o=>o.symbol===e.symbol):s;return {positions:n,totalEquity:parseFloat(r.marginSummary.accountValue),availableBalance:parseFloat(r.marginSummary.accountValue)-parseFloat(r.marginSummary.totalMarginUsed),totalUnrealizedPnl:n.reduce((o,i)=>o+i.unrealizedPnl,0),raw:r}}async getOpenOrders(e={}){if(!e.userAddress)throw new Error("Hyperliquid requires userAddress parameter. Example: { userAddress: '0x...' }");let r=await this.request("/info",{type:"openOrders",user:e.userAddress}),s=r.map(o=>{let i=`${o.coin}-USDC`,a=parseFloat(o.origSz),l=parseFloat(o.sz),c=a-l;return {orderId:o.oid.toString(),clientOrderId:o.cloid,symbol:i,side:o.side?"long":"short",orderType:"limit",price:parseFloat(o.limitPx),quantity:a,filledQuantity:c,remainingQuantity:l,status:c>0&&l>0?"partially_filled":"pending",timestamp:o.timestamp,updateTimestamp:o.timestamp}}),n=e.symbol?s.filter(o=>o.symbol===e.symbol):s;return {orders:n,totalCount:n.length,raw:r}}async getTrades(e={}){if(!e.userAddress)throw new Error("Hyperliquid requires userAddress parameter. Example: { userAddress: '0x...' }");let r=await this.request("/info",{type:"userFills",user:e.userAddress}),s=r.map(n=>{let o=`${n.coin}-USDC`,i=n.dir.includes("Long");return {tradeId:n.tid.toString(),orderId:n.oid.toString(),symbol:o,side:i?"long":"short",price:parseFloat(n.px),quantity:parseFloat(n.sz),fee:parseFloat(n.fee||"0"),feeCurrency:n.feeToken||"USDC",isMaker:n.side==="M",timestamp:n.time}});return e.symbol&&(s=s.filter(n=>n.symbol===e.symbol)),e.startTime&&(s=s.filter(n=>n.timestamp>=e.startTime)),e.endTime&&(s=s.filter(n=>n.timestamp<=e.endTime)),e.limit&&(s=s.slice(0,e.limit)),{trades:s,totalCount:s.length,raw:r}}async connectWebSocket(){if(this.wsManager||(this.wsManager=new ae(this._wsEndpoint)),this.wsManager.isConnectedNow()){console.log("[WebSocket] Already connected");return}await this.wsManager.connect();}disconnectWebSocket(){this.wsManager&&(this.wsManager.disconnect(),this.wsManager=null);}subscribeMarketData(e,r,s){if(!this.wsManager)throw new Error("WebSocket not connected. Call connectWebSocket() first.");return this.wsManager.subscribe(e,r,s)}subscribeCandles(e,r,s){if(!this.wsManager)throw new Error("WebSocket not connected. Call connectWebSocket() first.");let n=`${e}:${r}`;return this.wsManager.subscribe("candle",n,s)}subscribeUserData(e,r,s){if(!this.wsManager)throw new Error("WebSocket not connected. Call connectWebSocket() first.");let n=e==="fills"?"userFills":"userEvents";return this.wsManager.subscribe(n,r,s)}unsubscribe(e){this.wsManager&&this.wsManager.unsubscribe(e);}},V=class extends Error{constructor(r,s,n){super(r);this.statusCode=s;this.responseBody=n;this.name="HyperliquidApiError";}};var re=createContext({});function Xt({client:t,children:e}){return jsx(re.Provider,{value:{client:t},children:e})}function P(){let t=useContext(re);if(!t||!t.client)throw new Error("usePerpetualsClient must be used within a PerpetualsProvider");return t}function it(){return ["perps","coins"]}async function at(t){return await t.getSupportedCoins()}function be(t={}){let{client:e}=P();return useQuery({queryKey:it(),queryFn:async()=>at(e),staleTime:300*1e3,...t})}function lt(t){return ["perps","market",t.symbol]}async function ct(t,{symbol:e}){return await t.getMarket(e)}function se(t,e={}){let{client:r}=P();return useQuery({queryKey:lt(t),queryFn:async()=>ct(r,t),staleTime:10*1e3,...e})}function dt(t={}){return ["perps","markets",JSON.stringify((t.symbols??[]).sort())]}async function ut(t,{symbols:e}={}){return await t.getMarkets(e)}function xe(t={},e={}){let{client:r}=P();return useQuery({queryKey:dt(t),queryFn:async()=>ut(r,t),staleTime:10*1e3,...e})}function pt(t){return ["perps","klines",t.symbol,t.interval,String(t.limit??100)]}async function mt(t,{symbol:e,interval:r,limit:s}){return await t.getKlines(e,r,s)}function or(t,e={}){let{client:r}=P();return useQuery({queryKey:pt(t),queryFn:async()=>mt(r,t),staleTime:30*1e3,...e})}function ft(t){return ["perps","orderBook",t.symbol,String(t.maxLevel??20)]}async function yt(t,{symbol:e,maxLevel:r}){return await t.getOrderBook(e,r)}function he(t,e={}){let{client:r}=P();return useQuery({queryKey:ft(t),queryFn:async()=>yt(r,t),staleTime:5*1e3,...e})}function gt(t){return ["perps","recentTrades",t.symbol,String(t.limit??50)]}async function bt(t,{symbol:e,limit:r}){return await t.getRecentTrades(e,r)}function Pe(t,e={}){let{client:r}=P();return useQuery({queryKey:gt(t),queryFn:async()=>bt(r,t),staleTime:5*1e3,...e})}function xt(t){return ["perps","positions",t.userAddress??"",t.symbol??""]}async function ht(t,e){return await t.getPositions(e)}function ve(t,e={}){let{client:r}=P(),{enabled:s=true,...n}=t;return useQuery({queryKey:xt(n),queryFn:async()=>ht(r,n),enabled:s&&!!n.userAddress,staleTime:10*1e3,...e})}function Pt(t){return ["perps","orders",t.userAddress??"",t.symbol??""]}async function vt(t,e){return await t.getOpenOrders(e)}function Se(t,e={}){let{client:r}=P(),{enabled:s=true,...n}=t;return useQuery({queryKey:Pt(n),queryFn:async()=>vt(r,n),enabled:s&&!!n.userAddress,staleTime:5*1e3,...e})}function St(t){return ["perps","trades",t.userAddress??"",t.symbol??"",String(t.limit??50),String(t.startTime??""),String(t.endTime??"")]}async function kt(t,e){return await t.getTrades(e)}function ke(t,e={}){let{client:r}=P(),{enabled:s=true,...n}=t;return useQuery({queryKey:St(n),queryFn:async()=>kt(r,n),enabled:s&&!!n.userAddress,staleTime:30*1e3,...e})}async function Ct(t,e){return await t.placeOrder(e)}function ne(t={}){let{client:e}=P();return useMutation({mutationFn:async r=>Ct(e,r),...t})}async function Nt(t,e){return await t.cancelOrder(e)}function Ce(t={}){let{client:e}=P();return useMutation({mutationFn:async r=>Nt(e,r),...t})}function _(t){let{type:e,symbol:r,enabled:s=true}=t,{client:n}=P(),[o,i]=useState(null),[a,l]=useState(false),[c,d]=useState(null),u=useCallback(f=>{i(f);},[]);return useEffect(()=>{if(!s)return;let f=null,p=true;return (async()=>{try{if(await n.connectWebSocket(),!p)return;l(!0),d(null),f=n.subscribeMarketData(e,r,u);}catch(y){p&&(d(y instanceof Error?y:new Error("Connection failed")),l(false));}})(),()=>{if(p=false,f)try{n.unsubscribe(f);}catch(y){console.error("Failed to unsubscribe:",y);}n.disconnectWebSocket(),l(false),i(null);}},[n,e,r,s,u]),{data:o,isConnected:a,error:c}}function br(t){let{symbol:e,interval:r,enabled:s=true}=t,{client:n}=P(),[o,i]=useState(null),[a,l]=useState(false),[c,d]=useState(null),u=useCallback(f=>{i(f);},[]);return useEffect(()=>{if(!s)return;let f=null,p=true;return (async()=>{try{if(await n.connectWebSocket(),!p)return;l(!0),d(null),f=n.subscribeCandles(e,r,u);}catch(y){p&&(d(y instanceof Error?y:new Error("Connection failed")),l(false));}})(),()=>{if(p=false,f)try{n.unsubscribe(f);}catch(y){console.error("Failed to unsubscribe:",y);}n.disconnectWebSocket(),l(false),i(null);}},[n,e,r,s,u]),{data:o,isConnected:a,error:c}}function oe(t){let{type:e,userAddress:r,enabled:s=true}=t,{client:n}=P(),[o,i]=useState(null),[a,l]=useState(false),[c,d]=useState(null),u=useCallback(f=>{i(f);},[]);return useEffect(()=>{if(!s||!r)return;let f=null,p=true;return (async()=>{try{if(await n.connectWebSocket(),!p)return;l(!0),d(null),f=n.subscribeUserData(e,r,u);}catch(y){p&&(d(y instanceof Error?y:new Error("Connection failed")),l(false));}})(),()=>{if(p=false,f)try{n.unsubscribe(f);}catch(y){console.error("Failed to unsubscribe:",y);}n.disconnectWebSocket(),l(false),i(null);}},[n,e,r,s,u]),{data:o,isConnected:a,error:c}}function Te(){return jsx("div",{className:"flex items-center justify-center px-4 py-3 bg-neutral-900 border-b border-neutral-800",children:jsx("span",{className:"text-neutral-400 text-sm",children:"Market data not available"})})}function Ue(){return jsxs("div",{className:"flex items-center gap-6 px-4 py-3 bg-neutral-900 border-b border-neutral-800",children:[jsxs("div",{className:"flex items-center gap-3",children:[jsx(Skeleton,{className:"h-6 w-20 rounded"}),jsxs("div",{className:"flex items-center gap-2",children:[jsx(Skeleton,{className:"h-8 w-28 rounded"}),jsx(Skeleton,{className:"h-5 w-16 rounded"})]})]}),jsx("div",{className:"h-8 w-px bg-neutral-800"}),jsxs("div",{className:"flex items-center gap-6 text-sm",children:[jsxs("div",{className:"flex flex-col gap-1",children:[jsx(Skeleton,{className:"h-3 w-20 rounded"}),jsx(Skeleton,{className:"h-5 w-16 rounded"})]}),jsxs("div",{className:"flex flex-col gap-1",children:[jsx(Skeleton,{className:"h-3 w-20 rounded"}),jsx(Skeleton,{className:"h-5 w-16 rounded"})]}),jsxs("div",{className:"flex flex-col gap-1",children:[jsx(Skeleton,{className:"h-3 w-24 rounded"}),jsx(Skeleton,{className:"h-5 w-16 rounded"})]}),jsxs("div",{className:"flex flex-col gap-1",children:[jsx(Skeleton,{className:"h-3 w-32 rounded"}),jsxs("div",{className:"flex items-center gap-2",children:[jsx(Skeleton,{className:"h-5 w-16 rounded"}),jsx(Skeleton,{className:"h-5 w-20 rounded"})]})]})]})]})}function Fe(t){let[e,r]=useState(),[s,n]=useState(0),{data:o,isPending:i}=se({symbol:t}),{data:a,isConnected:l}=_({type:"ticker",symbol:t,enabled:!!o});return useEffect(()=>{o&&r(o);},[o]),useEffect(()=>{if(!a)return;let c=Pr(a,t);c&&r(d=>vr(d??o??void 0,c,t));},[a,o,t]),useEffect(()=>{let c=()=>{let u=Date.now(),f=480*60*1e3,p=u%f,g=f-p;return Math.floor(g/1e3)};n(c());let d=setInterval(()=>{n(c());},1e3);return ()=>clearInterval(d)},[]),{marketData:e,isLoading:i,fundingCountdown:s}}function Pr(t,e){if(Array.isArray(t)){let r=t.find(s=>!s||typeof s!="object"?false:s.symbol===e);return r&&typeof r=="object"?r:null}return t&&typeof t=="object"?t:null}function j(t,e){return typeof t=="number"&&Number.isFinite(t)?t:e}function vr(t,e,r){return {symbol:e.symbol??t?.symbol??r,price:j(e.price,t?.price??0),change24h:j(e.change24h,t?.change24h??0),volume24h:j(e.volume24h,t?.volume24h??0),fundingRate:j(e.fundingRate,t?.fundingRate??0),openInterest:j(e.openInterest,t?.openInterest??0),markPrice:j(e.markPrice,t?.markPrice??0),indexPrice:typeof e.indexPrice=="number"&&Number.isFinite(e.indexPrice)?e.indexPrice:t?.indexPrice,high24h:typeof e.high24h=="number"&&Number.isFinite(e.high24h)?e.high24h:t?.high24h,low24h:typeof e.low24h=="number"&&Number.isFinite(e.low24h)?e.low24h:t?.low24h}}function Sr(t){let e=Math.floor(t/3600),r=Math.floor(t%3600/60),s=t%60;return `${String(e).padStart(2,"0")}:${String(r).padStart(2,"0")}:${String(s).padStart(2,"0")}`}function Tt(t,e=2){return typeof t!="number"||!Number.isFinite(t)?"-":t>=1e9?`$${(t/1e9).toFixed(e)}B`:t>=1e6?`$${(t/1e6).toFixed(e)}M`:t>=1e3?`$${(t/1e3).toFixed(e)}K`:`$${t.toFixed(e)}`}function Ut(t){return typeof t!="number"||!Number.isFinite(t)?"-":t>=1e3?t.toLocaleString("en-US",{minimumFractionDigits:0,maximumFractionDigits:0}):t>=1?t.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:4}):t.toFixed(6)}function Ie({marketData:t,fundingCountdown:e}){let{symbol:r,price:s,change24h:n,indexPrice:o,volume24h:i,openInterest:a,fundingRate:l}=t,c=typeof n=="number"&&Number.isFinite(n)?n:0,d=typeof l=="number"&&Number.isFinite(l)?l:0,u=c>=0,f=c.toFixed(2);return jsxs("div",{className:"flex items-center px-4",style:{minHeight:64,maxHeight:64,gap:16},children:[jsxs("div",{className:"flex items-baseline",style:{gap:8},children:[jsx("span",{style:{fontSize:18,fontWeight:500,lineHeight:"23px",letterSpacing:"-0.36px",color:"#fcfcfc"},children:Ut(s)}),jsxs("span",{style:{fontSize:12,fontWeight:400,lineHeight:"16px",color:u?"#2fe3ac":"#ec397a"},children:[u?"+":"",f,"%"]})]}),jsxs("div",{className:"flex items-center",style:{gap:16},children:[jsxs("div",{className:"flex flex-col",children:[jsx("span",{style:{fontSize:12,color:"#c8c9d1",lineHeight:"16px",letterSpacing:"-0.12px"},children:"Oracle Price"}),jsx("span",{style:{fontSize:13,fontWeight:400,lineHeight:"17px",color:"#fcfcfc"},children:o?Ut(o):"-"})]}),jsxs("div",{className:"flex flex-col",children:[jsx("span",{style:{fontSize:12,color:"#c8c9d1",lineHeight:"16px",letterSpacing:"-0.12px"},children:"24h Volume"}),jsx("span",{style:{fontSize:13,fontWeight:400,lineHeight:"17px",color:"#fcfcfc"},children:Tt(i,0)})]}),jsxs("div",{className:"flex flex-col",children:[jsx("span",{style:{fontSize:12,color:"#c8c9d1",lineHeight:"16px",letterSpacing:"-0.12px"},children:"Open Interest"}),jsx("span",{style:{fontSize:13,fontWeight:400,lineHeight:"17px",color:"#fcfcfc"},children:Tt(a*(t.markPrice||s))})]}),jsxs("div",{className:"flex flex-col",children:[jsx("span",{style:{fontSize:12,color:"#c8c9d1",lineHeight:"16px",letterSpacing:"-0.12px"},children:"Funding / Countdown"}),jsxs("div",{className:"flex items-center",style:{gap:8},children:[jsxs("span",{style:{fontSize:13,lineHeight:"17px",color:d>=0?"#2fe3ac":"#ec397a"},children:[(d*100).toFixed(5),"%"]}),jsx("span",{style:{fontSize:13,lineHeight:"17px",color:"#fcfcfc"},children:Sr(e)})]})]})]})]})}function kr({symbol:t}){let{marketData:e,isLoading:r,fundingCountdown:s}=Fe(t);return r?jsx(Ue,{}):e?jsx(Ie,{marketData:e,fundingCountdown:s}):jsx(Te,{})}function Re({onSelectCoin:t}={}){let[e,r]=useState(""),[s,n]=useState([]),{data:o,isPending:i}=be(),{data:a,isPending:l}=xe({symbols:o},{enabled:!!o&&o.length>0});useEffect(()=>{a&&n(a);},[a]);let c=useMemo(()=>{if(!e.trim())return s;let u=e.toLowerCase().trim();return s.filter(f=>f.symbol.toLowerCase().includes(u))},[s,e]);return {coins:s,isLoading:i||l,searchQuery:e,setSearchQuery:r,filteredCoins:c,handleSelectCoin:u=>{t?.(u);}}}function Ft(t,e=2){return t>=1e9?`$${(t/1e9).toFixed(e)}B`:t>=1e6?`$${(t/1e6).toFixed(e)}M`:t>=1e3?`$${(t/1e3).toFixed(e)}K`:`$${t.toFixed(e)}`}function Or(t){return t>=1e3?t.toFixed(2):t>=1?t.toFixed(4):t.toFixed(6)}function Ee({coins:t,searchQuery:e,onSearchChange:r,onSelectCoin:s,isLoading:n}){return jsxs("div",{className:"flex flex-col",style:{backgroundColor:"#18181a",flex:"1 1 0",minHeight:0},children:[jsx("div",{style:{padding:"16px 16px 12px"},children:jsxs("div",{className:"flex items-center",style:{height:32,border:"1px solid #323542",borderRadius:4,padding:"0 6px 0 12px",gap:8},children:[jsx(SearchIcon,{className:"flex-shrink-0",style:{width:14,height:14,color:"#777a8c"}}),jsx("input",{type:"text",placeholder:"Search coins...",value:e,onChange:o=>r(o.target.value),className:"flex-1 bg-transparent outline-none",style:{fontSize:12,color:"#fcfcfc",border:"none"}})]})}),jsxs("div",{className:"flex-1 overflow-auto",children:[jsxs("div",{className:"flex items-center",style:{height:28,padding:"0 16px",borderBottom:"1px solid rgba(50,53,66,0.5)",position:"sticky",top:0,backgroundColor:"#18181a",zIndex:1},children:[jsx("span",{style:{flex:"0 0 140px",fontSize:12,color:"#777a8c"},children:"Token"}),jsx("span",{style:{flex:"0 0 100px",fontSize:12,color:"#777a8c",textAlign:"right"},children:"Last Price"}),jsx("span",{style:{flex:"0 0 120px",fontSize:12,color:"#777a8c",textAlign:"right"},children:"24h Change"}),jsx("span",{style:{flex:"0 0 100px",fontSize:12,color:"#777a8c",textAlign:"right"},children:"8h Funding"}),jsx("span",{style:{flex:"0 0 100px",fontSize:12,color:"#777a8c",textAlign:"right"},children:"24h Volume"}),jsx("span",{style:{flex:"1",fontSize:12,color:"#777a8c",textAlign:"right"},children:"Open Interest"})]}),n?jsx("div",{className:"flex items-center justify-center",style:{height:100},children:jsx("span",{style:{fontSize:12,color:"#777a8c"},children:"Loading..."})}):t.length===0?jsx("div",{className:"flex items-center justify-center",style:{height:100},children:jsx("span",{style:{fontSize:12,color:"#777a8c"},children:e?"No coins found":"No coins available"})}):t.map(o=>{let i=o.change24h>=0,a=o.change24h.toFixed(2),l=(o.fundingRate*100).toFixed(4),c=o.fundingRate>=0,d=o.symbol.split("-")[0];return jsxs("div",{className:"flex items-center cursor-pointer transition-colors",style:{height:36,padding:"0 16px",borderBottom:"1px solid rgba(50,53,66,0.5)"},onClick:()=>s(o.symbol),onMouseEnter:u=>{u.currentTarget.style.backgroundColor="rgba(255,255,255,0.03)";},onMouseLeave:u=>{u.currentTarget.style.backgroundColor="transparent";},children:[jsxs("div",{className:"flex items-center",style:{flex:"0 0 140px",gap:8},children:[jsx("img",{src:`https://app.hyperliquid.xyz/coins/${d}.svg`,alt:d,className:"rounded-full",style:{width:20,height:20},onError:u=>{let f=u.target;f.style.display="none";}}),jsx("span",{style:{fontSize:12,fontWeight:500,color:"#fcfcfc"},children:d})]}),jsx("span",{style:{flex:"0 0 100px",fontSize:12,color:"#fcfcfc",textAlign:"right"},children:Or(o.price)}),jsxs("span",{style:{flex:"0 0 120px",fontSize:12,fontWeight:500,color:i?"#2fe3ac":"#ec397a",textAlign:"right"},children:[i?"+":"",a,"%"]}),jsxs("span",{style:{flex:"0 0 100px",fontSize:12,color:c?"#2fe3ac":"#ec397a",textAlign:"right"},children:[l,"%"]}),jsx("span",{style:{flex:"0 0 100px",fontSize:12,color:"#c8c9d1",textAlign:"right"},children:Ft(o.volume24h)}),jsx("span",{style:{flex:"1",fontSize:12,color:"#c8c9d1",textAlign:"right"},children:Ft(o.openInterest*o.price)})]},o.symbol)})]})]})}function Tr({onSelectCoin:t,className:e}){let{filteredCoins:r,isLoading:s,searchQuery:n,setSearchQuery:o,handleSelectCoin:i}=Re({onSelectCoin:t});return jsx("div",{className:e,style:{display:"flex",flexDirection:"column",flex:"1 1 0",minHeight:0,overflow:"hidden"},children:jsx(Ee,{coins:r,searchQuery:n,onSearchChange:o,onSelectCoin:i,isLoading:s})})}function Rt(t,e){if(e<=0)return t;let r=new Map;return t.forEach(s=>{let n=Math.floor(s.price/e)*e,o=r.get(n);o?(o.quantity+=s.quantity,s.count&&(o.count=(o.count||0)+s.count)):r.set(n,{price:n,quantity:s.quantity,count:s.count});}),Array.from(r.values())}function Et(t){let e=0,r=t.map(n=>{let o=n.quantity*n.price;return e+=o,{...n,quantity:o,total:e,percentage:0}}),s=e;return r.map(n=>({...n,percentage:s>0?n.total/s*100:0}))}function ze({symbol:t,maxLevel:e=20,precision:r=.01}){let[s,n]=useState(null),[o,i]=useState(r),{data:a,isPending:l}=he({symbol:t,maxLevel:e}),{data:c}=_({type:"orderBook",symbol:t,enabled:!!a});return useEffect(()=>{c?n(c):a&&n(a);},[c,a]),{...useMemo(()=>{if(!s)return {bids:[],asks:[],spread:0,spreadPercentage:0};let u=Rt(s.bids,o),f=Rt(s.asks,o),p=u.sort((H,R)=>R.price-H.price).slice(0,e),g=f.sort((H,R)=>H.price-R.price).slice(0,e),y=Et(p),N=Et(g),h=y[0]?.price||0,I=(N[0]?.price||0)-h,W=h>0?I/h*100:0;return {bids:y,asks:N,spread:I,spreadPercentage:W}},[s,o,e]),isLoading:l,precision:o,setPrecision:i}}function Fr(t){return t>=1e3?t.toLocaleString("en-US",{minimumFractionDigits:0,maximumFractionDigits:0}):t>=1?t.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:4}):t.toFixed(6)}function zt(t){return Math.round(t).toLocaleString("en-US")}function Qt({price:t,quantity:e,total:r,percentage:s,side:n,onClick:o}){let i=n==="ask";return jsxs("div",{className:"relative flex items-center cursor-pointer hover:bg-white/5 transition-colors",style:{height:22,minHeight:22,maxHeight:22,padding:"0 16px",gap:16,fontSize:11},onClick:o,children:[jsx("div",{className:"absolute left-0 top-0",style:{height:20,width:`${s}%`,background:i?"linear-gradient(to right, rgba(209,57,236,0), rgb(236,57,122))":"linear-gradient(to right, rgba(47,194,227,0), rgb(47,227,172))",opacity:.15}}),jsx("div",{className:"relative z-10 flex items-center",style:{flex:"1 1 0%"},children:jsx("span",{style:{color:i?"#ec397a":"#2fe3ac",fontWeight:400},children:Fr(t)})}),jsx("div",{className:"relative z-10 flex items-center justify-end",style:{flex:"1 1 0%",color:"#fcfcfc"},children:zt(e)}),jsx("div",{className:"relative z-10 flex items-center justify-end",style:{flex:"1 1 0%",color:"#fcfcfc"},children:zt(r)})]})}function Qe({bids:t,asks:e,spread:r,spreadPercentage:s,onPriceClick:n}){let o=[...e].reverse();return jsxs("div",{className:"flex flex-col h-full",style:{backgroundColor:"#06070b",fontSize:11},children:[jsxs("div",{className:"flex items-center",style:{height:28,minHeight:28,padding:"0 16px",gap:16,color:"#777a8c",fontSize:11},children:[jsx("div",{className:"flex items-center",style:{flex:"1 1 0%"},children:"Price"}),jsx("div",{className:"flex items-center justify-end",style:{flex:"1 1 0%"},children:"Amount (USD)"}),jsx("div",{className:"flex items-center justify-end",style:{flex:"1 1 0%"},children:"Total (USD)"})]}),jsx("div",{className:"flex-1 flex flex-col-reverse overflow-hidden",children:o.map((i,a)=>jsx(Qt,{price:i.price,quantity:i.quantity,total:i.total,percentage:i.percentage,side:"ask",onClick:()=>n?.(i.price)},`ask-${i.price}-${a}`))}),jsx("div",{className:"flex items-center justify-center",style:{height:24,minHeight:24,padding:"0 16px",backgroundColor:"rgba(34,36,45,0.5)"},children:jsxs("div",{className:"flex items-center",style:{gap:12,fontSize:12,color:"#fcfcfc"},children:[jsx("span",{style:{color:"#fcfcfc"},children:"Spread:"}),jsx("button",{type:"button",className:"hover:text-white transition-colors cursor-pointer",style:{color:"#fcfcfc",fontWeight:400,background:"none",border:"none",padding:0},onClick:()=>n?.(r),children:r>=1?Math.round(r).toLocaleString("en-US"):r.toFixed(4)}),jsxs("span",{style:{color:"#fcfcfc",fontWeight:500},children:[s.toFixed(3),"%"]})]})}),jsx("div",{className:"flex-1 overflow-hidden",children:t.map((i,a)=>jsx(Qt,{price:i.price,quantity:i.quantity,total:i.total,percentage:i.percentage,side:"bid",onClick:()=>n?.(i.price)},`bid-${i.price}-${a}`))})]})}function Ir(){return jsxs("div",{className:"flex flex-col h-full",style:{padding:"0 16px"},children:[jsxs("div",{className:"flex justify-between items-center",style:{height:28,marginBottom:4},children:[jsx(Skeleton,{className:"h-3 w-12 rounded"}),jsx(Skeleton,{className:"h-3 w-14 rounded"}),jsx(Skeleton,{className:"h-3 w-14 rounded"})]}),Array.from({length:10}).map((t,e)=>jsxs("div",{className:"flex justify-between items-center",style:{height:22},children:[jsx(Skeleton,{className:"h-3 w-14 rounded"}),jsx(Skeleton,{className:"h-3 w-14 rounded"}),jsx(Skeleton,{className:"h-3 w-14 rounded"})]},`ask-skeleton-${e}`)),jsx("div",{className:"flex justify-center items-center",style:{height:28},children:jsx(Skeleton,{className:"h-4 w-32 rounded"})}),Array.from({length:10}).map((t,e)=>jsxs("div",{className:"flex justify-between items-center",style:{height:22},children:[jsx(Skeleton,{className:"h-3 w-14 rounded"}),jsx(Skeleton,{className:"h-3 w-14 rounded"}),jsx(Skeleton,{className:"h-3 w-14 rounded"})]},`bid-skeleton-${e}`))]})}function Dr(){return jsx("div",{className:"flex items-center justify-center h-full",children:jsx("span",{className:"text-neutral-400 text-sm",children:"No order book data available"})})}function Rr({symbol:t,maxLevel:e=20,onPriceClick:r,className:s}){let{bids:n,asks:o,spread:i,spreadPercentage:a,isLoading:l}=ze({symbol:t,maxLevel:e});return l?jsx(Ir,{}):n.length===0&&o.length===0?jsx(Dr,{}):jsx("div",{className:s,children:jsx(Qe,{bids:n,asks:o,spread:i,spreadPercentage:a,onPriceClick:r})})}function qe({symbol:t,limit:e=50}){let[r,s]=useState([]),{data:n,isPending:o}=Pe({symbol:t,limit:e}),{data:i}=_({type:"trades",symbol:t,enabled:!!n});return useEffect(()=>{n&&s(n.filter(Bt));},[n]),useEffect(()=>{i&&s(a=>{let l=zr(i);if(l.length===0)return a;let c=l.filter(u=>!a.some(f=>f.timestamp===u.timestamp&&f.price===u.price&&f.quantity===u.quantity));return c.length===0?a:[...c,...a].slice(0,e)});},[i,e]),{trades:r,isLoading:o}}function zr(t){return (Array.isArray(t)?t:[t]).filter(Bt)}function Bt(t){return t?typeof t.symbol=="string"&&(t.side==="buy"||t.side==="sell")&&typeof t.price=="number"&&Number.isFinite(t.price)&&typeof t.quantity=="number"&&Number.isFinite(t.quantity)&&typeof t.timestamp=="number"&&Number.isFinite(t.timestamp):false}function Qr(t){return typeof t!="number"||!Number.isFinite(t)?"-":t>=1e3?t.toFixed(2):t>=1?t.toFixed(4):t.toFixed(6)}function Lt(t){return typeof t!="number"||!Number.isFinite(t)?"-":t>=1e6?(t/1e6).toFixed(2)+"M":t>=1e3?(t/1e3).toFixed(2)+"K":t.toFixed(2)}function qr(t){if(typeof t!="number"||!Number.isFinite(t))return "-";let e=new Date(t),r=String(e.getHours()).padStart(2,"0"),s=String(e.getMinutes()).padStart(2,"0"),n=String(e.getSeconds()).padStart(2,"0");return `${r}:${s}:${n}`}function Le({trades:t,onTradeClick:e}){return jsxs("div",{className:"flex flex-col h-full overflow-auto",style:{backgroundColor:"#06070b",fontSize:11},children:[jsxs("div",{className:"sticky top-0 z-10 flex items-center",style:{height:28,minHeight:28,padding:"0 16px",gap:16,color:"#777a8c",fontSize:11},children:[jsx("div",{className:"flex-1",style:{maxWidth:100},children:"Price"}),jsx("div",{className:"flex-1 text-right",children:"Amount"}),jsx("div",{className:"flex-1 text-right",style:{maxWidth:100},children:"Total"}),jsx("div",{className:"flex-1 text-right",style:{maxWidth:70},children:"Time"})]}),jsx("div",{className:"flex-1",children:t.map((r,s)=>{let n=r.side==="buy",o=typeof r.price=="number"&&Number.isFinite(r.price)&&typeof r.quantity=="number"&&Number.isFinite(r.quantity)?r.price*r.quantity:void 0;return jsxs("div",{className:"flex items-center cursor-pointer hover:bg-white/5 transition-colors",style:{height:22,minHeight:22,maxHeight:22,padding:"0 16px",gap:16,fontSize:11},onClick:()=>e?.(r),children:[jsx("div",{className:"flex-1",style:{maxWidth:100},children:jsx("span",{style:{color:n?"#2fe3ac":"#ec397a",fontWeight:400},children:Qr(r.price)})}),jsx("div",{className:"flex-1 text-right",style:{color:"#fcfcfc"},children:Lt(r.quantity)}),jsx("div",{className:"flex-1 text-right",style:{maxWidth:100,color:"#fcfcfc"},children:Lt(o)}),jsx("div",{className:"flex-1 text-right",style:{maxWidth:70,color:"#c8c9d1"},children:qr(r.timestamp)})]},`${r.timestamp}-${r.price}-${s}`)})})]})}function Br(){return jsxs("div",{className:"flex flex-col h-full",style:{padding:"0 16px"},children:[jsxs("div",{className:"flex justify-between items-center",style:{height:28,marginBottom:4},children:[jsx(Skeleton,{className:"h-3 w-12 rounded"}),jsx(Skeleton,{className:"h-3 w-10 rounded"}),jsx(Skeleton,{className:"h-3 w-10 rounded"}),jsx(Skeleton,{className:"h-3 w-12 rounded"})]}),Array.from({length:12}).map((t,e)=>jsxs("div",{className:"flex justify-between items-center",style:{height:22},children:[jsx(Skeleton,{className:"h-3 w-14 rounded"}),jsx(Skeleton,{className:"h-3 w-10 rounded"}),jsx(Skeleton,{className:"h-3 w-10 rounded"}),jsx(Skeleton,{className:"h-3 w-12 rounded"})]},`trade-skeleton-${e}`))]})}function Lr(){return jsx("div",{className:"flex items-center justify-center h-full",children:jsx("span",{className:"text-neutral-400 text-sm",children:"No recent trades"})})}function Ar({symbol:t,limit:e=50,onTradeClick:r,className:s}){let{trades:n,isLoading:o}=qe({symbol:t,limit:e});return o?jsx(Br,{}):n.length===0?jsx(Lr,{}):jsx("div",{className:s,children:jsx(Le,{trades:n,onTradeClick:r})})}function We({symbol:t,userAddress:e,maxLeverage:r=150,onSuccess:s,onError:n}){let[o,i]=useState("long"),[a,l]=useState("market"),c=useForm({defaultValues:{amount:0,leverage:20,takeProfitPrice:void 0,takeProfitPercent:void 0,stopLossPrice:void 0,stopLossPercent:void 0}}),{data:d}=se({symbol:t}),{mutateAsync:u,isPending:f}=ne({onSuccess:()=>{c.reset(),s?.();},onError:k=>{n?.(k);}}),p=c.watch(),{amount:g,leverage:y,price:N}=p,h=useMemo(()=>a==="limit"&&N?N:d?.price||0,[a,N,d?.price]),B=useMemo(()=>!g||!h?0:g*h*5e-4,[g,h]),I=useMemo(()=>!g||!h?0:g*h+B,[g,h,B]),W=useMemo(()=>{if(!g||!h||!y||y===1)return;let k=.005,G=h;return o==="long"?G*(1-(1/y-k)):G*(1+(1/y-k))},[g,h,y,o]),H=1e4,R=1e4,me=0,C=useCallback(async k=>{if(!e)throw new Error("User address is required");let G=a==="limit"?k.price:void 0,fe=k.takeProfitPrice,ye=k.stopLossPrice;if(!fe&&k.takeProfitPercent&&k.takeProfitPercent>0&&h){let te=k.takeProfitPercent/100;fe=o==="long"?h*(1+te):h*(1-te);}if(!ye&&k.stopLossPercent&&k.stopLossPercent>0&&h){let te=k.stopLossPercent/100;ye=o==="long"?h*(1-te):h*(1+te);}await u({symbol:t,side:o,orderType:a,amount:k.amount,price:G,leverage:k.leverage,takeProfitPrice:fe,stopLossPrice:ye,userAddress:e});},[t,o,a,h,e,u]);return {form:c,side:o,orderType:a,setSide:i,setOrderType:l,handleSubmit:C,isSubmitting:f,currentPrice:h,estimatedFee:B,estimatedTotal:I,liquidationPrice:W,availableMargin:H,accountValue:R,currentPosition:me,maxLeverage:r}}function de(t,e=2){return t.toFixed(e)}function _r({leverage:t,maxLeverage:e,onLeverageChange:r,onClose:s}){let n=[1,2,3,5,10,20,25,50,100].filter(o=>o<=e);return jsxs("div",{className:"fixed inset-0 z-50 flex items-center justify-center",children:[jsx("div",{className:"absolute inset-0 bg-black/60",onClick:s,onKeyDown:o=>o.key==="Escape"&&s(),role:"button",tabIndex:-1,"aria-label":"Close"}),jsxs("div",{className:"relative z-10 w-72 bg-neutral-900 border border-neutral-700 rounded-lg p-4 shadow-2xl",children:[jsxs("div",{className:"flex items-center justify-between mb-4",children:[jsx("h3",{className:"text-sm font-medium text-white",children:"Adjust Leverage"}),jsx("button",{type:"button",onClick:s,className:"text-neutral-400 hover:text-white",children:jsx("svg",{className:"w-4 h-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"})})})]}),jsxs("div",{className:"text-center text-2xl font-bold text-white mb-4",children:[t,"x"]}),jsx(Slider,{value:[t],onChange:o=>r(Array.isArray(o)?o[0]:o),minValue:1,maxValue:e,step:1,className:"w-full mb-3"}),jsx("div",{className:"flex flex-wrap gap-1.5",children:n.map(o=>jsxs("button",{type:"button",className:cn("px-2.5 py-1 text-xs rounded transition-colors",t===o?"bg-green-600 text-white":"bg-neutral-800 text-neutral-400 hover:bg-neutral-700"),onClick:()=>r(o),children:[o,"x"]},o))}),jsx("button",{type:"button",className:"w-full mt-4 text-white h-9 rounded cursor-pointer transition-colors",style:{backgroundColor:"#16a34a"},onClick:s,children:"Confirm"})]})]})}function He({methods:t,side:e,orderType:r,onSideChange:s,onOrderTypeChange:n,onSubmit:o,isSubmitting:i,symbol:a,currentPrice:l,estimatedFee:c,liquidationPrice:d,availableMargin:u,accountValue:f,currentPosition:p,maxLeverage:g}){let[y,N]=useState(false),[h,B]=useState(false),I=t.watch("leverage")||20,W=t.watch("amount")||0,H=a.split("-")[0],R=u>0&&l?Math.min(W*l/(u*I)*100,100):0,me=C=>{let k=(Array.isArray(C)?C[0]:C)/100;if(l&&l>0){let G=u*I*k/l;t.setValue("amount",Number(G.toFixed(6)));}};return jsxs("div",{className:"flex flex-col h-full",style:{backgroundColor:"#06070b"},children:[jsxs("div",{className:"perp-order-form flex-1 overflow-y-auto",style:{padding:"16px 16px",display:"flex",flexDirection:"column",gap:16},children:[jsxs("div",{className:"flex",style:{border:"1px solid rgba(34,36,45,0.5)",borderRadius:8,padding:4,gap:4},children:[jsx("button",{type:"button",className:"flex-1 cursor-pointer transition-colors",style:{height:32,fontSize:16,borderRadius:4,backgroundColor:e==="long"?"#2fe3ac":"transparent",color:e==="long"?"#090909":"#c8c9d1",fontWeight:e==="long"?700:500},onClick:()=>s("long"),children:"Long"}),jsx("button",{type:"button",className:"flex-1 cursor-pointer transition-colors",style:{height:32,fontSize:16,borderRadius:4,backgroundColor:e==="short"?"#ec397a":"transparent",color:e==="short"?"#090909":"#c8c9d1",fontWeight:e==="short"?700:500},onClick:()=>s("short"),children:"Short"})]}),jsxs("div",{className:"flex items-center",style:{gap:8},children:[jsx("div",{className:"flex",children:[{key:"market",label:"Market"},{key:"limit",label:"Limit"}].map(C=>jsx("div",{style:{height:32,display:"flex",alignItems:"center",borderBottom:r===C.key?"2px solid #fcfcfc":"2px solid transparent",padding:"2px 0 0",cursor:"pointer"},children:jsx("button",{type:"button",className:"cursor-pointer transition-colors",style:{padding:"0 8px",fontSize:12,fontWeight:500,backgroundColor:"transparent",color:r===C.key?"#fcfcfc":"#c8c9d1",border:"none"},onClick:()=>n(C.key),children:C.label})},C.key))}),jsx("div",{className:"flex-1"}),jsxs("button",{type:"button",className:"cursor-pointer transition-colors",style:{height:24,padding:"0 5px",fontSize:12,borderRadius:4,backgroundColor:"rgba(34,36,45,0.5)",color:"#fcfcfc",fontWeight:400,border:"1px solid rgba(34,36,45,0.5)"},onClick:()=>N(true),children:["Leverage: ",I,"x"]})]}),jsx(RHForm,{methods:t,onSubmit:o,children:jsxs("div",{className:"space-y-3 w-full",children:[r==="limit"&&jsxs("div",{className:"perp-price-box",style:{borderRadius:4,padding:8,backgroundColor:"rgba(34,36,45,0.5)",border:"1px solid rgb(34,36,45)",height:64,display:"flex",flexDirection:"column",justifyContent:"center"},children:[jsxs("div",{className:"flex justify-between items-center",children:[jsx("span",{style:{fontSize:12,color:"#777a8c"},children:"Price"}),jsx("span",{style:{fontSize:12,color:"#777a8c"},children:"USDC"})]}),jsx(RHNumberInput,{name:"price",placeholder:"0.0 USDC",className:"w-full"})]}),jsxs("div",{className:"perp-buy-amt",style:{borderRadius:4,padding:8,backgroundColor:"rgba(34,36,45,0.5)",border:"1px solid rgb(34,36,45)",height:64,display:"flex",flexDirection:"column",justifyContent:"center"},children:[jsxs("div",{className:"flex justify-between items-center",children:[jsx("span",{style:{fontSize:12,color:"#777a8c"},children:"Buy Amount"}),jsx("span",{style:{fontSize:12,color:"#777a8c"},children:H})]}),jsx(RHNumberInput,{name:"amount",placeholder:"0.0 USDC",className:"w-full"})]}),jsxs("div",{children:[jsx("style",{children:`
|
|
1
|
+
import {createContext,useContext,useState,useCallback,useEffect,useMemo}from'react';import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {useQuery,useMutation}from'@tanstack/react-query';import {Skeleton,SearchIcon,RHForm,RHNumberInput,cn,Button,Slider}from'@liberfi.io/ui';import {useForm}from'react-hook-form';typeof window<"u"&&(window.__LIBERFI_VERSION__=window.__LIBERFI_VERSION__||{},window.__LIBERFI_VERSION__["@liberfi.io/ui-perpetuals"]="0.1.113");var Jt="0.1.113";var ae=class{ws=null;wsEndpoint;subscriptions=new Map;reconnectAttempts=0;maxReconnectAttempts=10;reconnectDelay=1e3;heartbeatInterval=null;messageQueue=[];isConnected=false;pingInterval=3e4;reconnectTimeout=null;isReconnecting=false;constructor(e){this.wsEndpoint=e;}async connect(){return new Promise((e,r)=>{try{this.ws&&this.ws.close(),this.ws=new WebSocket(this.wsEndpoint),this.ws.onopen=()=>{console.log("[WebSocket] Connected to Hyperliquid"),this.isConnected=!0,this.reconnectAttempts=0,this.isReconnecting=!1,this.startHeartbeat(),this.flushMessageQueue(),e();},this.ws.onmessage=s=>{this.handleMessage(s.data);},this.ws.onerror=s=>{console.error("[WebSocket] Error:",s),this.isConnected=!1,this.isReconnecting||r(new Error("WebSocket connection failed"));},this.ws.onclose=s=>{console.log(`[WebSocket] Closed: ${s.code} - ${s.reason||"No reason provided"}`),this.isConnected=!1,this.stopHeartbeat(),s.code!==1e3&&this.attemptReconnect();};}catch(s){r(s);}})}disconnect(){this.stopHeartbeat(),this.subscriptions.clear(),this.reconnectTimeout!==null&&(clearTimeout(this.reconnectTimeout),this.reconnectTimeout=null),this.ws&&(this.ws.close(1e3,"Normal closure"),this.ws=null),this.isConnected=false,this.isReconnecting=false,this.reconnectAttempts=0;}attemptReconnect(){if(this.isReconnecting)return;if(this.reconnectAttempts>=this.maxReconnectAttempts){console.error("[WebSocket] Max reconnection attempts reached");return}this.isReconnecting=true,this.reconnectAttempts++;let e=Math.min(this.reconnectDelay*Math.pow(2,this.reconnectAttempts-1),3e4);console.log(`[WebSocket] Reconnecting in ${e}ms (attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts})`),this.reconnectTimeout=window.setTimeout(()=>{this.connect().then(()=>{this.resubscribeAll();}).catch(r=>{console.error("[WebSocket] Reconnection failed:",r),this.isReconnecting=false;});},e);}startHeartbeat(){this.heartbeatInterval=window.setInterval(()=>{this.isConnected&&this.ws&&this.ws.readyState===WebSocket.OPEN&&this.send({method:"ping"});},this.pingInterval);}stopHeartbeat(){this.heartbeatInterval!==null&&(clearInterval(this.heartbeatInterval),this.heartbeatInterval=null);}send(e){this.isConnected&&this.ws&&this.ws.readyState===WebSocket.OPEN?this.ws.send(JSON.stringify(e)):this.messageQueue.push(e);}flushMessageQueue(){for(;this.messageQueue.length>0;){let e=this.messageQueue.shift();e&&this.send(e);}}resubscribeAll(){this.subscriptions.forEach(e=>{this.sendSubscription(e.type,e.param);});}handleMessage(e){try{let r=JSON.parse(e);r.channel?this.handleChannelMessage(r):r.method;}catch(r){console.error("[WebSocket] Failed to parse message:",r,e);}}handleChannelMessage(e){let r=e.channel;this.subscriptions.forEach((s,n)=>{if(this.isChannelMatch(r,s.type,s.param))try{let o=this.transformData(s.type,e.data,s.param);s.callback(o);}catch(o){console.error(`[WebSocket] Error in subscription callback (${n}):`,o);}});}isChannelMatch(e,r,s){return r==="ticker"?e==="allMids":r==="trades"?e==="trades":r==="orderBook"?e==="l2Book":r==="candle"?e==="candle":r==="userFills"?e==="userFills":r==="userEvents"?e==="userEvents":false}transformData(e,r,s){return e==="ticker"?this.transformTickerData(r):e==="trades"?this.transformTradesData(r,s):e==="orderBook"?this.transformOrderBookData(r,s):e==="candle"?this.transformCandleData(r,s):e==="userFills"?this.transformUserFillsData(r):e==="userEvents"?this.transformUserEventsData(r):r}transformTickerData(e){let r=e.mids||{};return Object.entries(r).map(([s,n])=>({symbol:`${s}-USDC`,price:parseFloat(n),timestamp:Date.now()}))}transformTradesData(e,r){return Array.isArray(e)?e.map(s=>({symbol:r,side:s.side==="B"?"buy":"sell",price:parseFloat(s.px),quantity:parseFloat(s.sz),timestamp:s.time,tradeId:s.tid})):[]}transformOrderBookData(e,r){let[s,n]=e.levels||[[],[]];return {symbol:r,bids:s.map(o=>({price:parseFloat(o.px),quantity:parseFloat(o.sz),count:o.n})),asks:n.map(o=>({price:parseFloat(o.px),quantity:parseFloat(o.sz),count:o.n})),timestamp:e.time||Date.now()}}transformCandleData(e,r){let[s]=r.split(":");return {symbol:s,open:parseFloat(e.o),high:parseFloat(e.h),low:parseFloat(e.l),close:parseFloat(e.c),volume:parseFloat(e.v),timestamp:e.t,closeTimestamp:e.T}}transformUserFillsData(e){return Array.isArray(e)?e.map(r=>({tradeId:r.tid?.toString(),orderId:r.oid?.toString(),symbol:`${r.coin}-USDC`,side:r.dir?.includes("Long")?"long":"short",price:parseFloat(r.px),quantity:parseFloat(r.sz),fee:parseFloat(r.fee||"0"),feeCurrency:r.feeToken||"USDC",isMaker:r.side==="M",timestamp:r.time})):[]}transformUserEventsData(e){return e}sendSubscription(e,r){let s;if(e==="ticker")s={method:"subscribe",subscription:{type:"allMids"}};else if(e==="trades")s={method:"subscribe",subscription:{type:"trades",coin:r.split("-")[0]}};else if(e==="orderBook")s={method:"subscribe",subscription:{type:"l2Book",coin:r.split("-")[0]}};else if(e==="candle"){let[n,o]=r.split(":");s={method:"subscribe",subscription:{type:"candle",coin:n.split("-")[0],interval:o}};}else e==="userFills"?s={method:"subscribe",subscription:{type:"userFills",user:r}}:e==="userEvents"&&(s={method:"subscribe",subscription:{type:"userEvents",user:r}});s&&this.send(s);}sendUnsubscription(e,r){let s;if(e==="ticker")s={method:"unsubscribe",subscription:{type:"allMids"}};else if(e==="trades")s={method:"unsubscribe",subscription:{type:"trades",coin:r.split("-")[0]}};else if(e==="orderBook")s={method:"unsubscribe",subscription:{type:"l2Book",coin:r.split("-")[0]}};else if(e==="candle"){let[n,o]=r.split(":");s={method:"unsubscribe",subscription:{type:"candle",coin:n.split("-")[0],interval:o}};}else e==="userFills"?s={method:"unsubscribe",subscription:{type:"userFills",user:r}}:e==="userEvents"&&(s={method:"unsubscribe",subscription:{type:"userEvents",user:r}});s&&this.send(s);}subscribe(e,r,s){let n=`${e}:${r}`;return this.subscriptions.set(n,{type:e,param:r,callback:s}),this.sendSubscription(e,r),n}unsubscribe(e){let r=this.subscriptions.get(e);r&&(this.sendUnsubscription(r.type,r.param),this.subscriptions.delete(e));}isConnectedNow(){return this.isConnected}};var ot={testnet:{api:"https://api.hyperliquid-testnet.xyz",ws:"wss://api.hyperliquid-testnet.xyz/ws"},mainnet:{api:"https://api.hyperliquid.xyz",ws:"wss://api.hyperliquid.xyz/ws"}},ge=class{apiEndpoint;_wsEndpoint;timeout;environment;wsManager=null;constructor(e={}){this.environment=e.environment||"testnet",this.apiEndpoint=e.apiEndpoint||ot[this.environment].api,this._wsEndpoint=e.wsEndpoint||ot[this.environment].ws,this.timeout=e.timeout||3e4;}async request(e,r){let s=`${this.apiEndpoint}${e}`;try{let n=new AbortController,o=setTimeout(()=>n.abort(),this.timeout),i=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r),signal:n.signal});if(clearTimeout(o),!i.ok)throw new V(`HTTP ${i.status}: ${i.statusText}`,i.status,await i.text());return await i.json()}catch(n){throw n.name==="AbortError"?new V(`Request timeout after ${this.timeout}ms`,408,""):n instanceof V?n:new V(`Network error: ${n.message}`,0,"")}}symbolToCoin(e){return e.split("-")[0]}parseInterval(e){return {"1m":6e4,"5m":3e5,"15m":9e5,"30m":18e5,"1h":36e5,"4h":144e5,"1d":864e5,"1w":6048e5}[e]}async getSupportedCoins(){let[e]=await this.request("/info",{type:"metaAndAssetCtxs"});return e.universe.map(r=>`${r.name}-USDC`)}async getMarket(e){let r=await this.getMarkets([e]);return r.length>0?r[0]:null}async getMarkets(e){let[r,s]=await this.request("/info",{type:"metaAndAssetCtxs"}),n=r.universe.map((o,i)=>{let a=s[i],l=`${o.name}-USDC`,c=parseFloat(a.midPx||a.markPx||"0"),d=a.prevDayPx?parseFloat(a.prevDayPx):c,u=d>0?(c-d)/d*100:0;return {symbol:l,price:c,change24h:u,volume24h:parseFloat(a.dayNtlVlm||"0"),fundingRate:parseFloat(a.funding||"0"),openInterest:parseFloat(a.openInterest||"0"),markPrice:parseFloat(a.markPx||"0"),indexPrice:parseFloat(a.oraclePx||a.midPx||"0")}});if(e&&e.length>0){let o=new Set(e);return n.filter(i=>o.has(i.symbol))}return n}async getKlines(e,r,s=100){let n=this.symbolToCoin(e),o=this.parseInterval(r),i=Date.now(),a=i-o*s;return (await this.request("/info",{type:"candleSnapshot",req:{coin:n,interval:r,startTime:a,endTime:i}})).map(c=>({symbol:e,open:parseFloat(c.o),high:parseFloat(c.h),low:parseFloat(c.l),close:parseFloat(c.c),volume:parseFloat(c.v),timestamp:c.t,closeTimestamp:c.T}))}async getOrderBook(e,r=10){let s=this.symbolToCoin(e),n=await this.request("/info",{type:"l2Book",coin:s}),[o,i]=n.levels;return {symbol:e,bids:o.slice(0,r).map(a=>({price:parseFloat(a.px),quantity:parseFloat(a.sz),count:a.n})),asks:i.slice(0,r).map(a=>({price:parseFloat(a.px),quantity:parseFloat(a.sz),count:a.n})),timestamp:n.time}}async getRecentTrades(e,r=50){let s=this.symbolToCoin(e);return (await this.request("/info",{type:"recentTrades",coin:s})).slice(0,r).map(o=>({symbol:e,side:o.side==="B"?"buy":"sell",price:parseFloat(o.px),quantity:parseFloat(o.sz),timestamp:o.time,tradeId:o.tid}))}async placeOrder(e){throw new Error("placeOrder() requires wallet private key configuration for EIP-712 signature. Please configure authentication before calling this method. See: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint")}async cancelOrder(e){throw new Error("cancelOrder() requires wallet private key configuration for EIP-712 signature. Please configure authentication before calling this method. See: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint")}async getPositions(e={}){if(!e.userAddress)throw new Error("Hyperliquid requires userAddress parameter. Example: { userAddress: '0x...' }");let r=await this.request("/info",{type:"clearinghouseState",user:e.userAddress}),s=r.assetPositions.map(o=>{let i=o.position,a=`${i.coin}-USDC`,l=parseFloat(i.szi);if(l===0)return null;let c=parseFloat(i.entryPx),d=parseFloat(i.unrealizedPnl),u=parseFloat(i.positionValue);return {symbol:a,side:l>0?"long":"short",quantity:Math.abs(l),entryPrice:c,markPrice:c,unrealizedPnl:d,unrealizedPnlPercent:parseFloat(i.returnOnEquity)*100,leverage:i.leverage.value,liquidationPrice:i.liquidationPx?parseFloat(i.liquidationPx):void 0,margin:parseFloat(i.marginUsed),notionalValue:Math.abs(u)}}).filter(Boolean),n=e.symbol?s.filter(o=>o.symbol===e.symbol):s;return {positions:n,totalEquity:parseFloat(r.marginSummary.accountValue),availableBalance:parseFloat(r.marginSummary.accountValue)-parseFloat(r.marginSummary.totalMarginUsed),totalUnrealizedPnl:n.reduce((o,i)=>o+i.unrealizedPnl,0),raw:r}}async getOpenOrders(e={}){if(!e.userAddress)throw new Error("Hyperliquid requires userAddress parameter. Example: { userAddress: '0x...' }");let r=await this.request("/info",{type:"openOrders",user:e.userAddress}),s=r.map(o=>{let i=`${o.coin}-USDC`,a=parseFloat(o.origSz),l=parseFloat(o.sz),c=a-l;return {orderId:o.oid.toString(),clientOrderId:o.cloid,symbol:i,side:o.side?"long":"short",orderType:"limit",price:parseFloat(o.limitPx),quantity:a,filledQuantity:c,remainingQuantity:l,status:c>0&&l>0?"partially_filled":"pending",timestamp:o.timestamp,updateTimestamp:o.timestamp}}),n=e.symbol?s.filter(o=>o.symbol===e.symbol):s;return {orders:n,totalCount:n.length,raw:r}}async getTrades(e={}){if(!e.userAddress)throw new Error("Hyperliquid requires userAddress parameter. Example: { userAddress: '0x...' }");let r=await this.request("/info",{type:"userFills",user:e.userAddress}),s=r.map(n=>{let o=`${n.coin}-USDC`,i=n.dir.includes("Long");return {tradeId:n.tid.toString(),orderId:n.oid.toString(),symbol:o,side:i?"long":"short",price:parseFloat(n.px),quantity:parseFloat(n.sz),fee:parseFloat(n.fee||"0"),feeCurrency:n.feeToken||"USDC",isMaker:n.side==="M",timestamp:n.time}});return e.symbol&&(s=s.filter(n=>n.symbol===e.symbol)),e.startTime&&(s=s.filter(n=>n.timestamp>=e.startTime)),e.endTime&&(s=s.filter(n=>n.timestamp<=e.endTime)),e.limit&&(s=s.slice(0,e.limit)),{trades:s,totalCount:s.length,raw:r}}async connectWebSocket(){if(this.wsManager||(this.wsManager=new ae(this._wsEndpoint)),this.wsManager.isConnectedNow()){console.log("[WebSocket] Already connected");return}await this.wsManager.connect();}disconnectWebSocket(){this.wsManager&&(this.wsManager.disconnect(),this.wsManager=null);}subscribeMarketData(e,r,s){if(!this.wsManager)throw new Error("WebSocket not connected. Call connectWebSocket() first.");return this.wsManager.subscribe(e,r,s)}subscribeCandles(e,r,s){if(!this.wsManager)throw new Error("WebSocket not connected. Call connectWebSocket() first.");let n=`${e}:${r}`;return this.wsManager.subscribe("candle",n,s)}subscribeUserData(e,r,s){if(!this.wsManager)throw new Error("WebSocket not connected. Call connectWebSocket() first.");let n=e==="fills"?"userFills":"userEvents";return this.wsManager.subscribe(n,r,s)}unsubscribe(e){this.wsManager&&this.wsManager.unsubscribe(e);}},V=class extends Error{constructor(r,s,n){super(r);this.statusCode=s;this.responseBody=n;this.name="HyperliquidApiError";}};var re=createContext({});function Xt({client:t,children:e}){return jsx(re.Provider,{value:{client:t},children:e})}function P(){let t=useContext(re);if(!t||!t.client)throw new Error("usePerpetualsClient must be used within a PerpetualsProvider");return t}function it(){return ["perps","coins"]}async function at(t){return await t.getSupportedCoins()}function be(t={}){let{client:e}=P();return useQuery({queryKey:it(),queryFn:async()=>at(e),staleTime:300*1e3,...t})}function lt(t){return ["perps","market",t.symbol]}async function ct(t,{symbol:e}){return await t.getMarket(e)}function se(t,e={}){let{client:r}=P();return useQuery({queryKey:lt(t),queryFn:async()=>ct(r,t),staleTime:10*1e3,...e})}function dt(t={}){return ["perps","markets",JSON.stringify((t.symbols??[]).sort())]}async function ut(t,{symbols:e}={}){return await t.getMarkets(e)}function xe(t={},e={}){let{client:r}=P();return useQuery({queryKey:dt(t),queryFn:async()=>ut(r,t),staleTime:10*1e3,...e})}function pt(t){return ["perps","klines",t.symbol,t.interval,String(t.limit??100)]}async function mt(t,{symbol:e,interval:r,limit:s}){return await t.getKlines(e,r,s)}function or(t,e={}){let{client:r}=P();return useQuery({queryKey:pt(t),queryFn:async()=>mt(r,t),staleTime:30*1e3,...e})}function ft(t){return ["perps","orderBook",t.symbol,String(t.maxLevel??20)]}async function yt(t,{symbol:e,maxLevel:r}){return await t.getOrderBook(e,r)}function he(t,e={}){let{client:r}=P();return useQuery({queryKey:ft(t),queryFn:async()=>yt(r,t),staleTime:5*1e3,...e})}function gt(t){return ["perps","recentTrades",t.symbol,String(t.limit??50)]}async function bt(t,{symbol:e,limit:r}){return await t.getRecentTrades(e,r)}function Pe(t,e={}){let{client:r}=P();return useQuery({queryKey:gt(t),queryFn:async()=>bt(r,t),staleTime:5*1e3,...e})}function xt(t){return ["perps","positions",t.userAddress??"",t.symbol??""]}async function ht(t,e){return await t.getPositions(e)}function ve(t,e={}){let{client:r}=P(),{enabled:s=true,...n}=t;return useQuery({queryKey:xt(n),queryFn:async()=>ht(r,n),enabled:s&&!!n.userAddress,staleTime:10*1e3,...e})}function Pt(t){return ["perps","orders",t.userAddress??"",t.symbol??""]}async function vt(t,e){return await t.getOpenOrders(e)}function Se(t,e={}){let{client:r}=P(),{enabled:s=true,...n}=t;return useQuery({queryKey:Pt(n),queryFn:async()=>vt(r,n),enabled:s&&!!n.userAddress,staleTime:5*1e3,...e})}function St(t){return ["perps","trades",t.userAddress??"",t.symbol??"",String(t.limit??50),String(t.startTime??""),String(t.endTime??"")]}async function kt(t,e){return await t.getTrades(e)}function ke(t,e={}){let{client:r}=P(),{enabled:s=true,...n}=t;return useQuery({queryKey:St(n),queryFn:async()=>kt(r,n),enabled:s&&!!n.userAddress,staleTime:30*1e3,...e})}async function Ct(t,e){return await t.placeOrder(e)}function ne(t={}){let{client:e}=P();return useMutation({mutationFn:async r=>Ct(e,r),...t})}async function Nt(t,e){return await t.cancelOrder(e)}function Ce(t={}){let{client:e}=P();return useMutation({mutationFn:async r=>Nt(e,r),...t})}function _(t){let{type:e,symbol:r,enabled:s=true}=t,{client:n}=P(),[o,i]=useState(null),[a,l]=useState(false),[c,d]=useState(null),u=useCallback(f=>{i(f);},[]);return useEffect(()=>{if(!s)return;let f=null,p=true;return (async()=>{try{if(await n.connectWebSocket(),!p)return;l(!0),d(null),f=n.subscribeMarketData(e,r,u);}catch(y){p&&(d(y instanceof Error?y:new Error("Connection failed")),l(false));}})(),()=>{if(p=false,f)try{n.unsubscribe(f);}catch(y){console.error("Failed to unsubscribe:",y);}n.disconnectWebSocket(),l(false),i(null);}},[n,e,r,s,u]),{data:o,isConnected:a,error:c}}function br(t){let{symbol:e,interval:r,enabled:s=true}=t,{client:n}=P(),[o,i]=useState(null),[a,l]=useState(false),[c,d]=useState(null),u=useCallback(f=>{i(f);},[]);return useEffect(()=>{if(!s)return;let f=null,p=true;return (async()=>{try{if(await n.connectWebSocket(),!p)return;l(!0),d(null),f=n.subscribeCandles(e,r,u);}catch(y){p&&(d(y instanceof Error?y:new Error("Connection failed")),l(false));}})(),()=>{if(p=false,f)try{n.unsubscribe(f);}catch(y){console.error("Failed to unsubscribe:",y);}n.disconnectWebSocket(),l(false),i(null);}},[n,e,r,s,u]),{data:o,isConnected:a,error:c}}function oe(t){let{type:e,userAddress:r,enabled:s=true}=t,{client:n}=P(),[o,i]=useState(null),[a,l]=useState(false),[c,d]=useState(null),u=useCallback(f=>{i(f);},[]);return useEffect(()=>{if(!s||!r)return;let f=null,p=true;return (async()=>{try{if(await n.connectWebSocket(),!p)return;l(!0),d(null),f=n.subscribeUserData(e,r,u);}catch(y){p&&(d(y instanceof Error?y:new Error("Connection failed")),l(false));}})(),()=>{if(p=false,f)try{n.unsubscribe(f);}catch(y){console.error("Failed to unsubscribe:",y);}n.disconnectWebSocket(),l(false),i(null);}},[n,e,r,s,u]),{data:o,isConnected:a,error:c}}function Te(){return jsx("div",{className:"flex items-center justify-center px-4 py-3 bg-neutral-900 border-b border-neutral-800",children:jsx("span",{className:"text-neutral-400 text-sm",children:"Market data not available"})})}function Ue(){return jsxs("div",{className:"flex items-center gap-6 px-4 py-3 bg-neutral-900 border-b border-neutral-800",children:[jsxs("div",{className:"flex items-center gap-3",children:[jsx(Skeleton,{className:"h-6 w-20 rounded"}),jsxs("div",{className:"flex items-center gap-2",children:[jsx(Skeleton,{className:"h-8 w-28 rounded"}),jsx(Skeleton,{className:"h-5 w-16 rounded"})]})]}),jsx("div",{className:"h-8 w-px bg-neutral-800"}),jsxs("div",{className:"flex items-center gap-6 text-sm",children:[jsxs("div",{className:"flex flex-col gap-1",children:[jsx(Skeleton,{className:"h-3 w-20 rounded"}),jsx(Skeleton,{className:"h-5 w-16 rounded"})]}),jsxs("div",{className:"flex flex-col gap-1",children:[jsx(Skeleton,{className:"h-3 w-20 rounded"}),jsx(Skeleton,{className:"h-5 w-16 rounded"})]}),jsxs("div",{className:"flex flex-col gap-1",children:[jsx(Skeleton,{className:"h-3 w-24 rounded"}),jsx(Skeleton,{className:"h-5 w-16 rounded"})]}),jsxs("div",{className:"flex flex-col gap-1",children:[jsx(Skeleton,{className:"h-3 w-32 rounded"}),jsxs("div",{className:"flex items-center gap-2",children:[jsx(Skeleton,{className:"h-5 w-16 rounded"}),jsx(Skeleton,{className:"h-5 w-20 rounded"})]})]})]})]})}function Fe(t){let[e,r]=useState(),[s,n]=useState(0),{data:o,isPending:i}=se({symbol:t}),{data:a,isConnected:l}=_({type:"ticker",symbol:t,enabled:!!o});return useEffect(()=>{o&&r(o);},[o]),useEffect(()=>{if(!a)return;let c=Pr(a,t);c&&r(d=>vr(d??o??void 0,c,t));},[a,o,t]),useEffect(()=>{let c=()=>{let u=Date.now(),f=480*60*1e3,p=u%f,g=f-p;return Math.floor(g/1e3)};n(c());let d=setInterval(()=>{n(c());},1e3);return ()=>clearInterval(d)},[]),{marketData:e,isLoading:i,fundingCountdown:s}}function Pr(t,e){if(Array.isArray(t)){let r=t.find(s=>!s||typeof s!="object"?false:s.symbol===e);return r&&typeof r=="object"?r:null}return t&&typeof t=="object"?t:null}function j(t,e){return typeof t=="number"&&Number.isFinite(t)?t:e}function vr(t,e,r){return {symbol:e.symbol??t?.symbol??r,price:j(e.price,t?.price??0),change24h:j(e.change24h,t?.change24h??0),volume24h:j(e.volume24h,t?.volume24h??0),fundingRate:j(e.fundingRate,t?.fundingRate??0),openInterest:j(e.openInterest,t?.openInterest??0),markPrice:j(e.markPrice,t?.markPrice??0),indexPrice:typeof e.indexPrice=="number"&&Number.isFinite(e.indexPrice)?e.indexPrice:t?.indexPrice,high24h:typeof e.high24h=="number"&&Number.isFinite(e.high24h)?e.high24h:t?.high24h,low24h:typeof e.low24h=="number"&&Number.isFinite(e.low24h)?e.low24h:t?.low24h}}function Sr(t){let e=Math.floor(t/3600),r=Math.floor(t%3600/60),s=t%60;return `${String(e).padStart(2,"0")}:${String(r).padStart(2,"0")}:${String(s).padStart(2,"0")}`}function Tt(t,e=2){return typeof t!="number"||!Number.isFinite(t)?"-":t>=1e9?`$${(t/1e9).toFixed(e)}B`:t>=1e6?`$${(t/1e6).toFixed(e)}M`:t>=1e3?`$${(t/1e3).toFixed(e)}K`:`$${t.toFixed(e)}`}function Ut(t){return typeof t!="number"||!Number.isFinite(t)?"-":t>=1e3?t.toLocaleString("en-US",{minimumFractionDigits:0,maximumFractionDigits:0}):t>=1?t.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:4}):t.toFixed(6)}function Ie({marketData:t,fundingCountdown:e}){let{symbol:r,price:s,change24h:n,indexPrice:o,volume24h:i,openInterest:a,fundingRate:l}=t,c=typeof n=="number"&&Number.isFinite(n)?n:0,d=typeof l=="number"&&Number.isFinite(l)?l:0,u=c>=0,f=c.toFixed(2);return jsxs("div",{className:"flex items-center px-4",style:{minHeight:64,maxHeight:64,gap:16},children:[jsxs("div",{className:"flex items-baseline",style:{gap:8},children:[jsx("span",{style:{fontSize:18,fontWeight:500,lineHeight:"23px",letterSpacing:"-0.36px",color:"#fcfcfc"},children:Ut(s)}),jsxs("span",{style:{fontSize:12,fontWeight:400,lineHeight:"16px",color:u?"#2fe3ac":"#ec397a"},children:[u?"+":"",f,"%"]})]}),jsxs("div",{className:"flex items-center",style:{gap:16},children:[jsxs("div",{className:"flex flex-col",children:[jsx("span",{style:{fontSize:12,color:"#c8c9d1",lineHeight:"16px",letterSpacing:"-0.12px"},children:"Oracle Price"}),jsx("span",{style:{fontSize:13,fontWeight:400,lineHeight:"17px",color:"#fcfcfc"},children:o?Ut(o):"-"})]}),jsxs("div",{className:"flex flex-col",children:[jsx("span",{style:{fontSize:12,color:"#c8c9d1",lineHeight:"16px",letterSpacing:"-0.12px"},children:"24h Volume"}),jsx("span",{style:{fontSize:13,fontWeight:400,lineHeight:"17px",color:"#fcfcfc"},children:Tt(i,0)})]}),jsxs("div",{className:"flex flex-col",children:[jsx("span",{style:{fontSize:12,color:"#c8c9d1",lineHeight:"16px",letterSpacing:"-0.12px"},children:"Open Interest"}),jsx("span",{style:{fontSize:13,fontWeight:400,lineHeight:"17px",color:"#fcfcfc"},children:Tt(a*(t.markPrice||s))})]}),jsxs("div",{className:"flex flex-col",children:[jsx("span",{style:{fontSize:12,color:"#c8c9d1",lineHeight:"16px",letterSpacing:"-0.12px"},children:"Funding / Countdown"}),jsxs("div",{className:"flex items-center",style:{gap:8},children:[jsxs("span",{style:{fontSize:13,lineHeight:"17px",color:d>=0?"#2fe3ac":"#ec397a"},children:[(d*100).toFixed(5),"%"]}),jsx("span",{style:{fontSize:13,lineHeight:"17px",color:"#fcfcfc"},children:Sr(e)})]})]})]})]})}function kr({symbol:t}){let{marketData:e,isLoading:r,fundingCountdown:s}=Fe(t);return r?jsx(Ue,{}):e?jsx(Ie,{marketData:e,fundingCountdown:s}):jsx(Te,{})}function Re({onSelectCoin:t}={}){let[e,r]=useState(""),[s,n]=useState([]),{data:o,isPending:i}=be(),{data:a,isPending:l}=xe({symbols:o},{enabled:!!o&&o.length>0});useEffect(()=>{a&&n(a);},[a]);let c=useMemo(()=>{if(!e.trim())return s;let u=e.toLowerCase().trim();return s.filter(f=>f.symbol.toLowerCase().includes(u))},[s,e]);return {coins:s,isLoading:i||l,searchQuery:e,setSearchQuery:r,filteredCoins:c,handleSelectCoin:u=>{t?.(u);}}}function Ft(t,e=2){return t>=1e9?`$${(t/1e9).toFixed(e)}B`:t>=1e6?`$${(t/1e6).toFixed(e)}M`:t>=1e3?`$${(t/1e3).toFixed(e)}K`:`$${t.toFixed(e)}`}function Or(t){return t>=1e3?t.toFixed(2):t>=1?t.toFixed(4):t.toFixed(6)}function Ee({coins:t,searchQuery:e,onSearchChange:r,onSelectCoin:s,isLoading:n}){return jsxs("div",{className:"flex flex-col",style:{backgroundColor:"#18181a",flex:"1 1 0",minHeight:0},children:[jsx("div",{style:{padding:"16px 16px 12px"},children:jsxs("div",{className:"flex items-center",style:{height:32,border:"1px solid #323542",borderRadius:4,padding:"0 6px 0 12px",gap:8},children:[jsx(SearchIcon,{className:"flex-shrink-0",style:{width:14,height:14,color:"#777a8c"}}),jsx("input",{type:"text",placeholder:"Search coins...",value:e,onChange:o=>r(o.target.value),className:"flex-1 bg-transparent outline-none",style:{fontSize:12,color:"#fcfcfc",border:"none"}})]})}),jsxs("div",{className:"flex-1 overflow-auto",children:[jsxs("div",{className:"flex items-center",style:{height:28,padding:"0 16px",borderBottom:"1px solid rgba(50,53,66,0.5)",position:"sticky",top:0,backgroundColor:"#18181a",zIndex:1},children:[jsx("span",{style:{flex:"0 0 140px",fontSize:12,color:"#777a8c"},children:"Token"}),jsx("span",{style:{flex:"0 0 100px",fontSize:12,color:"#777a8c",textAlign:"right"},children:"Last Price"}),jsx("span",{style:{flex:"0 0 120px",fontSize:12,color:"#777a8c",textAlign:"right"},children:"24h Change"}),jsx("span",{style:{flex:"0 0 100px",fontSize:12,color:"#777a8c",textAlign:"right"},children:"8h Funding"}),jsx("span",{style:{flex:"0 0 100px",fontSize:12,color:"#777a8c",textAlign:"right"},children:"24h Volume"}),jsx("span",{style:{flex:"1",fontSize:12,color:"#777a8c",textAlign:"right"},children:"Open Interest"})]}),n?jsx("div",{className:"flex items-center justify-center",style:{height:100},children:jsx("span",{style:{fontSize:12,color:"#777a8c"},children:"Loading..."})}):t.length===0?jsx("div",{className:"flex items-center justify-center",style:{height:100},children:jsx("span",{style:{fontSize:12,color:"#777a8c"},children:e?"No coins found":"No coins available"})}):t.map(o=>{let i=o.change24h>=0,a=o.change24h.toFixed(2),l=(o.fundingRate*100).toFixed(4),c=o.fundingRate>=0,d=o.symbol.split("-")[0];return jsxs("div",{className:"flex items-center cursor-pointer transition-colors",style:{height:36,padding:"0 16px",borderBottom:"1px solid rgba(50,53,66,0.5)"},onClick:()=>s(o.symbol),onMouseEnter:u=>{u.currentTarget.style.backgroundColor="rgba(255,255,255,0.03)";},onMouseLeave:u=>{u.currentTarget.style.backgroundColor="transparent";},children:[jsxs("div",{className:"flex items-center",style:{flex:"0 0 140px",gap:8},children:[jsx("img",{src:`https://app.hyperliquid.xyz/coins/${d}.svg`,alt:d,className:"rounded-full",style:{width:20,height:20},onError:u=>{let f=u.target;f.style.display="none";}}),jsx("span",{style:{fontSize:12,fontWeight:500,color:"#fcfcfc"},children:d})]}),jsx("span",{style:{flex:"0 0 100px",fontSize:12,color:"#fcfcfc",textAlign:"right"},children:Or(o.price)}),jsxs("span",{style:{flex:"0 0 120px",fontSize:12,fontWeight:500,color:i?"#2fe3ac":"#ec397a",textAlign:"right"},children:[i?"+":"",a,"%"]}),jsxs("span",{style:{flex:"0 0 100px",fontSize:12,color:c?"#2fe3ac":"#ec397a",textAlign:"right"},children:[l,"%"]}),jsx("span",{style:{flex:"0 0 100px",fontSize:12,color:"#c8c9d1",textAlign:"right"},children:Ft(o.volume24h)}),jsx("span",{style:{flex:"1",fontSize:12,color:"#c8c9d1",textAlign:"right"},children:Ft(o.openInterest*o.price)})]},o.symbol)})]})]})}function Tr({onSelectCoin:t,className:e}){let{filteredCoins:r,isLoading:s,searchQuery:n,setSearchQuery:o,handleSelectCoin:i}=Re({onSelectCoin:t});return jsx("div",{className:e,style:{display:"flex",flexDirection:"column",flex:"1 1 0",minHeight:0,overflow:"hidden"},children:jsx(Ee,{coins:r,searchQuery:n,onSearchChange:o,onSelectCoin:i,isLoading:s})})}function Rt(t,e){if(e<=0)return t;let r=new Map;return t.forEach(s=>{let n=Math.floor(s.price/e)*e,o=r.get(n);o?(o.quantity+=s.quantity,s.count&&(o.count=(o.count||0)+s.count)):r.set(n,{price:n,quantity:s.quantity,count:s.count});}),Array.from(r.values())}function Et(t){let e=0,r=t.map(n=>{let o=n.quantity*n.price;return e+=o,{...n,quantity:o,total:e,percentage:0}}),s=e;return r.map(n=>({...n,percentage:s>0?n.total/s*100:0}))}function ze({symbol:t,maxLevel:e=20,precision:r=.01}){let[s,n]=useState(null),[o,i]=useState(r),{data:a,isPending:l}=he({symbol:t,maxLevel:e}),{data:c}=_({type:"orderBook",symbol:t,enabled:!!a});return useEffect(()=>{c?n(c):a&&n(a);},[c,a]),{...useMemo(()=>{if(!s)return {bids:[],asks:[],spread:0,spreadPercentage:0};let u=Rt(s.bids,o),f=Rt(s.asks,o),p=u.sort((H,R)=>R.price-H.price).slice(0,e),g=f.sort((H,R)=>H.price-R.price).slice(0,e),y=Et(p),N=Et(g),h=y[0]?.price||0,I=(N[0]?.price||0)-h,W=h>0?I/h*100:0;return {bids:y,asks:N,spread:I,spreadPercentage:W}},[s,o,e]),isLoading:l,precision:o,setPrecision:i}}function Fr(t){return t>=1e3?t.toLocaleString("en-US",{minimumFractionDigits:0,maximumFractionDigits:0}):t>=1?t.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:4}):t.toFixed(6)}function zt(t){return Math.round(t).toLocaleString("en-US")}function Qt({price:t,quantity:e,total:r,percentage:s,side:n,onClick:o}){let i=n==="ask";return jsxs("div",{className:"relative flex items-center cursor-pointer hover:bg-white/5 transition-colors",style:{height:22,minHeight:22,maxHeight:22,padding:"0 16px",gap:16,fontSize:11},onClick:o,children:[jsx("div",{className:"absolute left-0 top-0",style:{height:20,width:`${s}%`,background:i?"linear-gradient(to right, rgba(209,57,236,0), rgb(236,57,122))":"linear-gradient(to right, rgba(47,194,227,0), rgb(47,227,172))",opacity:.15}}),jsx("div",{className:"relative z-10 flex items-center",style:{flex:"1 1 0%"},children:jsx("span",{style:{color:i?"#ec397a":"#2fe3ac",fontWeight:400},children:Fr(t)})}),jsx("div",{className:"relative z-10 flex items-center justify-end",style:{flex:"1 1 0%",color:"#fcfcfc"},children:zt(e)}),jsx("div",{className:"relative z-10 flex items-center justify-end",style:{flex:"1 1 0%",color:"#fcfcfc"},children:zt(r)})]})}function Qe({bids:t,asks:e,spread:r,spreadPercentage:s,onPriceClick:n}){let o=[...e].reverse();return jsxs("div",{className:"flex flex-col h-full",style:{backgroundColor:"#06070b",fontSize:11},children:[jsxs("div",{className:"flex items-center",style:{height:28,minHeight:28,padding:"0 16px",gap:16,color:"#777a8c",fontSize:11},children:[jsx("div",{className:"flex items-center",style:{flex:"1 1 0%"},children:"Price"}),jsx("div",{className:"flex items-center justify-end",style:{flex:"1 1 0%"},children:"Amount (USD)"}),jsx("div",{className:"flex items-center justify-end",style:{flex:"1 1 0%"},children:"Total (USD)"})]}),jsx("div",{className:"flex-1 flex flex-col-reverse overflow-hidden",children:o.map((i,a)=>jsx(Qt,{price:i.price,quantity:i.quantity,total:i.total,percentage:i.percentage,side:"ask",onClick:()=>n?.(i.price)},`ask-${i.price}-${a}`))}),jsx("div",{className:"flex items-center justify-center",style:{height:24,minHeight:24,padding:"0 16px",backgroundColor:"rgba(34,36,45,0.5)"},children:jsxs("div",{className:"flex items-center",style:{gap:12,fontSize:12,color:"#fcfcfc"},children:[jsx("span",{style:{color:"#fcfcfc"},children:"Spread:"}),jsx("button",{type:"button",className:"hover:text-white transition-colors cursor-pointer",style:{color:"#fcfcfc",fontWeight:400,background:"none",border:"none",padding:0},onClick:()=>n?.(r),children:r>=1?Math.round(r).toLocaleString("en-US"):r.toFixed(4)}),jsxs("span",{style:{color:"#fcfcfc",fontWeight:500},children:[s.toFixed(3),"%"]})]})}),jsx("div",{className:"flex-1 overflow-hidden",children:t.map((i,a)=>jsx(Qt,{price:i.price,quantity:i.quantity,total:i.total,percentage:i.percentage,side:"bid",onClick:()=>n?.(i.price)},`bid-${i.price}-${a}`))})]})}function Ir(){return jsxs("div",{className:"flex flex-col h-full",style:{padding:"0 16px"},children:[jsxs("div",{className:"flex justify-between items-center",style:{height:28,marginBottom:4},children:[jsx(Skeleton,{className:"h-3 w-12 rounded"}),jsx(Skeleton,{className:"h-3 w-14 rounded"}),jsx(Skeleton,{className:"h-3 w-14 rounded"})]}),Array.from({length:10}).map((t,e)=>jsxs("div",{className:"flex justify-between items-center",style:{height:22},children:[jsx(Skeleton,{className:"h-3 w-14 rounded"}),jsx(Skeleton,{className:"h-3 w-14 rounded"}),jsx(Skeleton,{className:"h-3 w-14 rounded"})]},`ask-skeleton-${e}`)),jsx("div",{className:"flex justify-center items-center",style:{height:28},children:jsx(Skeleton,{className:"h-4 w-32 rounded"})}),Array.from({length:10}).map((t,e)=>jsxs("div",{className:"flex justify-between items-center",style:{height:22},children:[jsx(Skeleton,{className:"h-3 w-14 rounded"}),jsx(Skeleton,{className:"h-3 w-14 rounded"}),jsx(Skeleton,{className:"h-3 w-14 rounded"})]},`bid-skeleton-${e}`))]})}function Dr(){return jsx("div",{className:"flex items-center justify-center h-full",children:jsx("span",{className:"text-neutral-400 text-sm",children:"No order book data available"})})}function Rr({symbol:t,maxLevel:e=20,onPriceClick:r,className:s}){let{bids:n,asks:o,spread:i,spreadPercentage:a,isLoading:l}=ze({symbol:t,maxLevel:e});return l?jsx(Ir,{}):n.length===0&&o.length===0?jsx(Dr,{}):jsx("div",{className:s,children:jsx(Qe,{bids:n,asks:o,spread:i,spreadPercentage:a,onPriceClick:r})})}function qe({symbol:t,limit:e=50}){let[r,s]=useState([]),{data:n,isPending:o}=Pe({symbol:t,limit:e}),{data:i}=_({type:"trades",symbol:t,enabled:!!n});return useEffect(()=>{n&&s(n.filter(Bt));},[n]),useEffect(()=>{i&&s(a=>{let l=zr(i);if(l.length===0)return a;let c=l.filter(u=>!a.some(f=>f.timestamp===u.timestamp&&f.price===u.price&&f.quantity===u.quantity));return c.length===0?a:[...c,...a].slice(0,e)});},[i,e]),{trades:r,isLoading:o}}function zr(t){return (Array.isArray(t)?t:[t]).filter(Bt)}function Bt(t){return t?typeof t.symbol=="string"&&(t.side==="buy"||t.side==="sell")&&typeof t.price=="number"&&Number.isFinite(t.price)&&typeof t.quantity=="number"&&Number.isFinite(t.quantity)&&typeof t.timestamp=="number"&&Number.isFinite(t.timestamp):false}function Qr(t){return typeof t!="number"||!Number.isFinite(t)?"-":t>=1e3?t.toFixed(2):t>=1?t.toFixed(4):t.toFixed(6)}function Lt(t){return typeof t!="number"||!Number.isFinite(t)?"-":t>=1e6?(t/1e6).toFixed(2)+"M":t>=1e3?(t/1e3).toFixed(2)+"K":t.toFixed(2)}function qr(t){if(typeof t!="number"||!Number.isFinite(t))return "-";let e=new Date(t),r=String(e.getHours()).padStart(2,"0"),s=String(e.getMinutes()).padStart(2,"0"),n=String(e.getSeconds()).padStart(2,"0");return `${r}:${s}:${n}`}function Le({trades:t,onTradeClick:e}){return jsxs("div",{className:"flex flex-col h-full overflow-auto",style:{backgroundColor:"#06070b",fontSize:11},children:[jsxs("div",{className:"sticky top-0 z-10 flex items-center",style:{height:28,minHeight:28,padding:"0 16px",gap:16,color:"#777a8c",fontSize:11},children:[jsx("div",{className:"flex-1",style:{maxWidth:100},children:"Price"}),jsx("div",{className:"flex-1 text-right",children:"Amount"}),jsx("div",{className:"flex-1 text-right",style:{maxWidth:100},children:"Total"}),jsx("div",{className:"flex-1 text-right",style:{maxWidth:70},children:"Time"})]}),jsx("div",{className:"flex-1",children:t.map((r,s)=>{let n=r.side==="buy",o=typeof r.price=="number"&&Number.isFinite(r.price)&&typeof r.quantity=="number"&&Number.isFinite(r.quantity)?r.price*r.quantity:void 0;return jsxs("div",{className:"flex items-center cursor-pointer hover:bg-white/5 transition-colors",style:{height:22,minHeight:22,maxHeight:22,padding:"0 16px",gap:16,fontSize:11},onClick:()=>e?.(r),children:[jsx("div",{className:"flex-1",style:{maxWidth:100},children:jsx("span",{style:{color:n?"#2fe3ac":"#ec397a",fontWeight:400},children:Qr(r.price)})}),jsx("div",{className:"flex-1 text-right",style:{color:"#fcfcfc"},children:Lt(r.quantity)}),jsx("div",{className:"flex-1 text-right",style:{maxWidth:100,color:"#fcfcfc"},children:Lt(o)}),jsx("div",{className:"flex-1 text-right",style:{maxWidth:70,color:"#c8c9d1"},children:qr(r.timestamp)})]},`${r.timestamp}-${r.price}-${s}`)})})]})}function Br(){return jsxs("div",{className:"flex flex-col h-full",style:{padding:"0 16px"},children:[jsxs("div",{className:"flex justify-between items-center",style:{height:28,marginBottom:4},children:[jsx(Skeleton,{className:"h-3 w-12 rounded"}),jsx(Skeleton,{className:"h-3 w-10 rounded"}),jsx(Skeleton,{className:"h-3 w-10 rounded"}),jsx(Skeleton,{className:"h-3 w-12 rounded"})]}),Array.from({length:12}).map((t,e)=>jsxs("div",{className:"flex justify-between items-center",style:{height:22},children:[jsx(Skeleton,{className:"h-3 w-14 rounded"}),jsx(Skeleton,{className:"h-3 w-10 rounded"}),jsx(Skeleton,{className:"h-3 w-10 rounded"}),jsx(Skeleton,{className:"h-3 w-12 rounded"})]},`trade-skeleton-${e}`))]})}function Lr(){return jsx("div",{className:"flex items-center justify-center h-full",children:jsx("span",{className:"text-neutral-400 text-sm",children:"No recent trades"})})}function Ar({symbol:t,limit:e=50,onTradeClick:r,className:s}){let{trades:n,isLoading:o}=qe({symbol:t,limit:e});return o?jsx(Br,{}):n.length===0?jsx(Lr,{}):jsx("div",{className:s,children:jsx(Le,{trades:n,onTradeClick:r})})}function We({symbol:t,userAddress:e,maxLeverage:r=150,onSuccess:s,onError:n}){let[o,i]=useState("long"),[a,l]=useState("market"),c=useForm({defaultValues:{amount:0,leverage:20,takeProfitPrice:void 0,takeProfitPercent:void 0,stopLossPrice:void 0,stopLossPercent:void 0}}),{data:d}=se({symbol:t}),{mutateAsync:u,isPending:f}=ne({onSuccess:()=>{c.reset(),s?.();},onError:k=>{n?.(k);}}),p=c.watch(),{amount:g,leverage:y,price:N}=p,h=useMemo(()=>a==="limit"&&N?N:d?.price||0,[a,N,d?.price]),B=useMemo(()=>!g||!h?0:g*h*5e-4,[g,h]),I=useMemo(()=>!g||!h?0:g*h+B,[g,h,B]),W=useMemo(()=>{if(!g||!h||!y||y===1)return;let k=.005,G=h;return o==="long"?G*(1-(1/y-k)):G*(1+(1/y-k))},[g,h,y,o]),H=1e4,R=1e4,me=0,C=useCallback(async k=>{if(!e)throw new Error("User address is required");let G=a==="limit"?k.price:void 0,fe=k.takeProfitPrice,ye=k.stopLossPrice;if(!fe&&k.takeProfitPercent&&k.takeProfitPercent>0&&h){let te=k.takeProfitPercent/100;fe=o==="long"?h*(1+te):h*(1-te);}if(!ye&&k.stopLossPercent&&k.stopLossPercent>0&&h){let te=k.stopLossPercent/100;ye=o==="long"?h*(1-te):h*(1+te);}await u({symbol:t,side:o,orderType:a,amount:k.amount,price:G,leverage:k.leverage,takeProfitPrice:fe,stopLossPrice:ye,userAddress:e});},[t,o,a,h,e,u]);return {form:c,side:o,orderType:a,setSide:i,setOrderType:l,handleSubmit:C,isSubmitting:f,currentPrice:h,estimatedFee:B,estimatedTotal:I,liquidationPrice:W,availableMargin:H,accountValue:R,currentPosition:me,maxLeverage:r}}function de(t,e=2){return t.toFixed(e)}function _r({leverage:t,maxLeverage:e,onLeverageChange:r,onClose:s}){let n=[1,2,3,5,10,20,25,50,100].filter(o=>o<=e);return jsxs("div",{className:"fixed inset-0 z-50 flex items-center justify-center",children:[jsx("div",{className:"absolute inset-0 bg-black/60",onClick:s,onKeyDown:o=>o.key==="Escape"&&s(),role:"button",tabIndex:-1,"aria-label":"Close"}),jsxs("div",{className:"relative z-10 w-72 bg-neutral-900 border border-neutral-700 rounded-lg p-4 shadow-2xl",children:[jsxs("div",{className:"flex items-center justify-between mb-4",children:[jsx("h3",{className:"text-sm font-medium text-white",children:"Adjust Leverage"}),jsx("button",{type:"button",onClick:s,className:"text-neutral-400 hover:text-white",children:jsx("svg",{className:"w-4 h-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"})})})]}),jsxs("div",{className:"text-center text-2xl font-bold text-white mb-4",children:[t,"x"]}),jsx(Slider,{value:[t],onChange:o=>r(Array.isArray(o)?o[0]:o),minValue:1,maxValue:e,step:1,className:"w-full mb-3"}),jsx("div",{className:"flex flex-wrap gap-1.5",children:n.map(o=>jsxs("button",{type:"button",className:cn("px-2.5 py-1 text-xs rounded transition-colors",t===o?"bg-green-600 text-white":"bg-neutral-800 text-neutral-400 hover:bg-neutral-700"),onClick:()=>r(o),children:[o,"x"]},o))}),jsx("button",{type:"button",className:"w-full mt-4 text-white h-9 rounded cursor-pointer transition-colors",style:{backgroundColor:"#16a34a"},onClick:s,children:"Confirm"})]})]})}function He({methods:t,side:e,orderType:r,onSideChange:s,onOrderTypeChange:n,onSubmit:o,isSubmitting:i,symbol:a,currentPrice:l,estimatedFee:c,liquidationPrice:d,availableMargin:u,accountValue:f,currentPosition:p,maxLeverage:g}){let[y,N]=useState(false),[h,B]=useState(false),I=t.watch("leverage")||20,W=t.watch("amount")||0,H=a.split("-")[0],R=u>0&&l?Math.min(W*l/(u*I)*100,100):0,me=C=>{let k=(Array.isArray(C)?C[0]:C)/100;if(l&&l>0){let G=u*I*k/l;t.setValue("amount",Number(G.toFixed(6)));}};return jsxs("div",{className:"flex flex-col h-full",style:{backgroundColor:"#06070b"},children:[jsxs("div",{className:"perp-order-form flex-1 overflow-y-auto",style:{padding:"16px 16px",display:"flex",flexDirection:"column",gap:16},children:[jsxs("div",{className:"flex",style:{border:"1px solid rgba(34,36,45,0.5)",borderRadius:8,padding:4,gap:4},children:[jsx("button",{type:"button",className:"flex-1 cursor-pointer transition-colors",style:{height:32,fontSize:16,borderRadius:4,backgroundColor:e==="long"?"#2fe3ac":"transparent",color:e==="long"?"#090909":"#c8c9d1",fontWeight:e==="long"?700:500},onClick:()=>s("long"),children:"Long"}),jsx("button",{type:"button",className:"flex-1 cursor-pointer transition-colors",style:{height:32,fontSize:16,borderRadius:4,backgroundColor:e==="short"?"#ec397a":"transparent",color:e==="short"?"#090909":"#c8c9d1",fontWeight:e==="short"?700:500},onClick:()=>s("short"),children:"Short"})]}),jsxs("div",{className:"flex items-center",style:{gap:8},children:[jsx("div",{className:"flex",children:[{key:"market",label:"Market"},{key:"limit",label:"Limit"}].map(C=>jsx("div",{style:{height:32,display:"flex",alignItems:"center",borderBottom:r===C.key?"2px solid #fcfcfc":"2px solid transparent",padding:"2px 0 0",cursor:"pointer"},children:jsx("button",{type:"button",className:"cursor-pointer transition-colors",style:{padding:"0 8px",fontSize:12,fontWeight:500,backgroundColor:"transparent",color:r===C.key?"#fcfcfc":"#c8c9d1",border:"none"},onClick:()=>n(C.key),children:C.label})},C.key))}),jsx("div",{className:"flex-1"}),jsxs("button",{type:"button",className:"cursor-pointer transition-colors",style:{height:24,padding:"0 5px",fontSize:12,borderRadius:4,backgroundColor:"rgba(34,36,45,0.5)",color:"#fcfcfc",fontWeight:400,border:"1px solid rgba(34,36,45,0.5)"},onClick:()=>N(true),children:["Leverage: ",I,"x"]})]}),jsx(RHForm,{methods:t,onSubmit:o,children:jsxs("div",{className:"space-y-3 w-full",children:[r==="limit"&&jsxs("div",{className:"perp-price-box",style:{borderRadius:4,padding:8,backgroundColor:"rgba(34,36,45,0.5)",border:"1px solid rgb(34,36,45)",height:64,display:"flex",flexDirection:"column",justifyContent:"center"},children:[jsxs("div",{className:"flex justify-between items-center",children:[jsx("span",{style:{fontSize:12,color:"#777a8c"},children:"Price"}),jsx("span",{style:{fontSize:12,color:"#777a8c"},children:"USDC"})]}),jsx(RHNumberInput,{name:"price",placeholder:"0.0 USDC",className:"w-full"})]}),jsxs("div",{className:"perp-buy-amt",style:{borderRadius:4,padding:8,backgroundColor:"rgba(34,36,45,0.5)",border:"1px solid rgb(34,36,45)",height:64,display:"flex",flexDirection:"column",justifyContent:"center"},children:[jsxs("div",{className:"flex justify-between items-center",children:[jsx("span",{style:{fontSize:12,color:"#777a8c"},children:"Buy Amount"}),jsx("span",{style:{fontSize:12,color:"#777a8c"},children:H})]}),jsx(RHNumberInput,{name:"amount",placeholder:"0.0 USDC",className:"w-full"})]}),jsxs("div",{children:[jsx("style",{children:`
|
|
2
2
|
.perp-buy-amt input, .perp-price-box input { font-size: 18px !important; line-height: 23px !important; }
|
|
3
3
|
.perp-order-form .group,
|
|
4
4
|
.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; }
|