diff --git a/src/@demex-info/assets/tokens/AAVE.svg b/src/@demex-info/assets/tokens/AAVE.svg index 5377c3cb..a5cb956a 100644 --- a/src/@demex-info/assets/tokens/AAVE.svg +++ b/src/@demex-info/assets/tokens/AAVE.svg @@ -1,8 +1,8 @@ - + - + diff --git a/src/@demex-info/assets/tokens/HUNY.svg b/src/@demex-info/assets/tokens/HUNY.svg new file mode 100644 index 00000000..b6b39d82 --- /dev/null +++ b/src/@demex-info/assets/tokens/HUNY.svg @@ -0,0 +1,696 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/@demex-info/assets/tokens/JUNO.svg b/src/@demex-info/assets/tokens/JUNO.svg new file mode 100644 index 00000000..d65fb3da --- /dev/null +++ b/src/@demex-info/assets/tokens/JUNO.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/@demex-info/assets/tokens/LKT.svg b/src/@demex-info/assets/tokens/LKT.svg index fbde94fb..f224ae0f 100644 --- a/src/@demex-info/assets/tokens/LKT.svg +++ b/src/@demex-info/assets/tokens/LKT.svg @@ -1,14 +1,14 @@ - + - + - + - + diff --git a/src/@demex-info/assets/tokens/MKR.svg b/src/@demex-info/assets/tokens/MKR.svg index 4da19ce1..9a639d13 100644 --- a/src/@demex-info/assets/tokens/MKR.svg +++ b/src/@demex-info/assets/tokens/MKR.svg @@ -1,8 +1,8 @@ - + - + diff --git a/src/@demex-info/assets/tokens/SAND.svg b/src/@demex-info/assets/tokens/SAND.svg index 5184580b..4e01196b 100644 --- a/src/@demex-info/assets/tokens/SAND.svg +++ b/src/@demex-info/assets/tokens/SAND.svg @@ -1,8 +1,8 @@ - + - + diff --git a/src/@demex-info/assets/tokens/index.ts b/src/@demex-info/assets/tokens/index.ts index 410dfbe0..a53a2df4 100644 --- a/src/@demex-info/assets/tokens/index.ts +++ b/src/@demex-info/assets/tokens/index.ts @@ -79,6 +79,7 @@ export { ReactComponent as HELMET } from "./HELMET.svg"; export { ReactComponent as HNT } from "./HNT.svg"; export { ReactComponent as HOT } from "./HOT.svg"; export { ReactComponent as HT } from "./HT.svg"; +export { ReactComponent as HUNY } from "./HUNY.svg"; export { ReactComponent as HUSD } from "./HUSD.svg"; export { ReactComponent as ICP } from "./ICP.svg"; export { ReactComponent as ICX } from "./ICX.svg"; @@ -86,6 +87,7 @@ export { ReactComponent as INJ } from "./INJ.svg"; export { ReactComponent as IOST } from "./IOST.svg"; export { ReactComponent as IOTX } from "./IOTX.svg"; export { ReactComponent as iUSD } from "./iUSD.svg"; +export { ReactComponent as JUNO } from "./JUNO.svg"; export { ReactComponent as KCS } from "./KCS.svg"; export { ReactComponent as KLAY } from "./KLAY.svg"; export { ReactComponent as KMD } from "./KMD.svg"; diff --git a/src/@demex-info/utils/markets.ts b/src/@demex-info/utils/markets.ts index 436f237e..ce9c4112 100644 --- a/src/@demex-info/utils/markets.ts +++ b/src/@demex-info/utils/markets.ts @@ -1,6 +1,7 @@ import { DEC_SHIFT } from "@demex-info/constants"; import BigNumber from "bignumber.js"; import { CarbonSDK, Models } from "carbon-js-sdk"; +import { WSModels } from "carbon-js-sdk/lib/websocket"; import moment from "moment"; import { BN_ZERO, parseNumber } from "./number"; @@ -69,16 +70,16 @@ export function parseMarketListMap(marketList: Models.Market[]): MarketListMap { return listMarket; } -export function parseMarketStats(marketStats: Models.MarketStats): MarketStatItem { +export function parseMarketStats(marketStats: WSModels.MarketStat): MarketStatItem { return { ...marketStats, - dayOpen: parseNumber(marketStats.dayOpen, BN_ZERO)!, - dayClose: parseNumber(marketStats.dayClose, BN_ZERO)!, - dayVolume: parseNumber(marketStats.dayVolume, BN_ZERO)!, - lastPrice: parseNumber(marketStats.lastPrice, BN_ZERO)!, + dayOpen: parseNumber(marketStats.day_open, BN_ZERO)!, + dayClose: parseNumber(marketStats.day_close, BN_ZERO)!, + dayVolume: parseNumber(marketStats.day_volume, BN_ZERO)!, + lastPrice: parseNumber(marketStats.last_price, BN_ZERO)!, // open_interest: parseNumber(marketStats.open_interest, BN_ZERO)!, open_interest: BN_ZERO, // TODO: Check on market open_interest - marketType: marketStats.marketType as MarketType, + marketType: marketStats.market_type as MarketType, }; } diff --git a/src/@demex-info/views/MarketsTable/MarketsTable.tsx b/src/@demex-info/views/MarketsTable/MarketsTable.tsx index 4458715b..15baa775 100644 --- a/src/@demex-info/views/MarketsTable/MarketsTable.tsx +++ b/src/@demex-info/views/MarketsTable/MarketsTable.tsx @@ -6,7 +6,7 @@ import { import { RootState } from "@demex-info/store/types"; import { BN_ZERO } from "@demex-info/utils"; import { - MarketListMap, MarketStatItem, MarketType, MarkType, isExpired, parseMarketListMap, parseMarketStats, + MarketListMap, MarketListItem, MarketStatItem, MarketType, MarkType, isExpired, parseMarketListMap, parseMarketStats, } from "@demex-info/utils/markets"; import { lazy } from "@loadable/component"; import { @@ -14,7 +14,8 @@ import { } from "@material-ui/core"; import { Skeleton } from "@material-ui/lab"; import BigNumber from "bignumber.js"; -import { CarbonSDK, Models } from "carbon-js-sdk"; +import { CarbonSDK, Models, TypeUtils } from "carbon-js-sdk"; +import { WSConnectorTypes, WSModels, WSResult } from "carbon-js-sdk/lib/websocket"; import clsx from "clsx"; import Long from "long"; import moment from "moment"; @@ -25,11 +26,10 @@ import { useSelector } from "react-redux"; // FuturesTypes, MarketPaper, MarketTab, // } from "./components"; import { - FuturesTypes, MarketPaper, + FuturesTypes, MarketPaper, TokenPopover, } from "./components"; const MarketGridTable = lazy(() => import("./components/MarketGridTable")); -const TokenPopover = lazy(() => import("./components/TokenPopover")); const MarketsTable: React.FC = () => { const [runMarkets, loading] = useAsyncTask("runMarkets"); @@ -100,8 +100,9 @@ const MarketsTable: React.FC = () => { const listData: MarketListMap = parseMarketListMap(listResponse); setList(listData); - const statsResponse = await sdk.query.marketstats.MarketStats({}); - const marketStatItems = statsResponse.marketstats.map((stat: Models.MarketStats) => ( + const response = await ws.request<{ result: TypeUtils.SimpleMap }>(WSConnectorTypes.WSRequest.MarketStats, {}) as WSResult<{ result: TypeUtils.SimpleMap }>; + const statsResponse = response.data.result ?? {}; + const marketStatItems = Object.values(statsResponse).map((stat: WSModels.MarketStat) => ( parseMarketStats(stat)), ); setStats(marketStatItems); @@ -114,11 +115,11 @@ const MarketsTable: React.FC = () => { }; useEffect(() => { - if (sdk && ws && ws?.connected) { + if (sdk && ws && ws?.connected === true) { reloadMarkets(); } return () => { }; - }, [sdk, ws]); + }, [sdk, ws?.connected]); useEffect(() => { setTimeout(() => setRenderReady(true)); @@ -169,7 +170,6 @@ const MarketsTable: React.FC = () => { marketsList.forEach((market: MarketStatItem) => { const marketItem = list?.[market.market] ?? {}; const baseDenom = marketItem?.base ?? ""; - const quoteDenom = marketItem?.quote ?? ""; const symbolUsd = sdk?.token.getUSDValue(baseDenom) ?? BN_ZERO; const adjustedVolume = sdk?.token.toHuman(baseDenom, market.dayVolume) ?? BN_ZERO; @@ -177,12 +177,16 @@ const MarketsTable: React.FC = () => { volume24H = volume24H.plus(usdVolume); openInterest = openInterest.plus(symbolUsd.times(market.open_interest)); + }); + + Object.values(list).forEach((market: MarketListItem) => { + if (market.marketType === "futures") return; - if (!coinsList.includes(baseDenom) && baseDenom.length > 0) { - coinsList.push(baseDenom); + if (!coinsList.includes(market.base) && market.base.length > 0) { + coinsList.push(market.base); } - if (!coinsList.includes(quoteDenom) && quoteDenom.length > 0) { - coinsList.push(quoteDenom); + if (!coinsList.includes(market.quote) && market.quote.length > 0) { + coinsList.push(market.quote); } }); @@ -369,11 +373,7 @@ const MarketsTable: React.FC = () => { } - { - openTokens && ( - - ) - } + {openTokens && } diff --git a/src/@demex-info/views/MarketsTable/components/MarketGridRow.tsx b/src/@demex-info/views/MarketsTable/components/MarketGridRow.tsx index 2498a2cf..1b6c0d66 100644 --- a/src/@demex-info/views/MarketsTable/components/MarketGridRow.tsx +++ b/src/@demex-info/views/MarketsTable/components/MarketGridRow.tsx @@ -1,5 +1,5 @@ import { AssetIcon, RenderGuard, TypographyLabel } from "@demex-info/components"; -import { DEC_SHIFT, getDemexLink, goToLink, Paths } from "@demex-info/constants"; +import { getDemexLink, goToLink, Paths } from "@demex-info/constants"; import { useAsyncTask } from "@demex-info/hooks"; import { RootState } from "@demex-info/store/types"; import { BN_ZERO, formatUsdPrice, SECONDS_PER_DAY, toPercentage } from "@demex-info/utils"; @@ -61,9 +61,9 @@ const MarketGridRow: React.FC = (props: Props) => { const baseUsd = sdk?.token.getUSDValue(listItem?.base ?? "") ?? BN_ZERO; const quoteUsd = sdk?.token.getUSDValue(listItem?.quote ?? "") ?? BN_ZERO; - const openPrice = stat.dayOpen.shiftedBy(-DEC_SHIFT).shiftedBy(-diffDp); - const closePrice = stat.dayClose.shiftedBy(-DEC_SHIFT).shiftedBy(-diffDp); - const lastPrice = stat.lastPrice.shiftedBy(-DEC_SHIFT).shiftedBy(-diffDp); + const openPrice = stat.dayOpen.shiftedBy(-diffDp); + const closePrice = stat.dayClose.shiftedBy(-diffDp); + const lastPrice = stat.lastPrice.shiftedBy(-diffDp); const lastPriceUsd = quoteUsd.times(lastPrice); const change24H = openPrice.isZero() ? BN_ZERO : closePrice.minus(openPrice).dividedBy(openPrice); @@ -129,7 +129,6 @@ const MarketGridRow: React.FC = (props: Props) => { to: new Long(currentDate), }); const candlestickArr: CandleStickItem[] = parseMarketCandlesticks(candleResponse.candlesticks, listItem, sdk); - if (candlestickArr.length > 0) { candlestickArr.forEach((candle: CandleStickItem) => { if (candle.close > newYBounds.max) { @@ -148,7 +147,33 @@ const MarketGridRow: React.FC = (props: Props) => { } }); return () => {}; - }, [stat.market]); + }, [stat.market, sdk]); + + const candleStickData = React.useMemo(() => { + const candleStickLabels = candleSticks ? candleSticks.map((candle: CandleStickItem) => candle.timestamp) : []; + return (canvas: HTMLCanvasElement) => { + const ctx = canvas.getContext("2d"); + const gradient = ctx?.createLinearGradient(0, 0, 0, 100); + gradient?.addColorStop(0, fade(graphLightColor, 0.6)); + gradient?.addColorStop(0.5, fade(graphLightColor, 0.3)); + gradient?.addColorStop(1, fade(graphLightColor, 0)); + return { + labels: candleStickLabels, + datasets: [{ + backgroundColor: gradient ?? graphLightColor, + borderColor: graphMainColor, + borderWidth: 1, + data: candleSticks, + fill: "start", + parsing: { + xAxisKey: "timestamp", + yAxisKey: "close", + }, + pointRadius: 0, + }], + }; + }; + }, [candleSticks, graphLightColor, graphMainColor]); return ( = (props: Props) => { (!loading && candleSticks) && ( { - const ctx = canvas.getContext("2d"); - const gradient = ctx?.createLinearGradient(0, 0, 0, 100); - gradient?.addColorStop(0, fade(graphLightColor, 0.6)); - gradient?.addColorStop(0.5, fade(graphLightColor, 0.3)); - gradient?.addColorStop(1, fade(graphLightColor, 0)); - return { - labels: candleSticks.map((candle: CandleStickItem) => candle.timestamp), - datasets: [{ - backgroundColor: gradient ?? graphLightColor, - borderColor: graphMainColor, - borderWidth: 1, - data: candleSticks, - fill: "start", - parsing: { - xAxisKey: "timestamp", - yAxisKey: "close", - }, - pointRadius: 0, - }], - }; - }} + data={candleStickData} width={240} height={88} options={graphOptions} diff --git a/src/@demex-info/views/MarketsTable/components/TokenPopover.tsx b/src/@demex-info/views/MarketsTable/components/TokenPopover.tsx index 01028b64..67eb81c0 100644 --- a/src/@demex-info/views/MarketsTable/components/TokenPopover.tsx +++ b/src/@demex-info/views/MarketsTable/components/TokenPopover.tsx @@ -1,5 +1,5 @@ import { - CoinIcon, PaperBox, RenderGuard, TypographyLabel, withLightTheme, + CoinIcon, PaperBox, TypographyLabel, withLightTheme, } from "@demex-info/components"; import { RootState } from "@demex-info/store/types"; import { Box, makeStyles, Theme } from "@material-ui/core"; @@ -23,24 +23,22 @@ const TokenPopover: React.FC = (props: Props) => { const { sdk } = useSelector((state: RootState) => state.app); return ( - 0}> - - { - tokens.map((token: string) => { - const tokenObj = sdk?.token.tokenForDenom(token); - const tokenName = sdk?.token.getTokenName(token) ?? ""; - return ( - - - - {NameOverride[tokenObj?.id ?? ""] ?? tokenObj?.name ?? "-"} - - - ); - }) - } - - + + { + tokens.map((token: string) => { + const tokenObj = sdk?.token.tokenForDenom(token); + const tokenName = sdk?.token.getTokenName(token) ?? ""; + return ( + + + + {NameOverride[tokenObj?.id ?? ""] ?? tokenObj?.name ?? "-"} + + + ); + }) + } + ); }; @@ -50,11 +48,35 @@ const useStyles = makeStyles((theme: Theme) => ({ maxWidth: "1.125rem", minHeight: "1.125rem", minWidth: "1.125rem", + marginTop: 1, }, dropdownPaper: { backgroundColor: theme.palette.background.default, padding: theme.spacing(2), zIndex: 3, + maxHeight: "15rem", + overflow: "auto", + "&::-webkit-scrollbar": { + // the actual width is this value minus twice of border width + width: theme.spacing(1.5), + height: theme.spacing(1.5), + }, + "&::-webkit-scrollbar-corner": { + backgroundColor: "transparent", + borderRadius: "4px", + }, + "&::-webkit-scrollbar-track": { + backgroundColor: "transparent", + borderRadius: "4px", + }, + "&::-webkit-scrollbar-thumb": { + backgroundClip: "padding-box", + backgroundColor: theme.palette.divider, + border: "3px solid", + borderColor: "transparent", + // the actual border radius should be this value minus twice of border width + borderRadius: theme.spacing(2.5), + }, [theme.breakpoints.only("xs")]: { padding: theme.spacing(1.5, 2), },