Skip to content

Commit 107d2e2

Browse files
committed
Merge branch 'main' into fix/ignore-sunset-filter
2 parents 0e0052d + 378a0c7 commit 107d2e2

23 files changed

Lines changed: 253 additions & 138 deletions

File tree

apps/evm/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# @venusprotocol/evm
22

3+
## 4.28.0
4+
5+
### Minor Changes
6+
7+
- 06a2283: feat: sunset of chain Unichain, opBNB, and Optimism
8+
39
## 4.27.0
410

511
### Minor Changes

apps/evm/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@venusprotocol/evm",
3-
"version": "4.27.0",
3+
"version": "4.28.0",
44
"private": true,
55
"scripts": {
66
"start": "vite",

apps/evm/src/components/Icon/icons/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,5 @@ export { default as ceefu } from './ceefu';
9292
export { default as pendle } from './pendle';
9393
export { default as stats } from './stats';
9494
export { default as diagramArrowDown } from './diagramArrowDown';
95+
export { default as sunset } from './sunset';
9596
export { default as fullScreen } from './fullScreen';
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import type { SVGProps } from 'react';
2+
3+
const SvgSunset = (props: SVGProps<SVGSVGElement>) => (
4+
<svg
5+
width="20"
6+
height="20"
7+
viewBox="0 0 20 20"
8+
fill="none"
9+
xmlns="http://www.w3.org/2000/svg"
10+
{...props}
11+
>
12+
<rect
13+
x="11"
14+
y="15"
15+
width="2"
16+
height="2"
17+
rx="1"
18+
transform="rotate(-180 11 15)"
19+
fill="currentColor"
20+
/>
21+
<rect x="9" y="7" width="2" height="5" rx="1" fill="currentColor" />
22+
<path
23+
d="M8.26795 4C9.03775 2.66667 10.9623 2.66667 11.7321 4L17.7942 14.5C18.564 15.8333 17.6018 17.5 16.0622 17.5H3.93782C2.39822 17.5 1.43597 15.8333 2.20577 14.5L8.26795 4Z"
24+
stroke="currentColor"
25+
strokeWidth="2"
26+
/>
27+
</svg>
28+
);
29+
30+
export default SvgSunset;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { ChainId } from '@venusprotocol/chains';
2+
3+
export const SUNSET_CHAIN_IDS: ChainId[] = [
4+
ChainId.OPBNB_MAINNET,
5+
ChainId.OPBNB_TESTNET,
6+
ChainId.OPTIMISM_MAINNET,
7+
ChainId.OPTIMISM_SEPOLIA,
8+
ChainId.UNICHAIN_MAINNET,
9+
ChainId.UNICHAIN_SEPOLIA,
10+
];

apps/evm/src/containers/AdBanner/Banner/index.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { cn } from '@venusprotocol/ui';
22

33
import { ButtonWrapper } from 'components';
4-
import { Link } from 'containers/Link';
4+
import { Link, type LinkProps } from 'containers/Link';
55
import { useBreakpointUp } from 'hooks/responsive';
66
import { useTranslation } from 'libs/translations';
77

@@ -10,6 +10,7 @@ export interface BannerProps extends Omit<React.HTMLAttributes<HTMLDivElement>,
1010
description: React.ReactNode;
1111
illustration: React.ReactNode;
1212
learnMoreUrl: string;
13+
learnMoreLinkProps?: Partial<LinkProps>;
1314
learnMoreLabel?: string;
1415
backgroundIllustration?: React.ReactNode;
1516
contentContainerClassName?: string;
@@ -19,6 +20,7 @@ export const Banner: React.FC<BannerProps> = ({
1920
className,
2021
contentContainerClassName,
2122
learnMoreUrl,
23+
learnMoreLinkProps,
2224
learnMoreLabel,
2325
title,
2426
description,
@@ -35,6 +37,11 @@ export const Banner: React.FC<BannerProps> = ({
3537
</div>
3638
);
3739

40+
const isInternalLink = learnMoreUrl.startsWith('/');
41+
const linkProps = isInternalLink
42+
? { to: learnMoreUrl, ...learnMoreLinkProps }
43+
: { href: learnMoreUrl, target: '_blank' as const, ...learnMoreLinkProps };
44+
3845
return (
3946
<div
4047
className={cn(
@@ -53,11 +60,7 @@ export const Banner: React.FC<BannerProps> = ({
5360
</div>
5461

5562
<ButtonWrapper size={isSmOrUp ? 'md' : 'xs'} className="px-5 md:px-6" asChild>
56-
<Link
57-
href={learnMoreUrl}
58-
target="_blank"
59-
className="hover:no-underline active:no-underline text-white"
60-
>
63+
<Link {...linkProps} className="hover:no-underline active:no-underline text-white">
6164
{learnMoreLabel ?? t('adBanner.startNow')}
6265
</Link>
6366
</ButtonWrapper>
Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,24 @@
1+
import { useGetPools } from 'clients/api';
2+
import config from 'config';
3+
import { routes } from 'constants/routing';
14
import { useTranslation } from 'libs/translations';
5+
import { ChainId } from 'types';
26
import { Banner } from '../Banner';
37
import illustration from './illustration.png';
48

5-
const LEARN_MORE_URL = 'https://community.venus.io/t/isolated-pools-sunset/5603';
6-
79
export const IsolatedPoolsSunsetBanner: React.FC = () => {
8-
const { t, Trans } = useTranslation();
10+
const { t } = useTranslation();
11+
const { data: getPoolsData } = useGetPools();
12+
13+
const hasIsolatedPools = (getPoolsData?.pools.length ?? 0) > 1;
14+
const FALLBACK_CHAIN_ID =
15+
config.network === 'testnet' ? ChainId.BSC_TESTNET : ChainId.BSC_MAINNET;
916

1017
return (
1118
<Banner
1219
className="bg-gradient-to-r from-[#01193A] to-[#0D3CB1]"
1320
title={<span className="text-white">{t('isolatedPoolsSunsetBanner.title')}</span>}
14-
description={
15-
<span className="text-grey">
16-
<Trans
17-
i18nKey="isolatedPoolsSunsetBanner.description"
18-
components={{
19-
White: <span className="text-white" />,
20-
}}
21-
/>
22-
</span>
23-
}
21+
description={<span className="text-grey">{t('isolatedPoolsSunsetBanner.description')}</span>}
2422
illustration={
2523
<div className="h-10 w-20 sm:h-12 sm:w-[90px] lg:h-14">
2624
<img
@@ -31,7 +29,8 @@ export const IsolatedPoolsSunsetBanner: React.FC = () => {
3129
</div>
3230
}
3331
contentContainerClassName="gap-x-1"
34-
learnMoreUrl={LEARN_MORE_URL}
32+
learnMoreUrl={routes.isolatedPools.path}
33+
learnMoreLinkProps={hasIsolatedPools ? undefined : { chainId: FALLBACK_CHAIN_ID }}
3534
/>
3635
);
3736
};
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Modal } from 'components';
2+
import { useTranslation } from 'libs/translations';
3+
import { useSunsetModalStore } from '../sunsetModalStore';
4+
5+
export const SunsetModal: React.FC = () => {
6+
const { t } = useTranslation();
7+
const isOpen = useSunsetModalStore(state => state.isOpen);
8+
const close = useSunsetModalStore(state => state.close);
9+
10+
return (
11+
<Modal isOpen={isOpen} handleClose={close} title={t('layout.sunsetModal.title')}>
12+
<p className="text-grey text-p2r">{t('layout.sunsetModal.description')}</p>
13+
</Modal>
14+
);
15+
};
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { cn } from '@venusprotocol/ui';
2+
import { Icon } from 'components';
3+
import { useSunsetModalStore } from '../sunsetModalStore';
4+
5+
export { SunsetModal } from './SunsetModal';
6+
7+
export interface SunsetIndicatorProps {
8+
interactive?: boolean;
9+
className?: string;
10+
}
11+
12+
export const SunsetIndicator: React.FC<SunsetIndicatorProps> = ({
13+
interactive = true,
14+
className,
15+
}) => {
16+
const open = useSunsetModalStore(state => state.open);
17+
18+
const handleClick = (e: React.MouseEvent) => {
19+
if (!interactive) return;
20+
e.preventDefault();
21+
e.stopPropagation();
22+
open();
23+
};
24+
25+
const handleMouseDown = (e: React.MouseEvent) => {
26+
if (!interactive) return;
27+
e.stopPropagation();
28+
};
29+
30+
return (
31+
<span
32+
onClick={handleClick}
33+
onMouseDown={handleMouseDown}
34+
className={cn(
35+
'flex flex-none items-center justify-center',
36+
interactive && 'cursor-pointer',
37+
className,
38+
)}
39+
>
40+
<Icon name="sunset" className="size-5 text-orange" />
41+
</span>
42+
);
43+
};

apps/evm/src/containers/Layout/NavBar/ChainSelect/index.tsx

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import config from 'config';
55
import { useTranslation } from 'libs/translations';
66
import { chains, useChainId, useSwitchChain } from 'libs/wallet';
77
import type { ChainId } from 'types';
8+
import { isSunsetChain } from 'utilities/isSunsetChain';
89
import { GaslessStatus } from './GaslessStatus';
10+
import { SunsetIndicator, SunsetModal } from './SunsetIndicator';
11+
import { useSunsetModalStore } from './sunsetModalStore';
912

1013
export interface ChainSelectProps
1114
extends Omit<SelectProps, 'value' | 'onChange' | 'options' | 'optionClassName'> {
@@ -16,37 +19,56 @@ export const ChainSelect: React.FC<ChainSelectProps> = props => {
1619
const { t } = useTranslation();
1720
const { chainId } = useChainId();
1821
const { switchChain } = useSwitchChain();
22+
const openSunsetModal = useSunsetModalStore(state => state.open);
23+
24+
const handleChange = (newChainId: ChainId | string | number) => {
25+
const id = Number(newChainId) as ChainId;
26+
if (isSunsetChain(id) && id !== chainId) {
27+
openSunsetModal();
28+
}
29+
switchChain({ chainId: id });
30+
};
1931

2032
const options = chains.map<SelectOption<ChainId>>(chain => ({
2133
label: ({ isRenderedInButton }) => {
22-
const metadata = chainMetadata[chain.id as ChainId];
34+
const optionChainId = chain.id as ChainId;
35+
const metadata = chainMetadata[optionChainId];
36+
const showSunsetIndicator = isSunsetChain(optionChainId);
37+
const isActiveChain = optionChainId === chainId;
38+
2339
return (
2440
<div className="flex items-center">
2541
<img src={metadata.iconSrc} alt={metadata.name} className="w-6 max-w-none flex-none" />
2642

2743
{!isRenderedInButton && (
28-
<span className={cn('flex ml-2 grow items-center gap-x-1')}>
44+
<span className={cn('flex ml-2 items-center gap-x-1')}>
2945
<span>{metadata.name}</span>
3046

31-
<GaslessStatus chainId={chain.id} displayLabel />
47+
<GaslessStatus chainId={optionChainId} displayLabel />
3248
</span>
3349
)}
50+
51+
{showSunsetIndicator && <SunsetIndicator className="ml-2" interactive={!isActiveChain} />}
3452
</div>
3553
);
3654
},
3755
value: chain.id,
3856
}));
3957

4058
return (
41-
<Select
42-
// When running in Safe Wallet app, it is responsible for the active chain
43-
disabled={config.isSafeApp}
44-
value={chainId}
45-
onChange={newChainId => switchChain({ chainId: Number(newChainId) })}
46-
options={options}
47-
menuPosition="right"
48-
menuTitle={t('layout.chainSelect.label')}
49-
{...props}
50-
/>
59+
<>
60+
<Select
61+
// When running in Safe Wallet app, it is responsible for the active chain
62+
disabled={config.isSafeApp}
63+
value={chainId}
64+
onChange={handleChange}
65+
options={options}
66+
menuPosition="right"
67+
menuTitle={t('layout.chainSelect.label')}
68+
{...props}
69+
/>
70+
71+
<SunsetModal />
72+
</>
5173
);
5274
};

0 commit comments

Comments
 (0)