import { Box, Button, Container, Divider, Grid, GridItem, HStack, Switch, Tab, TabList, TabPanel, TabPanels, Tabs, Text, useToast, VStack, } from "@chakra-ui/react"; import React, { useEffect, useState } from "react"; import { useAsync } from "react-async"; import { useEventSource } from "react-sse-hooks"; import { CfdTable } from "./components/cfdtables/CfdTable"; import CurrencyInputField from "./components/CurrencyInputField"; import CurrentPrice from "./components/CurrentPrice"; import useLatestEvent from "./components/Hooks"; import OrderTile from "./components/OrderTile"; import { Cfd, intoCfd, intoOrder, Order, PriceInfo, StateGroupKey, WalletInfo } from "./components/Types"; import Wallet from "./components/Wallet"; import { CfdSellOrderPayload, postCfdSellOrderRequest } from "./MakerClient"; const SPREAD = 1.01; export default function App() { document.title = "Hermes Maker"; let source = useEventSource({ source: "/api/feed", options: { withCredentials: true } }); const cfdsOrUndefined = useLatestEvent(source, "cfds", intoCfd); let cfds = cfdsOrUndefined ? cfdsOrUndefined! : []; const order = useLatestEvent(source, "order", intoOrder); const walletInfo = useLatestEvent(source, "wallet"); const priceInfo = useLatestEvent(source, "quote"); const toast = useToast(); let [minQuantity, setMinQuantity] = useState("10"); let [maxQuantity, setMaxQuantity] = useState("100"); let [orderPrice, setOrderPrice] = useState("0"); let [autoRefresh, setAutoRefresh] = useState(true); useEffect(() => { if (autoRefresh && priceInfo) { setOrderPrice((priceInfo.ask * SPREAD).toFixed(2).toString()); } }, [priceInfo, autoRefresh]); let { run: makeNewCfdSellOrder, isLoading: isCreatingNewCfdOrder } = useAsync({ deferFn: async ([payload]: any[]) => { try { await postCfdSellOrderRequest(payload as CfdSellOrderPayload); } catch (e) { const description = typeof e === "string" ? e : JSON.stringify(e); toast({ title: "Error", description, status: "error", duration: 9000, isClosable: true, }); } }, }); const pendingOrders = cfds.filter((value) => value.state.getGroup() === StateGroupKey.PENDING_ORDER); const pendingSettlements = cfds.filter((value) => value.state.getGroup() === StateGroupKey.PENDING_SETTLEMENT); const pendingRollOvers = cfds.filter((value) => value.state.getGroup() === StateGroupKey.PENDING_ROLL_OVER); const opening = cfds.filter((value) => value.state.getGroup() === StateGroupKey.OPENING); const open = cfds.filter((value) => value.state.getGroup() === StateGroupKey.OPEN); const closed = cfds.filter((value) => value.state.getGroup() === StateGroupKey.CLOSED); return ( Reference Price: Min Quantity: setMinQuantity(parse(valueString))} value={format(minQuantity)} /> Max Quantity: setMaxQuantity(parse(valueString))} value={format(maxQuantity)} /> Offer Price: { setOrderPrice(parse(valueString)); setAutoRefresh(false); }} value={format(orderPrice)} /> setAutoRefresh(!autoRefresh)} /> Auto-refresh Leverage: {order && } Open [{open.length}] Pending Orders [{pendingOrders.length}] Pending Settlements [{pendingSettlements.length}] Pending Roll Overs [{pendingRollOvers.length}] Opening [{opening.length}] Closed [{closed.length}] ); } function format(val: any) { return `$` + val; } function parse(val: any) { return val.replace(/^\$/, ""); }