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/.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 deleted file mode 100644 index f1cc3c70e..000000000 --- a/.github/workflows/ci-ens.yml +++ /dev/null @@ -1,25 +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: - - goerli - - 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 }} diff --git a/.github/workflows/ci-ipfs-goerli.yml b/.github/workflows/ci-ipfs-goerli.yml index 47e8607c9..30a5336fc 100644 --- a/.github/workflows/ci-ipfs-goerli.yml +++ b/.github/workflows/ci-ipfs-goerli.yml @@ -36,8 +36,12 @@ jobs: yarn install --frozen-lockfile - name: Build run: | - yarn build-ipfs + 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..50385f93d 100644 --- a/.github/workflows/ci-ipfs-test-production.yml +++ b/.github/workflows/ci-ipfs-test-production.yml @@ -36,8 +36,12 @@ jobs: yarn install --frozen-lockfile - name: Build run: | - yarn build-ipfs + 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..137864c8c 100644 --- a/.github/workflows/ci-ipfs-testnet.yml +++ b/.github/workflows/ci-ipfs-testnet.yml @@ -31,8 +31,12 @@ jobs: yarn install --frozen-lockfile - name: Build run: | - yarn build-ipfs + 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..15c495c6a 100644 --- a/.github/workflows/ci-ipfs.yml +++ b/.github/workflows/ci-ipfs.yml @@ -40,8 +40,12 @@ jobs: yarn install --frozen-lockfile - name: Build run: | - yarn build-ipfs + 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/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/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/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 @@ + 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 @@ + 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 @@ + 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 @@ + 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 @@ + 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 @@ + 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 @@ + diff --git a/assets/vault-banner/symbol-plus.svg b/assets/vault-banner/symbol-plus.svg new file mode 100644 index 000000000..b323fa545 --- /dev/null +++ b/assets/vault-banner/symbol-plus.svg @@ -0,0 +1 @@ + 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 = (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; }, [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/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/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/env-dynamics.mjs b/env-dynamics.mjs index 35729dbe3..134d4e4dd 100644 --- a/env-dynamics.mjs +++ b/env-dynamics.mjs @@ -18,6 +18,26 @@ const toBoolean = (val) => { /** @type boolean */ export const ipfsMode = toBoolean(process.env.IPFS_MODE); +/** @type string */ +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 || 'https://lido.fi'; +// Fix in the build time (build time don't have env vars) + +/** @type string */ +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 || '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 || '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 */ export const defaultChain = parseInt(process.env.DEFAULT_CHAIN, 10) || 17000; 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 {spaPage}; }; 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/referral/banner/banner.tsx b/features/referral/banner/banner.tsx index d8f668f4f..165a45aa9 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


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 9e4d84265..b319c8b14 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 = () => { @@ -30,7 +31,7 @@ export const HowCanIGetSteth: FC = () => { </OuterLink> , or 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 573cbbcb1..e5adb1923 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 = () => { @@ -18,14 +20,14 @@ 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 </Link>{' '} and in our{' '} <Link - href={'https://docs.lido.fi/#liquid-staking'} + href={`${config.docsOrigin}/#liquid-staking`} data-matomo={MATOMO_CLICK_EVENTS_TYPES.faqLidoEthAprDocs} > Docs 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/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.{' '} <a - href="https://docs.lido.fi/guides/steth-integration-guide#staking-rate-limits" + href={`${config.docsOrigin}/guides/steth-integration-guide#staking-rate-limits`} target="_blank" rel="noreferrer" > diff --git a/features/withdrawals/claim/claim.tsx b/features/withdrawals/claim/claim.tsx index 31d2c9c3f..320da6734 100644 --- a/features/withdrawals/claim/claim.tsx +++ b/features/withdrawals/claim/claim.tsx @@ -1,16 +1,21 @@ import { FaqPlaceholder } from 'features/ipfs'; +import { OnlyInfraRender } from 'shared/components/only-infra-render'; +import NoSSRWrapper from 'shared/components/no-ssr-wrapper'; + import { ClaimFaq } from '../withdrawals-faq/claim-faq'; import { ClaimForm } from './form'; import { ClaimWallet } from './wallet'; import { ClaimFormProvider } from './claim-form-context'; -import { OnlyInfraRender } from 'shared/components/only-infra-render'; export const Claim = () => { return ( <ClaimFormProvider> - <ClaimWallet /> - <ClaimForm /> + <NoSSRWrapper> + <ClaimWallet /> + <ClaimForm /> + </NoSSRWrapper> + <OnlyInfraRender renderIPFS={<FaqPlaceholder />}> <ClaimFaq /> </OnlyInfraRender> diff --git a/features/withdrawals/request/form/options/dex-options.tsx b/features/withdrawals/request/form/options/dex-options.tsx index 34e3ee727..fc0fc3889 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> ); }; @@ -64,7 +66,7 @@ const DexOption: React.FC<DexOptionProps> = ({ export const DexOptions: React.FC< React.ComponentProps<typeof DexOptionsContainer> > = (props) => { - const { data, initialLoading, loading, amount, selectedToken, enabledDexes } = + const { data, initialLoading, amount, selectedToken, enabledDexes } = useWithdrawalRates(); const isAnyDexEnabled = enabledDexes.length > 0; @@ -90,7 +92,6 @@ export const DexOptions: React.FC< onClickGoTo={() => trackMatomoEvent(matomoEvent)} url={link(amount, selectedToken)} key={title} - loading={loading} toReceive={rate ? toReceive : null} /> ); 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>{' '} diff --git a/features/withdrawals/request/request.tsx b/features/withdrawals/request/request.tsx index 18ab97783..7a70d302e 100644 --- a/features/withdrawals/request/request.tsx +++ b/features/withdrawals/request/request.tsx @@ -1,16 +1,20 @@ import { FaqPlaceholder } from 'features/ipfs'; import { OnlyInfraRender } from 'shared/components/only-infra-render'; +import NoSSRWrapper from 'shared/components/no-ssr-wrapper'; -import { RequestFormProvider } from './request-form-context'; import { RequestFaq } from '../withdrawals-faq/request-faq'; +import { RequestFormProvider } from './request-form-context'; import { RequestForm } from './form'; import { RequestWallet } from './wallet'; export const Request = () => { return ( <RequestFormProvider> - <RequestWallet /> - <RequestForm /> + <NoSSRWrapper> + <RequestWallet /> + <RequestForm /> + </NoSSRWrapper> + <OnlyInfraRender renderIPFS={<FaqPlaceholder />}> <RequestFaq /> </OnlyInfraRender> 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 ( diff --git a/features/withdrawals/withdrawals-tabs.tsx b/features/withdrawals/withdrawals-tabs.tsx index 63647315b..0e63c678d 100644 --- a/features/withdrawals/withdrawals-tabs.tsx +++ b/features/withdrawals/withdrawals-tabs.tsx @@ -2,11 +2,12 @@ import { Switch } from 'shared/components'; import { WITHDRAWALS_CLAIM_PATH, WITHDRAWALS_REQUEST_PATH } from 'consts/urls'; +import { GoerliSunsetBanner } from 'shared/banners/goerli-sunset'; + import { ClaimDataProvider } from './contexts/claim-data-context'; import { useWithdrawals } from './contexts/withdrawals-context'; import { Claim } from './claim'; import { Request } from './request'; -import { GoerliSunsetBanner } from 'shared/banners/goerli-sunset'; const withdrawalRoutes = [ { 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/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/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..0737100b0 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", @@ -38,7 +38,7 @@ "@lidofinance/api-rpc": "^0.41.0", "@lidofinance/eth-api-providers": "^0.41.0", "@lidofinance/eth-providers": "^0.41.0", - "@lidofinance/lido-ui": "^3.24.0", + "@lidofinance/lido-ui": "^3.26.0", "@lidofinance/next-api-wrapper": "^0.41.0", "@lidofinance/next-ip-rate-limit": "^0.41.0", "@lidofinance/next-pages": "^0.41.0", @@ -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/pages/_app.tsx b/pages/_app.tsx index 2ae16e58f..e016045d4 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -15,6 +15,7 @@ import { withCsp } from 'config/csp'; import { SecurityStatusBanner } from 'features/ipfs'; import { Providers } from 'providers'; import { BackgroundGradient } from 'shared/components/background-gradient/background-gradient'; +import NoSsrWrapper from 'shared/components/no-ssr-wrapper'; import { nprogress, COOKIES_ALLOWED_FULL_KEY } from 'utils'; // Migrations old theme cookies to new cross domain cookies @@ -55,7 +56,11 @@ const AppWrapper = (props: AppProps): JSX.Element => { /> <ToastContainer /> <MemoApp {...rest} /> - <CookiesTooltip /> + + <NoSsrWrapper> + <CookiesTooltip privacyLink={`${config.rootOrigin}/privacy-notice`} /> + </NoSsrWrapper> + <SecurityStatusBanner /> </Providers> ); diff --git a/pages/_document.tsx b/pages/_document.tsx index 9080492cd..b19106b27 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,10 @@ export default class MyDocument extends Document { } get metaPreviewImgUrl(): string { - return `${host}/lido-preview.png`; + const origin = config.ipfsMode + ? 'https://stake.lido.fi' + : config.selfOrigin; + return `${origin}/lido-preview.png`; } render(): JSX.Element { diff --git a/pages/index.tsx b/pages/index.tsx index 3cea362e5..4a2b17c67 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,11 +1,13 @@ +import { GetStaticProps } from 'next'; import { config } from 'config'; - import { StakePage } from 'features/stake'; import { HomePageIpfs } from 'features/ipfs'; -import { GetStaticProps } from 'next'; + +export default config.ipfsMode ? HomePageIpfs : StakePage; export const getStaticProps: GetStaticProps = async () => { - return { props: {} }; + return { + props: {}, + revalidate: 60, + }; }; - -export default config.ipfsMode ? HomePageIpfs : StakePage; 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..54a5af0b1 100644 --- a/pages/withdrawals/[mode].tsx +++ b/pages/withdrawals/[mode].tsx @@ -3,7 +3,6 @@ import { GetStaticPaths, GetStaticProps } from 'next'; import Head from 'next/head'; import { Layout } from 'shared/components'; -import NoSSRWrapper from 'shared/components/no-ssr-wrapper'; import { WithdrawalsTabs } from 'features/withdrawals'; import { WithdrawalsProvider } from 'features/withdrawals/contexts/withdrawals-context'; @@ -21,9 +20,7 @@ const Withdrawals: FC<WithdrawalsModePageParams> = ({ mode }) => { <title>Withdrawals | Lido - - - + ); @@ -49,5 +46,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 }; }; 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 = ( + + {children} + + ); + + const linkProps = { + href, + onClick, + children: buttonEl, + }; + + if (isLocalLink) { + return ; + } + + return ; +}; 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/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(); diff --git a/shared/banners/l2-banner/l2-banner.tsx b/shared/banners/l2-banner/l2-banner.tsx index 623aaf5ab..79594f0d9 100644 --- a/shared/banners/l2-banner/l2-banner.tsx +++ b/shared/banners/l2-banner/l2-banner.tsx @@ -1,13 +1,7 @@ -import { - Wrapper, - L2Icons, - TextWrap, - ButtonLinkWrap, - ButtonLinkWrapLocal, - ButtonStyle, - TextHeader, - FooterWrap, -} from './styles'; +import { config } from 'config'; + +import { BannerLinkButton } from '../banner-link-button'; +import { Wrapper, L2Icons, TextWrap, TextHeader, FooterWrap } from './styles'; type L2BannerProps = { title?: React.ReactNode; @@ -20,7 +14,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, @@ -32,31 +26,20 @@ export const L2Banner = ({ testidButton, onClickButton, }: L2BannerProps) => { - const buttonEl = ( - - {buttonText} - - ); - - const linkProps = { - href: buttonHref, - onClick: onClickButton, - children: buttonEl, - }; - - const linkEl = isLocalLink ? ( - - ) : ( - - ); - return ( {title && {title}} {text} - {linkEl} + + {buttonText} + ); 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/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/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..baff3cffc --- /dev/null +++ b/shared/banners/vaults-banner-info/styles.ts @@ -0,0 +1,39 @@ +import styled from 'styled-components'; + +export const Wrap = styled.div` + position: relative; + 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..044c39678 --- /dev/null +++ b/shared/banners/vaults-banner-info/vaults-banner-info.tsx @@ -0,0 +1,51 @@ +import { useThemeToggle } from '@lidofinance/lido-ui'; +import { trackEvent } from '@lidofinance/analytics-matomo'; + +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 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'; + +import { config } from 'config'; +import { MATOMO_CLICK_EVENTS } from 'consts/matomo-click-events'; + +import { BannerLinkButton } from '../banner-link-button'; +import { Wrap, Title, Description, Footer, Logos } from './styles'; + +const LINK_LEARN_MORE = `${config.rootOrigin}/#defi-strategies`; + +const linkClickHandler = () => + trackEvent(...MATOMO_CLICK_EVENTS.vaultsBannerLearnMore); + +export const VaultsBannerInfo = () => { + const { themeName } = useThemeToggle(); + return ( + + Explore restaking opportunities + + Use stETH to unlock restaking rewards through a set of carefully 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..2f384e8cb --- /dev/null +++ b/shared/banners/vaults-banner-strategies/styles.ts @@ -0,0 +1,112 @@ +import styled from 'styled-components'; + +export const Wrap = styled.div` + position: relative; + 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} { + order: 2; + margin-right: 0; + + &, + svg { + weight: 48px; + height: 48px; + } + } +`; + +export const Title = styled.div` + text-align: left; + + ${({ theme }) => theme.mediaQueries.md} { + flex: 1 1 auto; + order: 1; + } +`; + +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} { + display: grid; + width: fit-content; + grid-template-columns: repeat(3, auto); + + & > *:nth-child(4) { + display: none; + } + } +`; + +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; + } + ${({ theme }) => theme.mediaQueries.md} { + br { + display: none; + } + } +`; + +export const StrategyDivider = styled.div` + svg { + display: block; + fill: ${({ theme }) => + theme.name === 'dark' + ? 'var(--lido-color-text)' + : 'var(--lido-color-textSecondary)'}; + } +`; 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..9534fc54e --- /dev/null +++ b/shared/banners/vaults-banner-strategies/vaults-banner-strategies.tsx @@ -0,0 +1,80 @@ +import { Button, Link } from '@lidofinance/lido-ui'; +import { trackEvent } from '@lidofinance/analytics-matomo'; + +import { ReactComponent as IconStakehouse } from 'assets/vault-banner/strategy-stakehouse.svg'; +import { ReactComponent as SymbolPlus } from 'assets/vault-banner/symbol-plus.svg'; + +import { config } from 'config'; +import { MATOMO_CLICK_EVENTS } from 'consts/matomo-click-events'; + +import { + Wrap, + Header, + Icon, + Title, + TitleText, + TitleDescription, + Strategies, + StrategyItem, + StrategyDivider, +} from './styles'; + +const LINK_LEARN_MORE = `${config.rootOrigin}/#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/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 ( - + Terms of Use 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, 'ref'>>; @@ -16,7 +18,7 @@ export const LogoLDOPL: LogoComponent = (props) => { export const LogoLido: FC> = (props) => ( - + 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()} /> ); }; 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`} /> ); }; diff --git a/test/consts.ts b/test/consts.ts index eee68f600..d3de48077 100644 --- a/test/consts.ts +++ b/test/consts.ts @@ -98,6 +98,9 @@ const LIDO_STATS_SCHEMA = { bid: { type: 'number', }, + tsAdded: { + type: 'number', + }, currency: { type: 'string', }, 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'; diff --git a/yarn.lock b/yarn.lock index 8e74363a1..e85d5b36e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2199,10 +2199,10 @@ ua-parser-js "^1.0.35" use-callback-ref "1.2.5" -"@lidofinance/lido-ui@^3.24.0": - version "3.24.0" - resolved "https://registry.yarnpkg.com/@lidofinance/lido-ui/-/lido-ui-3.24.0.tgz#2abcd5637423e672386769781c7b5dfd40b51a1e" - integrity sha512-z43M04ZOxW0ul96MFbXOcitioGxLyo9a4TMRqMzW8Va8CeYeFwPyUbdzBuRQ/kj8Tsw0vVGGIzRqlcy1doSvBg== +"@lidofinance/lido-ui@^3.26.0": + version "3.26.0" + resolved "https://registry.yarnpkg.com/@lidofinance/lido-ui/-/lido-ui-3.26.0.tgz#44c65abbbc3aaa84f805ca8e99dcddd4010c975e" + integrity sha512-W990IJAZBuaJfxh8RxZRPUFwT/+xQ93uYAr/0/8an3IIGoX+lUKmyHn22r1FCZLK19xYR8Ikm6zLr3lvCM0t2w== dependencies: "@styled-system/should-forward-prop" "5.1.5" react-collapsed "3.0.2" @@ -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==