diff --git a/taker-frontend/package.json b/taker-frontend/package.json index 675117c..0853e84 100644 --- a/taker-frontend/package.json +++ b/taker-frontend/package.json @@ -13,8 +13,6 @@ "@chakra-ui/react": "^1.6.10", "@emotion/react": "^11", "@emotion/styled": "^11", - "react": "^17.0.2", - "react-dom": "^17.0.2", "@testing-library/jest-dom": "^5.9.0", "@testing-library/react": "^10.2.1", "@testing-library/user-event": "^12.0.2", @@ -23,17 +21,20 @@ "@types/react": "^17.0.34", "@types/react-dom": "^17.0.11", "@types/react-router-dom": "5.3.1", + "@vitejs/plugin-react": "^1.0.0", "framer-motion": "^4", + "react": "^17.0.2", "react-async": "^10.0.1", + "react-dom": "^17.0.2", "react-icons": "^3.0.0", "react-refresh": "^0.10.0", "react-router-dom": "5.3.0", "react-scripts": "4.0.3", "react-sse-hooks": "^1.0.5", - "web-vitals": "^0.2.2", - "@vitejs/plugin-react": "^1.0.0", + "react-use-websocket": "^2.9.1", "typescript": "^4.4.4", - "vite": "^2.6.13" + "vite": "^2.6.13", + "web-vitals": "^0.2.2" }, "devDependencies": { "@types/eslint": "^7", diff --git a/taker-frontend/src/App.tsx b/taker-frontend/src/App.tsx index 394f648..72789a3 100644 --- a/taker-frontend/src/App.tsx +++ b/taker-frontend/src/App.tsx @@ -4,10 +4,12 @@ import { useEffect, useState } from "react"; import { useAsync } from "react-async"; import { Route, Switch } from "react-router-dom"; import { useEventSource } from "react-sse-hooks"; +import useWebSocket from "react-use-websocket"; import History from "./components/History"; import Nav from "./components/NavBar"; import Trade from "./components/Trade"; import { + BXBTData, Cfd, CfdOrderRequestPayload, intoCfd, @@ -42,6 +44,22 @@ async function postCfdOrderRequest(payload: CfdOrderRequestPayload) { export const App = () => { const toast = useToast(); + const { + lastMessage, + readyState, + } = useWebSocket("wss://www.bitmex.com/realtime?subscribe=instrument:.BXBT", { + // Will attempt to reconnect on all close events, such as server shutting down + shouldReconnect: () => true, + }); + + let referencePrice; + if (readyState === 1 && lastMessage) { + const data: BXBTData[] = JSON.parse(lastMessage.data).data; + if (data && data[0]?.markPrice) { + referencePrice = data[0].markPrice; + } + } + let source = useEventSource({ source: "/api/feed" }); const walletInfo = useLatestEvent(source, "wallet"); const order = useLatestEvent(source, "order", intoOrder); @@ -53,7 +71,7 @@ export const App = () => { let [margin, setMargin] = useState("0"); let [userHasEdited, setUserHasEdited] = useState(false); - const { price, min_quantity, max_quantity, leverage, liquidation_price: liquidationPrice } = order || {}; + const { price: askPrice, min_quantity, max_quantity, leverage, liquidation_price: liquidationPrice } = order || {}; let effectiveQuantity = userHasEdited ? quantity : (min_quantity?.toString() || "0"); @@ -130,7 +148,8 @@ export const App = () => { quantity={format(effectiveQuantity)} max_quantity={max_quantity || 0} min_quantity={min_quantity || 0} - price={price} + referencePrice={referencePrice} + askPrice={askPrice} margin={margin} leverage={leverage} liquidationPrice={liquidationPrice} diff --git a/taker-frontend/src/components/Trade.tsx b/taker-frontend/src/components/Trade.tsx index 75ed2b4..9293d56 100644 --- a/taker-frontend/src/components/Trade.tsx +++ b/taker-frontend/src/components/Trade.tsx @@ -49,7 +49,8 @@ interface TradeProps { order_id?: string; min_quantity: number; max_quantity: number; - price?: number; + referencePrice?: number; + askPrice?: number; margin?: string; leverage?: number; quantity: string; @@ -63,7 +64,8 @@ const Trade = ( { min_quantity, max_quantity, - price: priceAsNumber, + referencePrice: referencePriceAsNumber, + askPrice: askPriceAsNumber, quantity, onQuantityChange, margin: marginAsNumber, @@ -76,7 +78,8 @@ const Trade = ( let outerCircleBg = useColorModeValue("gray.100", "gray.700"); let innerCircleBg = useColorModeValue("gray.200", "gray.600"); - const price = `$${priceAsNumber?.toLocaleString() || "0.0"}`; + const referencePrice = `$${referencePriceAsNumber?.toLocaleString() || "0.0"}`; + const askPrice = `$${askPriceAsNumber?.toLocaleString() || "0.0"}`; const liquidationPrice = `$${liquidationPriceAsNumber?.toLocaleString() || "0.0"}`; const margin = `₿${marginAsNumber?.toLocaleString() || "0.0"}`; @@ -122,8 +125,8 @@ const Trade = ( - - {price} + 0}> + {referencePrice} @@ -149,13 +152,13 @@ const Trade = ( @@ -163,7 +166,7 @@ const Trade = ( - Market buy {quantity} of BTC/USD @ {price} + Market buy {quantity} of BTC/USD @ {askPrice} diff --git a/taker-frontend/src/components/Types.tsx b/taker-frontend/src/components/Types.tsx index 47d46c0..66d01d6 100644 --- a/taker-frontend/src/components/Types.tsx +++ b/taker-frontend/src/components/Types.tsx @@ -265,3 +265,9 @@ export function intoCfd(key: string, value: any): any { return value; } } + +export interface BXBTData { + symbol: string; + markPrice: number; + timestamp: string; +} diff --git a/taker-frontend/yarn.lock b/taker-frontend/yarn.lock index b4d878f..624a565 100644 --- a/taker-frontend/yarn.lock +++ b/taker-frontend/yarn.lock @@ -10411,6 +10411,11 @@ react-style-singleton@^2.1.0: invariant "^2.2.4" tslib "^1.0.0" +react-use-websocket@^2.9.1: + version "2.9.1" + resolved "https://registry.yarnpkg.com/react-use-websocket/-/react-use-websocket-2.9.1.tgz#ef4a73a618b24f2a5875829ac0a0a0573c524710" + integrity sha512-jV6OxXuxWi6BiPVlbAJd/uWNaoQwkeGARFO9f6HidJeWUatB4J2UopbxI/fduiGpcpHGhRAmpLdfVjeRzrcTnQ== + react@^17.0.2: version "17.0.2" resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"