172 lines
7.3 KiB
JavaScript
172 lines
7.3 KiB
JavaScript
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 FTSO (eGHST) I’m 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);
|
||
const isRebase = props.upperToken === "STNK";
|
||
switch (props.action) {
|
||
case "STAKE":
|
||
await stake(props.chainId, props.address, actionAmount._value.toBigInt(), isRebase, props.isClaim);
|
||
break;
|
||
case "UNSTAKE":
|
||
await unstake(props.chainId, props.address, actionAmount._value.toBigInt(), props.isTrigger, isRebase);
|
||
break;
|
||
case "WRAP":
|
||
await wrap(props.chainId, props.address, actionAmount._value.toBigInt());
|
||
break;
|
||
case "UNWRAP":
|
||
await unwrap(props.chainId, props.address, actionAmount._value.toBigInt());
|
||
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;
|