Compare commits
No commits in common. "85055ff4c546604cf91c70e955d5c4df2287a210" and "3ad84a886e9f737348efade560340debec6a555d" have entirely different histories.
85055ff4c5
...
3ad84a886e
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "ghost-dao-interface",
|
"name": "ghost-dao-interface",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.7.55",
|
"version": "0.7.51",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@ -18,14 +18,13 @@ import { ReactElement, useState, useEffect } from "react";
|
|||||||
import { useNavigate, useLocation, createSearchParams } from "react-router-dom";
|
import { useNavigate, useLocation, createSearchParams } from "react-router-dom";
|
||||||
|
|
||||||
import GhostStyledIcon from "../../Icon/GhostIcon";
|
import GhostStyledIcon from "../../Icon/GhostIcon";
|
||||||
import { Tokens, NativeToken, useWallet } from "./Token";
|
import { Tokens, useWallet } from "./Token";
|
||||||
import { PrimaryButton, SecondaryButton } from "../../Button";
|
import { PrimaryButton, SecondaryButton } from "../../Button";
|
||||||
|
|
||||||
import ArrowUpIcon from "../../../assets/icons/arrow-up.svg?react";
|
import ArrowUpIcon from "../../../assets/icons/arrow-up.svg?react";
|
||||||
import { formatCurrency, shorten } from "../../../helpers";
|
import { formatCurrency, shorten } from "../../../helpers";
|
||||||
import { DecimalBigNumber } from "../../../helpers/DecimalBigNumber";
|
import { DecimalBigNumber } from "../../../helpers/DecimalBigNumber";
|
||||||
import { RESERVE_ADDRESSES, FTSO_ADDRESSES } from "../../../constants/addresses";
|
import { RESERVE_ADDRESSES, FTSO_ADDRESSES } from "../../../constants/addresses";
|
||||||
import { useUnstableProvider, useSystemAccount, useChainSpec } from "../../../hooks/ghost"
|
|
||||||
|
|
||||||
import { useAccount, useDisconnect, useSwitchChain } from "wagmi";
|
import { useAccount, useDisconnect, useSwitchChain } from "wagmi";
|
||||||
|
|
||||||
@ -53,12 +52,12 @@ const CloseButton = styled(IconButton)(theme => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const WalletTotalValue = ({ chainName, address, tokens, currency, setCurrency }) => {
|
const WalletTotalValue = ({ address, tokens }) => {
|
||||||
const ghstPrice = tokens?.ghst ? tokens.ghst.price : tokens?.price;
|
const ghstPrice = tokens.ghst.price;
|
||||||
const tokensObject = tokens?.ghst ? tokens : { tokens };
|
const [currency, setCurrency] = useState("USD");
|
||||||
const [topHovered, setTopHovered] = useState(false);
|
const [topHovered, setTopHovered] = useState(false);
|
||||||
|
|
||||||
const walletTotalValueUSD = Object.values(tokensObject).reduce(
|
const walletTotalValueUSD = Object.values(tokens).reduce(
|
||||||
(totalValue, token) => totalValue.add(token.balance.mul(token.price)),
|
(totalValue, token) => totalValue.add(token.balance.mul(token.price)),
|
||||||
new DecimalBigNumber(0n, 0),
|
new DecimalBigNumber(0n, 0),
|
||||||
);
|
);
|
||||||
@ -78,16 +77,16 @@ const WalletTotalValue = ({ chainName, address, tokens, currency, setCurrency })
|
|||||||
onMouseEnter={() => setTopHovered(true)}
|
onMouseEnter={() => setTopHovered(true)}
|
||||||
onMouseLeave={() => setTopHovered(false)}
|
onMouseLeave={() => setTopHovered(false)}
|
||||||
>
|
>
|
||||||
<Box width="100%" display="flex" flexDirection="row" justifyContent="space-between" alignItems="center">
|
<Box width="120px" display="flex" flexDirection="row" justifyContent="space-between" alignItems="center">
|
||||||
<Box>
|
<Box>
|
||||||
<Typography style={{ lineHeight: 1.1, fontWeight: 600, fontSize: "0.975rem" }} color="textSecondary">
|
<Typography style={{ lineHeight: 1.1, fontWeight: 600, fontSize: "0.975rem" }} color="textSecondary">
|
||||||
{chainName?.toUpperCase()}
|
MY WALLET
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography style={{ fontSize: ".85rem", lineHeight: 1.1 }} variant="h3">
|
<Typography style={{ fontSize: ".85rem", lineHeight: 1.1 }} variant="h3">
|
||||||
{shorten(address)}
|
{shorten(address)}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
{tokens?.ghst && <Box pt="1px">
|
<Box pt="1px">
|
||||||
<GhostStyledIcon
|
<GhostStyledIcon
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
component={LoopIcon}
|
component={LoopIcon}
|
||||||
@ -97,11 +96,12 @@ const WalletTotalValue = ({ chainName, address, tokens, currency, setCurrency })
|
|||||||
transform: topHovered ? "rotateZ(-180deg)" : "rotateZ(0deg)",
|
transform: topHovered ? "rotateZ(-180deg)" : "rotateZ(0deg)",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>}
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
|
||||||
<Typography style={{ fontWeight: 700 }} variant="h3">
|
<Typography style={{ fontWeight: 700 }} variant="h3">
|
||||||
{formatCurrency(walletValue[currency], currency === "USD" ? 2 : 5, currency === "USD" ? "USD" : "👻" )}
|
{formatCurrency(walletValue[currency], 2, currency === "USD" ? "USD" : "👻" )}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
@ -112,37 +112,12 @@ function InitialWalletView({ isWalletOpen, address, chainId, onClose }) {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const tokens = useWallet(chainId, address);
|
const tokens = useWallet(chainId, address);
|
||||||
|
|
||||||
const [currency, setCurrency] = useState("USD");
|
|
||||||
const { account, isExtensionMissing } = useUnstableProvider();
|
|
||||||
const { chains } = useSwitchChain();
|
const { chains } = useSwitchChain();
|
||||||
|
|
||||||
const chainName = useMemo(() => {
|
const chainName = useMemo(() => {
|
||||||
const chain = chains.find(chain => chain.id === chainId)
|
return chains.find(chain => chain.id === chainId).name.toLowerCase();
|
||||||
if (!chain) return null
|
|
||||||
return chain.name.toLowerCase()
|
|
||||||
}, [chains, chainId])
|
}, [chains, chainId])
|
||||||
|
|
||||||
const chainSpec = useChainSpec();
|
|
||||||
const accountBalanceRaw = useSystemAccount({ account });
|
|
||||||
|
|
||||||
const accountBalance = useMemo(() => {
|
|
||||||
const decimals = chainSpec ? chainSpec.properties.tokenDecimals : 18;
|
|
||||||
if (!accountBalanceRaw) return new DecimalBigNumber(0n, decimals);
|
|
||||||
const balance = accountBalanceRaw.data.free
|
|
||||||
+ accountBalanceRaw.data.frozen
|
|
||||||
+ accountBalanceRaw.data.reserved;
|
|
||||||
|
|
||||||
return new DecimalBigNumber(balance, decimals);
|
|
||||||
}, [accountBalanceRaw, chainSpec])
|
|
||||||
|
|
||||||
const nativeGhst = useMemo(() => {
|
|
||||||
return {
|
|
||||||
...tokens.ghst,
|
|
||||||
balance: accountBalance,
|
|
||||||
}
|
|
||||||
}, [tokens, accountBalance])
|
|
||||||
|
|
||||||
const onBtnClick = (dexName, from, to) => {
|
const onBtnClick = (dexName, from, to) => {
|
||||||
navigate({
|
navigate({
|
||||||
pathname: `${chains.find(chain => chain.id === chainId).name.toLowerCase()}/dex/` + dexName,
|
pathname: `${chains.find(chain => chain.id === chainId).name.toLowerCase()}/dex/` + dexName,
|
||||||
@ -156,7 +131,7 @@ function InitialWalletView({ isWalletOpen, address, chainId, onClose }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isWalletOpen && chainName) {
|
if (isWalletOpen) {
|
||||||
ReactGA.send({ hitType: "pageview", page: `/${chainName.toLowerCase()}/sidebar` });
|
ReactGA.send({ hitType: "pageview", page: `/${chainName.toLowerCase()}/sidebar` });
|
||||||
}
|
}
|
||||||
}, [isWalletOpen, chainName])
|
}, [isWalletOpen, chainName])
|
||||||
@ -171,13 +146,7 @@ function InitialWalletView({ isWalletOpen, address, chainId, onClose }) {
|
|||||||
<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" }}>
|
||||||
<Box sx={{ display: "flex", justifyContent: "space-between", padding: theme.spacing(3, 0, 1) }}>
|
<Box sx={{ display: "flex", justifyContent: "space-between", padding: theme.spacing(3, 0, 1) }}>
|
||||||
<WalletTotalValue
|
<WalletTotalValue address={address} tokens={tokens} />
|
||||||
currency={currency}
|
|
||||||
setCurrency={setCurrency}
|
|
||||||
chainName={chainName}
|
|
||||||
address={address}
|
|
||||||
tokens={tokens}
|
|
||||||
/>
|
|
||||||
<CloseButton size="small" onClick={onClose} aria-label="close wallet">
|
<CloseButton size="small" onClick={onClose} aria-label="close wallet">
|
||||||
<GhostStyledIcon component={CloseIcon} />
|
<GhostStyledIcon component={CloseIcon} />
|
||||||
</CloseButton>
|
</CloseButton>
|
||||||
@ -187,7 +156,7 @@ function InitialWalletView({ isWalletOpen, address, chainId, onClose }) {
|
|||||||
<Divider />
|
<Divider />
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box sx={{ display: "flex", flexDirection: "column" }} >
|
<Box sx={{ display: "flex", flexDirection: "column" }} style={{ gap: theme.spacing(1) }}>
|
||||||
<Tokens address={address} tokens={tokens} onClose={onClose} />
|
<Tokens address={address} tokens={tokens} onClose={onClose} />
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
@ -195,46 +164,6 @@ function InitialWalletView({ isWalletOpen, address, chainId, onClose }) {
|
|||||||
<Divider />
|
<Divider />
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{!isExtensionMissing
|
|
||||||
? <>
|
|
||||||
<Box sx={{ display: "flex", flexDirection: "column" }} style={{ gap: theme.spacing(2, 1) }}>
|
|
||||||
<WalletTotalValue
|
|
||||||
currency={currency}
|
|
||||||
setCurrency={setCurrency}
|
|
||||||
chainName={chainSpec?.chainName ?? ""}
|
|
||||||
address={account ?? "...wait"}
|
|
||||||
tokens={nativeGhst}
|
|
||||||
/>
|
|
||||||
<NativeToken {...nativeGhst} />
|
|
||||||
</Box>
|
|
||||||
<Box sx={{ margin: theme.spacing(2, -3, 3) }}>
|
|
||||||
<Divider />
|
|
||||||
</Box>
|
|
||||||
</>
|
|
||||||
: <Box
|
|
||||||
sx={{ borderRadius: "15px", background: theme.colors.paper.background }}
|
|
||||||
width="100%"
|
|
||||||
height="100%"
|
|
||||||
padding="20px 30px"
|
|
||||||
display="flex"
|
|
||||||
flexDirection="column"
|
|
||||||
justifyContent="space-around"
|
|
||||||
alignItems="center"
|
|
||||||
gap="10px"
|
|
||||||
>
|
|
||||||
<Typography sx={{ textAlign: "center" }} variant="subtitle1">GHOST Connect is not detected!</Typography>
|
|
||||||
<Typography sx={{ textAlign: "center" }} variant="body2">Download GHOST Connect for bounties, validator stats, and (10, 10) {"Stake\u00B2"} rewards.</Typography>
|
|
||||||
<PrimaryButton
|
|
||||||
fullWidth
|
|
||||||
onClick={() => window.open(GHOST_CONNECT, '_blank', 'noopener,noreferrer')}
|
|
||||||
>
|
|
||||||
Get GHOST Connect
|
|
||||||
</PrimaryButton>
|
|
||||||
</Box>
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Box sx={{ width: "100%", marginTop: "auto", marginX: "auto", padding: theme.spacing(2, 0) }}>
|
<Box sx={{ width: "100%", marginTop: "auto", marginX: "auto", padding: theme.spacing(2, 0) }}>
|
||||||
<DisconnectButton onClose={onClose} />
|
<DisconnectButton onClose={onClose} />
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@ -19,7 +19,6 @@ import { EMPTY_ADDRESS } from "../../../constants/addresses";
|
|||||||
|
|
||||||
import GhostStyledIcon from "../../Icon/GhostIcon";
|
import GhostStyledIcon from "../../Icon/GhostIcon";
|
||||||
import TokenStack from "../../TokenStack/TokenStack";
|
import TokenStack from "../../TokenStack/TokenStack";
|
||||||
import SingleToken from "../../Token/Token";
|
|
||||||
import { PrimaryButton, SecondaryButton } from "../../Button";
|
import { PrimaryButton, SecondaryButton } from "../../Button";
|
||||||
|
|
||||||
import { useBalance, useTokenSymbol } from "../../../hooks/tokens";
|
import { useBalance, useTokenSymbol } from "../../../hooks/tokens";
|
||||||
@ -69,57 +68,6 @@ const BalanceValue = ({
|
|||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|
||||||
export const NativeToken = (props) => {
|
|
||||||
const theme = useTheme();
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const chainId = useChainId();
|
|
||||||
|
|
||||||
const { chains } = useSwitchChain();
|
|
||||||
|
|
||||||
const chainName = useMemo(() => {
|
|
||||||
return chains.find(chain => chain.id === chainId).name.toLowerCase();
|
|
||||||
}, [chains, chainId])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Accordion expanded={props.expanded} onChange={props.onChangeExpanded}>
|
|
||||||
<AccordionSummary expandIcon={<GhostStyledIcon component={ExpandMoreIcon} color="disabled" />} >
|
|
||||||
<Box sx={{ display: "flex", justifyContent: "space-between", width: "100%", marginRight: "10px" }}>
|
|
||||||
<Box sx={{ display: "flex", alignItems: "center", gap: "15px" }}>
|
|
||||||
<SingleToken
|
|
||||||
sx={{
|
|
||||||
width: "30px",
|
|
||||||
height: "30px",
|
|
||||||
}}
|
|
||||||
name="GHST"
|
|
||||||
isNative
|
|
||||||
/>
|
|
||||||
<Typography>{props.symbol}</Typography>
|
|
||||||
</Box>
|
|
||||||
<BalanceValue
|
|
||||||
balance={props.balance}
|
|
||||||
balanceValueUSD={props.balance.mul(props.price)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</AccordionSummary>
|
|
||||||
<AccordionDetails style={{ margin: "auto", padding: theme.spacing(1, 0) }}>
|
|
||||||
<Box
|
|
||||||
sx={{ display: "flex", flexDirection: "column", flex: 1, mx: "32px", justifyContent: "center" }}
|
|
||||||
style={{ gap: theme.spacing(1) }}
|
|
||||||
>
|
|
||||||
<Box display="flex" flexDirection="column" className="ghst-pairs" style={{ width: "100%" }}>
|
|
||||||
<PrimaryButton
|
|
||||||
onClick={() =>{ navigate({ pathname: `${chainName}/bridge` }); onClose(); }}
|
|
||||||
fullWidth
|
|
||||||
>
|
|
||||||
<Typography>Get (10, 10) Stake</Typography>
|
|
||||||
</PrimaryButton>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
</AccordionDetails>
|
|
||||||
</Accordion>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Token = (props) => {
|
export const Token = (props) => {
|
||||||
const {
|
const {
|
||||||
isNative,
|
isNative,
|
||||||
@ -127,7 +75,7 @@ export const Token = (props) => {
|
|||||||
faucetPath,
|
faucetPath,
|
||||||
icons,
|
icons,
|
||||||
address,
|
address,
|
||||||
price,
|
price = 0,
|
||||||
balance,
|
balance,
|
||||||
onAddTokenToWallet,
|
onAddTokenToWallet,
|
||||||
expanded,
|
expanded,
|
||||||
@ -188,7 +136,7 @@ export const Token = (props) => {
|
|||||||
</Box>
|
</Box>
|
||||||
<BalanceValue
|
<BalanceValue
|
||||||
balance={balance}
|
balance={balance}
|
||||||
balanceValueUSD={balance?.mul(price)}
|
balanceValueUSD={balance.mul(price)}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</AccordionSummary>
|
</AccordionSummary>
|
||||||
@ -346,7 +294,7 @@ export const useWallet = (chainId, userAddress) => {
|
|||||||
}, {});
|
}, {});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Tokens = ({ address, tokens, isNative, onClose }) => {
|
export const Tokens = ({ address, tokens, onClose }) => {
|
||||||
const [expanded, setExpanded] = useState(null);
|
const [expanded, setExpanded] = useState(null);
|
||||||
const alwaysShowTokens = [tokens.native, tokens.reserve, tokens.ftso, tokens.ghst, tokens.reserveFtso];
|
const alwaysShowTokens = [tokens.native, tokens.reserve, tokens.ftso, tokens.ghst, tokens.reserveFtso];
|
||||||
|
|
||||||
@ -362,7 +310,7 @@ export const Tokens = ({ address, tokens, isNative, onClose }) => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{alwaysShowTokens.map((token, i) => (
|
{alwaysShowTokens.map((token, i) => (
|
||||||
<Token key={i} isNative={i == 0} {...tokenProps(token)} />
|
<Token key={i} isNative={i === 0} {...tokenProps(token)} />
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -143,7 +143,7 @@ const BondConfirmModal = ({
|
|||||||
<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 display="flex" flexDirection="column">
|
||||||
<Metric
|
<Metric
|
||||||
label="To Bond"
|
label="Assets to Bond"
|
||||||
metric={spendAmount}
|
metric={spendAmount}
|
||||||
/>
|
/>
|
||||||
<Box
|
<Box
|
||||||
@ -171,7 +171,7 @@ const BondConfirmModal = ({
|
|||||||
</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="To Receive" metric={receiveAmount} />
|
<Metric label="Assets to Receive" metric={receiveAmount} />
|
||||||
<Box
|
<Box
|
||||||
sx={{ background: "" }}
|
sx={{ background: "" }}
|
||||||
height="120px"
|
height="120px"
|
||||||
|
|||||||
@ -128,7 +128,7 @@ const StakeConfirmationModal = (props) => {
|
|||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
data-testid="stake-confirmation-modal"
|
data-testid="stake-confirmation-modal"
|
||||||
maxWidth="406px"
|
maxWidth="476px"
|
||||||
headerContent={
|
headerContent={
|
||||||
<Typography variant="h4">{`Confirm ${props.action}`}</Typography>
|
<Typography variant="h4">{`Confirm ${props.action}`}</Typography>
|
||||||
}
|
}
|
||||||
@ -140,7 +140,7 @@ const StakeConfirmationModal = (props) => {
|
|||||||
<Box display="flex" flexDirection="row" justifyContent="space-between" alignItems="center">
|
<Box display="flex" flexDirection="row" justifyContent="space-between" alignItems="center">
|
||||||
<Box height="170px" display="flex" flexDirection="column">
|
<Box height="170px" display="flex" flexDirection="column">
|
||||||
<Metric
|
<Metric
|
||||||
label={`To ${props.action}`}
|
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="column" justifyContent="center" alignItems="center">
|
<Box display="flex" flexDirection="column" justifyContent="center" alignItems="center">
|
||||||
@ -162,7 +162,7 @@ const StakeConfirmationModal = (props) => {
|
|||||||
<GhostStyledIcon component={ArrowRightIcon} />
|
<GhostStyledIcon component={ArrowRightIcon} />
|
||||||
<Box display="flex" flexDirection="column">
|
<Box display="flex" flexDirection="column">
|
||||||
<Metric
|
<Metric
|
||||||
label="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="column" justifyContent="center" alignItems="center">
|
<Box display="flex" flexDirection="column" justifyContent="center" alignItems="center">
|
||||||
|
|||||||
@ -126,7 +126,7 @@ const ProtocolDetails = ({ chainId, isMobileScreen, theme, }) => {
|
|||||||
url={`/${networkName.toLowerCase()}/bridge`}
|
url={`/${networkName.toLowerCase()}/bridge`}
|
||||||
name={`${bridgeNumbers} Stake\u00B2`}
|
name={`${bridgeNumbers} Stake\u00B2`}
|
||||||
sideName={`${formatNumber(gatekeepedApy, 2)}% APY`}
|
sideName={`${formatNumber(gatekeepedApy, 2)}% APY`}
|
||||||
description={`Staking\u00B2 strategy further deepens long-term incentives powered by sustainable cross-chain bridging revenue. ${bridgeNumbers} Stake\u00B2 ${csprSymbol} to receive organic APY with no warmup 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>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@ -24,21 +24,6 @@ export const UnstableProviderProvider = ({ children }) => {
|
|||||||
() => providerDetail ? providerDetail.provider : null
|
() => providerDetail ? providerDetail.provider : null
|
||||||
);
|
);
|
||||||
|
|
||||||
const { data: accounts } = useSWR(
|
|
||||||
() => providerDetail ? `providerDetail.${providerDetail.info.uuid}.provider.getAccounts(${chainId})` : null,
|
|
||||||
async () => {
|
|
||||||
if (!providerDetail) return []
|
|
||||||
const activeProvider = await providerDetail.provider;
|
|
||||||
return activeProvider.getAccounts(chainId);
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
const account = useMemo(() => {
|
|
||||||
if (Array.isArray(accounts)) return accounts.at(0).address;
|
|
||||||
if (typeof accounts === 'string') return accounts.address;
|
|
||||||
return undefined
|
|
||||||
}, [accounts])
|
|
||||||
|
|
||||||
const connectionState = useMemo(() => {
|
const connectionState = useMemo(() => {
|
||||||
if (!providerDetail) return 'no-extension';
|
if (!providerDetail) return 'no-extension';
|
||||||
if (!provider) return 'loading';
|
if (!provider) return 'loading';
|
||||||
@ -67,11 +52,10 @@ export const UnstableProviderProvider = ({ children }) => {
|
|||||||
providerDetail,
|
providerDetail,
|
||||||
connectProviderByIndex: setProviderIndex,
|
connectProviderByIndex: setProviderIndex,
|
||||||
chainId,
|
chainId,
|
||||||
account,
|
|
||||||
client,
|
client,
|
||||||
setChainId,
|
setChainId,
|
||||||
chainHead$
|
chainHead$
|
||||||
}), [providerDetails, providerDetail, chainId, client, account, chainHead$]);
|
}), [providerDetails, providerDetail, chainId, client, chainHead$]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UnstableProvider.Provider value={value}>
|
<UnstableProvider.Provider value={value}>
|
||||||
|
|||||||
@ -14,5 +14,3 @@ export * from "./useBabeSlots";
|
|||||||
export * from "./useErasTotalStaked";
|
export * from "./useErasTotalStaked";
|
||||||
export * from "./useLatestBlockNumber";
|
export * from "./useLatestBlockNumber";
|
||||||
export * from "./useEraIndex";
|
export * from "./useEraIndex";
|
||||||
export * from "./useSystemAccount";
|
|
||||||
export * from "./useChainSpec";
|
|
||||||
|
|||||||
@ -1,31 +0,0 @@
|
|||||||
import useSWR from "swr"
|
|
||||||
import { useUnstableProvider } from "./UnstableProvider"
|
|
||||||
|
|
||||||
export const useChainSpec = () => {
|
|
||||||
const { client } = useUnstableProvider()
|
|
||||||
const { data: chainSpecV1 } = useSWR(
|
|
||||||
client ? ["chainSpec_v1_", client] : null,
|
|
||||||
async ([prefix, client]) => {
|
|
||||||
const methods = ["chainName", "properties", "genesisHash"]
|
|
||||||
const responses = await Promise.all(methods.map((method) => {
|
|
||||||
return new Promise((resolve, reject) =>
|
|
||||||
client._request(`${prefix}${method}`, [], {
|
|
||||||
onSuccess: resolve,
|
|
||||||
onError: reject,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.catch((_) => undefined)
|
|
||||||
}))
|
|
||||||
return {
|
|
||||||
chainName: responses?.at(0),
|
|
||||||
properties: responses?.at(1),
|
|
||||||
genesisHash: responses?.at(2)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
revalidateOnFocus: false,
|
|
||||||
refreshInterval: 0
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return chainSpecV1
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
import useSWRSubscription from "swr/subscription"
|
|
||||||
import { getDynamicBuilder, getLookupFn } from "@polkadot-api/metadata-builders"
|
|
||||||
import { distinct, filter, map, mergeMap } from "rxjs"
|
|
||||||
|
|
||||||
import { useUnstableProvider } from "./UnstableProvider"
|
|
||||||
import { useMetadata } from "./MetadataProvider"
|
|
||||||
|
|
||||||
export const useSystemAccount = ({ account }) => {
|
|
||||||
const { chainHead$, chainId } = useUnstableProvider()
|
|
||||||
const metadata = useMetadata()
|
|
||||||
const { data: systemAccount } = useSWRSubscription(
|
|
||||||
chainHead$ && chainId && account && metadata
|
|
||||||
? ["systemAccount", chainHead$, chainId, account, metadata]
|
|
||||||
: null,
|
|
||||||
([_, chainHead$, chainId, account, metadata], { next }) => {
|
|
||||||
const { finalized$, storage$ } = chainHead$
|
|
||||||
const subscription = finalized$.pipe(
|
|
||||||
filter(Boolean),
|
|
||||||
mergeMap((blockInfo) => {
|
|
||||||
const builder = getDynamicBuilder(getLookupFn(metadata))
|
|
||||||
const storageAccount = builder.buildStorage("System", "Account")
|
|
||||||
return storage$(blockInfo?.hash, "value", () =>
|
|
||||||
storageAccount?.keys.enc(account)
|
|
||||||
).pipe(
|
|
||||||
filter(Boolean),
|
|
||||||
distinct(),
|
|
||||||
map((value) => storageAccount?.value.dec(value))
|
|
||||||
)
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.subscribe({
|
|
||||||
next(systemAccount) {
|
|
||||||
next(null, systemAccount)
|
|
||||||
},
|
|
||||||
error: next,
|
|
||||||
})
|
|
||||||
return () => subscription.unsubscribe()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return systemAccount
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user