import { Avatar, Box, Link } from "@mui/material"; import { styled } from "@mui/material/styles"; import React, { useEffect, useState } from "react"; import { useSearchParams } from "react-router-dom"; import { DecimalBigNumber } from "../../../helpers/DecimalBigNumber"; import { useChainId } from "wagmi"; import TokenModal from "./TokenModal"; import StakeConfirmationModal from "./StakeConfirmationModal"; import StakeSettingsModal from "./StakeSettingsModal"; import SwapCard from "../../../components/Swap/SwapCard"; import SwapCollection from "../../../components/Swap/SwapCollection"; import { InfoNotification } from "../../../components/Notification"; import { PrimaryButton } from "../../../components/Button"; import { GHST_ADDRESSES, FTSO_ADDRESSES, STNK_ADDRESSES, STAKING_ADDRESSES, } from "../../../constants/addresses"; import { useCurrentIndex } from "../../../hooks/staking"; import { useBalance, useTokenSymbol } from "../../../hooks/tokens"; import { formatNumber } from "../../../helpers"; const PREFIX = "StakeInputArea"; const classes = { inputRow: `${PREFIX}-inputRow`, gridItem: `${PREFIX}-gridItem`, input: `${PREFIX}-input`, button: `${PREFIX}-button`, }; const StyledBox = styled(Box)(({ theme }) => ({ [`& .${classes.inputRow}`]: { justifyContent: "space-around", alignItems: "center", height: "auto", marginTop: "4px", }, [`& .${classes.gridItem}`]: { width: "100%", paddingRight: "5px", alignItems: "center", justifyContent: "center", }, [`& .${classes.input}`]: { [theme.breakpoints.down("md")]: { marginBottom: "10px", }, [theme.breakpoints.up("sm")]: { marginBottom: "0", }, }, [`& .${classes.button}`]: { width: "100%", minWidth: "163px", maxWidth: "542px", }, })); export const StakeInputArea = ({ upperToken, setUpperToken, bottomToken, setBottomToken, action, chainId, address, connect, settingsModalOpen, closeSettingModal }) => { const [upperTokenModalOpen, setUpperTokenModalOpen] = useState(false); const [bottomTokenModalOpen, setBottomTokenModalOpen] = useState(false); const [confirmationModalOpen, setConfirmationModalOpen] = useState(false); const [formatDecimals, setFormatDecimals] = useState(localStorage.getItem("stake-decimals") ? localStorage.getItem("stake-decimals") : "5" ); const [isClaim, setIsClaim] = useState(localStorage.getItem("stake-isClaim") ? localStorage.getItem("stake-isClaim") === 'true' : true ); const [isTrigger, setIsTrigger] = useState(localStorage.getItem("stake-isTrigger") ? localStorage.getItem("stake-isTrigger") === 'true' : true ); const [amount, setAmount] = useState(""); const [receiveAmount, setReceiveAmount] = useState(""); const [exceedsAmount, setExceedsAmount] = useState(false) const { currentIndex, refetch: refetchCurrentIndex } = useCurrentIndex(chainId); const { balance: ftsoBalance, refetch: ftsoRefetch } = useBalance(chainId, "FTSO", address); const { balance: stnkBalance, refetch: stnkRefetch } = useBalance(chainId, "STNK", address); const { balance: ghstBalance, refetch: ghstRefetch } = useBalance(chainId, "GHST", address); const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO"); const { symbol: stnkSymbol } = useTokenSymbol(chainId, "STNK"); const { symbol: ghstSymbol } = useTokenSymbol(chainId, "GHST"); const setIsClaimInner = (value) => { setIsClaim(value); localStorage.setItem("stake-isClaim", value); } const setIsTriggerInner = (value) => { setIsTrigger(value); localStorage.setItem("stake-isTrigger", value); } const setFormatDecimalsInner = (value) => { if (Number(value) <= 17) { setFormatDecimals(value); localStorage.setItem("staking-decimals", value); } } useEffect(() => { const innerBalance = upperToken === "GHST" ? ghstBalance : upperToken === "STNK" ? stnkBalance : ftsoBalance; if ( (upperToken === "FTSO" && bottomToken === "STNK") || (upperToken === "STNK" && bottomToken === "FTSO") ) { setReceiveAmount(amount); setExceedsAmount(new DecimalBigNumber(amount, 9).gt(innerBalance)) } else { const decimals = upperToken === "GHST" ? 18 : 9; const raw = new DecimalBigNumber(amount, decimals); const amountIn = new DecimalBigNumber(raw._value.toBigInt(), decimals); const result = upperToken === "GHST" ? currentIndex.mul(amountIn).toString() : currentIndex._value > 0n ? amountIn.div(currentIndex).toString() : "0"; const innerBalance = upperToken === "GHST" ? ghstBalance : upperToken === "STNK" ? stnkBalance : ftsoBalance; setReceiveAmount(result); setExceedsAmount(amountIn.gt(innerBalance)); } }, [upperToken, bottomToken, amount, currentIndex]); const handleTokenModalInput = (value, isUpper) => { if (isUpper) { if (value === bottomToken) { const newValue = value === "GHST" ? "STNK" : "GHST"; setBottomToken(newValue) } setUpperToken(value); } else { setBottomToken(value); } } const onSwapClick = () => { const tmpUpper = upperToken; const tmpBottom = bottomToken; setUpperToken(tmpBottom); setBottomToken(tmpUpper); } const SwapCardTemplate = (tokenName, tokenAmount, isUpper, handleModal) => { const balance = tokenName === "STNK" || tokenName === "sCSPR" ? stnkBalance : tokenName === "FTSO" || tokenName === "eCSPR" ? ftsoBalance : ghstBalance; let realTokenName = ""; switch (tokenName.toUpperCase()) { case "FTSO": realTokenName = ftsoSymbol; break; case "ECSPR": realTokenName = ftsoSymbol; break; case "STNK": realTokenName = stnkSymbol; break; case "SCSPR": realTokenName = stnkSymbol; break; case "GHST": realTokenName = ghstSymbol; break; case "CSPR": realTokenName = ghstSymbol; break; } return ( handleModal(true)} inputProps={{ "data-testid": `${tokenName.toLowerCase()}-input`, min: "0" }} value={tokenAmount} onChange={event => setAmount(event.target.value)} info={`Balance: ${formatNumber(balance, formatDecimals)} ${tokenName}`} endString={isUpper ? "Max" : ""} endStringOnClick={() => isUpper && setAmount(balance.toString())} disabled={!isUpper} inputWidth={`${tokenAmount.length > 0 ? tokenAmount.length : 1}ch`} /> ) } const closeAndUpdate = () => { setAmount(""); setConfirmationModalOpen(false); refetchCurrentIndex(); ftsoRefetch(); stnkRefetch(); ghstRefetch(); } return ( <> {upperTokenModalOpen && ( handleTokenModalInput(data.token, data.isUpper)} handleClose={() => setUpperTokenModalOpen(false)} ftsoBalance={formatNumber(ftsoBalance, formatDecimals)} stnkBalance={formatNumber(stnkBalance, formatDecimals)} ghstBalance={formatNumber(ghstBalance, formatDecimals)} isUpper={true} ftsoSymbol={ftsoSymbol} stnkSymbol={stnkSymbol} ghstSymbol={ghstSymbol} /> )} {bottomTokenModalOpen && ( handleTokenModalInput(data.token, data.isUpper)} handleClose={() => setBottomTokenModalOpen(false)} ftsoBalance={formatNumber(ftsoBalance, formatDecimals)} stnkBalance={formatNumber(stnkBalance, formatDecimals)} ghstBalance={formatNumber(ghstBalance, formatDecimals)} tokenToExclude={upperToken} isUpper={false} ftsoSymbol={ftsoSymbol} stnkSymbol={stnkSymbol} ghstSymbol={ghstSymbol} /> )} setConfirmationModalOpen(true)} loading={false} disabled={exceedsAmount} > {exceedsAmount ? "Exceeds amount" : action[0] + String(action.toLowerCase()).slice(1) } setFormatDecimalsInner(event.currentTarget.value)} isClaim={isClaim} onIsClaimChanged={setIsClaimInner} isTrigger={isTrigger} onTriggerRebaseChange={setIsTriggerInner} /> closeAndUpdate()} chainId={chainId} address={address} action={action} upperToken={upperToken} bottomToken={bottomToken} amount={amount} receiveAmount={receiveAmount} amountExceedsBalance={exceedsAmount} connect={connect} spendDecimals={upperToken === "GHST" ? 18 : 9} receiveDecimals={bottomToken === "GHST" ? 18 : 9} isClaim={isClaim} isTrigger={isTrigger} ftsoSymbol={ftsoSymbol} stnkSymbol={stnkSymbol} ghstSymbol={ghstSymbol} /> ); };