diff --git a/package.json b/package.json index 0e4079c3e0..28807300cb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "kwenta", - "version": "7.4.12", + "version": "7.4.13", "description": "Kwenta", "main": "index.js", "scripts": { diff --git a/packages/app/package.json b/packages/app/package.json index 1b9fd7bdbd..5f2b0eb931 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "@kwenta/app", - "version": "7.4.12", + "version": "7.4.13", "scripts": { "dev": "next", "build": "next build", diff --git a/packages/app/src/components/TVChart/DataFeed.ts b/packages/app/src/components/TVChart/DataFeed.ts index 5c6c1217f8..6c2e92cc48 100644 --- a/packages/app/src/components/TVChart/DataFeed.ts +++ b/packages/app/src/components/TVChart/DataFeed.ts @@ -55,28 +55,6 @@ const splitBaseQuote = (symbolName: string) => { return { base, quote } } -// TODO: Make this dynamic -const getPriceScale = (asset: string | null) => { - switch (asset) { - case 'BTC': - case 'BNB': - case 'ETH': - case 'stETH': - case 'XAU': - return 100 - case 'DOGE': - case 'FTM': - case 'AUD': - return 10000 - case 'SHIB': - case 'FLOKI': - case 'PEPE': - return 1000000000 - default: - return 1000 - } -} - const fetchCombinedCandles = async ( base: string, from: number, @@ -156,6 +134,7 @@ const subscribeOffChainPrices = ( const DataFeedFactory = ( networkId: NetworkId, + chartScale: number, onSubscribe: (priceListener: PricesListener) => void ): IBasicDataFeed => { _latestChartBar.current = undefined @@ -177,7 +156,7 @@ const DataFeedFactory = ( ticker: symbolName, exchange: '', minmov: 1, - pricescale: getPriceScale(asset), + pricescale: chartScale, has_intraday: true, intraday_multipliers: supportedResolutions, supported_resolution: supportedResolutions, diff --git a/packages/app/src/components/TVChart/TVChart.tsx b/packages/app/src/components/TVChart/TVChart.tsx index baf07ca1e8..b5361bc824 100644 --- a/packages/app/src/components/TVChart/TVChart.tsx +++ b/packages/app/src/components/TVChart/TVChart.tsx @@ -1,5 +1,5 @@ import { NetworkId, ConditionalOrder, PricesListener } from '@kwenta/sdk/types' -import { formatOrderDisplayType, formatNumber } from '@kwenta/sdk/utils' +import { formatOrderDisplayType, formatNumber, suggestedDecimals } from '@kwenta/sdk/utils' import { ChartingLibraryWidgetOptions, IChartingLibraryWidget, @@ -30,6 +30,7 @@ export type ChartProps = { potentialTrade?: ChartPosition | null openOrders: ConditionalOrder[] showOrderLines: boolean + initialPrice: string onChartReady?: () => void onToggleShowOrderLines?: () => void } @@ -55,6 +56,7 @@ export function TVChart({ potentialTrade, openOrders, showOrderLines, + initialPrice, onToggleShowOrderLines, onChartReady = () => { return @@ -91,6 +93,10 @@ export function TVChart({ _oderLineRefs.current = [] } + const decimals = + Number(initialPrice) > 100 && Number(initialPrice) < 1000 ? 3 : suggestedDecimals(initialPrice) + const chartScale = 10 ** decimals + useEffect(() => { return () => { if (_priceListener.current) { @@ -164,7 +170,11 @@ export function TVChart({ const widgetOptions: ChartingLibraryWidgetOptions = { symbol: marketAsset + ':sUSD', - datafeed: DataFeedFactory((network?.id ?? chain.optimism.id) as NetworkId, onSubscribe), + datafeed: DataFeedFactory( + (network?.id ?? chain.optimism.id) as NetworkId, + chartScale, + onSubscribe + ), interval: interval as ResolutionString, container: containerId, library_path: libraryPath, @@ -234,7 +244,7 @@ export function TVChart({ clearExistingWidget() } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [network?.id as NetworkId, currentTheme, marketAssetLoaded]) + }, [network?.id as NetworkId, currentTheme, marketAssetLoaded, chartScale]) useEffect(() => { if (onToggleShowOrderLines) { diff --git a/packages/app/src/queries/rates/useCandlesticksQuery.ts b/packages/app/src/queries/rates/useCandlesticksQuery.ts index 44fe4619d2..7d689b3e37 100644 --- a/packages/app/src/queries/rates/useCandlesticksQuery.ts +++ b/packages/app/src/queries/rates/useCandlesticksQuery.ts @@ -6,8 +6,8 @@ import { getSupportedResolution } from 'components/TVChart/utils' import { DEFAULT_NETWORK_ID } from 'constants/defaults' import logError from 'utils/logError' -import { DEFAULT_PYTH_TV_ENDPOINT, NON_CRYPTO_ASSET_TYPES } from './constants' -import { mapCandles, mapPythCandles } from './utils' +import { DEFAULT_PYTH_TV_ENDPOINT } from './constants' +import { formatPythSymbol, mapCandles, mapPythCandles } from './utils' export const requestCandlesticks = async ( currencyKey: string | null, @@ -19,18 +19,13 @@ export const requestCandlesticks = async ( const ratesEndpoint = getRatesEndpoint(networkId) const pythTvEndpoint = DEFAULT_PYTH_TV_ENDPOINT - let prefix = - Object.keys(NON_CRYPTO_ASSET_TYPES).find((type) => - NON_CRYPTO_ASSET_TYPES[type].includes(currencyKey!) - ) || 'Crypto' - if (period <= 3600) { const response = await axios .get(pythTvEndpoint, { params: { from: minTimestamp, to: maxTimestamp, - symbol: `${prefix}.${currencyKey}/USD`, + symbol: formatPythSymbol(currencyKey!), resolution: getSupportedResolution(period), }, }) diff --git a/packages/app/src/queries/rates/utils.ts b/packages/app/src/queries/rates/utils.ts index 3e59e43f5e..390e248824 100644 --- a/packages/app/src/queries/rates/utils.ts +++ b/packages/app/src/queries/rates/utils.ts @@ -1,5 +1,6 @@ import { CandleResult } from '@kwenta/sdk/utils' +import { NON_CRYPTO_ASSET_TYPES } from './constants' import { Candle, PythResponse } from './types' export const mapCandles = (candles: CandleResult[]): Candle[] => { @@ -27,3 +28,12 @@ export const mapPythCandles = (candleData: PythResponse): Candle[] => { } }) } + +export const formatPythSymbol = (asset: string): string => { + if (asset === 'ETHBTC') return 'Crypto.ETH/BTC' + const prefix = + Object.keys(NON_CRYPTO_ASSET_TYPES).find((type) => + NON_CRYPTO_ASSET_TYPES[type].includes(asset) + ) || 'Crypto' + return `${prefix}.${asset}/USD` +} diff --git a/packages/app/src/sections/exchange/TradeCard/CurrencyCard/CurrencyCardInput.tsx b/packages/app/src/sections/exchange/TradeCard/CurrencyCard/CurrencyCardInput.tsx index 92bbb2a1ce..fdc031fac9 100644 --- a/packages/app/src/sections/exchange/TradeCard/CurrencyCard/CurrencyCardInput.tsx +++ b/packages/app/src/sections/exchange/TradeCard/CurrencyCard/CurrencyCardInput.tsx @@ -141,7 +141,6 @@ const CurrencyAmount = styled(NumericInput)` input { font-size: 30px; - line-height: 2.25em; letter-spacing: -1px; height: 30px; width: 100%; diff --git a/packages/app/src/sections/futures/MarketDetails/utils.ts b/packages/app/src/sections/futures/MarketDetails/utils.ts index 388a850acb..15b7118bda 100644 --- a/packages/app/src/sections/futures/MarketDetails/utils.ts +++ b/packages/app/src/sections/futures/MarketDetails/utils.ts @@ -21,8 +21,8 @@ export const marketDataKeyMap: Record = { [MarketDataKey.dailyTrades]: '24h-trades', [MarketDataKey.openInterestLong]: 'open-interest-l', [MarketDataKey.openInterestShort]: 'open-interest-s', - [MarketDataKey.openInterestLongMobile]: 'open-interest-lm', - [MarketDataKey.openInterestShortMobile]: 'open-interest-sm', + [MarketDataKey.openInterestLongMobile]: 'open-interest-l', + [MarketDataKey.openInterestShortMobile]: 'open-interest-s', [MarketDataKey.instFundingRate]: '1h-funding-rate', [MarketDataKey.hourlyFundingRate]: 'funding-rate', [MarketDataKey.skew]: 'skew', diff --git a/packages/app/src/sections/futures/MobileTrade/MobileTrade.tsx b/packages/app/src/sections/futures/MobileTrade/MobileTrade.tsx index aa7eaade2d..ac95a82c1b 100644 --- a/packages/app/src/sections/futures/MobileTrade/MobileTrade.tsx +++ b/packages/app/src/sections/futures/MobileTrade/MobileTrade.tsx @@ -34,7 +34,7 @@ const MobileTrade: React.FC = () => { <> {deviceType === 'mobile' && } - {deviceType === 'mobile' && } + {deviceType === 'mobile' && } diff --git a/packages/app/src/sections/futures/MobileTrade/UserTabs/PositionsTab.tsx b/packages/app/src/sections/futures/MobileTrade/UserTabs/PositionsTab.tsx index fafa313c7b..f3e610cbea 100644 --- a/packages/app/src/sections/futures/MobileTrade/UserTabs/PositionsTab.tsx +++ b/packages/app/src/sections/futures/MobileTrade/UserTabs/PositionsTab.tsx @@ -127,7 +127,7 @@ const PositionsTab = () => {
{row.market.marketName} - {accountType === 'isolated_margin' ? 'Isolated Margin' : 'Cross-Margin'} + {accountType === 'isolated_margin' ? 'Isolated Margin' : 'Smart Margin'}
diff --git a/packages/app/src/sections/futures/PositionChart.tsx b/packages/app/src/sections/futures/PositionChart.tsx index 169c8fa07b..88142af25a 100644 --- a/packages/app/src/sections/futures/PositionChart.tsx +++ b/packages/app/src/sections/futures/PositionChart.tsx @@ -6,6 +6,7 @@ import { FlexDiv } from 'components/layout/flex' import TVChart from 'components/TVChart' import { selectConditionalOrdersForMarket, + selectMarketIndexPrice, selectPosition, selectPositionPreviewData, selectSelectedMarketPositionHistory, @@ -23,6 +24,7 @@ export default function PositionChart({ display = true }: PositionChartProps) { const previewTrade = useAppSelector(selectTradePreview) const subgraphPosition = useAppSelector(selectSelectedMarketPositionHistory) const positionPreview = useAppSelector(selectPositionPreviewData) + const initialPrice = useAppSelector(selectMarketIndexPrice) const [showOrderLines, setShowOrderLines] = useState(true) const [isChartReady, setIsChartReady] = useState(false) @@ -52,6 +54,7 @@ export default function PositionChart({ display = true }: PositionChartProps) { = ({ asset, position }) => { const defaultAsset = useAppSelector(selectMarketAsset) diff --git a/packages/app/src/sections/futures/ShareModal/ShareModalButton.tsx b/packages/app/src/sections/futures/ShareModal/ShareModalButton.tsx index 76ab0eedf8..61d5f203dd 100644 --- a/packages/app/src/sections/futures/ShareModal/ShareModalButton.tsx +++ b/packages/app/src/sections/futures/ShareModal/ShareModalButton.tsx @@ -1,6 +1,6 @@ import { ZERO_WEI } from '@kwenta/sdk/constants' import { PositionSide } from '@kwenta/sdk/types' -import { formatDollars, formatNumber } from '@kwenta/sdk/utils' +import { formatDollars, formatNumber, getMarketName } from '@kwenta/sdk/utils' import { toPng } from 'html-to-image' import { FC } from 'react' import { useTranslation } from 'react-i18next' @@ -10,7 +10,6 @@ import TwitterIcon from 'assets/svg/social/twitter.svg' import Button from 'components/Button' import { DesktopOnlyView, MobileOrTabletView } from 'components/Media' import { SharePositionParams } from 'state/futures/types' -import { getMarketName } from 'utils/futures' function getTwitterText( side: PositionSide, diff --git a/packages/app/src/sections/futures/Trade/MarketsDropdown.tsx b/packages/app/src/sections/futures/Trade/MarketsDropdown.tsx index 19a26d95d3..39b70391a9 100644 --- a/packages/app/src/sections/futures/Trade/MarketsDropdown.tsx +++ b/packages/app/src/sections/futures/Trade/MarketsDropdown.tsx @@ -6,6 +6,7 @@ import { MarketKeyByAsset, floorNumber, formatDollars, + getMarketName, } from '@kwenta/sdk/utils' import { wei } from '@synthetixio/wei' import { useRouter } from 'next/router' @@ -42,7 +43,7 @@ import { useAppSelector } from 'state/hooks' import { selectPreviousDayPrices } from 'state/prices/selectors' import { FetchStatus } from 'state/types' import media from 'styles/media' -import { getMarketName, getSynthDescription } from 'utils/futures' +import { getSynthDescription } from 'utils/futures' import { MARKETS_DETAILS_HEIGHT_DESKTOP, @@ -235,7 +236,7 @@ const MarketsDropdown: React.FC = ({ mobile }) => { )} ), - size: 35, + size: 30, }, { header: () => {t('futures.markets-drop-down.market')}, @@ -249,7 +250,7 @@ const MarketsDropdown: React.FC = ({ mobile }) => { {getDisplayAsset(row.original.asset)} ), - size: 80, + size: 65, }, { header: () => {t('futures.markets-drop-down.price')}, @@ -265,10 +266,14 @@ const MarketsDropdown: React.FC = ({ mobile }) => { ) }, - size: 80, + size: 100, }, { - header: () => {t('futures.markets-drop-down.change')}, + header: () => ( + + {t('futures.markets-drop-down.change')} + + ), cell: ({ row }) => { return (
@@ -284,6 +289,7 @@ const MarketsDropdown: React.FC = ({ mobile }) => { row.original.change ? row.original.change * 100 : '0', 2 )} + style={{ textAlign: 'right', width: '60px' }} /> } /> @@ -293,7 +299,7 @@ const MarketsDropdown: React.FC = ({ mobile }) => { accessorKey: 'change', sortingFn: 'basic', enableSorting: true, - size: 50, + size: 60, }, ]} data={options} diff --git a/packages/app/src/sections/futures/Trade/TradeBalance.tsx b/packages/app/src/sections/futures/Trade/TradeBalance.tsx index e5430033d0..6ee1b87f54 100644 --- a/packages/app/src/sections/futures/Trade/TradeBalance.tsx +++ b/packages/app/src/sections/futures/Trade/TradeBalance.tsx @@ -1,7 +1,7 @@ import { MIN_MARGIN_AMOUNT } from '@kwenta/sdk/constants' import { formatDollars } from '@kwenta/sdk/utils' -import { memo, useMemo, useState } from 'react' -import { useTranslation } from 'react-i18next' +import { FC, memo, useCallback, useMemo, useState } from 'react' +import { Trans, useTranslation } from 'react-i18next' import styled from 'styled-components' import HelpIcon from 'assets/svg/app/question-mark.svg' @@ -14,7 +14,7 @@ import Tooltip from 'components/Tooltip/Tooltip' import useWindowSize from 'hooks/useWindowSize' import { setOpenModal } from 'state/app/reducer' import { selectShowModal } from 'state/app/selectors' -import { selectSusdBalance } from 'state/balances/selectors' +import { ModalType } from 'state/app/types' import { selectAvailableMargin, selectFuturesType, @@ -29,74 +29,122 @@ import CrossMarginInfoBox from '../TradeCrossMargin/CrossMarginInfoBox' import SmartMarginOnboardModal from './SmartMarginOnboardModal' -type TradeBalanceProps = { - isMobile?: boolean +type BrdigeAndWithdrawButtonProps = { + modalType: ModalType + onPillClick: () => void + expanded: boolean } -const TradeBalance: React.FC = memo(({ isMobile = false }) => { +const BrdigeAndWithdrawButton: FC = ({ + modalType, + onPillClick, + expanded, +}) => { + const dispatch = useAppDispatch() + + return ( + + { + e.stopPropagation() + dispatch(setOpenModal(modalType)) + }} + /> + + + + + ) +} + +const TradeBalance = memo(() => { const { t } = useTranslation() const dispatch = useAppDispatch() - const { deviceType } = useWindowSize() - const idleMargin = useAppSelector(selectIdleMargin) - const lockedMargin = useAppSelector(selectLockedMarginInMarkets) - const walletBal = useAppSelector(selectSusdBalance) + const { deviceType } = useWindowSize() const accountType = useAppSelector(selectFuturesType) + const availableCrossMargin = useAppSelector(selectIdleMargin) + const lockedMargin = useAppSelector(selectLockedMarginInMarkets) const availableIsolatedMargin = useAppSelector(selectAvailableMargin) const withdrawable = useAppSelector(selectWithdrawableMargin) const openModal = useAppSelector(selectShowModal) const [expanded, setExpanded] = useState(false) + const { isMobile, size } = useMemo(() => { + const isMobile = deviceType === 'mobile' + const size: 'small' | 'medium' = isMobile ? 'small' : 'medium' + return { isMobile, size } + }, [deviceType]) + + const isCrossMarginAccount = useMemo(() => accountType === 'cross_margin', [accountType]) + const isDepositRequired = useMemo(() => { - return walletBal.lt(MIN_MARGIN_AMOUNT) && withdrawable.eq(0) && lockedMargin.eq(0) - }, [lockedMargin, walletBal, withdrawable]) + return isCrossMarginAccount && availableCrossMargin.lt(MIN_MARGIN_AMOUNT) && lockedMargin.eq(0) + }, [availableCrossMargin, lockedMargin]) - const onClickContainer = () => { - if (accountType === 'isolated_margin') return + const onClickContainer = useCallback(() => { + if (!isCrossMarginAccount) return setExpanded(!expanded) - } + }, [expanded, isCrossMarginAccount]) return ( - - - {accountType === 'cross_margin' && isDepositRequired ? ( + + + {isDepositRequired ? ( - - {t('futures.market.trade.trade-balance.no-available-margin')} + + {availableCrossMargin.lt(0.01) ? ( + t('futures.market.trade.trade-balance.no-available-margin') + ) : ( + + )} - + {t('futures.market.trade.trade-balance.min-margin')} - + {availableCrossMargin.lt(0.01) ? ( + + ) : ( + + )} ) : ( <> {isMobile ? ( - + {t('futures.market.trade.trade-balance.available-margin')}: - {accountType === 'isolated_margin' - ? formatDollars(availableIsolatedMargin) - : formatDollars(idleMargin)} + {isCrossMarginAccount + ? formatDollars(availableCrossMargin) + : formatDollars(availableIsolatedMargin)} - {accountType === 'cross_margin' && lockedMargin.gt(0) && ( + {isCrossMarginAccount && lockedMargin.gt(0) && ( {t('futures.market.trade.trade-balance.locked-margin')}: @@ -115,20 +163,27 @@ const TradeBalance: React.FC = memo(({ isMobile = false }) => )} - + + ) : ( - + {t('futures.market.trade.trade-balance.available-margin')} - {accountType === 'isolated_margin' - ? formatDollars(availableIsolatedMargin) - : formatDollars(idleMargin)} + {isCrossMarginAccount + ? formatDollars(availableCrossMargin) + : formatDollars(availableIsolatedMargin)} - {accountType === 'cross_margin' && lockedMargin.gt(0) && ( + {isCrossMarginAccount && lockedMargin.gt(0) && ( @@ -147,35 +202,20 @@ const TradeBalance: React.FC = memo(({ isMobile = false }) => )} - + + )} )} - - {(accountType === 'isolated_margin' || withdrawable.gt(0) || !isDepositRequired) && ( - - { - e.stopPropagation() - dispatch( - setOpenModal( - accountType === 'isolated_margin' - ? 'futures_isolated_transfer' - : 'futures_cross_withdraw' - ) - ) - }} - /> - - - - - )} - {expanded && accountType === 'cross_margin' && ( + {expanded && isCrossMarginAccount && ( {} )} {openModal === 'futures_smart_margin_socket' && ( diff --git a/packages/app/src/sections/homepage/Assets.tsx b/packages/app/src/sections/homepage/Assets.tsx index d7e7893063..57e9d4bdeb 100644 --- a/packages/app/src/sections/homepage/Assets.tsx +++ b/packages/app/src/sections/homepage/Assets.tsx @@ -1,4 +1,5 @@ import { SECONDS_PER_DAY } from '@kwenta/sdk/constants' +import { MarketKeyByAsset } from '@kwenta/sdk/utils' import { wei } from '@synthetixio/wei' import { ColorType, createChart, UTCTimestamp } from 'lightweight-charts' import router from 'next/router' @@ -149,9 +150,7 @@ const Assets = () => { ? marketPrice.sub(pastPrice.rate).div(marketPrice) : 0, image: , - icon: ( - - ), + icon: , } }) }, [futuresMarkets, pastRates, futuresVolumes, t, prices]) diff --git a/packages/app/src/sections/leaderboard/TraderHistory.tsx b/packages/app/src/sections/leaderboard/TraderHistory.tsx index 0b4f71074a..4c63e9a1a7 100644 --- a/packages/app/src/sections/leaderboard/TraderHistory.tsx +++ b/packages/app/src/sections/leaderboard/TraderHistory.tsx @@ -1,4 +1,5 @@ import { ZERO_WEI } from '@kwenta/sdk/constants' +import { getMarketName } from '@kwenta/sdk/utils' import { wei, WeiSource } from '@synthetixio/wei' import router from 'next/router' import { FC, memo, useEffect, useMemo } from 'react' @@ -26,7 +27,6 @@ import { useAppDispatch, useAppSelector } from 'state/hooks' import { FetchStatus } from 'state/types' import { ExternalLink, FOOTER_HEIGHT } from 'styles/common' import media from 'styles/media' -import { getMarketName } from 'utils/futures' type TraderHistoryProps = { trader: string diff --git a/packages/app/src/translations/en.json b/packages/app/src/translations/en.json index 4a1017be08..596a13d512 100644 --- a/packages/app/src/translations/en.json +++ b/packages/app/src/translations/en.json @@ -957,6 +957,7 @@ "available-margin": "Available Margin", "locked-margin": "Locked Margin", "no-available-margin": "No available margin", + "only-available-margin": "Only {{balance}} available margin", "min-margin": "Min. $50 sUSD required to trade", "tooltip": "Margin currently locked in closed markets. It will become available once the market reopens." }, diff --git a/packages/app/src/utils/futures.ts b/packages/app/src/utils/futures.ts index 7813d3cbb1..5be4f1bc70 100644 --- a/packages/app/src/utils/futures.ts +++ b/packages/app/src/utils/futures.ts @@ -14,8 +14,8 @@ import { import { AssetDisplayByAsset, MarketKeyByAsset, - getDisplayAsset, formatNumber, + getMarketName, } from '@kwenta/sdk/utils' import Wei, { wei } from '@synthetixio/wei' import { TFunction } from 'i18next' @@ -31,10 +31,6 @@ import { } from 'state/futures/types' import { deserializeWeiObject } from 'state/helpers' -export const getMarketName = (asset: FuturesMarketAsset) => { - return `${getDisplayAsset(asset)}/sUSD` -} - export const getSynthDescription = (synth: FuturesMarketAsset, t: TFunction) => { const assetDisplayName = AssetDisplayByAsset[synth] return t('common.currency.futures-market-short-name', { diff --git a/packages/app/src/utils/icons.ts b/packages/app/src/utils/icons.ts index ae6d707dd5..41c8fc815b 100644 --- a/packages/app/src/utils/icons.ts +++ b/packages/app/src/utils/icons.ts @@ -16,10 +16,12 @@ import BLURIcon from 'assets/png/currencies/sBLUR.png' import BNBIcon from 'assets/png/currencies/sBNB.png' import BTCIcon from 'assets/png/currencies/sBTC.png' import CHFIcon from 'assets/png/currencies/sCHF.png' +import COMPIcon from 'assets/png/currencies/sCOMP.png' import CRVIcon from 'assets/png/currencies/sCRV.png' import DOGEIcon from 'assets/png/currencies/sDOGE.png' import DOTIcon from 'assets/png/currencies/sDOT.png' import DYDXIcon from 'assets/png/currencies/sDYDX.png' +import ETCIcon from 'assets/png/currencies/sETC.png' import ETHIcon from 'assets/png/currencies/sETH.png' import ETHBTCIcon from 'assets/png/currencies/sETHBTC.png' import EURIcon from 'assets/png/currencies/sEUR.png' @@ -37,11 +39,14 @@ import LDOIcon from 'assets/png/currencies/sLDO.png' import LINKIcon from 'assets/png/currencies/sLINK.png' import LTCIcon from 'assets/png/currencies/sLTC.png' import MATICIcon from 'assets/png/currencies/sMATIC.png' +import MAVIcon from 'assets/png/currencies/sMAV.png' +import MKRIcon from 'assets/png/currencies/sMKR.png' import NEARIcon from 'assets/png/currencies/sNEAR.png' import SNXIcon from 'assets/png/currencies/SNX.png' import OILIcon from 'assets/png/currencies/sOIL.png' import OPIcon from 'assets/png/currencies/sOP.png' import PEPEIcon from 'assets/png/currencies/sPEPE.png' +import RPLIcon from 'assets/png/currencies/sRPL.png' import SHIBIcon from 'assets/png/currencies/sSHIB.png' import SOLIcon from 'assets/png/currencies/sSOL.png' import STETHIcon from 'assets/png/currencies/sstETH.png' @@ -53,6 +58,7 @@ import XAGIcon from 'assets/png/currencies/sXAG.png' import XAUIcon from 'assets/png/currencies/sXAU.png' import XMRIcon from 'assets/png/currencies/sXMR.png' import XRPIcon from 'assets/png/currencies/sXRP.png' +import YFIIcon from 'assets/png/currencies/sYFI.png' import WBTCIcon from 'assets/png/currencies/WBTC.png' import { SynthsName } from 'constants/currency' @@ -70,11 +76,14 @@ export const SYNTH_ICONS: Record = sBLURPERP: BLURIcon, sBNBPERP: BNBIcon, sBTCPERP: BTCIcon, + sCOMPPERP: COMPIcon, sCRVPERP: CRVIcon, sDOGEPERP: DOGEIcon, sDOTPERP: DOTIcon, sDYDXPERP: DYDXIcon, sETHPERP: ETHIcon, + sETHBTCPERP: ETHBTCIcon, + sETCPERP: ETCIcon, sEURPERP: EURIcon, sFILPERP: FILIcon, sFLOKIPERP: FLOKIIcon, @@ -87,9 +96,12 @@ export const SYNTH_ICONS: Record = sLDOPERP: LDOIcon, sLTCPERP: LTCIcon, sMATICPERP: MATICIcon, + sMAVPERP: MAVIcon, + sMKRPERP: MKRIcon, sNEARPERP: NEARIcon, sOPPERP: OPIcon, sPEPEPERP: PEPEIcon, + sRPLPERP: RPLIcon, sSHIBPERP: SHIBIcon, sSOLPERP: SOLIcon, sSTETHPERP: STETHIcon, @@ -100,6 +112,7 @@ export const SYNTH_ICONS: Record = sXAGPERP: XAGIcon, sXMRPERP: XMRIcon, sXRPPERP: XRPIcon, + sYFIPERP: YFIIcon, sAAVE: AAVEIcon, sADA: ADAIcon, sAPE: APEIcon, diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 9f5c42a5d1..a9114487ca 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@kwenta/sdk", - "version": "1.0.2", + "version": "1.0.3", "description": "SDK for headless interaction with Kwenta", "main": "dist/index.js", "directories": { diff --git a/packages/sdk/src/constants/futures.ts b/packages/sdk/src/constants/futures.ts index 48382d66c3..c1613ff050 100644 --- a/packages/sdk/src/constants/futures.ts +++ b/packages/sdk/src/constants/futures.ts @@ -490,6 +490,86 @@ export const MARKETS: Record = { testnet: '0xb7abd25a76ddaffdf847224f03198ccb92723f90b2429cf33f0eecb96e352a86', }, }, + [FuturesMarketKey.sETHBTCPERP]: { + key: FuturesMarketKey.sETHBTCPERP, + asset: FuturesMarketAsset.ETHBTC, + supports: 'both', + version: 2, + pythIds: { + mainnet: '0xc96458d393fe9deb7a7d63a0ac41e2898a67a7750dbd166673279e06c868df0a', + testnet: '0x754a0a0800247d77751e35efb91638c828046103be3bb3d26989e65bf4010859', + }, + }, + [FuturesMarketKey.sXMRPERP]: { + key: FuturesMarketKey.sXMRPERP, + asset: FuturesMarketAsset.XMR, + supports: 'both', + version: 2, + pythIds: { + mainnet: '0x46b8cc9347f04391764a0361e0b17c3ba394b001e7c304f7650f6376e37c321d', + testnet: '0xa7e2e2f7d47b17d18e6d49c427f21fb30c0a85e621a8502c3c4e486f3ab543c8', + }, + }, + [FuturesMarketKey.sMAVPERP]: { + key: FuturesMarketKey.sMAVPERP, + asset: FuturesMarketAsset.MAV, + supports: 'both', + version: 2, + pythIds: { + mainnet: '0x5b131ede5d017511cf5280b9ebf20708af299266a033752b64180c4201363b11', + testnet: '0x01a33b54c2911e1f58fdc02bc03e3778508bb9a84571afca33e2757791eb1269', + }, + }, + [FuturesMarketKey.sETCPERP]: { + key: FuturesMarketKey.sETCPERP, + asset: FuturesMarketAsset.ETC, + supports: 'both', + version: 2, + pythIds: { + mainnet: '0x7f5cc8d963fc5b3d2ae41fe5685ada89fd4f14b435f8050f28c7fd409f40c2d8', + testnet: '0xd77bfe9814f5a4718e1420881093efa8c0fe1a783472899f27ad4c7a58ef4d27', + }, + }, + [FuturesMarketKey.sCOMPPERP]: { + key: FuturesMarketKey.sCOMPPERP, + asset: FuturesMarketAsset.COMP, + supports: 'both', + version: 2, + pythIds: { + mainnet: '0x4a8e42861cabc5ecb50996f92e7cfa2bce3fd0a2423b0c44c9b423fb2bd25478', + testnet: '0x4e149083ba3766e716b77c1a6f7744709a075bed2ac08dc485543616454a6404', + }, + }, + [FuturesMarketKey.sYFIPERP]: { + key: FuturesMarketKey.sYFIPERP, + asset: FuturesMarketAsset.YFI, + supports: 'both', + version: 2, + pythIds: { + mainnet: '0x425f4b198ab2504936886c1e93511bb6720fbcf2045a4f3c0723bb213846022f', + testnet: '0xc9c8430ee6c26e218abe9f1c9cb88a664f7096d4934d8dfda17bc5d79e918848', + }, + }, + [FuturesMarketKey.sMKRPERP]: { + key: FuturesMarketKey.sMKRPERP, + asset: FuturesMarketAsset.MKR, + supports: 'both', + version: 2, + pythIds: { + mainnet: '0x9375299e31c0deb9c6bc378e6329aab44cb48ec655552a70d4b9050346a30378', + testnet: '0xc4d994230a6db7909135e4673287fb672f45ea92fb40b1bc9adf101ecf877ab7', + }, + }, + [FuturesMarketKey.sRPLPERP]: { + key: FuturesMarketKey.sRPLPERP, + asset: FuturesMarketAsset.RPL, + supports: 'both', + version: 2, + pythIds: { + mainnet: '0x24f94ac0fd8638e3fc41aab2e4df933e63f763351b640bf336a6ec70651c4503', + testnet: '0x9c48c155a80410aaa3699f6257d2255f6c95d0879766db1a187a249096ed2e94', + }, + }, } export const MARKET_ASSETS_BY_PYTH_ID = Object.values(MARKETS) diff --git a/packages/sdk/src/types/futures.ts b/packages/sdk/src/types/futures.ts index b8053e4c7c..a037e0e053 100644 --- a/packages/sdk/src/types/futures.ts +++ b/packages/sdk/src/types/futures.ts @@ -116,6 +116,14 @@ export enum FuturesMarketKey { sFLOKIPERP = 'sFLOKIPERP', sINJPERP = 'sINJPERP', sSTETHPERP = 'sSTETHPERP', + sETHBTCPERP = 'sETHBTCPERP', + sXMRPERP = 'sXMRPERP', + sMAVPERP = 'sMAVPERP', + sETCPERP = 'sETCPERP', + sCOMPPERP = 'sCOMPPERP', + sYFIPERP = 'sYFIPERP', + sMKRPERP = 'sMKRPERP', + sRPLPERP = 'sRPLPERP', } export enum FuturesMarketAsset { @@ -161,6 +169,14 @@ export enum FuturesMarketAsset { FLOKI = 'FLOKI', INJ = 'INJ', STETH = 'STETH', + ETHBTC = 'ETHBTC', + XMR = 'XMR', + MAV = 'MAV', + ETC = 'ETC', + COMP = 'COMP', + YFI = 'YFI', + MKR = 'MKR', + RPL = 'RPL', } export interface FuturesMarketConfig { diff --git a/packages/sdk/src/utils/futures.ts b/packages/sdk/src/utils/futures.ts index 57eea997c0..0b4a0dfe70 100644 --- a/packages/sdk/src/utils/futures.ts +++ b/packages/sdk/src/utils/futures.ts @@ -119,6 +119,7 @@ export const marketsForNetwork = (networkId: number, logError: IContext['logErro } export const getMarketName = (asset: FuturesMarketAsset | null) => { + if (asset === 'ETHBTC') return 'ETH/BTC' return `${getDisplayAsset(asset)}/sUSD` } @@ -701,6 +702,14 @@ export const MarketAssetByKey: Record = { [FuturesMarketKey.sINJPERP]: FuturesMarketAsset.INJ, [FuturesMarketKey.sTRXPERP]: FuturesMarketAsset.TRX, [FuturesMarketKey.sSTETHPERP]: FuturesMarketAsset.STETH, + [FuturesMarketKey.sETHBTCPERP]: FuturesMarketAsset.ETHBTC, + [FuturesMarketKey.sXMRPERP]: FuturesMarketAsset.XMR, + [FuturesMarketKey.sMAVPERP]: FuturesMarketAsset.MAV, + [FuturesMarketKey.sETCPERP]: FuturesMarketAsset.ETC, + [FuturesMarketKey.sCOMPPERP]: FuturesMarketAsset.COMP, + [FuturesMarketKey.sYFIPERP]: FuturesMarketAsset.YFI, + [FuturesMarketKey.sMKRPERP]: FuturesMarketAsset.MKR, + [FuturesMarketKey.sRPLPERP]: FuturesMarketAsset.RPL, } as const export const MarketKeyByAsset: Record = { @@ -746,11 +755,19 @@ export const MarketKeyByAsset: Record = { [FuturesMarketAsset.INJ]: FuturesMarketKey.sINJPERP, [FuturesMarketAsset.TRX]: FuturesMarketKey.sTRXPERP, [FuturesMarketAsset.STETH]: FuturesMarketKey.sSTETHPERP, + [FuturesMarketAsset.ETHBTC]: FuturesMarketKey.sETHBTCPERP, + [FuturesMarketAsset.XMR]: FuturesMarketKey.sXMRPERP, + [FuturesMarketAsset.MAV]: FuturesMarketKey.sMAVPERP, + [FuturesMarketAsset.ETC]: FuturesMarketKey.sETCPERP, + [FuturesMarketAsset.COMP]: FuturesMarketKey.sCOMPPERP, + [FuturesMarketAsset.YFI]: FuturesMarketKey.sYFIPERP, + [FuturesMarketAsset.MKR]: FuturesMarketKey.sMKRPERP, + [FuturesMarketAsset.RPL]: FuturesMarketKey.sRPLPERP, } as const export const AssetDisplayByAsset: Record = { [FuturesMarketAsset.sBTC]: 'Bitcoin', - [FuturesMarketAsset.sETH]: 'Ether', + [FuturesMarketAsset.sETH]: 'Ethereum', [FuturesMarketAsset.LINK]: 'Chainlink', [FuturesMarketAsset.SOL]: 'Solana', [FuturesMarketAsset.AVAX]: 'Avalanche', @@ -791,6 +808,14 @@ export const AssetDisplayByAsset: Record = { [FuturesMarketAsset.INJ]: 'Injective', [FuturesMarketAsset.TRX]: 'Tron', [FuturesMarketAsset.STETH]: 'Lido Staked ETH', + [FuturesMarketAsset.ETHBTC]: 'Ether/Bitcoin Ratio', + [FuturesMarketAsset.XMR]: 'Monero', + [FuturesMarketAsset.MAV]: 'Maverick', + [FuturesMarketAsset.ETC]: 'Ethereum Classic', + [FuturesMarketAsset.COMP]: 'Compound', + [FuturesMarketAsset.YFI]: 'Yearn.Finance', + [FuturesMarketAsset.MKR]: 'Maker', + [FuturesMarketAsset.RPL]: 'Rocket Pool', } as const export const marketOverrides: Partial>> = {} diff --git a/packages/sdk/src/utils/number.ts b/packages/sdk/src/utils/number.ts index 39f16adeaa..7b77524ee6 100644 --- a/packages/sdk/src/utils/number.ts +++ b/packages/sdk/src/utils/number.ts @@ -224,7 +224,7 @@ export const suggestedDecimals = (value: WeiSource) => { if (value >= 0.001) return 6 if (value >= 0.0001) return 7 if (value >= 0.00001) return 8 - return 9 + return 11 } export const floorNumber = (num: WeiSource, decimals?: number) => {