diff --git a/.changeset/fluffy-books-stare.md b/.changeset/fluffy-books-stare.md new file mode 100644 index 0000000000..5c67d0a9a5 --- /dev/null +++ b/.changeset/fluffy-books-stare.md @@ -0,0 +1,5 @@ +--- +"@venusprotocol/landing": minor +--- + +update landing page diff --git a/apps/evm/src/components/AccountHealthBar/index.tsx b/apps/evm/src/components/AccountHealthBar/index.tsx index 108949c3ca..ca2fcd4e52 100644 --- a/apps/evm/src/components/AccountHealthBar/index.tsx +++ b/apps/evm/src/components/AccountHealthBar/index.tsx @@ -1,19 +1,14 @@ /** @jsxImportSource @emotion/react */ +import { formatCentsToReadableValue, theme } from '@venusprotocol/ui'; import { useMemo } from 'react'; -import PLACEHOLDER_KEY from 'constants/placeholderKey'; -import { useTranslation } from 'libs/translations'; -import { - calculatePercentage, - formatCentsToReadableValue, - formatPercentageToReadableValue, -} from 'utilities'; - -import { theme } from '@venusprotocol/ui'; import { HEALTH_FACTOR_MODERATE_THRESHOLD, HEALTH_FACTOR_SAFE_THRESHOLD, } from 'constants/healthFactor'; +import PLACEHOLDER_KEY from 'constants/placeholderKey'; +import { useTranslation } from 'libs/translations'; +import { calculatePercentage, formatPercentageToReadableValue } from 'utilities'; import { LabeledProgressBar } from '../LabeledProgressBar'; const safeBorrowLimitPercentage = 100 / HEALTH_FACTOR_SAFE_THRESHOLD; diff --git a/apps/evm/src/components/Apy/PrimeBadge/SimulationText/index.tsx b/apps/evm/src/components/Apy/PrimeBadge/SimulationText/index.tsx index 233d0fb7b7..955b436b12 100644 --- a/apps/evm/src/components/Apy/PrimeBadge/SimulationText/index.tsx +++ b/apps/evm/src/components/Apy/PrimeBadge/SimulationText/index.tsx @@ -1,7 +1,7 @@ +import { formatTokensToReadableValue } from '@venusprotocol/ui'; import { useGetToken } from 'libs/tokens'; import { useTranslation } from 'libs/translations'; import type { PrimeSimulationDistribution, Token } from 'types'; -import { formatTokensToReadableValue } from 'utilities'; export interface SimulationTextProps { token: Token; diff --git a/apps/evm/src/containers/AccountData/index.tsx b/apps/evm/src/containers/AccountData/index.tsx index b646b47ffe..d5e65ce0c7 100644 --- a/apps/evm/src/containers/AccountData/index.tsx +++ b/apps/evm/src/containers/AccountData/index.tsx @@ -1,12 +1,11 @@ +import { cn, formatCentsToReadableValue } from '@venusprotocol/ui'; import type BigNumber from 'bignumber.js'; -import { cn } from '@venusprotocol/ui'; import { AccountHealthBar, HealthFactorPill, LabeledInlineContent, ValueUpdate } from 'components'; import PLACEHOLDER_KEY from 'constants/placeholderKey'; import { useTranslation } from 'libs/translations'; import { memo } from 'react'; import type { Asset, Pool, Swap, TokenAction } from 'types'; -import { formatCentsToReadableValue } from 'utilities'; import useGetValues from './useGetValues'; const MemoizedAccountHealthBar = memo(AccountHealthBar); diff --git a/apps/evm/src/containers/ImportablePositions/Notice/index.tsx b/apps/evm/src/containers/ImportablePositions/Notice/index.tsx index 18582db1e1..a775797ded 100644 --- a/apps/evm/src/containers/ImportablePositions/Notice/index.tsx +++ b/apps/evm/src/containers/ImportablePositions/Notice/index.tsx @@ -1,12 +1,12 @@ -import { cn } from '@venusprotocol/ui'; +import { cn, formatCentsToReadableValue } from '@venusprotocol/ui'; import { BigNumber } from 'bignumber.js'; + import { NoticeInfo } from 'components'; import { MAX_POSITION_SUPPLY_BALANCE_CENTS, MIN_POSITION_SUPPLY_BALANCE_CENTS, } from 'constants/importPositions'; import { useTranslation } from 'libs/translations'; -import { formatCentsToReadableValue } from 'utilities'; export interface NoticeProps { className?: string; diff --git a/apps/evm/src/containers/ImportablePositions/ProtocolPositions/Position/index.tsx b/apps/evm/src/containers/ImportablePositions/ProtocolPositions/Position/index.tsx index 7848747254..f3c41ecb9a 100644 --- a/apps/evm/src/containers/ImportablePositions/ProtocolPositions/Position/index.tsx +++ b/apps/evm/src/containers/ImportablePositions/ProtocolPositions/Position/index.tsx @@ -1,4 +1,5 @@ -import { cn } from '@venusprotocol/ui'; +import { cn, formatCentsToReadableValue, formatTokensToReadableValue } from '@venusprotocol/ui'; + import { useImportSupplyPosition } from 'clients/api'; import { Apy, Button, Delimiter, Icon, TokenIcon } from 'components'; import { routes } from 'constants/routing'; @@ -13,9 +14,7 @@ import { handleError, isUserRejectedTxError } from 'libs/errors'; import { useTranslation } from 'libs/translations'; import { calculateYearlyInterests, - formatCentsToReadableValue, formatPercentageToReadableValue, - formatTokensToReadableValue, getCombinedDistributionApys, } from 'utilities'; import { ApyCell } from './ApyCell'; diff --git a/apps/evm/src/containers/Layout/ClaimRewardButton/RewardGroupContent/index.tsx b/apps/evm/src/containers/Layout/ClaimRewardButton/RewardGroupContent/index.tsx index be31603597..b5387153df 100644 --- a/apps/evm/src/containers/Layout/ClaimRewardButton/RewardGroupContent/index.tsx +++ b/apps/evm/src/containers/Layout/ClaimRewardButton/RewardGroupContent/index.tsx @@ -1,6 +1,8 @@ -import { LayeredValues, TokenIconWithSymbol } from 'components'; +import { formatCentsToReadableValue } from '@venusprotocol/ui'; import { useMemo } from 'react'; -import { convertMantissaToTokens, formatCentsToReadableValue } from 'utilities'; + +import { LayeredValues, TokenIconWithSymbol } from 'components'; +import { convertMantissaToTokens } from 'utilities'; import type { ExternalRewardsGroup, InternalRewardsGroup, PendingReward } from '../types'; export interface RewardGroupContentProps { diff --git a/apps/evm/src/containers/Layout/ClaimRewardButton/index.tsx b/apps/evm/src/containers/Layout/ClaimRewardButton/index.tsx index 0ae86f96d0..b09f2b001a 100644 --- a/apps/evm/src/containers/Layout/ClaimRewardButton/index.tsx +++ b/apps/evm/src/containers/Layout/ClaimRewardButton/index.tsx @@ -1,14 +1,13 @@ +import { cn, formatCentsToReadableValue } from '@venusprotocol/ui'; import BigNumber from 'bignumber.js'; import { useMemo, useState } from 'react'; -import { cn } from '@venusprotocol/ui'; import { type Claim, useClaimRewards } from 'clients/api'; import { type ButtonProps, Icon, Modal, PrimaryButton } from 'components'; import { useGetChainMetadata } from 'hooks/useGetChainMetadata'; import { VError } from 'libs/errors'; import { useTranslation } from 'libs/translations'; import { useAccountAddress } from 'libs/wallet'; -import { formatCentsToReadableValue } from 'utilities'; import { useBreakpointUp } from 'hooks/responsive'; import TEST_IDS from '../testIds'; diff --git a/apps/evm/src/containers/Layout/Header/MarketInfo/index.tsx b/apps/evm/src/containers/Layout/Header/MarketInfo/index.tsx index e4d137058a..e1322bcd68 100644 --- a/apps/evm/src/containers/Layout/Header/MarketInfo/index.tsx +++ b/apps/evm/src/containers/Layout/Header/MarketInfo/index.tsx @@ -1,14 +1,16 @@ +import { formatCentsToReadableValue } from '@venusprotocol/ui'; import BigNumber from 'bignumber.js'; +import { useMemo } from 'react'; +import { useParams } from 'react-router'; +import type { Address } from 'viem'; + import { useGetAsset, useGetPool } from 'clients/api'; import { CellGroup, type CellProps, Icon, Spinner, TokenIcon } from 'components'; import { NULL_ADDRESS } from 'constants/address'; import PLACEHOLDER_KEY from 'constants/placeholderKey'; import { useTranslation } from 'libs/translations'; import { useAccountAddress } from 'libs/wallet'; -import { useMemo } from 'react'; -import { useParams } from 'react-router'; -import { formatCentsToReadableValue, formatPercentageToReadableValue } from 'utilities'; -import type { Address } from 'viem'; +import { formatPercentageToReadableValue } from 'utilities'; import { AddTokenToWalletDropdown } from './AddTokenToWalletDropdown'; import { GoToTokenContractDropdown } from './GoToTokenContractDropdown'; import { UtilizationRate } from './UtilizationRate'; diff --git a/apps/evm/src/containers/MarketTable/useGenerateColumns.tsx b/apps/evm/src/containers/MarketTable/useGenerateColumns.tsx index 58c016aa7c..8c3f6505c7 100644 --- a/apps/evm/src/containers/MarketTable/useGenerateColumns.tsx +++ b/apps/evm/src/containers/MarketTable/useGenerateColumns.tsx @@ -1,7 +1,7 @@ /** @jsxImportSource @emotion/react */ +import { cn, formatCentsToReadableValue, formatTokensToReadableValue } from '@venusprotocol/ui'; import { useMemo } from 'react'; -import { cn } from '@venusprotocol/ui'; import { InfoIcon, LayeredValues, @@ -19,9 +19,7 @@ import { compareBigNumbers, compareBooleans, compareStrings, - formatCentsToReadableValue, formatPercentageToReadableValue, - formatTokensToReadableValue, getCombinedDistributionApys, isAssetPaused, isCollateralActionDisabled, diff --git a/apps/evm/src/containers/PoolStats/index.tsx b/apps/evm/src/containers/PoolStats/index.tsx index e734247b7e..4ad27c6ea3 100644 --- a/apps/evm/src/containers/PoolStats/index.tsx +++ b/apps/evm/src/containers/PoolStats/index.tsx @@ -1,3 +1,4 @@ +import { formatCentsToReadableValue, formatTokensToReadableValue } from '@venusprotocol/ui'; import BigNumber from 'bignumber.js'; import { useGetTokenBalances, @@ -11,12 +12,7 @@ import { useGetVTreasuryContractAddress } from 'hooks/useGetVTreasuryContractAdd import { useGetToken, useGetTokens } from 'libs/tokens'; import { useTranslation } from 'libs/translations'; import type { Pool } from 'types'; -import { - areTokensEqual, - convertMantissaToTokens, - formatCentsToReadableValue, - formatTokensToReadableValue, -} from 'utilities'; +import { areTokensEqual, convertMantissaToTokens } from 'utilities'; import type { Address } from 'viem'; import { getTreasuryBalanceCents } from './getTreasuryBalanceCents'; diff --git a/apps/evm/src/containers/PrimeStatusBanner/index.tsx b/apps/evm/src/containers/PrimeStatusBanner/index.tsx index db0de86153..0bb9c39213 100644 --- a/apps/evm/src/containers/PrimeStatusBanner/index.tsx +++ b/apps/evm/src/containers/PrimeStatusBanner/index.tsx @@ -1,7 +1,7 @@ import type BigNumber from 'bignumber.js'; import { useMemo } from 'react'; -import { cn } from '@venusprotocol/ui'; +import { cn, formatTokensToReadableValue } from '@venusprotocol/ui'; import PrimeLogo from 'assets/img/primeLogo.svg?react'; import { useClaimPrimeToken } from 'clients/api'; import { Card, PrimaryButton, ProgressBar } from 'components'; @@ -18,7 +18,7 @@ import type { Token } from 'types'; import { useGetUserPrimeInfo } from 'hooks/useGetUserPrimeInfo'; import { useAccountAddress } from 'libs/wallet'; -import { formatPercentageToReadableValue, formatTokensToReadableValue } from 'utilities'; +import { formatPercentageToReadableValue } from 'utilities'; import NoPrimeTokensLeftWarning from './NoPrimeTokensLeftWarning'; import PrimeTokensLeft from './PrimeTokensLeft'; import { formatWaitingPeriod } from './formatWaitingPeriod'; diff --git a/apps/evm/src/hooks/useDebounceValue.ts b/apps/evm/src/hooks/useDebounceValue.ts index f992127789..8871eae34f 100644 --- a/apps/evm/src/hooks/useDebounceValue.ts +++ b/apps/evm/src/hooks/useDebounceValue.ts @@ -1,7 +1,7 @@ +import { debounce } from '@venusprotocol/ui'; import { useEffect, useMemo, useState } from 'react'; -import { DEFAULT_DEBOUNCE_DELAY, debounce } from 'utilities'; -export default function useDebounceValue(value: T, delay = DEFAULT_DEBOUNCE_DELAY) { +export default function useDebounceValue(value: T, delay?: number) { const [debouncedValue, setDebouncedValue] = useState(value); const debouncedSetter = useMemo( diff --git a/apps/evm/src/hooks/useFormatTokensToReadableValue.ts b/apps/evm/src/hooks/useFormatTokensToReadableValue.ts index 46583e7f68..785ce526ed 100644 --- a/apps/evm/src/hooks/useFormatTokensToReadableValue.ts +++ b/apps/evm/src/hooks/useFormatTokensToReadableValue.ts @@ -1,7 +1,10 @@ +import { + type FormatTokensToReadableValueInput, + formatTokensToReadableValue, +} from '@venusprotocol/ui'; import { useMemo } from 'react'; import PLACEHOLDER_KEY from 'constants/placeholderKey'; -import { type FormatTokensToReadableValueInput, formatTokensToReadableValue } from 'utilities'; export type UseFormatTokensToReadableValueInput = FormatTokensToReadableValueInput; diff --git a/apps/evm/src/libs/analytics/useAnalytics/index.ts b/apps/evm/src/libs/analytics/useAnalytics/index.ts index ebc5139caf..4e5c9ac756 100644 --- a/apps/evm/src/libs/analytics/useAnalytics/index.ts +++ b/apps/evm/src/libs/analytics/useAnalytics/index.ts @@ -1,3 +1,4 @@ +import { debounce } from '@venusprotocol/ui'; import { usePostHog } from 'posthog-js/react'; import { useCallback, useMemo } from 'react'; import { useLocation } from 'react-router'; @@ -6,7 +7,6 @@ import { useAccount } from 'wagmi'; import config from 'config'; import { logError } from 'libs/errors'; import { useChainId } from 'libs/wallet'; -import { debounce } from 'utilities'; import { useAuthAnalyticVariantContext } from '../context'; import type { AnalyticEventName, AnalyticEventProps } from './types'; diff --git a/apps/evm/src/pages/Account/NewPage/PerformanceChart/DollarValueChange/index.tsx b/apps/evm/src/pages/Account/NewPage/PerformanceChart/DollarValueChange/index.tsx index edd73e6d5e..1f901ab7f8 100644 --- a/apps/evm/src/pages/Account/NewPage/PerformanceChart/DollarValueChange/index.tsx +++ b/apps/evm/src/pages/Account/NewPage/PerformanceChart/DollarValueChange/index.tsx @@ -1,5 +1,4 @@ -import { cn } from '@venusprotocol/ui'; -import { formatCentsToReadableValue } from 'utilities'; +import { cn, formatCentsToReadableValue } from '@venusprotocol/ui'; export interface DollarValueChangeProps { value?: number; diff --git a/apps/evm/src/pages/Account/NewPage/PerformanceChart/index.tsx b/apps/evm/src/pages/Account/NewPage/PerformanceChart/index.tsx index aa80b0a0b8..6690f62a51 100644 --- a/apps/evm/src/pages/Account/NewPage/PerformanceChart/index.tsx +++ b/apps/evm/src/pages/Account/NewPage/PerformanceChart/index.tsx @@ -1,4 +1,4 @@ -import { Spinner, cn, theme } from '@venusprotocol/ui'; +import { Spinner, cn, formatCentsToReadableValue, theme } from '@venusprotocol/ui'; import { type AccountPerformanceHistoryDataPoint, type AccountPerformanceHistoryPeriod, @@ -12,7 +12,7 @@ import { useIsFeatureEnabled } from 'hooks/useIsFeatureEnabled'; import { useTranslation } from 'libs/translations'; import { useAccountAddress } from 'libs/wallet'; import { useState } from 'react'; -import { formatCentsToReadableValue, formatPercentageToReadableValue } from 'utilities'; +import { formatPercentageToReadableValue } from 'utilities'; import { DollarValueChange } from './DollarValueChange'; import { formatToReadableAxisDate } from './formatToReadableAxisDate'; import { formatToReadableTitleDate } from './formatToReadableTitleDate'; diff --git a/apps/evm/src/pages/Account/NewPage/Summary/index.tsx b/apps/evm/src/pages/Account/NewPage/Summary/index.tsx index 3e483eff9d..9959270967 100644 --- a/apps/evm/src/pages/Account/NewPage/Summary/index.tsx +++ b/apps/evm/src/pages/Account/NewPage/Summary/index.tsx @@ -1,10 +1,10 @@ -import { cn } from '@venusprotocol/ui'; +import { cn, formatCentsToReadableValue } from '@venusprotocol/ui'; import { Card, Cell, type CellProps } from 'components'; import { useGetToken } from 'libs/tokens'; import { useTranslation } from 'libs/translations'; import type { Pool, Vault } from 'types'; -import { formatCentsToReadableValue, formatPercentageToReadableValue } from 'utilities'; +import { formatPercentageToReadableValue } from 'utilities'; import { useExtractData } from '../../useExtractData'; import circularGradientSrc from './circularGradient.svg'; diff --git a/apps/evm/src/pages/Account/PoolSummary/index.tsx b/apps/evm/src/pages/Account/PoolSummary/index.tsx index acc3ce43f3..710435726d 100644 --- a/apps/evm/src/pages/Account/PoolSummary/index.tsx +++ b/apps/evm/src/pages/Account/PoolSummary/index.tsx @@ -1,14 +1,11 @@ +import { formatCentsToReadableValue } from '@venusprotocol/ui'; import type BigNumber from 'bignumber.js'; import { AccountHealthBar, Card, Cell, CellGroup, type CellProps, cn } from 'components'; import type { Pool, Vault } from 'types'; import { useHealthFactor } from 'hooks/useHealthFactor'; import { useTranslation } from 'libs/translations'; -import { - formatCentsToReadableValue, - formatHealthFactorToReadableValue, - formatPercentageToReadableValue, -} from 'utilities'; +import { formatHealthFactorToReadableValue, formatPercentageToReadableValue } from 'utilities'; import Section from '../Section'; import { useExtractData } from '../useExtractData'; diff --git a/apps/evm/src/pages/Bridge/index.tsx b/apps/evm/src/pages/Bridge/index.tsx index b07c1c8489..c3ec94e06c 100644 --- a/apps/evm/src/pages/Bridge/index.tsx +++ b/apps/evm/src/pages/Bridge/index.tsx @@ -3,7 +3,7 @@ import { useCallback, useMemo, useRef } from 'react'; import { Controller } from 'react-hook-form'; import type { Chain } from 'viem'; -import { cn } from '@venusprotocol/ui'; +import { cn, formatTokensToReadableValue } from '@venusprotocol/ui'; import { useBridgeXvs, useGetBalanceOf, useGetXvsBridgeFeeEstimation } from 'clients/api'; import { ApproveTokenSteps, @@ -31,7 +31,7 @@ import { useGetToken } from 'libs/tokens'; import { useTranslation } from 'libs/translations'; import { useAccountAddress, useChainId, useSwitchChain } from 'libs/wallet'; import { ChainId } from 'types'; -import { convertMantissaToTokens, formatTokensToReadableValue } from 'utilities'; +import { convertMantissaToTokens } from 'utilities'; import { ChainSelect, getOptionsFromChainsList } from './ChainSelect'; import { bridgeChains } from './constants'; import LayerZeroLogo from './layerZeroLogo.svg?react'; diff --git a/apps/evm/src/pages/Bridge/useBridgeForm.ts b/apps/evm/src/pages/Bridge/useBridgeForm.ts index 1cef81a77c..a5937b7fee 100644 --- a/apps/evm/src/pages/Bridge/useBridgeForm.ts +++ b/apps/evm/src/pages/Bridge/useBridgeForm.ts @@ -1,4 +1,5 @@ import { zodResolver } from '@hookform/resolvers/zod'; +import { formatCentsToReadableValue, formatTokensToReadableValue } from '@venusprotocol/ui'; import BigNumber from 'bignumber.js'; import { fromUnixTime, isBefore } from 'date-fns'; import { type MutableRefObject, useCallback, useEffect, useMemo } from 'react'; @@ -17,13 +18,7 @@ import { useGetChainMetadata } from 'hooks/useGetChainMetadata'; import { useTranslation } from 'libs/translations'; import { useAccountAddress, useChainId } from 'libs/wallet'; import { ChainId, type Token } from 'types'; -import { - convertDollarsToCents, - convertMantissaToTokens, - convertTokensToMantissa, - formatCentsToReadableValue, - formatTokensToReadableValue, -} from 'utilities'; +import { convertDollarsToCents, convertMantissaToTokens, convertTokensToMantissa } from 'utilities'; import { parseUnits } from 'viem'; import { bridgeChains } from './constants'; diff --git a/apps/evm/src/pages/Market/MarketHistory/Card/ApyChart/index.tsx b/apps/evm/src/pages/Market/MarketHistory/Card/ApyChart/index.tsx index c1a02bfee0..fcd3439298 100644 --- a/apps/evm/src/pages/Market/MarketHistory/Card/ApyChart/index.tsx +++ b/apps/evm/src/pages/Market/MarketHistory/Card/ApyChart/index.tsx @@ -1,8 +1,8 @@ -import { theme } from '@venusprotocol/ui'; +import { formatCentsToReadableValue, theme } from '@venusprotocol/ui'; import type BigNumber from 'bignumber.js'; import { useTranslation } from 'libs/translations'; -import { formatCentsToReadableValue, formatPercentageToReadableValue } from 'utilities'; +import { formatPercentageToReadableValue } from 'utilities'; import type { MarketHistoryPeriodType } from 'clients/api'; import { AreaChart } from 'components'; diff --git a/apps/evm/src/pages/Market/MarketHistory/Card/CapThreshold/index.tsx b/apps/evm/src/pages/Market/MarketHistory/Card/CapThreshold/index.tsx index 84df14c28c..40deb768d0 100644 --- a/apps/evm/src/pages/Market/MarketHistory/Card/CapThreshold/index.tsx +++ b/apps/evm/src/pages/Market/MarketHistory/Card/CapThreshold/index.tsx @@ -1,15 +1,11 @@ -import { theme } from '@venusprotocol/ui'; +import { formatCentsToReadableValue, formatTokensToReadableValue, theme } from '@venusprotocol/ui'; import BigNumber from 'bignumber.js'; import { ProgressCircle, Tooltip } from 'components'; import { useTranslation } from 'libs/translations'; import { useMemo } from 'react'; import type { Token } from 'types'; -import { - formatCentsToReadableValue, - formatPercentageToReadableValue, - formatTokensToReadableValue, -} from 'utilities'; +import { formatPercentageToReadableValue } from 'utilities'; const THRESHOLD_GRADIENT_ID = 'cap-threshold-gradient'; diff --git a/apps/evm/src/pages/Market/MarketInfo/index.tsx b/apps/evm/src/pages/Market/MarketInfo/index.tsx index 167e1ce18f..8476210207 100644 --- a/apps/evm/src/pages/Market/MarketInfo/index.tsx +++ b/apps/evm/src/pages/Market/MarketInfo/index.tsx @@ -1,3 +1,4 @@ +import { formatCentsToReadableValue, formatTokensToReadableValue } from '@venusprotocol/ui'; import BigNumber from 'bignumber.js'; import { LabeledInlineContent } from 'components'; import PLACEHOLDER_KEY from 'constants/placeholderKey'; @@ -6,11 +7,7 @@ import { useIsFeatureEnabled } from 'hooks/useIsFeatureEnabled'; import { useTranslation } from 'libs/translations'; import { useMemo } from 'react'; import type { Asset, Token } from 'types'; -import { - formatCentsToReadableValue, - formatPercentageToReadableValue, - formatTokensToReadableValue, -} from 'utilities'; +import { formatPercentageToReadableValue } from 'utilities'; import { MarketCard } from '../MarketCard'; import TEST_IDS from '../testIds'; import type { Stat } from '../types'; diff --git a/apps/evm/src/pages/Market/OperationForm/BorrowForm/useForm/useFormValidation.ts b/apps/evm/src/pages/Market/OperationForm/BorrowForm/useForm/useFormValidation.ts index 77574dd4c3..8c627bc708 100644 --- a/apps/evm/src/pages/Market/OperationForm/BorrowForm/useForm/useFormValidation.ts +++ b/apps/evm/src/pages/Market/OperationForm/BorrowForm/useForm/useFormValidation.ts @@ -1,10 +1,10 @@ +import { formatTokensToReadableValue } from '@venusprotocol/ui'; import BigNumber from 'bignumber.js'; import { useMemo } from 'react'; import type { Asset, Pool } from 'types'; import { useTranslation } from 'libs/translations'; -import { formatTokensToReadableValue } from 'utilities'; import type { FormError } from '../../types'; import type { FormErrorCode, FormValues } from './types'; diff --git a/apps/evm/src/pages/Market/OperationForm/SupplyForm/useForm/useFormValidation.ts b/apps/evm/src/pages/Market/OperationForm/SupplyForm/useForm/useFormValidation.ts index 91b2529505..9dcce13cd3 100644 --- a/apps/evm/src/pages/Market/OperationForm/SupplyForm/useForm/useFormValidation.ts +++ b/apps/evm/src/pages/Market/OperationForm/SupplyForm/useForm/useFormValidation.ts @@ -1,10 +1,10 @@ +import { formatTokensToReadableValue } from '@venusprotocol/ui'; import BigNumber from 'bignumber.js'; import { useMemo } from 'react'; import { MAXIMUM_PRICE_IMPACT_THRESHOLD_PERCENTAGE } from 'constants/swap'; import { useTranslation } from 'libs/translations'; import type { Asset, Swap, SwapError } from 'types'; -import { formatTokensToReadableValue } from 'utilities'; import { getSwapToTokenAmountReceivedTokens } from 'utilities/getSwapToTokenAmountReceived'; import type { FormError } from '../../types'; import type { FormErrorCode, FormValues } from './types'; diff --git a/apps/evm/src/pages/Pools/PoolTable/index.tsx b/apps/evm/src/pages/Pools/PoolTable/index.tsx index c397e262b6..79a4d4bd33 100644 --- a/apps/evm/src/pages/Pools/PoolTable/index.tsx +++ b/apps/evm/src/pages/Pools/PoolTable/index.tsx @@ -1,4 +1,5 @@ /** @jsxImportSource @emotion/react */ +import { formatCentsToReadableValue } from '@venusprotocol/ui'; import BigNumber from 'bignumber.js'; import { useMemo } from 'react'; @@ -8,7 +9,6 @@ import { routes } from 'constants/routing'; import { useTranslation } from 'libs/translations'; import { useAccountAddress } from 'libs/wallet'; import type { Pool } from 'types'; -import { formatCentsToReadableValue } from 'utilities'; import { useBreakpointUp } from 'hooks/responsive'; import { useStyles } from './styles'; diff --git a/apps/evm/src/pages/PrimeCalculator/Form/RewardDetails/index.tsx b/apps/evm/src/pages/PrimeCalculator/Form/RewardDetails/index.tsx index 71d85405e3..3c0dd3a1c4 100644 --- a/apps/evm/src/pages/PrimeCalculator/Form/RewardDetails/index.tsx +++ b/apps/evm/src/pages/PrimeCalculator/Form/RewardDetails/index.tsx @@ -1,3 +1,4 @@ +import { formatTokensToReadableValue } from '@venusprotocol/ui'; import type BigNumber from 'bignumber.js'; import { useMemo } from 'react'; @@ -6,7 +7,7 @@ import { PRIME_APY_DOC_URL } from 'constants/prime'; import { Link } from 'containers/Link'; import { useTranslation } from 'libs/translations'; import type { Token } from 'types'; -import { formatPercentageToReadableValue, formatTokensToReadableValue } from 'utilities'; +import { formatPercentageToReadableValue } from 'utilities'; import TokenAmountAndApy from './TokenAmountAndApy'; diff --git a/apps/evm/src/pages/PrimeCalculator/Form/index.tsx b/apps/evm/src/pages/PrimeCalculator/Form/index.tsx index 5a29afc935..e9851c49e6 100644 --- a/apps/evm/src/pages/PrimeCalculator/Form/index.tsx +++ b/apps/evm/src/pages/PrimeCalculator/Form/index.tsx @@ -1,4 +1,5 @@ import { zodResolver } from '@hookform/resolvers/zod'; +import { formatCentsToReadableValue, formatTokensToReadableValue } from '@venusprotocol/ui'; import BigNumber from 'bignumber.js'; import { useCallback, useEffect, useMemo, useRef } from 'react'; import { Controller, useForm, useWatch } from 'react-hook-form'; @@ -31,8 +32,6 @@ import { convertDollarsToCents, convertMantissaToTokens, convertTokensToMantissa, - formatCentsToReadableValue, - formatTokensToReadableValue, } from 'utilities'; import { NULL_ADDRESS } from 'constants/address'; diff --git a/apps/evm/src/pages/Swap/SwapDetails/index.tsx b/apps/evm/src/pages/Swap/SwapDetails/index.tsx index bbcb59fb26..41dca7b4ae 100644 --- a/apps/evm/src/pages/Swap/SwapDetails/index.tsx +++ b/apps/evm/src/pages/Swap/SwapDetails/index.tsx @@ -1,6 +1,6 @@ import { useMemo } from 'react'; -import { cn } from '@venusprotocol/ui'; +import { cn, formatTokensToReadableValue } from '@venusprotocol/ui'; import PLACEHOLDER_KEY from 'constants/placeholderKey'; import { HIGH_PRICE_IMPACT_THRESHOLD_PERCENTAGE, @@ -8,11 +8,7 @@ import { } from 'constants/swap'; import { useTranslation } from 'libs/translations'; import type { Swap } from 'types'; -import { - convertMantissaToTokens, - formatPercentageToReadableValue, - formatTokensToReadableValue, -} from 'utilities'; +import { convertMantissaToTokens, formatPercentageToReadableValue } from 'utilities'; import { LabeledInlineContent } from 'components'; diff --git a/apps/evm/src/pages/Vai/Borrow/index.tsx b/apps/evm/src/pages/Vai/Borrow/index.tsx index b22a1cb097..c0328e1836 100644 --- a/apps/evm/src/pages/Vai/Borrow/index.tsx +++ b/apps/evm/src/pages/Vai/Borrow/index.tsx @@ -1,3 +1,4 @@ +import { formatTokensToReadableValue } from '@venusprotocol/ui'; import BigNumber from 'bignumber.js'; import { useCallback, useEffect, useMemo } from 'react'; import { Controller, type SubmitHandler } from 'react-hook-form'; @@ -34,7 +35,6 @@ import { convertMantissaToTokens, convertTokensToMantissa, formatPercentageToReadableValue, - formatTokensToReadableValue, } from 'utilities'; import { NULL_ADDRESS } from 'constants/address'; @@ -43,7 +43,6 @@ import { HEALTH_FACTOR_SAFE_MAX_THRESHOLD, } from 'constants/healthFactor'; import { RhfSubmitButton, RhfTokenTextField } from 'containers/Form'; -import useFormatTokensToReadableValue from 'hooks/useFormatTokensToReadableValue'; import { useGetChainMetadata } from 'hooks/useGetChainMetadata'; import { AccountVaiData } from '../AccountVaiData'; import TEST_IDS from './testIds'; @@ -175,7 +174,7 @@ export const Borrow: React.FC = () => { return `${readableFeeVai} (${readableFeePercentage})`; }, [feePercentage, feeTokens, vai]); - const readableLimit = useFormatTokensToReadableValue({ + const readableLimit = formatTokensToReadableValue({ value: limitTokens, token: vai, }); diff --git a/apps/evm/src/utilities/convertMantissaToTokens.ts b/apps/evm/src/utilities/convertMantissaToTokens.ts index 73a8b4c29a..db56df6924 100644 --- a/apps/evm/src/utilities/convertMantissaToTokens.ts +++ b/apps/evm/src/utilities/convertMantissaToTokens.ts @@ -1,6 +1,6 @@ +import { formatTokensToReadableValue } from '@venusprotocol/ui'; import BigNumber from 'bignumber.js'; import type { Token, VToken } from 'types'; -import { formatTokensToReadableValue } from './formatTokensToReadableValue'; export interface ConvertMantissaToTokensInput { value: BigNumber | bigint; diff --git a/apps/evm/src/utilities/formatHealthFactorToReadableValue/index.ts b/apps/evm/src/utilities/formatHealthFactorToReadableValue/index.ts index 0c1fa1ed65..13e07b149f 100644 --- a/apps/evm/src/utilities/formatHealthFactorToReadableValue/index.ts +++ b/apps/evm/src/utilities/formatHealthFactorToReadableValue/index.ts @@ -1,5 +1,5 @@ +import { shortenValueWithSuffix } from '@venusprotocol/ui'; import BigNumber from 'bignumber.js'; -import shortenValueWithSuffix from 'utilities/shortenValueWithSuffix'; export const HEALTH_FACTOR_MAX_VALUE = 100; export const HEALTH_FACTOR_MAX_DECIMALS = 2; diff --git a/apps/evm/src/utilities/formatPercentageToReadableValue/index.ts b/apps/evm/src/utilities/formatPercentageToReadableValue/index.ts index fdd3a5b820..20b34b4209 100644 --- a/apps/evm/src/utilities/formatPercentageToReadableValue/index.ts +++ b/apps/evm/src/utilities/formatPercentageToReadableValue/index.ts @@ -1,8 +1,8 @@ +import { getSmartDecimalPlaces } from '@venusprotocol/ui'; import BigNumber from 'bignumber.js'; import { ONE_THOUSAND } from 'constants/numbers'; import PLACEHOLDER_KEY from 'constants/placeholderKey'; -import getSmartDecimalPlaces from 'utilities/getSmartDecimalPlaces'; const MIN_VALUE = 0.01; const MAX_VALUE = 10 * ONE_THOUSAND; diff --git a/apps/evm/src/utilities/index.ts b/apps/evm/src/utilities/index.ts index 0f20caa513..48b7719207 100755 --- a/apps/evm/src/utilities/index.ts +++ b/apps/evm/src/utilities/index.ts @@ -1,7 +1,5 @@ export { default as calculateDailyEarningsCents } from './calculateDailyEarningsCents'; export { default as convertPercentageFromSmartContract } from './convertPercentageFromSmartContract'; -export { default as shortenValueWithSuffix } from './shortenValueWithSuffix'; -export { default as formatCentsToReadableValue } from './formatCentsToReadableValue'; export { default as formatPercentageToReadableValue } from './formatPercentageToReadableValue'; export { default as convertTokensToMantissa } from './convertTokensToMantissa'; export { default as indexBy } from './indexBy'; @@ -17,7 +15,6 @@ export { default as convertDollarsToCents } from './convertDollarsToCents'; export { default as areTokensEqual } from './areTokensEqual'; export { default as getCombinedDistributionApys } from './getCombinedDistributionApys'; export { default as areAddressesEqual } from './areAddressesEqual'; -export { default as getSmartDecimalPlaces } from './getSmartDecimalPlaces'; export { default as callOrThrow } from './callOrThrow'; export { default as convertPriceMantissaToDollars } from './convertPriceMantissaToDollars'; export { default as convertFactorFromSmartContract } from './convertFactorFromSmartContract'; @@ -31,7 +28,6 @@ export * from './generateTransactionDeadline'; export * from './getDisabledTokenActions'; export * from './isAssetPaused'; export * from './restService'; -export * from './formatTokensToReadableValue'; export * from './convertMantissaToTokens'; export * from './generatePseudoRandomRefetchInterval'; export * from './calculateYearlyEarnings'; @@ -55,4 +51,3 @@ export * from './isCollateralActionDisabled'; export * from './getBoostedAssetSupplyApy'; export * from './buffer'; export * from './formatHealthFactorToReadableValue'; -export * from './debounce'; diff --git a/apps/landing/package.json b/apps/landing/package.json index 3a4f01c585..3a8345f244 100644 --- a/apps/landing/package.json +++ b/apps/landing/package.json @@ -21,12 +21,14 @@ "axios": "^1.7.2", "classnames": "^2.3.1", "genversion": "^3.2.0", + "motion": "^12.23.12", "normalize.css": "^8.0.1", "posthog-js": "^1.257.0", "react": "^19.1.0", "react-dom": "^19.1.0", "react-router": "^7.6.0", - "react-scrolllock": "^5.0.1" + "react-scrolllock": "^5.0.1", + "usehooks-ts": "^3.1.1" }, "devDependencies": { "@stylelint/postcss-css-in-js": "0.38.0", diff --git a/apps/landing/src/api/constants.ts b/apps/landing/src/api/constants.ts deleted file mode 100644 index e53eeda342..0000000000 --- a/apps/landing/src/api/constants.ts +++ /dev/null @@ -1,40 +0,0 @@ -export const getTokenPublicUrl = (filePath: string) => `/coins/${filePath}`; - -export const tokenIconUrls = { - UNI: getTokenPublicUrl('uni.svg'), - XVS: getTokenPublicUrl('xvs.svg'), - DOT: getTokenPublicUrl('dot.svg'), - AAVE: getTokenPublicUrl('aave.svg'), - SXP: getTokenPublicUrl('sxp.svg'), - DAI: getTokenPublicUrl('dai.svg'), - LTC: getTokenPublicUrl('ltc.svg'), - BCH: getTokenPublicUrl('bch.svg'), - MATIC: getTokenPublicUrl('matic.svg'), - TRX: getTokenPublicUrl('trx.svg'), - TRXOLD: getTokenPublicUrl('trx.svg'), - LINK: getTokenPublicUrl('link.svg'), - wBETH: getTokenPublicUrl('wbeth.svg'), - UST: getTokenPublicUrl('ust.svg'), - BTCB: getTokenPublicUrl('btcb.svg'), - BUSD: getTokenPublicUrl('busd.svg'), - BETH: getTokenPublicUrl('beth.svg'), - ADA: getTokenPublicUrl('ada.svg'), - XRP: getTokenPublicUrl('xrp.svg'), - TUSD: getTokenPublicUrl('tusd.svg'), - TUSDOLD: getTokenPublicUrl('tusd.svg'), - LUNA: getTokenPublicUrl('luna.svg'), - DOGE: getTokenPublicUrl('doge.svg'), - USDC: getTokenPublicUrl('usdc.svg'), - ETH: getTokenPublicUrl('eth.svg'), - FIL: getTokenPublicUrl('fil.svg'), - USDT: getTokenPublicUrl('usdt.svg'), - Cake: getTokenPublicUrl('cake.svg'), - BNB: getTokenPublicUrl('bnb.svg'), - SolvBTC: getTokenPublicUrl('solvBtc.png'), -}; - -export const bscMainnetVCanAddress = '0xeBD0070237a0713E8D94fEf1B728d3d993d290ef'; - -export const compoundDecimals = 18; - -export const vTokenDecimals = 8; diff --git a/apps/landing/src/api/hooks/useVenusApi.ts b/apps/landing/src/api/hooks/useVenusApi.ts index 8e75c43121..2b2ae01b66 100644 --- a/apps/landing/src/api/hooks/useVenusApi.ts +++ b/apps/landing/src/api/hooks/useVenusApi.ts @@ -1,38 +1,8 @@ import { useQuery } from '@tanstack/react-query'; -import { fetchMarkets, fetchTvl } from '../index'; -import { getMarketsToRender } from '../utils'; +import { fetchTvl } from '../index'; -export const useVenusApi = () => { - const { - data: getLegacyPoolMarketsData, - isLoading: isGetLegacyPoolMarketsLoading, - error: getLegacyPoolMarketsError, - refetch: refetchMarkets, - } = useQuery({ - queryKey: ['legacyPoolMarkets'], - queryFn: fetchMarkets, - }); - - const { - data: getTvlData, - isLoading: isGetTvlDataLoading, - error: getTvlDataError, - refetch: refetchTvl, - } = useQuery({ +export const useVenusApi = () => + useQuery({ queryKey: ['tvl'], queryFn: fetchTvl, }); - - const topMarkets = getMarketsToRender(getLegacyPoolMarketsData); - - return { - ...getTvlData, - topMarkets, - isLoading: isGetLegacyPoolMarketsLoading || isGetTvlDataLoading, - errors: { getLegacyPoolMarketsError, getTvlDataError }, - refetch: () => { - refetchMarkets(); - refetchTvl(); - }, - }; -}; diff --git a/apps/landing/src/api/index.ts b/apps/landing/src/api/index.ts index 8b7548f55e..a270f61e1f 100644 --- a/apps/landing/src/api/index.ts +++ b/apps/landing/src/api/index.ts @@ -1,18 +1,12 @@ import axios from 'axios'; -import type { MarketsResponseData, ProposalsResponseData, TvlResponseData } from './types'; -import { formatTvlData, mapMarketsData } from './utils'; +import type { ProposalsResponseData, TvlResponseData } from './types'; +import { formatTvlData } from './utils'; const apiBaseUrl = 'https://api.venus.io/'; -const marketsRequestUrl = `${apiBaseUrl}markets/core-pool?limit=500`; const proposalsRequestUrl = `${apiBaseUrl}governance/proposals?limit=1`; const tvlRequestUrl = `${apiBaseUrl}markets/tvl`; -export async function fetchMarkets() { - const { data: response }: { data: MarketsResponseData } = await axios.get(marketsRequestUrl); - return mapMarketsData(response.result); -} - export async function fetchProposalCount() { const { data: response }: { data: ProposalsResponseData } = await axios.get(proposalsRequestUrl); return response.total; diff --git a/apps/landing/src/api/types.ts b/apps/landing/src/api/types.ts index 7f91837807..2c5879f213 100644 --- a/apps/landing/src/api/types.ts +++ b/apps/landing/src/api/types.ts @@ -1,36 +1,3 @@ -export type MarketResponse = { - address: string; - supplyApy: string; - supplyXvsApy: string; - totalSupplyMantissa: string; - totalBorrowsMantissa: string; - liquidityCents: string; - borrowApy: string; - borrowXvsApy: string; - symbol: string; - tokenPriceCents: string; - underlyingSymbol: string; - underlyingDecimal: number; - exchangeRateMantissa: string; -}; - -export type MarketMapped = { - supplyApy: number; - supplyXvsApy: number; - totalSupplyUsd: number; - totalBorrowsUsd: number; - liquidity: number; - borrowApy: number; - symbol: string; - underlyingSymbol: string; - underlyingIconUrl: string; - depositApy: number; -}; - -export type MarketsResponseData = { - result: MarketResponse[]; -}; - export type ProposalsResponseData = { total: number; }; diff --git a/apps/landing/src/api/utils.ts b/apps/landing/src/api/utils.ts index 94fd29f0a9..9d26e6a82d 100644 --- a/apps/landing/src/api/utils.ts +++ b/apps/landing/src/api/utils.ts @@ -1,78 +1,10 @@ -import { - bscMainnetVCanAddress, - compoundDecimals, - tokenIconUrls, - vTokenDecimals, -} from './constants'; -import type { MarketMapped, MarketResponse, TvlResponseData } from './types'; +import type { Token } from '@venusprotocol/chains'; +import { formatCentsToReadableValue, formatTokensToReadableValue } from '@venusprotocol/ui'; +import BigNumber from 'bignumber.js'; +import type { TvlResponseData } from './types'; export const scale = (value: string | number, decimals: number) => Number(value) / 10 ** decimals; -export const convertCentsToUsd = (value: string | number) => Number(value) / 100; - -export const mapMarketsData = (markets?: MarketResponse[]): MarketMapped[] => { - if (!markets) return []; - - return markets.reduce((acc, i) => { - // Hotfix to filter out vCAN token - if (i.address === bscMainnetVCanAddress) { - return acc; - } - - const underlyingIconUrl = tokenIconUrls[i.underlyingSymbol as keyof typeof tokenIconUrls]; - - const tokenPriceUsd = convertCentsToUsd(i.tokenPriceCents); - const totalBorrowsTokens = scale(i.totalBorrowsMantissa, i.underlyingDecimal); - - const totalSupplyVTokens = scale(i.totalSupplyMantissa, vTokenDecimals); - const exchangeRateVTokens = - Number(i.exchangeRateMantissa) === 0 - ? 0 - : 1 / - scale(i.exchangeRateMantissa, compoundDecimals + i.underlyingDecimal - vTokenDecimals); - - const totalSupplyTokens = totalSupplyVTokens / exchangeRateVTokens; - - const formattedMarket: MarketMapped = { - ...i, - supplyApy: Number(i.supplyApy), - supplyXvsApy: Number(i.supplyXvsApy), - totalSupplyUsd: totalSupplyTokens * tokenPriceUsd, - totalBorrowsUsd: totalBorrowsTokens * tokenPriceUsd, - liquidity: convertCentsToUsd(i.liquidityCents), - depositApy: Number(i.supplyApy) + Number(i.supplyXvsApy), - borrowApy: Number(i.borrowApy) - Number(i.borrowXvsApy), - underlyingIconUrl, - }; - - return acc.concat(formattedMarket); - }, []); -}; - -function sortByTotalSupplyUsd(a: MarketMapped, b: MarketMapped) { - return b.totalSupplyUsd - a.totalSupplyUsd; -} - -function sortBySupplyApy(a: MarketMapped, b: MarketMapped) { - return b.supplyApy - a.supplyApy; -} - -export const getMarketsToRender = (markets?: MarketMapped[]) => { - if (!markets) return []; - // first we get all markets sorted by their size/supply in USD - const sortedMarkets = markets.sort(sortByTotalSupplyUsd); - // then we list the top 5 markets, ordered by their supply APY (higher APYs first) - return sortedMarkets.slice(0, 5).sort(sortBySupplyApy); -}; - -export const formatUsd = (value: number) => { - const formattedValue = new Intl.NumberFormat('en-EN', { - style: 'currency', - currency: 'USD', - }).format(value); - return formattedValue; -}; - export const nFormatter = (num: number, digits = 2) => { const lookup = [ { value: 1, symbol: '' }, @@ -91,16 +23,37 @@ export const nFormatter = (num: number, digits = 2) => { return item ? formatValue(num / item.value) + item.symbol : formatValue(num); }; +// TODO: import from @venusprotocol/tokens package once it's been created +const xvs: Token = { + address: '0xcF6BB5389c92Bdda8a3747Ddb454cB7a64626C63', + decimals: 18, + symbol: 'XVS', + asset: '', +}; + export function formatTvlData(apiData: TvlResponseData) { const totalSupplyCents = Number(apiData.suppliedSumCents.split('.', 1)); const totalBorrowCents = Number(apiData.borrowedSumCents.split('.', 1)); const totalLiquidityCents = Number(apiData.liquiditySumCents.split('.', 1)); + + const totalXvsBuyBackTokens = new BigNumber('71252.12'); // TODO: fetch from API + const { marketCount, chainCount } = apiData; return { - totalSupplyUsd: formatUsd(convertCentsToUsd(totalSupplyCents)), - totalBorrowUsd: formatUsd(convertCentsToUsd(totalBorrowCents)), - totalLiquidityUsd: formatUsd(convertCentsToUsd(totalLiquidityCents)), + totalSupplyUsd: formatCentsToReadableValue({ + value: totalSupplyCents, + }), + totalBorrowUsd: formatCentsToReadableValue({ + value: totalBorrowCents, + }), + totalLiquidityUsd: formatCentsToReadableValue({ + value: totalLiquidityCents, + }), + totalXvsBuyBackTokens: formatTokensToReadableValue({ + value: totalXvsBuyBackTokens, + token: xvs, + }), marketCount, chainCount, }; diff --git a/apps/landing/src/assets/styles/index.css b/apps/landing/src/assets/styles/index.css index 9c78cd10bb..b6c7e1a2ae 100644 --- a/apps/landing/src/assets/styles/index.css +++ b/apps/landing/src/assets/styles/index.css @@ -27,7 +27,7 @@ p { font-size: 1rem; @media (min-width: 1280px) { - font-size: 1.2rem; + font-size: 1.125rem; } } diff --git a/apps/landing/src/components/MainContent/Background.module.css b/apps/landing/src/components/MainContent/Background.module.css index 551255b507..98b8a5de9a 100644 --- a/apps/landing/src/components/MainContent/Background.module.css +++ b/apps/landing/src/components/MainContent/Background.module.css @@ -1,19 +1,15 @@ .bg { - background-image: url('./assets/bgMobile.png'); - background-size: 100% 862px; - background-repeat: no-repeat; - background-position: right top; - - @media (min-width: 640px) { - background-image: url('./assets/bg.png'); - background-size: 520px 802px; - } + height: calc(100vh - 40px); + min-height: 760px; + display: flex; + align-items: center; +} +.content { @media (min-width: 840px) { - background-size: 623px 937px; - } - - @media (min-width: 1280px) { - background-size: 950px 1400px; + display: flex; + align-items: center; + justify-content: space-between; + gap: 24px; } } diff --git a/apps/landing/src/components/MainContent/Background.tsx b/apps/landing/src/components/MainContent/Background.tsx index 313b3b514f..77ea03f884 100644 --- a/apps/landing/src/components/MainContent/Background.tsx +++ b/apps/landing/src/components/MainContent/Background.tsx @@ -1,7 +1,8 @@ import { cn } from '@venusprotocol/ui'; -import Market from '../Market/Market'; +import Container from '../Container/Container'; import s from './Background.module.css'; import Intro from './Intro'; +import Market from './Market'; interface IMainContentProps { className?: string; @@ -9,8 +10,10 @@ interface IMainContentProps { const Background: React.FC = ({ className }) => (
- - + + + +
); diff --git a/apps/landing/src/components/MainContent/Cell.module.css b/apps/landing/src/components/MainContent/Cell.module.css new file mode 100644 index 0000000000..5326d5e00d --- /dev/null +++ b/apps/landing/src/components/MainContent/Cell.module.css @@ -0,0 +1,48 @@ +.root { + display: flex; + flex-direction: column; + gap: 4px; + + @media (min-width: 840px) { + border-bottom: 1px solid rgba(255,255,255,0.2); + border-style: dashed; + padding-bottom: 16px; + } + + @media (min-width: 1280px) { + padding-bottom: 24px; + } +} + +.root:nth-child(odd) { + @media (min-width: 840px) { + padding-right: 24px; + } + + @media (min-width: 1280px) { + padding-right: 40px; + } +} + +.root:nth-child(even) { + @media (min-width: 840px) { + padding-left: 24px; + } + + @media (min-width: 1280px) { + padding-left: 40px; + } +} + +.label { + font-size: 14px; + color: rgb(var(--color-grey)); + white-space: nowrap; +} + +.value { + font-size: 24px; + font-weight: 700; + color: rgb(var(--color-offWhite)); + white-space: nowrap; +} diff --git a/apps/landing/src/components/MainContent/Cell.tsx b/apps/landing/src/components/MainContent/Cell.tsx new file mode 100644 index 0000000000..6df226cbff --- /dev/null +++ b/apps/landing/src/components/MainContent/Cell.tsx @@ -0,0 +1,16 @@ +import s from './Cell.module.css'; + +export interface ICellProps { + label: string; + value: string | number; +} + +const Cell: React.FC = ({ label, value }) => ( +
+

{label}

+ +

{value}

+
+); + +export default Cell; diff --git a/apps/landing/src/components/MainContent/ChainIcon.module.css b/apps/landing/src/components/MainContent/ChainIcon.module.css new file mode 100644 index 0000000000..3e3b9c4765 --- /dev/null +++ b/apps/landing/src/components/MainContent/ChainIcon.module.css @@ -0,0 +1,31 @@ +.root { + display: flex; + align-items: center; + width: 32px; + height: 32px; + border-radius: 999px; + flex-shrink: 0; + overflow: hidden; +} + +.logoContainer { + height: 32px; + width: 32px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 999px; + flex-shrink: 0; +} + +.logo { + width: 20px; + height: 20px; + flex-shrink: 0; +} + +.name { + font-size: 14px; + padding-right: 10px; + white-space: nowrap; +} \ No newline at end of file diff --git a/apps/landing/src/components/MainContent/ChainIcon.tsx b/apps/landing/src/components/MainContent/ChainIcon.tsx new file mode 100644 index 0000000000..6c51c96a9b --- /dev/null +++ b/apps/landing/src/components/MainContent/ChainIcon.tsx @@ -0,0 +1,107 @@ +import { MainnetChainId } from '@venusprotocol/chains'; +import { motion } from 'motion/react'; + +import s from './ChainIcon.module.css'; +import arbitrumLogoSrc from './assets/arbitrum.svg'; +import baseLogoSrc from './assets/base.svg'; +import bnbChainLogoSrc from './assets/bnbChain.svg'; +import ethereumLogoSrc from './assets/ethereum.svg'; +import opBnbLogoSrc from './assets/opBnb.svg'; +import optimismLogoSrc from './assets/optimism.svg'; +import unichainLogoSrc from './assets/unichain.svg'; +import zkSyncLogoSrc from './assets/zkSync.svg'; + +const chainLogoMap: { + [chainId in MainnetChainId]: { + logoSrc: string; + name: string; + color: string; + }; +} = { + [MainnetChainId.ARBITRUM_ONE]: { + logoSrc: arbitrumLogoSrc, + name: 'Arbitrum One', + color: '#2D3C52', + }, + [MainnetChainId.BASE_MAINNET]: { + logoSrc: baseLogoSrc, + name: 'Base', + color: '#2066FF', + }, + [MainnetChainId.BSC_MAINNET]: { + logoSrc: bnbChainLogoSrc, + name: 'BNB Chain', + color: '#F0B90B', + }, + [MainnetChainId.ETHEREUM]: { + logoSrc: ethereumLogoSrc, + name: 'Ethereum', + color: '#3A78FE', + }, + [MainnetChainId.OPBNB_MAINNET]: { + logoSrc: opBnbLogoSrc, + name: 'opBNB', + color: '#2D3C52', + }, + [MainnetChainId.OPTIMISM_MAINNET]: { + logoSrc: optimismLogoSrc, + name: 'Optimism', + color: '#E93430', + }, + [MainnetChainId.UNICHAIN_MAINNET]: { + logoSrc: unichainLogoSrc, + name: 'Unichain', + color: '#E736A1', + }, + [MainnetChainId.ZKSYNC_MAINNET]: { + logoSrc: zkSyncLogoSrc, + name: 'ZKsync', + color: '#3A78FF', + }, +}; + +export interface IChainIconProps { + chainId: MainnetChainId; + isOpen: boolean; + onMouseEnter: () => void; + onMouseLeave: () => void; +} + +const ChainIcon: React.FC = ({ isOpen, onMouseEnter, onMouseLeave, chainId }) => { + const chain = chainLogoMap[chainId]; + + return ( + +
+ {`${chain.name} +
+ + + {chain.name} + +
+ ); +}; + +export default ChainIcon; diff --git a/apps/landing/src/components/MainContent/Intro.module.css b/apps/landing/src/components/MainContent/Intro.module.css index 80b00000ab..a5c12546be 100644 --- a/apps/landing/src/components/MainContent/Intro.module.css +++ b/apps/landing/src/components/MainContent/Intro.module.css @@ -1,17 +1,10 @@ .intro { - display: flex; - flex-direction: column; - align-items: baseline; position: relative; - padding-top: 224px; - - @media (min-width: 640px) { - justify-content: end; - padding-top: 335px; - } + margin-bottom: 40px; + flex-shrink: 0; - @media (min-width: 1280px) { - padding-top: 462px; + @media (min-width: 840px) { + margin-bottom: 0; } } @@ -44,65 +37,34 @@ } } -.container { - display: flex; - flex-direction: column; - align-items: flex-start; -} - .title { margin-bottom: 16px; - font-size: 2rem; font-variant: all-small-caps; font-weight: 400; + font-size: 32px; line-height: 130%; - letter-spacing: 0.5rem; + letter-spacing: 0.4rem; + @media (min-width: 640px) { - font-size: 2.5rem; + font-size: 40px; + line-height: 110%; + letter-spacing: 0.5rem; } - @media (min-width: 840px) { + + @media (min-width: 1280px) { + font-size: 52px; + line-height: 130%; letter-spacing: 0.65rem; - font-size: 3.25rem; } } .description { color: rgb(var(--color-offWhite)); - font-size: 1rem; line-height: 150%; - margin-bottom: 40px; - letter-spacing: 0.06em; - - @media (min-width: 640px) { - margin-bottom: 48px; - } - - @media (min-width: 840px) { - font-size: 1.125rem; - } -} - -.linkLaunchApp { - margin-bottom: 40px; - - @media (min-width: 640px) { - margin-bottom: 0; - } -} - -.cta { margin-bottom: 32px; - width: 100%; - @media (min-width: 640px) { - display: flex; - align-items: flex-end; - justify-content: space-between; - margin-bottom: 40px; - } - - @media (min-width: 840px) { - margin-bottom: 48px; + @media (min-width: 1280px) { + letter-spacing: 0.06em; } } diff --git a/apps/landing/src/components/MainContent/Intro.tsx b/apps/landing/src/components/MainContent/Intro.tsx index 66466be45f..8bfec80dc0 100644 --- a/apps/landing/src/components/MainContent/Intro.tsx +++ b/apps/landing/src/components/MainContent/Intro.tsx @@ -1,61 +1,20 @@ -import { useDAppUrl } from '../../hooks/useDAppUrl'; -import Container from '../Container/Container'; -import Link from '../Link/Link'; import LinkLaunchApp from '../Link/LinkLaunchApp'; import s from './Intro.module.css'; -import IconArrow from './assets/arrow.svg?react'; function Intro() { - const { dAppUrl } = useDAppUrl(); - - const links = [ - { - text: 'Supply', - href: dAppUrl, - }, - { - text: 'Borrow', - href: dAppUrl, - }, - ]; - return (
- -

- Universal
- Money Markets -

- -

- Simple and powerful community-driven finance
- for the entire globe. -

- -
- +

+ Universal
+ Money Markets +

-
- {links.map(({ text, href }) => ( -
- - {text} +

+ Simple and powerful community-driven finance
+ for the entire globe. +

- - -
- ))} -
-
-
+
); } diff --git a/apps/landing/src/components/MainContent/MainContent.module.css b/apps/landing/src/components/MainContent/MainContent.module.css index 350aedb24c..1adba1a8eb 100644 --- a/apps/landing/src/components/MainContent/MainContent.module.css +++ b/apps/landing/src/components/MainContent/MainContent.module.css @@ -1,5 +1,22 @@ .root { width: 100%; max-width: var(--global-max-width); + background-image: url('./assets/bgMobile.png'); + background-size: 100% 862px; + background-repeat: no-repeat; + background-position: right top; + + @media (min-width: 640px) { + background-image: url('./assets/bg.png'); + background-size: 650px; + } + + @media (min-width: 840px) { + background-size: 900px; + } + + @media (min-width: 1280px) { + background-size: 80%; + } } diff --git a/apps/landing/src/components/MainContent/Market.module.css b/apps/landing/src/components/MainContent/Market.module.css new file mode 100644 index 0000000000..8fbbc8a1b8 --- /dev/null +++ b/apps/landing/src/components/MainContent/Market.module.css @@ -0,0 +1,110 @@ +.root { + border-radius: 16px; + background: rgba(24, 29, 42, 0.10); + box-shadow: 0px 8px 6px 0px rgba(0, 0, 0, 0.05), 0px 1px 1px 0px rgba(255, 255, 255, 0.25) inset, 0px -1px 1px 0px #21293A inset, 2px 3px 3px -3px #5F5A88 inset; + backdrop-filter: blur(25px); + padding: 24px 16px; + flex-grow: 1; + overflow: hidden; + + @media (min-width: 640px) { + padding: 24px; + } + + @media (min-width: 840px) { + padding: 40px 24px; + max-width: 575px; + min-width: 376px; + } + + @media (min-width: 1280px) { + padding: 48px 64px; + display: flex; + flex-direction: column; + justify-content: space-between; + border-radius: 24px; + } +} + +.btn { + margin-top: 24px; + border: none; + display: inline-block; + transition: background-color .3s, border-color .3s, color .3s; + color: white; + text-decoration: none; + padding: 12px 32px; + background-color: rgb(var(--color-blue)); + border-radius: 8px; + + &:hover { + background-color: rgb(var(--color-mediumBlue)); + } + + &:active { + background-color: rgb(var(--color-darkBlue)); + } + +} + +.totalList { + display: flex; + flex-direction: column; + display: grid; + grid-template-columns: 1fr 1fr; + grid-column-gap: 40px; + grid-row-gap: 16px; + padding-bottom: 24px; + margin-bottom: 24px; + border-bottom: 1px solid rgba(255,255,255,0.2); + border-style: dashed; + + @media (min-width: 640px) { + flex-direction: row; + align-items: center; + display: flex; + } + + @media (min-width: 840px) { + display: grid; + border-bottom: 0; + grid-column-gap: 0; + grid-row-gap: 16px; + margin-bottom: 16px; + padding-bottom: 0; + } + + @media (min-width: 1280px) { + grid-row-gap: 24px; + margin-bottom: 24px; + } +} + +.chainCountLabel { + margin-bottom: 16px; + font-size: 14px; +} + +.chainList { + display: flex; + gap: 8px; + overflow: auto; + -ms-overflow-style: none; + scrollbar-width: none; + margin: 0 -15px; + padding: 0 17px; + + @media (min-width: 640px) { + margin: 0 -23px; + padding: 0 25px; + } + + @media (min-width: 1280px) { + margin: 0 -63px; + padding: 0 65px; + } +} + +.chainList::-webkit-scrollbar { + display: none; +} \ No newline at end of file diff --git a/apps/landing/src/components/MainContent/Market.tsx b/apps/landing/src/components/MainContent/Market.tsx new file mode 100644 index 0000000000..2cbcae5b44 --- /dev/null +++ b/apps/landing/src/components/MainContent/Market.tsx @@ -0,0 +1,108 @@ +import { MainnetChainId } from '@venusprotocol/chains'; +import { cn, debounce } from '@venusprotocol/ui'; +import { useMemo, useState } from 'react'; +import { useMediaQuery } from 'usehooks-ts'; + +import { useVenusApi } from '../../api/hooks/useVenusApi'; +import Cell, { type ICellProps } from './Cell'; +import ChainIcon from './ChainIcon'; +import s from './Market.module.css'; + +interface IMarketProps { + className?: string; +} + +const loadingState = 'Loading...'; + +const Market: React.FC = ({ className }) => { + const { data, error: getTvlDataError, refetch } = useVenusApi(); + const [openChainId, setOpenChainId] = useState(); + + const isMdUp = useMediaQuery('(min-width: 840px)'); + + const debouncedSetOpenChainId = useMemo( + () => + debounce({ + fn: setOpenChainId, + delay: 2000, + }), + [], + ); + + const openChainIcon = (chainId: MainnetChainId) => { + setOpenChainId(chainId); + + if (!isMdUp) { + // Automatically close chain after a small delay on mobile and tablets + debouncedSetOpenChainId(undefined); + } + }; + + const cells: ICellProps[] = [ + { + label: 'Total supply', + value: data?.totalSupplyUsd || loadingState, + }, + { + label: 'Total borrow', + value: data?.totalBorrowUsd || loadingState, + }, + { + label: 'Total XVS buyback', + value: data?.totalXvsBuyBackTokens || loadingState, + }, + { + label: 'Assets', + value: data?.marketCount || loadingState, + }, + ]; + + const chainIds = [ + MainnetChainId.BSC_MAINNET, + MainnetChainId.ETHEREUM, + MainnetChainId.OPBNB_MAINNET, + MainnetChainId.UNICHAIN_MAINNET, + MainnetChainId.ARBITRUM_ONE, + MainnetChainId.ZKSYNC_MAINNET, + MainnetChainId.OPTIMISM_MAINNET, + MainnetChainId.BASE_MAINNET, + ]; + + return ( +
+ {getTvlDataError ? ( + <> +

{getTvlDataError.message}

+ + + + ) : ( +
    + {cells.map(cell => ( + + ))} +
+ )} + +

+ {data?.chainCount ? `${data.chainCount} chains` : loadingState} +

+ +
+ {chainIds.map(chainId => ( + openChainIcon(chainId)} + onMouseLeave={() => setOpenChainId(undefined)} + /> + ))} +
+
+ ); +}; + +export default Market; diff --git a/apps/landing/src/components/MainContent/assets/arbitrum.svg b/apps/landing/src/components/MainContent/assets/arbitrum.svg new file mode 100644 index 0000000000..a4bd640b2f --- /dev/null +++ b/apps/landing/src/components/MainContent/assets/arbitrum.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/apps/landing/src/components/MainContent/assets/arrow.svg b/apps/landing/src/components/MainContent/assets/arrow.svg deleted file mode 100644 index 39c163f4ce..0000000000 --- a/apps/landing/src/components/MainContent/assets/arrow.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/apps/landing/src/components/MainContent/assets/base.svg b/apps/landing/src/components/MainContent/assets/base.svg new file mode 100644 index 0000000000..12cf5fe810 --- /dev/null +++ b/apps/landing/src/components/MainContent/assets/base.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/apps/landing/src/components/MainContent/assets/bnbChain.svg b/apps/landing/src/components/MainContent/assets/bnbChain.svg new file mode 100644 index 0000000000..37b4b02acd --- /dev/null +++ b/apps/landing/src/components/MainContent/assets/bnbChain.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/apps/landing/src/components/MainContent/assets/ethereum.svg b/apps/landing/src/components/MainContent/assets/ethereum.svg new file mode 100644 index 0000000000..f1702c58d3 --- /dev/null +++ b/apps/landing/src/components/MainContent/assets/ethereum.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/apps/landing/src/components/MainContent/assets/opBnb.svg b/apps/landing/src/components/MainContent/assets/opBnb.svg new file mode 100644 index 0000000000..feea1ecd0d --- /dev/null +++ b/apps/landing/src/components/MainContent/assets/opBnb.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/apps/landing/src/components/MainContent/assets/optimism.svg b/apps/landing/src/components/MainContent/assets/optimism.svg new file mode 100644 index 0000000000..f4ee40cb77 --- /dev/null +++ b/apps/landing/src/components/MainContent/assets/optimism.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/apps/landing/src/components/MainContent/assets/unichain.svg b/apps/landing/src/components/MainContent/assets/unichain.svg new file mode 100644 index 0000000000..de9f5f8287 --- /dev/null +++ b/apps/landing/src/components/MainContent/assets/unichain.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/apps/landing/src/components/MainContent/assets/zkSync.svg b/apps/landing/src/components/MainContent/assets/zkSync.svg new file mode 100644 index 0000000000..8a16030875 --- /dev/null +++ b/apps/landing/src/components/MainContent/assets/zkSync.svg @@ -0,0 +1,4 @@ + + + + diff --git a/apps/landing/src/components/Market/Market.module.css b/apps/landing/src/components/Market/Market.module.css deleted file mode 100644 index 18f6fb1fb5..0000000000 --- a/apps/landing/src/components/Market/Market.module.css +++ /dev/null @@ -1,223 +0,0 @@ -.root { - @media (min-width: 1280px) { - display: flex; - flex-direction: column; - } -} - -.btn { - margin-top: 24px; - border: none; - display: inline-block; - transition: background-color .3s, border-color .3s, color .3s; - color: white; - text-decoration: none; - padding: 12px 32px; - background-color: rgb(var(--color-blue)); - border-radius: 8px; - - &:hover { - background-color: rgb(var(--color-mediumBlue)); - } - - &:active { - background-color: rgb(var(--color-darkBlue)); - } - -} - -.totalWrapper { - border-radius: 16px; - background: rgba(24, 29, 42, 0.10); - box-shadow: 0px 8px 6px 0px rgba(0, 0, 0, 0.05), 0px 1px 1px 0px rgba(255, 255, 255, 0.25) inset, 0px -1px 1px 0px #21293A inset, 2px 3px 3px -3px #5F5A88 inset; - backdrop-filter: blur(50px); - padding: 16px 16px; - width: 100%; - - @media (min-width: 640px) { - padding: 16px 24px; - } - - @media (min-width: 1280px) { - padding: 16px 64px; - } -} - -.totalList { - display: flex; - flex-direction: column; - justify-content: space-between; - width: 100%; - - @media (min-width: 640px) { - flex-direction: row; - align-items: center; - } - - @media (min-width: 1280px) { - align-items: stretch; - } -} - -.totalItem { - &:not(&:first-child) { - border-top: 1px solid rgb(var(--color-lightGrey)); - padding-top: 12px; - margin-top: 16px; - padding-top: 16px; - - @media (min-width: 640px) { - border-top: none; - margin-top: 0; - padding-top: 0; - } - } -} - -.divider { - @media (min-width: 640px) { - display: block; - width: 1px; - height: 60px; - } - @media (min-width: 840px) { - height: 70px; - } -} - -.totalTitle { - color: rgb(var(--color-grey)); - font-size: 14px; - margin-bottom: 8px; -} - -.totalSum { - color: rgb(var(--color-offWhite)); - font-weight: 600; - font-size: 24px; - - @media (min-width: 640px) { - font-size: 18px; - } - - @media (min-width: 840px) { - font-size: 24px; - } -} - -.launchBtnDesktop { - display: none; - @media (min-width: 1280px) { - display: inline-block; - } -} - -.marketsWrapper { - margin-top: 24px; - border-radius: 24px; - padding: 0 4px 0 4px; - @media (min-width: 640px) { - box-shadow: 0px 8px 6px 0px rgba(0, 0, 0, 0.05), 0px 1px 1px 0px rgba(255, 255, 255, 0.25) inset, 0px -1px 1px 0px #21293A inset, 2px 3px 3px -3px #5F5A88 inset; - background: rgba(24, 29, 42, 0.50); - backdrop-filter: blur(50px); - padding: 20px 32px 0 32px; - } - @media (min-width: 840px) { - padding: 40px 24px 0 24px; - } - @media (min-width: 1280px) { - padding: 40px 64px 0 64px; - flex-grow: 1; - } -} - -.marketLabelsDesktop { - display: none; - @media (min-width: 640px) { - display: flex; - padding-bottom: 16px; - } -} - -.marketLabelDesktopItem { - width: 20%; - font-size: 14px; - color: rgb(var(--color-grey)); - &:not(&:first-child) { - text-align: right; - } -} - -.marketItem { - border-radius: 8px; - padding: 12px 8px; - font-size: 14px; - - &+& { - margin-top: 16px; - } - - box-shadow: 0px 8px 6px 0px rgba(0, 0, 0, 0.05), 0px 1px 1px 0px rgba(255, 255, 255, 0.25) inset, 0px -1px 1px 0px #21293A inset, 2px 3px 3px -3px #5F5A88 inset; - background: rgba(24, 29, 42, 0.50); - - @media (min-width: 640px) { - box-shadow: unset; - background: unset; - display: flex; - padding: 24px 0; - } -} -.marketItemSymbol { - padding-bottom: 14px; - border-bottom: 1px solid rgba(255, 255, 255, 0.05); - margin-bottom: 12px; - display: flex; - align-items: center; - - @media (min-width: 640px) { - border-bottom: none; - margin-bottom: 0; - padding-bottom: 0; - width: 20%; - } -} -.icon { - display: inline-block; - width: 24px; - height: 24px; - border-radius: 50%; - margin-right: 8px; - @media (min-width: 640px) { - width: 32px; - height: 32px; - } -} -.marketItemLabel { - color: rgb(var(--color-grey)); - font-size: 12px; - - @media (min-width: 640px) { - display: none; - } -} -.marketItemValuesWrapper { - display: flex; - align-items: center; - flex-grow: 1; -} -.marketItemValue { - color: rgb(var(--color-offWhite)); - display: flex; - flex-direction: column; - width: 25%; - font-size: 0.875rem; - - &:not(&:first-child) { - text-align: right; - } - @media (min-width: 640px) { - text-align: right; - padding-left: 12px; - font-size: 1rem; - } -} diff --git a/apps/landing/src/components/Market/Market.tsx b/apps/landing/src/components/Market/Market.tsx deleted file mode 100644 index 91ff325478..0000000000 --- a/apps/landing/src/components/Market/Market.tsx +++ /dev/null @@ -1,117 +0,0 @@ -import { cn } from '@venusprotocol/ui'; -import { useVenusApi } from '../../api/hooks/useVenusApi'; -import { nFormatter } from '../../api/utils'; -import { useDAppUrl } from '../../hooks/useDAppUrl'; -import Container from '../Container/Container'; -import Link from '../Link/Link'; -import s from './Market.module.css'; - -interface IMarketProps { - className?: string; -} - -const loadingState = 'Loading...'; - -const Market: React.FC = ({ className }) => { - const { - totalSupplyUsd, - totalBorrowUsd, - totalLiquidityUsd, - topMarkets, - isLoading, - errors: { getLegacyPoolMarketsError, getTvlDataError }, - refetch, - } = useVenusApi(); - - const { dAppUrl } = useDAppUrl(); - - if (getLegacyPoolMarketsError || getTvlDataError) { - return ( - - {getLegacyPoolMarketsError &&

{getLegacyPoolMarketsError.message}

} - {getTvlDataError &&

{getTvlDataError.message}

} - -
- ); - } - - return ( - -
-
    -
  • -
    -

    Market size

    -

    {isLoading ? loadingState : totalSupplyUsd}

    -
    -
  • - -
  • -
    -

    Total Borrowed

    -

    {isLoading ? loadingState : totalBorrowUsd}

    -
    -
  • - -
  • -
    -

    Total Liquidity

    -

    {isLoading ? loadingState : totalLiquidityUsd}

    -
    -
  • -
-
- - {isLoading ? ( -

{loadingState}

- ) : ( -
-
- Assets - Market size - Supply APY - Total borrowed - Borrow APY -
- -
    - {topMarkets.map(i => ( -
  • -
    - {i.underlyingSymbol} - {i.underlyingSymbol} -
    -
    -

    - Market size $ - {nFormatter(i.totalSupplyUsd)} -

    -

    - Supply APY - {nFormatter(i.depositApy)}% -

    -

    - Borrowed $ - {nFormatter(i.totalBorrowsUsd)} -

    -

    - Borrow APY - {nFormatter(i.borrowApy)}% -

    -
    -
  • - ))} -
- - - All markets - -
- )} -
- ); -}; - -export default Market; diff --git a/apps/landing/src/components/VenusPrime/VenusPrime.module.css b/apps/landing/src/components/VenusPrime/VenusPrime.module.css index b22f0fd168..7956daab8f 100644 --- a/apps/landing/src/components/VenusPrime/VenusPrime.module.css +++ b/apps/landing/src/components/VenusPrime/VenusPrime.module.css @@ -1,16 +1,3 @@ -.root { - margin-top: 60px; - @media (min-width: 840px) { - margin-top: 80px; - } - @media (min-width: 840px) { - margin-top: 80px; - } - @media (min-width: 1280px) { - margin-top: 100px; - } -} - .card { display: flex; flex-direction: column; @@ -64,14 +51,6 @@ } } -.backgroundImg { - background-size: contain; - background-position: center; - background-repeat: no-repeat; - flex: 1; - min-height: 100%; -} - .textWrapper { display: flex; flex-direction: column; diff --git a/apps/landing/src/components/VenusPrime/assets/venusPrimeLogo640.png b/apps/landing/src/components/VenusPrime/assets/venusPrimeLogo640.png index a972ae550d..37f1be0e2d 100644 Binary files a/apps/landing/src/components/VenusPrime/assets/venusPrimeLogo640.png and b/apps/landing/src/components/VenusPrime/assets/venusPrimeLogo640.png differ diff --git a/apps/landing/src/components/VenusPrime/assets/venusPrimeLogo840.png b/apps/landing/src/components/VenusPrime/assets/venusPrimeLogo840.png index 8925d15fa4..6e6b1f0b85 100644 Binary files a/apps/landing/src/components/VenusPrime/assets/venusPrimeLogo840.png and b/apps/landing/src/components/VenusPrime/assets/venusPrimeLogo840.png differ diff --git a/apps/landing/src/components/VenusPrime/index.tsx b/apps/landing/src/components/VenusPrime/index.tsx index 3e7e75cbe6..5a0b4d4230 100644 --- a/apps/landing/src/components/VenusPrime/index.tsx +++ b/apps/landing/src/components/VenusPrime/index.tsx @@ -1,12 +1,10 @@ -import { cn } from '@venusprotocol/ui'; import Container from '../Container/Container'; import Link from '../Link/Link'; import s from './VenusPrime.module.css'; const VenusPrime: React.FC = () => ( - +
-

diff --git a/packages/ui/package.json b/packages/ui/package.json index c34c7cbba2..3f3267541d 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -25,7 +25,9 @@ "tailwindcss": ">=3.3.0" }, "dependencies": { - "@radix-ui/react-slot": "^1.1.2" + "@radix-ui/react-slot": "^1.1.2", + "bignumber.js": "^9.3.1", + "viem": "^2.34.0" }, "peerDependencies": { "tailwindcss": ">=3.3.0" diff --git a/packages/ui/src/constants/index.ts b/packages/ui/src/constants/index.ts new file mode 100644 index 0000000000..c1d222261c --- /dev/null +++ b/packages/ui/src/constants/index.ts @@ -0,0 +1,5 @@ +export const PLACEHOLDER_KEY = '-'; +export const ONE_THOUSAND = 1000; +export const ONE_MILLION = ONE_THOUSAND * 1000; +export const ONE_BILLION = ONE_MILLION * 1000; +export const ONE_TRILLION = ONE_BILLION * 1000; diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index 33cdfb9f84..fed013369b 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -4,6 +4,11 @@ export * from './tailwind.config'; // Utilities export * from './utilities/cn'; +export * from './utilities/getSmartDecimalPlaces'; +export * from './utilities/shortenValueWithSuffix'; +export * from './utilities/formatCentsToReadableValue'; +export * from './utilities/formatTokensToReadableValue'; +export * from './utilities/debounce'; // Components export * from './components/Button'; diff --git a/packages/ui/src/types.ts b/packages/ui/src/types.ts new file mode 100644 index 0000000000..9d8ee73df5 --- /dev/null +++ b/packages/ui/src/types.ts @@ -0,0 +1,17 @@ +import type { Address } from 'viem'; + +// TODO: import from @venusprotocol/tokens package once it's been created +export interface Token { + symbol: string; + decimals: number; + asset: string; + address: Address; + isNative?: boolean; + tokenWrapped?: Token; +} + +export interface VToken extends Omit { + decimals: 8; // VBep tokens all have 8 decimals + underlyingToken: Token; + asset?: string; +} diff --git a/apps/evm/src/utilities/debounce/index.ts b/packages/ui/src/utilities/debounce/index.ts similarity index 100% rename from apps/evm/src/utilities/debounce/index.ts rename to packages/ui/src/utilities/debounce/index.ts diff --git a/apps/evm/src/utilities/formatCentsToReadableValue/__tests__/index.spec.ts b/packages/ui/src/utilities/formatCentsToReadableValue/__tests__/index.spec.ts similarity index 93% rename from apps/evm/src/utilities/formatCentsToReadableValue/__tests__/index.spec.ts rename to packages/ui/src/utilities/formatCentsToReadableValue/__tests__/index.spec.ts index 1157714fd3..3a465721d3 100644 --- a/apps/evm/src/utilities/formatCentsToReadableValue/__tests__/index.spec.ts +++ b/packages/ui/src/utilities/formatCentsToReadableValue/__tests__/index.spec.ts @@ -1,10 +1,10 @@ import BigNumber from 'bignumber.js'; -import PLACEHOLDER_KEY from 'constants/placeholderKey'; +import { PLACEHOLDER_KEY } from '../../../constants'; -import formatCentsToReadableValue, { type FormatCentsToReadableValueInput } from '..'; +import { type FormatCentsToReadableValueInput, formatCentsToReadableValue } from '..'; -describe('utilities/formatCentsToReadableValue', () => { +describe('formatCentsToReadableValue', () => { it('should return PLACEHOLDER_KEY when value is undefined', () => { const input: FormatCentsToReadableValueInput = { value: undefined, diff --git a/apps/evm/src/utilities/formatCentsToReadableValue/index.ts b/packages/ui/src/utilities/formatCentsToReadableValue/index.ts similarity index 87% rename from apps/evm/src/utilities/formatCentsToReadableValue/index.ts rename to packages/ui/src/utilities/formatCentsToReadableValue/index.ts index efad06d466..b52bb19762 100644 --- a/apps/evm/src/utilities/formatCentsToReadableValue/index.ts +++ b/packages/ui/src/utilities/formatCentsToReadableValue/index.ts @@ -1,8 +1,7 @@ import BigNumber from 'bignumber.js'; -import { ONE_TRILLION } from 'constants/numbers'; -import PLACEHOLDER_KEY from 'constants/placeholderKey'; -import { shortenValueWithSuffix } from 'utilities'; +import { ONE_TRILLION, PLACEHOLDER_KEY } from '../../constants'; +import { shortenValueWithSuffix } from '../shortenValueWithSuffix'; const THRESHOLDS = { DOLLARS: { @@ -22,7 +21,7 @@ export interface FormatCentsToReadableValueInput { isTokenPrice?: boolean; } -const formatCentsToReadableValue = ({ +export const formatCentsToReadableValue = ({ value, isTokenPrice = false, }: FormatCentsToReadableValueInput) => { @@ -62,5 +61,3 @@ const formatCentsToReadableValue = ({ return `${isNegative ? '-' : ''}$${formattedValueDollars}`; }; - -export default formatCentsToReadableValue; diff --git a/apps/evm/src/utilities/formatTokensToReadableValue/__tests__/index.spec.ts b/packages/ui/src/utilities/formatTokensToReadableValue/__tests__/index.spec.ts similarity index 89% rename from apps/evm/src/utilities/formatTokensToReadableValue/__tests__/index.spec.ts rename to packages/ui/src/utilities/formatTokensToReadableValue/__tests__/index.spec.ts index 90bae0f982..2ee282cf97 100644 --- a/apps/evm/src/utilities/formatTokensToReadableValue/__tests__/index.spec.ts +++ b/packages/ui/src/utilities/formatTokensToReadableValue/__tests__/index.spec.ts @@ -1,10 +1,15 @@ import BigNumber from 'bignumber.js'; -import { busd } from '__mocks__/models/tokens'; - -import PLACEHOLDER_KEY from 'constants/placeholderKey'; - -import formatTokensToReadableValue, { type FormatTokensToReadableValueInput } from '..'; +import { type FormatTokensToReadableValueInput, formatTokensToReadableValue } from '..'; +import { PLACEHOLDER_KEY } from '../../../constants'; +import type { Token } from '../../../types'; + +const busd: Token = { + address: '0x8301F2213c0eeD49a7E28Ae4c3e91722919B8B47', + decimals: 18, + symbol: 'BUSD', + asset: '', +}; describe('formatTokensToReadableValue', () => { test('should return placeholder when value is undefined', () => { diff --git a/apps/evm/src/utilities/formatTokensToReadableValue/index.ts b/packages/ui/src/utilities/formatTokensToReadableValue/index.ts similarity index 84% rename from apps/evm/src/utilities/formatTokensToReadableValue/index.ts rename to packages/ui/src/utilities/formatTokensToReadableValue/index.ts index 18a3c3c83a..e170848ea3 100644 --- a/apps/evm/src/utilities/formatTokensToReadableValue/index.ts +++ b/packages/ui/src/utilities/formatTokensToReadableValue/index.ts @@ -1,10 +1,8 @@ +import { shortenValueWithSuffix } from '@venusprotocol/ui'; import BigNumber from 'bignumber.js'; -import { ONE_TRILLION } from 'constants/numbers'; -import PLACEHOLDER_KEY from 'constants/placeholderKey'; -import type { Token, VToken } from 'types'; - -import shortenValueWithSuffix from '../shortenValueWithSuffix'; +import { ONE_TRILLION, PLACEHOLDER_KEY } from '../../constants'; +import type { Token, VToken } from '../../types'; const MIN_VALUE = 0.000001; const MAX_VALUE = 100 * ONE_TRILLION; @@ -59,5 +57,3 @@ export const formatTokensToReadableValue = ({ return readableValue; }; - -export default formatTokensToReadableValue; diff --git a/apps/evm/src/utilities/getSmartDecimalPlaces/__tests__/index.spec.ts b/packages/ui/src/utilities/getSmartDecimalPlaces/__tests__/index.spec.ts similarity index 92% rename from apps/evm/src/utilities/getSmartDecimalPlaces/__tests__/index.spec.ts rename to packages/ui/src/utilities/getSmartDecimalPlaces/__tests__/index.spec.ts index 490ae11ce5..ae5ae4fac9 100644 --- a/apps/evm/src/utilities/getSmartDecimalPlaces/__tests__/index.spec.ts +++ b/packages/ui/src/utilities/getSmartDecimalPlaces/__tests__/index.spec.ts @@ -1,8 +1,8 @@ import BigNumber from 'bignumber.js'; -import getSmartDecimalPlaces from '..'; +import { getSmartDecimalPlaces } from '..'; -describe('utilities/getSmartDecimalPlaces', () => { +describe('getSmartDecimalPlaces', () => { it('should work with zero and return 0', () => { expect(getSmartDecimalPlaces({ value: new BigNumber('0') })).toBe(0); }); diff --git a/apps/evm/src/utilities/getSmartDecimalPlaces/index.ts b/packages/ui/src/utilities/getSmartDecimalPlaces/index.ts similarity index 89% rename from apps/evm/src/utilities/getSmartDecimalPlaces/index.ts rename to packages/ui/src/utilities/getSmartDecimalPlaces/index.ts index 7280a76a25..9a192aa2fb 100644 --- a/apps/evm/src/utilities/getSmartDecimalPlaces/index.ts +++ b/packages/ui/src/utilities/getSmartDecimalPlaces/index.ts @@ -1,6 +1,6 @@ import type BigNumber from 'bignumber.js'; -const getSmartDecimalPlaces = ({ +export const getSmartDecimalPlaces = ({ value, maxDecimalPlaces, }: { @@ -26,5 +26,3 @@ const getSmartDecimalPlaces = ({ const decimals = fixedValue.substring(dotIndex + 1); return decimals.length; }; - -export default getSmartDecimalPlaces; diff --git a/apps/evm/src/utilities/shortenValueWithSuffix/__tests__/index.spec.ts b/packages/ui/src/utilities/shortenValueWithSuffix/__tests__/index.spec.ts similarity index 98% rename from apps/evm/src/utilities/shortenValueWithSuffix/__tests__/index.spec.ts rename to packages/ui/src/utilities/shortenValueWithSuffix/__tests__/index.spec.ts index 73e22b65bd..aa1242e09e 100644 --- a/apps/evm/src/utilities/shortenValueWithSuffix/__tests__/index.spec.ts +++ b/packages/ui/src/utilities/shortenValueWithSuffix/__tests__/index.spec.ts @@ -1,6 +1,6 @@ import BigNumber from 'bignumber.js'; -import shortenValueWithSuffix from '..'; +import { shortenValueWithSuffix } from '..'; describe('shortenValueWithSuffix', () => { it('should return a formatted value in billions with "T" suffix when value is greater or equal to one trillion', () => { diff --git a/apps/evm/src/utilities/shortenValueWithSuffix/index.ts b/packages/ui/src/utilities/shortenValueWithSuffix/index.ts similarity index 88% rename from apps/evm/src/utilities/shortenValueWithSuffix/index.ts rename to packages/ui/src/utilities/shortenValueWithSuffix/index.ts index 71ab0cd439..76257a15d3 100644 --- a/apps/evm/src/utilities/shortenValueWithSuffix/index.ts +++ b/packages/ui/src/utilities/shortenValueWithSuffix/index.ts @@ -1,7 +1,7 @@ import BigNumber from 'bignumber.js'; -import { ONE_BILLION, ONE_MILLION, ONE_THOUSAND, ONE_TRILLION } from 'constants/numbers'; -import getSmartDecimalPlaces from 'utilities/getSmartDecimalPlaces'; +import { ONE_BILLION, ONE_MILLION, ONE_THOUSAND, ONE_TRILLION } from '../../constants'; +import { getSmartDecimalPlaces } from '../getSmartDecimalPlaces'; const LARGE_VALUE_MAX_DECIMAL_PLACES = 2; @@ -11,7 +11,7 @@ export interface ShortenValueWithSuffix { roundingMode?: BigNumber.RoundingMode; } -const shortenValueWithSuffix = ({ +export const shortenValueWithSuffix = ({ value, maxDecimalPlaces, roundingMode, @@ -42,5 +42,3 @@ const shortenValueWithSuffix = ({ return `${new BigNumber(formattedValue).toFormat(decimalPlaces, roundingMode)}${suffix}`; }; - -export default shortenValueWithSuffix; diff --git a/yarn.lock b/yarn.lock index bc7448da25..dcad1ce33b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1425,7 +1425,7 @@ resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.4.0.tgz#c9299c34d248bc26e82563735f78953d2efca83c" integrity sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg== -"@emotion/styled@^11.0.0", "@emotion/styled@^11.11.0": +"@emotion/styled@^11.11.0": version "11.14.1" resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.14.1.tgz#8c34bed2948e83e1980370305614c20955aacd1c" integrity sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw== @@ -4438,7 +4438,7 @@ dependencies: semver "^7.3.5" -"@openzeppelin-3/contracts@npm:@openzeppelin/contracts@^3.4.2-solc-0.7": +"@openzeppelin-3/contracts@npm:@openzeppelin/contracts@^3.4.2-solc-0.7", "@openzeppelin/contracts-v0.7@npm:@openzeppelin/contracts@v3.4.2": version "3.4.2" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.4.2.tgz#d81f786fda2871d1eb8a8c5a73e455753ba53527" integrity sha512-z0zMCjyhhp4y7XKAcDAi3Vgms4T2PstwBdahiO0+9NaGICQKjynK3wduSRplTgk4LXmoO1yfDGO5RbjKYxtuxA== @@ -4453,11 +4453,6 @@ resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.9.5.tgz#572b5da102fc9be1d73f34968e0ca56765969812" integrity sha512-f7L1//4sLlflAN7fVzJLoRedrf5Na3Oal5PZfIq55NFcVZ90EpV1q5xOvL4lFvg3MNICSDr2hH0JUBxwlxcoPg== -"@openzeppelin/contracts-v0.7@npm:@openzeppelin/contracts@v3.4.2": - version "3.4.2" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.4.2.tgz#d81f786fda2871d1eb8a8c5a73e455753ba53527" - integrity sha512-z0zMCjyhhp4y7XKAcDAi3Vgms4T2PstwBdahiO0+9NaGICQKjynK3wduSRplTgk4LXmoO1yfDGO5RbjKYxtuxA== - "@openzeppelin/contracts@3.4.2-solc-0.7": version "3.4.2-solc-0.7" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.4.2-solc-0.7.tgz#38f4dbab672631034076ccdf2f3201fab1726635" @@ -7684,7 +7679,7 @@ bigint-crypto-utils@^3.0.23: resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.3.0.tgz#72ad00ae91062cf07f2b1def9594006c279c1d77" integrity sha512-jOTSb+drvEDxEq6OuUybOAv/xxoh3cuYRUIPyu8sSHQNKM303UQ2R1DAo45o1AkcIXw6fzbaFI1+xGGdaXs2lg== -bignumber.js@^9.1.1, bignumber.js@^9.1.2: +bignumber.js@^9.1.1, bignumber.js@^9.1.2, bignumber.js@^9.3.1: version "9.3.1" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.3.1.tgz#759c5aaddf2ffdc4f154f7b493e1c8770f88c4d7" integrity sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ== @@ -10322,6 +10317,15 @@ framer-motion@^12.17.0: motion-utils "^12.12.1" tslib "^2.4.0" +framer-motion@^12.23.12: + version "12.23.12" + resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-12.23.12.tgz#80cf6fd7c111073a0c558e336c85ca36cca80d3d" + integrity sha512-6e78rdVtnBvlEVgu6eFEAgG9v3wLnYEboM8I5O5EXvfKC8gxGQB8wXJdhkMy10iVcn05jl6CNw7/HTsTCfwcWg== + dependencies: + motion-dom "^12.23.12" + motion-utils "^12.23.6" + tslib "^2.4.0" + framer-motion@^6.3.11: version "6.5.1" resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-6.5.1.tgz#802448a16a6eb764124bf36d8cbdfa6dd6b931a7" @@ -12497,6 +12501,11 @@ lodash.camelcase@^4.3.0: resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== + lodash.defaults@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" @@ -13408,11 +13417,23 @@ motion-dom@^12.17.0: dependencies: motion-utils "^12.12.1" +motion-dom@^12.23.12: + version "12.23.12" + resolved "https://registry.yarnpkg.com/motion-dom/-/motion-dom-12.23.12.tgz#87974046e7e61bc4932f36d35e8eab6bb6f3e434" + integrity sha512-RcR4fvMCTESQBD/uKQe49D5RUeDOokkGRmz4ceaJKDBgHYtZtntC/s2vLvY38gqGaytinij/yi3hMcWVcEF5Kw== + dependencies: + motion-utils "^12.23.6" + motion-utils@^12.12.1: version "12.12.1" resolved "https://registry.yarnpkg.com/motion-utils/-/motion-utils-12.12.1.tgz#63e28751325cb9d1cd684f3c273a570022b0010e" integrity sha512-f9qiqUHm7hWSLlNW8gS9pisnsN7CRFRD58vNjptKdsqFLpkVnX00TNeD6Q0d27V9KzT7ySFyK1TZ/DShfVOv6w== +motion-utils@^12.23.6: + version "12.23.6" + resolved "https://registry.yarnpkg.com/motion-utils/-/motion-utils-12.23.6.tgz#fafef80b4ea85122dd0d6c599a0c63d72881f312" + integrity sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ== + motion@^12.0.3: version "12.17.0" resolved "https://registry.yarnpkg.com/motion/-/motion-12.17.0.tgz#a3ecf7a229f773090d190aa32ac2eb46d4101916" @@ -13421,6 +13442,14 @@ motion@^12.0.3: framer-motion "^12.17.0" tslib "^2.4.0" +motion@^12.23.12: + version "12.23.12" + resolved "https://registry.yarnpkg.com/motion/-/motion-12.23.12.tgz#9f3552636c1e94911eee42e6f85db8f60db83c19" + integrity sha512-8jCD8uW5GD1csOoqh1WhH1A6j5APHVE15nuBkFeRiMzYBdRwyAHmSP/oXSuW0WJPZRXTFdBoG4hY9TFWNhhwng== + dependencies: + framer-motion "^12.23.12" + tslib "^2.4.0" + mri@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b" @@ -14797,10 +14826,10 @@ react-dom@^19.1.0: dependencies: scheduler "^0.26.0" -react-error-overlay@6.0.11, react-error-overlay@6.1.0: - version "6.0.11" - resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.11.tgz#92835de5841c5cf08ba00ddd2d677b6d17ff9adb" - integrity sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg== +react-error-overlay@6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.1.0.tgz#22b86256beb1c5856f08a9a228adb8121dd985f2" + integrity sha512-SN/U6Ytxf1QGkw/9ve5Y+NxBbZM6Ht95tuXNMKs8EJyFa/Vy/+Co3stop3KBHARfn/giv+Lj1uUnTfOJ3moFEQ== react-fast-compare@^2.0.1: version "2.0.4" @@ -15963,16 +15992,7 @@ string-env-interpolation@^1.0.1: resolved "https://registry.yarnpkg.com/string-env-interpolation/-/string-env-interpolation-1.0.1.tgz#ad4397ae4ac53fe6c91d1402ad6f6a52862c7152" integrity sha512-78lwMoCcn0nNu8LszbP1UA7g55OeE4v7rCeWnM5B453rnNr4aq+5it3FEYtZrSEiMvHZOZ9Jlqb0OD0M2VInqg== -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -16012,7 +16032,7 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -16026,13 +16046,6 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^7.0.1, strip-ansi@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" @@ -17113,6 +17126,13 @@ use-sync-external-store@1.4.0: resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz#adbc795d8eeb47029963016cefdf89dc799fcebc" integrity sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw== +usehooks-ts@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/usehooks-ts/-/usehooks-ts-3.1.1.tgz#0bb7f38f36f8219ee4509cc5e944ae610fb97656" + integrity sha512-I4diPp9Cq6ieSUH2wu+fDAVQO43xwtulo+fKEidHUwZPnYImbtkTjzIJYcDcJqxgmX31GVqNFURodvcgHcW0pA== + dependencies: + lodash.debounce "^4.0.8" + utf-8-validate@^5.0.2: version "5.0.9" resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.9.tgz#ba16a822fbeedff1a58918f2a6a6b36387493ea3" @@ -17261,7 +17281,7 @@ viem@2.23.2: ox "0.6.7" ws "8.18.0" -viem@>=2.29.0, viem@^2.1.1, viem@^2.22.23, viem@^2.23.1, viem@^2.27.2, viem@^2.31.7: +viem@>=2.29.0, viem@^2.1.1, viem@^2.22.23, viem@^2.23.1, viem@^2.27.2, viem@^2.31.7, viem@^2.34.0: version "2.34.0" resolved "https://registry.yarnpkg.com/viem/-/viem-2.34.0.tgz#566b15838d3121d03eaa9bdb2b8bf9b86c37d152" integrity sha512-HJZG9Wt0DLX042MG0PK17tpataxtdAEhpta9/Q44FqKwy3xZMI5Lx4jF+zZPuXFuYjZ68R0PXqRwlswHs6r4gA== @@ -17593,7 +17613,7 @@ workerpool@6.2.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -17611,15 +17631,6 @@ wrap-ansi@^6.0.1, wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"