ghost-dao-interface/src/containers/Stake/components/StakeConfirmationModal.jsx
Uncle Fatso e8342708c4
fix issue during UNSTAKE and avoid false warmup popup
Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
2025-08-16 16:53:54 +03:00

202 lines
8.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { CheckBoxOutlineBlank, CheckBoxOutlined } from "@mui/icons-material";
import { Box, Checkbox, FormControlLabel, Typography } from "@mui/material";
import { useEffect, useState } from "react";
import ArrowRightIcon from '@mui/icons-material/ArrowRight';
import { DecimalBigNumber } from "../../../helpers/DecimalBigNumber";
import GhostStyledIcon from "../../../components/Icon/GhostIcon";
import Modal from "../../../components/Modal/Modal";
import { PrimaryButton, SecondaryButton } from "../../../components/Button";
import Metric from "../../../components/Metric/Metric";
import { TokenAllowanceGuard } from "../../../components/TokenAllowanceGuard/TokenAllowanceGuard";
import { useWarmupLength, stake, unstake, wrap, unwrap } from "../../../hooks/staking";
import { formatNumber } from "../../../helpers";
import { STAKING_ADDRESSES } from "../../../constants/addresses";
const StakeConfirmationModal = (props) => {
const { warmupLength, warmupExists: needsWarmup } = useWarmupLength(props.chainId);
const [acknowledgedWarmup, setAcknowledgedWarmup] = useState(false);
const [isPending, setIsPending] = useState(false);
useEffect(() => setAcknowledgedWarmup(acknowledgedWarmup || !needsWarmup), [acknowledgedWarmup, needsWarmup])
const AcknowledgeWarmupCheckbox = () => {
if (!needsWarmup) return <></>;
return (
<>
<Box sx={{ marginBottom: "1rem" }}>
<hr style={{ borderWidth: "0.5px" }} />
<FormControlLabel
control={
<Checkbox
data-testid="acknowledge-warmup"
checked={acknowledgedWarmup}
onChange={event => setAcknowledgedWarmup(event.target.checked)}
icon={<CheckBoxOutlineBlank viewBox="0 0 24 24" />}
checkedIcon={<CheckBoxOutlined viewBox="0 0 24 24" />}
/>
}
label={`I understand the ${props.ftsoSymbol} Im staking will only be available to claim ${warmupLength.toString()} epochs after my transaction is confirmed`}
/>
</Box>
</>
);
};
const NeedsWarmupDetails = () => {
if (needsWarmup && props.action === "STAKE") {
return (
<>
<AcknowledgeWarmupCheckbox />
<SecondaryButton
fullWidth
href="https://ghostchain.io/ghostdao_litepaper"
>
Why is there a warmup?
</SecondaryButton>
</>
);
} else {
return <></>;
}
};
const doAction = async () => {
setIsPending(true);
const actionAmount = new DecimalBigNumber(props.amount, props.spendDecimals);
let isRebase = false;
switch (props.action) {
case "STAKE":
isRebase = props.bottomToken === props.stnkSymbol;
await stake(
props.chainId,
props.address,
actionAmount._value.toBigInt(),
isRebase,
props.isClaim,
props.ftsoSymbol,
props.stnkSymbol,
props.ghstSymbol
);
break;
case "UNSTAKE":
isRebase = props.upperToken === props.stnkSymbol;
await unstake(
props.chainId,
props.address,
actionAmount._value.toBigInt(),
props.isTrigger,
isRebase,
props.ftsoSymbol,
props.stnkSymbol,
props.ghstSymbol
);
break;
case "WRAP":
await wrap(
props.chainId,
props.address,
actionAmount._value.toBigInt(),
props.ghstSymbol
);
break;
case "UNWRAP":
await unwrap(
props.chainId,
props.address,
actionAmount._value.toBigInt(),
props.stnkSymbol
);
break;
default:
console.log("Wrong action to be executed!");
}
setIsPending(false);
props.onClose();
}
return (
<Modal
data-testid="stake-confirmation-modal"
maxWidth="476px"
topLeft={<></>}
headerContent={
<Box display="flex" flexDirection="row">
<Typography variant="h5">{`Confirm ${props.action}`}</Typography>
</Box>
}
open={props.open}
onClose={() => isPending ? {} : props.onClose()}
minHeight={"100px"}
>
<Box display="flex" flexDirection="column">
<Box display="flex" flexDirection="row" justifyContent="space-between" alignItems="center">
<Box display="flex" flexDirection="column">
<Metric
label={`Assets to Spend`}
metric={formatNumber(new DecimalBigNumber(props.amount, props.spendDecimals), 5)}
/>
<Box display="flex" flexDirection="row" justifyContent="center">
<Typography>
{props.upperToken}
</Typography>
</Box>
</Box>
<GhostStyledIcon component={ArrowRightIcon} />
<Box display="flex" flexDirection="column">
<Metric
label="Assets to Receive"
metric={formatNumber(new DecimalBigNumber(props.receiveAmount, props.receiveDecimals), 5)}
/>
<Box display="flex" flexDirection="row" justifyContent="center">
<Typography>
{props.bottomToken}
</Typography>
</Box>
</Box>
</Box>
<Box sx={{ marginTop: "2rem" }}>
{acknowledgedWarmup || props.action !== "STAKE" ?
<TokenAllowanceGuard
spendAmount={new DecimalBigNumber(props.amount, props.spendDecimals)}
tokenName={props.upperToken}
owner={props.address}
spender={STAKING_ADDRESSES[props.chainId]}
decimals={props.spendDecimals}
approvalText={`Approve ${props.upperToken}`}
approvalPendingText={"Approving..."}
connect={props.connect}
isVertical
>
<PrimaryButton
data-testid="submit-modal-button"
loading={isPending}
fullWidth
disabled={
isPending ||
parseFloat(props.amount) === 0 ||
props.amountExceedsBalance ||
(props.action === "STAKE" && !acknowledgedWarmup)
}
onClick={() => doAction()}
>
Confirm
</PrimaryButton>
</TokenAllowanceGuard>
:
<NeedsWarmupDetails />
}
</Box>
</Box>
</Modal>
);
};
export default StakeConfirmationModal;