diff --git a/IPFS.json b/IPFS.json index df2d553d..df650256 100644 --- a/IPFS.json +++ b/IPFS.json @@ -3,7 +3,8 @@ "cid": "bafybeib3zmyqlmantvdd6i5q4ehmo4larvorgquyanne3uoqdbedwgh3aq", "leastSafeVersion": "0.36.1", "config": { - "enabledWithdrawalDexes": ["one-inch", "paraswap", "bebop"] + "enabledWithdrawalDexes": ["one-inch", "paraswap", "bebop"], + "multiChainBanner": [324, 10, 42161, 137, 8453, 5000, 59144, 534352, 56] } }, "5": { @@ -16,7 +17,10 @@ "cid": "bafybeibbsoqlofslw273b4ih2pdxfaz2zbjmred2ijog725tcmfoewix7y", "leastSafeVersion": "0.36.1", "config": { - "enabledWithdrawalDexes": ["one-inch", "paraswap", "bebop"] + "enabledWithdrawalDexes": ["one-inch", "paraswap", "bebop"], + "multiChainBanner": [ + 324, 10, 42161, 137, 8453, 5000, 59144, 534352, 56, 34443 + ] } } } diff --git a/assets/icons/lido-multichain/mode.svg b/assets/icons/lido-multichain/mode.svg new file mode 100644 index 00000000..c3eaca42 --- /dev/null +++ b/assets/icons/lido-multichain/mode.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/config/external-config/types.ts b/config/external-config/types.ts index 92ea1ad0..7c043506 100644 --- a/config/external-config/types.ts +++ b/config/external-config/types.ts @@ -12,6 +12,7 @@ export type ManifestEntry = { export type ManifestConfig = { enabledWithdrawalDexes: DexWithdrawalApi[]; + multiChainBanner: number[]; }; export type ExternalConfig = Omit & diff --git a/config/external-config/utils.ts b/config/external-config/utils.ts index 9dc7e8d8..ad7f72c1 100644 --- a/config/external-config/utils.ts +++ b/config/external-config/utils.ts @@ -4,7 +4,45 @@ import { getDexConfig } from 'features/withdrawals/request/withdrawal-rates'; import FallbackLocalManifest from 'IPFS.json' assert { type: 'json' }; -// TODO: refactor on config expansion +const isEnabledDexesValid = (config: object) => { + if ( + !( + 'enabledWithdrawalDexes' in config && + Array.isArray(config.enabledWithdrawalDexes) + ) + ) + return false; + + const enabledWithdrawalDexes = config.enabledWithdrawalDexes; + + if ( + !enabledWithdrawalDexes.every( + (dex) => typeof dex === 'string' && dex !== '', + ) + ) + return false; + + return new Set(enabledWithdrawalDexes).size === enabledWithdrawalDexes.length; +}; + +const isMultiChainBannerValid = (config: object) => { + // allow empty config + if (!('multiChainBanner' in config) || !config.multiChainBanner) return true; + + if (!Array.isArray(config.multiChainBanner)) return false; + + const multiChainBanner = config.multiChainBanner; + + if ( + !multiChainBanner.every( + (chainId) => typeof chainId === 'number' && chainId > 0, + ) + ) + return false; + + return !(new Set(multiChainBanner).size !== multiChainBanner.length); +}; + export const isManifestEntryValid = ( entry?: unknown, ): entry is ManifestEntry => { @@ -18,16 +56,10 @@ export const isManifestEntryValid = ( entry.config ) { const config = entry.config; - if ( - 'enabledWithdrawalDexes' in config && - Array.isArray(config.enabledWithdrawalDexes) - ) { - const enabledWithdrawalDexes = config.enabledWithdrawalDexes; - return ( - new Set(enabledWithdrawalDexes).size === enabledWithdrawalDexes.length - ); - } - return false; + + return [isEnabledDexesValid, isMultiChainBannerValid] + .map((validator) => validator(config)) + .every((isValid) => isValid); } return false; }; @@ -39,6 +71,7 @@ export const getBackwardCompatibleConfig = ( enabledWithdrawalDexes: config.enabledWithdrawalDexes.filter( (dex) => !!getDexConfig(dex), ), + multiChainBanner: config.multiChainBanner ?? [], }; }; diff --git a/config/groups/revalidation.ts b/config/groups/revalidation.ts index 59c55f76..523d09e7 100644 --- a/config/groups/revalidation.ts +++ b/config/groups/revalidation.ts @@ -1,15 +1,2 @@ -import type { ManifestConfig, ManifestEntry } from 'config/external-config'; - export const DEFAULT_REVALIDATION = 60 * 15; // 15 minutes export const ERROR_REVALIDATION_SECONDS = 60; // 1 minute - -export const FALLBACK_CONFIG: ManifestConfig = { - enabledWithdrawalDexes: [], -}; - -export const FALLBACK_MANIFEST_ENTRY: ManifestEntry = { - cid: undefined, - ens: undefined, - leastSafeVersion: undefined, - config: FALLBACK_CONFIG, -}; diff --git a/consts/chains.ts b/consts/chains.ts index e5bb343b..506330d2 100644 --- a/consts/chains.ts +++ b/consts/chains.ts @@ -14,4 +14,5 @@ export enum LIDO_MULTICHAIN_CHAINS { Linea = 59144, Scroll = 534352, 'BNB Chain' = 56, + 'Mode Chain' = 34443, } diff --git a/consts/external-links.ts b/consts/external-links.ts index af4db36e..a62599c7 100644 --- a/consts/external-links.ts +++ b/consts/external-links.ts @@ -5,6 +5,6 @@ export const LINK_ADD_NFT_GUIDE = `${config.helpOrigin}/en/articles/7858367-how- export const OPEN_OCEAN_REFERRAL_ADDRESS = '0xbb1263222b2c020f155d409dba05c4a3861f18f8'; -// for dev and local testing you can set to 'http:/localhost:3000/runtime/IPFS.json' and have file at /public/runtime/IPFS.json +// for dev and local testing you can set to 'http://localhost:3000/runtime/IPFS.json' and have file at /public/runtime/IPFS.json export const IPFS_MANIFEST_URL = 'https://raw.githubusercontent.com/lidofinance/ethereum-staking-widget/main/IPFS.json'; diff --git a/shared/hooks/use-dapp-status.ts b/shared/hooks/use-dapp-status.ts index 2ddc41cb..b4f6909b 100644 --- a/shared/hooks/use-dapp-status.ts +++ b/shared/hooks/use-dapp-status.ts @@ -4,14 +4,19 @@ import { useAccount } from 'wagmi'; import { LIDO_MULTICHAIN_CHAINS } from 'consts/chains'; import { useIsSupportedChain } from './use-is-supported-chain'; +import { useConfig } from 'config'; export const useDappStatus = () => { + const { multiChainBanner } = useConfig().externalConfig; const { chainId, isConnected: isWalletConnected } = useAccount(); const isSupportedChain = useIsSupportedChain(); const isLidoMultichainChain = useMemo( - () => !!chainId && !!LIDO_MULTICHAIN_CHAINS[chainId], - [chainId], + () => + !!chainId && + !!LIDO_MULTICHAIN_CHAINS[chainId] && + multiChainBanner.includes(chainId), + [chainId, multiChainBanner], ); const isDappActive = useMemo(() => { diff --git a/shared/wallet/lido-multichain-fallback/lido-multichain-fallback.tsx b/shared/wallet/lido-multichain-fallback/lido-multichain-fallback.tsx index bbf6b478..534e9479 100644 --- a/shared/wallet/lido-multichain-fallback/lido-multichain-fallback.tsx +++ b/shared/wallet/lido-multichain-fallback/lido-multichain-fallback.tsx @@ -11,6 +11,7 @@ import { ReactComponent as PolygonLogo } from 'assets/icons/lido-multichain/poly import { ReactComponent as ZkSyncLogo } from 'assets/icons/lido-multichain/zk-sync.svg'; import { ReactComponent as ScrollLogo } from 'assets/icons/lido-multichain/scroll.svg'; import { ReactComponent as BNBLogo } from 'assets/icons/lido-multichain/bnb.svg'; +import { ReactComponent as ModeLogo } from 'assets/icons/lido-multichain/mode.svg'; import { config } from 'config'; import { useUserConfig } from 'config/user-config'; @@ -34,6 +35,7 @@ const multichainLogos = { [LIDO_MULTICHAIN_CHAINS['zkSync Era']]: ZkSyncLogo, [LIDO_MULTICHAIN_CHAINS.Scroll]: ScrollLogo, [LIDO_MULTICHAIN_CHAINS['BNB Chain']]: BNBLogo, + [LIDO_MULTICHAIN_CHAINS['Mode Chain']]: ModeLogo, }; const getChainLogo = (chainId: LIDO_MULTICHAIN_CHAINS) => { diff --git a/shared/wallet/lido-multichain-fallback/styles.tsx b/shared/wallet/lido-multichain-fallback/styles.tsx index 965a0057..9ed5fe72 100644 --- a/shared/wallet/lido-multichain-fallback/styles.tsx +++ b/shared/wallet/lido-multichain-fallback/styles.tsx @@ -63,6 +63,14 @@ export const Wrap = styled((props) => )` #f0b90b 91.42% ); `; + case LIDO_MULTICHAIN_CHAINS['Mode Chain']: + return css` + background: linear-gradient( + 54.14deg, + #626931 -22.38%, + #b4c740 91.42% + ); + `; default: return css` background: linear-gradient(