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 ConnectedTakers, { TakerId } from "./components/ConnectedTakers"; import CurrencyInputField from "./components/CurrencyInputField"; import CurrentPrice from "./components/CurrentPrice"; import createErrorToast from "./components/ErrorToast"; 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 takersOrUndefined = useLatestEvent(source, "takers"); let takers = takersOrUndefined || []; const toast = useToast(); let [minQuantity, setMinQuantity] = useState("100"); let [maxQuantity, setMaxQuantity] = useState("1000"); 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) { createErrorToast(toast, e); } }, }); 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(/^\$/, ""); }