diff --git a/features/earn/shared/v2/vault-card/index.ts b/features/earn/shared/v2/vault-card/index.ts index d221a6a1e..d13328412 100644 --- a/features/earn/shared/v2/vault-card/index.ts +++ b/features/earn/shared/v2/vault-card/index.ts @@ -1 +1,2 @@ export * from './vault-card'; +export * from './legacy-vault-card'; diff --git a/features/earn/shared/v2/vault-card/legacy-vault-card.tsx b/features/earn/shared/v2/vault-card/legacy-vault-card.tsx new file mode 100644 index 000000000..81aa198a6 --- /dev/null +++ b/features/earn/shared/v2/vault-card/legacy-vault-card.tsx @@ -0,0 +1,170 @@ +import React from 'react'; +import { Button } from '@lidofinance/lido-ui'; + +import { + CardWrapper, + CardOverlayLink, + CardHeader, + CardHeaderContent, + CardTitle, + CardDescription, + CardStats, + StatItem, + StatLabel, + StatValue, + CardDivider, + CardCta, + VaultIconWrapper, + CardTitleBadge, + ChevronsUpIcon, + StyledTooltip, + BadgeStyled, + TitleTextStyled, +} from './styles'; +import { LocalLink } from 'shared/components/local-link'; +import { EARN_PATH } from 'consts/urls'; +import { EARN_VAULT_DEPOSIT_SLUG } from 'features/earn/consts'; +import { FormatPercent } from 'shared/formatters/format-percent'; +import { FormatLargeAmount } from 'shared/formatters/format-large-amount'; +import { FormatToken } from 'shared/formatters/format-token'; +import { Badge } from 'features/earn/shared/badge'; +import { getTokenDecimals } from 'utils/token-decimals'; +import { useConfig } from 'config/use-config'; +import { InlineLoader } from '../../inline-loader'; +import { VaultTip } from '../../vault-tip'; + +type VaultStats = { + tvl?: number | null; + apx?: number | null; + apxLabel: string; + isLoading?: boolean; + apxHint?: React.ReactNode; +}; + +type LegacyVaultPosition = { + sharesBalance?: bigint; + sharesSymbol: string; + isLoading?: boolean; +}; + +type LegacyVaultCardProps = { + title: string; + description?: string; + urlSlug: string; + stats: VaultStats; + ctaLabel: string; + position?: LegacyVaultPosition; + variant?: 'eth' | 'usd' | 'default'; + illustration?: React.ReactNode; + depositLinkCallback?: () => void; + protectedBadgeTooltipText?: React.ReactNode; +}; + +export const LegacyVaultCard: React.FC = ({ + title, + description, + urlSlug, + stats, + position, + ctaLabel, + variant = 'default', + illustration, + depositLinkCallback, + protectedBadgeTooltipText, +}) => { + const isDeprecated = useConfig().externalConfig.earnVaults.find( + (vault) => vault.name === urlSlug, + )?.deprecated; + + const depositHref = `${EARN_PATH}/${urlSlug}/${EARN_VAULT_DEPOSIT_SLUG}`; + + return ( + + + + + + {title} + {protectedBadgeTooltipText && ( + + + + )} + {isDeprecated && ( + + }> + {' '} + Upgrading + + + )} + + {description} + + {illustration} + + + + + + {stats.apxLabel} + + {stats.apxHint} + + + + + + + + + + TVL + + + + + + + {!!position?.sharesBalance && ( + + My position + + + + + + + )} + + + + + + + + ); +}; diff --git a/features/earn/shared/v2/vault-card/styles.tsx b/features/earn/shared/v2/vault-card/styles.tsx index 77e49904d..ee984b05c 100644 --- a/features/earn/shared/v2/vault-card/styles.tsx +++ b/features/earn/shared/v2/vault-card/styles.tsx @@ -223,6 +223,17 @@ export const StatValueIcon = styled.span` height: 24px; `; +export const StatSubValue = styled.span` + color: var(--lido-color-textSecondary); + font-size: ${({ theme }) => theme.fontSizesMap.xs}px; + font-weight: 400; + line-height: 24px; + + ${({ theme }) => theme.mediaQueries.md} { + display: none; + } +`; + export const CardCta = styled.div` margin-top: 32px; `; diff --git a/features/earn/shared/v2/vault-card/vault-card.tsx b/features/earn/shared/v2/vault-card/vault-card.tsx index 18cc24f84..85db15584 100644 --- a/features/earn/shared/v2/vault-card/vault-card.tsx +++ b/features/earn/shared/v2/vault-card/vault-card.tsx @@ -17,7 +17,6 @@ import { VaultIconWrapper, CardTitleBadge, ChevronsUpIcon, - StatValueIcon, StyledTooltip, BadgeStyled, TitleTextStyled, @@ -45,12 +44,11 @@ type VaultStats = { }; type VaultPosition = { - balance?: bigint; - claimable?: bigint; - pending?: Array<{ tokenSymbol: string; amount: bigint }>; + sharesBalance?: bigint; + sharesSymbol: string; + baseAmount?: bigint; + baseSymbol: string; isLoading?: boolean; - symbol: string; - icon?: React.ReactNode; }; type VaultCardProps = { @@ -137,7 +135,7 @@ export const VaultCard: React.FC = ({ {stats.apxLabel} {stats.apxHint} @@ -157,22 +155,34 @@ export const VaultCard: React.FC = ({ - {!!position?.balance && ( + {!!position?.sharesBalance && ( - My position + + My deposit + + You hold{' '} + + . Shown in {position.baseSymbol} at current conversion rates. + + - {position.icon && ( - {position.icon} - )} diff --git a/features/earn/shared/v2/vault-page/content/styles.tsx b/features/earn/shared/v2/vault-page/content/styles.tsx index 11c2b341f..160d809b4 100644 --- a/features/earn/shared/v2/vault-page/content/styles.tsx +++ b/features/earn/shared/v2/vault-page/content/styles.tsx @@ -69,16 +69,24 @@ export const TopSectionDescription = styled.p` export const TopSectionStatsRow = styled.div` display: flex; gap: ${({ theme }) => theme.spaceMap.md}px; - max-width: 300px; + + ${({ theme }) => theme.mediaQueries.md} { + flex-direction: column; + } `; export const TopSectionStatItem = styled.div` display: flex; flex-direction: column; + flex: 0 0 160px; gap: 4px; - &:first-child { - flex: 1; + ${({ theme }) => theme.mediaQueries.md} { + flex-direction: row; + justify-content: space-between; + align-items: flex-start; + flex: unset; + gap: ${({ theme }) => theme.spaceMap.sm}px; } `; @@ -91,6 +99,22 @@ export const TopSectionStatLabel = styled.span` line-height: 24px; `; +export const TopSectionStatValueGroup = styled.div` + display: flex; + flex-direction: column; + + ${({ theme }) => theme.mediaQueries.md} { + align-items: flex-end; + } +`; + +export const TopSectionStatSubValue = styled.span` + color: var(--lido-color-textSecondary); + font-size: ${({ theme }) => theme.fontSizesMap.xs}px; + font-weight: 400; + line-height: 24px; +`; + export const TopSectionStatValue = styled.span<{ $accent?: boolean }>` font-weight: 700; font-size: ${({ theme }) => theme.fontSizesMap.lg}px; @@ -99,7 +123,7 @@ export const TopSectionStatValue = styled.span<{ $accent?: boolean }>` $accent ? 'var(--lido-color-success)' : 'var(--lido-color-text)'}; ${({ theme }) => theme.mediaQueries.md} { - font-size: ${({ theme }) => theme.fontSizesMap.sm}px; + font-size: ${({ theme }) => theme.fontSizesMap.xs}px; line-height: 24px; } `; diff --git a/features/earn/shared/v2/vault-page/content/top-section.tsx b/features/earn/shared/v2/vault-page/content/top-section.tsx index 80c540a9c..11e50f3ee 100644 --- a/features/earn/shared/v2/vault-page/content/top-section.tsx +++ b/features/earn/shared/v2/vault-page/content/top-section.tsx @@ -1,9 +1,15 @@ import type { ComponentType, FC, SVGProps } from 'react'; -import { FormatLargeAmount, FormatPercent } from 'shared/formatters'; +import { + FormatLargeAmount, + FormatPercent, + FormatToken, +} from 'shared/formatters'; +import { FormatPrice } from 'shared/formatters/format-price'; import { InlineLoader } from 'features/earn/shared/inline-loader'; import { VaultTip } from 'features/earn/shared/vault-tip'; import { Badge } from 'features/earn/shared/badge'; +import { getTokenDecimals } from 'utils/token-decimals'; import { TopSectionStyled, @@ -15,10 +21,22 @@ import { TopSectionStatsRow, TopSectionStatItem, TopSectionStatLabel, + TopSectionStatSubValue, TopSectionStatValue, + TopSectionStatValueGroup, } from './styles'; type VaultIllustration = ComponentType>; + +export type VaultBalanceProp = { + amount?: bigint; + symbol: string; + sharesAmount?: bigint; + sharesSymbol: string; + usdAmount?: number; + isLoading?: boolean; +}; + type TopSectionProps = { logo: VaultIllustration; title: string; @@ -29,6 +47,7 @@ type TopSectionProps = { isApxLoading?: boolean; isTvlLoading?: boolean; protectedBadgeTooltipText?: React.ReactNode; + balance?: VaultBalanceProp; }; export const TopSection: FC = (props) => { @@ -41,6 +60,7 @@ export const TopSection: FC = (props) => { isApxLoading, isTvlLoading, protectedBadgeTooltipText, + balance, } = props; return ( @@ -61,7 +81,7 @@ export const TopSection: FC = (props) => { APY* (7d avg.) - {apxHint} + {apxHint} @@ -77,6 +97,43 @@ export const TopSection: FC = (props) => { + {!!balance?.sharesAmount && ( + + + My deposit + + You hold{' '} + + .{' '} + {balance.usdAmount != null + ? `Shown in ${balance.symbol} and USD at current conversion rates.` + : `Shown in ${balance.symbol} at current conversion rates.`} + + + + + + + + + {!balance.isLoading && balance.usdAmount != null && ( + + + + )} + + + )} ); diff --git a/features/earn/shared/v2/vault-page/vault-page.tsx b/features/earn/shared/v2/vault-page/vault-page.tsx index 9ee8cac50..c2d5c6e2b 100644 --- a/features/earn/shared/v2/vault-page/vault-page.tsx +++ b/features/earn/shared/v2/vault-page/vault-page.tsx @@ -15,6 +15,7 @@ import { useInpageNavigation } from 'providers/inpage-navigation'; import { VaultChart } from '../vault-chart'; +import type { VaultBalanceProp } from './content/top-section'; import { SidePanel } from './side-panel'; import { VaultPageContent } from './content'; import { TopSection } from './content/top-section'; @@ -62,6 +63,7 @@ type Props = { riskDisclosure: ReactNode; strategyContent?: ReactNode; faqContent?: ReactNode; + balance?: VaultBalanceProp; matomo?: { performanceTabEvent?: MATOMO_EVENT_TYPE; strategyTabEvent?: MATOMO_EVENT_TYPE; @@ -131,6 +133,7 @@ export const VaultPage: FC = (props) => { isApxLoading={props.isApxLoading} isTvlLoading={props.isTvlLoading} protectedBadgeTooltipText={protectedBadgeTooltipText} + balance={props.balance} /> diff --git a/features/earn/shared/v2/vault-position/index.ts b/features/earn/shared/v2/vault-position/index.ts deleted file mode 100644 index 827cf6ffc..000000000 --- a/features/earn/shared/v2/vault-position/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './vault-position'; diff --git a/features/earn/shared/v2/vault-position/styles.ts b/features/earn/shared/v2/vault-position/styles.ts deleted file mode 100644 index 4a57d0ca7..000000000 --- a/features/earn/shared/v2/vault-position/styles.ts +++ /dev/null @@ -1,83 +0,0 @@ -import styled, { css } from 'styled-components'; - -export const PositionContainer = styled.div` - display: flex; - flex-direction: column; - border-radius: ${({ theme }) => theme.borderRadiusesMap.lg}px; - gap: ${({ theme }) => theme.spaceMap.lg}px; - background-color: ${({ theme }) => - theme.name === 'light' ? `#F6F7F8` : 'var(--lido-color-controlBg)'}; -`; - -export const PositionEntry = styled.div` - display: flex; - flex-direction: column; - gap: ${({ theme }) => theme.spaceMap.sm}px; -`; - -export const PositionEntryTitle = styled.h3` - color: ${({ theme }) => theme.colors.textSecondary}; - font-size: 12px; - font-style: normal; - font-weight: 400; - - & > svg { - width: 20px; - height: 20px; - aspect-ratio: 1/1; - vertical-align: bottom; - } -`; - -export const PositionEntryBody = styled.div<{ - compact?: boolean; -}>` - display: grid; - gap: 0px 8px; - grid-template-rows: 24px 20px; - grid-template-columns: 28px auto min-content; - - ${({ compact }) => - compact && - css` - grid-template-rows: 28px 0px; - `} -`; - -export const PositionIcon = styled.div` - width: 28px; - height: 28px; - grid-row: 1 / span 2; - align-self: center; - - & > svg { - width: 100%; - height: 100%; - aspect-ratio: 1/1; - } -`; - -export const PositionSubBalance = styled.div` - grid-row: 2; - grid-column: 2; -`; - -export const PositionBalance = styled.div` - grid-row: 1; - grid-column: 2; - color: var(--lido-color-text); - font-size: 14px; - font-weight: 700; - line-height: 24px; - - :not(&:has(+ ${PositionSubBalance})) { - grid-row: 1 / span 2; - align-self: center; - } -`; - -export const PositionDecorator = styled.div` - grid-row: 1 / span 2; - grid-column: 3; - align-self: center; -`; diff --git a/features/earn/shared/v2/vault-position/vault-position.tsx b/features/earn/shared/v2/vault-position/vault-position.tsx deleted file mode 100644 index 49875e5dc..000000000 --- a/features/earn/shared/v2/vault-position/vault-position.tsx +++ /dev/null @@ -1,87 +0,0 @@ -import { type Address } from 'viem'; - -import { FormatPrice, FormatToken } from 'shared/formatters'; -import { TokenToWallet } from 'shared/components'; - -import { VaultTip } from '../../vault-tip'; -import { InlineLoader } from '../../inline-loader'; - -import { - PositionBalance, - PositionContainer, - PositionEntry, - PositionEntryBody, - PositionEntryTitle, - PositionIcon, - PositionSubBalance, - PositionDecorator, -} from './styles'; - -type TokenBalance = { - token?: Address; - symbol: string; - balance?: bigint; - decimals?: number; - icon?: React.ReactNode; - usdAmount?: number | null; - isLoading?: boolean; - rightDecorator?: React.ReactNode; -}; - -export type VaultPositionProps = { - position: TokenBalance; - positionTip?: React.ReactNode; -}; - -type PositionBodyProps = { - position: TokenBalance; - compact?: boolean; -}; - -const PositionBody = ({ position, compact }: PositionBodyProps) => { - return ( - - {position.icon} - - - - - {' '} - - - - - {!position.isLoading && position.usdAmount != null && ( - - - - )} - {position.rightDecorator && ( - {position.rightDecorator} - )} - - ); -}; - -export const VaultPosition = ({ - position, - positionTip, -}: VaultPositionProps) => { - return ( - - - - My position {positionTip} - - - - - ); -}; diff --git a/features/earn/vault-dvv/vault-card-dvv-v2.tsx b/features/earn/vault-dvv/vault-card-dvv-v2.tsx index b3f7fe9f2..283981f3b 100644 --- a/features/earn/vault-dvv/vault-card-dvv-v2.tsx +++ b/features/earn/vault-dvv/vault-card-dvv-v2.tsx @@ -4,7 +4,7 @@ import { trackMatomoEvent } from 'utils/track-matomo-event'; import { MATOMO_EARN_EVENTS_TYPES } from 'consts/matomo/matomo-earn-events'; import { useDVVStats } from './hooks/use-dvv-stats'; import { useDVVPosition } from './hooks/use-dvv-position'; -import { VaultCard } from '../shared/v2/vault-card'; +import { LegacyVaultCard } from '../shared/v2/vault-card'; import { EARN_VAULT_DVV_SLUG } from '../consts'; import { DVV_TOKEN_SYMBOL, DVV_VAULT_DESCRIPTION } from './consts'; import { DVVAprBreakdown } from './components/dvv-apr-breakdown'; @@ -15,7 +15,7 @@ export const VaultCardDVV = () => { const { sharesBalance, isLoading: isLoadingPosition } = useDVVPosition(); return ( - { position={ isWalletConnected ? { - balance: sharesBalance, - symbol: DVV_TOKEN_SYMBOL, + sharesBalance: sharesBalance, + sharesSymbol: DVV_TOKEN_SYMBOL, isLoading: isLoadingPosition, } : undefined diff --git a/features/earn/vault-eth/deposit/deposit-requests/deposit-requests.tsx b/features/earn/vault-eth/deposit/deposit-requests/deposit-requests.tsx index 76efe24b3..123cd3d82 100644 --- a/features/earn/vault-eth/deposit/deposit-requests/deposit-requests.tsx +++ b/features/earn/vault-eth/deposit/deposit-requests/deposit-requests.tsx @@ -1,6 +1,4 @@ import { RequestsContainer } from 'modules/mellow-meta-vaults/components/request'; -import { VaultPosition } from 'features/earn/shared/v2/vault-position/vault-position'; -import { TokenEarnEthIcon } from 'assets/earn-v2'; import { useEthVaultAvailable } from '../../hooks/use-vault-available'; import { @@ -10,8 +8,6 @@ import { } from '../hooks'; import { EthVaultDepositPendingRequests } from './deposit-pending-requests'; import { EthVaultDepositClaimableRequest } from './deposit-claimable-request'; -import { useEthVaultPosition } from '../../hooks/use-position'; -import { ETH_VAULT_TOKEN_SYMBOL } from '../../consts'; export const EthVaultDepositRequests = () => { const { isEthVaultAvailable } = useEthVaultAvailable(); @@ -24,34 +20,12 @@ export const EthVaultDepositRequests = () => { totalClaimableShares, } = useEthVaultDepositRequests(); - const { - data: earnethPositionData, - isLoading: isPositionLoading, - usdBalance: usdAmount, - usdQuery: { isLoading: isPositionLoadingUsd }, - } = useEthVaultPosition(); - - const earnethBalance = earnethPositionData?.earnethSharesBalance ?? 0n; - - if ( - (earnethBalance === 0n && depositRequests.length === 0) || - !isEthVaultAvailable - ) { + if (depositRequests.length === 0 || !isEthVaultAvailable) { return null; } return ( - , - isLoading: isPositionLoading || isPositionLoadingUsd, - usdAmount, - }} - /> { const data = isEnabled ? earnethBalanceQuery.data : undefined; const wsteth = earnethToWstethQuery.data; - const { usdAmount, ...usdQuery } = useWstethUsd( + const { usdAmount, ethAmount, ...usdQuery } = useWstethUsd( wsteth, publicClientMainnet.chain?.id, ); return { ...earnethBalanceQuery, - isLoading: earnethBalanceQuery.isLoading || earnethToWstethQuery.isLoading, + isLoading: + earnethBalanceQuery.isLoading || + earnethToWstethQuery.isPending || + usdQuery.isLoading, data, earnethSharesBalance: data?.earnethSharesBalance, usdQuery, usdBalance: usdAmount ?? 0, + ethAmount, }; }; diff --git a/features/earn/vault-eth/vault-card.tsx b/features/earn/vault-eth/vault-card.tsx index 4f4d3fe1e..232cb6b6f 100644 --- a/features/earn/vault-eth/vault-card.tsx +++ b/features/earn/vault-eth/vault-card.tsx @@ -1,6 +1,5 @@ import { VaultEthIcon } from 'assets/earn-v2'; import { trackMatomoEvent } from 'utils/track-matomo-event'; -import { getTokenIcon } from 'utils/get-token-icon'; import { MATOMO_EARN_EVENTS_TYPES } from 'consts/matomo'; import { VaultListWarning } from 'features/earn/shared/v2/vault-warning'; @@ -14,6 +13,7 @@ import { ETH_VAULT_TITLE, ETH_VAULT_TOKEN_SYMBOL, } from './consts'; +import { TOKEN_SYMBOLS } from 'consts/tokens'; import { useEthVaultPosition } from './hooks/use-position'; import { useEthVaultAvailable } from './hooks/use-vault-available'; import { ProtectedTooltip } from './protected-tooltip'; @@ -23,8 +23,11 @@ export const EthVaultCard = () => { const { tvlUsd, isLoading: isTvlLoading } = useEthVaultStats(); const { listWarningText } = useEthVaultAvailable(); - const { data: earnethPositionData, isLoading: isPositionLoading } = - useEthVaultPosition(); + const { + data: earnethPositionData, + isLoading: isPositionLoading, + ethAmount, + } = useEthVaultPosition(); const sharesBalance = earnethPositionData?.earnethSharesBalance; @@ -41,9 +44,10 @@ export const EthVaultCard = () => { isLoading: isApyLoading || isTvlLoading, }} position={{ - balance: sharesBalance, - symbol: ETH_VAULT_TOKEN_SYMBOL, - icon: getTokenIcon(ETH_VAULT_TOKEN_SYMBOL), + sharesBalance, + sharesSymbol: ETH_VAULT_TOKEN_SYMBOL, + baseAmount: ethAmount, + baseSymbol: TOKEN_SYMBOLS.eth, isLoading: isPositionLoading, }} ctaLabel={sharesBalance && sharesBalance > 0n ? 'Manage' : 'Deposit'} diff --git a/features/earn/vault-eth/vault-page.tsx b/features/earn/vault-eth/vault-page.tsx index 8b48460f6..14e7484d4 100644 --- a/features/earn/vault-eth/vault-page.tsx +++ b/features/earn/vault-eth/vault-page.tsx @@ -14,9 +14,15 @@ import { EthVaultPositionManager } from './position-manager/position-manager'; import { EarnEthFaq } from './faq/faq'; import { useEthVaultStats } from './hooks/use-vault-stats'; import { useEthVaultApy } from './hooks/use-vault-apy'; +import { useEthVaultPosition } from './hooks/use-position'; import { EARN_VAULT_DEPOSIT_SLUG, EARN_VAULT_WITHDRAW_SLUG } from '../consts'; import { EthVaultApyHint } from './components/apy-hint'; -import { ETH_VAULT_DESCRIPTION, ETH_VAULT_TITLE } from './consts'; +import { + ETH_VAULT_DESCRIPTION, + ETH_VAULT_TITLE, + ETH_VAULT_TOKEN_SYMBOL, +} from './consts'; +import { TOKEN_SYMBOLS } from 'consts/tokens'; import { ProtectedTooltip } from './protected-tooltip'; const FEES = [ @@ -159,6 +165,14 @@ export const EthVaultPage: FC<{ }> = ({ action }) => { const { apy, isLoading: isApyLoading } = useEthVaultApy(); const { tvlUsd, isLoading: isTvlLoading } = useEthVaultStats(); + const { + data: earnethPositionData, + isLoading: isPositionLoading, + ethAmount, + usdBalance, + } = useEthVaultPosition(); + + const sharesBalance = earnethPositionData?.earnethSharesBalance; return ( <> @@ -171,6 +185,18 @@ export const EthVaultPage: FC<{ apxHint={} sidePanel={} vaultName="ethVault" + balance={ + sharesBalance + ? { + amount: ethAmount, + symbol: TOKEN_SYMBOLS.eth, + sharesAmount: sharesBalance, + sharesSymbol: ETH_VAULT_TOKEN_SYMBOL, + usdAmount: usdBalance, + isLoading: isPositionLoading, + } + : undefined + } faqContent={} strategyContent={ { const { isEthVaultAvailable } = useEthVaultAvailable(); @@ -24,15 +20,6 @@ export const EthVaultWithdrawRequests = () => { useEthVaultWithdrawClaimAll(); const isClaiming = isClaimingSingle || isClaimingAll; - const { - data: earnethPositionData, - isLoading: isPositionLoading, - usdBalance: usdAmount, - usdQuery: { isLoading: isPositionLoadingUsd } = { isLoading: false }, - } = useEthVaultPosition(); - - const earnethBalance = earnethPositionData?.earnethSharesBalance ?? 0n; - const requests = requestsData?.requests || []; const claimableRequests = requestsData?.claimableRequests || []; const pendingRequests = requestsData?.pendingRequests || []; @@ -40,21 +27,10 @@ export const EthVaultWithdrawRequests = () => { const TOOLTIP_TEXT = 'The final claimable wstETH may differ slightly, since your request continues earning until processing is complete.'; - if ((earnethBalance === 0n && requests.length === 0) || !isEthVaultAvailable) - return null; + if (requests.length === 0 || !isEthVaultAvailable) return null; return ( - , - isLoading: isPositionLoading || isPositionLoadingUsd, - usdAmount, - }} - /> {claimableRequests.length > 0 && ( Ready to claim{' '} diff --git a/features/earn/vault-ggv/vault-card-ggv-v2.tsx b/features/earn/vault-ggv/vault-card-ggv-v2.tsx index 6844081a3..1b0147302 100644 --- a/features/earn/vault-ggv/vault-card-ggv-v2.tsx +++ b/features/earn/vault-ggv/vault-card-ggv-v2.tsx @@ -2,7 +2,7 @@ import { VaultGgvIcon } from 'assets/earn-v2'; import { useDappStatus } from 'modules/web3'; import { trackMatomoEvent } from 'utils/track-matomo-event'; import { MATOMO_EARN_EVENTS_TYPES } from 'consts/matomo/matomo-earn-events'; -import { VaultCard } from '../shared/v2/vault-card'; +import { LegacyVaultCard } from '../shared/v2/vault-card'; import { EARN_VAULT_GGV_SLUG } from '../consts'; import { GGVApyHint } from './components/ggv-apy-hint'; import { GGV_VAULT_DESCRIPTION, GGV_TOKEN_SYMBOL } from './consts'; @@ -15,7 +15,7 @@ export const VaultCardGGV = () => { const { sharesBalance, isLoading: isLoadingPosition } = useGGVPosition(); return ( - { position={ isWalletConnected ? { - balance: sharesBalance, - symbol: GGV_TOKEN_SYMBOL, + sharesBalance: sharesBalance, + sharesSymbol: GGV_TOKEN_SYMBOL, isLoading: isLoadingPosition, } : undefined diff --git a/features/earn/vault-stg/vault-card-stg-v2.tsx b/features/earn/vault-stg/vault-card-stg-v2.tsx index b5e76d3bb..996e9cc35 100644 --- a/features/earn/vault-stg/vault-card-stg-v2.tsx +++ b/features/earn/vault-stg/vault-card-stg-v2.tsx @@ -5,10 +5,9 @@ import { MATOMO_EARN_EVENTS_TYPES } from 'consts/matomo/matomo-earn-events'; import { useSTGApy } from './hooks/use-stg-apy'; import { useSTGStats } from './hooks/use-stg-stats'; import { useSTGPosition } from './hooks/use-stg-position'; -import { VaultCard } from '../shared/v2/vault-card'; +import { LegacyVaultCard } from '../shared/v2/vault-card'; import { EARN_VAULT_STG_SLUG } from '../consts'; import { STGApyHint } from './components/stg-apy-hint'; -import { useDepositRequests } from './deposit/hooks'; import { STG_VAULT_DESCRIPTION, STG_TOKEN_SYMBOL } from './consts'; export const VaultCardSTG = () => { @@ -17,19 +16,9 @@ export const VaultCardSTG = () => { const { apy, isLoading: isLoadingApy } = useSTGApy(); const { strethSharesBalance, isLoading: isLoadingPosition } = useSTGPosition(); - const { - totalClaimableStrethShares, - pendingRequests, - isLoading: isLoadingDepositRequests, - } = useDepositRequests(); - - const pending = pendingRequests.map((request) => ({ - tokenSymbol: request.token, - amount: request.assets, - })); return ( - { position={ isWalletConnected ? { - balance: strethSharesBalance, - symbol: STG_TOKEN_SYMBOL, - claimable: totalClaimableStrethShares, - pending, - isLoading: isLoadingPosition || isLoadingDepositRequests, + sharesBalance: strethSharesBalance, + sharesSymbol: STG_TOKEN_SYMBOL, + isLoading: isLoadingPosition, } : undefined } diff --git a/features/earn/vault-usd/deposit/deposit-requests/deposit-requests.tsx b/features/earn/vault-usd/deposit/deposit-requests/deposit-requests.tsx index 7045225da..c4d42cba3 100644 --- a/features/earn/vault-usd/deposit/deposit-requests/deposit-requests.tsx +++ b/features/earn/vault-usd/deposit/deposit-requests/deposit-requests.tsx @@ -7,20 +7,11 @@ import { } from '../hooks'; import { UsdVaultDepositPendingRequests } from './deposit-pending-requests'; import { UsdVaultDepositClaimableRequest } from './deposit-claimable-request'; -import { useUsdVaultPosition } from '../../hooks/use-position'; -import { VaultPosition } from 'features/earn/shared/v2/vault-position/vault-position'; -import { USD_VAULT_TOKEN_SYMBOL } from '../../consts'; -import { TokenEarnUsdIcon } from 'assets/earn-v2'; export const UsdVaultDepositRequests = () => { const { isUsdVaultAvailable } = useUsdVaultAvailable(); const { cancel, isCanceling } = useUsdVaultDepositCancel(); const { claim, isClaiming } = useUsdVaultDepositClaim(); - const { - data: usdVaultPositionData, - isLoading: isPositionLoading, - usdBalance: usdAmount, - } = useUsdVaultPosition(); const { requests: depositRequests, @@ -28,27 +19,12 @@ export const UsdVaultDepositRequests = () => { totalClaimableShares, } = useUsdVaultDepositRequests(); - const usdVaultBalance = usdVaultPositionData?.earnusdSharesBalance ?? 0n; - - if ( - (usdVaultBalance === 0n && depositRequests.length === 0) || - !isUsdVaultAvailable - ) { + if (depositRequests.length === 0 || !isUsdVaultAvailable) { return null; } return ( - , - isLoading: isPositionLoading, - usdAmount, - }} - /> { return { ...earnusdBalanceQuery, - isLoading: earnusdBalanceQuery.isLoading || earnusdToUsdcQuery.isLoading, + isLoading: earnusdBalanceQuery.isLoading || earnusdToUsdcQuery.isPending, data, earnusdSharesBalance: data?.earnusdSharesBalance, usdQuery, usdBalance: usdAmount ?? 0, + usdcAmount: usdc, }; }; diff --git a/features/earn/vault-usd/vault-card.tsx b/features/earn/vault-usd/vault-card.tsx index be80e68a0..301b1a3e0 100644 --- a/features/earn/vault-usd/vault-card.tsx +++ b/features/earn/vault-usd/vault-card.tsx @@ -1,6 +1,5 @@ import { VaultUsdIcon } from 'assets/earn-v2'; import { trackMatomoEvent } from 'utils/track-matomo-event'; -import { getTokenIcon } from 'utils/get-token-icon'; import { MATOMO_EARN_EVENTS_TYPES } from 'consts/matomo'; import { VaultCard } from '../shared/v2/vault-card'; @@ -14,6 +13,7 @@ import { USD_VAULT_TITLE, USD_VAULT_TOKEN_SYMBOL, } from './consts'; +import { TOKEN_SYMBOLS } from 'consts/tokens'; import { useUsdVaultPosition } from './hooks/use-position'; import { ProtectedTooltip } from './protected-tooltip'; import { useUsdVaultAvailable } from './hooks/use-vault-available'; @@ -21,8 +21,11 @@ import { useUsdVaultAvailable } from './hooks/use-vault-available'; export const UsdVaultCard = () => { const { apy, isLoading: isApyLoading } = useUsdVaultApy(); const { tvlUsd, isLoading: isTvlLoading } = useUsdVaultStats(); - const { data: usdPositionData, isLoading: isPositionLoading } = - useUsdVaultPosition(); + const { + data: usdPositionData, + isLoading: isPositionLoading, + usdcAmount, + } = useUsdVaultPosition(); const { listWarningText } = useUsdVaultAvailable(); const sharesBalance = usdPositionData?.earnusdSharesBalance; @@ -40,9 +43,10 @@ export const UsdVaultCard = () => { isLoading: isApyLoading || isTvlLoading, }} position={{ - balance: sharesBalance, - symbol: USD_VAULT_TOKEN_SYMBOL, - icon: getTokenIcon(USD_VAULT_TOKEN_SYMBOL), + sharesBalance, + sharesSymbol: USD_VAULT_TOKEN_SYMBOL, + baseAmount: usdcAmount, + baseSymbol: TOKEN_SYMBOLS.usdc, isLoading: isPositionLoading, }} ctaLabel={sharesBalance && sharesBalance > 0n ? 'Manage' : 'Deposit'} diff --git a/features/earn/vault-usd/vault-page.tsx b/features/earn/vault-usd/vault-page.tsx index 0f4359a8b..03340d4e8 100644 --- a/features/earn/vault-usd/vault-page.tsx +++ b/features/earn/vault-usd/vault-page.tsx @@ -14,9 +14,15 @@ import { EarnUsdFaq } from './faq/faq'; import { EARN_VAULT_DEPOSIT_SLUG, EARN_VAULT_WITHDRAW_SLUG } from '../consts'; import { useUsdVaultStats } from './hooks/use-vault-stats'; import { useUsdVaultApy } from './hooks/use-vault-apy'; +import { useUsdVaultPosition } from './hooks/use-position'; import { Disclaimers } from '../shared/v2/disclaimers'; import { UsdVaultApyHint } from './components/apy-hint'; -import { USD_VAULT_DESCRIPTION, USD_VAULT_TITLE } from './consts'; +import { + USD_VAULT_DESCRIPTION, + USD_VAULT_TITLE, + USD_VAULT_TOKEN_SYMBOL, +} from './consts'; +import { TOKEN_SYMBOLS } from 'consts/tokens'; import { ProtectedTooltip } from './protected-tooltip'; const FEES = [ @@ -159,6 +165,13 @@ export const VaultPageUSD: FC<{ }> = ({ action }) => { const { apy, isLoading: isApyLoading } = useUsdVaultApy(); const { tvlUsd, isLoading: isTvlLoading } = useUsdVaultStats(); + const { + data: earnusdPositionData, + isLoading: isPositionLoading, + usdcAmount, + } = useUsdVaultPosition(); + + const sharesBalance = earnusdPositionData?.earnusdSharesBalance; return ( <> @@ -171,6 +184,17 @@ export const VaultPageUSD: FC<{ apxHint={} sidePanel={} vaultName="usdVault" + balance={ + sharesBalance + ? { + amount: usdcAmount, + symbol: TOKEN_SYMBOLS.usdc, + sharesAmount: sharesBalance, + sharesSymbol: USD_VAULT_TOKEN_SYMBOL, + isLoading: isPositionLoading, + } + : undefined + } faqContent={} strategyContent={ { const { isUsdVaultAvailable } = useUsdVaultAvailable(); @@ -23,13 +19,6 @@ export const UsdVaultWithdrawRequests = () => { const { withdrawClaimAll, isClaiming: isClaimingAll } = useUsdVaultWithdrawClaimAll(); const isClaiming = isClaimingSingle || isClaimingAll; - const { - data: earnusdPositionData, - isLoading: isPositionLoading, - usdBalance: usdAmount, - } = useUsdVaultPosition(); - - const earnusdBalance = earnusdPositionData?.earnusdSharesBalance ?? 0n; const requests = data?.requests || []; const claimableRequests = data?.claimableRequests || []; @@ -38,21 +27,10 @@ export const UsdVaultWithdrawRequests = () => { const TOOLTIP_TEXT = 'The final claimable USDC may differ slightly, since your request continues earning until processing is complete.'; - if ((earnusdBalance === 0n && requests.length === 0) || !isUsdVaultAvailable) - return null; + if (requests.length === 0 || !isUsdVaultAvailable) return null; return ( - , - isLoading: isPositionLoading, - usdAmount, - }} - /> {claimableRequests.length > 0 && ( Ready to claim{' '}