apply small changes for the app
Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
This commit is contained in:
parent
2fca4651cc
commit
e244299465
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "ghost-dao-interface",
|
"name": "ghost-dao-interface",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.7.50",
|
"version": "0.7.51",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@ -198,7 +198,7 @@ function App() {
|
|||||||
<Route path="dashboard" element={<TreasuryDashboard chainId={addressChainId ? addressChainId : chainId} />} />
|
<Route path="dashboard" element={<TreasuryDashboard chainId={addressChainId ? addressChainId : chainId} />} />
|
||||||
<Route path="bonds" element={<Bonds connect={tryConnectInjected} address={address} chainId={addressChainId ? addressChainId : chainId} />} />
|
<Route path="bonds" element={<Bonds connect={tryConnectInjected} address={address} chainId={addressChainId ? addressChainId : chainId} />} />
|
||||||
<Route path="bonds/:id" element={<BondModalContainer config={config} connect={tryConnectInjected} address={address} chainId={addressChainId ? addressChainId : chainId} />} />
|
<Route path="bonds/:id" element={<BondModalContainer config={config} connect={tryConnectInjected} address={address} chainId={addressChainId ? addressChainId : chainId} />} />
|
||||||
<Route path="stake" element={<StakeContainer connect={tryConnectInjected} address={address} chainId={addressChainId ? addressChainId : chainId} />} />
|
<Route path="stake" element={<StakeContainer config={config} connect={tryConnectInjected} address={address} chainId={addressChainId ? addressChainId : chainId} />} />
|
||||||
<Route path="bridge" element={<Bridge config={config} connect={tryConnectInjected} address={address} chainId={addressChainId ? addressChainId : chainId} />} />
|
<Route path="bridge" element={<Bridge config={config} connect={tryConnectInjected} address={address} chainId={addressChainId ? addressChainId : chainId} />} />
|
||||||
<Route path="dex/:name" element={<Dex config={config} connect={tryConnectInjected} address={address} chainId={addressChainId ? addressChainId : chainId} />} />
|
<Route path="dex/:name" element={<Dex config={config} connect={tryConnectInjected} address={address} chainId={addressChainId ? addressChainId : chainId} />} />
|
||||||
<Route path="governance" element={<Governance config={config} connect={tryConnectInjected} address={address} chainId={addressChainId ? addressChainId : chainId} />} />
|
<Route path="governance" element={<Governance config={config} connect={tryConnectInjected} address={address} chainId={addressChainId ? addressChainId : chainId} />} />
|
||||||
|
|||||||
@ -84,22 +84,20 @@ const Modal = ({
|
|||||||
// getModalStyle is not a pure function, we roll the style only on the first render
|
// getModalStyle is not a pure function, we roll the style only on the first render
|
||||||
const [modalStyle] = useState(getModalStyle);
|
const [modalStyle] = useState(getModalStyle);
|
||||||
const closeButton = (
|
const closeButton = (
|
||||||
<IconButton
|
<GhostStyledIcon
|
||||||
aria-label="close"
|
aria-label="close"
|
||||||
color="inherit"
|
component={CloseIcon}
|
||||||
size="small"
|
sx={{ cursor: "pointer" }}
|
||||||
onClick={e => {
|
onClick={e => {
|
||||||
if (props.onClose) {
|
if (props.onClose) {
|
||||||
props.onClose(e, "escapeKeyDown");
|
props.onClose(e, "escapeKeyDown");
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
/>
|
||||||
<GhostStyledIcon component={CloseIcon} />
|
|
||||||
</IconButton>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
//modal must have a close position. Close position and topLeft or topRight cant be used for the same position.
|
//modal must have a close position. Close position and topLeft or topRight cant be used for the same position.
|
||||||
const topRightPos = closePosition === "right" ? closeButton : topRight;
|
const topRightPos = topRight ? topRight : closeButton;
|
||||||
const topLeftPos = closePosition === "left" ? closeButton : topLeft;
|
const topLeftPos = closePosition === "left" ? closeButton : topLeft;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -113,7 +111,7 @@ const Modal = ({
|
|||||||
{...props}
|
{...props}
|
||||||
minHeight={minHeight}
|
minHeight={minHeight}
|
||||||
maxWidth={maxWidth}
|
maxWidth={maxWidth}
|
||||||
>
|
>
|
||||||
<Paper
|
<Paper
|
||||||
style={modalStyle}
|
style={modalStyle}
|
||||||
className={classes.paper}
|
className={classes.paper}
|
||||||
|
|||||||
@ -64,7 +64,7 @@ const Paper = ({
|
|||||||
{(topLeft || headerText || topRight || headerContent) && (
|
{(topLeft || headerText || topRight || headerContent) && (
|
||||||
<Grid item className="card-header">
|
<Grid item className="card-header">
|
||||||
<Box display="flex" justifyContent="space-between">
|
<Box display="flex" justifyContent="space-between">
|
||||||
{topLeft && <div className="top-left">{topLeft}</div>}
|
{topLeft && <Box className="top-left" display="flex" justifyContent="center" alignItems="center">{topLeft}</Box>}
|
||||||
{headerText && !headerContent && (
|
{headerText && !headerContent && (
|
||||||
<Box display="flex" flexDirection="row" alignItems="center">
|
<Box display="flex" flexDirection="row" alignItems="center">
|
||||||
<Typography fontSize="24px" className="header-text" fontWeight={700} lineHeight="33px">
|
<Typography fontSize="24px" className="header-text" fontWeight={700} lineHeight="33px">
|
||||||
@ -83,7 +83,7 @@ const Paper = ({
|
|||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
{headerContent}
|
{headerContent}
|
||||||
<div className="top-right">{topRight}</div>
|
<Box className="top-right" display="flex" justifyContent="center" alignItems="center">{topRight}</Box>
|
||||||
</Box>
|
</Box>
|
||||||
{subHeader && <Box display="flex">{subHeader}</Box>}
|
{subHeader && <Box display="flex">{subHeader}</Box>}
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@ -44,6 +44,7 @@ const SwapCard = ({
|
|||||||
tokenName,
|
tokenName,
|
||||||
inputWidth,
|
inputWidth,
|
||||||
inputFontSize,
|
inputFontSize,
|
||||||
|
chainTokenName,
|
||||||
maxWidth = "416px",
|
maxWidth = "416px",
|
||||||
...props
|
...props
|
||||||
}) => {
|
}) => {
|
||||||
@ -72,12 +73,26 @@ const SwapCard = ({
|
|||||||
cursor: tokenOnClick ? "pointer" : "default",
|
cursor: tokenOnClick ? "pointer" : "default",
|
||||||
}}
|
}}
|
||||||
borderRadius="6px"
|
borderRadius="6px"
|
||||||
paddingX="9px"
|
paddingX="7px"
|
||||||
paddingY="6.5px"
|
paddingY="2px"
|
||||||
alignItems="center"
|
alignItems="center"
|
||||||
{...onClickProps}
|
{...onClickProps}
|
||||||
>
|
>
|
||||||
{typeof token === "string" ? <Token name={token} sx={{ fontSize: "21px" }} /> : token}
|
{typeof token === "string"
|
||||||
|
? <Token
|
||||||
|
chainTokenName={chainTokenName}
|
||||||
|
name={token}
|
||||||
|
parentSx={{
|
||||||
|
"& svg:nth-of-type(2)": {
|
||||||
|
transform: "scale(0.52)",
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
sx={{
|
||||||
|
transform: "scale(0.65)",
|
||||||
|
transformOrigin: "center"
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
: token}
|
||||||
|
|
||||||
{(typeof token === "string" || tokenName) && (
|
{(typeof token === "string" || tokenName) && (
|
||||||
<Typography fontSize="15px" lineHeight="24px" marginLeft="9px">
|
<Typography fontSize="15px" lineHeight="24px" marginLeft="9px">
|
||||||
|
|||||||
@ -69,27 +69,28 @@ export const parseKnownToken = (name) => {
|
|||||||
return icon;
|
return icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Token = ({ chainTokenName, name, viewBox = "0 0 260 260", fontSize = "large", ...props }) => {
|
const Token = ({ chainTokenName, name, isNative, parentSx, viewBox = "0 0 260 260", fontSize = "large", ...props }) => {
|
||||||
return (
|
return (
|
||||||
<Box display="flex" justifyContent="center" alignItems="center" position="relative">
|
<Box display="flex" justifyContent="center" alignItems="center" position="relative" sx={{ ...parentSx }} >
|
||||||
<StyledSvgIcon
|
<StyledSvgIcon
|
||||||
inheritViewBox
|
inheritViewBox
|
||||||
fontSize={fontSize}
|
fontSize={fontSize}
|
||||||
component={parseKnownToken(name)}
|
component={parseKnownToken(name)}
|
||||||
|
style={{ animation: `spinTokenIcon ${isNative ? 10 : 0}s linear infinite` }}
|
||||||
{...props}
|
{...props}
|
||||||
></StyledSvgIcon>
|
></StyledSvgIcon>
|
||||||
{chainTokenName && (
|
{chainTokenName && (
|
||||||
<StyledSvgIcon
|
<StyledSvgIcon
|
||||||
inheritViewBox
|
inheritViewBox
|
||||||
component={parseKnownToken(chainTokenName)}
|
component={parseKnownToken(chainTokenName)}
|
||||||
style={{
|
sx={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
marginLeft: "70%",
|
bottom: 0,
|
||||||
marginTop: "45%",
|
right: 0,
|
||||||
width: "45%",
|
transform: "translate(15%, 15%) scale(0.8)",
|
||||||
height: "45%",
|
borderRadius: "100%",
|
||||||
|
zIndex: 10,
|
||||||
border: "1px solid #fff",
|
border: "1px solid #fff",
|
||||||
borderRadius: "100%"
|
|
||||||
}}
|
}}
|
||||||
></StyledSvgIcon>
|
></StyledSvgIcon>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
import { Avatar, Box } from "@mui/material";
|
import { Avatar, Box } from "@mui/material";
|
||||||
import Token from "../Token/Token";
|
import Token from "../Token/Token";
|
||||||
|
|
||||||
const TokenStack = ({ tokens, style, images, network, ...props }) => {
|
const TokenStack = ({ chainTokenNames, tokens, style, images, network, ...props }) => {
|
||||||
const imageStyles = {
|
const imageStyles = {
|
||||||
height: "27px",
|
height: "27px",
|
||||||
width: "27px",
|
width: "27px",
|
||||||
...style,
|
...style,
|
||||||
|
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<Box display="flex" flexDirection="row" marginTop={network ? "3px" : "0px"} marginLeft={network ? "3px" : "0px"}>
|
<Box display="flex" flexDirection="row" marginTop={network ? "3px" : "0px"} marginLeft={network ? "3px" : "0px"}>
|
||||||
@ -20,18 +21,25 @@ const TokenStack = ({ tokens, style, images, network, ...props }) => {
|
|||||||
<Avatar
|
<Avatar
|
||||||
src={image}
|
src={image}
|
||||||
style={{
|
style={{
|
||||||
...(i !== 0 ? { marginLeft: -7, zIndex: 1, ...imageStyles } : { zIndex: 1, ...imageStyles }),
|
...(i !== 0 ? { marginLeft: -7, zIndex: 100 - i, ...imageStyles } : { zIndex: 100 - i, ...imageStyles }),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
{tokens?.map((token, i) => (
|
{tokens?.map((token, i) => (
|
||||||
<Token
|
<Token
|
||||||
{...props}
|
|
||||||
key={i}
|
key={i}
|
||||||
name={token}
|
name={token}
|
||||||
style={{
|
style={{
|
||||||
...(i !== 0 ? { marginLeft: -12, zIndex: 1, ...style } : { zIndex: 2, ...style }),
|
...(i !== 0 ? { marginLeft: -12, zIndex: 100 - i, ...style } : { zIndex: 100 - i, ...style }),
|
||||||
}}
|
}}
|
||||||
|
parentSx={{
|
||||||
|
"& svg:nth-of-type(2)": {
|
||||||
|
transform: "translate(22%, 22%) scale(0.6)",
|
||||||
|
zIndex: 100,
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
chainTokenName={chainTokenNames?.at(i)}
|
||||||
|
{...props}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@ -132,7 +132,6 @@ function InitialWalletView({ isWalletOpen, address, chainId, onClose }) {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isWalletOpen) {
|
if (isWalletOpen) {
|
||||||
console.log(`/${chainName.toLowerCase()}/sidebar`)
|
|
||||||
ReactGA.send({ hitType: "pageview", page: `/${chainName.toLowerCase()}/sidebar` });
|
ReactGA.send({ hitType: "pageview", page: `/${chainName.toLowerCase()}/sidebar` });
|
||||||
}
|
}
|
||||||
}, [isWalletOpen, chainName])
|
}, [isWalletOpen, chainName])
|
||||||
@ -143,7 +142,6 @@ function InitialWalletView({ isWalletOpen, address, chainId, onClose }) {
|
|||||||
}
|
}
|
||||||
}, [isWalletOpen, tokens])
|
}, [isWalletOpen, tokens])
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Paper>
|
<Paper>
|
||||||
<Box sx={{ padding: theme.spacing(0, 3), display: "flex", flexDirection: "column", minHeight: "100vh" }}>
|
<Box sx={{ padding: theme.spacing(0, 3), display: "flex", flexDirection: "column", minHeight: "100vh" }}>
|
||||||
|
|||||||
@ -130,6 +130,7 @@ export const Token = (props) => {
|
|||||||
height: "28px",
|
height: "28px",
|
||||||
}}
|
}}
|
||||||
tokens={props.icons}
|
tokens={props.icons}
|
||||||
|
chainTokenNames={props.chainTokenNames}
|
||||||
/>
|
/>
|
||||||
<Typography>{symbol}</Typography>
|
<Typography>{symbol}</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
@ -207,7 +208,7 @@ export const useWallet = (chainId, userAddress) => {
|
|||||||
|
|
||||||
const nativeSymbol = useMemo(() => {
|
const nativeSymbol = useMemo(() => {
|
||||||
return config?.getClient()?.chain?.nativeCurrency?.symbol;
|
return config?.getClient()?.chain?.nativeCurrency?.symbol;
|
||||||
}, [config]);
|
}, [chainId, config]);
|
||||||
|
|
||||||
const { symbol: reserveSymbol } = useTokenSymbol(chainId, "RESERVE");
|
const { symbol: reserveSymbol } = useTokenSymbol(chainId, "RESERVE");
|
||||||
const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO");
|
const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO");
|
||||||
@ -223,7 +224,7 @@ export const useWallet = (chainId, userAddress) => {
|
|||||||
|
|
||||||
if (token0?.at(0) === reserveSymbol) {
|
if (token0?.at(0) === reserveSymbol) {
|
||||||
tokenAddresses = [lpReserveFtsoTokens?.token0, lpReserveFtsoTokens?.token1];
|
tokenAddresses = [lpReserveFtsoTokens?.token0, lpReserveFtsoTokens?.token1];
|
||||||
let tokenNames = [...token0, ...token1];
|
tokenNames = [...token0, ...token1];
|
||||||
}
|
}
|
||||||
|
|
||||||
return { tokenAddresses, tokenNames }
|
return { tokenAddresses, tokenNames }
|
||||||
@ -251,6 +252,7 @@ export const useWallet = (chainId, userAddress) => {
|
|||||||
address: ftsoAddress,
|
address: ftsoAddress,
|
||||||
balance: ftsoBalance,
|
balance: ftsoBalance,
|
||||||
price: ftsoPrice,
|
price: ftsoPrice,
|
||||||
|
chainTokenNames: [nativeSymbol],
|
||||||
icons: ["FTSO"],
|
icons: ["FTSO"],
|
||||||
externalUrl: "https://ghostchain.io/wp-content/uploads/2025/03/eGHST.svg",
|
externalUrl: "https://ghostchain.io/wp-content/uploads/2025/03/eGHST.svg",
|
||||||
refetch: ftsoRefetch,
|
refetch: ftsoRefetch,
|
||||||
@ -261,6 +263,7 @@ export const useWallet = (chainId, userAddress) => {
|
|||||||
balance: ghstBalance,
|
balance: ghstBalance,
|
||||||
price: ghstPrice,
|
price: ghstPrice,
|
||||||
icons: ["GHST"],
|
icons: ["GHST"],
|
||||||
|
chainTokenNames: [nativeSymbol],
|
||||||
externalUrl: "https://ghostchain.io/wp-content/uploads/2025/03/GHST.svg",
|
externalUrl: "https://ghostchain.io/wp-content/uploads/2025/03/GHST.svg",
|
||||||
refetch: ghstRefetch,
|
refetch: ghstRefetch,
|
||||||
},
|
},
|
||||||
@ -271,6 +274,10 @@ export const useWallet = (chainId, userAddress) => {
|
|||||||
balance: lpReserveFtsoBalance,
|
balance: lpReserveFtsoBalance,
|
||||||
price: lpReserveFtsoPrice,
|
price: lpReserveFtsoPrice,
|
||||||
icons: lpReserveFtsoTokenNames?.tokenNames,
|
icons: lpReserveFtsoTokenNames?.tokenNames,
|
||||||
|
chainTokenNames: [
|
||||||
|
lpReserveFtsoTokenNames?.tokenNames?.at(0) !== reserveSymbol && nativeSymbol,
|
||||||
|
lpReserveFtsoTokenNames?.tokenNames?.at(1) !== reserveSymbol && nativeSymbol,
|
||||||
|
],
|
||||||
externalUrl: "https://ghostchain.io/wp-content/uploads/2025/03/uni-v2.svg",
|
externalUrl: "https://ghostchain.io/wp-content/uploads/2025/03/uni-v2.svg",
|
||||||
refetch: lpReserveFtsoRefetch,
|
refetch: lpReserveFtsoRefetch,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,7 @@ export const AVAILABLE_DEXES = {
|
|||||||
name: "Uniswap",
|
name: "Uniswap",
|
||||||
icon: UniswapIcon,
|
icon: UniswapIcon,
|
||||||
viewBox: "0 0 195 230",
|
viewBox: "0 0 195 230",
|
||||||
|
isFork: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[NetworkId.TESTNET_HOODI]: [
|
[NetworkId.TESTNET_HOODI]: [
|
||||||
@ -16,6 +17,7 @@ export const AVAILABLE_DEXES = {
|
|||||||
name: "Uniswap",
|
name: "Uniswap",
|
||||||
icon: UniswapIcon,
|
icon: UniswapIcon,
|
||||||
viewBox: "0 0 195 230",
|
viewBox: "0 0 195 230",
|
||||||
|
isFork: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[NetworkId.TESTNET_MORDOR]: [
|
[NetworkId.TESTNET_MORDOR]: [
|
||||||
@ -23,6 +25,7 @@ export const AVAILABLE_DEXES = {
|
|||||||
name: "Uniswap",
|
name: "Uniswap",
|
||||||
icon: UniswapIcon,
|
icon: UniswapIcon,
|
||||||
viewBox: "0 0 195 230",
|
viewBox: "0 0 195 230",
|
||||||
|
isFork: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
@ -91,6 +91,7 @@ export const BondModal = ({ bond, chainId, address, config, connect }) => {
|
|||||||
if (isNetworkLegacy(chainId)) {
|
if (isNetworkLegacy(chainId)) {
|
||||||
return {
|
return {
|
||||||
address: bond.quoteToken.quoteTokenAddress,
|
address: bond.quoteToken.quoteTokenAddress,
|
||||||
|
chainNames: bond.quoteToken.chainNames,
|
||||||
icons: bond.quoteToken.icons,
|
icons: bond.quoteToken.icons,
|
||||||
name: bond.quoteToken.name,
|
name: bond.quoteToken.name,
|
||||||
}
|
}
|
||||||
@ -112,7 +113,11 @@ export const BondModal = ({ bond, chainId, address, config, connect }) => {
|
|||||||
</Box>
|
</Box>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<TokenStack tokens={preparedQuoteToken.icons} sx={{ fontSize: "27px" }} />
|
<TokenStack
|
||||||
|
chainTokenNames={preparedQuoteToken.chainNames}
|
||||||
|
tokens={preparedQuoteToken.icons}
|
||||||
|
sx={{ fontSize: "27px" }}
|
||||||
|
/>
|
||||||
<Box display="flex" flexDirection="column" ml={1} justifyContent="center" alignItems="center">
|
<Box display="flex" flexDirection="column" ml={1} justifyContent="center" alignItems="center">
|
||||||
<Typography variant="h4" fontWeight={500}>
|
<Typography variant="h4" fontWeight={500}>
|
||||||
{preparedQuoteToken.name}
|
{preparedQuoteToken.name}
|
||||||
|
|||||||
@ -42,6 +42,7 @@ const BondConfirmModal = ({
|
|||||||
isNative,
|
isNative,
|
||||||
bondQuoteTokenName,
|
bondQuoteTokenName,
|
||||||
bondQuoteTokenIcons,
|
bondQuoteTokenIcons,
|
||||||
|
bondQuoteTokenChainNames,
|
||||||
handleConfirmClose
|
handleConfirmClose
|
||||||
}) => {
|
}) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
@ -127,16 +128,16 @@ const BondConfirmModal = ({
|
|||||||
maxWidth="476px"
|
maxWidth="476px"
|
||||||
minHeight="200px"
|
minHeight="200px"
|
||||||
open={isOpen}
|
open={isOpen}
|
||||||
headerContent={
|
headerContent={<Typography variant="h4">{bondQuoteTokenName} Bond</Typography>}
|
||||||
<Box display="flex" flexDirection="row">
|
|
||||||
<TokenStack tokens={bondQuoteTokenIcons} sx={{ fontSize: "27px" }} />
|
|
||||||
<Typography variant="h4" sx={{ marginLeft: "6px" }}>
|
|
||||||
{bondQuoteTokenName}
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
}
|
|
||||||
onClose={!isPending && handleConfirmCloseMaster}
|
onClose={!isPending && handleConfirmCloseMaster}
|
||||||
topLeft={<GhostStyledIcon viewBox="0 0 23 23" component={SettingsIcon} style={{ cursor: "pointer" }} onClick={handleSettingsOpen} />}
|
topRight={
|
||||||
|
<GhostStyledIcon
|
||||||
|
viewBox="0 0 23 23"
|
||||||
|
component={SettingsIcon}
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
onClick={handleSettingsOpen}
|
||||||
|
/>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<>
|
<>
|
||||||
<Box display="flex" flexDirection="row" justifyContent="space-between" alignItems="center">
|
<Box display="flex" flexDirection="row" justifyContent="space-between" alignItems="center">
|
||||||
@ -145,19 +146,58 @@ const BondConfirmModal = ({
|
|||||||
label="Assets to Bond"
|
label="Assets to Bond"
|
||||||
metric={spendAmount}
|
metric={spendAmount}
|
||||||
/>
|
/>
|
||||||
<Box display="flex" flexDirection="row" justifyContent="center">
|
<Box
|
||||||
|
sx={{ background: "" }}
|
||||||
|
height="120px"
|
||||||
|
display="flex"
|
||||||
|
flexDirection="column"
|
||||||
|
justifyContent="center"
|
||||||
|
alignItems="center"
|
||||||
|
>
|
||||||
|
<TokenStack
|
||||||
|
parentSx={{
|
||||||
|
height: "80px",
|
||||||
|
"& svg:nth-of-type(2)": {
|
||||||
|
transform: "translate(50%, -30%)",
|
||||||
|
zIndex: 100,
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
sx={{ transform: "scale(1.65)", }}
|
||||||
|
tokens={bond.quoteToken.icons}
|
||||||
|
chainTokenNames={bond.quoteToken.chainNames}
|
||||||
|
/>
|
||||||
<Typography>{bondQuoteTokenName}</Typography>
|
<Typography>{bondQuoteTokenName}</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
<GhostStyledIcon sx={{ transform: "rotate(-90deg)" }} component={ArrowDropDownIcon} />
|
<GhostStyledIcon sx={{ transform: "rotate(-90deg)" }} component={ArrowDropDownIcon} />
|
||||||
<Box display="flex" flexDirection="column">
|
<Box display="flex" flexDirection="column">
|
||||||
<Metric label="Assets to Receive" metric={receiveAmount} />
|
<Metric label="Assets to Receive" metric={receiveAmount} />
|
||||||
<Box display="flex" flexDirection="row" justifyContent="center">
|
<Box
|
||||||
|
sx={{ background: "" }}
|
||||||
|
height="120px"
|
||||||
|
display="flex"
|
||||||
|
flexDirection="column"
|
||||||
|
justifyContent="center"
|
||||||
|
alignItems="center"
|
||||||
|
gap="0"
|
||||||
|
>
|
||||||
|
<TokenStack
|
||||||
|
parentSx={{
|
||||||
|
height: "80px",
|
||||||
|
"& svg:nth-of-type(2)": {
|
||||||
|
transform: "translate(50%, -30%)",
|
||||||
|
zIndex: 100,
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
sx={{ transform: "scale(1.65)", }}
|
||||||
|
tokens={bond.baseToken.icons}
|
||||||
|
chainTokenNames={bond.baseToken.chainNames}
|
||||||
|
/>
|
||||||
<Typography>{bond.baseToken.name}</Typography>
|
<Typography>{bond.baseToken.name}</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
<Box mt="21px" mb="21px" borderTop={`1px solid ${theme.colors.gray[500]}`}></Box>
|
<Box mt="10px" mb="18px" borderTop={`1px solid ${theme.colors.gray[500]}`}></Box>
|
||||||
<DataRow title="ROI" balance={<BondDiscount discount={bond.discount} textOnly />} />
|
<DataRow title="ROI" balance={<BondDiscount discount={bond.discount} textOnly />} />
|
||||||
<DataRow title="Bond Slippage" balance={<BondSlippage slippage={slippage} textOnly />} />
|
<DataRow title="Bond Slippage" balance={<BondSlippage slippage={slippage} textOnly />} />
|
||||||
<DataRow title="Vesting Term" balance={<BondVesting vesting={bond.vesting} />} />
|
<DataRow title="Vesting Term" balance={<BondVesting vesting={bond.vesting} />} />
|
||||||
|
|||||||
@ -100,12 +100,19 @@ const BondInputArea = ({
|
|||||||
<Box display="flex" flexDirection="column" width="100%" maxWidth="476px">
|
<Box display="flex" flexDirection="column" width="100%" maxWidth="476px">
|
||||||
<Box mb="21px">
|
<Box mb="21px">
|
||||||
<SwapCollection
|
<SwapCollection
|
||||||
|
iconNotNeeded
|
||||||
UpperSwapCard={
|
UpperSwapCard={
|
||||||
<SwapCard
|
<SwapCard
|
||||||
maxWidth="476px"
|
maxWidth="476px"
|
||||||
inputWidth={isVerySmallScreen ? "100px" : isSemiSmallScreen ? "180px" : "250px"}
|
inputWidth={isVerySmallScreen ? "100px" : isSemiSmallScreen ? "180px" : "250px"}
|
||||||
id="from"
|
id="from"
|
||||||
token={<TokenStack tokens={bond.quoteToken.icons} sx={{ fontSize: "21px" }} />}
|
token={
|
||||||
|
<TokenStack
|
||||||
|
chainTokenNames={bond.quoteToken.chainNames}
|
||||||
|
tokens={bond.quoteToken.icons}
|
||||||
|
sx={{ fontSize: "25px", height: "30px" }}
|
||||||
|
/>
|
||||||
|
}
|
||||||
tokenName={preparedQuoteToken.name}
|
tokenName={preparedQuoteToken.name}
|
||||||
info={formatCurrency(balance, formatDecimals, preparedQuoteToken.name)}
|
info={formatCurrency(balance, formatDecimals, preparedQuoteToken.name)}
|
||||||
endString="Max"
|
endString="Max"
|
||||||
@ -119,7 +126,13 @@ const BondInputArea = ({
|
|||||||
maxWidth="476px"
|
maxWidth="476px"
|
||||||
inputWidth={isVerySmallScreen ? "100px" : isSemiSmallScreen ? "180px" : "250px"}
|
inputWidth={isVerySmallScreen ? "100px" : isSemiSmallScreen ? "180px" : "250px"}
|
||||||
id="to"
|
id="to"
|
||||||
token={<TokenStack tokens={bond.baseToken.icons} sx={{ fontSize: "21px" }} />}
|
token={
|
||||||
|
<TokenStack
|
||||||
|
chainTokenNames={bond.baseToken.chainNames}
|
||||||
|
tokens={bond.baseToken.icons}
|
||||||
|
sx={{ fontSize: "25px", height: "30px" }}
|
||||||
|
/>
|
||||||
|
}
|
||||||
tokenName={bond.baseToken.name}
|
tokenName={bond.baseToken.name}
|
||||||
value={amountInBaseToken.toString({ decimals: 9 })}
|
value={amountInBaseToken.toString({ decimals: 9 })}
|
||||||
inputProps={{ "data-testid": "toInput" }}
|
inputProps={{ "data-testid": "toInput" }}
|
||||||
@ -229,6 +242,7 @@ const BondInputArea = ({
|
|||||||
receiveAmount={formatNumber(amountInBaseToken, formatDecimals)}
|
receiveAmount={formatNumber(amountInBaseToken, formatDecimals)}
|
||||||
bondQuoteTokenName={preparedQuoteToken.name}
|
bondQuoteTokenName={preparedQuoteToken.name}
|
||||||
bondQuoteTokenIcons={preparedQuoteToken.icons}
|
bondQuoteTokenIcons={preparedQuoteToken.icons}
|
||||||
|
bondQuoteTokenChainNames={preparedQuoteToken.chainNames}
|
||||||
isNative={preparedQuoteToken.address === undefined}
|
isNative={preparedQuoteToken.address === undefined}
|
||||||
handleSettingsOpen={handleSettingsOpen}
|
handleSettingsOpen={handleSettingsOpen}
|
||||||
isOpen={confirmOpen}
|
isOpen={confirmOpen}
|
||||||
|
|||||||
@ -72,7 +72,7 @@ const BondCard = ({ bond, secondsTo, chainName }) => {
|
|||||||
return (
|
return (
|
||||||
<Box key={bond.id} id={bond.id + `--bond`} mt="32px">
|
<Box key={bond.id} id={bond.id + `--bond`} mt="32px">
|
||||||
<Box display="flex" alignItems="center">
|
<Box display="flex" alignItems="center">
|
||||||
<TokenStack tokens={bond.quoteToken.icons} />
|
<TokenStack chainTokenNames={bond.quoteToken.chainNames} tokens={bond.quoteToken.icons} />
|
||||||
|
|
||||||
<Box display="flex" flexDirection="column" ml="8px">
|
<Box display="flex" flexDirection="column" ml="8px">
|
||||||
<Typography>{bond.quoteToken.name}</Typography>
|
<Typography>{bond.quoteToken.name}</Typography>
|
||||||
@ -237,7 +237,7 @@ const BondRow = ({ bond, secondsTo, chainName }) => {
|
|||||||
|
|
||||||
const TokenIcons = ({ token, chainId, explorer }) => (
|
const TokenIcons = ({ token, chainId, explorer }) => (
|
||||||
<Box display="flex" alignItems="center">
|
<Box display="flex" alignItems="center">
|
||||||
<TokenStack tokens={token.icons} />
|
<TokenStack chainTokenNames={token.chainNames} tokens={token.icons} />
|
||||||
|
|
||||||
<Box display="flex" flexDirection="column" ml="16px">
|
<Box display="flex" flexDirection="column" ml="16px">
|
||||||
<Typography style={{ fontSize: "12px", fontWeight: 600, lineHeight: "18px" }}>{token.name}</Typography>
|
<Typography style={{ fontSize: "12px", fontWeight: 600, lineHeight: "18px" }}>{token.name}</Typography>
|
||||||
|
|||||||
@ -103,7 +103,7 @@ export const ClaimBonds = ({ chainId, address, secondsTo }) => {
|
|||||||
headerContent={
|
headerContent={
|
||||||
<Box display="flex" alignItems="center" flexDirection="row" gap="5px">
|
<Box display="flex" alignItems="center" flexDirection="row" gap="5px">
|
||||||
<Typography variant="h6">
|
<Typography variant="h6">
|
||||||
Your Bonds
|
My Bonds
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
}
|
}
|
||||||
@ -143,7 +143,7 @@ export const ClaimBonds = ({ chainId, address, secondsTo }) => {
|
|||||||
{notes.map((note, index) => (
|
{notes.map((note, index) => (
|
||||||
<Box key={index} mt="32px">
|
<Box key={index} mt="32px">
|
||||||
<Box display="flex" alignItems="center">
|
<Box display="flex" alignItems="center">
|
||||||
<TokenStack tokens={note.quoteToken.icons} />
|
<TokenStack chainTokenNames={note.quoteToken.chainNames} tokens={note.quoteToken.icons} />
|
||||||
<Box ml="8px">
|
<Box ml="8px">
|
||||||
<Typography>{note.quoteToken.name}</Typography>
|
<Typography>{note.quoteToken.name}</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
@ -205,7 +205,7 @@ export const ClaimBonds = ({ chainId, address, secondsTo }) => {
|
|||||||
<TableRow key={index}>
|
<TableRow key={index}>
|
||||||
<TableCell style={{ padding: "8px 0" }}>
|
<TableCell style={{ padding: "8px 0" }}>
|
||||||
<Box display="flex" alignItems="center">
|
<Box display="flex" alignItems="center">
|
||||||
<TokenStack tokens={note.quoteToken.icons} />
|
<TokenStack chainTokenNames={note.quoteToken.chainNames} tokens={note.quoteToken.icons} />
|
||||||
<Box display="flex" flexDirection="column" ml="16px">
|
<Box display="flex" flexDirection="column" ml="16px">
|
||||||
<Typography>{note.quoteToken.name}</Typography>
|
<Typography>{note.quoteToken.name}</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@ -5,7 +5,8 @@ import { getBlockNumber } from "@wagmi/core";
|
|||||||
import { useConfig } from "wagmi";
|
import { useConfig } from "wagmi";
|
||||||
import { ss58Decode } from "@polkadot-labs/hdkd-helpers";
|
import { ss58Decode } from "@polkadot-labs/hdkd-helpers";
|
||||||
import { toHex } from "@polkadot-api/utils";
|
import { toHex } from "@polkadot-api/utils";
|
||||||
import CheckCircleIcon from '@mui/icons-material/CheckCircle';
|
import CheckIcon from '@mui/icons-material/CheckCircle';
|
||||||
|
import CancelIcon from '@mui/icons-material/Cancel';
|
||||||
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
|
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
|
||||||
import { CheckBoxOutlineBlank, CheckBoxOutlined } from "@mui/icons-material";
|
import { CheckBoxOutlineBlank, CheckBoxOutlined } from "@mui/icons-material";
|
||||||
|
|
||||||
@ -165,6 +166,7 @@ const BridgeView = ({
|
|||||||
incomingFee
|
incomingFee
|
||||||
}) => {
|
}) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
const [inputFocused, setInputFocused] = useState(false);
|
||||||
|
|
||||||
const config = useConfig();
|
const config = useConfig();
|
||||||
const { gatekeeperAddress } = useGatekeeperAddress(chainId);
|
const { gatekeeperAddress } = useGatekeeperAddress(chainId);
|
||||||
@ -189,13 +191,17 @@ const BridgeView = ({
|
|||||||
<SwapCard
|
<SwapCard
|
||||||
id={`bridge-token-receiver`}
|
id={`bridge-token-receiver`}
|
||||||
inputWidth={"100%"}
|
inputWidth={"100%"}
|
||||||
value={convertedReceiver ? shorten(receiver, 15, -10) : receiver}
|
onBlur={() => setInputFocused(true)}
|
||||||
onChange={event => setReceiver(convertedReceiver ? "" : event.currentTarget.value)}
|
onFocus={() => setInputFocused(false)}
|
||||||
|
onChange={event => setReceiver(event.currentTarget.value)}
|
||||||
|
placeholder={convertedReceiver ? shorten(receiver, 15, -10) : "GHOST address (sf prefixed)"}
|
||||||
|
value={convertedReceiver ? "" : receiver}
|
||||||
inputProps={{ "data-testid": "fromInput" }}
|
inputProps={{ "data-testid": "fromInput" }}
|
||||||
placeholder="GHOST address (sf prefixed)"
|
|
||||||
endString={convertedReceiver
|
endString={convertedReceiver
|
||||||
? <GhostStyledIcon color="success" viewBox="0 0 25 25" component={CheckCircleIcon} />
|
? <GhostStyledIcon color="success" viewBox="0 0 25 25" component={CheckIcon} />
|
||||||
: undefined
|
: inputFocused && receiver !== ""
|
||||||
|
? <GhostStyledIcon color="error" viewBox="0 0 25 25" component={CancelIcon} />
|
||||||
|
: undefined
|
||||||
}
|
}
|
||||||
type="text"
|
type="text"
|
||||||
maxWidth="100%"
|
maxWidth="100%"
|
||||||
@ -274,7 +280,7 @@ const WelcomeView = ({
|
|||||||
<>
|
<>
|
||||||
<Typography>{warmupPeriod <= 0
|
<Typography>{warmupPeriod <= 0
|
||||||
? `You have succesfully warmed-up your ${isStakingOpened ? " " : "bonded "}${ftsoSymbol} ${isStakingOpened ? "(3, 3)" : "(1, 1)"} Staked at:`
|
? `You have succesfully warmed-up your ${isStakingOpened ? " " : "bonded "}${ftsoSymbol} ${isStakingOpened ? "(3, 3)" : "(1, 1)"} Staked at:`
|
||||||
: `${isStakingOpened ? "Stake" : "Bond"} is in warm-up${isStakingOpened ? "" : ", which extends with each purchase"}. Your ${ftsoSymbol} ${isStakingOpened ? "(3, 3)" : "(1, 1)"} is Staked at:`
|
: `${isStakingOpened ? "Stake" : "Bond"} is in warm-up${isStakingOpened ? "" : ", which extends with each purchase"}. Your ${ftsoSymbol} (3, 3) Staked at:`
|
||||||
}</Typography>
|
}</Typography>
|
||||||
|
|
||||||
<Box display="flex" justifyContent="center">
|
<Box display="flex" justifyContent="center">
|
||||||
@ -421,7 +427,7 @@ const ConfirmStep = ({
|
|||||||
<Box display="flex" flexDirection="column" justifyContent="space-between" alignItems="center" gap="10px">
|
<Box display="flex" flexDirection="column" justifyContent="space-between" alignItems="center" gap="10px">
|
||||||
<Metric label="To Receive" metric={formatNumber(receivedEstimation, 5)} />
|
<Metric label="To Receive" metric={formatNumber(receivedEstimation, 5)} />
|
||||||
<Box width="100%" display="flex" flexDirection="column" justifyContent="center" alignItems="center">
|
<Box width="100%" display="flex" flexDirection="column" justifyContent="center" alignItems="center">
|
||||||
<Token name={"GHST"} sx={{ fontSize: "55px" }} />
|
<Token isNative name={"GHST"} sx={{ fontSize: "55px" }} />
|
||||||
<Typography>{ghstSymbol}</Typography>
|
<Typography>{ghstSymbol}</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
@ -493,7 +499,7 @@ const ConfirmStep = ({
|
|||||||
disabled={isPending || !acknowledgeWalletCustody || !acknowledgeBridgingRisk}
|
disabled={isPending || !acknowledgeWalletCustody || !acknowledgeBridgingRisk}
|
||||||
fullWidth
|
fullWidth
|
||||||
>
|
>
|
||||||
{isPending ? "Confirming..." : "I Confirm"}
|
{isPending ? "Confirming..." : "Confirm"}
|
||||||
</PrimaryButton>
|
</PrimaryButton>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -28,7 +28,8 @@ import SwapCollection from "../../components/Swap/SwapCollection";
|
|||||||
import { ghost } from "../../hooks/staking";
|
import { ghost } from "../../hooks/staking";
|
||||||
import { useBalance } from "../../hooks/tokens";
|
import { useBalance } from "../../hooks/tokens";
|
||||||
|
|
||||||
import CheckIcon from '@mui/icons-material/Check';
|
import CheckIcon from '@mui/icons-material/CheckCircle';
|
||||||
|
import CancelIcon from '@mui/icons-material/Cancel';
|
||||||
import HourglassBottomIcon from '@mui/icons-material/HourglassBottom';
|
import HourglassBottomIcon from '@mui/icons-material/HourglassBottom';
|
||||||
import CheckCircleIcon from '@mui/icons-material/CheckCircle';
|
import CheckCircleIcon from '@mui/icons-material/CheckCircle';
|
||||||
|
|
||||||
@ -58,6 +59,7 @@ export const BridgeCardAction = ({
|
|||||||
storeTransactionHash,
|
storeTransactionHash,
|
||||||
}) => {
|
}) => {
|
||||||
const [isPending, setIsPending] = useState(false);
|
const [isPending, setIsPending] = useState(false);
|
||||||
|
const [inputFocused, setInputFocused] = useState(false);
|
||||||
const [receiver, setReceiver] = useState("");
|
const [receiver, setReceiver] = useState("");
|
||||||
const [convertedReceiver, setConvertedReceiver] = useState(undefined);
|
const [convertedReceiver, setConvertedReceiver] = useState(undefined);
|
||||||
const [amount, setAmount] = useState("");
|
const [amount, setAmount] = useState("");
|
||||||
@ -166,13 +168,17 @@ export const BridgeCardAction = ({
|
|||||||
UpperSwapCard={<SwapCard
|
UpperSwapCard={<SwapCard
|
||||||
id={`bridge-token-receiver`}
|
id={`bridge-token-receiver`}
|
||||||
inputWidth={"100%"}
|
inputWidth={"100%"}
|
||||||
value={convertedReceiver ? sliceString(receiver, 15, -10) : receiver}
|
value={convertedReceiver ? "" : receiver}
|
||||||
onChange={event => setReceiver(convertedReceiver ? "" : event.currentTarget.value)}
|
onBlur={() => setInputFocused(true)}
|
||||||
|
onFocus={() => setInputFocused(false)}
|
||||||
|
onChange={event => setReceiver(event.currentTarget.value)}
|
||||||
inputProps={{ "data-testid": "fromInput" }}
|
inputProps={{ "data-testid": "fromInput" }}
|
||||||
placeholder="GHOST address (sf prefixed)"
|
placeholder={convertedReceiver ? sliceString(receiver, 15, -10) : "GHOST address (sf prefixed)"}
|
||||||
endString={convertedReceiver
|
endString={convertedReceiver
|
||||||
? <GhostStyledIcon color="success" viewBox="0 0 25 25" component={CheckCircleIcon} />
|
? <GhostStyledIcon color="success" viewBox="0 0 25 25" component={CheckCircleIcon} />
|
||||||
: undefined
|
: inputFocused && receiver !== ""
|
||||||
|
? <GhostStyledIcon color="error" viewBox="0 0 25 25" component={CancelIcon} />
|
||||||
|
: undefined
|
||||||
}
|
}
|
||||||
type="text"
|
type="text"
|
||||||
maxWidth="100%"
|
maxWidth="100%"
|
||||||
|
|||||||
@ -33,11 +33,23 @@ const RouteHop = ({ theme, token, chainTokenName, arrowNeeded }) => {
|
|||||||
sx={{ backgroundColor: theme.colors.gray[600] }}
|
sx={{ backgroundColor: theme.colors.gray[600] }}
|
||||||
borderRadius="6px"
|
borderRadius="6px"
|
||||||
paddingX="9px"
|
paddingX="9px"
|
||||||
paddingY="6.5px"
|
paddingY="2px"
|
||||||
alignItems="center"
|
alignItems="center"
|
||||||
>
|
>
|
||||||
<Token chainTokenName={chainTokenName} name={token} sx={{ fontSize: "21px" }} />
|
<Token
|
||||||
<Typography fontSize="15px" lineHeight="24px" marginLeft="9px">
|
chainTokenName={chainTokenName}
|
||||||
|
name={token}
|
||||||
|
parentSx={{
|
||||||
|
"& svg:nth-of-type(2)": {
|
||||||
|
transform: "scale(0.52)",
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
sx={{
|
||||||
|
transform: "scale(0.65)",
|
||||||
|
transformOrigin: "center"
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Typography fontSize="15px" lineHeight="24px" marginLeft="5px">
|
||||||
{token}
|
{token}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@ -32,6 +32,7 @@ import {
|
|||||||
EMPTY_ADDRESS,
|
EMPTY_ADDRESS,
|
||||||
WETH_ADDRESSES,
|
WETH_ADDRESSES,
|
||||||
} from "../../constants/addresses";
|
} from "../../constants/addresses";
|
||||||
|
import { AVAILABLE_DEXES } from "../../constants/dexes";
|
||||||
import { useLocalStorage } from "../../hooks/localstorage";
|
import { useLocalStorage } from "../../hooks/localstorage";
|
||||||
import { useTokenSymbol } from "../../hooks/tokens";
|
import { useTokenSymbol } from "../../hooks/tokens";
|
||||||
import { getTokenAddress } from "../../hooks/helpers";
|
import { getTokenAddress } from "../../hooks/helpers";
|
||||||
@ -184,6 +185,13 @@ const Dex = ({ chainId, address, connect, config }) => {
|
|||||||
setSearchParams(newQueryParameters);
|
setSearchParams(newQueryParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isDexFork = useMemo(() => {
|
||||||
|
const dexInfo = AVAILABLE_DEXES[chainId]?.find(elem =>
|
||||||
|
elem.name.toLowerCase() == pathname.name.toLowerCase()
|
||||||
|
)
|
||||||
|
return dexInfo ? dexInfo.isFork : false;
|
||||||
|
}, [chainId, pathname])
|
||||||
|
|
||||||
const setSlippageInner = useCallback((value) => {
|
const setSlippageInner = useCallback((value) => {
|
||||||
const maybeValue = parseFloat(value);
|
const maybeValue = parseFloat(value);
|
||||||
if (!maybeValue || parseFloat(value) <= 100) {
|
if (!maybeValue || parseFloat(value) <= 100) {
|
||||||
@ -242,7 +250,7 @@ const Dex = ({ chainId, address, connect, config }) => {
|
|||||||
|
|
||||||
<PageTitle
|
<PageTitle
|
||||||
name="DEX Swap"
|
name="DEX Swap"
|
||||||
subtitle={`(3, 3) Swap ${chainSymbol} for ${ftsoSymbol} and ${ftsoSymbol}-${chainSymbol} LP powered by ${pathname.name.charAt(0).toUpperCase() + pathname.name.slice(1).toLowerCase()} V2`}
|
subtitle={`(3, 3) Swap ${chainSymbol} for ${ftsoSymbol} and ${ftsoSymbol}-${chainSymbol} LP powered by ${pathname.name.charAt(0).toUpperCase() + pathname.name.slice(1).toLowerCase()} V2${isDexFork ? " Fork" : ""}`}
|
||||||
/>
|
/>
|
||||||
<Container
|
<Container
|
||||||
style={{
|
style={{
|
||||||
@ -397,6 +405,7 @@ const Dex = ({ chainId, address, connect, config }) => {
|
|||||||
<Box height="350px">
|
<Box height="350px">
|
||||||
{isSwap ?
|
{isSwap ?
|
||||||
<SwapContainer
|
<SwapContainer
|
||||||
|
chainSymbol={chainSymbol}
|
||||||
tokenNameTop={tokenNameTop}
|
tokenNameTop={tokenNameTop}
|
||||||
tokenNameBottom={tokenNameBottom}
|
tokenNameBottom={tokenNameBottom}
|
||||||
onCardsSwap={onCardsSwap}
|
onCardsSwap={onCardsSwap}
|
||||||
@ -416,6 +425,7 @@ const Dex = ({ chainId, address, connect, config }) => {
|
|||||||
/>
|
/>
|
||||||
:
|
:
|
||||||
<PoolContainer
|
<PoolContainer
|
||||||
|
chainSymbol={chainSymbol}
|
||||||
tokenNameTop={tokenNameTop}
|
tokenNameTop={tokenNameTop}
|
||||||
tokenNameBottom={tokenNameBottom}
|
tokenNameBottom={tokenNameBottom}
|
||||||
onCardsSwap={onCardsSwap}
|
onCardsSwap={onCardsSwap}
|
||||||
|
|||||||
@ -20,6 +20,7 @@ import {
|
|||||||
} from "../../hooks/uniswapv2";
|
} from "../../hooks/uniswapv2";
|
||||||
|
|
||||||
const PoolContainer = ({
|
const PoolContainer = ({
|
||||||
|
chainSymbol,
|
||||||
tokenNameTop,
|
tokenNameTop,
|
||||||
tokenNameBottom,
|
tokenNameBottom,
|
||||||
onCardsSwap,
|
onCardsSwap,
|
||||||
@ -219,7 +220,8 @@ const PoolContainer = ({
|
|||||||
UpperSwapCard={
|
UpperSwapCard={
|
||||||
<SwapCard
|
<SwapCard
|
||||||
id="from"
|
id="from"
|
||||||
token={<TokenStack tokens={[tokenNameTop]} sx={{ fontSize: "21px" }} />}
|
token={tokenNameTop}
|
||||||
|
chainTokenName={tokenNameTop !== chainSymbol && chainSymbol}
|
||||||
tokenName={tokenNameTop}
|
tokenName={tokenNameTop}
|
||||||
info={(!isSmallScreen ? "Balance: " : "") + formatCurrency(balanceTop, formatDecimals, tokenNameTop)}
|
info={(!isSmallScreen ? "Balance: " : "") + formatCurrency(balanceTop, formatDecimals, tokenNameTop)}
|
||||||
endString="Max"
|
endString="Max"
|
||||||
@ -233,7 +235,8 @@ const PoolContainer = ({
|
|||||||
LowerSwapCard={
|
LowerSwapCard={
|
||||||
<SwapCard
|
<SwapCard
|
||||||
id="to"
|
id="to"
|
||||||
token={<TokenStack tokens={[tokenNameBottom]} sx={{ fontSize: "21px" }} />}
|
token={tokenNameBottom}
|
||||||
|
chainTokenName={tokenNameBottom !== chainSymbol && chainSymbol}
|
||||||
tokenName={tokenNameBottom}
|
tokenName={tokenNameBottom}
|
||||||
value={amountBottom}
|
value={amountBottom}
|
||||||
onChange={event => emptyPool ? setAmountBottom(event.currentTarget.value) : {}}
|
onChange={event => emptyPool ? setAmountBottom(event.currentTarget.value) : {}}
|
||||||
|
|||||||
@ -25,6 +25,7 @@ import {
|
|||||||
import { EMPTY_ADDRESS } from "../../constants/addresses";
|
import { EMPTY_ADDRESS } from "../../constants/addresses";
|
||||||
|
|
||||||
const SwapContainer = ({
|
const SwapContainer = ({
|
||||||
|
chainSymbol,
|
||||||
tokenNameTop,
|
tokenNameTop,
|
||||||
tokenNameBottom,
|
tokenNameBottom,
|
||||||
address,
|
address,
|
||||||
@ -212,7 +213,8 @@ const SwapContainer = ({
|
|||||||
<SwapCard
|
<SwapCard
|
||||||
maxWidth="356px"
|
maxWidth="356px"
|
||||||
id="from"
|
id="from"
|
||||||
token={<TokenStack tokens={[tokenNameTop]} sx={{ fontSize: "21px" }} />}
|
token={tokenNameTop}
|
||||||
|
chainTokenName={tokenNameTop !== chainSymbol && chainSymbol}
|
||||||
tokenName={tokenNameTop}
|
tokenName={tokenNameTop}
|
||||||
info={
|
info={
|
||||||
(!isSmallScreen ? "Balance: " : "") +
|
(!isSmallScreen ? "Balance: " : "") +
|
||||||
@ -230,8 +232,8 @@ const SwapContainer = ({
|
|||||||
<SwapCard
|
<SwapCard
|
||||||
maxWidth="356px"
|
maxWidth="356px"
|
||||||
id="to"
|
id="to"
|
||||||
token={<TokenStack tokens={[tokenNameBottom]} sx={{ fontSize: "21px" }} />}
|
token={tokenNameBottom}
|
||||||
tokenName={tokenNameBottom}
|
chainTokenName={tokenNameBottom !== chainSymbol && chainSymbol}
|
||||||
value={amountBottom}
|
value={amountBottom}
|
||||||
inputProps={{ "data-testid": "toInput" }}
|
inputProps={{ "data-testid": "toInput" }}
|
||||||
tokenOnClick={() => setBottomTokenListOpen(true)}
|
tokenOnClick={() => setBottomTokenListOpen(true)}
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import { isAddress, getAddress } from "@ethersproject/address";
|
|||||||
|
|
||||||
import Modal from "../../components/Modal/Modal";
|
import Modal from "../../components/Modal/Modal";
|
||||||
import SwapCard from "../../components/Swap/SwapCard";
|
import SwapCard from "../../components/Swap/SwapCard";
|
||||||
import TokenStack from "../../components/TokenStack/TokenStack";
|
import Token from "../../components/Token/Token";
|
||||||
|
|
||||||
import { DecimalBigNumber } from "../../helpers/DecimalBigNumber";
|
import { DecimalBigNumber } from "../../helpers/DecimalBigNumber";
|
||||||
import { formatNumber } from "../../helpers/";
|
import { formatNumber } from "../../helpers/";
|
||||||
@ -65,26 +65,24 @@ const TokenModal = ({ chainId, account, chainSymbol, listOpen, setListOpen, setT
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
name: chainSymbol,
|
name: chainSymbol,
|
||||||
icons: [chainSymbol],
|
|
||||||
balance: nativeBalance,
|
balance: nativeBalance,
|
||||||
address: EMPTY_ADDRESS,
|
address: EMPTY_ADDRESS,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: reserveSymbol,
|
name: reserveSymbol,
|
||||||
icons: [chainSymbol],
|
|
||||||
balance: reserveBalance,
|
balance: reserveBalance,
|
||||||
address: RESERVE_ADDRESSES[chainId]
|
address: RESERVE_ADDRESSES[chainId]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: ftsoSymbol,
|
name: ftsoSymbol,
|
||||||
icons: ["FTSO"],
|
|
||||||
balance: ftsoBalance,
|
balance: ftsoBalance,
|
||||||
|
chainTokenName: chainSymbol,
|
||||||
address: FTSO_ADDRESSES[chainId]
|
address: FTSO_ADDRESSES[chainId]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: ghstSymbol,
|
name: ghstSymbol,
|
||||||
icons: ["GHST"],
|
|
||||||
balance: ghstBalance,
|
balance: ghstBalance,
|
||||||
|
chainTokenName: chainSymbol,
|
||||||
address: GHST_ADDRESSES[chainId]
|
address: GHST_ADDRESSES[chainId]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -105,7 +103,7 @@ const TokenModal = ({ chainId, account, chainSymbol, listOpen, setListOpen, setT
|
|||||||
maxWidth="476px"
|
maxWidth="476px"
|
||||||
minHeight="200px"
|
minHeight="200px"
|
||||||
open={listOpen}
|
open={listOpen}
|
||||||
headerText={"Select a token"}
|
headerText={"Select a Token"}
|
||||||
onClose={() => setListOpen(false)}
|
onClose={() => setListOpen(false)}
|
||||||
>
|
>
|
||||||
<SwapCard
|
<SwapCard
|
||||||
@ -132,10 +130,18 @@ const TokenModal = ({ chainId, account, chainSymbol, listOpen, setListOpen, setT
|
|||||||
return (
|
return (
|
||||||
<TableRow onClick={() => setUsedAddress(token)} hover key={index} id={index + `--token`} data-testid={index + `--token`}>
|
<TableRow onClick={() => setUsedAddress(token)} hover key={index} id={index + `--token`} data-testid={index + `--token`}>
|
||||||
<TableCell style={{ padding: "8px 0" }}>
|
<TableCell style={{ padding: "8px 0" }}>
|
||||||
<TokenStack style={{ width: "32px", height: "32px" }} tokens={token.icons} />
|
<Token
|
||||||
|
chainTokenName={token.chainTokenName}
|
||||||
|
name={token.name}
|
||||||
|
parentSx={{
|
||||||
|
"& svg:nth-of-type(2)": {
|
||||||
|
transform: "translate(-5%, 10%) scale(0.8)",
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
<TableCell style={{ padding: "8px 0", height: "32px" }}>
|
<TableCell style={{ padding: "8px", height: "32px" }}>
|
||||||
<Typography>{token.name}</Typography>
|
<Typography>{token.name}</Typography>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
|
|||||||
@ -110,8 +110,6 @@ const ProposalDetails = ({ chainId, address, connect, config }) => {
|
|||||||
const { pastTotalSupply: totalSupply } = usePastTotalSupply(chainId, "GHST", proposalSnapshot);
|
const { pastTotalSupply: totalSupply } = usePastTotalSupply(chainId, "GHST", proposalSnapshot);
|
||||||
const { pastVotes } = usePastVotes(chainId, "GHST", proposalSnapshot, address);
|
const { pastVotes } = usePastVotes(chainId, "GHST", proposalSnapshot, address);
|
||||||
|
|
||||||
console.log(location.pathname)
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
ReactGA.send({ hitType: "pageview", page: `${chainId}/governance/${id}` });
|
ReactGA.send({ hitType: "pageview", page: `${chainId}/governance/${id}` });
|
||||||
}, []);
|
}, []);
|
||||||
@ -239,10 +237,10 @@ const ProposalDetails = ({ chainId, address, connect, config }) => {
|
|||||||
<Box display="flex" flexDirection="column">
|
<Box display="flex" flexDirection="column">
|
||||||
<Box display="flex" justifyContent="space-between">
|
<Box display="flex" justifyContent="space-between">
|
||||||
<Typography sx={{ textShadow: "0 0 black", fontWeight: 600 }} variant="body1" color={theme.colors.feedback.success}>
|
<Typography sx={{ textShadow: "0 0 black", fontWeight: 600 }} variant="body1" color={theme.colors.feedback.success}>
|
||||||
For: {formatNumber(forVotes.toString(), 2)} ({formatNumber(forPercentage?.toString(), 1)}%)
|
For: {formatNumber(forVotes.toString(), 2)} ({formatNumber(forPercentage?.toString(), 2)}%)
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography sx={{ textShadow: "0 0 black", fontWeight: 600 }} variant="body1" color={theme.colors.feedback.error}>
|
<Typography sx={{ textShadow: "0 0 black", fontWeight: 600 }} variant="body1" color={theme.colors.feedback.error}>
|
||||||
Against: {formatNumber(againstVotes.toString(), 2)} ({formatNumber(againstPercentage?.toString(), 1)}%)
|
Against: {formatNumber(againstVotes.toString(), 2)} ({formatNumber(againstPercentage?.toString(), 2)}%)
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
<LinearProgressBar
|
<LinearProgressBar
|
||||||
@ -263,7 +261,7 @@ const ProposalDetails = ({ chainId, address, connect, config }) => {
|
|||||||
</Box>
|
</Box>
|
||||||
<Box display="flex" justifyContent="space-between">
|
<Box display="flex" justifyContent="space-between">
|
||||||
<Typography>Locked</Typography>
|
<Typography>Locked</Typography>
|
||||||
<Typography>{formatCurrency(proposalLocked, 4, ghstSymbol)}</Typography>
|
<Typography>{formatCurrency(proposalLocked, 5, ghstSymbol)}</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<hr width="100%" />
|
<hr width="100%" />
|
||||||
@ -273,7 +271,7 @@ const ProposalDetails = ({ chainId, address, connect, config }) => {
|
|||||||
<Typography>Quorum</Typography>
|
<Typography>Quorum</Typography>
|
||||||
<InfoTooltip message={`Minimum $${ghstSymbol} turnout required for the proposal to become valid, as percentage of the total $${ghstSymbol} supply at the time when proposal was created`} />
|
<InfoTooltip message={`Minimum $${ghstSymbol} turnout required for the proposal to become valid, as percentage of the total $${ghstSymbol} supply at the time when proposal was created`} />
|
||||||
</Box>
|
</Box>
|
||||||
<Typography>{formatNumber(proposalQuorum.toString(), 4)} ({formatNumber(quorumPercentage, 1)}%)</Typography>
|
<Typography>{formatNumber(proposalQuorum.toString(), 5)} ({formatNumber(quorumPercentage, 2)}%)</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box display="flex" justifyContent="space-between">
|
<Box display="flex" justifyContent="space-between">
|
||||||
@ -281,7 +279,7 @@ const ProposalDetails = ({ chainId, address, connect, config }) => {
|
|||||||
<Typography>Total</Typography>
|
<Typography>Total</Typography>
|
||||||
<InfoTooltip message={`Total votes for the proposal, as percentage of the total $${ghstSymbol} supply at the time when proposal was created`}/>
|
<InfoTooltip message={`Total votes for the proposal, as percentage of the total $${ghstSymbol} supply at the time when proposal was created`}/>
|
||||||
</Box>
|
</Box>
|
||||||
<Typography>{formatNumber(totalSupply.toString(), 4)} ({formatNumber(votePercentage, 1)}%)</Typography>
|
<Typography>{formatNumber(totalSupply.toString(), 5)} ({formatNumber(votePercentage, 2)}%)</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box display="flex" justifyContent="space-between">
|
<Box display="flex" justifyContent="space-between">
|
||||||
@ -289,7 +287,7 @@ const ProposalDetails = ({ chainId, address, connect, config }) => {
|
|||||||
<Typography>Votes</Typography>
|
<Typography>Votes</Typography>
|
||||||
<InfoTooltip message={`Your voting power, as percentage of total $${ghstSymbol} at the time when proposal was created`} />
|
<InfoTooltip message={`Your voting power, as percentage of total $${ghstSymbol} at the time when proposal was created`} />
|
||||||
</Box>
|
</Box>
|
||||||
<Typography>{formatNumber(pastVotes.toString(), 4)} ({formatNumber(voteWeightPercentage, 1)}%)</Typography>
|
<Typography>{formatNumber(pastVotes.toString(), 5)} ({formatNumber(voteWeightPercentage, 2)}%)</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
|||||||
@ -81,7 +81,7 @@ export const parseFunctionCalldata = ({
|
|||||||
case allPossibleFunctions[1].value:
|
case allPossibleFunctions[1].value:
|
||||||
return <SetAdjustmentParsed key={index} {...props} />;
|
return <SetAdjustmentParsed key={index} {...props} />;
|
||||||
case allPossibleFunctions[2].value:
|
case allPossibleFunctions[2].value:
|
||||||
return <CreateBondParsed {...props} />;
|
return <CreateBondParsed key={index} {...props} />;
|
||||||
case allPossibleFunctions[3].value:
|
case allPossibleFunctions[3].value:
|
||||||
return <SetProposalThresholdParsed key={index} {...props} />;
|
return <SetProposalThresholdParsed key={index} {...props} />;
|
||||||
case allPossibleFunctions[4].value:
|
case allPossibleFunctions[4].value:
|
||||||
@ -288,7 +288,7 @@ export const ParsedCell = (props) => {
|
|||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
<TableCell align="center" style={{ padding: "8px 0" }}>
|
<TableCell align="center" style={{ padding: "8px 0" }}>
|
||||||
<Typography>{formatCurrency(props.value, 4, props.nativeCoin)}</Typography>
|
<Typography>{formatCurrency(props.value, 5, props.nativeCoin)}</Typography>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
<TableCell>
|
<TableCell>
|
||||||
@ -330,7 +330,7 @@ export const ParsedCell = (props) => {
|
|||||||
<Box display="flex" justifyContent="space-between">
|
<Box display="flex" justifyContent="space-between">
|
||||||
<Typography>Value</Typography>
|
<Typography>Value</Typography>
|
||||||
<Link onClick={handleCalldataCopy} target="_blank" rel="noopener noreferrer">
|
<Link onClick={handleCalldataCopy} target="_blank" rel="noopener noreferrer">
|
||||||
<Typography>{formatCurrency(props.value, 4, props.nativeCoin)}</Typography>
|
<Typography>{formatCurrency(props.value, 5, props.nativeCoin)}</Typography>
|
||||||
</Link>
|
</Link>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import Paper from "../../components/Paper/Paper";
|
|||||||
import TokenStack from "../../components/TokenStack/TokenStack";
|
import TokenStack from "../../components/TokenStack/TokenStack";
|
||||||
import { useTokenSymbol } from "../../hooks/tokens";
|
import { useTokenSymbol } from "../../hooks/tokens";
|
||||||
|
|
||||||
const Stake = ({ chainId, address, isOpened, closeModal, connect }) => {
|
const Stake = ({ chainId, chainSymbol, address, isOpened, closeModal, connect }) => {
|
||||||
const [action, setAction] = useState("STAKE");
|
const [action, setAction] = useState("STAKE");
|
||||||
const [settingsModalOpen, setSettingsModalOpen] = useState(false);
|
const [settingsModalOpen, setSettingsModalOpen] = useState(false);
|
||||||
|
|
||||||
@ -31,13 +31,13 @@ const Stake = ({ chainId, address, isOpened, closeModal, connect }) => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case (upperToken === ftsoSymbol && bottomToken === ghstSymbol):
|
case (upperToken === ftsoSymbol && bottomToken === ghstSymbol):
|
||||||
setAction("STAKE")
|
setAction("Stake")
|
||||||
break;
|
break;
|
||||||
case (upperToken === ghstSymbol && bottomToken === ftsoSymbol):
|
case (upperToken === ghstSymbol && bottomToken === ftsoSymbol):
|
||||||
setAction("UNSTAKE")
|
setAction("Unstake")
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
setAction("STAKE")
|
setAction("Stake")
|
||||||
}
|
}
|
||||||
}, [ftsoSymbol, ghstSymbol, upperToken, bottomToken])
|
}, [ftsoSymbol, ghstSymbol, upperToken, bottomToken])
|
||||||
|
|
||||||
@ -46,10 +46,10 @@ const Stake = ({ chainId, address, isOpened, closeModal, connect }) => {
|
|||||||
headerContent={
|
headerContent={
|
||||||
<Box display="flex" justifyContent="center" alignItems="center" gap="15px">
|
<Box display="flex" justifyContent="center" alignItems="center" gap="15px">
|
||||||
<Typography variant="h4">{action}</Typography>
|
<Typography variant="h4">{action}</Typography>
|
||||||
<TokenStack tokens={[upperToken, bottomToken]} />
|
<TokenStack tokens={[upperToken, bottomToken, chainSymbol]} />
|
||||||
</Box>
|
</Box>
|
||||||
}
|
}
|
||||||
topLeft={
|
topRight={
|
||||||
<GhostStyledIcon
|
<GhostStyledIcon
|
||||||
viewBox="0 0 23 23"
|
viewBox="0 0 23 23"
|
||||||
component={SettingsIcon}
|
component={SettingsIcon}
|
||||||
@ -64,6 +64,7 @@ const Stake = ({ chainId, address, isOpened, closeModal, connect }) => {
|
|||||||
>
|
>
|
||||||
<Box display="flex" alignItems="center" justifyContent="center" flexDirection="column">
|
<Box display="flex" alignItems="center" justifyContent="center" flexDirection="column">
|
||||||
<StakeArea
|
<StakeArea
|
||||||
|
chainSymbol={chainSymbol}
|
||||||
settingsModalOpen={settingsModalOpen}
|
settingsModalOpen={settingsModalOpen}
|
||||||
closeSettingModal={() => setSettingsModalOpenInner(false)}
|
closeSettingModal={() => setSettingsModalOpenInner(false)}
|
||||||
upperToken={upperToken}
|
upperToken={upperToken}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Dispatch, SetStateAction, useState, useEffect } from "react";
|
import { Dispatch, SetStateAction, useState, useEffect, useMemo } from "react";
|
||||||
import { Box, Container, Grid, Divider, Typography, useMediaQuery, useTheme } from "@mui/material";
|
import { Box, Container, Grid, Divider, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||||
import { useLocation } from "react-router-dom";
|
import { useLocation } from "react-router-dom";
|
||||||
import ReactGA from "react-ga4";
|
import ReactGA from "react-ga4";
|
||||||
@ -19,7 +19,7 @@ import { Apy, CurrentIndex, TotalDeposit } from "./components/Metric";
|
|||||||
import { useEpoch } from "../../hooks/staking";
|
import { useEpoch } from "../../hooks/staking";
|
||||||
import { useTokenSymbol } from "../../hooks/tokens";
|
import { useTokenSymbol } from "../../hooks/tokens";
|
||||||
|
|
||||||
export const StakeContainer = ({ chainId, address, connect }) => {
|
export const StakeContainer = ({ chainId, address, config, connect }) => {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const [isModalOpened, handleModal] = useState(false);
|
const [isModalOpened, handleModal] = useState(false);
|
||||||
|
|
||||||
@ -32,6 +32,12 @@ export const StakeContainer = ({ chainId, address, connect }) => {
|
|||||||
|
|
||||||
const { epoch, refetch: refetchEpoch } = useEpoch(chainId);
|
const { epoch, refetch: refetchEpoch } = useEpoch(chainId);
|
||||||
|
|
||||||
|
const chainSymbol = useMemo(() => {
|
||||||
|
const chainSymbol = config?.getClient()?.chain?.nativeCurrency?.symbol;
|
||||||
|
if (chainSymbol) return chainSymbol;
|
||||||
|
return "WTF";
|
||||||
|
}, [config, chainId])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
ReactGA.send({ hitType: "pageview", page: location.pathname });
|
ReactGA.send({ hitType: "pageview", page: location.pathname });
|
||||||
}, [location])
|
}, [location])
|
||||||
@ -39,6 +45,7 @@ export const StakeContainer = ({ chainId, address, connect }) => {
|
|||||||
if (isModalOpened) {
|
if (isModalOpened) {
|
||||||
return (
|
return (
|
||||||
<Stake
|
<Stake
|
||||||
|
chainSymbol={chainSymbol}
|
||||||
chainId={chainId}
|
chainId={chainId}
|
||||||
address={address}
|
address={address}
|
||||||
isOpened={isModalOpened}
|
isOpened={isModalOpened}
|
||||||
@ -88,7 +95,7 @@ export const StakeContainer = ({ chainId, address, connect }) => {
|
|||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Divider sx={{ marginTop: "30px" }} />
|
<Divider sx={{ marginTop: "30px" }} />
|
||||||
<ClaimsArea chainId={chainId} address={address} epoch={epoch} />
|
<ClaimsArea chainId={chainId} address={address} chainSymbol={chainSymbol} epoch={epoch} />
|
||||||
<Divider />
|
<Divider />
|
||||||
|
|
||||||
<Box mt="15px" display="flex" flexDirection="column" alignItems="center" justifyContent="center">
|
<Box mt="15px" display="flex" flexDirection="column" alignItems="center" justifyContent="center">
|
||||||
@ -104,7 +111,7 @@ export const StakeContainer = ({ chainId, address, connect }) => {
|
|||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Paper>
|
</Paper>
|
||||||
<FarmPools chainId={chainId} />
|
<FarmPools chainId={chainId} chainSymbol={chainSymbol} />
|
||||||
</Box>
|
</Box>
|
||||||
</Container>
|
</Container>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@ -42,7 +42,7 @@ const ClaimConfirmationModal = (props) => {
|
|||||||
maxWidth="356px"
|
maxWidth="356px"
|
||||||
topLeft={<></>}
|
topLeft={<></>}
|
||||||
headerContent={
|
headerContent={
|
||||||
<Box display="flex" flexDirection="row">
|
<Box display="flex" flexDirection="column">
|
||||||
<Typography variant="h5">{`Confirm ${capitalize(props.action)}`}</Typography>
|
<Typography variant="h5">{`Confirm ${capitalize(props.action)}`}</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,7 +50,7 @@ const StyledTableHeader = styled(TableHead)(({ theme }) => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const ClaimsArea = ({ chainId, address, epoch }) => {
|
export const ClaimsArea = ({ chainId, address, chainSymbol, epoch }) => {
|
||||||
const isSmallScreen = useMediaQuery("(max-width: 745px)");
|
const isSmallScreen = useMediaQuery("(max-width: 745px)");
|
||||||
|
|
||||||
const { breakoutFromStaking } = useBreakoutModal();
|
const { breakoutFromStaking } = useBreakoutModal();
|
||||||
@ -70,7 +70,17 @@ export const ClaimsArea = ({ chainId, address, epoch }) => {
|
|||||||
|
|
||||||
const claimableBalance = useMemo(() => {
|
const claimableBalance = useMemo(() => {
|
||||||
if (isNetworkLegacy(chainId)) {
|
if (isNetworkLegacy(chainId)) {
|
||||||
return isPayoutGhst ? balanceForShares.div(currentIndex) : balanceForShares;
|
return isPayoutGhst
|
||||||
|
? new DecimalBigNumber(
|
||||||
|
balanceForShares && currentIndex && currentIndex._value !== 0n
|
||||||
|
? (balanceForShares._value * (10n ** BigInt(9 + currentIndex._decimals - balanceForShares._decimals))) / currentIndex._value
|
||||||
|
: 0n,
|
||||||
|
9
|
||||||
|
)
|
||||||
|
: new DecimalBigNumber(
|
||||||
|
balanceForShares ? balanceForShares._value : 0n,
|
||||||
|
balanceForShares ? balanceForShares._decimals : 9
|
||||||
|
);
|
||||||
}
|
}
|
||||||
const toClaim = new DecimalBigNumber(claim.shares, 18);
|
const toClaim = new DecimalBigNumber(claim.shares, 18);
|
||||||
return isPayoutGhst ? toClaim : toClaim.mul(currentIndex);
|
return isPayoutGhst ? toClaim : toClaim.mul(currentIndex);
|
||||||
@ -108,7 +118,7 @@ export const ClaimsArea = ({ chainId, address, epoch }) => {
|
|||||||
|
|
||||||
if (claim.shares === 0n) return <></>;
|
if (claim.shares === 0n) return <></>;
|
||||||
|
|
||||||
const warmupTooltip = `Your claim earns rebases during warm-up. You can emergency withdraw, but this forfeits the rebases`;
|
const warmupTooltip = `Claim earns rebases during warm-up. You can emergency withdraw, but this forfeits the rebases`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -134,7 +144,7 @@ export const ClaimsArea = ({ chainId, address, epoch }) => {
|
|||||||
justifyContent="space-between"
|
justifyContent="space-between"
|
||||||
flexDirection={isSmallScreen ? "column" : "row"}
|
flexDirection={isSmallScreen ? "column" : "row"}
|
||||||
>
|
>
|
||||||
<Typography variant="h6">Your active {isPayoutGhst ? ghstSymbol : stnkSymbol} claim</Typography>
|
<Typography variant="h6">My active {isPayoutGhst ? ghstSymbol : stnkSymbol} claim</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
}
|
}
|
||||||
tooltip={warmupTooltip}
|
tooltip={warmupTooltip}
|
||||||
@ -164,6 +174,7 @@ export const ClaimsArea = ({ chainId, address, epoch }) => {
|
|||||||
</TableRow>
|
</TableRow>
|
||||||
</StyledTableHeader>
|
</StyledTableHeader>
|
||||||
<ClaimInfo
|
<ClaimInfo
|
||||||
|
chainSymbol={chainSymbol}
|
||||||
setConfirmationModalOpen={setConfirmationModalOpen}
|
setConfirmationModalOpen={setConfirmationModalOpen}
|
||||||
prepareBalance={claimableBalance}
|
prepareBalance={claimableBalance}
|
||||||
isPayoutGhst={isPayoutGhst}
|
isPayoutGhst={isPayoutGhst}
|
||||||
@ -184,6 +195,7 @@ export const ClaimsArea = ({ chainId, address, epoch }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const ClaimInfo = ({
|
const ClaimInfo = ({
|
||||||
|
chainSymbol,
|
||||||
setConfirmationModalOpen,
|
setConfirmationModalOpen,
|
||||||
prepareBalance,
|
prepareBalance,
|
||||||
claim,
|
claim,
|
||||||
@ -200,7 +212,10 @@ const ClaimInfo = ({
|
|||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell style={{ padding: "8px 8px 8px 0" }}>
|
<TableCell style={{ padding: "8px 8px 8px 0" }}>
|
||||||
<Box display="flex" flexDirection="row" alignItems="center" style={{ whiteSpace: "nowrap" }}>
|
<Box display="flex" flexDirection="row" alignItems="center" style={{ whiteSpace: "nowrap" }}>
|
||||||
<Token key={isPayoutGhst ? ghstSymbol : stnkSymbol} name={isPayoutGhst ? ghstSymbol : stnkSymbol} />
|
<Token
|
||||||
|
chainTokenName={chainSymbol}
|
||||||
|
name={isPayoutGhst ? ghstSymbol : stnkSymbol}
|
||||||
|
/>
|
||||||
<Box marginLeft="14px" marginRight="10px">
|
<Box marginLeft="14px" marginRight="10px">
|
||||||
<Typography>{isPayoutGhst ? ghstSymbol : stnkSymbol}</Typography>
|
<Typography>{isPayoutGhst ? ghstSymbol : stnkSymbol}</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@ -23,7 +23,7 @@ import { useTotalSupply, useTokenSymbol } from "../../../hooks/tokens";
|
|||||||
|
|
||||||
import { EMPTY_ADDRESS, FTSO_ADDRESSES } from "../../../constants/addresses";
|
import { EMPTY_ADDRESS, FTSO_ADDRESSES } from "../../../constants/addresses";
|
||||||
|
|
||||||
const FarmPools = ({ chainId }) => {
|
const FarmPools = ({ chainId, chainSymbol }) => {
|
||||||
const isSmallScreen = useMediaQuery("(max-width: 775px)");
|
const isSmallScreen = useMediaQuery("(max-width: 775px)");
|
||||||
const { network } = useParams();
|
const { network } = useParams();
|
||||||
|
|
||||||
@ -35,8 +35,9 @@ const FarmPools = ({ chainId }) => {
|
|||||||
|
|
||||||
const pools = [
|
const pools = [
|
||||||
{
|
{
|
||||||
icons: ["FTSO", tokenNameConverter(chainId, reserveSymbol)],
|
icons: [tokenNameConverter(chainId, reserveSymbol), "FTSO"],
|
||||||
name: `${ftsoSymbol}-${reserveSymbol}`,
|
chainTokenNames: [undefined, chainSymbol],
|
||||||
|
name: `${reserveSymbol}-${ftsoSymbol}`,
|
||||||
dex: "Uniswap V2",
|
dex: "Uniswap V2",
|
||||||
url: `/${network}/dex/uniswap`,
|
url: `/${network}/dex/uniswap`,
|
||||||
tvl: reserveFtsoUniValuation,
|
tvl: reserveFtsoUniValuation,
|
||||||
@ -101,7 +102,7 @@ const FarmPoolCard = ({ id, pool }) => {
|
|||||||
<Box id={id + `--bond`}>
|
<Box id={id + `--bond`}>
|
||||||
<Box display="flex" alignItems="center" flexDirection="column" gap="20px">
|
<Box display="flex" alignItems="center" flexDirection="column" gap="20px">
|
||||||
<Box display="flex" alignItems="center" gap="20px">
|
<Box display="flex" alignItems="center" gap="20px">
|
||||||
<TokenStack tokens={pool.icons} />
|
<TokenStack chainTokenNames={pool.chainTokenNames} tokens={pool.icons} />
|
||||||
<Typography>{pool.name}</Typography>
|
<Typography>{pool.name}</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
@ -127,7 +128,7 @@ const FarmPoolRow = ({ id, pool }) => {
|
|||||||
<TableRow key={id} id={id + `--pool`} data-testid={id + `--pool`}>
|
<TableRow key={id} id={id + `--pool`} data-testid={id + `--pool`}>
|
||||||
<TableCell style={{ padding: "8px 0" }}>
|
<TableCell style={{ padding: "8px 0" }}>
|
||||||
<Box display="flex" alignItems="center" gap="20px">
|
<Box display="flex" alignItems="center" gap="20px">
|
||||||
<TokenStack tokens={pool.icons} />
|
<TokenStack chainTokenNames={pool.chainTokenNames} tokens={pool.icons} />
|
||||||
<Typography>{pool.name}</Typography>
|
<Typography>{pool.name}</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import { useAccount } from "wagmi";
|
|||||||
import { StakeInputArea } from "./StakeInputArea";
|
import { StakeInputArea } from "./StakeInputArea";
|
||||||
|
|
||||||
export const StakeArea = ({
|
export const StakeArea = ({
|
||||||
|
chainSymbol,
|
||||||
upperToken,
|
upperToken,
|
||||||
setUpperToken,
|
setUpperToken,
|
||||||
bottomToken,
|
bottomToken,
|
||||||
@ -19,6 +20,7 @@ export const StakeArea = ({
|
|||||||
return (
|
return (
|
||||||
<Box width="100%">
|
<Box width="100%">
|
||||||
<StakeInputArea
|
<StakeInputArea
|
||||||
|
chainSymbol={chainSymbol}
|
||||||
upperToken={upperToken}
|
upperToken={upperToken}
|
||||||
setUpperToken={setUpperToken}
|
setUpperToken={setUpperToken}
|
||||||
bottomToken={bottomToken}
|
bottomToken={bottomToken}
|
||||||
|
|||||||
@ -7,8 +7,9 @@ import { DecimalBigNumber } from "../../../helpers/DecimalBigNumber";
|
|||||||
|
|
||||||
import GhostStyledIcon from "../../../components/Icon/GhostIcon";
|
import GhostStyledIcon from "../../../components/Icon/GhostIcon";
|
||||||
import Modal from "../../../components/Modal/Modal";
|
import Modal from "../../../components/Modal/Modal";
|
||||||
import { PrimaryButton, SecondaryButton } from "../../../components/Button";
|
|
||||||
import Metric from "../../../components/Metric/Metric";
|
import Metric from "../../../components/Metric/Metric";
|
||||||
|
import Token from "../../../components/Token/Token";
|
||||||
|
import { PrimaryButton, SecondaryButton } from "../../../components/Button";
|
||||||
import { TokenAllowanceGuard } from "../../../components/TokenAllowanceGuard/TokenAllowanceGuard";
|
import { TokenAllowanceGuard } from "../../../components/TokenAllowanceGuard/TokenAllowanceGuard";
|
||||||
|
|
||||||
import { useWarmupLength, stake, unstake, wrap, unwrap } from "../../../hooks/staking";
|
import { useWarmupLength, stake, unstake, wrap, unwrap } from "../../../hooks/staking";
|
||||||
@ -73,7 +74,7 @@ const StakeConfirmationModal = (props) => {
|
|||||||
const actionAmount = new DecimalBigNumber(props.amount, props.spendDecimals);
|
const actionAmount = new DecimalBigNumber(props.amount, props.spendDecimals);
|
||||||
let isRebase = false;
|
let isRebase = false;
|
||||||
|
|
||||||
switch (props.action) {
|
switch (props.action.toUpperCase()) {
|
||||||
case "STAKE":
|
case "STAKE":
|
||||||
isRebase = props.bottomToken === props.stnkSymbol;
|
isRebase = props.bottomToken === props.stnkSymbol;
|
||||||
await stake(
|
await stake(
|
||||||
@ -128,11 +129,8 @@ const StakeConfirmationModal = (props) => {
|
|||||||
<Modal
|
<Modal
|
||||||
data-testid="stake-confirmation-modal"
|
data-testid="stake-confirmation-modal"
|
||||||
maxWidth="476px"
|
maxWidth="476px"
|
||||||
topLeft={<></>}
|
|
||||||
headerContent={
|
headerContent={
|
||||||
<Box display="flex" flexDirection="row">
|
<Typography variant="h4">{`Confirm ${props.action}`}</Typography>
|
||||||
<Typography variant="h5">{`Confirm ${props.action}`}</Typography>
|
|
||||||
</Box>
|
|
||||||
}
|
}
|
||||||
open={props.open}
|
open={props.open}
|
||||||
onClose={() => isPending ? {} : props.onClose()}
|
onClose={() => isPending ? {} : props.onClose()}
|
||||||
@ -140,15 +138,25 @@ const StakeConfirmationModal = (props) => {
|
|||||||
>
|
>
|
||||||
<Box display="flex" flexDirection="column">
|
<Box display="flex" flexDirection="column">
|
||||||
<Box display="flex" flexDirection="row" justifyContent="space-between" alignItems="center">
|
<Box display="flex" flexDirection="row" justifyContent="space-between" alignItems="center">
|
||||||
<Box display="flex" flexDirection="column">
|
<Box height="170px" display="flex" flexDirection="column">
|
||||||
<Metric
|
<Metric
|
||||||
label={`Assets to Spend`}
|
label={`Assets to Spend`}
|
||||||
metric={formatNumber(new DecimalBigNumber(props.amount, props.spendDecimals), 5)}
|
metric={formatNumber(new DecimalBigNumber(props.amount, props.spendDecimals), 5)}
|
||||||
/>
|
/>
|
||||||
<Box display="flex" flexDirection="row" justifyContent="center">
|
<Box display="flex" flexDirection="column" justifyContent="center" alignItems="center">
|
||||||
<Typography>
|
<Token
|
||||||
{props.upperToken}
|
parentSx={{
|
||||||
</Typography>
|
height: "80px",
|
||||||
|
"& svg:nth-of-type(2)": {
|
||||||
|
transform: "translate(50%, -30%)",
|
||||||
|
zIndex: 100,
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
sx={{ transform: "scale(1.65)", }}
|
||||||
|
chainTokenName={props.chainSymbol}
|
||||||
|
name={props.upperToken}
|
||||||
|
/>
|
||||||
|
<Typography>{props.upperToken}</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
<GhostStyledIcon component={ArrowRightIcon} />
|
<GhostStyledIcon component={ArrowRightIcon} />
|
||||||
@ -157,15 +165,25 @@ const StakeConfirmationModal = (props) => {
|
|||||||
label="Assets to Receive"
|
label="Assets to Receive"
|
||||||
metric={formatNumber(new DecimalBigNumber(props.receiveAmount, props.receiveDecimals), 5)}
|
metric={formatNumber(new DecimalBigNumber(props.receiveAmount, props.receiveDecimals), 5)}
|
||||||
/>
|
/>
|
||||||
<Box display="flex" flexDirection="row" justifyContent="center">
|
<Box display="flex" flexDirection="column" justifyContent="center" alignItems="center">
|
||||||
<Typography>
|
<Token
|
||||||
{props.bottomToken}
|
parentSx={{
|
||||||
</Typography>
|
height: "80px",
|
||||||
|
"& svg:nth-of-type(2)": {
|
||||||
|
transform: "translate(50%, -30%)",
|
||||||
|
zIndex: 100,
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
sx={{ transform: "scale(1.65)", }}
|
||||||
|
chainTokenName={props.chainSymbol}
|
||||||
|
name={props.upperToken === props.ftsoSymbol ? props.ghstSymbol : props.ftsoSymbol}
|
||||||
|
/>
|
||||||
|
<Typography>{props.bottomToken}</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box sx={{ marginTop: "2rem" }}>
|
<Box sx={{ marginTop: "1.5rem" }}>
|
||||||
{acknowledgedWarmup || props.action !== "STAKE" ?
|
{acknowledgedWarmup || props.action !== "STAKE" ?
|
||||||
<TokenAllowanceGuard
|
<TokenAllowanceGuard
|
||||||
spendAmount={new DecimalBigNumber(props.amount, props.spendDecimals)}
|
spendAmount={new DecimalBigNumber(props.amount, props.spendDecimals)}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ const StakeInfoText = () => {
|
|||||||
fontSize="0.875em"
|
fontSize="0.875em"
|
||||||
lineHeight="15px"
|
lineHeight="15px"
|
||||||
>
|
>
|
||||||
Staking drives value accrual, rewarding stakers with rebase yields that fluctuate based on ghostDAO monetary policy and are backed by bond proceeds.
|
Staking generates rebase yields governed by ghostDAO monetary policy and backed by bonds, Protocol Owned Liquidity (POL), and allocators.
|
||||||
<Link
|
<Link
|
||||||
color={theme.colors.primary[300]}
|
color={theme.colors.primary[300]}
|
||||||
href="https://ghostchain.io/ghostdao_litepaper"
|
href="https://ghostchain.io/ghostdao_litepaper"
|
||||||
|
|||||||
@ -68,6 +68,7 @@ const StyledBox = styled(Box)(({ theme }) => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
export const StakeInputArea = ({
|
export const StakeInputArea = ({
|
||||||
|
chainSymbol,
|
||||||
upperToken,
|
upperToken,
|
||||||
setUpperToken,
|
setUpperToken,
|
||||||
bottomToken,
|
bottomToken,
|
||||||
@ -198,7 +199,7 @@ export const StakeInputArea = ({
|
|||||||
id={`${tokenName.toLowerCase()}-input`}
|
id={`${tokenName.toLowerCase()}-input`}
|
||||||
token={tokenName}
|
token={tokenName}
|
||||||
tokenName={realTokenName}
|
tokenName={realTokenName}
|
||||||
tokenOnClick={() => handleModal(true)}
|
chainTokenName={chainSymbol}
|
||||||
inputProps={{ "data-testid": `${tokenName.toLowerCase()}-input`, min: "0" }}
|
inputProps={{ "data-testid": `${tokenName.toLowerCase()}-input`, min: "0" }}
|
||||||
value={tokenAmount}
|
value={tokenAmount}
|
||||||
onChange={event => setAmount(event.target.value)}
|
onChange={event => setAmount(event.target.value)}
|
||||||
@ -240,11 +241,7 @@ export const StakeInputArea = ({
|
|||||||
loading={false}
|
loading={false}
|
||||||
disabled={exceedsAmount}
|
disabled={exceedsAmount}
|
||||||
>
|
>
|
||||||
{exceedsAmount ?
|
{exceedsAmount ? "Exceeds amount" : action }
|
||||||
"Exceeds amount"
|
|
||||||
:
|
|
||||||
action[0] + String(action.toLowerCase()).slice(1)
|
|
||||||
}
|
|
||||||
</PrimaryButton>
|
</PrimaryButton>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
@ -261,6 +258,7 @@ export const StakeInputArea = ({
|
|||||||
onTriggerRebaseChange={setIsTriggerInner}
|
onTriggerRebaseChange={setIsTriggerInner}
|
||||||
/>
|
/>
|
||||||
<StakeConfirmationModal
|
<StakeConfirmationModal
|
||||||
|
chainSymbol={chainSymbol}
|
||||||
open={confirmationModalOpen}
|
open={confirmationModalOpen}
|
||||||
onClose={() => closeAndUpdate()}
|
onClose={() => closeAndUpdate()}
|
||||||
chainId={chainId}
|
chainId={chainId}
|
||||||
|
|||||||
@ -116,7 +116,7 @@ const ProtocolDetails = ({ chainId, isMobileScreen, theme, }) => {
|
|||||||
theme={theme}
|
theme={theme}
|
||||||
url={`/${networkName.toLowerCase()}/stake`}
|
url={`/${networkName.toLowerCase()}/stake`}
|
||||||
name="(3, 3) Stake"
|
name="(3, 3) Stake"
|
||||||
sideName={`${formatNumber(apyInner, 0)}% APY`}
|
sideName={`${formatNumber(apyInner, 2)}% APY`}
|
||||||
description={`Staking enables (3, 3) coordination by aligning long-term incentives, sustainably backed by (1, 1) Bonds, LP fees, and Farming. Stake ${ftsoSymbol} to earn rewards and unlock ${bridgeNumbers} Stake\u00B2.`}
|
description={`Staking enables (3, 3) coordination by aligning long-term incentives, sustainably backed by (1, 1) Bonds, LP fees, and Farming. Stake ${ftsoSymbol} to earn rewards and unlock ${bridgeNumbers} Stake\u00B2.`}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ const ProtocolDetails = ({ chainId, isMobileScreen, theme, }) => {
|
|||||||
theme={theme}
|
theme={theme}
|
||||||
url={`/${networkName.toLowerCase()}/bridge`}
|
url={`/${networkName.toLowerCase()}/bridge`}
|
||||||
name={`${bridgeNumbers} Stake\u00B2`}
|
name={`${bridgeNumbers} Stake\u00B2`}
|
||||||
sideName={`${formatNumber(gatekeepedApy, 0)}% APY`}
|
sideName={`${formatNumber(gatekeepedApy, 2)}% APY`}
|
||||||
description={`Staking\u00B2 strategy further deepens long-term incentives powered by sustainable crosschain bridging revenue. ${bridgeNumbers} Stake\u00B2 your ${csprSymbol} to receive organic APY with no warm-up and no dilution.`}
|
description={`Staking\u00B2 strategy further deepens long-term incentives powered by sustainable crosschain bridging revenue. ${bridgeNumbers} Stake\u00B2 your ${csprSymbol} to receive organic APY with no warm-up and no dilution.`}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import { useTokenSymbol, useTokenSymbols } from "../tokens";
|
|||||||
import {
|
import {
|
||||||
getTokenAddress,
|
getTokenAddress,
|
||||||
getTokenIcons,
|
getTokenIcons,
|
||||||
|
getChainTokenNames,
|
||||||
getBondNameDisplayName,
|
getBondNameDisplayName,
|
||||||
getTokenPurchaseLink,
|
getTokenPurchaseLink,
|
||||||
executeOnChainTransaction
|
executeOnChainTransaction
|
||||||
@ -123,7 +124,7 @@ export const useLiveBonds = (chainId, chainName) => {
|
|||||||
const marketCapacity = markets?.at(index).result?.at(0) ? markets.at(index).result.at(0) : 0n;
|
const marketCapacity = markets?.at(index).result?.at(0) ? markets.at(index).result.at(0) : 0n;
|
||||||
const quoteTokenAddress = markets?.at(index).result?.at(1) ? markets.at(index).result.at(1) : "";
|
const quoteTokenAddress = markets?.at(index).result?.at(1) ? markets.at(index).result.at(1) : "";
|
||||||
const capacityInQuote = markets?.at(index).result?.at(2) ? markets.at(index).result.at(2) : 0n;
|
const capacityInQuote = markets?.at(index).result?.at(2) ? markets.at(index).result.at(2) : 0n;
|
||||||
const marketMaxPayout = markets?.at(index).result?.at(4) ? markets.at(index).result.at(4) : 0n;
|
const marketMaxPayout = markets?.at(index).result?.at(4) ? markets.at(index).result.at(4) : 0n;
|
||||||
const quoteTokenDecimals = metas?.at(index).result?.at(5) ? metas.at(index).result.at(5) : 18;
|
const quoteTokenDecimals = metas?.at(index).result?.at(5) ? metas.at(index).result.at(5) : 18;
|
||||||
const quoteTokenPerUsd = quotePrices?.at(index).result
|
const quoteTokenPerUsd = quotePrices?.at(index).result
|
||||||
? new DecimalBigNumber(quotePrices.at(index).result * (10n ** 9n), quoteTokenDecimals)
|
? new DecimalBigNumber(quotePrices.at(index).result * (10n ** 9n), quoteTokenDecimals)
|
||||||
@ -162,13 +163,15 @@ export const useLiveBonds = (chainId, chainName) => {
|
|||||||
baseToken: {
|
baseToken: {
|
||||||
name: baseTokenSymbol,
|
name: baseTokenSymbol,
|
||||||
purchaseUrl: getTokenPurchaseLink(chainId, "", chainName),
|
purchaseUrl: getTokenPurchaseLink(chainId, "", chainName),
|
||||||
|
tokenAddress: getTokenAddress(chainId, "FTSO"),
|
||||||
|
chainNames: getChainTokenNames(chainId, "FTSO"),
|
||||||
icons: ["FTSO"],
|
icons: ["FTSO"],
|
||||||
tokenAddress: getTokenAddress(chainId, "FTSO")
|
|
||||||
},
|
},
|
||||||
quoteToken: {
|
quoteToken: {
|
||||||
name: tokenNameConverter(chainId, quoteTokenSymbol),
|
name: tokenNameConverter(chainId, quoteTokenSymbol),
|
||||||
purchaseUrl: getTokenPurchaseLink(chainId, quoteTokenAddress, chainName),
|
purchaseUrl: getTokenPurchaseLink(chainId, quoteTokenAddress, chainName),
|
||||||
icons: getTokenIcons(chainId, quoteTokenAddress),
|
icons: getTokenIcons(chainId, quoteTokenAddress),
|
||||||
|
chainNames: getChainTokenNames(chainId, quoteTokenAddress),
|
||||||
decimals: quoteTokenDecimals,
|
decimals: quoteTokenDecimals,
|
||||||
quoteTokenAddress,
|
quoteTokenAddress,
|
||||||
},
|
},
|
||||||
@ -190,7 +193,7 @@ export const useLiveBonds = (chainId, chainName) => {
|
|||||||
inQuoteToken: maxPayoutInQuoteToken,
|
inQuoteToken: maxPayoutInQuoteToken,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}).sort((a, b) => (a.id > b.id ? -1 : 1)) : [];
|
}).sort((a, b) => (a.id > b.id ? -1 : 1)) || [];
|
||||||
return { liveBonds, refetch };
|
return { liveBonds, refetch };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,6 +258,7 @@ export const useNotes = (chainId, address) => {
|
|||||||
quoteToken: {
|
quoteToken: {
|
||||||
name: tokenNameConverter(chainId, quoteTokenSymbol),
|
name: tokenNameConverter(chainId, quoteTokenSymbol),
|
||||||
icons: getTokenIcons(chainId, quoteTokenAddress),
|
icons: getTokenIcons(chainId, quoteTokenAddress),
|
||||||
|
chainNames: getChainTokenNames(chainId, quoteTokenAddress),
|
||||||
},
|
},
|
||||||
vesting: terms?.at(index).result?.at(2) ? terms.at(index).result.at(2) : 0,
|
vesting: terms?.at(index).result?.at(2) ? terms.at(index).result.at(2) : 0,
|
||||||
created: notesRaw?.at(index).result?.at(1) ? notesRaw.at(index).result.at(1) : 0,
|
created: notesRaw?.at(index).result?.at(1) ? notesRaw.at(index).result.at(1) : 0,
|
||||||
|
|||||||
@ -174,7 +174,7 @@ export const getTokenIcons = (chainId, address) => {
|
|||||||
icons = ["GHST"];
|
icons = ["GHST"];
|
||||||
break;
|
break;
|
||||||
case FTSO_DAI_LP_ADDRESSES[chainId]:
|
case FTSO_DAI_LP_ADDRESSES[chainId]:
|
||||||
icons = ["FTSO", "WETH"];
|
icons = ["WETH", "FTSO"];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
icons = [""]
|
icons = [""]
|
||||||
@ -182,6 +182,21 @@ export const getTokenIcons = (chainId, address) => {
|
|||||||
return icons;
|
return icons;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getChainTokenNames = (chainId, address) => {
|
||||||
|
let icons = [undefined];
|
||||||
|
switch (address) {
|
||||||
|
case FTSO_DAI_LP_ADDRESSES[chainId]:
|
||||||
|
icons = [undefined, "WETH"];
|
||||||
|
break;
|
||||||
|
case RESERVE_ADDRESSES[chainId]:
|
||||||
|
icons = [undefined]
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
icons = ["WETH"]
|
||||||
|
}
|
||||||
|
return icons;
|
||||||
|
}
|
||||||
|
|
||||||
export const getBondNameDisplayName = (chainId, tokenAddress, baseTokenSymbol) => {
|
export const getBondNameDisplayName = (chainId, tokenAddress, baseTokenSymbol) => {
|
||||||
let stringValue = tokenNameConverter(chainId, "WETH")
|
let stringValue = tokenNameConverter(chainId, "WETH")
|
||||||
if (tokenAddress.toUpperCase() === FTSO_DAI_LP_ADDRESSES[chainId].toUpperCase()) {
|
if (tokenAddress.toUpperCase() === FTSO_DAI_LP_ADDRESSES[chainId].toUpperCase()) {
|
||||||
|
|||||||
@ -173,3 +173,8 @@ input:-webkit-autofill {
|
|||||||
color: #ffffff !important;
|
color: #ffffff !important;
|
||||||
-webkit-text-fill-color: #ffffff !important;
|
-webkit-text-fill-color: #ffffff !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes spinTokenIcon {
|
||||||
|
from { transform: rotate(360deg); }
|
||||||
|
to { transform: rotate(0deg); }
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user