,
+ banner: (
+
+ {APP_DEPRECATION_BANNER.text}
+ setShouldShowBanner(false)} />
+
+ ),
+ };
+}
+
+function ChainBanner(chainId: number | undefined) {
const [shouldShowBanner, setShouldShowBanner] = useKeyedState(true, chainId, { persist: true });
if (chainId === undefined || !BANNERS[chainId] || !shouldShowBanner) {
@@ -29,12 +53,15 @@ function Banner(chainId: number | undefined) {
}
export function Header({ className, children, chainId, ...props }: React.ComponentProps<"div"> & { chainId?: number }) {
- const { placeholder, banner } = Banner(chainId);
+ const { placeholder: deprecationPlaceholder, banner: deprecationBanner } = AppDeprecationBanner();
+ const { placeholder: chainPlaceholder, banner: chainBanner } = ChainBanner(chainId);
return (
<>
- {placeholder}
+ {deprecationPlaceholder}
+ {chainPlaceholder}
- {banner}
+ {deprecationBanner}
+ {chainBanner}
diff --git a/apps/lite/src/lib/constants.tsx b/apps/lite/src/lib/constants.tsx
index e226083..8b2620c 100644
--- a/apps/lite/src/lib/constants.tsx
+++ b/apps/lite/src/lib/constants.tsx
@@ -1,7 +1,59 @@
import { SafeLink } from "@morpho-org/uikit/components/safe-link";
import { type Deployments } from "@morpho-org/uikit/lib/deployments";
import { ReactNode } from "react";
-import { hemi, optimism, plumeMainnet, polygon, sei, worldchain } from "wagmi/chains";
+import { type Chain, hemi, optimism, plumeMainnet, polygon, sei, worldchain } from "wagmi/chains";
+
+/**
+ * App-wide deprecation banner configuration.
+ * Set to undefined to disable the banner.
+ */
+export const APP_DEPRECATION_BANNER: { color: string; text: ReactNode } | undefined = {
+ color: "bg-amber-600",
+ text: (
+
+ Morpho Lite will be gradually phased out in the coming months; learn more{" "}
+
+ here
+
+ .
+
+ ),
+};
+
+/**
+ * Chain-specific deprecation modal configuration.
+ * Only chains listed here will show the deprecation modal.
+ */
+export const CHAIN_DEPRECATION_INFO: Partial<
+ Record
+> = {
+ [worldchain.id]: {
+ chain: worldchain,
+ cutoffDate: "February 14, 2026",
+ ecosystemBuilder: "Oku",
+ ecosystemBuilderUrl: "https://oku.trade/morpho/vaults?inputChain=worldchain",
+ },
+ [plumeMainnet.id]: {
+ chain: plumeMainnet,
+ cutoffDate: "February 14, 2026",
+ ecosystemBuilder: "Mystic",
+ ecosystemBuilderUrl: "https://app.mysticfinance.xyz",
+ },
+ [sei.id]: {
+ chain: sei,
+ cutoffDate: "February 14, 2026",
+ ecosystemBuilder: "Feather",
+ ecosystemBuilderUrl: "https://app.feather.zone/portfolio",
+ },
+};
+
+export function isReduceOnly(chainId: number | undefined) {
+ return chainId !== undefined && CHAIN_DEPRECATION_INFO[chainId] !== undefined;
+}
export const APP_DETAILS = {
// NOTE: Should always match the title in `index.html` (won't break anything, but should be correct)
@@ -91,7 +143,7 @@ export const BANNERS: Record
Claim rewards and access enhanced features on the external{" "}
- Oku Trade
+ Oku
{" "}
interface.
diff --git a/apps/lite/src/lib/wagmi-config.ts b/apps/lite/src/lib/wagmi-config.ts
index 5ba3a37..00824f3 100644
--- a/apps/lite/src/lib/wagmi-config.ts
+++ b/apps/lite/src/lib/wagmi-config.ts
@@ -42,16 +42,6 @@ function createFallbackTransport(rpcs: ({ url: string } & HttpTransportConfig)[]
);
}
-function createPonderHttp(chainId: number) {
- return [
- {
- url: `https://v1-indexer.marble.live/rpc/${chainId}`,
- batch: false,
- methods: { include: ["eth_getLogs"] },
- },
- ];
-}
-
function createPrivateProxyHttp(chainId: number): ({ url: string } & HttpTransportConfig)[] {
const subdomain = import.meta.env.DEV ? "rpc-dev" : "rpc";
const url = `https://${subdomain}.morpho.dev/cache/evm/${chainId}?secret=${import.meta.env.VITE_ERPC_API_KEY}`;
@@ -102,7 +92,6 @@ const chains = [
const transports: { [K in (typeof chains)[number]["id"]]: Transport } & { [k: number]: Transport } = {
// full support
[mainnet.id]: createFallbackTransport([
- ...createPonderHttp(mainnet.id),
...createPrivateProxyHttp(mainnet.id),
{ url: "https://rpc.mevblocker.io", batch: { batchSize: 10 } },
{ url: "https://rpc.ankr.com/eth", batch: { batchSize: 10 } },
@@ -110,7 +99,6 @@ const transports: { [K in (typeof chains)[number]["id"]]: Transport } & { [k: nu
{ url: "https://eth.merkle.io", batch: false },
]),
[base.id]: createFallbackTransport([
- ...createPonderHttp(base.id),
...createPrivateProxyHttp(base.id),
{ url: "https://base.gateway.tenderly.co", batch: { batchSize: 10 } },
{ url: "https://base.drpc.org", batch: false },
@@ -118,31 +106,26 @@ const transports: { [K in (typeof chains)[number]["id"]]: Transport } & { [k: nu
{ url: "https://base.lava.build", batch: false },
]),
[polygon.id]: createFallbackTransport([
- ...createPonderHttp(polygon.id),
...createPrivateProxyHttp(polygon.id),
{ url: "https://polygon.gateway.tenderly.co", batch: { batchSize: 10 } },
{ url: "https://polygon.drpc.org", batch: false },
]),
[unichain.id]: createFallbackTransport([
- ...createPonderHttp(unichain.id),
...createPrivateProxyHttp(unichain.id),
{ url: "https://unichain.gateway.tenderly.co", batch: { batchSize: 10 } },
{ url: "https://unichain.drpc.org", batch: false },
]),
[customChains.katana.id]: createFallbackTransport([
- ...createPonderHttp(customChains.katana.id),
...createPrivateProxyHttp(customChains.katana.id),
...customChains.katana.rpcUrls.default.http.map((url) => ({ url, batch: false })),
]),
[arbitrum.id]: createFallbackTransport([
- ...createPonderHttp(arbitrum.id),
...createPrivateProxyHttp(arbitrum.id),
{ url: "https://arbitrum.gateway.tenderly.co", batch: { batchSize: 10 } },
{ url: "https://rpc.ankr.com/arbitrum", batch: { batchSize: 10 } },
{ url: "https://arbitrum.drpc.org", batch: false },
]),
[customChains.hyperevm.id]: createFallbackTransport([
- ...createPonderHttp(customChains.hyperevm.id),
...createPrivateProxyHttp(customChains.hyperevm.id),
{ url: "https://rpc.hyperlend.finance/archive", batch: false },
]),
@@ -202,7 +185,6 @@ const transports: { [K in (typeof chains)[number]["id"]]: Transport } & { [k: nu
{ url: "https://scroll.drpc.org", batch: false },
]),
[sei.id]: createFallbackTransport([
- ...createPonderHttp(sei.id),
...createPrivateProxyHttp(sei.id),
{ url: "https://sei-public.nodies.app", batch: false, key: "sei-nodies-maxNum-2000" },
{ url: "https://sei.therpc.io", batch: false, key: "sei-therpc-maxNum-2000" },
@@ -221,7 +203,6 @@ const transports: { [K in (typeof chains)[number]["id"]]: Transport } & { [k: nu
{ url: "https://sonic.drpc.org", batch: false },
]),
[customChains.tac.id]: createFallbackTransport([
- ...createPonderHttp(customChains.tac.id),
...createPrivateProxyHttp(customChains.tac.id),
{ url: "https://rpc.tac.build/", batch: false },
{ url: "https://tac.therpc.io", batch: false },
diff --git a/apps/lite/test/components/earn-sheet-content.test.tsx b/apps/lite/test/components/earn-sheet-content.test.tsx
index 2636f92..c59ea6b 100644
--- a/apps/lite/test/components/earn-sheet-content.test.tsx
+++ b/apps/lite/test/components/earn-sheet-content.test.tsx
@@ -72,9 +72,17 @@ describe("deposit flow", () => {
await client.deal({ account, amount: parseEther(amount), erc20: asset.address }); // for deposit
await client.impersonateAccount({ address: account });
- render( , {
- wagmiConfig,
- });
+ render(
+ ,
+ {
+ wagmiConfig,
+ },
+ );
// Wait for tabs -- this implies the `Testable` wrapper has connected the mock account
await waitFor(() => screen.findAllByRole("tab"));
@@ -178,9 +186,17 @@ describe("withdraw flow", () => {
]);
const maxText = formatUnits(maxWithdraw, asset.decimals!);
- render( , {
- wagmiConfig,
- });
+ render(
+ ,
+ {
+ wagmiConfig,
+ },
+ );
// Wait for tabs -- this implies the `Testable` wrapper has connected the mock account
await waitFor(() => screen.findAllByRole("tab"));
@@ -251,9 +267,17 @@ describe("withdraw flow", () => {
await client.deal({ account, amount: parseEther(shares), erc20: vaultAddress }); // for withdraw
await client.impersonateAccount({ address: account });
- render( , {
- wagmiConfig,
- });
+ render(
+ ,
+ {
+ wagmiConfig,
+ },
+ );
// Wait for tabs -- this implies the `Testable` wrapper has connected the mock account
await waitFor(() => screen.findAllByRole("tab"));