diff --git a/packages/dapp-example/src/QuickSwap.tsx b/packages/dapp-example/src/QuickSwap.tsx index 27bac5dd..db3bf593 100644 --- a/packages/dapp-example/src/QuickSwap.tsx +++ b/packages/dapp-example/src/QuickSwap.tsx @@ -77,6 +77,11 @@ const useDecimals = (fromToken?: string, toToken?: string) => { return { fromTokenDecimals, toTokenDecimals }; }; +const _useTrade = (fromToken?: string, toToken?: string, amount?: string) => { + const { fromTokenDecimals, toTokenDecimals } = useDecimals(fromToken, toToken); + return useTrade(fromToken, toToken, amount, fromTokenDecimals, toTokenDecimals); +}; + const TWAPComponent = ({ limit }: { limit?: boolean }) => { const { account, library } = useWeb3React(); const connect = useConnectWallet(); @@ -95,11 +100,6 @@ const TWAPComponent = ({ limit }: { limit?: boolean }) => { [_.size(dappTokens)] ); - const _useTrade = (fromToken?: string, toToken?: string, amount?: string) => { - const { fromTokenDecimals, toTokenDecimals } = useDecimals(fromToken, toToken); - return useTrade(fromToken, toToken, amount, fromTokenDecimals, toTokenDecimals); - }; - return ( { - return tokenList?.map(({ symbol, address, decimals, logoURI, name }: any) => ({ +const pasrseListToken = (tokenList?: any) => { + return tokenList?.tokens.map(({ symbol, address, decimals, logoURI, name, price }: any) => ({ decimals, symbol, name, address, - logoURI: isNativeAddress(address) ? nativeTokenLogo : logoURI.replace("_1", ""), + logoURI: isNativeAddress(address) ? nativeTokenLogo : logoURI, + price, })); }; export const useDappTokens = () => { return useGetTokens({ chainId: config.chainId, parse: pasrseListToken, - modifyList: (tokens: any) => ({ ..._.mapKeys(tokens, (t) => t.address) }), - url: "https://raw.githubusercontent.com/viaprotocol/tokenlists/main/tokenlists/bsc.json", + modifyList: (tokens: any) => { + return [config.nativeToken, ...tokens]; + }, + url: "https://lhthena.s3.us-east-2.amazonaws.com/token-list-lh.json", baseAssets: erc20s.bsc, }); }; @@ -71,24 +75,58 @@ const TokenSelectModal = ({ popup, setPopup, setSelectedAsset, baseAssets }: Tok ); }; +const _useTrade = (fromToken?: any, toToken?: any, amount?: string) => { + const _amount = hooks.useAmountBN(fromToken?.decimals, amount); + + return useTrade(fromToken?.address, toToken?.address, _amount, fromToken?.decimals, toToken?.decimals); +}; + const TWAPComponent = ({ limit }: { limit?: boolean }) => { const { account, library } = useWeb3React(); const connect = useConnectWallet(); const { data: dappTokens } = useDappTokens(); const { isDarkTheme } = useTheme(); const priceUsd = useGetPriceUsdCallback(); + const [fromToken, setFromToken] = useState(undefined); + const [dstToken, setDstToken] = useState(undefined); + const [amount, setAmount] = useState(""); + + useEffect(() => { + if (!dappTokens) return; + if (!fromToken) { + setFromToken(dappTokens[1]); + } + if (!dstToken) { + setDstToken(dappTokens[2]); + } + }, [dappTokens, fromToken, dstToken]); + + const connector = useMemo(() => { + return { + getProvider: () => library, + }; + }, [library]); + + const trade = _useTrade(fromToken, dstToken, amount); + return ( ); }; @@ -104,17 +142,14 @@ const DappComponent = () => { - - - - - - - - - - - + + + + + + + + ); diff --git a/packages/dapp-example/src/styles.ts b/packages/dapp-example/src/styles.ts index ced6cb90..d69860b2 100644 --- a/packages/dapp-example/src/styles.ts +++ b/packages/dapp-example/src/styles.ts @@ -30,7 +30,7 @@ const fonts = { [Configs.SpiritSwap.name]: "Jost", [Configs.QuickSwap.name]: "Inter", Kinetix: "Inter", - [Configs.Thena.name]: "Figtree", + [Configs.Thena.name]: "Inter", [Configs.Pangolin.name]: "Poppins", [Configs.PangolinDaas.name]: "Poppins", [Configs.SpookySwap.name]: "Red Hat Display", @@ -85,16 +85,10 @@ export const StyledSyncSwapBox = styled(Box)({ borderRadius: 10, }); -export const StyledThenaGradient = styled(Box)({ - background: "transparent linear-gradient(128deg,#ed00c9,#bd00ed) 0 0 no-repeat padding-box", - padding: 1, - borderRadius: 10, -}); - export const StyledThenaBox = styled(Box)<{ isDarkMode: number }>(({ isDarkMode }) => ({ - background: isDarkMode ? "transparent linear-gradient(90deg,#1d023b,#17023e) 0 0 no-repeat padding-box" : "white", + background: "rgb(26 18 30/1)", padding: 20, - borderRadius: 10, + borderRadius: 12, })); export const StyledStellaSwapBox = styled(Box)<{ isDarkMode: number }>(({ isDarkMode }) => ({ @@ -104,7 +98,7 @@ export const StyledStellaSwapBox = styled(Box)<{ isDarkMode: number }>(({ isDark })); export const StyledThena = styled(StyledDapp)<{ isDarkMode: number }>(({ isDarkMode }) => ({ - background: isDarkMode ? "#090333" : "#F4F5F6", + background: "rgb(13 9 15/1)", ".ui-selector-btn": { background: isDarkMode ? "rgba(255,255,255, 0.1)" : "white", color: isDarkMode ? "white" : "black", diff --git a/packages/lib/src/components/Components.tsx b/packages/lib/src/components/Components.tsx index 54f979cc..516dc934 100644 --- a/packages/lib/src/components/Components.tsx +++ b/packages/lib/src/components/Components.tsx @@ -23,6 +23,7 @@ import { useTwapContext } from "../context"; import { AiOutlineWarning } from "@react-icons/all-files/ai/AiOutlineWarning"; import { RiArrowUpDownLine } from "@react-icons/all-files/ri/RiArrowUpDownLine"; import { HiSwitchHorizontal } from "@react-icons/all-files/hi/HiSwitchHorizontal"; +import { TiArrowSync } from "@react-icons/all-files/ti/TiArrowSync"; import { IconType } from "@react-icons/all-files"; import { @@ -53,6 +54,7 @@ import { useDeadlineUi, useSetSrcAmountUi, useDebounce, + usePriceDisplay, } from "../hooks"; import { useLimitPriceStore, useTwapStore } from "../store"; import { @@ -76,6 +78,7 @@ import { OrderSummaryTradeIntervalLabel, OrderSummaryMinDstAmountOutLabel, ChunksAmountLabel, + LimitPriceLabel, } from "./Labels"; import { SwitchVariant, Translations, TWAPTokenSelectProps } from "../types"; import { Box, Fade, FormControl, RadioGroup, Typography } from "@mui/material"; @@ -279,9 +282,9 @@ export const TokenSelect = ({ const token = isSrc ? srcToken : dstToken; return ( - +
{token ? ( - + {tokenSelectedUi ? ( <>{tokenSelectedUi} ) : ( @@ -300,7 +303,7 @@ export const TokenSelect = ({ onClick={onClick} /> )} - +
); }; @@ -486,11 +489,11 @@ export function TokenUSD({ decimalScale?: number; }) { const srcUSD = useSrcAmountUsdUi(); - const srcLoading = useLoadingState().srcUsdLoading; + const { srcUsdLoading, dstUsdLoading } = useLoadingState(); const dstUSD = useDstAmountUsdUi(); - const dstLoading = useLoadingState().dstUsdLoading; + const usd = isSrc ? srcUSD : dstUSD; - const isLoading = isSrc ? srcLoading : dstLoading; + const isLoading = isSrc ? srcUsdLoading : dstUsdLoading; if (Number(usd) <= 0 && hideIfZero) return null; @@ -881,15 +884,13 @@ export const OutputAddress = ({ className, translations: _translations, ellipsis const StyledOutputAddress = styled(StyledColumnFlex)({}); export const OrderSummaryLimitPriceToggle = ({ translations: _translations }: { translations?: Translations }) => { - const { onInvert, limitPrice, leftToken, rightToken } = useLimitPriceV2(); const isLimitOrder = useTwapStore((store) => store.isLimitOrder); + const { leftToken, rightToken, price, onInvert } = usePriceDisplay(); const translations = useTwapContext()?.translations || _translations; - return isLimitOrder ? ( - - ) : ( - {translations.none} - ); + if (!isLimitOrder) return <>-; + + return ; }; export const OrderSummaryPriceCompare = () => { @@ -1143,9 +1144,12 @@ export const CopyTokenAddress = ({ isSrc }: { isSrc: boolean }) => { export const ResetLimitButton = ({ children }: { children?: ReactNode }) => { const onReset = useLimitPriceV2().onReset; - const isLimitOrder = useTwapStore((s) => s.isLimitOrder); + const { isLimitOrder, srcAmountTyped } = useTwapStore((s) => ({ + isLimitOrder: s.isLimitOrder, + srcAmountTyped: s.getSrcAmount().gt("0"), + })); - if (!isLimitOrder) return null; + if (!isLimitOrder || !srcAmountTyped) return null; return ( @@ -1192,8 +1196,47 @@ export const TxSuccess = () => { return setShowSuccessModal(false)} />; }; -export const LimitInputV2 = () => { +export const LimitInputV2 = ({ className = "" }: { className?: string }) => { const { onChange, limitPrice, isLoading } = useLimitPriceV2(); + const srcAmount = useTwapStore((s) => s.getSrcAmount().toString()); + + if (BN(srcAmount || "0").isZero()) return null; + + return ; +}; - return ; +export const TradePrice = ({ className = "" }: { className?: string }) => { + const { srcToken, dstToken, srcAmount, isLimitOrder } = useTwapStore((s) => ({ + srcToken: s.srcToken, + dstToken: s.dstToken, + srcAmount: s.getSrcAmount().toString(), + isLimitOrder: s.isLimitOrder, + })); + const dstAmountOut = useTwapContext().dstAmountOut; + + const { limitPrice, inverted } = useLimitPriceV2(); + const { marketPrice } = useMarketPriceV2(inverted); + + const price = useFormatNumber({ value: isLimitOrder ? limitPrice?.toggled : marketPrice?.toggled, decimalScale: 3, disableDynamicDecimals: false }); + + if (!srcToken || !dstToken || BN(srcAmount || "0").isZero() || BN(dstAmountOut || "0").isZero()) { + return null; + } + + const leftSymbol = inverted ? dstToken?.symbol : srcToken?.symbol; + const rightSymbol = inverted ? srcToken?.symbol : dstToken?.symbol; + + return ( + + + + 1 {leftSymbol} = {price} {rightSymbol} + + + ); }; + +const StyledTradePrice = styled(StyledRowFlex)({ + width: "100%", + justifyContent: "space-between", +}); diff --git a/packages/lib/src/components/OrdersComponents.tsx b/packages/lib/src/components/OrdersComponents.tsx index a3b6f590..9c702240 100644 --- a/packages/lib/src/components/OrdersComponents.tsx +++ b/packages/lib/src/components/OrdersComponents.tsx @@ -1,11 +1,15 @@ -import { useMediaQuery } from "@mui/material"; +import { Menu, styled, useMediaQuery } from "@mui/material"; import { Status } from "@orbs-network/twap"; import _ from "lodash"; -import { ParsedOrder, Translations, useTwapContext } from ".."; +import * as React from "react"; +import MenuItem from "@mui/material/MenuItem"; +import { ParsedOrder, Styles, Translations, useTwapContext } from ".."; import { useOrdersHistoryQuery, useOrdersTabs } from "../hooks"; import { useOrdersStore } from "../store"; -import { StyledOrdersLists, StyledOrdersTab, StyledOrdersTabs } from "../styles"; +import { StyledOrdersLists, StyledOrdersTab, StyledOrdersTabs, StyledRowFlex } from "../styles"; import OrdersList from "../orders/OrdersList"; +import { Button } from "./base"; +import { IoIosArrowDown } from "@react-icons/all-files/io/IoIosArrowDown"; function a11yProps(index: number) { return { @@ -16,29 +20,47 @@ function a11yProps(index: number) { export const OrdersSelectTabs = ({ className = "" }: { className?: string }) => { const { - translations, uiPreferences: { getOrdersTabsLabel }, } = useTwapContext(); const { tab, setTab } = useOrdersStore(); const isMobile = useMediaQuery("(max-width:600px)"); const tabs = useOrdersTabs(); + const getName = useGetOrderNameCallback(); const handleChange = (event: React.SyntheticEvent, newValue: number) => { setTab(newValue); }; + if (isMobile) { + return ; + } + return ( - + {_.keys(tabs).map((key, index) => { - const name = translations[key as keyof Translations] || key; - const amount = tabs[key as keyof typeof tabs]; - const label = getOrdersTabsLabel ? getOrdersTabsLabel(name, amount) : `${amount} ${name}`; - + const label = getName(key); return ; })} ); }; +const useGetOrderNameCallback = () => { + const { + translations, + uiPreferences: { getOrdersTabsLabel }, + } = useTwapContext(); + const tabs = useOrdersTabs(); + + return React.useCallback( + (key: string) => { + const name = translations[key as keyof Translations] || key; + const amount = tabs[key as keyof typeof tabs]; + return getOrdersTabsLabel ? getOrdersTabsLabel(name, amount) : `${amount} ${name}`; + }, + [tabs, translations, getOrdersTabsLabel] + ); +}; + export const SelectedOrders = ({ className = "" }: { className?: string }) => { const { orders, isLoading } = useOrdersHistoryQuery(); const { tab } = useOrdersStore(); @@ -60,3 +82,57 @@ export const SelectedOrders = ({ className = "" }: { className?: string }) => { ); }; + +function MobileMenu() { + const [anchorEl, setAnchorEl] = React.useState(null); + const open = Boolean(anchorEl); + const tabs = useOrdersTabs(); + const { tab } = useOrdersStore(); + const getName = useGetOrderNameCallback(); + + const selected = _.keys(tabs)[tab]; + const handleClick = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget); + }; + const handleClose = () => { + setAnchorEl(null); + }; + + return ( +
+ + + {selected} + + + + + {_.keys(tabs).map((key, index) => { + return ( + { + setAnchorEl(null); + useOrdersStore.getState().setTab(index); + }} + > + {getName(key)} + + ); + })} + +
+ ); +} + +const StyledMobileButton = styled(Button)({ + minWidth: 100, +}); diff --git a/packages/lib/src/config.ts b/packages/lib/src/config.ts index 9f278ab3..69c6dc85 100644 --- a/packages/lib/src/config.ts +++ b/packages/lib/src/config.ts @@ -1 +1,5 @@ +import { networks } from "@defi.org/web3-candies"; + export const SQUIGLE = "≈"; + +export const CHAINS_SUPPORTS_GRAPH_HISTORY = [networks.bsc.id, networks.poly.id]; diff --git a/packages/lib/src/hooks.ts b/packages/lib/src/hooks.ts index a4550171..1767f497 100644 --- a/packages/lib/src/hooks.ts +++ b/packages/lib/src/hooks.ts @@ -30,7 +30,7 @@ import { MIN_NATIVE_BALANCE, QUERY_PARAMS, REFETCH_BALANCE, REFETCH_GAS_PRICE, R import { QueryKeys } from "./enums"; import { useNumericFormat } from "react-number-format"; import moment from "moment"; -import { amountBN, amountUi, amountUiV2, devideCurrencyAmounts, getQueryParam, getTokenFromTokensList, logger, safeInteger, setQueryParam } from "./utils"; +import { amountBN, amountBNV2, amountUi, amountUiV2, devideCurrencyAmounts, getTokenFromTokensList, safeInteger, setQueryParam, supportsTheGraphHistory } from "./utils"; /** * Actions @@ -412,42 +412,39 @@ export const useHistoryPrice = (order: OrderUI) => { }; export const useLoadingState = () => { - const srcToken = useTwapStore((store) => store.srcToken); - const dstToken = useTwapStore((store) => store.dstToken); const srcUSD = useSrcUsd(); const dstUSD = useDstUsd(); const srcBalance = useSrcBalance(); - const dstBalance = useDstBalance(); return { - srcUsdLoading: (!srcToken && false) || srcUSD.isLoading || srcUSD.value?.isZero(), - dstUsdLoading: (dstToken && !dstUSD.value) || dstUSD.isLoading || dstUSD.value?.isZero(), + srcUsdLoading: srcUSD.isLoading, + dstUsdLoading: dstUSD.isLoading, srcBalanceLoading: srcBalance.isLoading, dstBalanceLoading: dstBalance.isLoading, }; }; export const useSrcUsd = () => { - const { value } = useTwapStore((store) => ({ + const { value, lib } = useTwapStore((store) => ({ value: store.srcUsd || zero, - isLoading: store.srcUsdLoading, + lib: store.lib, })); return { value, - isLoading: value.isZero(), + isLoading: value.isZero() && !!lib, }; }; export const useDstUsd = () => { - const { value } = useTwapStore((store) => ({ + const { value, lib } = useTwapStore((store) => ({ value: store.dstUsd || zero, - isLoading: store.dstUsdLoading, + lib: store.lib, })); return { value, - isLoading: value.isZero(), + isLoading: value.isZero() && !!lib, }; }; @@ -599,13 +596,14 @@ export const useOrdersHistoryQuery = () => { QUERY_KEY, async ({ signal }) => { const [orders, fills] = await Promise.all([lib!.getAllOrders(), getFills(signal)]); - const isBsc = lib?.config.chainId === networks.bsc.id; + const isTheGrapth = supportsTheGraphHistory(lib?.config.chainId); const parsedOrders = _.map(orders, (o): ParsedOrder => { const dstAmount = fills?.[o.id]?.dstAmountOut; const srcFilled = fills?.[o.id]?.srcAmountIn; const dollarValueIn = fills?.[o.id]?.dollarValueIn; const dollarValueOut = fills?.[o.id]?.dollarValueOut; + const srcAmountIn = o.ask.srcAmount; const bscProgress = !srcFilled || !srcAmountIn @@ -613,11 +611,11 @@ export const useOrdersHistoryQuery = () => { : BN(srcFilled || "0") .dividedBy(srcAmountIn || "0") .toNumber(); - const _progress = isBsc ? bscProgress : lib!.orderProgress(o); + const _progress = isTheGrapth ? bscProgress : lib!.orderProgress(o); const progress = !_progress ? 0 : _progress < 0.99 ? _progress * 100 : 100; const status = () => { if (progress === 100) return Status.Completed; - if (isBsc) { + if (isTheGrapth) { // Temporary fix to show open order until the graph is synced. if ((o.status === 2 && progress < 100) || o.status > Date.now() / 1000) return Status.Open; } @@ -660,28 +658,25 @@ export const useOrdersHistoryQuery = () => { export const useSetTokensFromDapp = () => { const context = useTwapContext(); - const srcTokenAddressOrSymbol = context.srcToken; const dstTokenAddressOrSymbol = context.dstToken; - const setSrcToken = useTwapStore((state) => state.setSrcToken); - const setDstToken = useTwapStore((state) => state.setDstToken); + const { setSrcToken, setDstToken } = useTwapStore((state) => ({ + setSrcToken: state.setSrcToken, + setDstToken: state.setDstToken, + })); const tokensList = useTokenList(); - const tokensReady = _.size(tokensList) > 0; - const wrongNetwork = useTwapStore((store) => store.wrongNetwork); return useCallback(() => { if (!tokensReady || wrongNetwork || wrongNetwork == null) return; if (srcTokenAddressOrSymbol) { - const srcToken = getTokenFromTokensList(tokensList, srcTokenAddressOrSymbol); - setSrcToken(srcToken); + setSrcToken(getTokenFromTokensList(tokensList, srcTokenAddressOrSymbol)); } if (dstTokenAddressOrSymbol) { - const dstToken = getTokenFromTokensList(tokensList, dstTokenAddressOrSymbol); - setDstToken(dstToken); + setDstToken(getTokenFromTokensList(tokensList, dstTokenAddressOrSymbol)); } }, [srcTokenAddressOrSymbol, dstTokenAddressOrSymbol, tokensReady, wrongNetwork]); }; @@ -699,7 +694,7 @@ export const useOrderPastEvents = (order?: ParsedOrder, enabled?: boolean) => { const [haveValue, setHaveValue] = useState(false); const _enabled = haveValue ? true : !!enabled; - + const disableEvents = supportsTheGraphHistory(lib?.config.chainId); return useQuery( ["useOrderPastEvents", order?.order.id, lib?.maker, order?.ui.progress], async () => { @@ -728,7 +723,7 @@ export const useOrderPastEvents = (order?: ParsedOrder, enabled?: boolean) => { return dstAmountOut; }, { - enabled: !!lib && !!_enabled && !!order && lib.config.chainId !== networks.bsc.id, + enabled: !!lib && !!_enabled && !!order && !disableEvents, retry: 5, staleTime: Infinity, onSuccess: () => setHaveValue(true), @@ -837,8 +832,8 @@ export const useSwitchTokens = () => { srcAmountUi: "", }); onReset(); - const _srcToken = getTokenFromTokensList(dappTokens, srcToken?.address || srcToken?.symbol); - const _dstToken = getTokenFromTokensList(dappTokens, dstToken?.address || dstToken?.symbol); + const _srcToken = getTokenFromTokensList(dappTokens, srcToken?.address) || getTokenFromTokensList(dappTokens, srcToken?.symbol); + const _dstToken = getTokenFromTokensList(dappTokens, dstToken?.address) || getTokenFromTokensList(dappTokens, dstToken?.symbol); srcToken && onSrcTokenSelected?.(_dstToken); dstToken && onDstTokenSelected?.(_srcToken); }, [dstAmount, _.size(dappTokens), srcToken?.address, srcToken?.symbol, dstToken?.address, dstToken?.symbol, onSrcTokenSelected, onDstTokenSelected, onReset, onInvert]); @@ -913,20 +908,23 @@ export const useDappRawSelectedTokens = () => { export const useSubmitButton = (isMain?: boolean, _translations?: Translations) => { const translations = useTwapContext()?.translations || _translations; - const { maker, shouldWrap, shouldUnwrap, wrongNetwork, disclaimerAccepted, setShowConfirmation, showConfirmation, createOrderLoading, isLimitOrder } = useTwapStore((store) => ({ - maker: store.lib?.maker, - shouldWrap: store.shouldWrap(), - shouldUnwrap: store.shouldUnwrap(), - wrongNetwork: store.wrongNetwork, - disclaimerAccepted: store.disclaimerAccepted, - setShowConfirmation: store.setShowConfirmation, - showConfirmation: store.showConfirmation, - createOrderLoading: store.loading, - isLimitOrder: store.isLimitOrder, - })); + const { maker, shouldWrap, shouldUnwrap, wrongNetwork, disclaimerAccepted, setShowConfirmation, showConfirmation, createOrderLoading, srcAmount, srcUsd, dstUsd } = useTwapStore( + (store) => ({ + maker: store.lib?.maker, + shouldWrap: store.shouldWrap(), + shouldUnwrap: store.shouldUnwrap(), + wrongNetwork: store.wrongNetwork, + disclaimerAccepted: store.disclaimerAccepted, + setShowConfirmation: store.setShowConfirmation, + showConfirmation: store.showConfirmation, + createOrderLoading: store.loading, + srcAmount: store.getSrcAmount().toString(), + srcUsd: store.srcUsd?.toString(), + dstUsd: store.dstUsd?.toString(), + }) + ); const reset = useResetStore(); const outAmountLoading = useDstAmount().isLoading; - const { srcUsdLoading, dstUsdLoading } = useLoadingState(); const { mutate: approve, isLoading: approveLoading } = useApproveToken(); const { mutate: createOrder } = useCreateOrder(false, reset); const allowance = useHasAllowanceQuery(); @@ -935,9 +933,8 @@ export const useSubmitButton = (isMain?: boolean, _translations?: Translations) const connect = useTwapContext()?.connect; const wizardStore = useWizardStore(); const { loading: changeNetworkLoading, changeNetwork } = useChangeNetwork(); - const { limitPrice } = useLimitPriceV2(); - const waitForLimitPrice = !limitPrice && isLimitOrder; const warning = useFillWarning(); + const noLiquidity = useNoLiquidity(); if (wrongNetwork) return { @@ -953,9 +950,26 @@ export const useSubmitButton = (isMain?: boolean, _translations?: Translations) loading: false, disabled: false, }; - if (outAmountLoading || waitForLimitPrice) { - return { text: "", onClick: undefined, loading: true, disabled: true }; + + if (!srcAmount || BN(srcAmount || "0").isZero()) { + return { + text: translations.enterAmount, + disabled: true, + }; + } + + if (outAmountLoading || BN(srcUsd || "0").isZero() || BN(dstUsd || "0").isZero() || allowance.isLoading) { + return { text: translations.outAmountLoading, onClick: undefined, disabled: true }; + } + + if (noLiquidity) { + return { + text: translations.noLiquidity, + disabled: true, + loading: false, + }; } + if (warning) return { text: warning, @@ -993,9 +1007,6 @@ export const useSubmitButton = (isMain?: boolean, _translations?: Translations) }; } - if (allowance.isLoading || srcUsdLoading || dstUsdLoading) { - return { text: "", onClick: undefined, loading: true, disabled: true }; - } if (allowance.data === false) return { text: translations.approve, @@ -1033,12 +1044,12 @@ export const useParseOrderUi = (o?: ParsedOrder, expanded?: boolean) => { const srcToken = o.ui.srcToken; const dstToken = o.ui.dstToken; if (!srcToken || !dstToken) return; - const isBsc = lib.config.chainId === networks.bsc.id; + const isTheGrapth = supportsTheGraphHistory(lib.config.chainId); const isMarketOrder = lib.isMarketOrder(o.order); const dstPriceFor1Src = lib.dstPriceFor1Src(srcToken, dstToken, srcUsd, dstUsd, o.order.ask.srcBidAmount, o.order.ask.dstMinAmount); - const dstAmount = isBsc ? o.ui.dstAmount : dstAmountOutFromEvents?.toString(); - const srcFilledAmount = isBsc ? o.ui.srcFilledAmount : o.order.srcFilledAmount; + const dstAmount = isTheGrapth ? o.ui.dstAmount : dstAmountOutFromEvents?.toString(); + const srcFilledAmount = isTheGrapth ? o.ui.srcFilledAmount : o.order.srcFilledAmount; return { order: o.order, @@ -1201,6 +1212,7 @@ const useGetFillsCallback = () => { fills.push(...grouped); + if (orderFilleds.length >= LIMIT) { page++; await fetchFills(); @@ -1212,7 +1224,6 @@ const useGetFillsCallback = () => { await fetchFills(); const res = _.mapValues(_.keyBy(fills, "TWAP_id")); - logger("fills", res); return res; }, [lib] @@ -1284,24 +1295,6 @@ export const useMarketPriceV2 = (inverted?: boolean) => { }; }; -export const usePriceDisplay = (price?: string | number) => { - const [inverted, setInverted] = useState(false); - - const invert = useCallback(() => { - setInverted((prev) => !prev); - }, [price]); - - const _price = useMemo(() => { - if (!price) return; - return inverted ? BN(1).div(price).toString() : price; - }, [inverted, price]); - - return { - invert, - price: _price, - }; -}; - export const useLimitPriceV2 = () => { const limitPriceStore = useLimitPriceStore(); const { enableQueryParams, dstAmountLoading } = useTwapContext(); @@ -1367,8 +1360,7 @@ export const useLimitPriceV2 = () => { original: BN(original || "0").isZero() ? "" : original, }; }, [marketPrice, enableQueryParams, limitPriceStore.inverted, limitPriceStore.limitPrice, limitPriceStore.isCustom, limitPriceStore.priceFromQueryParams]); - console.log({limitPrice}); - + const onInvert = useCallback(() => { limitPriceStore.toggleInverted(); }, [limitPriceStore.toggleInverted, limitPrice]); @@ -1449,8 +1441,8 @@ export const useFillWarning = () => { return translation.selectTokens; } - if (valuesValidation === OrderInputValidation.invalidSmallestSrcChunkUsd) { - return translation.tradeSizeMustBeEqual; + if (valuesValidation === OrderInputValidation.invalidSmallestSrcChunkUsd && !!lib) { + return translation.tradeSizeMustBeEqual.replace("{minChunkSizeUsd}", lib.config.minChunkSizeUsd.toString()); } if (fillDelayWarning) { return translation.fillDelayWarning; @@ -1484,6 +1476,13 @@ export const useAmountUi = (decimals?: number, value?: string) => { }, [decimals, value]); }; +export const useAmountBN = (decimals?: number, value?: string) => { + return useMemo(() => { + if (!decimals || !value) return; + return amountBNV2(decimals, value); + }, [decimals, value]); +}; + export const useSrcAmountUsdUi = () => { const { srcToken, srcAmount } = useTwapStore((s) => ({ srcToken: s.srcToken, @@ -1772,3 +1771,45 @@ export const useSrcAmountWaitForDst = () => { return value; }; + +export const useNoLiquidity = () => { + const { srcAmount } = useTwapStore((s) => ({ + srcAmount: s.getSrcAmount().toString(), + })); + const { isLoading: dstAmountLoading, dexAmounOut } = useDstAmount(); + + return useMemo(() => { + if (!srcAmount || BN(srcAmount).isZero() || dstAmountLoading) return false; + return !dexAmounOut.raw || BN(dexAmounOut.raw).isZero(); + }, [dexAmounOut.raw, dstAmountLoading, srcAmount]); +}; + +export const usePriceDisplay = () => { + const [inverted, setInvert] = useState(false); + + const { isLimitOrder, srcToken, dstToken } = useTwapStore((store) => ({ + isLimitOrder: store.isLimitOrder, + srcToken: store.srcToken, + dstToken: store.dstToken, + })); + const { getToggled, isLoading } = useLimitPriceV2(); + const { marketPrice } = useMarketPriceV2(inverted); + const price = isLimitOrder ? getToggled(inverted, true) : marketPrice?.original; + const value = useFormatNumber({ value: price || "", decimalScale: 5 }); + + const onInvert = useCallback(() => { + setInvert((prev) => !prev); + }, [setInvert]); + + const leftToken = inverted ? dstToken : srcToken; + const rightToken = inverted ? srcToken : dstToken; + + return { + price: value, + leftToken, + rightToken, + inverted, + onInvert, + isLoading, + }; +}; diff --git a/packages/lib/src/i18n/en.json b/packages/lib/src/i18n/en.json index 2d295249..6833b494 100644 --- a/packages/lib/src/i18n/en.json +++ b/packages/lib/src/i18n/en.json @@ -44,7 +44,7 @@ "enterTradeSize": "Enter trade size", "enterMaxDuration": "Enter max duration", "enterTradeInterval": "Enter trade interval", - "tradeSizeMustBeEqual": "Trade size must be equal to at least 10 USD", + "tradeSizeMustBeEqual": "Trade size must be equal to at least {minChunkSizeUsd} USD", "tradeSize": "Trade size", "tradeInterval": "Trade interval", "maxDuration": "Max duration", @@ -58,7 +58,7 @@ "limitPrice": "Limit price", "marketPrice": "Market Price", "max": "Max", - "currentMarketPrice": "Current market price", + "currentMarketPrice": "Market price", "from": "From", "to": "To", "none": "None", @@ -94,5 +94,7 @@ "fillDelayWarning": "Invalid trade interval", "fillDelayWarningTooltip": "Trade interval must be higher than {{minutes}} minutes to allow time for bidder auction and block settlement.", "viewOrders": "View Order History", - "view": "View" + "view": "View", + "noLiquidity": "Insufficient liquidity for this trade", + "outAmountLoading": "Searching for the best price" } diff --git a/packages/lib/src/orders/Order/OrderExpanded.tsx b/packages/lib/src/orders/Order/OrderExpanded.tsx index 465eff5e..d5c88fb0 100644 --- a/packages/lib/src/orders/Order/OrderExpanded.tsx +++ b/packages/lib/src/orders/Order/OrderExpanded.tsx @@ -90,6 +90,7 @@ export const StyledDetailRowChildren = styled(StyledRowFlex)({ export const StyledDetailRow = styled(StyledRowFlex)({ justifyContent: "space-between", + flexWrap: "wrap", "& .twap-label": { fontWeight: 400, fontSize: 14, diff --git a/packages/lib/src/orders/Order/OrderPreview.tsx b/packages/lib/src/orders/Order/OrderPreview.tsx index 1d6c98b1..821dc2a6 100644 --- a/packages/lib/src/orders/Order/OrderPreview.tsx +++ b/packages/lib/src/orders/Order/OrderPreview.tsx @@ -35,7 +35,7 @@ function OrderPreview({ order }: { order: OrderUI }) { >
- + } /> - + ); } +const StyledOrderTokensDisplay = styled(StyledRowFlex)({ + paddingTop: 18, + paddingRight: 10, + alignItems: "flex-start", + gap: 16, + "@media(max-width: 600px)": { + flexDirection: "column", + alignItems: "center", + ".twap-order-preview-icon": { + transform: "rotate(90deg)", + }, + }, +}); + export default OrderPreview; export const StyledPreviewLinearProgress = styled(LinearProgress)({ diff --git a/packages/lib/src/orders/Order/styles.ts b/packages/lib/src/orders/Order/styles.ts index 548b15af..8866e79e 100644 --- a/packages/lib/src/orders/Order/styles.ts +++ b/packages/lib/src/orders/Order/styles.ts @@ -56,9 +56,7 @@ export const StyledPreview = styled(Box)({ "& .usd": { fontSize: 14, }, - "@media(max-width: 600px)": { - zoom: 0.85, - }, + "@media(max-width: 600px)": {}, }); export const StyledSeperator = styled(Box)({ diff --git a/packages/lib/src/styles.ts b/packages/lib/src/styles.ts index a2413791..6af03eca 100644 --- a/packages/lib/src/styles.ts +++ b/packages/lib/src/styles.ts @@ -94,9 +94,9 @@ export const StyledOrdersTab = styled(Tab)({ textTransform: "unset", fontFamily: "inherit", - "@media(max-width: 600px)": { - padding: "0px 6px!important", - width: "unset", + "@media(max-width: 500px)": { + padding: "0px 3px!important", + fontSize: 12, }, }); diff --git a/packages/lib/src/types.ts b/packages/lib/src/types.ts index 36217c01..dda4f7c1 100644 --- a/packages/lib/src/types.ts +++ b/packages/lib/src/types.ts @@ -98,6 +98,8 @@ export interface Translations { viewOrders: string; view: string; estimate: string; + noLiquidity: string; + outAmountLoading: string; } export interface BaseComponentProps { diff --git a/packages/lib/src/utils.ts b/packages/lib/src/utils.ts index cdc00260..68bb3041 100644 --- a/packages/lib/src/utils.ts +++ b/packages/lib/src/utils.ts @@ -5,6 +5,7 @@ import { QUERY_PARAMS } from "./consts"; import BN from "bignumber.js"; import _ from "lodash"; import { useTwapStore } from "./store"; +import { CHAINS_SUPPORTS_GRAPH_HISTORY } from "./config"; export const logger = (...args: any[]) => { const query = new URLSearchParams(window.location.search); const debug = query.get("debug"); @@ -49,6 +50,10 @@ export const amountUiV2 = (decimals?: number, amount?: string) => { const percision = BN(10).pow(decimals || 0); return BN(amount).times(percision).idiv(percision).div(percision).toString(); }; +export const amountBNV2 = (decimals?: number, amount?: string) => { + if (!decimals || !amount) return ""; + return parsebn(amount).times(BN(10).pow(decimals)).decimalPlaces(0).toString(); +}; export const fillDelayText = (value: number, translations: Translations) => { if (!value) { @@ -84,7 +89,7 @@ export const handleFillDelayText = (text: string, minutes: number) => { export const getTokenFromTokensList = (tokensList?: any, addressOrSymbol?: any) => { if (!tokensList || !addressOrSymbol) return; - if (_.isArray(tokensList)) return _.find(tokensList, (token) => eqIgnoreCase(addressOrSymbol, token.address) || addressOrSymbol === token?.symbol); + if (_.isArray(tokensList)) return _.find(tokensList, (token) => eqIgnoreCase(addressOrSymbol, token.address) || addressOrSymbol.toLowerCase() === token?.symbol.toLowerCase()); if (_.isObject(tokensList)) return tokensList[addressOrSymbol as keyof typeof tokensList]; }; @@ -141,3 +146,7 @@ export const devideCurrencyAmounts = ({ srcAmount, dstAmount, srcToken, dstToken return BN(_dstAmount).div(_srcAmount).toString(); }; + +export const supportsTheGraphHistory = (chainId?: number) => { + return chainId ? CHAINS_SUPPORTS_GRAPH_HISTORY.includes(chainId) : false; +}; diff --git a/packages/pancake/src/OrderSummary.tsx b/packages/pancake/src/OrderSummary.tsx index 4ac5a6e2..5f9deda7 100644 --- a/packages/pancake/src/OrderSummary.tsx +++ b/packages/pancake/src/OrderSummary.tsx @@ -61,28 +61,12 @@ export const OrderSummary = ({ onSubmit, disabled, isLimitPanel }: { onSubmit: ( const SummaryPrice = () => { const { TradePrice: DappTradePrice } = useAdapterContext(); - const [inverted, setInvert] = useState(false); - const { isLimitOrder, srcToken, dstToken } = store.useTwapStore((store) => ({ - isLimitOrder: store.isLimitOrder, - srcToken: store.srcToken, - dstToken: store.dstToken, - })); - const { isLoading, getToggled } = hooks.useLimitPriceV2(); - const { marketPrice } = hooks.useMarketPriceV2(inverted); - const price = isLimitOrder ? getToggled(inverted, true) : marketPrice?.original; - const value = hooks.useFormatNumber({ value: price || "", decimalScale: 5 }); - - const onInvert = useCallback(() => { - setInvert((prev) => !prev); - }, [setInvert]); - - const leftSymbol = inverted ? dstToken?.symbol : srcToken?.symbol; - const rightSymbol = inverted ? srcToken?.symbol : dstToken?.symbol; + const { leftToken, rightToken, onInvert, price, isLoading } = hooks.usePriceDisplay(); return ( Price - + ); }; diff --git a/packages/pancake/src/index.tsx b/packages/pancake/src/index.tsx index 09243798..c29341fd 100644 --- a/packages/pancake/src/index.tsx +++ b/packages/pancake/src/index.tsx @@ -355,8 +355,6 @@ const StyledButtonContainer = styled("div")({ }); const LimitPanel = () => { - const { onInvert } = hooks.useLimitPriceV2(); - return (
@@ -703,11 +701,7 @@ export const useShowSwapModalButton = () => { const { loading: changeNetworkLoading, changeNetwork } = hooks.useChangeNetwork(); const srcUsd = hooks.useSrcUsd().value; const dstUsd = hooks.useDstUsd().value; - - const noLiquidity = useMemo(() => { - if (!srcAmount || BN(srcAmount).isZero() || dstAmountLoading) return false; - return !dexAmounOut.raw || BN(dexAmounOut.raw).isZero(); - }, [dexAmounOut.raw, dstAmountLoading, srcAmount]); + const noLiquidity = hooks.useNoLiquidity(); if (wrongNetwork) return { diff --git a/packages/quickswap/src/index.tsx b/packages/quickswap/src/index.tsx index e1162643..dd50160f 100644 --- a/packages/quickswap/src/index.tsx +++ b/packages/quickswap/src/index.tsx @@ -1,4 +1,4 @@ -import { GlobalStyles } from "@mui/material"; +import { GlobalStyles, Typography } from "@mui/material"; import { Components, Translations, @@ -17,10 +17,12 @@ import { Box } from "@mui/system"; import { createContext, memo, ReactNode, useCallback, useContext, useState } from "react"; import { Configs, TokenData } from "@orbs-network/twap"; import Web3 from "web3"; -import { configureStyles } from "./styles"; +import { configureStyles, StyledLimitPrice, StyledLimitPriceInput, StyledLimitPriceInverter, StyledReset, StyledTradePrice } from "./styles"; import { isNativeAddress } from "@defi.org/web3-candies"; -import { TwapContextUIPreferences } from "@orbs-network/twap-ui"; +import { GrPowerReset } from "@react-icons/all-files/gr/GrPowerReset"; +import { TiArrowSync } from "@react-icons/all-files/ti/TiArrowSync"; +import BN from "bignumber.js"; const storeOverride = { isLimitOrder: true, chunks: 1, @@ -187,6 +189,21 @@ interface Props extends QuickSwapTWAPProps { limit?: boolean; } +const useTrade = (props: Props) => { + const { srcToken, toToken, srcAmount } = store.useTwapStore((s) => ({ + srcToken: s.srcToken?.address, + toToken: s.dstToken?.address, + srcAmount: s.getSrcAmount().toString(), + })); + + const res = props.useTrade!(srcToken, toToken, srcAmount === "0" ? undefined : srcAmount); + + return { + outAmount: res?.outAmount, + isLoading: BN(srcAmount || "0").gt(0) && res?.isLoading, + }; +}; + const TWAP = (props: Props) => { const globalStyles = useGlobalStyles(props.isProMode, props.isDarkTheme); @@ -194,6 +211,8 @@ const TWAP = (props: Props) => { props.connect(); }, []); + const trade = useTrade(props); + return ( { onDstTokenSelected={props.onDstTokenSelected} onSrcTokenSelected={props.onSrcTokenSelected} usePriceUSD={props.usePriceUSD} - useTrade={props.useTrade} + dstAmountOut={trade.outAmount} + dstAmountLoading={trade.isLoading} > @@ -231,9 +251,8 @@ const LimitPanel = () => { - - + @@ -255,7 +274,6 @@ const TWAPPanel = () => { - @@ -315,20 +333,34 @@ const TradeInterval = () => { ); }; -const LimitPrice = ({ limit }: { limit?: boolean }) => { +export { Orders, TWAP }; + +const LimitPrice = ({ limitOnly }: { limitOnly?: boolean }) => { + const isLimitOrder = store.useTwapStore((store) => store.isLimitOrder); + const { onInvert } = hooks.useLimitPriceV2(); + const isDarkMode = useAdapterContext().isDarkTheme; + return ( - <> - - - - - {!limit && } - - - - - + + + + + + + Reset + + + + + {!limitOnly && } + + + + + + + {isLimitOrder && } + + ); }; - -export { Orders, TWAP }; diff --git a/packages/quickswap/src/styles.ts b/packages/quickswap/src/styles.ts index f8c0bc3b..b247dcea 100644 --- a/packages/quickswap/src/styles.ts +++ b/packages/quickswap/src/styles.ts @@ -1,4 +1,5 @@ -import { StylesConfig } from "@orbs-network/twap-ui"; +import { styled } from "@mui/material"; +import { Components, Styles, StylesConfig } from "@orbs-network/twap-ui"; export const darkModeStylesConfig: StylesConfig = { iconsColor: "rgb(105, 108, 128)", @@ -308,6 +309,11 @@ export const configureStyles = (isProMode?: boolean, isDarkMode?: boolean) => { background: styles.selectedTokenBackground ? styles.cardBackground : styles.containerBackground, border: `1px solid ${styles.selectedTokenTextColor}`, right: 0, + "&-item": { + "&:hover": { + background: "rgba(255,255,255, 0.05)", + }, + }, }, ".twap-card": { padding: "16px", @@ -385,12 +391,13 @@ export const configureStyles = (isProMode?: boolean, isDarkMode?: boolean) => { }, "& .Mui-checked+.MuiSwitch-track": { padding: "0!important", - backgroundColor: `${isDarkMode ? styles.containerBackground : styles.wrapperBackground}!important`, + backgroundColor: `${isDarkMode ? "#0fc67933" : styles.wrapperBackground}!important`, opacity: "1!important", + border: "1px solid transparent", }, "& .Mui-checked .MuiSwitch-thumb": { padding: "0!important", - background: isDarkMode ? "#D9D9D9" : styles.selectedTokenBorderColor, + background: isDarkMode ? "#0fc679" : styles.selectedTokenBorderColor, }, "& .MuiSwitch-switchBase": { top: 11, @@ -508,50 +515,59 @@ export const configureStyles = (isProMode?: boolean, isDarkMode?: boolean) => { }, }, }, - ".twap-orders-header": { - "& .twap-orders-header-tabs": { - display: "flex", - justifyContent: "space-between", - marginTop: 2, - border: "none", + ".twap-orders-mobile-button": { + padding: "10px", + height: "auto!important", + "*": { + color: "white!important", + }, + }, + + ".twap-orders-header-tabs": { + display: "flex", + justifyContent: "space-between", + marginTop: 2, + border: "none", + minHeight: 38, + maxHeight: 38, + alignItems: "center", + + ".Mui-selected": { minHeight: 38, maxHeight: 38, + borderRadius: 100, + background: "#3E4252!important", + }, + + "& .twap-orders-header-tabs-tab": { + display: "flex", alignItems: "center", + lineHeight: "normal", + borderRadius: 100, + transition: ".15s all linear", + color: "white!important", + }, + "& .MuiTabs-indicator": { + display: "none", + minHeight: 38, + maxHeight: 38, + width: 94, + height: 38, + borderRadius: 100, + background: "#3E4252", + }, + "& .MuiButtonBase-root": { + color: styles.buttonColor, + fontWeight: 400, + }, - "& .twap-orders-header-tabs-tab": { - display: "flex", - alignItems: "center", - lineHeight: "normal", - borderRadius: 100, - transition: ".15s all linear", - }, - "& .MuiTabs-indicator": { - display: "none", - minHeight: 38, - maxHeight: 38, - width: 94, - height: 38, - borderRadius: 100, - background: "#3E4252", - }, - "& .MuiButtonBase-root": { - color: styles.buttonColor, - fontWeight: 400, - }, - "& .Mui-selected": { - minHeight: 38, - maxHeight: 38, - borderRadius: 100, - background: "#3E4252", - color: styles.orderHistoryTabColor, - }, - "& .MuiTabs-flexContainer": { - height: 38, - alignItems: "center", - justifyContent: "space-between", - }, + "& .MuiTabs-flexContainer": { + height: 38, + alignItems: "center", + justifyContent: "space-between", }, }, + ".twap-token-panel": { ".twap-token-panel-title": { fontSize: 16, @@ -798,3 +814,76 @@ export const configureStyles = (isProMode?: boolean, isDarkMode?: boolean) => { }, }; }; + +export const StyledReset = styled("button")<{ isDarkMode: number }>(({ isDarkMode }) => { + return { + ...getButtonStyles(isDarkMode), + border: "unset", + display: "flex", + alignItems: "center", + gap: 6, + height: "auto", + padding: "5px 10px", + cursor: "pointer", + p: { + fontSize: 13, + }, + svg: { + width: 12, + height: 12, + path: { + color: "white!important", + }, + }, + }; +}); + +export const StyledLimitPriceInverter = styled("div")(({ theme }) => { + return { + cursor: "pointer", + position: "relative", + top: 2, + svg: { + width: 22, + height: 22, + }, + }; +}); + +export const StyledLimitPriceInput = styled(Components.LimitInputV2)(({ theme }) => { + return { + width: "100%", + maxWidth: 280, + borderRadius: 8, + padding: "4px 10px", + marginLeft: "auto", + background: "#12131a", + border: "1px solid rgba(255,255,255,0.2)", + input: { + textAlign: "right", + }, + ".twap-loader": { + right: 10, + }, + }; +}); + +export const StyledTradePrice = styled(Components.TradePrice)(() => { + return { + width: "100%", + justifyContent: "flex-end", + ".twap-label": { + display: "none", + }, + ".limit-price-text": { + fontSize: 14, + }, + }; +}); + +export const StyledLimitPrice = styled(Components.Base.Card)({ + marginTop: 12, + display: "flex", + flexDirection: "column", + gap: 12, +}); diff --git a/packages/thena/src/i18n/en.json b/packages/thena/src/i18n/en.json index 0967ef42..cf9bc00e 100644 --- a/packages/thena/src/i18n/en.json +++ b/packages/thena/src/i18n/en.json @@ -1 +1,5 @@ -{} +{ + "enterAmount": "Enter an amount", + "outAmountLoading": "Fetching Quotes", + "insufficientFunds": "Insufficient Balance" +} diff --git a/packages/thena/src/index.tsx b/packages/thena/src/index.tsx index df155235..e8baf3dd 100644 --- a/packages/thena/src/index.tsx +++ b/packages/thena/src/index.tsx @@ -1,10 +1,10 @@ -import { GlobalStyles, Box } from "@mui/material"; -import { Components, useTwapContext, Styles as TwapStyles, TWAPTokenSelectProps, hooks, Translations, TwapAdapter, Orders } from "@orbs-network/twap-ui"; +import { GlobalStyles, Box, ThemeProvider, Typography } from "@mui/material"; +import { Components, Styles as TwapStyles, TWAPTokenSelectProps, hooks, Translations, TwapAdapter, Orders, TwapContextUIPreferences } from "@orbs-network/twap-ui"; import translations from "./i18n/en.json"; import { Configs, TokenData } from "@orbs-network/twap"; -import { createContext, useContext } from "react"; +import { createContext, useContext, useEffect, useMemo } from "react"; import Web3 from "web3"; -import { isNativeAddress } from "@defi.org/web3-candies"; +import { eqIgnoreCase, isNativeAddress } from "@defi.org/web3-candies"; import { TWAPProps, store } from "@orbs-network/twap-ui"; import { memo, ReactNode, useCallback, useState } from "react"; import { @@ -14,18 +14,28 @@ import { StyledOrderSummary, StyledPanelInput, StyledPercentSelector, - StyledTokenPanelTop, StyledTokenSelect, configureStyles, StyledColumnFlex, - StyledLimitPrice, StyledOrders, StyledPoweredBy, StyledSubmit, StyledTokenChange, StyledDisclaimerText, + darkTheme, + lightTheme, + StyledTokenPanelUsd, + StyledTopColumn, + StyledReset, + StyledLimitPriceContainer, + StyledTradePrice, + StyledLimitPriceInput, + StyledLimitPriceInverter, } from "./styles"; +import { GrPowerReset } from "@react-icons/all-files/gr/GrPowerReset"; +import { TiArrowSync } from "@react-icons/all-files/ti/TiArrowSync"; +import { useTwapContext } from "@orbs-network/twap-ui"; const storeOverride = { isLimitOrder: true, chunks: 1, @@ -33,7 +43,13 @@ const storeOverride = { customFillDelay: { resolution: store.TimeResolution.Minutes, amount: 2 }, }; -const ModifiedTokenSelectModal = (props: TWAPTokenSelectProps) => { +const uiPreferences: TwapContextUIPreferences = { + usdPrefix: "$", + inputPlaceholder: "0.0", + switchVariant: "ios", +}; + +const MemoizedTokenModal = memo((props: TWAPTokenSelectProps) => { const { TokenSelectModal, dappTokens } = useAdapterContext(); return ( @@ -47,16 +63,36 @@ const ModifiedTokenSelectModal = (props: TWAPTokenSelectProps) => { setOtherAsset={props.onSelect} /> ); -}; -const memoizedTokenSelect = memo(ModifiedTokenSelectModal); +}); + +const TokenSelectModal = ({ onClose, isSrc, isOpen }: any) => { + const { dappTokens } = useAdapterContext(); + const onTokenSelectedCallback = hooks.useSelectTokenCallback(); + + const onSelect = useCallback( + (token: any) => { + onTokenSelectedCallback({ isSrc, token }); + onClose(); + }, + [onTokenSelectedCallback, isSrc] + ); + const { srcTokenAddress, dstTokenAddress } = store.useTwapStore((s) => ({ + srcTokenAddress: s.srcToken?.address, + dstTokenAddress: s.dstToken?.address, + })); -const TokenSelect = ({ open, onClose, isSrcToken }: { open: boolean; onClose: () => void; isSrcToken?: boolean }) => { - return ; + const { srcTokenSelected, dstTokenSelected } = useMemo(() => { + return { + srcTokenSelected: dappTokens?.find((it) => eqIgnoreCase(it.address, srcTokenAddress || "")), + dstTokenSelected: dappTokens?.find((it) => eqIgnoreCase(it.address, dstTokenAddress || "")), + }; + }, [dappTokens, srcTokenAddress, dstTokenAddress]); + + return ; }; const TokenPanel = ({ isSrcToken }: { isSrcToken?: boolean }) => { const [tokenListOpen, setTokenListOpen] = useState(false); - const translations = useTwapContext().translations; const onClose = useCallback(() => { setTokenListOpen(false); @@ -64,41 +100,26 @@ const TokenPanel = ({ isSrcToken }: { isSrcToken?: boolean }) => { return ( <> - - + - - {isSrcToken ? translations.from : translations.to} - {isSrcToken && } - - - + {isSrcToken && } + + - - - - - - setTokenListOpen(true)} /> - - + + setTokenListOpen(true)} /> + + + + - + ); }; -const Card = ({ children, className = "" }: { children: ReactNode; className?: string }) => { - const { isDarkTheme } = useAdapterContext(); - return ( - -
{children}
-
- ); -}; - const SrcTokenPercentSelector = () => { const onPercentClick = hooks.useCustomActions(); @@ -108,18 +129,17 @@ const SrcTokenPercentSelector = () => { return ( + - - + ); }; const OrderSummary = ({ children }: { children: ReactNode }) => { - const { isDarkTheme } = useAdapterContext(); return ( - + @@ -134,7 +154,7 @@ const OrderSummary = ({ children }: { children: ReactNode }) => { {children} - + @@ -154,18 +174,14 @@ const config = Configs.Thena; interface ThenaTWAPProps extends TWAPProps { connect: () => void; - dappTokens: ThenaRawToken[]; -} - -interface ThenaRawToken { - address: string; - decimals: number; - name: string; - symbol: string; - logoURI: string; + dappTokens: any[]; + connector?: any; + outAmount?: string; + outAmountLoading?: boolean; + setFromAmount: (amount: string) => void; } -const parseToken = (rawToken: ThenaRawToken): TokenData | undefined => { +const parseToken = (rawToken: any): TokenData | undefined => { const { address, decimals, symbol, logoURI } = rawToken; if (!symbol) { console.error("Invalid token", rawToken); @@ -188,7 +204,47 @@ const AdapterContextProvider = AdapterContext.Provider; const useAdapterContext = () => useContext(AdapterContext); +export const useProvider = (props: ThenaTWAPProps) => { + const [provider, setProvider] = useState(undefined); + + const setProviderFromConnector = useCallback(async () => { + const res = await props.connector?.getProvider(); + setProvider(res); + }, [setProvider, props.connector]); + + useEffect(() => { + setProviderFromConnector(); + }, [props.account, props.connectedChainId, setProviderFromConnector]); + + return provider; +}; + +const AmountUpdater = () => { + const srcAmount = store.useTwapStore((state) => state.srcAmountUi); + const setFromAmount = useAdapterContext().setFromAmount; + useEffect(() => { + setFromAmount(srcAmount || "0"); + }, [setFromAmount, srcAmount]); + + return null; +}; + +const usePriceUSD = (address?: string) => { + const dappTokens = useTwapContext().dappTokens; + return useMemo(() => { + if (!address) return undefined; + const token = dappTokens?.find((it: any) => eqIgnoreCase(it.address, address)); + return token?.price; + }, [address, dappTokens]); +}; + const TWAP = (props: ThenaTWAPProps) => { + const theme = useMemo(() => { + return props.isDarkTheme ? darkTheme : lightTheme; + }, [props.isDarkTheme]); + + const provider = useProvider(props); + return ( { maxFeePerGas={props.maxFeePerGas} priorityFeePerGas={props.priorityFeePerGas} translations={translations as Translations} - provider={props.provider} + provider={provider} account={props.account} dappTokens={props.dappTokens} parseToken={parseToken} @@ -206,14 +262,20 @@ const TWAP = (props: ThenaTWAPProps) => { storeOverride={props.limit ? storeOverride : undefined} onDstTokenSelected={props.onDstTokenSelected} onSrcTokenSelected={props.onSrcTokenSelected} - priceUsd={props.priceUsd} + usePriceUSD={usePriceUSD} + uiPreferences={uiPreferences} + dstAmountOut={props?.outAmount} + dstAmountLoading={props?.outAmountLoading} > - - - {props.limit ? : } + + + + + {props.limit ? : } - - + + + ); @@ -223,15 +285,17 @@ const TWAPPanel = () => { return (
- - - - + + + + + + - + @@ -245,15 +309,16 @@ const LimitPanel = () => { return (
- - - - + + + + + + - - - - + + + @@ -268,9 +333,14 @@ const LimitPanel = () => { ); }; +const MainSubmit = () => { + const account = useAdapterContext().account; + return ; +}; + const TradeSize = () => { return ( - + @@ -282,25 +352,25 @@ const TradeSize = () => { - + ); }; const MaxDuration = () => { return ( - + - + ); }; const TradeInterval = () => { return ( - + @@ -308,23 +378,37 @@ const TradeInterval = () => { - + ); }; -const LimitPrice = ({ limit }: { limit?: boolean }) => { +const LimitPrice = ({ limitOnly }: { limitOnly?: boolean }) => { + const isLimitOrder = store.useTwapStore((store) => store.isLimitOrder); + const { onInvert } = hooks.useLimitPriceV2(); + return ( - <> - - - - - {!limit && } - - - - - + + + + + + + + Reset + + + + + {!limitOnly && } + + + + + + + {isLimitOrder && } + + ); }; diff --git a/packages/thena/src/styles.ts b/packages/thena/src/styles.ts index 68a0878d..2c060eaf 100644 --- a/packages/thena/src/styles.ts +++ b/packages/thena/src/styles.ts @@ -1,8 +1,42 @@ -import { styled } from "@mui/material"; +import { createTheme, styled, Theme } from "@mui/material"; import { Components, Styles, OrdersPanel } from "@orbs-network/twap-ui"; -const gradient = "linear-gradient(to right, rgb(216, 0, 183), rgb(177, 0, 222), rgb(177, 0, 222), rgb(216, 0, 183))"; -export const StyledPanelInput = styled(Components.TokenInput)({ +const isDarkMode = (theme: Theme) => theme.palette.mode === "dark"; + +export const darkTheme = createTheme({ + palette: { + mode: "dark", + }, +}); + +export const lightTheme = createTheme({ + palette: { + mode: "light", + }, +}); + +export const baseStyles = (theme: Theme) => { + return { + secondaryBg: "rgb(66 45 76/1)", + borderMain: "1px solid rgb(53 36 61/1)", + colorMain: "rgb(243 242 244/1)", + colorDark: "rgb(104 87 112/1)", + fontFamily: "Inter", + }; +}; + +const cardStyles = (theme: Theme) => { + const styles = baseStyles(theme); + return { + width: "100%", + borderRadius: 12, + background: " transparent", + border: styles.borderMain, + padding: 12, + }; +}; + +export const StyledPanelInput = styled(Components.TokenPanelInput)({ width: "100%", input: { fontSize: 20, @@ -10,64 +44,181 @@ export const StyledPanelInput = styled(Components.TokenInput)({ }, }); -export const StyledCard = styled("div")<{ isDarkTheme: number }>(({ isDarkTheme }) => ({ - width: "100%", - padding: 1, - borderRadius: 3, - background: "transparent linear-gradient(128deg,#ed00c9,#bd00ed) 0 0 no-repeat padding-box", - ".twap-card-children": { - minHeight: 50, - borderRadius: 3, - padding: 10, - background: isDarkTheme ? "rgb(9 3 51/1)" : "white", - display: "flex", - alighItems: "center", - }, +export const StyledCard = styled(Components.Base.Card)(({ theme }) => ({ + ...cardStyles(theme), })); export const StyledTokenPanelTop = styled(Styles.StyledRowFlex)({ justifyContent: "space-between", }); -export const StyledBalance = styled(Components.TokenBalance)({ - maxWidth: "unset", - "*": { - fontWeight: 600, - fontSize: 14, - "@media(max-width: 600px)": { +export const StyledBalance = styled(Components.TokenBalance)(({ theme }) => { + const styles = baseStyles(theme); + return { + maxWidth: "unset", + "*": { + fontSize: "14px!important", + color: styles.colorDark, + }, + }; +}); + +export const StyledTokenPanelUsd = styled(Components.TokenUSD)(({ theme }) => { + const styles = baseStyles(theme); + return { + "*": { + fontSize: "14px!important", + color: styles.colorDark, + }, + }; +}); + +export const StyledPercentSelector = styled(Styles.StyledRowFlex)(({ theme }) => { + return { + width: "fit-content", + gap: 4, + marginLeft: "auto", + button: { + background: "transparent", + border: "unset", + padding: "6px 12px", fontSize: 14, + fontWeight: 500, + borderRadius: 4, + color: "rgb(217 213 219/1)", + cursor: "pointer", + "&:hover": { + background: "rgb(40 27 46/1)", + }, + "@media(max-width: 600px)": { + fontSize: 12, + padding: "0px 7px", + }, }, - }, + "@media(max-width: 600px)": { + gap: 4, + }, + }; }); -export const StyledPercentSelector = styled(Styles.StyledRowFlex)({ - width: "fit-content", - gap: 8, - button: { - background: "rgb(255 255 255/0.08)", - border: "unset", - height: 28, +export const StyledLimitPriceContainer = styled(StyledCard)({ + display: "flex", + flexDirection: "column", + gap: 14, +}); + +export const StyledTopColumn = styled(Styles.StyledColumnFlex)({ + gap: 4, +}); + +const buttonStyles = (theme: Theme) => { + const styles = baseStyles(theme); + return { + background: "rgb(53 36 61/1)", padding: "0px 10px", - fontSize: 14, - fontWeight: 600, + fontWeight: 500, + fontSize: 16, + borderRadius: 8, + height: 44, + color: styles.colorMain, cursor: "pointer", - "@media(max-width: 600px)": { - fontSize: 12, - padding: "0px 7px", + border: "unset", + "&:hover": { + background: styles.secondaryBg, + }, + "*": { + color: "inherit", + stroke: styles.colorMain, + }, + "&:disabled": { + background: "rgb(53 36 61/1)", + pointerEvents: "none", + color: "rgb(104 87 112/1)", + cursor: "not-allowed", + opacity: 1, + }, + }; +}; + +export const StyledLimitPriceInverter = styled("div")(({ theme }) => { + return { + cursor: "pointer", + position: "relative", + top: 2, + svg: { + width: 22, + height: 22, + }, + }; +}); + +export const StyledLimitPriceInput = styled(Components.LimitInputV2)(({ theme }) => { + const styles = baseStyles(theme); + return { + width: "100%", + maxWidth: 280, + background: styles.secondaryBg, + borderRadius: 8, + padding: "12px 10px", + marginLeft: "auto", + input: { + textAlign: "right", + }, + ".twap-loader": { + right: 10, + }, + }; +}); + +export const StyledTradePrice = styled(Components.TradePrice)(() => { + return { + width: "100%", + justifyContent: "flex-end", + ".twap-label": { + display: "none", + }, + ".limit-price-text": { + fontSize: 14, }, + }; +}); + +export const StyledButton = styled("button")(({ theme }) => { + return { + ...buttonStyles(theme), + }; +}); + +export const StyledReset = styled(StyledButton)({ + display: "flex", + alignItems: "center", + gap: 6, + height: "auto", + padding: "5px 10px", + p: { + fontSize: 13, }, - "@media(max-width: 600px)": { - gap: 4, + svg: { + width: 12, + height: 12, }, }); -export const StyledTokenChange = styled(Components.ChangeTokensOrder)({ - button: { - background: "rgb(255 255 255/0.08)", - borderRadius: "unset", - width: 45, - height: 45, - }, +export const StyledTokenChange = styled(Components.ChangeTokensOrder)(({ theme }) => { + const styles = baseStyles(theme); + return { + height: 0, + position: "relative", + button: { + background: "rgb(53 36 61/1)", + borderRadius: 8, + width: 42, + height: 42, + "&:hover": { + background: styles.secondaryBg, + }, + }, + }; }); export const StyledContainer = styled(Styles.StyledColumnFlex)({ @@ -75,224 +226,259 @@ export const StyledContainer = styled(Styles.StyledColumnFlex)({ }); export const StyledColumnFlex = styled(Styles.StyledColumnFlex)({ - gap: 20, + gap: 8, }); -export const StyledSubmit = styled(Components.SubmitButton)({}); +export const StyledSubmit = styled(Components.SubmitButton)<{ connected?: number }>(({ theme, connected }) => { + return { + ...buttonStyles(theme), + background: connected ? "rgb(53 36 61/1)" : "rgb(220 0 212/1)", + marginTop: 20, + "&:hover": { + background: connected ? "rgb(53 36 61/1)" : "rgb(220 0 212/1)", + }, + }; +}); export const StyledPoweredBy = styled(Components.PoweredBy)({ marginTop: 20, }); -export const StyledTokenSelect = styled(Components.TokenSelect)({ - gap: 15, - ".twap-token-logo": { - width: 28, - height: 28, - }, - ".twap-token-name": { - fontSize: 18, - fontWeight: 600, - }, - p: { - fontSize: 14, - fontWeight: 600, - }, - ".twap-token-display": { +export const StyledTokenSelect = styled(Components.TokenSelect)(({ theme }) => { + const styles = baseStyles(theme); + return { gap: 10, - }, + background: styles.secondaryBg, + padding: "6px 8px 6px 6px", + borderRadius: "20px", + ".twap-token-not-selected": { + padding: "0px 0px 0px 10px", + }, + ".twap-token-logo": { + width: 24, + height: 24, + }, + ".twap-token-name": { + fontSize: 14, + fontWeight: 400, + lineHeight: "24px", + color: "rgb(217 213 219/1)", + }, + svg: { + fill: "rgb(217 213 219/1)", + width: 16, + height: 16, + }, + ".twap-token-display": { + gap: 10, + }, + }; }); -export const StyledLimitPrice = styled(Components.LimitPriceInput)({ - ".twap-input": { - height: "auto", - input: { - fontSize: 15, +export const StyledOrders = styled(OrdersPanel)(({ theme }) => { + const styles = baseStyles(theme); + return { + color: styles.colorMain, + ".twap-odnp-button": { + ...buttonStyles(theme), + background: "rgb(220 0 212/1)", + "&:hover": { + background: "rgb(220 0 212/1)", + }, + }, + ".twap-orders-mobile-button": { + ...buttonStyles(theme), }, - }, -}); -export const StyledOrders = styled(OrdersPanel)<{ isDarkMode: number }>(({ isDarkMode }) => ({ - color: isDarkMode ? "white" : "rgb(10 9 62/1)", - ".twap-order": { - background: isDarkMode ? "rgb(16 22 69/1)" : "white", - border: isDarkMode ? "1px solid transparent" : "1px solid #BD01D2", - padding: 20, - borderRadius: 5, - ".twap-label p": { + ".twap-cancel-order": { + ...buttonStyles(theme), fontSize: 14, + minWidth: 160, + marginTop: 40, }, - ".twap-order-separator": { - display: "none", + ".twap-order-expanded-wrapper": { + background: "rgb(40 27 46/1)!important", }, - ".twap-market-price-section": { - background: isDarkMode ? "#090333" : "rgba(0,0,0, 0.1)", - width: "100%", - padding: "5px 10px", - borderRadius: 8, - "*": { - fontSize: "13px", + ".twap-order": { + ...cardStyles(theme), + + ".twap-label p": { + fontSize: 14, + }, + + ".twap-order-separator": { + display: "none", + }, + ".twap-market-price-section": { + width: "100%", + borderRadius: 8, + "*": { + fontSize: "13px", + }, + ".twap-small-label p": { + fontSize: "14px!important", + }, + }, + ".MuiLinearProgress-root": { + background: styles.secondaryBg, + }, + ".MuiLinearProgress-bar": { + background: "rgb(220 0 212/1)", }, - ".twap-small-label p": { - fontSize: "14px!important", + ".MuiLinearProgress-root::after": { + display: "none", + }, + "&:hover": { + background: "rgb(40 27 46/1)", }, }, - ".MuiLinearProgress-root": { - background: "rgba(255,255,255,0.1)", + ".twap-orders-header-tabs": { + background: "rgb(40 27 46/1)!important", + border: "unset", }, - ".MuiLinearProgress-bar": { - background: gradient, + ".Mui-selected": { + background: "rgb(53 36 61/1)!important", + color: `${styles.colorMain}!important`, }, - ".MuiLinearProgress-root::after": { + ".MuiTouchRipple-root": { display: "none", }, - }, - - ".twap-orders-header": { - ".twap-label": { - p: { - fontSize: "16px!important", - }, - }, - ".twap-orders-header-tabs": { - border: "1px solid #BD01D2", + ".MuiTabs-indicator": { + display: "none!important", }, ".MuiButtonBase-root": { borderRadius: 4, transition: "0.3s all", - color: isDarkMode ? "white" : "rgb(10 9 62/1)", + color: "rgb(179 171 183/1)", }, - ".Mui-selected": { - background: gradient, - color: "white!important", + ".twap-orders-header": { + ".twap-label": { + p: { + fontSize: "16px!important", + }, + }, }, - ".MuiTabs-indicator": { - display: "none", + "@media(min-width: 600px)": { + ".twap-time-selector-list": { + "&-item": { + "&:hover": { + background: "rgba(255,255,255,0.05)", + }, + }, + }, }, - }, -})); + }; +}); -export const StyledOrderSummary = styled(Components.OrderSummaryModalContainer)<{ isDarkMode: number }>(({ isDarkMode }) => ({ - fontFamily: "Figtree", +export const StyledOrderSummary = styled(Components.OrderSummaryModalContainer)(({ theme }) => { + const styles = baseStyles(theme); + return { + fontFamily: styles.fontFamily, - ".twap-modal-content": { - ".twap-card": { - background: isDarkMode ? "rgb(13 18 56/1)" : "transparent", - border: isDarkMode ? "1px solid transparent" : "1px solid rgb(13 18 56/1)", - borderRadius: 8, - padding: 20, - }, - svg: { - color: isDarkMode ? "white" : "black", - }, - "twap-order-summary-details": {}, - ".twap-order-summary-details-item": { - div: { - "&:last-of-type": { - "*": { - fontSize: 14, + ".twap-modal-content": { + ".twap-card": { + ...cardStyles(theme), + }, + svg: { + color: styles.colorMain, + }, + "twap-order-summary-details": {}, + ".twap-order-summary-details-item": { + flexWrap: "wrap", + div: { + "&:last-of-type": { + "*": { + fontSize: 14, + }, }, }, }, }, - }, - ".twap-price-compare": { - fontSize: 14, - "*": { + ".twap-price-compare": { fontSize: 14, + "*": { + fontSize: 14, + }, }, - }, - ".twap-orders-summary-token-display": { - ".twap-token-logo": { - width: 45, - height: 45, + ".twap-orders-summary-token-display": { + ".twap-token-logo": { + width: 45, + height: 45, + }, }, - }, - "@media(max-width: 600px)": { - ".twap-order-summary-details-item": { - flexDirection: "column", - alignItems: "flex-start", + "@media(max-width: 600px)": {}, + }; +}); + +export const configureStyles = (theme: Theme) => { + const styles = baseStyles(theme); + return { + ".twap-orders-mobile-menu": { + ".MuiPopover-paper": { + background: styles.secondaryBg, + }, + "*": { + color: "white", + }, }, - ".twap-orders-summary-token-display-flex": { - "&:last-of-type": { - flexDirection: "column", - alignItems: "flex-start", + ".twap-odnp-link": { + ...buttonStyles(theme), + }, + ".twap-time-selector-selected": { + p: { + fontSize: "13px!important", }, }, - }, -})); - -const buttonStyles = { - borderRadius: 3, - background: "linear-gradient(to right, rgb(216, 0, 183), rgb(177, 0, 222), rgb(177, 0, 222), rgb(216, 0, 183))", - minHeight: 57, - fontWeight: 700, - fontSize: 17, - textTransform: "uppercase", - lineHeight: "24px", - padding: 10, - color: "white!important", - "*": { - fontWeight: "inherit", - fontSize: "inherit", - lineHeight: "inherit", - color: "white!important", - }, -}; + ".twap-time-selector-list": { + background: styles.secondaryBg, + borderRadius: "12px!important", + }, -export const configureStyles = (isDarkMode?: boolean) => { - return { - ".twap-odnp-button": { - ...buttonStyles, - border: "unset", - minHeight: "auto", - padding: "4px 10px!important", - fontSize: 14, - textTransform: "none", + ".MuiSwitch-track": { + background: "#422D4C!important", }, - ".twap-button": { - ...buttonStyles, + ".MuiSwitch-switchBase.Mui-checked+.MuiSwitch-track": { + background: "rgb(220 0 212/1)!important", }, + ".twap-modal-content": { - padding: "50px 20px 20px 20px", - background: isDarkMode ? "rgb(16 22 69/1)" : "white", - border: "1px solid rgb(0 0 175/1)", + padding: "20px 20px 20px 20px", maxHeight: "90vh", overflowY: "auto", width: "calc(100vw - 40px)", - borderRadius: 8, - color: isDarkMode ? "white" : "rgb(10 9 62/1)", + background: "#1B121E", + borderRadius: 12, + color: styles.colorMain, ".twap-ui-close": { color: "inherit", }, + ".MuiCircularProgress-root": { + color: "rgb(220 0 212/1)", + }, }, ".twap-container": { "*": { - color: isDarkMode ? "white" : "rgb(10 9 62/1)", + color: styles.colorMain, }, }, ".twap-slider": { ".MuiSlider-valueLabel": { - backgroundColor: isDarkMode ? "rgb(16 22 69/1)" : "white", + backgroundColor: "rgb(16 22 69/1)", }, }, ".twap-input": { input: { + padding: 0, + color: styles.colorMain, "&::placeholder": { - color: isDarkMode ? "white!important" : "rgb(10 9 62/1)!important", + color: styles.colorMain, opacity: 0.4, }, }, }, - ".twap-limit-price-input": { - paddingLeft: "5px!important", - background: isDarkMode ? "rgb(16 22 69 / 1)" : "#F4F5F6", - borderRadius: 8, - }, ".MuiBackdrop-root": { - background: isDarkMode ? "rgb(9 3 51/0.88)!important" : "white!important", - opacity: isDarkMode ? "unset" : "0.7!important", + background: "rgba(13, 9, 15, 0.8)!important", }, ".twap-time-selector": { ".twap-input": { @@ -317,54 +503,27 @@ export const configureStyles = (isDarkMode?: boolean) => { fontWeight: 600, }, }, - ".MuiSwitch-thumb ": { - background: gradient, - }, - ".MuiSlider-thumb": { - background: gradient, - }, - ".MuiSwitch-track": { - backgroundColor: isDarkMode ? "white!important" : "rgb(10 9 62/1)!important", - }, ".twap-label": { p: { - fontSize: 16, + fontSize: 15, fontWeight: 500, }, }, - ".twap-time-selector-list": { - background: "rgb(16 22 69/1)", - border: "1px solid rgb(0 0 175/1)", - }, - ".twap-time-selector-list-item": { - "&:hover": { - background: "rgba(255,255,255,0.03)", - }, - }, + ".twap-usd": { p: { fontSize: 14, - fontWeight: 600, }, }, - ".twap-token-panel-title": { - "*": { - color: isDarkMode ? "white" : "rgb(10 9 62/1)", - fontSize: "16!important", - fontWeight: "500!important", - }, - }, ".twap-tooltip": { "& .MuiTooltip-tooltip": { - backgroundColor: isDarkMode ? "rgb(16 22 69/1)" : "white", - borderRadius: "4px", - color: isDarkMode ? "white" : "rgb(10 9 62/1)", + background: styles.secondaryBg, + borderRadius: "8px", fontSize: 14, lineHeight: 1.5, - padding: 10, - border: "1px solid rgb(0 0 175/1)", - fontFamily: "Figtree", + padding: 12, + fontFamily: "Inter", "& *": { color: "inherit", fontSize: 14, @@ -383,14 +542,11 @@ export const configureStyles = (isDarkMode?: boolean) => { "*": { fontFamily: "inherit", - color: isDarkMode ? "white" : "rgb(10 9 62/1)", }, }, }; }; -export const StyledDisclaimerText = styled(Components.DisclaimerText)<{ isDarkMode: number }>(({ isDarkMode }) => ({ - "*": { - color: isDarkMode ? "white" : "rgb(10 9 62/1)", - }, +export const StyledDisclaimerText = styled(Components.DisclaimerText)(({}) => ({ + "*": {}, }));