visual sugar during the bridge transaction added
Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
This commit is contained in:
parent
0a3786b85e
commit
cec3521f39
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "ghost-dao-interface",
|
||||
"private": true,
|
||||
"version": "0.2.14",
|
||||
"version": "0.2.15",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
@ -97,7 +97,7 @@ const NavContent = ({ chainId, addressChainId }) => {
|
||||
{ghstSymbol} Price: {formatCurrency(ghstPrice, 2)}
|
||||
</Box>
|
||||
<Box fontSize="12px" fontWeight="500" lineHeight={"15px"}>
|
||||
GHOST Supply: {formatCurrency(ghostedSupplyPrice, 2)}
|
||||
GHOSTed Supply: {formatCurrency(ghostedSupplyPrice, 2)}
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
|
@ -21,6 +21,7 @@ import { useBlockNumber, useTransactionConfirmations } from "wagmi";
|
||||
import { keccak256 } from "viem";
|
||||
import { u64, u128 } from "scale-ts";
|
||||
|
||||
import ContentPasteIcon from '@mui/icons-material/ContentPaste';
|
||||
import PendingIcon from '@mui/icons-material/Pending';
|
||||
import PendingActionsIcon from '@mui/icons-material/PendingActions';
|
||||
import ArrowBack from '@mui/icons-material/ArrowBack';
|
||||
@ -28,6 +29,7 @@ import ArrowRightIcon from '@mui/icons-material/ArrowRight';
|
||||
import HourglassBottomIcon from '@mui/icons-material/HourglassBottom';
|
||||
import ThumbUpIcon from '@mui/icons-material/ThumbUp';
|
||||
import ThumbDownAltIcon from '@mui/icons-material/ThumbDownAlt';
|
||||
import HandshakeIcon from '@mui/icons-material/Handshake';
|
||||
import CheckCircleIcon from '@mui/icons-material/CheckCircle';
|
||||
import CheckIcon from '@mui/icons-material/Check';
|
||||
|
||||
@ -38,6 +40,7 @@ import SwapCollection from "../../components/Swap/SwapCollection";
|
||||
import TokenStack from "../../components/TokenStack/TokenStack";
|
||||
import GhostStyledIcon from "../../components/Icon/GhostIcon";
|
||||
import Modal from "../../components/Modal/Modal";
|
||||
import InfoTooltip from "../../components/Tooltip/InfoTooltip";
|
||||
import { PrimaryButton } from "../../components/Button";
|
||||
|
||||
import { GATEKEEPER_ADDRESSES } from "../../constants/addresses";
|
||||
@ -66,6 +69,7 @@ const Bridge = ({ chainId, address, config, connect }) => {
|
||||
const isSemiSmallScreen = useMediaQuery("(max-width: 480px)");
|
||||
const isVerySmallScreen = useMediaQuery("(max-width: 379px)");
|
||||
|
||||
const [copiedIndex, setCopiedIndex] = useState(null);
|
||||
const [isPending, setIsPending] = useState(false);
|
||||
const [bridgeAction, setBridgeAction] = useState(true);
|
||||
const [activeTxIndex, setActiveTxIndex] = useState(-1);
|
||||
@ -77,7 +81,7 @@ const Bridge = ({ chainId, address, config, connect }) => {
|
||||
return string.slice(0, first) + "..." + string.slice(second);
|
||||
}
|
||||
|
||||
const initialStoredTransactions = sessionStorage.getItem(STORAGE_PREFIX);
|
||||
const initialStoredTransactions = localStorage.getItem(STORAGE_PREFIX);
|
||||
// const initialStoredTransactions = JSON.stringify([
|
||||
// {
|
||||
// sessionIndex: 124,
|
||||
@ -177,9 +181,7 @@ const Bridge = ({ chainId, address, config, connect }) => {
|
||||
}, [config]);
|
||||
|
||||
const currentRecord = useMemo(() => {
|
||||
if (activeTxIndex === -1) return undefined
|
||||
const current = storedTransactions.at(activeTxIndex)
|
||||
if (!current) return undefined
|
||||
if (!watchTransaction) return undefined
|
||||
|
||||
const finalization = Math.max(0, (finalityDelay + watchTransaction.blockNumber) - Number(blockNumber));
|
||||
const receivedClapsLength = receivedClaps?.length ?? 0;
|
||||
@ -233,10 +235,17 @@ const Bridge = ({ chainId, address, config, connect }) => {
|
||||
const removeStoredRecord = useCallback(() => {
|
||||
const newStoredTransactions = storedTransactions.filter((_, index) => index !== activeTxIndex)
|
||||
setStoredTransactions(newStoredTransactions);
|
||||
sessionStorage.setItem(STORAGE_PREFIX, JSON.stringify(newStoredTransactions));
|
||||
localStorage.setItem(STORAGE_PREFIX, JSON.stringify(newStoredTransactions));
|
||||
setActiveTxIndex(-1);
|
||||
}, [storedTransactions, activeTxIndex, setStoredTransactions, setActiveTxIndex]);
|
||||
|
||||
const copyToClipboard = (text, index) => {
|
||||
navigator.clipboard.writeText(text).then(() => {
|
||||
setCopiedIndex(index);
|
||||
setTimeout(() => setCopiedIndex(null) , 800);
|
||||
});
|
||||
};
|
||||
|
||||
const ghostOrConnect = async () => {
|
||||
if (address === "") {
|
||||
connect();
|
||||
@ -262,10 +271,13 @@ const Bridge = ({ chainId, address, config, connect }) => {
|
||||
|
||||
const newStoredTransactions = [...storedTransactions, transaction];
|
||||
setStoredTransactions(newStoredTransactions);
|
||||
sessionStorage.setItem(STORAGE_PREFIX, JSON.stringify(newStoredTransactions));
|
||||
localStorage.setItem(STORAGE_PREFIX, JSON.stringify(newStoredTransactions));
|
||||
|
||||
if (providerDetail) {
|
||||
setActiveTxIndex(newStoredTransactions.length - 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Box height="calc(100vh - 43px)">
|
||||
@ -332,16 +344,18 @@ const Bridge = ({ chainId, address, config, connect }) => {
|
||||
alignItems="center"
|
||||
>
|
||||
<GhostStyledIcon
|
||||
sx={{ width: "35px", height: "35px" }}
|
||||
sx={{
|
||||
width: "35px",
|
||||
height: "35px",
|
||||
transition: "transform 0.5s ease-in-out",
|
||||
transform: (currentRecord?.finalization ?? 0) % 2 === 0 ? "rotate(0deg)" : "rotate(180deg)"
|
||||
}}
|
||||
viewBox="0 0 25 25"
|
||||
component={HourglassBottomIcon}
|
||||
/>
|
||||
<Typography variant="caption">Finalization</Typography>
|
||||
<Typography variant="caption">
|
||||
{Math.max(
|
||||
0,
|
||||
(finalityDelay + (currentRecord ? currentRecord.blockNumber : 0) - Number(blockNumber))
|
||||
).toString()} blocks left
|
||||
{(currentRecord?.finalization ?? 0).toString()} blocks left
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
@ -364,16 +378,46 @@ const Bridge = ({ chainId, address, config, connect }) => {
|
||||
alignItems="center"
|
||||
>
|
||||
<Box display="flex" flexDirection="row" justifyContent="center" alignItems="center">
|
||||
{currentRecord?.step <= 1
|
||||
? (
|
||||
<>
|
||||
<GhostStyledIcon
|
||||
sx={{ width: "35px", height: "35px" }}
|
||||
sx={{
|
||||
width: "35px",
|
||||
height: "35px",
|
||||
transition: "transform 0.5s ease-in-out",
|
||||
transform: currentRecord?.step === 1 && Number(blockNumber) % 2 === 0
|
||||
? "rotateX(0deg)"
|
||||
: "rotateX(180deg)"
|
||||
}}
|
||||
viewBox="0 0 25 25"
|
||||
component={ThumbUpIcon}
|
||||
/>
|
||||
<GhostStyledIcon
|
||||
sx={{ width: "35px", height: "35px" }}
|
||||
sx={{
|
||||
width: "35px",
|
||||
height: "35px",
|
||||
transition: "transform 0.5s ease-in-out",
|
||||
transform: currentRecord?.step === 1 && Number(blockNumber) % 2 === 0
|
||||
? "rotateX(0deg)"
|
||||
: "rotateX(180deg)"
|
||||
}}
|
||||
viewBox="0 0 25 25"
|
||||
component={ThumbDownAltIcon}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
: (
|
||||
<GhostStyledIcon
|
||||
sx={{
|
||||
width: "35px",
|
||||
height: "35px",
|
||||
}}
|
||||
viewBox="0 0 25 25"
|
||||
component={HandshakeIcon}
|
||||
/>
|
||||
)
|
||||
}
|
||||
</Box>
|
||||
<Box display="flex" flexDirection="column" justifyContent="center" alignItems="center">
|
||||
<Typography variant="caption">Slow Claps</Typography>
|
||||
@ -416,7 +460,55 @@ const Bridge = ({ chainId, address, config, connect }) => {
|
||||
|
||||
<Box display="flex" flexDirection="column" gap="5px" padding="0.6rem 0">
|
||||
<Box display="flex" flexDirection="row" justifyContent="space-between">
|
||||
<Box display="flex" flexDirection="row">
|
||||
<Typography variant="body2">Session Index:</Typography>
|
||||
<InfoTooltip message={<>
|
||||
<Typography variant="subtitle1">Transaction Watchmen</Typography>
|
||||
<Box
|
||||
width="280px"
|
||||
height="250px"
|
||||
margin="0"
|
||||
padding="0"
|
||||
marginTop="5px"
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
sx={{ overflowY: "auto" }}
|
||||
>
|
||||
{authorities?.map((authority, idx) => {
|
||||
const authorityAddress = ss58Address(authority.asHex(), 1996);
|
||||
const disabled = clapsInSession?.at(idx)?.at(1)?.disabled;
|
||||
const clapped = receivedClaps?.some(authId => authId === idx);
|
||||
|
||||
return (
|
||||
<Box
|
||||
key={idx}
|
||||
display="flex"
|
||||
flexDirection="row"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "10px",
|
||||
width: "275px",
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'normal',
|
||||
textOverflow: "ellipsis",
|
||||
color: clapped
|
||||
? theme.colors.primary[300]
|
||||
: clapped
|
||||
? theme.colors.feedback.error
|
||||
: theme.colors.gray[10]
|
||||
}}
|
||||
>
|
||||
{authorityAddress}
|
||||
</Typography>
|
||||
</Box>
|
||||
)
|
||||
})}
|
||||
</Box>
|
||||
</>} />
|
||||
</Box>
|
||||
<Typography variant="body2">{currentRecord?.sessionIndex}</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
@ -427,11 +519,17 @@ const Bridge = ({ chainId, address, config, connect }) => {
|
||||
>
|
||||
<Typography variant="body2">Receiver Address:</Typography>
|
||||
<Link
|
||||
onClick={() => navigator.clipboard.writeText(currentRecord ? currentRecord.receiverAddress : "")}
|
||||
style={{ display: "flex", flexDirection: "row", justifyContent: "center", alignItems: "center" }}
|
||||
onClick={() => copyToClipboard(currentRecord ? currentRecord.receiverAddress : "", 0)}
|
||||
>
|
||||
<Typography variant="body2">{
|
||||
currentRecord ? sliceString(currentRecord.receiverAddress, 14, -5) : ""
|
||||
}</Typography>
|
||||
<Typography variant="body2">
|
||||
{currentRecord ? sliceString(currentRecord.receiverAddress, 14, -5) : ""}
|
||||
</Typography>
|
||||
<GhostStyledIcon
|
||||
sx={{ marginLeft: "5px", width: "12px", height: "12px" }}
|
||||
viewBox="0 0 25 25"
|
||||
component={copiedIndex === 0 ? CheckIcon : ContentPasteIcon}
|
||||
/>
|
||||
</Link>
|
||||
</Box>
|
||||
<Box display="flex" flexDirection="row" justifyContent="space-between">
|
||||
@ -453,21 +551,36 @@ const Bridge = ({ chainId, address, config, connect }) => {
|
||||
<Box display="flex" flexDirection="row" justifyContent="space-between">
|
||||
<Typography variant="body2">Transaction Hash:</Typography>
|
||||
<Link
|
||||
onClick={() => navigator.clipboard.writeText(currentRecord ? currentRecord.transactionHash : "")}
|
||||
style={{ display: "flex", flexDirection: "row", justifyContent: "center", alignItems: "center" }}
|
||||
onClick={() => copyToClipboard(currentRecord ? currentRecord.transactionHash : "", 1)}
|
||||
>
|
||||
<Typography variant="body2">{
|
||||
currentRecord ? sliceString(currentRecord.transactionHash, 10, -8) : "0x"
|
||||
}</Typography>
|
||||
<Typography variant="body2">
|
||||
{currentRecord ? sliceString(currentRecord.transactionHash, 10, -8) : "0x"}
|
||||
</Typography>
|
||||
<GhostStyledIcon
|
||||
sx={{ marginLeft: "5px", width: "12px", height: "12px" }}
|
||||
viewBox="0 0 25 25"
|
||||
component={copiedIndex === 1 ? CheckIcon : ContentPasteIcon}
|
||||
/>
|
||||
</Link>
|
||||
</Box>
|
||||
<Box display="flex" flexDirection="row" justifyContent="space-between">
|
||||
<Box display="flex" flexDirection="row">
|
||||
<Typography variant="body2">Arguments Hash:</Typography>
|
||||
<InfoTooltip message="A unique identifier for transaction parameters, represented as a hash generated by keccak256(receiver, amount, chainId)." />
|
||||
</Box>
|
||||
<Link
|
||||
onClick={() => navigator.clipboard.writeText(hashedArguments ? hashedArguments : "")}
|
||||
style={{ display: "flex", flexDirection: "row", justifyContent: "center", alignItems: "center" }}
|
||||
onClick={() => copyToClipboard(hashedArguments ? hashedArguments : "", 2)}
|
||||
>
|
||||
<Typography variant="body2">{
|
||||
hashedArguments ? sliceString(hashedArguments, 10, -8) : "0x"
|
||||
}</Typography>
|
||||
<Typography variant="body2">
|
||||
{hashedArguments ? sliceString(hashedArguments, 10, -8) : "0x"}
|
||||
</Typography>
|
||||
<GhostStyledIcon
|
||||
sx={{ marginLeft: "5px", width: "12px", height: "12px" }}
|
||||
viewBox="0 0 25 25"
|
||||
component={copiedIndex === 2 ? CheckIcon : ContentPasteIcon}
|
||||
/>
|
||||
</Link>
|
||||
</Box>
|
||||
</Box>
|
||||
@ -499,7 +612,7 @@ const Bridge = ({ chainId, address, config, connect }) => {
|
||||
onClick={() => setBridgeAction(!bridgeAction)}
|
||||
/>)}
|
||||
<Typography variant="h4">{
|
||||
bridgeAction ? `Bridge $${ghstSymbol}` : "Transaction history"
|
||||
bridgeAction ? `Bridge $${ghstSymbol}` : "Transaction History"
|
||||
}</Typography>
|
||||
</Box>
|
||||
}
|
||||
@ -509,7 +622,6 @@ const Bridge = ({ chainId, address, config, connect }) => {
|
||||
style={{ display: "flex", alignItems: "center", cursor: "pointer" }}
|
||||
onClick={() => setBridgeAction(!bridgeAction)}
|
||||
/>)}
|
||||
|
||||
enableBackground
|
||||
fullWidth
|
||||
>
|
||||
@ -578,6 +690,7 @@ const Bridge = ({ chainId, address, config, connect }) => {
|
||||
<em>
|
||||
GHOST Wallet is not detected on your browser. Download
|
||||
<Link
|
||||
underline="always"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href="https://git.ghostchain.io/ghostchain/ghost-extension-wallet/releases"
|
||||
@ -591,19 +704,71 @@ const Bridge = ({ chainId, address, config, connect }) => {
|
||||
? (
|
||||
<Box width="100%" display="flex" flexDirection="column" gap="0px">
|
||||
<Box maxWidth="416px" display="flex" justifyContent={isVerySmallScreen ? "end" : "space-between"}>
|
||||
{!isVerySmallScreen && <Typography fontSize="12px" lineHeight="15px">Est. Commission:</Typography>}
|
||||
{!isVerySmallScreen && <Typography fontSize="12px" lineHeight="15px">Estimated Fee:</Typography>}
|
||||
<Typography fontSize="12px" lineHeight="15px">{incomingFee.toFixed(4)}%</Typography>
|
||||
</Box>
|
||||
<Box maxWidth="416px" display="flex" justifyContent={isVerySmallScreen ? "end" : "space-between"}>
|
||||
{!isVerySmallScreen && <Typography fontSize="12px" lineHeight="15px">Finality Delay:</Typography>}
|
||||
{!isVerySmallScreen && <Box display="flex" flexDirection="row">
|
||||
<Typography fontSize="12px" lineHeight="15px">Finality Delay:</Typography>
|
||||
<InfoTooltip message="This period ensures that the transaction is securely added to the ledger and cannot be altered or canceled." />
|
||||
</Box>}
|
||||
<Typography fontSize="12px" lineHeight="15px">{finalityDelay} blocks</Typography>
|
||||
</Box>
|
||||
<hr width="100%" />
|
||||
<Box maxWidth="416px" display="flex" justifyContent={isVerySmallScreen ? "end" : "space-between"}>
|
||||
{!isVerySmallScreen && <Typography fontSize="12px" lineHeight="15px">Current Epoch:</Typography>}
|
||||
<Typography fontSize="12px" lineHeight="15px">{currentSession ?? 0}</Typography>
|
||||
</Box>
|
||||
<Box maxWidth="416px" display="flex" justifyContent={isVerySmallScreen ? "end" : "space-between"}>
|
||||
{!isVerySmallScreen && <Typography fontSize="12px" lineHeight="15px">Number of validators:</Typography>}
|
||||
{!isVerySmallScreen && <Box display="flex" flexDirection="row">
|
||||
<Typography fontSize="12px" lineHeight="15px">Number of validators:</Typography>
|
||||
<InfoTooltip message={<>
|
||||
<Typography variant="subtitle1">Validators</Typography>
|
||||
<Box
|
||||
width="280px"
|
||||
height="250px"
|
||||
margin="0"
|
||||
padding="0"
|
||||
marginTop="5px"
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
sx={{ overflowY: "auto" }}
|
||||
>
|
||||
{authorities?.map((authority, idx) => {
|
||||
const authorityAddress = ss58Address(authority.asHex(), 1996);
|
||||
const clapInfo = clapsInSession?.at(idx)?.at(1);
|
||||
|
||||
return (
|
||||
<Box
|
||||
key={idx}
|
||||
display="flex"
|
||||
flexDirection="row"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
sx={{
|
||||
fontSize: "10px",
|
||||
color: !clapInfo?.disabled
|
||||
? theme.colors.primary[300]
|
||||
: theme.colors.feedback.error
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: "250px",
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'normal',
|
||||
textOverflow: "ellipsis"
|
||||
}}
|
||||
>
|
||||
{authorityAddress}
|
||||
</div>
|
||||
<div>{clapInfo?.claps ?? 0}</div>
|
||||
</Box>
|
||||
)
|
||||
})}
|
||||
</Box>
|
||||
</>} />
|
||||
</Box>}
|
||||
<Typography fontSize="12px" lineHeight="15px">{clapsInSessionLength}</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
@ -625,11 +790,7 @@ const Bridge = ({ chainId, address, config, connect }) => {
|
||||
loading={isPending}
|
||||
onClick={() => ghostOrConnect()}
|
||||
>
|
||||
{address === "" ?
|
||||
"Connect"
|
||||
:
|
||||
"Bridge"
|
||||
}
|
||||
{address === "" ? "Connect" : "Bridge" }
|
||||
</PrimaryButton>
|
||||
</>
|
||||
)}
|
||||
|
Loading…
Reference in New Issue
Block a user