diff --git a/public/icons/tokens/wxtz.svg b/public/icons/tokens/wxtz.svg
index ea1bbeb8..84e23b56 100644
--- a/public/icons/tokens/wxtz.svg
+++ b/public/icons/tokens/wxtz.svg
@@ -1,4 +1,9 @@
-
+
+
+
+
+
+
diff --git a/src/components/MarketSwitcher.tsx b/src/components/MarketSwitcher.tsx
index 1fe9f756..90717c2c 100644
--- a/src/components/MarketSwitcher.tsx
+++ b/src/components/MarketSwitcher.tsx
@@ -59,7 +59,7 @@ type MarketLogoProps = {
export const MarketLogo = ({ size, logo, testChainName }: MarketLogoProps) => {
return (
-
+
{testChainName && (
@@ -173,35 +173,36 @@ export const MarketSwitcher = () => {
- {availableMarkets.map((marketId: CustomMarket) => {
- const { market, network } = getMarketInfoById(marketId);
- const marketNaming = getMarketHelpData(market.marketTitle);
- return (
-
- );
- })}
+ {availableMarkets
+ .map((marketId: CustomMarket) => {
+ const { market, network } = getMarketInfoById(marketId);
+ const marketNaming = getMarketHelpData(market.marketTitle);
+ return (
+
+ );
+ })}
);
};
diff --git a/src/components/TextWithTooltip.tsx b/src/components/TextWithTooltip.tsx
index 47044578..c75f029f 100644
--- a/src/components/TextWithTooltip.tsx
+++ b/src/components/TextWithTooltip.tsx
@@ -27,7 +27,12 @@ export const TextWithTooltip = ({
const [open, setOpen] = useState(false);
return (
-
+
{text && {text}}
{children}>} open={open} setOpen={setOpen}>
diff --git a/src/components/primitives/WarningSnackbar.tsx b/src/components/primitives/WarningSnackbar.tsx
new file mode 100644
index 00000000..454b14f9
--- /dev/null
+++ b/src/components/primitives/WarningSnackbar.tsx
@@ -0,0 +1,32 @@
+import { Alert, Snackbar } from '@mui/material'
+import React from 'react'
+
+type TSnackbar = {
+ open: boolean;
+ message: string;
+}
+
+type TProps = {
+ snackbar: TSnackbar;
+ handleCloseSnackbar: () => void;
+}
+
+export default function WarningSnackbar({ snackbar, handleCloseSnackbar }: TProps) {
+ return (
+
+
+ {snackbar.message}
+
+
+ )
+}
diff --git a/src/components/transactions/FlowCommons/TxModalDetails.tsx b/src/components/transactions/FlowCommons/TxModalDetails.tsx
index 67cb9df8..93e97177 100644
--- a/src/components/transactions/FlowCommons/TxModalDetails.tsx
+++ b/src/components/transactions/FlowCommons/TxModalDetails.tsx
@@ -144,8 +144,8 @@ export const DetailsNumberLineWithSub = ({
loading = false,
}: DetailsNumberLineWithSubProps) => {
return (
-
-
+
+
{loading ? (
<>
diff --git a/src/helpers/toggle-mode.tsx b/src/helpers/toggle-mode.tsx
new file mode 100644
index 00000000..ef55edef
--- /dev/null
+++ b/src/helpers/toggle-mode.tsx
@@ -0,0 +1,10 @@
+export const toggleMode = () => {
+ const isTestnetEnabled = localStorage.getItem('testnetsEnabled') === 'true';
+ const toggledTestnet = isTestnetEnabled ? "false" : "true";
+ localStorage.setItem('testnetsEnabled', toggledTestnet);
+
+ // Set window.location to trigger a page reload when navigating to the the dashboard
+ window.location.href = '/';
+
+ return toggledTestnet;
+};
\ No newline at end of file
diff --git a/src/hooks/useSnackbar.tsx b/src/hooks/useSnackbar.tsx
new file mode 100644
index 00000000..c4d29950
--- /dev/null
+++ b/src/hooks/useSnackbar.tsx
@@ -0,0 +1,25 @@
+import { useState } from 'react';
+
+const snackbarInit = {
+ open: false,
+ message: ""
+}
+
+export default function useSnackbar() {
+ const [snackbar, setSnackbar] = useState(snackbarInit);
+
+ function handleCloseSnackbar() {
+ setSnackbar(state => ({ ...state, open: false }));
+ }
+
+ function handleOpenSnackbar({ message = "" }: { message: string }) {
+ setSnackbar({ open: true, message });
+ }
+
+ return {
+ snackbar,
+ setSnackbar,
+ handleCloseSnackbar,
+ handleOpenSnackbar
+ }
+}
\ No newline at end of file
diff --git a/src/layouts/AppHeader.tsx b/src/layouts/AppHeader.tsx
index d09fdcca..a92645da 100644
--- a/src/layouts/AppHeader.tsx
+++ b/src/layouts/AppHeader.tsx
@@ -21,6 +21,11 @@ import { NavItems } from './components/NavItems';
import { MobileMenu } from './MobileMenu';
import { SettingsMenu } from './SettingsMenu';
import WalletWidget from './WalletWidget';
+import { toggleMode } from 'src/helpers/toggle-mode';
+import { useWeb3Context } from 'src/libs/hooks/useWeb3Context';
+import { ChainId } from 'src/ui-config/networksConfig';
+import useSnackbar from 'src/hooks/useSnackbar';
+import WarningSnackbar from 'src/components/primitives/WarningSnackbar';
interface Props {
children: React.ReactElement;
@@ -40,6 +45,8 @@ export function AppHeader() {
const { breakpoints } = useTheme();
const md = useMediaQuery(breakpoints.down('md'));
const sm = useMediaQuery(breakpoints.down('sm'));
+ const { switchNetwork } = useWeb3Context();
+ const { snackbar, handleCloseSnackbar, handleOpenSnackbar } = useSnackbar();
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
const [walletWidgetOpen, setWalletWidgetOpen] = useState(false);
@@ -56,72 +63,89 @@ export function AppHeader() {
const headerHeight = 80;
- const disableTestnet = () => {
- localStorage.setItem('testnetsEnabled', 'false');
- // Set window.location to trigger a page reload when navigating to the the dashboard
- window.location.href = '/';
+ const handleNetworkSwitch = () => {
+ const isTestnetEnabled = localStorage.getItem('testnetsEnabled') === 'true';
+ const newChainId = isTestnetEnabled ? ChainId.etherlink : ChainId.etherlink_testnet;
+
+ switchNetwork(newChainId)
+ .then(toggleMode)
+ .catch(err => {
+ console.log('Switch network error => ', `"${err.code}"`)
+ if(err.code.toString() === "-32002") {
+ handleOpenSnackbar({
+ message: "Resolve any pending requests from your wallet or try again!"
+ });
+ }
+ });
};
const testnetTooltip = (
- Testnet mode is ON
+ {ENABLE_TESTNET && Testnet mode is ON}
+ {!ENABLE_TESTNET && Testnet mode is OFF}
- The app is running in testnet mode. Learn how it works in{' '}
+ {ENABLE_TESTNET &&
+ The app is running in testnet mode. Learn how it works in
+ }
+ {!ENABLE_TESTNET &&
+ The app is running in mainnet mode. Learn how it works in
+ }
FAQ.
-
);
return (
-
- ({
- height: headerHeight,
- position: 'sticky',
- top: 0,
- transition: theme.transitions.create('top'),
- zIndex: theme.zIndex.appBar,
- background: theme.palette.background.navbar,
- padding: {
- xs: mobileMenuOpen || walletWidgetOpen ? '8px 20px' : '8px 8px 8px 20px',
- xsm: '8px 20px',
- },
- display: 'flex',
- alignItems: 'center',
- flexDirection: 'space-between',
- })}
- >
+ <>
+
setMobileMenuOpen(false)}
+ component="header"
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore
+ sx={(theme) => ({
+ height: headerHeight,
+ position: 'sticky',
+ top: 0,
+ transition: theme.transitions.create('top'),
+ zIndex: theme.zIndex.appBar,
+ background: theme.palette.background.navbar,
+ padding: {
+ xs: mobileMenuOpen || walletWidgetOpen ? '8px 20px' : '8px 8px 8px 20px',
+ xsm: '8px 20px',
+ },
+ display: 'flex',
+ alignItems: 'center',
+ flexDirection: 'space-between',
+ })}
>
-
-
-
- {ENABLE_TESTNET && (
+ setMobileMenuOpen(false)}
+ >
+
+
+
- TESTNET
+ {ENABLE_TESTNET ? "TESTNET" : "MAINNET"}
- )}
-
-
-
-
-
-
-
+
- {!mobileMenuOpen && (
-
- )}
+
+
+
-
-
-
+
- {!walletWidgetOpen && (
-
-
+ )}
+
+
+
- )}
-
-
+
+ {!walletWidgetOpen && (
+
+
+
+ )}
+
+
+
+ >
);
}
diff --git a/src/layouts/components/TestNetModeSwitcher.tsx b/src/layouts/components/TestNetModeSwitcher.tsx
index 039d8fdf..6f18e1e7 100644
--- a/src/layouts/components/TestNetModeSwitcher.tsx
+++ b/src/layouts/components/TestNetModeSwitcher.tsx
@@ -1,29 +1,41 @@
import { Trans } from '@lingui/macro';
import { Box, FormControlLabel, ListItem, ListItemText, MenuItem, Switch } from '@mui/material';
-import React, { useState } from 'react';
+import React from 'react';
+import WarningSnackbar from 'src/components/primitives/WarningSnackbar';
+import { toggleMode } from 'src/helpers/toggle-mode';
+import useSnackbar from 'src/hooks/useSnackbar';
+import { useWeb3Context } from 'src/libs/hooks/useWeb3Context';
+import { ChainId } from 'src/ui-config/networksConfig';
+
interface TestNetModeSwitcherProps {
component?: typeof MenuItem | typeof ListItem;
}
export const TestNetModeSwitcher = ({ component = ListItem }: TestNetModeSwitcherProps) => {
- // const testnetsEnabledId = 'testnetsEnabled';
- const testnetsEnabledLocalstorage = true;
- // localStorage.getItem(testnetsEnabledId) === 'true' || false;
- const [testnetsEnabled] = useState(testnetsEnabledLocalstorage);
+ const testnetEnabled = localStorage.getItem("testnetsEnabled") === 'true';
+ const { snackbar, handleCloseSnackbar, handleOpenSnackbar } = useSnackbar();
+ const { switchNetwork } = useWeb3Context();
+
+ const handleNetworkSwitch = () => {
+ const newChainId = testnetEnabled ? ChainId.etherlink : ChainId.etherlink_testnet;
- const toggleTestnetsEnabled = () => {
- // const newState = !testnetsEnabled;
- // setTestnetsMode(!testnetsEnabled);
- // localStorage.setItem(testnetsEnabledId, newState ? 'true' : 'false');
- // // Set window.location to trigger a page reload when navigating to the the dashboard
- // window.location.href = '/';
+ switchNetwork(newChainId)
+ .then(toggleMode)
+ .catch(err => {
+ console.log('Switch network error => ', `"${err.message}"`)
+ if (err.code.toString() === "-32002") {
+ handleOpenSnackbar({
+ message: "Resolve any pending requests from your wallet or try again!"
+ });
+ }
+ });
};
return (
}
- label={testnetsEnabled ? 'On' : 'Off'}
+ label={testnetEnabled ? 'On' : 'Off'}
labelPlacement="start"
/>
+
);
};
diff --git a/src/libs/web3-data-provider/Web3Provider.tsx b/src/libs/web3-data-provider/Web3Provider.tsx
index 0e73794b..b190dfc5 100644
--- a/src/libs/web3-data-provider/Web3Provider.tsx
+++ b/src/libs/web3-data-provider/Web3Provider.tsx
@@ -366,8 +366,10 @@ export const Web3ContextProvider: React.FC<{ children: ReactElement }> = ({ chil
}
} else if (switchError.code === 4001) {
setSwitchNetworkError(undefined);
+ throw switchError;
} else {
setSwitchNetworkError(switchError);
+ throw switchError;
}
}
}
diff --git a/src/modules/dashboard/lists/SupplyAssetsList/WalletEmptyInfo.tsx b/src/modules/dashboard/lists/SupplyAssetsList/WalletEmptyInfo.tsx
index 1952813c..6cabd0ad 100644
--- a/src/modules/dashboard/lists/SupplyAssetsList/WalletEmptyInfo.tsx
+++ b/src/modules/dashboard/lists/SupplyAssetsList/WalletEmptyInfo.tsx
@@ -16,6 +16,8 @@ type WalletEmptyInfoProps = Pick & {
export function WalletEmptyInfo({ bridge, chainId, icon, sx, symbol }: WalletEmptyInfoProps) {
const network = [ChainId.avalanche].includes(chainId) ? 'Ethereum & Bitcoin' : 'Ethereum';
+ const isWstEth = symbol === 'wstETH';
+
return (
{bridge ? (
@@ -24,12 +26,21 @@ export function WalletEmptyInfo({ bridge, chainId, icon, sx, symbol }: WalletEmp
{{bridge.name}} to transfer your {network} assets.
) : (
-
- Your wallet is empty. Purchase or transfer assets.{' '}
- {symbol === 'wstETH' ? (
- Wrap your Lido stETH here.
- ) : null}
-
+ <>
+
+ Your wallet is empty. Purchase or transfer assets.{' '}
+
+ {isWstEth &&
+ <>
+
+
+
+ Wrap your Lido stETH here.
+
+
+ >
+ }
+ >
)}
);
diff --git a/src/modules/reserve-overview/BorrowInfo.tsx b/src/modules/reserve-overview/BorrowInfo.tsx
index 04afc1ac..6df9645a 100644
--- a/src/modules/reserve-overview/BorrowInfo.tsx
+++ b/src/modules/reserve-overview/BorrowInfo.tsx
@@ -44,6 +44,7 @@ export const BorrowInfo = ({
display: 'flex',
alignItems: 'center',
flexWrap: 'wrap',
+ gap: '10px'
}}
>
{showBorrowCapStatus ? (
diff --git a/src/ui-config/marketsConfig.tsx b/src/ui-config/marketsConfig.tsx
index 9b840399..0cb83f4b 100644
--- a/src/ui-config/marketsConfig.tsx
+++ b/src/ui-config/marketsConfig.tsx
@@ -53,6 +53,7 @@ export type MarketDataType = {
export enum CustomMarket {
etherlink_testnet = 'etherlink_testnet',
+ etherlink = 'etherlink',
}
export const marketsData: {
@@ -77,5 +78,25 @@ export const marketsData: {
COLLECTOR: '0x250fB04547404729D22Eb8f9C498Da13E9980f2D',
},
faucetUrl: 'https://faucet.etherlink.com',
+ },
+ [CustomMarket.etherlink]: {
+ marketTitle: 'Etherlink',
+ chainId: 42793, //ChainId.etherlink,
+ v3: true,
+ enabledFeatures: {
+ liquiditySwap: false,
+ collateralRepay: false,
+ faucet: false,
+ },
+ addresses: {
+ LENDING_POOL_ADDRESS_PROVIDER: '0x33cf76bcff795d3C3522B9EF539c10877D3C32dE'.toLowerCase(),
+ LENDING_POOL: '0xb12Ec57a854C2D6beE878ac803d84624f525226A',
+ WALLET_BALANCE_PROVIDER: '0xAB6e6CbCeA13870c809B93e1134747c0239c9B75',
+ UI_POOL_DATA_PROVIDER: '0xa412ab4428c6E5543661e463987485121a898943',
+ UI_INCENTIVE_DATA_PROVIDER: '0x8d254ECDb2FF209e00771A006814D5D74fbFf28C',
+ WETH_GATEWAY: '0x0d2304c30Fca9781dF8a4DC06A44f3f7c475dD1A',
+ COLLECTOR: '0x78466b9DC7023Ad14b955dCDf8BffD2888BCfcF0',
+ },
+ faucetUrl: 'https://faucet.etherlink.com',
},
} as const;
\ No newline at end of file
diff --git a/src/ui-config/networksConfig.ts b/src/ui-config/networksConfig.ts
index f210f5dc..9fff00d8 100644
--- a/src/ui-config/networksConfig.ts
+++ b/src/ui-config/networksConfig.ts
@@ -51,11 +51,13 @@ export type BaseNetworkConfig = Omit;
export enum ChainId {
mainnet = 1,
etherlink_testnet = 128123,
+ etherlink = 42793,
}
export const ChainIdToNetwork: Record = {
1: 'mainnet',
128123: 'etherlink_testnet',
+ 42793: 'etherlink',
};
export const networkConfigs: Record = {
@@ -84,7 +86,6 @@ export const networkConfigs: Record = {
name: 'Etherlink Testnet',
publicJsonRPCUrl: [
'https://node.ghostnet.etherlink.com',
- 'https://etherlink-rollup-testnet-archive.zeeve.net/Rdj3r1npGPHxcDcQvOT/rpc',
],
baseUniswapAdapter: '0x0',
baseAssetSymbol: 'XTZ',
@@ -94,4 +95,19 @@ export const networkConfigs: Record = {
isTestnet: true,
networkLogoPath: '/icons/networks/etherlink.svg',
},
+ [ChainId.etherlink]: {
+ name: 'Etherlink',
+ publicJsonRPCUrl: [
+ 'https://rpc.superlend.xyz',
+ 'https://plend-etherlink-mainnet-djs2w.zeeve.net/TuychDxGCScIED1nCk0m/rpc',
+ 'https://node.mainnet.etherlink.com'
+ ],
+ baseUniswapAdapter: '0x0',
+ baseAssetSymbol: 'XTZ',
+ wrappedBaseAssetSymbol: 'WXTZ',
+ baseAssetDecimals: 18,
+ explorerLink: 'https://explorer.etherlink.com',
+ isTestnet: false,
+ networkLogoPath: '/icons/networks/etherlink.svg',
+ },
} as const;
diff --git a/src/utils/marketsAndNetworksConfig.ts b/src/utils/marketsAndNetworksConfig.ts
index a378098b..cd9aaff8 100644
--- a/src/utils/marketsAndNetworksConfig.ts
+++ b/src/utils/marketsAndNetworksConfig.ts
@@ -22,9 +22,8 @@ export type Pool = {
};
export const STAGING_ENV = process.env.NEXT_PUBLIC_ENV === 'staging';
-export const PROD_ENV = !process.env.NEXT_PUBLIC_ENV || process.env.NEXT_PUBLIC_ENV === 'prod';
-export const ENABLE_TESTNET =
- PROD_ENV || global?.window?.localStorage.getItem('testnetsEnabled') === 'true';
+export const PROD_ENV = process.env.NEXT_PUBLIC_ENV === 'prod';
+export const ENABLE_TESTNET = global?.window?.localStorage.getItem('testnetsEnabled') === 'true';
// determines if forks should be shown
const FORK_ENABLED =
@@ -102,7 +101,7 @@ export function getSupportedChainIds(): number[] {
if (STAGING_ENV || ENABLE_TESTNET) {
return isTestnet;
}
-
+
return !isTestnet;
})
.reduce(