From 347f05e7ebaea1e9983874775a9231e4b430bcf0 Mon Sep 17 00:00:00 2001 From: Anton Shalimov Date: Mon, 6 May 2024 20:45:22 +0300 Subject: [PATCH 01/30] feat: add origins to .env and config --- .env.example | 7 +++++++ env-dynamics.mjs | 11 +++++++++++ 2 files changed, 18 insertions(+) diff --git a/.env.example b/.env.example index 38794b8a6..c272c237d 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,10 @@ +# for supporting of domain agnostic +SELF_ORIGIN=https://stake.lido.fi +ROOT_ORIGIN=https://lido.fi +DOCS_ORIGIN=https://docs.lido.fi +HELP_ORIGIN=https://help.lido.fi +RESEARCH_ORIGIN=https://research.lido.fi + # EL_RPC_URLS_{CHAIN_ID} list or URLs delimeted by commas, first entry is primary, else are fallbacks EL_RPC_URLS_1= EL_RPC_URLS_5= diff --git a/env-dynamics.mjs b/env-dynamics.mjs index 35729dbe3..8e6042903 100644 --- a/env-dynamics.mjs +++ b/env-dynamics.mjs @@ -18,6 +18,17 @@ const toBoolean = (val) => { /** @type boolean */ export const ipfsMode = toBoolean(process.env.IPFS_MODE); +/** @type string */ +export const selfOrigin = process.env.SELF_ORIGIN; +/** @type string */ +export const rootOrigin = process.env.ROOT_ORIGIN; +/** @type string */ +export const docsOrigin = process.env.DOCS_ORIGIN; +/** @type string */ +export const helpOrigin = process.env.HELP_ORIGIN; +/** @type string */ +export const researchOrigin = process.env.RESEARCH_ORIGIN; + // Keep fallback as in 'config/get-secret-config.ts' /** @type number */ export const defaultChain = parseInt(process.env.DEFAULT_CHAIN, 10) || 17000; From 0fc5d76ae54c6360e0acd793c7042641cf9f59a5 Mon Sep 17 00:00:00 2001 From: Anton Shalimov Date: Mon, 6 May 2024 20:56:11 +0300 Subject: [PATCH 02/30] feat: use selfOrigin --- pages/_document.tsx | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/pages/_document.tsx b/pages/_document.tsx index 9080492cd..b947a3dfb 100644 --- a/pages/_document.tsx +++ b/pages/_document.tsx @@ -14,8 +14,6 @@ import { config } from 'config'; import { contentSecurityPolicy } from 'config/csp'; import { InsertIpfsBaseScript } from 'features/ipfs/ipfs-base-script'; -let host = 'https://stake.lido.fi'; - const secureHeaders = createHeadersObject({ contentSecurityPolicy }); const cspMetaTagContent = secureHeaders['Content-Security-Policy'] ?? @@ -28,10 +26,6 @@ export default class MyDocument extends Document { const sheet = new ServerStyleSheet(); const originalRenderPage = ctx.renderPage; - if (ctx?.req?.headers?.host) { - host = `https://${ctx?.req?.headers?.host}`; - } - try { ctx.renderPage = () => originalRenderPage({ @@ -68,7 +62,8 @@ export default class MyDocument extends Document { } get metaPreviewImgUrl(): string { - return `${host}/lido-preview.png`; + // TODO: needs fix for IPFS + return `${config.selfOrigin}/lido-preview.png`; } render(): JSX.Element { From f57442169d55d846898b2a11cf272668709100a1 Mon Sep 17 00:00:00 2001 From: Anton Shalimov Date: Mon, 6 May 2024 20:57:30 +0300 Subject: [PATCH 03/30] feat: use researchOrigin --- features/referral/banner/banner.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/features/referral/banner/banner.tsx b/features/referral/banner/banner.tsx index d8f668f4f..65684a3e0 100644 --- a/features/referral/banner/banner.tsx +++ b/features/referral/banner/banner.tsx @@ -1,6 +1,7 @@ import { FC } from 'react'; import { Block, Link } from '@lidofinance/lido-ui'; +import { config } from 'config'; import { BannerTextStyle, BannerHeader, BannerMainTextStyle } from './styles'; export const Banner: FC = () => { @@ -19,9 +20,11 @@ export const Banner: FC = () => { partners approved by the Lido DAO are eligible for rewards. To apply to Lido's whitelist you could here: - + {' '} - https://research.lido.fi/t/referral-program-whitelisting-ethereum/1039 + ${config.researchOrigin}/t/referral-program-whitelisting-ethereum/1039


From c6671e3fcc2d3ce4b36b829b4afdbeee1bfb657f Mon Sep 17 00:00:00 2001 From: Anton Shalimov Date: Mon, 6 May 2024 20:59:14 +0300 Subject: [PATCH 04/30] feat: use docsOrigin --- .../rpc-availability-check-result-box.tsx | 3 ++- features/stake/stake-faq/list/lido-eth-apr.tsx | 4 +++- .../stake/stake-form/wallet/limit-meter/components.tsx | 7 +++++-- shared/banners/goerli-sunset/goerli-sunset-banner.tsx | 8 +++++--- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/features/ipfs/rpc-availability-check-result-box/rpc-availability-check-result-box.tsx b/features/ipfs/rpc-availability-check-result-box/rpc-availability-check-result-box.tsx index 80147588b..02cb651b5 100644 --- a/features/ipfs/rpc-availability-check-result-box/rpc-availability-check-result-box.tsx +++ b/features/ipfs/rpc-availability-check-result-box/rpc-availability-check-result-box.tsx @@ -1,6 +1,7 @@ import { useCallback } from 'react'; import { Check, Close } from '@lidofinance/lido-ui'; +import { config } from 'config'; import { SETTINGS_PATH } from 'consts/urls'; import { useIPFSInfoBoxStatuses } from 'providers/ipfs-info-box-statuses'; import { usePrefixedPush } from 'shared/hooks/use-prefixed-history'; @@ -8,7 +9,7 @@ import { LinkArrow } from 'shared/components/link-arrow/link-arrow'; import { Wrap, RpcStatusBox, Button, Text } from './styles'; -export const IPFS_INFO_URL = 'https://docs.lido.fi/ipfs/about'; +export const IPFS_INFO_URL = `${config.docsOrigin}/ipfs/about`; export const RPCAvailabilityCheckResultBox = () => { const { isRPCAvailable, handleClickDismiss } = useIPFSInfoBoxStatuses(); diff --git a/features/stake/stake-faq/list/lido-eth-apr.tsx b/features/stake/stake-faq/list/lido-eth-apr.tsx index 573cbbcb1..b80fc0e20 100644 --- a/features/stake/stake-faq/list/lido-eth-apr.tsx +++ b/features/stake/stake-faq/list/lido-eth-apr.tsx @@ -1,5 +1,7 @@ import { FC } from 'react'; import { Accordion, Link } from '@lidofinance/lido-ui'; + +import { config } from 'config'; import { MATOMO_CLICK_EVENTS_TYPES } from 'consts/matomo-click-events'; export const LidoEthApr: FC = () => { @@ -25,7 +27,7 @@ export const LidoEthApr: FC = () => { {' '} and in our{' '} Docs diff --git a/features/stake/stake-form/wallet/limit-meter/components.tsx b/features/stake/stake-form/wallet/limit-meter/components.tsx index fe74fd6fa..426190ff8 100644 --- a/features/stake/stake-form/wallet/limit-meter/components.tsx +++ b/features/stake/stake-form/wallet/limit-meter/components.tsx @@ -1,6 +1,9 @@ import { LIMIT_LEVEL } from 'types'; -import { LimitReachedIcon, LimitSafeIcon, LimitWarnIcon } from './icons'; + +import { config } from 'config'; import { TooltipHoverable } from 'shared/components'; + +import { LimitReachedIcon, LimitSafeIcon, LimitWarnIcon } from './icons'; import { Bars, EmptyBar, @@ -90,7 +93,7 @@ export const LimitHelp: LimitComponent = ({ limitLevel }) => { stake over the global staking limit. The global limit goes down with each deposit but it's passively restored on each block.{' '} diff --git a/shared/banners/goerli-sunset/goerli-sunset-banner.tsx b/shared/banners/goerli-sunset/goerli-sunset-banner.tsx index 9e9edc680..79100437b 100644 --- a/shared/banners/goerli-sunset/goerli-sunset-banner.tsx +++ b/shared/banners/goerli-sunset/goerli-sunset-banner.tsx @@ -1,11 +1,13 @@ import { CHAINS } from '@lido-sdk/constants'; import { useSDK } from '@lido-sdk/react'; import { Text, Link } from '@lidofinance/lido-ui'; + +import { config } from 'config'; + import { SunsetMessageStyle } from './styles'; -const URL_INFORMATION = 'https://docs.lido.fi/deployed-contracts/goerli/'; -const URL_HOLESKY = - 'https://docs.lido.fi/deployed-contracts/holesky/#hole%C5%A1ky-testnet'; +const URL_INFORMATION = `${config.docsOrigin}/deployed-contracts/goerli/`; +const URL_HOLESKY = `${config.docsOrigin}/deployed-contracts/holesky/#hole%C5%A1ky-testnet`; export const GoerliSunsetBanner = () => { const { chainId } = useSDK(); From 90ed630ecd482184abf71ef7aa57ee903c4306ca Mon Sep 17 00:00:00 2001 From: Anton Shalimov Date: Mon, 6 May 2024 21:00:17 +0300 Subject: [PATCH 05/30] feat: use helpOrigin --- consts/external-links.ts | 5 +++-- .../tx-stage-request-success/tx-stage-request-success.tsx | 4 ++-- .../withdrawals/withdrawals-faq/list/what-is-slashing.tsx | 5 +++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/consts/external-links.ts b/consts/external-links.ts index 8b186d87f..89910dfa2 100644 --- a/consts/external-links.ts +++ b/consts/external-links.ts @@ -1,5 +1,6 @@ -export const LINK_ADD_NFT_GUIDE = - 'https://help.lido.fi/en/articles/7858367-how-do-i-add-the-lido-nft-to-metamask'; +import { config } from 'config'; + +export const LINK_ADD_NFT_GUIDE = `${config.helpOrigin}/en/articles/7858367-how-do-i-add-the-lido-nft-to-metamask`; export const OPEN_OCEAN_REFERRAL_ADDRESS = '0xbb1263222b2c020f155d409dba05c4a3861f18f8'; diff --git a/features/withdrawals/request/transaction-modal-request/tx-stage-request-success/tx-stage-request-success.tsx b/features/withdrawals/request/transaction-modal-request/tx-stage-request-success/tx-stage-request-success.tsx index a159822fd..6ca952280 100644 --- a/features/withdrawals/request/transaction-modal-request/tx-stage-request-success/tx-stage-request-success.tsx +++ b/features/withdrawals/request/transaction-modal-request/tx-stage-request-success/tx-stage-request-success.tsx @@ -2,6 +2,7 @@ import type { BigNumber } from 'ethers'; import { useSDK } from '@lido-sdk/react'; import { Link, Loader } from '@lidofinance/lido-ui'; +import { config } from 'config'; import { WITHDRAWALS_CLAIM_PATH } from 'consts/urls'; import { MATOMO_CLICK_EVENTS_TYPES } from 'consts/matomo-click-events'; import { trackMatomoEvent } from 'utils/track-matomo-event'; @@ -22,8 +23,7 @@ import { AddNftWrapper, } from './styles'; -const LINK_ADD_NFT_GUIDE = - 'https://help.lido.fi/en/articles/7858367-how-do-i-add-the-lido-nft-to-metamask'; +const LINK_ADD_NFT_GUIDE = `${config.helpOrigin}/en/articles/7858367-how-do-i-add-the-lido-nft-to-metamask`; type TxRequestStageSuccessProps = { txHash: string | null; diff --git a/features/withdrawals/withdrawals-faq/list/what-is-slashing.tsx b/features/withdrawals/withdrawals-faq/list/what-is-slashing.tsx index 6574756a5..537241169 100644 --- a/features/withdrawals/withdrawals-faq/list/what-is-slashing.tsx +++ b/features/withdrawals/withdrawals-faq/list/what-is-slashing.tsx @@ -1,8 +1,9 @@ import { Accordion, Link } from '@lidofinance/lido-ui'; + +import { config } from 'config'; import { MATOMO_CLICK_EVENTS_TYPES } from 'consts/matomo-click-events'; -const PENALTIES_INFO_LINK = - 'https://help.lido.fi/en/articles/5232780-what-are-staking-validator-penalties'; +const PENALTIES_INFO_LINK = `${config.helpOrigin}/en/articles/5232780-what-are-staking-validator-penalties`; export const WhatIsSlashing: React.FC = () => { return ( From 74e3cb715c52fb5caad2082bc92d1b3376b9a0a0 Mon Sep 17 00:00:00 2001 From: Anton Shalimov Date: Mon, 6 May 2024 21:02:51 +0300 Subject: [PATCH 06/30] feat: use rootOrigin --- features/rewards/components/stats/Stats.tsx | 3 ++- features/stake/stake-faq/list/how-can-i-get-steth.tsx | 5 +++-- features/stake/stake-faq/list/how-can-i-unstake-steth.tsx | 3 ++- features/stake/stake-faq/list/how-can-i-use-steth.tsx | 4 +++- features/stake/stake-faq/list/lido-eth-apr.tsx | 2 +- .../wsteth/shared/wrap-faq/list/how-can-i-get-wsteth.tsx | 3 ++- .../wsteth/shared/wrap-faq/list/how-can-i-use-wsteth.tsx | 6 ++++-- shared/banners/l2-banner/l2-banner.tsx | 4 +++- shared/banners/l2-banners/l2-after-wrap.tsx | 6 ++++-- shared/banners/modal-pool-banners/modal-pool-banners.tsx | 6 ++++-- shared/components/layout/footer/footer.tsx | 8 ++++++-- shared/components/logos/logos.tsx | 4 +++- 12 files changed, 37 insertions(+), 17 deletions(-) diff --git a/features/rewards/components/stats/Stats.tsx b/features/rewards/components/stats/Stats.tsx index a9755874b..85061db6a 100644 --- a/features/rewards/components/stats/Stats.tsx +++ b/features/rewards/components/stats/Stats.tsx @@ -1,5 +1,6 @@ import { Box, Link } from '@lidofinance/lido-ui'; +import { config } from 'config'; import { useRewardsHistory } from 'features/rewards/hooks'; import EthSymbol from 'features/rewards/components/EthSymbol'; import NumberFormat from 'features/rewards/components/NumberFormat'; @@ -69,7 +70,7 @@ export const Stats: React.FC = () => { )} - <Link href="https://lido.fi/faq"> + <Link href={`${config.rootOrigin}/faq`}> <Box data-testid="moreInfo" color="secondary" diff --git a/features/stake/stake-faq/list/how-can-i-get-steth.tsx b/features/stake/stake-faq/list/how-can-i-get-steth.tsx index 48b9b33e0..a2985e168 100644 --- a/features/stake/stake-faq/list/how-can-i-get-steth.tsx +++ b/features/stake/stake-faq/list/how-can-i-get-steth.tsx @@ -1,9 +1,10 @@ import { FC } from 'react'; import { Accordion, Link as OuterLink } from '@lidofinance/lido-ui'; +import { config } from 'config'; import { MATOMO_CLICK_EVENTS_TYPES } from 'consts/matomo-click-events'; -import { trackMatomoEvent } from 'utils/track-matomo-event'; import { HOME_PATH } from 'consts/urls'; +import { trackMatomoEvent } from 'utils/track-matomo-event'; import { LocalLink } from 'shared/components/local-link'; export const HowCanIGetSteth: FC = () => { @@ -23,7 +24,7 @@ export const HowCanIGetSteth: FC = () => { </LocalLink>{' '} and in other{' '} <OuterLink - href={'https://lido.fi/lido-ecosystem?tokens=stETH&categories=Get'} + href={`${config.rootOrigin}/lido-ecosystem?tokens=stETH&categories=Get`} data-matomo={MATOMO_CLICK_EVENTS_TYPES.faqHowCanIGetStEthIntegrations} > DEX Lido integrations diff --git a/features/stake/stake-faq/list/how-can-i-unstake-steth.tsx b/features/stake/stake-faq/list/how-can-i-unstake-steth.tsx index 4ff25fd58..219ad4436 100644 --- a/features/stake/stake-faq/list/how-can-i-unstake-steth.tsx +++ b/features/stake/stake-faq/list/how-can-i-unstake-steth.tsx @@ -2,6 +2,7 @@ import { FC } from 'react'; import { Accordion, Link as OuterLink } from '@lidofinance/lido-ui'; +import { config } from 'config'; import { WITHDRAWALS_CLAIM_PATH } from 'consts/urls'; import { MATOMO_CLICK_EVENTS_TYPES } from 'consts/matomo-click-events'; import { trackMatomoEvent } from 'utils/track-matomo-event'; @@ -26,7 +27,7 @@ export const HowCanIUnstakeSteth: FC = () => { to unstake stETH and receive ETH at a 1:1 ratio. Also, you can exchange stETH on{' '} <OuterLink - href="https://lido.fi/lido-ecosystem?tokens=stETH&categories=Get" + href={`${config.rootOrigin}/lido-ecosystem?tokens=stETH&categories=Get`} data-matomo={ MATOMO_CLICK_EVENTS_TYPES.faqHowCanIUnstakeStEthIntegrations } diff --git a/features/stake/stake-faq/list/how-can-i-use-steth.tsx b/features/stake/stake-faq/list/how-can-i-use-steth.tsx index c728f5eb9..c3d51d489 100644 --- a/features/stake/stake-faq/list/how-can-i-use-steth.tsx +++ b/features/stake/stake-faq/list/how-can-i-use-steth.tsx @@ -1,5 +1,7 @@ import { FC } from 'react'; import { Accordion, Link } from '@lidofinance/lido-ui'; + +import { config } from 'config'; import { MATOMO_CLICK_EVENTS_TYPES } from 'consts/matomo-click-events'; export const HowCanIUseSteth: FC = () => { @@ -8,7 +10,7 @@ export const HowCanIUseSteth: FC = () => { <p> You can use your stETH as collateral, for lending, and{' '} <Link - href="https://lido.fi/lido-ecosystem" + href={`${config.rootOrigin}/lido-ecosystem`} data-matomo={MATOMO_CLICK_EVENTS_TYPES.faqHowCanIUseSteth} > more diff --git a/features/stake/stake-faq/list/lido-eth-apr.tsx b/features/stake/stake-faq/list/lido-eth-apr.tsx index b80fc0e20..e5adb1923 100644 --- a/features/stake/stake-faq/list/lido-eth-apr.tsx +++ b/features/stake/stake-faq/list/lido-eth-apr.tsx @@ -20,7 +20,7 @@ export const LidoEthApr: FC = () => { <p> More about Lido staking APR for Ethereum you could find on the{' '} <Link - href={'https://lido.fi/ethereum'} + href={`${config.rootOrigin}/ethereum`} data-matomo={MATOMO_CLICK_EVENTS_TYPES.faqLidoEthAprEthLandingPage} > Ethereum landing page diff --git a/features/wsteth/shared/wrap-faq/list/how-can-i-get-wsteth.tsx b/features/wsteth/shared/wrap-faq/list/how-can-i-get-wsteth.tsx index 9ad8752f4..d9d916e53 100644 --- a/features/wsteth/shared/wrap-faq/list/how-can-i-get-wsteth.tsx +++ b/features/wsteth/shared/wrap-faq/list/how-can-i-get-wsteth.tsx @@ -1,6 +1,7 @@ import { FC } from 'react'; import { Accordion, Link as OuterLink } from '@lidofinance/lido-ui'; +import { config } from 'config'; import { WRAP_PATH } from 'consts/urls'; import { MATOMO_CLICK_EVENTS_TYPES } from 'consts/matomo-click-events'; import { trackMatomoEvent } from 'utils/track-matomo-event'; @@ -24,7 +25,7 @@ export const HowCanIGetWsteth: FC = () => { </LocalLink>{' '} or{' '} <OuterLink - href={'https://lido.fi/lido-ecosystem?tokens=wstETH&categories=Get'} + href={`${config.rootOrigin}/lido-ecosystem?tokens=wstETH&categories=Get`} data-matomo={MATOMO_CLICK_EVENTS_TYPES.faqHowCanIGetStEthIntegrations} > DEX Lido integrations diff --git a/features/wsteth/shared/wrap-faq/list/how-can-i-use-wsteth.tsx b/features/wsteth/shared/wrap-faq/list/how-can-i-use-wsteth.tsx index e563deb1a..a3265bcb6 100644 --- a/features/wsteth/shared/wrap-faq/list/how-can-i-use-wsteth.tsx +++ b/features/wsteth/shared/wrap-faq/list/how-can-i-use-wsteth.tsx @@ -1,5 +1,7 @@ import { FC } from 'react'; import { Accordion, Link } from '@lidofinance/lido-ui'; + +import { config } from 'config'; import { MATOMO_CLICK_EVENTS_TYPES } from 'consts/matomo-click-events'; export const HowCanIUseWsteth: FC = () => { @@ -8,14 +10,14 @@ export const HowCanIUseWsteth: FC = () => { <p> wstETH is useful across{' '} <Link - href={'https://lido.fi/lido-ecosystem?networks=arbitrum%2Coptimism'} + href={`${config.rootOrigin}/lido-ecosystem?networks=arbitrum%2Coptimism`} data-matomo={MATOMO_CLICK_EVENTS_TYPES.faqHowCanIUseWstethL2} > L2 </Link>{' '} and other{' '} <Link - href={'https://lido.fi/lido-ecosystem?tokens=wstETH'} + href={`${config.rootOrigin}/lido-ecosystem?tokens=wstETH`} data-matomo={ MATOMO_CLICK_EVENTS_TYPES.faqHowCanIUseWstethDefiProtocols } diff --git a/shared/banners/l2-banner/l2-banner.tsx b/shared/banners/l2-banner/l2-banner.tsx index 623aaf5ab..26b78c084 100644 --- a/shared/banners/l2-banner/l2-banner.tsx +++ b/shared/banners/l2-banner/l2-banner.tsx @@ -1,3 +1,5 @@ +import { config } from 'config'; + import { Wrapper, L2Icons, @@ -20,7 +22,7 @@ type L2BannerProps = { onClickButton?: () => void; }; -export const L2_DISCOVERY_LINK = 'https://lido.fi/lido-on-l2'; +export const L2_DISCOVERY_LINK = `${config.rootOrigin}/lido-on-l2`; export const L2Banner = ({ title, diff --git a/shared/banners/l2-banners/l2-after-wrap.tsx b/shared/banners/l2-banners/l2-after-wrap.tsx index 7cfaf84d1..55caf55b3 100644 --- a/shared/banners/l2-banners/l2-after-wrap.tsx +++ b/shared/banners/l2-banners/l2-after-wrap.tsx @@ -1,11 +1,13 @@ import { trackEvent } from '@lidofinance/analytics-matomo'; + +import { config } from 'config'; import { MATOMO_CLICK_EVENTS } from 'consts/matomo-click-events'; + import { L2Banner } from '../l2-banner'; const linkClickHandler = () => trackEvent(...MATOMO_CLICK_EVENTS.l2LowFeeWrap); -const L2_LEARN_MORE_AFTER_WRAP_LINK = - 'https://lido.fi/lido-ecosystem?networks=arbitrum%2Coptimism%2Cbase%2Czksync+era%2Cmantle%2Clinea%2Cpolygon&criteria=or&tokens=wsteth'; +const L2_LEARN_MORE_AFTER_WRAP_LINK = `${config.rootOrigin}/lido-ecosystem?networks=arbitrum%2Coptimism%2Cbase%2Czksync+era%2Cmantle%2Clinea%2Cpolygon&criteria=or&tokens=wsteth`; export const L2AfterWrap = () => { return ( diff --git a/shared/banners/modal-pool-banners/modal-pool-banners.tsx b/shared/banners/modal-pool-banners/modal-pool-banners.tsx index 16c0f1786..40c394bf4 100644 --- a/shared/banners/modal-pool-banners/modal-pool-banners.tsx +++ b/shared/banners/modal-pool-banners/modal-pool-banners.tsx @@ -1,10 +1,12 @@ import { trackEvent } from '@lidofinance/analytics-matomo'; -import { Curve } from 'shared/banners/curve'; + +import { config } from 'config'; import { MATOMO_CLICK_EVENTS } from 'consts/matomo-click-events'; +import { Curve } from 'shared/banners/curve'; import { TextStyles, DescStyles, ButtonLinkWrap, ButtonStyled } from './styles'; -const ECOSYSTEM_LINK = 'https://lido.fi/lido-ecosystem'; +const ECOSYSTEM_LINK = `${config.rootOrigin}/lido-ecosystem`; const linkClickHandler = () => trackEvent(...MATOMO_CLICK_EVENTS.clickExploreDeFi); diff --git a/shared/components/layout/footer/footer.tsx b/shared/components/layout/footer/footer.tsx index c4d95004e..b044d04f6 100644 --- a/shared/components/layout/footer/footer.tsx +++ b/shared/components/layout/footer/footer.tsx @@ -1,5 +1,6 @@ import { FC } from 'react'; import buildInfo from 'build-info.json'; +import { config } from 'config'; import { FooterStyle, @@ -42,13 +43,16 @@ export const Footer: FC = () => { return ( <FooterStyle size="full" forwardedAs="footer"> <LogoLidoStyle /> - <FooterLink data-testid="termsOfUse" href="https://lido.fi/terms-of-use"> + <FooterLink + data-testid="termsOfUse" + href={`${config.rootOrigin}/terms-of-use`} + > Terms of Use </FooterLink> <LinkDivider /> <FooterLink data-testid="privacyNotice" - href="https://lido.fi/privacy-notice" + href={`${config.rootOrigin}/privacy-notice`} $marginRight="auto" > Privacy Notice diff --git a/shared/components/logos/logos.tsx b/shared/components/logos/logos.tsx index b85e8d81d..ac6e5fbde 100644 --- a/shared/components/logos/logos.tsx +++ b/shared/components/logos/logos.tsx @@ -2,6 +2,8 @@ import { FC, HTMLAttributes, SVGProps } from 'react'; import Link from 'next/link'; import { LidoLogo } from '@lidofinance/lido-ui'; +import { config } from 'config'; + import { LogoLDOPLStyle, LogoLDOStyle, LogoLidoStyle } from './styles'; export type LogoComponent = FC<Omit<SVGProps<SVGSVGElement>, 'ref'>>; @@ -16,7 +18,7 @@ export const LogoLDOPL: LogoComponent = (props) => { export const LogoLido: FC<HTMLAttributes<HTMLDivElement>> = (props) => ( <LogoLidoStyle {...props}> - <Link href="https://lido.fi"> + <Link href={config.rootOrigin}> <LidoLogo data-testid="lidoLogo" /> </Link> </LogoLidoStyle> From ee655108b20cd326459a32ca043f2a1f1fb98004 Mon Sep 17 00:00:00 2001 From: Anton Shalimov <a.shalimof@yandex.ru> Date: Tue, 7 May 2024 15:28:23 +0300 Subject: [PATCH 07/30] fix(IPFS): metaPreviewImgUrl --- pages/_document.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pages/_document.tsx b/pages/_document.tsx index b947a3dfb..b19106b27 100644 --- a/pages/_document.tsx +++ b/pages/_document.tsx @@ -62,8 +62,10 @@ export default class MyDocument extends Document { } get metaPreviewImgUrl(): string { - // TODO: needs fix for IPFS - return `${config.selfOrigin}/lido-preview.png`; + const origin = config.ipfsMode + ? 'https://stake.lido.fi' + : config.selfOrigin; + return `${origin}/lido-preview.png`; } render(): JSX.Element { From 8ff52d56444ccf8a0dc5c8d4022ef70c9e4e6132 Mon Sep 17 00:00:00 2001 From: Anton Shalimov <a.shalimof@yandex.ru> Date: Tue, 7 May 2024 15:46:39 +0300 Subject: [PATCH 08/30] feat(ci): add '*_ORIGIN' envs to ci-ipfs*.yml --- .github/workflows/ci-ipfs-goerli.yml | 4 ++++ .github/workflows/ci-ipfs-test-production.yml | 4 ++++ .github/workflows/ci-ipfs-testnet.yml | 4 ++++ .github/workflows/ci-ipfs.yml | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/.github/workflows/ci-ipfs-goerli.yml b/.github/workflows/ci-ipfs-goerli.yml index 47e8607c9..167b31434 100644 --- a/.github/workflows/ci-ipfs-goerli.yml +++ b/.github/workflows/ci-ipfs-goerli.yml @@ -38,6 +38,10 @@ jobs: run: | yarn build-ipfs env: + ROOT_ORIGIN: ${{ vars.ROOT_ORIGIN }} + DOCS_ORIGIN: ${{ vars.DOCS_ORIGIN }} + HELP_ORIGIN: ${{ vars.HELP_ORIGIN }} + RESEARCH_ORIGIN: ${{ vars.RESEARCH_ORIGIN }} DEFAULT_CHAIN: ${{ vars.DEFAULT_CHAIN }} SUPPORTED_CHAINS: ${{ vars.SUPPORTED_CHAINS }} WIDGET_API_BASE_PATH_FOR_IPFS: ${{ vars.WIDGET_API_BASE_PATH_FOR_IPFS }} diff --git a/.github/workflows/ci-ipfs-test-production.yml b/.github/workflows/ci-ipfs-test-production.yml index afa5d55a3..fb796f9f4 100644 --- a/.github/workflows/ci-ipfs-test-production.yml +++ b/.github/workflows/ci-ipfs-test-production.yml @@ -38,6 +38,10 @@ jobs: run: | yarn build-ipfs env: + ROOT_ORIGIN: ${{ vars.ROOT_ORIGIN }} + DOCS_ORIGIN: ${{ vars.DOCS_ORIGIN }} + HELP_ORIGIN: ${{ vars.HELP_ORIGIN }} + RESEARCH_ORIGIN: ${{ vars.RESEARCH_ORIGIN }} DEFAULT_CHAIN: ${{ vars.DEFAULT_CHAIN }} SUPPORTED_CHAINS: ${{ vars.SUPPORTED_CHAINS }} WIDGET_API_BASE_PATH_FOR_IPFS: ${{ vars.WIDGET_API_BASE_PATH_FOR_IPFS }} diff --git a/.github/workflows/ci-ipfs-testnet.yml b/.github/workflows/ci-ipfs-testnet.yml index bdaa36cde..e5fac3723 100644 --- a/.github/workflows/ci-ipfs-testnet.yml +++ b/.github/workflows/ci-ipfs-testnet.yml @@ -33,6 +33,10 @@ jobs: run: | yarn build-ipfs env: + ROOT_ORIGIN: ${{ vars.ROOT_ORIGIN }} + DOCS_ORIGIN: ${{ vars.DOCS_ORIGIN }} + HELP_ORIGIN: ${{ vars.HELP_ORIGIN }} + RESEARCH_ORIGIN: ${{ vars.RESEARCH_ORIGIN }} DEFAULT_CHAIN: ${{ vars.DEFAULT_CHAIN }} SUPPORTED_CHAINS: ${{ vars.SUPPORTED_CHAINS }} WIDGET_API_BASE_PATH_FOR_IPFS: ${{ vars.WIDGET_API_BASE_PATH_FOR_IPFS }} diff --git a/.github/workflows/ci-ipfs.yml b/.github/workflows/ci-ipfs.yml index 9e788d188..8d222b441 100644 --- a/.github/workflows/ci-ipfs.yml +++ b/.github/workflows/ci-ipfs.yml @@ -42,6 +42,10 @@ jobs: run: | yarn build-ipfs env: + ROOT_ORIGIN: ${{ vars.ROOT_ORIGIN }} + DOCS_ORIGIN: ${{ vars.DOCS_ORIGIN }} + HELP_ORIGIN: ${{ vars.HELP_ORIGIN }} + RESEARCH_ORIGIN: ${{ vars.RESEARCH_ORIGIN }} DEFAULT_CHAIN: ${{ vars.DEFAULT_CHAIN }} SUPPORTED_CHAINS: ${{ vars.SUPPORTED_CHAINS }} WIDGET_API_BASE_PATH_FOR_IPFS: ${{ vars.WIDGET_API_BASE_PATH_FOR_IPFS }} From 7d8f7e37b3f08f2c77df96f19d08e60818c9bde2 Mon Sep 17 00:00:00 2001 From: Anton Shalimov <a.shalimof@yandex.ru> Date: Thu, 23 May 2024 11:48:53 +0300 Subject: [PATCH 09/30] feat: pass 'termsLink' and 'privacyNoticeLink' to reef-knot --- shared/wallet/connect-wallet-modal/connect-wallet-modal.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/shared/wallet/connect-wallet-modal/connect-wallet-modal.tsx b/shared/wallet/connect-wallet-modal/connect-wallet-modal.tsx index 8aac208cf..56dfe19a6 100644 --- a/shared/wallet/connect-wallet-modal/connect-wallet-modal.tsx +++ b/shared/wallet/connect-wallet-modal/connect-wallet-modal.tsx @@ -1,6 +1,8 @@ import { useThemeToggle } from '@lidofinance/lido-ui'; import { WalletsModalForEth } from 'reef-knot/connect-wallet-modal'; import { WalletIdsEthereum } from 'reef-knot/wallets'; + +import { config } from 'config'; import { walletsMetrics } from 'consts/matomo-wallets-events'; const WALLETS_PINNED: WalletIdsEthereum[] = ['okx', 'browserExtension']; @@ -13,6 +15,8 @@ export const ConnectWalletModal = () => { shouldInvertWalletIcon={themeName === 'dark'} metrics={walletsMetrics} walletsPinned={WALLETS_PINNED} + termsLink={`${config.rootOrigin}/terms-of-use`} + privacyNoticeLink={`${config.rootOrigin}/privacy-notice`} /> ); }; From 67a5122d0ce1576a2a0baeacf23fd638a81142d6 Mon Sep 17 00:00:00 2001 From: Anton Shalimov <a.shalimof@yandex.ru> Date: Thu, 23 May 2024 12:47:09 +0300 Subject: [PATCH 10/30] fix: fix rootOrigin for faq --- env-dynamics.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/env-dynamics.mjs b/env-dynamics.mjs index 8e6042903..a9eec6ce8 100644 --- a/env-dynamics.mjs +++ b/env-dynamics.mjs @@ -21,7 +21,7 @@ export const ipfsMode = toBoolean(process.env.IPFS_MODE); /** @type string */ export const selfOrigin = process.env.SELF_ORIGIN; /** @type string */ -export const rootOrigin = process.env.ROOT_ORIGIN; +export const rootOrigin = process.env.ROOT_ORIGIN || ''; /** @type string */ export const docsOrigin = process.env.DOCS_ORIGIN; /** @type string */ From d752e3ed92d8c3b1ee9002079975a460740c68a6 Mon Sep 17 00:00:00 2001 From: Evgeny Taktarov <je.mouth@gmail.com> Date: Wed, 29 May 2024 19:14:17 +0700 Subject: [PATCH 11/30] fix: error handling for failed tx --- utils/getErrorMessage.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/utils/getErrorMessage.ts b/utils/getErrorMessage.ts index 0b42a3edd..1678bb215 100644 --- a/utils/getErrorMessage.ts +++ b/utils/getErrorMessage.ts @@ -2,6 +2,7 @@ export enum ErrorMessage { NOT_ENOUGH_ETHER = 'Not enough ether for gas.', DENIED_SIG = 'User denied the transaction signature.', SOMETHING_WRONG = 'Something went wrong.', + TRANSACTION_REVERTED = 'Transaction was included into block but reverted during execution', ENABLE_BLIND_SIGNING = 'Please enable blind signing on your Ledger hardware wallet.', LIMIT_REACHED = 'Transaction could not be completed because stake limit is exhausted. Please wait until the stake limit restores and try again. Otherwise, you can swap your Ethereum on 1inch platform instantly.', DEVICE_LOCKED = 'Please unlock your Ledger hardware wallet', @@ -32,6 +33,8 @@ export const getErrorMessage = (error: unknown): ErrorMessage => { return ErrorMessage.LIMIT_REACHED; case 'INVALID_REFERRAL': return ErrorMessage.INVALID_REFERRAL; + case 'TRANSACTION_REVERTED': + return ErrorMessage.TRANSACTION_REVERTED; case 'ENABLE_BLIND_SIGNING': return ErrorMessage.ENABLE_BLIND_SIGNING; case 'DEVICE_LOCKED': @@ -49,6 +52,15 @@ export const extractCodeFromError = ( // early exit on non object error if (!error || typeof error != 'object') return 0; + if ( + 'code' in error && + error.code === 'CALL_EXCEPTION' && + 'receipt' in error + ) { + const receipt = error.receipt as { blockHash?: string }; + if (receipt.blockHash?.startsWith('0x')) return 'TRANSACTION_REVERTED'; + } + if ('reason' in error && typeof error.reason == 'string') { if (error.reason.includes('STAKE_LIMIT')) return 'LIMIT_REACHED'; if (error.reason.includes('INVALID_REFERRAL')) return 'INVALID_REFERRAL'; From 7aaad55561bc986e25a65407e9da808e6e1c2150 Mon Sep 17 00:00:00 2001 From: Evgeny Taktarov <je.mouth@gmail.com> Date: Wed, 29 May 2024 19:34:40 +0700 Subject: [PATCH 12/30] build(ci): remove goerli jobs --- .github/workflows/ci-dev.yml | 9 --------- .github/workflows/ci-ens.yml | 1 - 2 files changed, 10 deletions(-) diff --git a/.github/workflows/ci-dev.yml b/.github/workflows/ci-dev.yml index 170557437..29671e68b 100644 --- a/.github/workflows/ci-dev.yml +++ b/.github/workflows/ci-dev.yml @@ -30,15 +30,6 @@ jobs: TARGET_WORKFLOW: 'deploy_holesky_testnet_ethereum_staking_widget.yaml' TARGET: 'develop' - - name: Goerli testnet deploy - uses: lidofinance/dispatch-workflow@v1 - env: - APP_ID: ${{ secrets.APP_ID }} - APP_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }} - TARGET_REPO: 'lidofinance/infra-mainnet' - TARGET_WORKFLOW: 'deploy_testnet_ethereum_staking_widget.yaml' - TARGET: 'develop' - tests: needs: deploy if: ${{ github.event.pull_request.draft == false }} diff --git a/.github/workflows/ci-ens.yml b/.github/workflows/ci-ens.yml index f1cc3c70e..daf87ca01 100644 --- a/.github/workflows/ci-ens.yml +++ b/.github/workflows/ci-ens.yml @@ -12,7 +12,6 @@ on: required: true type: choice options: - - goerli - mainnet jobs: From e2f84b1c1fa85988fb0b9345dedf8cc75acddf20 Mon Sep 17 00:00:00 2001 From: Evgeny Taktarov <je.mouth@gmail.com> Date: Thu, 30 May 2024 13:27:11 +0700 Subject: [PATCH 13/30] build(ci): remove experimental ens ci --- .github/workflows/ci-ens.yml | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 .github/workflows/ci-ens.yml diff --git a/.github/workflows/ci-ens.yml b/.github/workflows/ci-ens.yml deleted file mode 100644 index daf87ca01..000000000 --- a/.github/workflows/ci-ens.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Deploy ENS - -on: - workflow_dispatch: - inputs: - IPFS_CID: - description: 'IPFS CID' - required: true - type: string - CHAIN_NAME: - description: 'Chain name' - required: true - type: choice - options: - - mainnet - -jobs: - ens-deploy: - uses: lidofinance/actions/.github/workflows/ci-ens.yml@main - with: - ipfs_cid: ${{ inputs.IPFS_CID }} - chain_name: ${{ inputs.CHAIN_NAME }} - secrets: - DELEGATE_PRIVATE_KEY: ${{ secrets.DELEGATE_PRIVATE_KEY }} From 80d72a6b68c6ab6f712009a8d5111e6d57548352 Mon Sep 17 00:00:00 2001 From: Evgeny Taktarov <je.mouth@gmail.com> Date: Thu, 30 May 2024 13:48:40 +0700 Subject: [PATCH 14/30] fix: blinking best rate --- features/withdrawals/request/form/options/options-picker.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/withdrawals/request/form/options/options-picker.tsx b/features/withdrawals/request/form/options/options-picker.tsx index abc8c359c..79af92aa8 100644 --- a/features/withdrawals/request/form/options/options-picker.tsx +++ b/features/withdrawals/request/form/options/options-picker.tsx @@ -83,7 +83,7 @@ const toFloor = (num: number): string => (Math.floor(num * 10000) / 10000).toString(); const DexButton: React.FC<OptionButtonProps> = ({ isActive, onClick }) => { - const { loading, bestRate, enabledDexes } = useWithdrawalRates({ + const { initialLoading, bestRate, enabledDexes } = useWithdrawalRates({ fallbackValue: DEFAULT_VALUE_FOR_RATE, }); const isAnyDexEnabled = enabledDexes.length > 0; @@ -107,7 +107,7 @@ const DexButton: React.FC<OptionButtonProps> = ({ isActive, onClick }) => { </OptionsPickerRow> <OptionsPickerRow data-testid="dexBestRate"> <OptionsPickerSubLabel>Best Rate:</OptionsPickerSubLabel> - {loading ? <InlineLoaderSmall /> : bestRateValue} + {initialLoading ? <InlineLoaderSmall /> : bestRateValue} </OptionsPickerRow> <OptionsPickerRow data-testid="dexWaitingTime"> <OptionsPickerSubLabel>Waiting time:</OptionsPickerSubLabel>{' '} From e2e463d1d8409ef8bcd5831467f035b95313e1d8 Mon Sep 17 00:00:00 2001 From: Evgeny Taktarov <je.mouth@gmail.com> Date: Thu, 30 May 2024 15:52:17 +0700 Subject: [PATCH 15/30] build: clean up build scripts --- .github/workflows/ci-ipfs-goerli.yml | 2 +- .github/workflows/ci-ipfs-test-production.yml | 2 +- .github/workflows/ci-ipfs-testnet.yml | 2 +- .github/workflows/ci-ipfs.yml | 2 +- README.md | 4 ++-- features/ipfs/home-page-ipfs.tsx | 2 +- next.config.mjs | 2 +- package.json | 11 +++++------ yarn.lock | 9 +-------- 9 files changed, 14 insertions(+), 22 deletions(-) diff --git a/.github/workflows/ci-ipfs-goerli.yml b/.github/workflows/ci-ipfs-goerli.yml index 47e8607c9..2ee2a0ac9 100644 --- a/.github/workflows/ci-ipfs-goerli.yml +++ b/.github/workflows/ci-ipfs-goerli.yml @@ -36,7 +36,7 @@ jobs: yarn install --frozen-lockfile - name: Build run: | - yarn build-ipfs + yarn build:ipfs env: DEFAULT_CHAIN: ${{ vars.DEFAULT_CHAIN }} SUPPORTED_CHAINS: ${{ vars.SUPPORTED_CHAINS }} diff --git a/.github/workflows/ci-ipfs-test-production.yml b/.github/workflows/ci-ipfs-test-production.yml index afa5d55a3..497028c5c 100644 --- a/.github/workflows/ci-ipfs-test-production.yml +++ b/.github/workflows/ci-ipfs-test-production.yml @@ -36,7 +36,7 @@ jobs: yarn install --frozen-lockfile - name: Build run: | - yarn build-ipfs + yarn build:ipfs env: DEFAULT_CHAIN: ${{ vars.DEFAULT_CHAIN }} SUPPORTED_CHAINS: ${{ vars.SUPPORTED_CHAINS }} diff --git a/.github/workflows/ci-ipfs-testnet.yml b/.github/workflows/ci-ipfs-testnet.yml index bdaa36cde..4d1ff229f 100644 --- a/.github/workflows/ci-ipfs-testnet.yml +++ b/.github/workflows/ci-ipfs-testnet.yml @@ -31,7 +31,7 @@ jobs: yarn install --frozen-lockfile - name: Build run: | - yarn build-ipfs + yarn build:ipfs env: DEFAULT_CHAIN: ${{ vars.DEFAULT_CHAIN }} SUPPORTED_CHAINS: ${{ vars.SUPPORTED_CHAINS }} diff --git a/.github/workflows/ci-ipfs.yml b/.github/workflows/ci-ipfs.yml index 9e788d188..4a6b7cad9 100644 --- a/.github/workflows/ci-ipfs.yml +++ b/.github/workflows/ci-ipfs.yml @@ -40,7 +40,7 @@ jobs: yarn install --frozen-lockfile - name: Build run: | - yarn build-ipfs + yarn build:ipfs env: DEFAULT_CHAIN: ${{ vars.DEFAULT_CHAIN }} SUPPORTED_CHAINS: ${{ vars.SUPPORTED_CHAINS }} diff --git a/README.md b/README.md index 413ff5198..0bc9fd878 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ yarn dev for IPFS mode below: ```bash -yarn dev-ipfs # will start with HMR +yarn dev:ipfs # will start with HMR ``` ### Environment variables @@ -61,7 +61,7 @@ yarn build && yarn start for IPFS mode below: ```bash -yarn build-ipfs +yarn build:ipfs ``` ## Adding a new route API diff --git a/features/ipfs/home-page-ipfs.tsx b/features/ipfs/home-page-ipfs.tsx index 9f84a3d51..1b97361c2 100644 --- a/features/ipfs/home-page-ipfs.tsx +++ b/features/ipfs/home-page-ipfs.tsx @@ -111,6 +111,6 @@ export const HomePageIpfs: FC = () => { } } - // Fix for runtime of `dev-ipfs` (see: package.json scripts) + // Fix for runtime of `dev:ipfs` (see: package.json scripts) return <NoSSRWrapper>{spaPage}</NoSSRWrapper>; }; diff --git a/next.config.mjs b/next.config.mjs index 90ce35a8b..35741393f 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -8,7 +8,7 @@ buildDynamics(); const basePath = process.env.BASE_PATH; const developmentMode = process.env.NODE_ENV === 'development'; -const isIPFSMode = process.env.IPFS_MODE; +const isIPFSMode = process.env.IPFS_MODE === 'true'; // cache control export const CACHE_CONTROL_HEADER = 'x-cache-control'; diff --git a/package.json b/package.json index b8bbc0fc5..2fd0806b0 100644 --- a/package.json +++ b/package.json @@ -6,11 +6,11 @@ "license": "GPL-3.0-or-later", "scripts": { "dev": "NODE_ENV=development node server.mjs", - "build": "next build", - "build:analyze": "ANALYZE_BUNDLE=true next build", - "start": "NODE_OPTIONS='-r next-logger' NODE_ENV=production node server.mjs", - "dev-ipfs": "cross-env IPFS_MODE=true next dev", - "build-ipfs": "cross-env IPFS_MODE=true next build && cross-env IPFS_MODE=true next export", + "dev:ipfs": "IPFS_MODE=true next dev", + "build": "NODE_OPTIONS='--no-warnings=ExperimentalWarning' next build", + "build:analyze": "ANALYZE_BUNDLE=true yarn build", + "build:ipfs": "IPFS_MODE=true yarn build && IPFS_MODE=true next export", + "start": "NODE_ENV=production node -r next-logger --no-warnings=ExperimentalWarning server.mjs", "lint": "eslint --ext ts,tsx,js,mjs .", "lint:fix": "yarn lint --fix", "types": "tsc --noEmit", @@ -103,7 +103,6 @@ "@types/winston": "^2.4.4", "@typescript-eslint/eslint-plugin": "^6.2.1", "@typescript-eslint/parser": "^6.2.1", - "cross-env": "^7.0.3", "eslint": "^8.46.0", "eslint-config-prettier": "^9.0.0", "eslint-import-resolver-typescript": "^3.5.5", diff --git a/yarn.lock b/yarn.lock index 8e74363a1..b345fdd73 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5101,13 +5101,6 @@ create-require@^1.1.0: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== -cross-env@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" - integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== - dependencies: - cross-spawn "^7.0.1" - cross-fetch@^3.1.4: version "3.1.8" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.8.tgz#0327eba65fd68a7d119f8fb2bf9334a1a7956f82" @@ -5115,7 +5108,7 @@ cross-fetch@^3.1.4: dependencies: node-fetch "^2.6.12" -cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== From f8c8844be5b044065e11b0d965abe8f65fa26006 Mon Sep 17 00:00:00 2001 From: Evgeny Taktarov <je.mouth@gmail.com> Date: Thu, 30 May 2024 17:28:59 +0700 Subject: [PATCH 16/30] fix: double states for dex options --- .../request/form/options/dex-options.tsx | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/features/withdrawals/request/form/options/dex-options.tsx b/features/withdrawals/request/form/options/dex-options.tsx index 34e3ee727..9a5ac877c 100644 --- a/features/withdrawals/request/form/options/dex-options.tsx +++ b/features/withdrawals/request/form/options/dex-options.tsx @@ -33,6 +33,19 @@ const DexOption: React.FC<DexOptionProps> = ({ loading, onClickGoTo, }) => { + let amountComponent: React.ReactNode = '-'; + if (loading) { + amountComponent = <InlineLoaderSmall />; + } else if (toReceive) { + amountComponent = ( + <FormatToken + approx + amount={toReceive ?? BigNumber.from(0)} + symbol="ETH" + /> + ); + } + return ( <DexOptionStyled> <Icon /> @@ -45,18 +58,7 @@ const DexOption: React.FC<DexOptionProps> = ({ > Go to {title} </DexOptionBlockLink> - <DexOptionAmount> - {loading && !toReceive && <InlineLoaderSmall />} - {toReceive ? ( - <FormatToken - approx - amount={toReceive ?? BigNumber.from(0)} - symbol="ETH" - /> - ) : ( - '-' - )} - </DexOptionAmount> + <DexOptionAmount>{amountComponent}</DexOptionAmount> </DexOptionStyled> ); }; From ceda512f55403655fe1b1d09a86ca7968c9856ce Mon Sep 17 00:00:00 2001 From: Anton Shalimov <a.shalimof@yandex.ru> Date: Mon, 3 Jun 2024 14:01:32 +0300 Subject: [PATCH 17/30] feat: add default origins to env-dynamics.mjs --- env-dynamics.mjs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/env-dynamics.mjs b/env-dynamics.mjs index a9eec6ce8..134d4e4dd 100644 --- a/env-dynamics.mjs +++ b/env-dynamics.mjs @@ -19,15 +19,24 @@ const toBoolean = (val) => { export const ipfsMode = toBoolean(process.env.IPFS_MODE); /** @type string */ -export const selfOrigin = process.env.SELF_ORIGIN; +export const selfOrigin = process.env.SELF_ORIGIN || 'https://stake.lido.fi'; +// Fix in the build time (build time don't have env vars) + /** @type string */ -export const rootOrigin = process.env.ROOT_ORIGIN || ''; +export const rootOrigin = process.env.ROOT_ORIGIN || 'https://lido.fi'; +// Fix in the build time (build time don't have env vars) + /** @type string */ -export const docsOrigin = process.env.DOCS_ORIGIN; +export const docsOrigin = process.env.DOCS_ORIGIN || 'https://docs.lido.fi'; +// Fix in the build time (build time don't have env vars) + /** @type string */ -export const helpOrigin = process.env.HELP_ORIGIN; +export const helpOrigin = process.env.HELP_ORIGIN || 'https://help.lido.fi'; +// Fix in the build time (build time don't have env vars) + /** @type string */ -export const researchOrigin = process.env.RESEARCH_ORIGIN; +export const researchOrigin = process.env.RESEARCH_ORIGIN || 'https://research.lido.fi'; +// Fix in the build time (build time don't have env vars) // Keep fallback as in 'config/get-secret-config.ts' /** @type number */ From aa6212d1d0f6980badc9d4eb096b72766bbfbdbb Mon Sep 17 00:00:00 2001 From: Anton Shalimov <a.shalimof@yandex.ru> Date: Mon, 3 Jun 2024 14:02:26 +0300 Subject: [PATCH 18/30] feat: add revalidate 60s for all pages --- pages/index.tsx | 9 ++++++++- pages/referral.tsx | 8 ++++++++ pages/rewards.tsx | 8 ++++++++ pages/settings.tsx | 5 ++++- pages/withdrawals/[mode].tsx | 2 +- pages/wrap/[[...mode]].tsx | 5 +++-- 6 files changed, 32 insertions(+), 5 deletions(-) diff --git a/pages/index.tsx b/pages/index.tsx index 1d106536b..4a2b17c67 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,6 +1,13 @@ +import { GetStaticProps } from 'next'; import { config } from 'config'; - import { StakePage } from 'features/stake'; import { HomePageIpfs } from 'features/ipfs'; export default config.ipfsMode ? HomePageIpfs : StakePage; + +export const getStaticProps: GetStaticProps = async () => { + return { + props: {}, + revalidate: 60, + }; +}; diff --git a/pages/referral.tsx b/pages/referral.tsx index 40dff0604..f60165f9a 100644 --- a/pages/referral.tsx +++ b/pages/referral.tsx @@ -1,4 +1,5 @@ import { FC } from 'react'; +import { GetStaticProps } from 'next'; import { Banner } from 'features/referral'; import { Layout } from 'shared/components'; @@ -11,3 +12,10 @@ const Referral: FC = () => { }; export default Referral; + +export const getStaticProps: GetStaticProps = async () => { + return { + props: {}, + revalidate: 60, + }; +}; diff --git a/pages/rewards.tsx b/pages/rewards.tsx index b197c291e..f48f377e2 100644 --- a/pages/rewards.tsx +++ b/pages/rewards.tsx @@ -1,4 +1,5 @@ import { FC } from 'react'; +import { GetStaticProps } from 'next'; import Head from 'next/head'; import { Layout } from 'shared/components'; import { TopCard, RewardsList } from 'features/rewards/features'; @@ -32,3 +33,10 @@ const Rewards: FC = () => { }; export default Rewards; + +export const getStaticProps: GetStaticProps = async () => { + return { + props: {}, + revalidate: 60, + }; +}; diff --git a/pages/settings.tsx b/pages/settings.tsx index bd584333c..9d88b7d4a 100644 --- a/pages/settings.tsx +++ b/pages/settings.tsx @@ -18,5 +18,8 @@ export default Settings; export const getStaticProps: GetStaticProps = async () => { if (!config.ipfsMode) return { notFound: true }; - return { props: {} }; + return { + props: {}, + revalidate: 60, + }; }; diff --git a/pages/withdrawals/[mode].tsx b/pages/withdrawals/[mode].tsx index 7aada07a3..45b4c95ee 100644 --- a/pages/withdrawals/[mode].tsx +++ b/pages/withdrawals/[mode].tsx @@ -49,5 +49,5 @@ export const getStaticProps: GetStaticProps< WithdrawalsModePageParams > = async ({ params }) => { if (!params?.mode) return { notFound: true }; - return { props: { mode: params.mode } }; + return { props: { mode: params.mode }, revalidate: 60 }; }; diff --git a/pages/wrap/[[...mode]].tsx b/pages/wrap/[[...mode]].tsx index 97a695c2d..34255198c 100644 --- a/pages/wrap/[[...mode]].tsx +++ b/pages/wrap/[[...mode]].tsx @@ -43,8 +43,9 @@ export const getStaticProps: GetStaticProps< WrapModePageParams > = async ({ params }) => { const mode = params?.mode; - if (!mode) return { props: { mode: 'wrap' } }; - if (mode[0] === 'unwrap') return { props: { mode: 'unwrap' } }; + if (!mode) return { props: { mode: 'wrap' }, revalidate: 60 }; + if (mode[0] === 'unwrap') + return { props: { mode: 'unwrap' }, revalidate: 60 }; return { notFound: true }; }; From f3350d45d84279b81248128c9bd83dd130356020 Mon Sep 17 00:00:00 2001 From: Dmitrii Podlesnyi <rezed93@gmail.com> Date: Tue, 4 Jun 2024 18:00:50 +0700 Subject: [PATCH 19/30] feat: vault banners --- assets/vault-banner/icon-gauntlet-dark.svg | 1 + assets/vault-banner/icon-gauntlet-light.svg | 1 + assets/vault-banner/icon-p2p-dark.svg | 1 + assets/vault-banner/icon-p2p-light.svg | 1 + assets/vault-banner/icon-re7-dark.svg | 1 + assets/vault-banner/icon-re7-light.svg | 1 + assets/vault-banner/icon-stakehouse-dark.svg | 1 + assets/vault-banner/icon-stakehouse-light.svg | 1 + assets/vault-banner/strategy-stakehouse.svg | 1 + assets/vault-banner/symbol-plus.svg | 1 + config/feature-flags/hooks.ts | 24 ++--- config/feature-flags/types.ts | 2 + config/feature-flags/utils.ts | 1 + consts/matomo-click-events.ts | 12 +++ features/stake/stake-form/stake-form.tsx | 9 +- .../wsteth/unwrap/unwrap-form/unwrap-form.tsx | 9 +- features/wsteth/wrap/wrap-form/wrap-form.tsx | 9 +- .../banner-link-button/banner-link-button.tsx | 35 ++++++++ shared/banners/banner-link-button/index.ts | 1 + shared/banners/banner-link-button/styles.ts | 33 +++++++ shared/banners/l2-banner/l2-banner.tsx | 39 +++----- shared/banners/l2-banner/styles.ts | 32 ------- shared/banners/vaults-banner-info/index.ts | 1 + shared/banners/vaults-banner-info/styles.ts | 38 ++++++++ .../vaults-banner-info/vaults-banner-info.tsx | 50 +++++++++++ .../banners/vaults-banner-strategies/index.ts | 1 + .../vaults-banner-strategies/styles.ts | 88 +++++++++++++++++++ .../vaults-banner-strategies.tsx | 81 +++++++++++++++++ ...-stage-operation-succeed-balance-shown.tsx | 19 ++-- 29 files changed, 405 insertions(+), 89 deletions(-) create mode 100644 assets/vault-banner/icon-gauntlet-dark.svg create mode 100644 assets/vault-banner/icon-gauntlet-light.svg create mode 100644 assets/vault-banner/icon-p2p-dark.svg create mode 100644 assets/vault-banner/icon-p2p-light.svg create mode 100644 assets/vault-banner/icon-re7-dark.svg create mode 100644 assets/vault-banner/icon-re7-light.svg create mode 100644 assets/vault-banner/icon-stakehouse-dark.svg create mode 100644 assets/vault-banner/icon-stakehouse-light.svg create mode 100644 assets/vault-banner/strategy-stakehouse.svg create mode 100644 assets/vault-banner/symbol-plus.svg create mode 100644 shared/banners/banner-link-button/banner-link-button.tsx create mode 100644 shared/banners/banner-link-button/index.ts create mode 100644 shared/banners/banner-link-button/styles.ts create mode 100644 shared/banners/vaults-banner-info/index.ts create mode 100644 shared/banners/vaults-banner-info/styles.ts create mode 100644 shared/banners/vaults-banner-info/vaults-banner-info.tsx create mode 100644 shared/banners/vaults-banner-strategies/index.ts create mode 100644 shared/banners/vaults-banner-strategies/styles.ts create mode 100644 shared/banners/vaults-banner-strategies/vaults-banner-strategies.tsx diff --git a/assets/vault-banner/icon-gauntlet-dark.svg b/assets/vault-banner/icon-gauntlet-dark.svg new file mode 100644 index 000000000..07fb19f71 --- /dev/null +++ b/assets/vault-banner/icon-gauntlet-dark.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" fill="none"><rect width="39" height="39" x=".5" y=".5" stroke="#fff" stroke-opacity=".1" rx="19.5"/><g clip-path="url(#a)"><g filter="url(#b)" opacity=".5"><path fill="#7180F5" fill-rule="evenodd" d="M18.323 21.9h3.786v-3.8h-3.786v-3.8h7.572v11.4H14.536v-3.8H10.75V6.7h15.145v3.8H14.536V21.9h3.787Z" clip-rule="evenodd"/><path fill="#FF8099" d="M29.682 10.5h-3.787v3.8h3.787v-3.8Z"/><path fill="#1E1C2D" d="M14.536 25.7H10.75v3.8h3.786v-3.8Z"/></g><path fill="#7180F5" fill-rule="evenodd" d="M19.023 24.75h3.786v-3.8h-3.786v-3.8h7.573v11.4h-11.36v-3.8H11.45V9.55h15.146v3.8h-11.36V24.75h3.787Z" clip-rule="evenodd"/><path fill="#FF8099" d="M30.382 13.35h-3.786v3.8h3.786v-3.8Z"/><path fill="#1E1C2D" d="M15.237 28.55H11.45v3.8h3.787v-3.8Z"/></g><defs><clipPath id="a"><path fill="#fff" d="M1 1h38v38H1z"/></clipPath><filter id="b" width="46.932" height="50.8" x="-3.25" y="-7.3" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_6369_12529" stdDeviation="7"/></filter></defs></svg> diff --git a/assets/vault-banner/icon-gauntlet-light.svg b/assets/vault-banner/icon-gauntlet-light.svg new file mode 100644 index 000000000..35c2bbac2 --- /dev/null +++ b/assets/vault-banner/icon-gauntlet-light.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" fill="none"><rect width="39" height="39" x=".5" y=".5" stroke="#000" stroke-opacity=".1" rx="19.5"/><g clip-path="url(#a)"><g filter="url(#b)" opacity=".5"><path fill="#7180F5" fill-rule="evenodd" d="M18.323 21.9h3.786v-3.8h-3.786v-3.8h7.572v11.4H14.536v-3.8H10.75V6.7h15.145v3.8H14.536V21.9h3.787Z" clip-rule="evenodd"/><path fill="#FF8099" d="M29.682 10.5h-3.787v3.8h3.787v-3.8Z"/><path fill="#1E1C2D" d="M14.536 25.7H10.75v3.8h3.786v-3.8Z"/></g><path fill="#7180F5" fill-rule="evenodd" d="M19.023 24.75h3.786v-3.8h-3.786v-3.8h7.573v11.4h-11.36v-3.8H11.45V9.55h15.146v3.8h-11.36V24.75h3.787Z" clip-rule="evenodd"/><path fill="#FF8099" d="M30.382 13.35h-3.786v3.8h3.786v-3.8Z"/><path fill="#1E1C2D" d="M15.237 28.55H11.45v3.8h3.787v-3.8Z"/></g><defs><clipPath id="a"><path fill="#fff" d="M1 1h38v38H1z"/></clipPath><filter id="b" width="46.932" height="50.8" x="-3.25" y="-7.3" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_6254_13385" stdDeviation="7"/></filter></defs></svg> diff --git a/assets/vault-banner/icon-p2p-dark.svg b/assets/vault-banner/icon-p2p-dark.svg new file mode 100644 index 000000000..d1f4bd43a --- /dev/null +++ b/assets/vault-banner/icon-p2p-dark.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" fill="none"><rect width="39" height="39" x=".5" y=".5" stroke="#fff" stroke-opacity=".1" rx="19.5"/><g clip-path="url(#a)"><path fill="#fff" fill-rule="evenodd" d="M6.362 17.078c0-.056.046-.102.102-.102h7.959c.056 0 .102.046.102.102v3.056a.102.102 0 0 1-.102.102H6.464a.102.102 0 0 1-.102-.102v-3.056Zm7.142 2.088c0 .028-.022.051-.05.051h-6.02a.051.051 0 0 1-.051-.05v-1.121c0-.028.022-.051.05-.051h6.02c.029 0 .051.023.051.05v1.121Zm-6.223 2.292c.056 0 .102.046.102.102v.815a.102.102 0 0 1-.102.102h-.817a.102.102 0 0 1-.102-.102v-.815c0-.056.046-.102.102-.102h.817Zm18.875.102a.102.102 0 0 0-.102-.102h-.816a.102.102 0 0 0-.102.102v.815c0 .056.046.102.102.102h.816a.102.102 0 0 0 .102-.102v-.815Zm-10.305-.102a.102.102 0 0 0-.102.102v.815c0 .056.046.102.102.102h7.958a.102.102 0 0 0 .102-.102v-.815a.102.102 0 0 0-.102-.102h-7.958Zm9.285-4.38c0-.056.046-.102.102-.102h7.958c.056 0 .102.046.102.102v3.056a.102.102 0 0 1-.102.102h-7.958a.102.102 0 0 1-.102-.102v-3.056Zm7.09.917c.029 0 .052.023.052.05v1.121c0 .028-.023.051-.051.051h-6.02a.051.051 0 0 1-.05-.05v-1.121c0-.028.022-.051.05-.051h6.02Zm-16.477-.917c0-.056.046-.102.102-.102h7.958c.057 0 .102.046.102.102v3.056a.102.102 0 0 1-.102.102h-7.958a.102.102 0 0 1-.102-.102v-.815c0-.056.046-.102.102-.102h6.99a.05.05 0 0 0 .05-.05v-1.121a.05.05 0 0 0-.05-.051h-6.99a.102.102 0 0 1-.102-.102v-.815Z" clip-rule="evenodd"/><g filter="url(#b)"><path fill="#fff" fill-opacity=".5" fill-rule="evenodd" d="M6.362 16.146c0-.056.046-.102.102-.102h7.959c.056 0 .102.046.102.102v3.056a.102.102 0 0 1-.102.102H6.464a.102.102 0 0 1-.102-.102v-3.056Zm7.142 2.088c0 .028-.022.051-.05.051h-6.02a.051.051 0 0 1-.051-.05v-1.121c0-.029.022-.051.05-.051h6.02c.029 0 .051.023.051.05v1.121Zm-6.223 2.292c.056 0 .102.046.102.102v.815a.102.102 0 0 1-.102.102h-.817a.102.102 0 0 1-.102-.102v-.815c0-.056.046-.102.102-.102h.817Zm18.875.102a.102.102 0 0 0-.102-.102h-.816a.102.102 0 0 0-.102.102v.815c0 .056.046.102.102.102h.816a.102.102 0 0 0 .102-.102v-.815Zm-10.305-.102a.102.102 0 0 0-.102.102v.815c0 .056.046.102.102.102h7.958a.102.102 0 0 0 .102-.102v-.815a.102.102 0 0 0-.102-.102h-7.958Zm9.285-4.38c0-.056.046-.102.102-.102h7.958c.056 0 .102.046.102.102v3.056a.102.102 0 0 1-.102.102h-7.958a.102.102 0 0 1-.102-.102v-3.056Zm7.09.917c.029 0 .052.023.052.05v1.121c0 .028-.023.051-.051.051h-6.02a.051.051 0 0 1-.05-.05v-1.121c0-.029.022-.051.05-.051h6.02Zm-16.477-.917c0-.056.046-.102.102-.102h7.958c.057 0 .102.046.102.102v3.056a.102.102 0 0 1-.102.102h-7.958a.102.102 0 0 1-.102-.102v-.815c0-.056.046-.102.102-.102h6.99a.05.05 0 0 0 .05-.05v-1.121a.051.051 0 0 0-.05-.051h-6.99a.102.102 0 0 1-.102-.102v-.815Z" clip-rule="evenodd"/></g></g><defs><clipPath id="a"><path fill="#fff" d="M1 1h38v38H1z"/></clipPath><filter id="b" width="46.935" height="25.501" x="-3.638" y="6.044" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_6369_12526" stdDeviation="5"/></filter></defs></svg> diff --git a/assets/vault-banner/icon-p2p-light.svg b/assets/vault-banner/icon-p2p-light.svg new file mode 100644 index 000000000..1d1a94860 --- /dev/null +++ b/assets/vault-banner/icon-p2p-light.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" fill="none"><rect width="39" height="39" x=".5" y=".5" stroke="#000" stroke-opacity=".1" rx="19.5"/><g clip-path="url(#a)"><path fill="#121314" fill-rule="evenodd" d="M6.362 17.078c0-.056.046-.102.102-.102h7.959c.056 0 .102.046.102.102v3.056a.102.102 0 0 1-.102.102H6.464a.102.102 0 0 1-.102-.102v-3.056Zm7.142 2.088c0 .028-.022.051-.05.051h-6.02a.051.051 0 0 1-.051-.05v-1.121c0-.028.022-.051.05-.051h6.02c.029 0 .051.023.051.05v1.121Zm-6.223 2.292c.056 0 .102.046.102.102v.815a.102.102 0 0 1-.102.102h-.817a.102.102 0 0 1-.102-.102v-.815c0-.056.046-.102.102-.102h.817Zm18.875.102a.102.102 0 0 0-.102-.102h-.816a.102.102 0 0 0-.102.102v.815c0 .056.046.102.102.102h.816a.102.102 0 0 0 .102-.102v-.815Zm-10.305-.102a.102.102 0 0 0-.102.102v.815c0 .056.046.102.102.102h7.958a.102.102 0 0 0 .102-.102v-.815a.102.102 0 0 0-.102-.102h-7.958Zm9.285-4.38c0-.056.046-.102.102-.102h7.958c.056 0 .102.046.102.102v3.056a.102.102 0 0 1-.102.102h-7.958a.102.102 0 0 1-.102-.102v-3.056Zm7.09.917c.029 0 .052.023.052.05v1.121c0 .028-.023.051-.051.051h-6.02a.051.051 0 0 1-.05-.05v-1.121c0-.028.022-.051.05-.051h6.02Zm-16.477-.917c0-.056.046-.102.102-.102h7.958c.057 0 .102.046.102.102v3.056a.102.102 0 0 1-.102.102h-7.958a.102.102 0 0 1-.102-.102v-.815c0-.056.046-.102.102-.102h6.99a.05.05 0 0 0 .05-.05v-1.121a.05.05 0 0 0-.05-.051h-6.99a.102.102 0 0 1-.102-.102v-.815Z" clip-rule="evenodd"/><g filter="url(#b)"><path fill="#121314" fill-opacity=".5" fill-rule="evenodd" d="M6.362 16.146c0-.056.046-.102.102-.102h7.959c.056 0 .102.046.102.102v3.056a.102.102 0 0 1-.102.102H6.464a.102.102 0 0 1-.102-.102v-3.056Zm7.142 2.088c0 .028-.022.051-.05.051h-6.02a.051.051 0 0 1-.051-.05v-1.121c0-.028.022-.051.05-.051h6.02c.029 0 .051.023.051.05v1.121Zm-6.223 2.292c.056 0 .102.046.102.102v.815a.102.102 0 0 1-.102.102h-.817a.102.102 0 0 1-.102-.102v-.815c0-.056.046-.102.102-.102h.817Zm18.875.102a.102.102 0 0 0-.102-.102h-.816a.102.102 0 0 0-.102.102v.815c0 .057.046.102.102.102h.816a.102.102 0 0 0 .102-.102v-.815Zm-10.305-.102a.102.102 0 0 0-.102.102v.815c0 .057.046.102.102.102h7.958a.102.102 0 0 0 .102-.102v-.815a.102.102 0 0 0-.102-.102h-7.958Zm9.285-4.38c0-.056.046-.102.102-.102h7.958c.056 0 .102.046.102.102v3.056a.102.102 0 0 1-.102.102h-7.958a.102.102 0 0 1-.102-.102v-3.056Zm7.09.917c.029 0 .052.023.052.05v1.121c0 .028-.023.051-.051.051h-6.02a.051.051 0 0 1-.05-.05v-1.121c0-.028.022-.051.05-.051h6.02Zm-16.477-.917c0-.056.046-.102.102-.102h7.958c.057 0 .102.046.102.102v3.056a.102.102 0 0 1-.102.102h-7.958a.102.102 0 0 1-.102-.102v-.815c0-.056.046-.102.102-.102h6.99a.05.05 0 0 0 .05-.05v-1.121a.05.05 0 0 0-.05-.051h-6.99a.102.102 0 0 1-.102-.102v-.815Z" clip-rule="evenodd"/></g></g><defs><clipPath id="a"><path fill="#fff" d="M1 1h38v38H1z"/></clipPath><filter id="b" width="46.935" height="25.501" x="-3.638" y="6.044" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_6254_13457" stdDeviation="5"/></filter></defs></svg> diff --git a/assets/vault-banner/icon-re7-dark.svg b/assets/vault-banner/icon-re7-dark.svg new file mode 100644 index 000000000..0f81956d7 --- /dev/null +++ b/assets/vault-banner/icon-re7-dark.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="40" height="40" fill="none"><rect width="39" height="39" x=".5" y=".5" stroke="#fff" stroke-opacity=".1" rx="19.5"/><g clip-path="url(#a)"><path fill="url(#b)" d="M13.35 10.025h13.774v19.95H13.35z"/><g filter="url(#c)" opacity=".5"><path fill="url(#d)" d="M11.449 10.025h13.774v19.95H11.449z"/></g></g><defs><pattern id="b" width="1" height="1" patternContentUnits="objectBoundingBox"><use xlink:href="#e" transform="matrix(.01646 0 0 .01136 .023 0)"/></pattern><pattern id="d" width="1" height="1" patternContentUnits="objectBoundingBox"><use xlink:href="#e" transform="matrix(.01646 0 0 .01136 .02 0)"/></pattern><clipPath id="a"><path fill="#fff" d="M1 1h38v38H1z"/></clipPath><filter id="c" width="33.774" height="39.95" x="1.449" y=".025" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_6369_12528" stdDeviation="5"/></filter><image xlink:href="data:image/png;base64,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" id="e" width="440" height="88"/></defs></svg> diff --git a/assets/vault-banner/icon-re7-light.svg b/assets/vault-banner/icon-re7-light.svg new file mode 100644 index 000000000..05578ffad --- /dev/null +++ b/assets/vault-banner/icon-re7-light.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="40" height="40" fill="none"><rect width="39" height="39" x=".5" y=".5" stroke="#000" stroke-opacity=".1" rx="19.5"/><g clip-path="url(#a)"><path fill="url(#b)" d="M13.35 10.025h13.774v19.95H13.35z"/><g filter="url(#c)" opacity=".5"><path fill="url(#d)" d="M11.449 10.025h13.774v19.95H11.449z"/></g></g><defs><pattern id="b" width="1" height="1" patternContentUnits="objectBoundingBox"><use xlink:href="#e" transform="matrix(.01766 0 0 .0122 -.003 0)"/></pattern><pattern id="d" width="1" height="1" patternContentUnits="objectBoundingBox"><use xlink:href="#e" transform="matrix(.01766 0 0 .0122 -.003 0)"/></pattern><clipPath id="a"><path fill="#fff" d="M1 1h38v38H1z"/></clipPath><filter id="c" width="33.774" height="39.95" x="1.449" y=".025" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_6254_13498" stdDeviation="5"/></filter><image xlink:href="data:image/png;base64,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" id="e" width="57" height="82"/></defs></svg> diff --git a/assets/vault-banner/icon-stakehouse-dark.svg b/assets/vault-banner/icon-stakehouse-dark.svg new file mode 100644 index 000000000..e50c166d4 --- /dev/null +++ b/assets/vault-banner/icon-stakehouse-dark.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" fill="none"><rect width="39" height="39" x=".5" y=".5" stroke="#fff" stroke-opacity=".1" rx="19.5"/><g clip-path="url(#a)"><mask id="b" width="26" height="22" x="7" y="9" maskUnits="userSpaceOnUse" style="mask-type:luminance"><path fill="#fff" d="m32.339 9.988-4.678 4.678a4.51 4.51 0 0 1-3.19 1.32h-8.71a4.501 4.501 0 0 1-3.19-1.32l-4.678-4.68-.437-.436c.033.319.08.662.149 1.024a12.523 12.523 0 0 0 2.262 5.193 7.129 7.129 0 0 0 3.173 2.413 7.251 7.251 0 0 0 2.609.486h8.935a7.25 7.25 0 0 0 2.608-.486 7.13 7.13 0 0 0 3.173-2.413 12.722 12.722 0 0 0 1.62-2.934 12.523 12.523 0 0 0 .791-3.283c-.146.146-.292.291-.437.438ZM8.427 19.484l3.078 3.08h4.872l-2.435 2.435 1.894 1.895 4.33-4.33h8.464l3.079-3.08a2.68 2.68 0 0 0-3.789 0l-.399.4H12.615l-.4-.4a2.67 2.67 0 0 0-1.893-.784c-.686 0-1.372.262-1.895.784Zm12.414 4.297-4.1 4.017 1.766 1.767c.862.862 2.26.862 3.121 0l5.784-5.784h-6.57Z"/></mask><g mask="url(#b)"><path fill="url(#c)" d="M32.824 9.555H7.408v20.651h25.416V9.556Z"/></g><g filter="url(#d)" opacity=".8"><mask id="e" width="26" height="22" x="7" y="7" maskUnits="userSpaceOnUse" style="mask-type:luminance"><path fill="#fff" d="m32.339 8.088-4.678 4.678a4.51 4.51 0 0 1-3.19 1.32h-8.71a4.501 4.501 0 0 1-3.19-1.32L7.893 8.087l-.437-.437c.033.32.08.662.149 1.024a12.521 12.521 0 0 0 2.262 5.193 7.129 7.129 0 0 0 3.173 2.414 7.251 7.251 0 0 0 2.609.485h8.935a7.25 7.25 0 0 0 2.608-.485 7.13 7.13 0 0 0 3.173-2.414 12.726 12.726 0 0 0 1.62-2.934 12.522 12.522 0 0 0 .791-3.283l-.437.438ZM8.427 17.584l3.078 3.08h4.872l-2.435 2.435 1.894 1.895 4.33-4.33h8.464l3.079-3.08a2.68 2.68 0 0 0-3.789 0l-.399.4H12.615l-.4-.4a2.67 2.67 0 0 0-1.893-.784c-.686 0-1.372.262-1.895.784Zm12.414 4.297-4.1 4.017 1.766 1.767c.862.862 2.26.862 3.121 0l5.784-5.784h-6.57Z"/></mask><g mask="url(#e)"><path fill="url(#f)" d="M32.824 7.655H7.408v20.651h25.416V7.656Z"/></g></g></g><defs><linearGradient id="c" x1="7.408" x2="32.824" y1="19.568" y2="19.568" gradientUnits="userSpaceOnUse"><stop offset=".26" stop-color="#4919F9"/><stop offset=".714" stop-color="#ED8620"/></linearGradient><linearGradient id="f" x1="7.408" x2="32.824" y1="17.668" y2="17.668" gradientUnits="userSpaceOnUse"><stop offset=".26" stop-color="#4919F9"/><stop offset=".714" stop-color="#ED8620"/></linearGradient><clipPath id="a"><path fill="#fff" d="M1 1h38v38H1z"/></clipPath><filter id="d" width="53.32" height="48.651" x="-6.544" y="-6.345" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_6369_12527" stdDeviation="7"/></filter></defs></svg> diff --git a/assets/vault-banner/icon-stakehouse-light.svg b/assets/vault-banner/icon-stakehouse-light.svg new file mode 100644 index 000000000..624ccca75 --- /dev/null +++ b/assets/vault-banner/icon-stakehouse-light.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" fill="none"><rect width="39" height="39" x=".5" y=".5" stroke="#000" stroke-opacity=".1" rx="19.5"/><g clip-path="url(#a)"><mask id="b" width="26" height="22" x="7" y="9" maskUnits="userSpaceOnUse" style="mask-type:luminance"><path fill="#fff" d="m32.339 9.988-4.678 4.678a4.51 4.51 0 0 1-3.19 1.32h-8.71a4.498 4.498 0 0 1-3.19-1.32L7.893 9.987l-.437-.437c.033.32.08.662.149 1.024a12.524 12.524 0 0 0 2.262 5.193 7.129 7.129 0 0 0 3.173 2.414 7.249 7.249 0 0 0 2.609.485h8.935c.903 0 1.786-.168 2.608-.485a7.13 7.13 0 0 0 3.173-2.414 12.726 12.726 0 0 0 1.62-2.934 12.524 12.524 0 0 0 .791-3.283l-.437.438ZM8.427 19.485l3.078 3.078h4.872L13.942 25l1.894 1.895 4.33-4.33h8.464l3.079-3.08a2.68 2.68 0 0 0-3.789 0l-.399.4H12.615l-.4-.4a2.67 2.67 0 0 0-1.893-.784c-.686 0-1.372.262-1.895.785Zm12.414 4.296-4.1 4.018 1.766 1.766c.862.862 2.26.862 3.121 0l5.784-5.784h-6.57Z"/></mask><g mask="url(#b)"><path fill="url(#c)" d="M32.824 9.555H7.408v20.652h25.416V9.555Z"/></g><g filter="url(#d)" opacity=".8"><mask id="e" width="26" height="22" x="7" y="7" maskUnits="userSpaceOnUse" style="mask-type:luminance"><path fill="#fff" d="m32.339 8.088-4.678 4.678a4.51 4.51 0 0 1-3.19 1.32h-8.71a4.501 4.501 0 0 1-3.19-1.32L7.893 8.087l-.437-.437c.033.32.08.662.149 1.024a12.521 12.521 0 0 0 2.262 5.193 7.129 7.129 0 0 0 3.173 2.414 7.251 7.251 0 0 0 2.609.485h8.935a7.25 7.25 0 0 0 2.608-.485 7.13 7.13 0 0 0 3.173-2.414 12.726 12.726 0 0 0 1.62-2.934 12.522 12.522 0 0 0 .791-3.283l-.437.438ZM8.427 17.584l3.078 3.08h4.872l-2.435 2.435 1.894 1.895 4.33-4.33h8.464l3.079-3.08a2.68 2.68 0 0 0-3.789 0l-.399.4H12.615l-.4-.4a2.67 2.67 0 0 0-1.893-.784c-.686 0-1.372.262-1.895.784Zm12.414 4.297-4.1 4.017 1.766 1.767c.862.862 2.26.862 3.121 0l5.784-5.784h-6.57Z"/></mask><g mask="url(#e)"><path fill="url(#f)" d="M32.824 7.655H7.408v20.651h25.416V7.656Z"/></g></g></g><defs><linearGradient id="c" x1="7.408" x2="32.824" y1="19.568" y2="19.568" gradientUnits="userSpaceOnUse"><stop offset=".26" stop-color="#4919F9"/><stop offset=".714" stop-color="#ED8620"/></linearGradient><linearGradient id="f" x1="7.408" x2="32.824" y1="17.668" y2="17.668" gradientUnits="userSpaceOnUse"><stop offset=".26" stop-color="#4919F9"/><stop offset=".714" stop-color="#ED8620"/></linearGradient><clipPath id="a"><path fill="#fff" d="M1 1h38v38H1z"/></clipPath><filter id="d" width="53.32" height="48.651" x="-6.544" y="-6.345" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_6254_13429" stdDeviation="7"/></filter></defs></svg> diff --git a/assets/vault-banner/strategy-stakehouse.svg b/assets/vault-banner/strategy-stakehouse.svg new file mode 100644 index 000000000..d4d9bc615 --- /dev/null +++ b/assets/vault-banner/strategy-stakehouse.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 75 75" fill="none"><g clip-path="url(#a)"><mask id="b" width="51" height="42" x="12" y="16" maskUnits="userSpaceOnUse" style="mask-type:luminance"><path fill="#fff" d="m61.852 17.74-9.232 9.232a8.901 8.901 0 0 1-6.295 2.607H29.13a8.901 8.901 0 0 1-6.295-2.608c-3.079-3.078-6.155-6.154-9.232-9.233l-.863-.863c.065.63.159 1.307.293 2.021a24.72 24.72 0 0 0 2.068 6.294 25.124 25.124 0 0 0 2.398 3.956 14.07 14.07 0 0 0 6.262 4.763c1.622.626 3.366.958 5.148.958h17.635a14.31 14.31 0 0 0 5.149-.958 14.072 14.072 0 0 0 6.262-4.763 25.123 25.123 0 0 0 3.198-5.791 24.72 24.72 0 0 0 1.268-4.459 24.57 24.57 0 0 0 .293-2.021l-.863.864ZM14.658 36.482l6.075 6.076h9.616l-4.807 4.808 3.739 3.739 8.546-8.547h16.704l6.078-6.076a5.289 5.289 0 0 0-7.478 0l-.787.789h-29.42l-.789-.79a5.271 5.271 0 0 0-3.738-1.548 5.273 5.273 0 0 0-3.739 1.549Zm24.501 8.48-8.092 7.929 3.486 3.487a4.355 4.355 0 0 0 6.16 0l11.415-11.416H39.159Z"/></mask><g mask="url(#b)"><path fill="url(#c)" d="M62.809 16.886H12.647v40.758h50.162V16.886Z"/></g><g filter="url(#d)" opacity=".8"><mask id="e" width="51" height="41" x="12" y="13" maskUnits="userSpaceOnUse" style="mask-type:luminance"><path fill="#fff" d="m61.852 13.99-9.232 9.232a8.901 8.901 0 0 1-6.295 2.607H29.13a8.901 8.901 0 0 1-6.295-2.608c-3.079-3.078-6.155-6.154-9.232-9.233l-.863-.863c.065.63.159 1.307.293 2.021a24.72 24.72 0 0 0 2.068 6.294 25.124 25.124 0 0 0 2.398 3.956 14.07 14.07 0 0 0 6.262 4.763c1.622.626 3.366.958 5.148.958h17.635a14.31 14.31 0 0 0 5.149-.958 14.072 14.072 0 0 0 6.262-4.763 25.123 25.123 0 0 0 3.198-5.791 24.72 24.72 0 0 0 1.268-4.459 24.57 24.57 0 0 0 .293-2.021l-.863.864ZM14.658 32.732l6.075 6.076h9.616l-4.807 4.808 3.739 3.739 8.546-8.547h16.704l6.078-6.076a5.289 5.289 0 0 0-7.478 0l-.787.789h-29.42l-.789-.79a5.271 5.271 0 0 0-3.738-1.548 5.273 5.273 0 0 0-3.739 1.549Zm24.501 8.48-8.092 7.929 3.486 3.487a4.355 4.355 0 0 0 6.16 0l11.415-11.416H39.159Z"/></mask><g mask="url(#e)"><path fill="url(#f)" d="M62.809 13.136H12.647v40.758h50.162V13.136Z"/></g></g></g><defs><linearGradient id="c" x1="12.646" x2="62.809" y1="36.647" y2="36.647" gradientUnits="userSpaceOnUse"><stop offset=".26" stop-color="#4919F9"/><stop offset=".714" stop-color="#ED8620"/></linearGradient><linearGradient id="f" x1="12.646" x2="62.809" y1="32.897" y2="32.897" gradientUnits="userSpaceOnUse"><stop offset=".26" stop-color="#4919F9"/><stop offset=".714" stop-color="#ED8620"/></linearGradient><clipPath id="a"><path fill="#fff" d="M0 0h75v75H0z"/></clipPath><filter id="d" width="77.974" height="68.759" x="-1.259" y="-.865" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feGaussianBlur result="effect1_foregroundBlur_6243_11058" stdDeviation="7"/></filter></defs></svg> diff --git a/assets/vault-banner/symbol-plus.svg b/assets/vault-banner/symbol-plus.svg new file mode 100644 index 000000000..a2c6e888f --- /dev/null +++ b/assets/vault-banner/symbol-plus.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="15" height="14" fill="none"><path fill="#7A8AA0" fill-rule="evenodd" d="M7.87 3.5a.583.583 0 0 0-1.167 0v2.917H3.786a.583.583 0 1 0 0 1.166h2.917V10.5a.583.583 0 0 0 1.167 0V7.583h2.917a.583.583 0 0 0 0-1.166H7.87V3.5Z" clip-rule="evenodd"/></svg> diff --git a/config/feature-flags/hooks.ts b/config/feature-flags/hooks.ts index 3fcaa9553..4672e612e 100644 --- a/config/feature-flags/hooks.ts +++ b/config/feature-flags/hooks.ts @@ -2,30 +2,18 @@ import { useContext, useMemo } from 'react'; import invariant from 'tiny-invariant'; import { ConfigContext } from '../provider'; -import { FeatureFlagsContextType } from './context-hook'; -import { FeatureFlagsType } from './types'; +import type { FeatureFlagsContextType } from './context-hook'; +import type { FeatureFlagsType } from './types'; -type UseFeatureFlagReturnType = { - [key in keyof FeatureFlagsType]: boolean; -} & { - setFeatureFlag: (featureFlag: keyof FeatureFlagsType, value: boolean) => void; -}; - -export const useFeatureFlag = ( - flag: keyof FeatureFlagsType, -): UseFeatureFlagReturnType | null => { +export const useFeatureFlag = <K extends keyof FeatureFlagsType>(flag: K) => { const context = useContext(ConfigContext); invariant(context, 'Attempt to use `feature flag` outside of provider'); return useMemo(() => { return { [flag]: context.featureFlags[flag], setFeatureFlag: context.featureFlags?.setFeatureFlag, - }; + } as { + setFeatureFlag: FeatureFlagsContextType['setFeatureFlag']; + } & Record<K, FeatureFlagsType[K]>; }, [context.featureFlags, flag]); }; - -export const useFeatureFlags = (): FeatureFlagsContextType | null => { - const context = useContext(ConfigContext); - invariant(context, 'Attempt to use `feature flag` outside of provider'); - return useMemo(() => context.featureFlags, [context.featureFlags]); -}; diff --git a/config/feature-flags/types.ts b/config/feature-flags/types.ts index ec8a110b3..23f53be3a 100644 --- a/config/feature-flags/types.ts +++ b/config/feature-flags/types.ts @@ -1,6 +1,8 @@ export const RPC_SETTINGS_PAGE_ON_INFRA_IS_ENABLED = 'rpcSettingsPageOnInfraIsEnabled'; +export const VAULTS_BANNER_IS_ENABLED = 'vaultsBannerIsEnabled'; export type FeatureFlagsType = { [RPC_SETTINGS_PAGE_ON_INFRA_IS_ENABLED]: boolean; + [VAULTS_BANNER_IS_ENABLED]: boolean; }; diff --git a/config/feature-flags/utils.ts b/config/feature-flags/utils.ts index d4d721b5f..7c2262241 100644 --- a/config/feature-flags/utils.ts +++ b/config/feature-flags/utils.ts @@ -3,5 +3,6 @@ import { FeatureFlagsType } from './types'; export const getFeatureFlagsDefault = (): FeatureFlagsType => { return { rpcSettingsPageOnInfraIsEnabled: false, + vaultsBannerIsEnabled: false, }; }; diff --git a/consts/matomo-click-events.ts b/consts/matomo-click-events.ts index 60553768c..3d2ff1044 100644 --- a/consts/matomo-click-events.ts +++ b/consts/matomo-click-events.ts @@ -14,6 +14,8 @@ export const enum MATOMO_CLICK_EVENTS_TYPES { l2LowFeeStake = 'l2LowFeeStake', l2LowFeeWrap = 'l2LowFeeWrap', l2swap = 'l2swap', + vaultsBannerLearnMore = 'vaultsBannerLearnMore', + vaultsBannerExploreAll = 'vaultsBannerExploreAll', // FAQ faqSafeWorkWithLidoAudits = 'faqSafeWorkWithLidoAudits', faqLidoEthAprEthLandingPage = 'faqLidoEthAprEthLandingPage', @@ -126,6 +128,16 @@ export const MATOMO_CLICK_EVENTS: Record< 'Push «Swap» in Swap ETH to wstETH on L2 banner on staking widget', 'eth_widget_banner_swap_ETH_on_L2', ], + [MATOMO_CLICK_EVENTS_TYPES.vaultsBannerLearnMore]: [ + 'Ethereum_Staking_Widget', + 'Click on "Learn more" on Vaults banner', + 'eth_widget_learn_more_vaults_banner', + ], + [MATOMO_CLICK_EVENTS_TYPES.vaultsBannerExploreAll]: [ + 'Ethereum_Staking_Widget', + 'Push "Explore all strategies"', + 'eth_widget_explore_all_strategies', + ], // FAQ [MATOMO_CLICK_EVENTS_TYPES.faqSafeWorkWithLidoAudits]: [ 'Ethereum_Staking_Widget', diff --git a/features/stake/stake-form/stake-form.tsx b/features/stake/stake-form/stake-form.tsx index be945df58..695b6570e 100644 --- a/features/stake/stake-form/stake-form.tsx +++ b/features/stake/stake-form/stake-form.tsx @@ -1,4 +1,5 @@ import { FC, memo } from 'react'; +import { useFeatureFlag, VAULTS_BANNER_IS_ENABLED } from 'config/feature-flags'; import { StakeFormProvider } from './stake-form-context'; @@ -9,8 +10,10 @@ import { StakeFormInfo } from './stake-form-info'; import { SwapDiscountBanner } from '../swap-discount-banner'; import { StakeBlock, FormControllerStyled } from './styles'; import { L2FromStakeToWrap } from 'shared/banners/l2-banners/l2-from-stake-to-wrap'; +import { VaultsBannerInfo } from 'shared/banners/vaults-banner-info'; export const StakeForm: FC = memo(() => { + const { vaultsBannerIsEnabled } = useFeatureFlag(VAULTS_BANNER_IS_ENABLED); return ( <StakeFormProvider> <Wallet /> @@ -19,7 +22,11 @@ export const StakeForm: FC = memo(() => { <StakeAmountInput /> <StakeSubmitButton /> <SwapDiscountBanner> - <L2FromStakeToWrap /> + {vaultsBannerIsEnabled ? ( + <VaultsBannerInfo /> + ) : ( + <L2FromStakeToWrap /> + )} </SwapDiscountBanner> </FormControllerStyled> <StakeFormInfo /> diff --git a/features/wsteth/unwrap/unwrap-form/unwrap-form.tsx b/features/wsteth/unwrap/unwrap-form/unwrap-form.tsx index c4b0bc246..27befa33e 100644 --- a/features/wsteth/unwrap/unwrap-form/unwrap-form.tsx +++ b/features/wsteth/unwrap/unwrap-form/unwrap-form.tsx @@ -1,8 +1,10 @@ import { memo, FC } from 'react'; +import { useFeatureFlag, VAULTS_BANNER_IS_ENABLED } from 'config/feature-flags'; import { MATOMO_CLICK_EVENTS } from 'consts/matomo-click-events'; import { InputWrap, WrapBlock } from 'features/wsteth/shared/styles'; import { L2Wsteth } from 'shared/banners/l2-banners/l2-wsteth'; +import { VaultsBannerInfo } from 'shared/banners/vaults-banner-info'; import { FormController } from 'shared/hook-form/form-controller/form-controller'; import { UnwrapStats } from './unwrap-stats'; @@ -11,6 +13,7 @@ import { TokenAmountInputUnwrap } from '../unwrap-form-controls/amount-input-unw import { SubmitButtonUnwrap } from '../unwrap-form-controls/submit-button-unwrap'; export const UnwrapForm: FC = memo(() => { + const { vaultsBannerIsEnabled } = useFeatureFlag(VAULTS_BANNER_IS_ENABLED); return ( <UnwrapFormProvider> <WrapBlock data-testid="unwrapForm"> @@ -20,7 +23,11 @@ export const UnwrapForm: FC = memo(() => { </InputWrap> <SubmitButtonUnwrap /> </FormController> - <L2Wsteth matomoEventLink={MATOMO_CLICK_EVENTS.l2BannerUnwrap} /> + {vaultsBannerIsEnabled ? ( + <VaultsBannerInfo /> + ) : ( + <L2Wsteth matomoEventLink={MATOMO_CLICK_EVENTS.l2BannerUnwrap} /> + )} <UnwrapStats /> </WrapBlock> </UnwrapFormProvider> diff --git a/features/wsteth/wrap/wrap-form/wrap-form.tsx b/features/wsteth/wrap/wrap-form/wrap-form.tsx index c31999dc5..5ecafbdfc 100644 --- a/features/wsteth/wrap/wrap-form/wrap-form.tsx +++ b/features/wsteth/wrap/wrap-form/wrap-form.tsx @@ -1,6 +1,8 @@ import { memo } from 'react'; +import { useFeatureFlag, VAULTS_BANNER_IS_ENABLED } from 'config/feature-flags'; import { L2Wsteth } from 'shared/banners/l2-banners/l2-wsteth'; +import { VaultsBannerInfo } from 'shared/banners/vaults-banner-info'; import { FormController } from 'shared/hook-form/form-controller'; import { MATOMO_CLICK_EVENTS } from 'consts/matomo-click-events'; @@ -11,6 +13,7 @@ import { InputGroupWrap } from '../wrap-form-controls/input-group-wrap'; import { SubmitButtonWrap } from '../wrap-form-controls/submit-button-wrap'; export const WrapForm: React.FC = memo(() => { + const { vaultsBannerIsEnabled } = useFeatureFlag(VAULTS_BANNER_IS_ENABLED); return ( <WrapFormProvider> <WrapBlock data-testid="wrapForm"> @@ -18,7 +21,11 @@ export const WrapForm: React.FC = memo(() => { <InputGroupWrap /> <SubmitButtonWrap /> </FormController> - <L2Wsteth matomoEventLink={MATOMO_CLICK_EVENTS.l2BannerWrap} /> + {vaultsBannerIsEnabled ? ( + <VaultsBannerInfo /> + ) : ( + <L2Wsteth matomoEventLink={MATOMO_CLICK_EVENTS.l2BannerWrap} /> + )} <WrapFormStats /> </WrapBlock> </WrapFormProvider> diff --git a/shared/banners/banner-link-button/banner-link-button.tsx b/shared/banners/banner-link-button/banner-link-button.tsx new file mode 100644 index 000000000..dc121aac3 --- /dev/null +++ b/shared/banners/banner-link-button/banner-link-button.tsx @@ -0,0 +1,35 @@ +import { ButtonLinkWrap, ButtonLinkWrapLocal, ButtonStyle } from './styles'; + +type BannerLinkButtonProps = { + href: string; + testId?: string; + onClick?: () => void; + isLocalLink?: boolean; + children: React.ReactNode; +}; + +export const BannerLinkButton = ({ + href, + testId, + onClick, + isLocalLink, + children, +}: BannerLinkButtonProps) => { + const buttonEl = ( + <ButtonStyle data-testid={testId} size="sm" color="primary"> + {children} + </ButtonStyle> + ); + + const linkProps = { + href, + onClick, + children: buttonEl, + }; + + if (isLocalLink) { + return <ButtonLinkWrapLocal {...linkProps} />; + } + + return <ButtonLinkWrap {...linkProps} />; +}; diff --git a/shared/banners/banner-link-button/index.ts b/shared/banners/banner-link-button/index.ts new file mode 100644 index 000000000..8ef569614 --- /dev/null +++ b/shared/banners/banner-link-button/index.ts @@ -0,0 +1 @@ +export * from './banner-link-button'; diff --git a/shared/banners/banner-link-button/styles.ts b/shared/banners/banner-link-button/styles.ts new file mode 100644 index 000000000..91e237b79 --- /dev/null +++ b/shared/banners/banner-link-button/styles.ts @@ -0,0 +1,33 @@ +import styled, { css } from 'styled-components'; +import { Button, Link } from '@lidofinance/lido-ui'; +import { LocalLink } from 'shared/components/local-link'; + +const buttonLinkWrapCss = css` + display: block; + + ${({ theme }) => theme.mediaQueries.md} { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + } +`; + +export const ButtonLinkWrap = styled(Link)` + ${buttonLinkWrapCss}; +`; + +export const ButtonLinkWrapLocal = styled(LocalLink)` + ${buttonLinkWrapCss}; +`; + +export const ButtonStyle = styled(Button)` + padding: 7px 16px; + font-size: 12px; + line-height: 20px; + + ${({ theme }) => theme.mediaQueries.md} { + display: none; + } +`; diff --git a/shared/banners/l2-banner/l2-banner.tsx b/shared/banners/l2-banner/l2-banner.tsx index 623aaf5ab..7c6fccc71 100644 --- a/shared/banners/l2-banner/l2-banner.tsx +++ b/shared/banners/l2-banner/l2-banner.tsx @@ -1,13 +1,5 @@ -import { - Wrapper, - L2Icons, - TextWrap, - ButtonLinkWrap, - ButtonLinkWrapLocal, - ButtonStyle, - TextHeader, - FooterWrap, -} from './styles'; +import { BannerLinkButton } from '../banner-link-button'; +import { Wrapper, L2Icons, TextWrap, TextHeader, FooterWrap } from './styles'; type L2BannerProps = { title?: React.ReactNode; @@ -32,31 +24,20 @@ export const L2Banner = ({ testidButton, onClickButton, }: L2BannerProps) => { - const buttonEl = ( - <ButtonStyle data-testid={testidButton} size="sm" color="primary"> - {buttonText} - </ButtonStyle> - ); - - const linkProps = { - href: buttonHref, - onClick: onClickButton, - children: buttonEl, - }; - - const linkEl = isLocalLink ? ( - <ButtonLinkWrapLocal {...linkProps} /> - ) : ( - <ButtonLinkWrap {...linkProps} /> - ); - return ( <Wrapper data-testid={testId}> {title && <TextHeader>{title}</TextHeader>} <TextWrap>{text}</TextWrap> <FooterWrap> <L2Icons /> - {linkEl} + <BannerLinkButton + href={buttonHref} + testId={testidButton} + onClick={onClickButton} + isLocalLink={isLocalLink} + > + {buttonText} + </BannerLinkButton> </FooterWrap> </Wrapper> ); diff --git a/shared/banners/l2-banner/styles.ts b/shared/banners/l2-banner/styles.ts index 498a5301f..1b0ed9218 100644 --- a/shared/banners/l2-banner/styles.ts +++ b/shared/banners/l2-banner/styles.ts @@ -1,8 +1,6 @@ import styled, { css } from 'styled-components'; -import { Button, Link } from '@lidofinance/lido-ui'; import IconsLight from 'assets/icons/l2-swap-light.svg'; import IconsDark from 'assets/icons/l2-swap-dark.svg'; -import { LocalLink } from 'shared/components/local-link'; export const Wrapper = styled.div` position: relative; @@ -76,33 +74,3 @@ export const TextWrap = styled.div` font-weight: 400; position: relative; `; - -const buttonLinkWrapCss = css` - display: block; - - ${({ theme }) => theme.mediaQueries.md} { - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - } -`; - -export const ButtonLinkWrap = styled(Link)` - ${buttonLinkWrapCss}; -`; - -export const ButtonLinkWrapLocal = styled(LocalLink)` - ${buttonLinkWrapCss}; -`; - -export const ButtonStyle = styled(Button)` - padding: 7px 16px; - font-size: 12px; - line-height: 20px; - - ${({ theme }) => theme.mediaQueries.md} { - display: none; - } -`; diff --git a/shared/banners/vaults-banner-info/index.ts b/shared/banners/vaults-banner-info/index.ts new file mode 100644 index 000000000..6618838bc --- /dev/null +++ b/shared/banners/vaults-banner-info/index.ts @@ -0,0 +1 @@ +export * from './vaults-banner-info'; diff --git a/shared/banners/vaults-banner-info/styles.ts b/shared/banners/vaults-banner-info/styles.ts new file mode 100644 index 000000000..7d08bad36 --- /dev/null +++ b/shared/banners/vaults-banner-info/styles.ts @@ -0,0 +1,38 @@ +import styled from 'styled-components'; + +export const Wrap = styled.div` + padding: 16px; + border-radius: 16px; + background-color: ${({ theme }) => + theme.name === 'dark' ? '#28282f' : '#f2f3fc'}; +`; + +export const Title = styled.div` + margin-bottom: 8px; + font-size: 20px; + line-height: 20px; + font-weight: 700; + color: var(--lido-color-text); +`; + +export const Description = styled.div` + margin-bottom: 15px; + font-size: 12px; + font-weight: 400; + line-height: 20px; + color: var(--lido-color-textSecondary); +`; + +export const Footer = styled.div` + display: flex; + justify-content: space-between; +`; + +export const Logos = styled.div` + display: flex; + gap: 8px; + + svg { + display: block; + } +`; diff --git a/shared/banners/vaults-banner-info/vaults-banner-info.tsx b/shared/banners/vaults-banner-info/vaults-banner-info.tsx new file mode 100644 index 000000000..4fca9b0e0 --- /dev/null +++ b/shared/banners/vaults-banner-info/vaults-banner-info.tsx @@ -0,0 +1,50 @@ +import { useThemeToggle } from '@lidofinance/lido-ui'; + +import { BannerLinkButton } from '../banner-link-button'; +import { Wrap, Title, Description, Footer, Logos } from './styles'; + +import { ReactComponent as IconGauntletDark } from 'assets/vault-banner/icon-gauntlet-dark.svg'; +import { ReactComponent as IconP2PDark } from 'assets/vault-banner/icon-p2p-dark.svg'; +import { ReactComponent as IconRe7Dark } from 'assets/vault-banner/icon-re7-dark.svg'; +import { ReactComponent as IconStakehouseDark } from 'assets/vault-banner/icon-stakehouse-dark.svg'; + +import { ReactComponent as IconGauntletLight } from 'assets/vault-banner/icon-gauntlet-light.svg'; +import { ReactComponent as IconP2PLight } from 'assets/vault-banner/icon-p2p-light.svg'; +import { ReactComponent as IconRe7Light } from 'assets/vault-banner/icon-re7-light.svg'; +import { ReactComponent as IconStakehouseLight } from 'assets/vault-banner/icon-stakehouse-light.svg'; + +import { trackEvent } from '@lidofinance/analytics-matomo'; +import { MATOMO_CLICK_EVENTS } from 'consts/matomo-click-events'; + +const LINK_LEARN_MORE = 'https://lido.fi/#defi-strategies'; + +const linkClickHandler = () => + trackEvent(...MATOMO_CLICK_EVENTS.vaultsBannerLearnMore); + +export const VaultsBannerInfo = () => { + const { themeName } = useThemeToggle(); + return ( + <Wrap> + <Title>Get more with restaking vaults + + Use stETH to unlock restaking rewards through the best-in-class + opinionated curated vaults + +
+ + {themeName === 'dark' ? : } + {themeName === 'dark' ? ( + + ) : ( + + )} + {themeName === 'dark' ? : } + {themeName === 'dark' ? : } + + + Learn more + +
+ + ); +}; diff --git a/shared/banners/vaults-banner-strategies/index.ts b/shared/banners/vaults-banner-strategies/index.ts new file mode 100644 index 000000000..b87bcf90e --- /dev/null +++ b/shared/banners/vaults-banner-strategies/index.ts @@ -0,0 +1 @@ +export * from './vaults-banner-strategies'; diff --git a/shared/banners/vaults-banner-strategies/styles.ts b/shared/banners/vaults-banner-strategies/styles.ts new file mode 100644 index 000000000..62322e142 --- /dev/null +++ b/shared/banners/vaults-banner-strategies/styles.ts @@ -0,0 +1,88 @@ +import styled from 'styled-components'; + +export const Wrap = styled.div` + margin-bottom: 20px; + padding: 16px; + border-radius: 16px; + background-color: ${({ theme }) => + theme.name === 'dark' ? '#28282f' : '#f2f3fc'}; +`; + +export const Header = styled.div` + display: flex; + align-items: center; + margin-bottom: 15px; +`; + +export const Icon = styled.div` + margin-right: 15px; + + &, + svg { + display: block; + weight: 75px; + height: 75px; + } + + ${({ theme }) => theme.mediaQueries.md} { + &, + svg { + weight: 48px; + height: 48px; + } + } +`; + +export const Title = styled.div` + text-align: left; +`; + +export const TitleText = styled.div` + font-size: 20px; + line-height: 28px; + font-weight: 700; + color: var(--lido-color-text); + + ${({ theme }) => theme.mediaQueries.md} { + font-size: 16px; + line-height: 24px; + } +`; + +export const TitleDescription = styled.div` + font-size: 12px; + line-height: 20px; + font-weight: 400; + color: var(--lido-color-textSecondary); +`; + +export const Strategies = styled.div` + display: flex; + align-items: center; + justify-content: space-between; + flex-wrap: wrap; + gap: 10px; + + ${({ theme }) => theme.mediaQueries.md} { + justify-content: center; + } +`; + +export const StrategyItem = styled.div` + flex: 0 0 auto; + text-align: left; + font-size: 12px; + line-height: 16px; + font-weight: 400; + color: var(--lido-color-text); + + b { + font-weight: 700; + } +`; + +export const StrategyDivider = styled.div` + svg { + display: block; + } +`; diff --git a/shared/banners/vaults-banner-strategies/vaults-banner-strategies.tsx b/shared/banners/vaults-banner-strategies/vaults-banner-strategies.tsx new file mode 100644 index 000000000..7eb27eb6e --- /dev/null +++ b/shared/banners/vaults-banner-strategies/vaults-banner-strategies.tsx @@ -0,0 +1,81 @@ +import { Button, Link } from '@lidofinance/lido-ui'; +import { + Wrap, + Header, + Icon, + Title, + TitleText, + TitleDescription, + Strategies, + StrategyItem, + StrategyDivider, +} from './styles'; +import { ReactComponent as IconStakehouse } from 'assets/vault-banner/strategy-stakehouse.svg'; +import { ReactComponent as SymbolPlus } from 'assets/vault-banner/symbol-plus.svg'; + +import { trackEvent } from '@lidofinance/analytics-matomo'; +import { MATOMO_CLICK_EVENTS } from 'consts/matomo-click-events'; + +const LINK_LEARN_MORE = 'https://lido.fi/#defi-strategies'; + +const linkClickHandler = () => + trackEvent(...MATOMO_CLICK_EVENTS.vaultsBannerExploreAll); + +export const VaultsBannerStrategies = () => { + const divider = ( + + + + ); + return ( + <> + +
+ + + + + <TitleText>Restaking Vault</TitleText> + <TitleDescription>Curated by Steakhouse Financial</TitleDescription> + +
+ + + stETH +
+ APR +
+ + {divider} + + + Symbiotic +
+ Points +
+ + {divider} + + + Mellow +
+ Points +
+ + {divider} + + + Restaking +
+ APR TBD +
+
+
+ + + + + ); +}; diff --git a/shared/transaction-modal/tx-stages-composed/tx-stage-operation-succeed-balance-shown.tsx b/shared/transaction-modal/tx-stages-composed/tx-stage-operation-succeed-balance-shown.tsx index 8b2bd7fdc..6589234b7 100644 --- a/shared/transaction-modal/tx-stages-composed/tx-stage-operation-succeed-balance-shown.tsx +++ b/shared/transaction-modal/tx-stages-composed/tx-stage-operation-succeed-balance-shown.tsx @@ -3,11 +3,13 @@ import styled from 'styled-components'; import { InlineLoader } from '@lidofinance/lido-ui'; import { L2AfterStake } from 'shared/banners/l2-banners/l2-after-stake'; import { L2AfterWrap } from 'shared/banners/l2-banners/l2-after-wrap'; +import { VaultsBannerStrategies } from 'shared/banners/vaults-banner-strategies'; import { TxAmount } from '../tx-stages-parts/tx-amount'; import { SuccessText } from '../tx-stages-parts/success-text'; import { TxStageSuccess } from '../tx-stages-basic'; import type { BigNumber } from 'ethers'; +import { useFeatureFlag, VAULTS_BANNER_IS_ENABLED } from 'config/feature-flags'; export const SkeletonBalance = styled(InlineLoader).attrs({ color: 'text', @@ -29,10 +31,19 @@ export const TxStageOperationSucceedBalanceShown = ({ operationText, txHash, }: TxStageOperationSucceedBalanceShownProps) => { + const { vaultsBannerIsEnabled } = useFeatureFlag(VAULTS_BANNER_IS_ENABLED); + const balanceEl = balance && ( ); + const renderBanner = () => { + if (vaultsBannerIsEnabled) return ; + if (balanceToken === 'stETH') return ; + if (balanceToken === 'wstETH') return ; + return undefined; + }; + return ( } showEtherscan={false} - footer={ - balanceToken === 'stETH' ? ( - - ) : balanceToken === 'wstETH' ? ( - - ) : undefined - } + footer={renderBanner()} /> ); }; From 00e550d3da68e0f5e11c1bf46e732a48eb4959d9 Mon Sep 17 00:00:00 2001 From: Anton Shalimov Date: Tue, 4 Jun 2024 15:06:56 +0300 Subject: [PATCH 20/30] fix: index page --- pages/index.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/pages/index.tsx b/pages/index.tsx index 4b7f70ca9..4a2b17c67 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -2,11 +2,6 @@ import { GetStaticProps } from 'next'; import { config } from 'config'; import { StakePage } from 'features/stake'; import { HomePageIpfs } from 'features/ipfs'; -import { GetStaticProps } from 'next'; - -export const getStaticProps: GetStaticProps = async () => { - return { props: {} }; -}; export default config.ipfsMode ? HomePageIpfs : StakePage; From 2df365225329c8a0d09e3451d514b641cfa53234 Mon Sep 17 00:00:00 2001 From: Evgeny Taktarov Date: Tue, 4 Jun 2024 23:05:56 +0700 Subject: [PATCH 21/30] fix: remove unused state --- features/withdrawals/request/form/options/dex-options.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/features/withdrawals/request/form/options/dex-options.tsx b/features/withdrawals/request/form/options/dex-options.tsx index 9a5ac877c..fc0fc3889 100644 --- a/features/withdrawals/request/form/options/dex-options.tsx +++ b/features/withdrawals/request/form/options/dex-options.tsx @@ -66,7 +66,7 @@ const DexOption: React.FC = ({ export const DexOptions: React.FC< React.ComponentProps > = (props) => { - const { data, initialLoading, loading, amount, selectedToken, enabledDexes } = + const { data, initialLoading, amount, selectedToken, enabledDexes } = useWithdrawalRates(); const isAnyDexEnabled = enabledDexes.length > 0; @@ -92,7 +92,6 @@ export const DexOptions: React.FC< onClickGoTo={() => trackMatomoEvent(matomoEvent)} url={link(amount, selectedToken)} key={title} - loading={loading} toReceive={rate ? toReceive : null} /> ); From 323533b6a31dae634cb531c234ab7f5ad0744c9b Mon Sep 17 00:00:00 2001 From: Dmitrii Podlesnyi Date: Wed, 5 Jun 2024 16:10:23 +0700 Subject: [PATCH 22/30] chore: vaults banner text updated --- assets/vault-banner/icon-gauntlet-dark.svg | 1 - assets/vault-banner/icon-gauntlet-light.svg | 1 - assets/vault-banner/icon-mev-dark.svg | 1 + assets/vault-banner/icon-mev-light.svg | 1 + .../vaults-banner-info/vaults-banner-info.tsx | 12 ++++++------ 5 files changed, 8 insertions(+), 8 deletions(-) delete mode 100644 assets/vault-banner/icon-gauntlet-dark.svg delete mode 100644 assets/vault-banner/icon-gauntlet-light.svg create mode 100644 assets/vault-banner/icon-mev-dark.svg create mode 100644 assets/vault-banner/icon-mev-light.svg diff --git a/assets/vault-banner/icon-gauntlet-dark.svg b/assets/vault-banner/icon-gauntlet-dark.svg deleted file mode 100644 index 07fb19f71..000000000 --- a/assets/vault-banner/icon-gauntlet-dark.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/assets/vault-banner/icon-gauntlet-light.svg b/assets/vault-banner/icon-gauntlet-light.svg deleted file mode 100644 index 35c2bbac2..000000000 --- a/assets/vault-banner/icon-gauntlet-light.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/assets/vault-banner/icon-mev-dark.svg b/assets/vault-banner/icon-mev-dark.svg new file mode 100644 index 000000000..a709432a9 --- /dev/null +++ b/assets/vault-banner/icon-mev-dark.svg @@ -0,0 +1 @@ + diff --git a/assets/vault-banner/icon-mev-light.svg b/assets/vault-banner/icon-mev-light.svg new file mode 100644 index 000000000..f7d22ef9f --- /dev/null +++ b/assets/vault-banner/icon-mev-light.svg @@ -0,0 +1 @@ + diff --git a/shared/banners/vaults-banner-info/vaults-banner-info.tsx b/shared/banners/vaults-banner-info/vaults-banner-info.tsx index 4fca9b0e0..ad2f06063 100644 --- a/shared/banners/vaults-banner-info/vaults-banner-info.tsx +++ b/shared/banners/vaults-banner-info/vaults-banner-info.tsx @@ -3,12 +3,12 @@ import { useThemeToggle } from '@lidofinance/lido-ui'; import { BannerLinkButton } from '../banner-link-button'; import { Wrap, Title, Description, Footer, Logos } from './styles'; -import { ReactComponent as IconGauntletDark } from 'assets/vault-banner/icon-gauntlet-dark.svg'; +import { ReactComponent as IconMevDark } from 'assets/vault-banner/icon-mev-dark.svg'; import { ReactComponent as IconP2PDark } from 'assets/vault-banner/icon-p2p-dark.svg'; import { ReactComponent as IconRe7Dark } from 'assets/vault-banner/icon-re7-dark.svg'; import { ReactComponent as IconStakehouseDark } from 'assets/vault-banner/icon-stakehouse-dark.svg'; -import { ReactComponent as IconGauntletLight } from 'assets/vault-banner/icon-gauntlet-light.svg'; +import { ReactComponent as IconMevLight } from 'assets/vault-banner/icon-mev-light.svg'; import { ReactComponent as IconP2PLight } from 'assets/vault-banner/icon-p2p-light.svg'; import { ReactComponent as IconRe7Light } from 'assets/vault-banner/icon-re7-light.svg'; import { ReactComponent as IconStakehouseLight } from 'assets/vault-banner/icon-stakehouse-light.svg'; @@ -25,10 +25,10 @@ export const VaultsBannerInfo = () => { const { themeName } = useThemeToggle(); return ( - Get more with restaking vaults + Explore restaking opportunities - Use stETH to unlock restaking rewards through the best-in-class - opinionated curated vaults + Use stETH to unlock restaking rewards through a set of carefully curated + vaults