add ghost connect into right side panel
Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
This commit is contained in:
parent
0879af509e
commit
85055ff4c5
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "ghost-dao-interface",
|
"name": "ghost-dao-interface",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.7.54",
|
"version": "0.7.55",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@ -18,13 +18,14 @@ 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, useWallet } from "./Token";
|
import { Tokens, NativeToken, 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";
|
||||||
|
|
||||||
@ -52,12 +53,12 @@ const CloseButton = styled(IconButton)(theme => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const WalletTotalValue = ({ address, tokens }) => {
|
const WalletTotalValue = ({ chainName, address, tokens, currency, setCurrency }) => {
|
||||||
const ghstPrice = tokens.ghst.price;
|
const ghstPrice = tokens?.ghst ? tokens.ghst.price : tokens?.price;
|
||||||
const [currency, setCurrency] = useState("USD");
|
const tokensObject = tokens?.ghst ? tokens : { tokens };
|
||||||
const [topHovered, setTopHovered] = useState(false);
|
const [topHovered, setTopHovered] = useState(false);
|
||||||
|
|
||||||
const walletTotalValueUSD = Object.values(tokens).reduce(
|
const walletTotalValueUSD = Object.values(tokensObject).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),
|
||||||
);
|
);
|
||||||
@ -77,16 +78,16 @@ const WalletTotalValue = ({ address, tokens }) => {
|
|||||||
onMouseEnter={() => setTopHovered(true)}
|
onMouseEnter={() => setTopHovered(true)}
|
||||||
onMouseLeave={() => setTopHovered(false)}
|
onMouseLeave={() => setTopHovered(false)}
|
||||||
>
|
>
|
||||||
<Box width="120px" display="flex" flexDirection="row" justifyContent="space-between" alignItems="center">
|
<Box width="100%" 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">
|
||||||
MY WALLET
|
{chainName?.toUpperCase()}
|
||||||
</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>
|
||||||
<Box pt="1px">
|
{tokens?.ghst && <Box pt="1px">
|
||||||
<GhostStyledIcon
|
<GhostStyledIcon
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
component={LoopIcon}
|
component={LoopIcon}
|
||||||
@ -96,12 +97,11 @@ const WalletTotalValue = ({ address, tokens }) => {
|
|||||||
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], 2, currency === "USD" ? "USD" : "👻" )}
|
{formatCurrency(walletValue[currency], currency === "USD" ? 2 : 5, currency === "USD" ? "USD" : "👻" )}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
@ -112,6 +112,9 @@ 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(() => {
|
||||||
@ -120,6 +123,26 @@ function InitialWalletView({ isWalletOpen, address, chainId, onClose }) {
|
|||||||
return chain.name.toLowerCase()
|
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,
|
||||||
@ -148,7 +171,13 @@ 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 address={address} tokens={tokens} />
|
<WalletTotalValue
|
||||||
|
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>
|
||||||
@ -158,7 +187,7 @@ function InitialWalletView({ isWalletOpen, address, chainId, onClose }) {
|
|||||||
<Divider />
|
<Divider />
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box sx={{ display: "flex", flexDirection: "column" }} style={{ gap: theme.spacing(1) }}>
|
<Box sx={{ display: "flex", flexDirection: "column" }} >
|
||||||
<Tokens address={address} tokens={tokens} onClose={onClose} />
|
<Tokens address={address} tokens={tokens} onClose={onClose} />
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
@ -166,6 +195,46 @@ 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,6 +19,7 @@ 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";
|
||||||
@ -68,6 +69,57 @@ 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,
|
||||||
@ -75,7 +127,7 @@ export const Token = (props) => {
|
|||||||
faucetPath,
|
faucetPath,
|
||||||
icons,
|
icons,
|
||||||
address,
|
address,
|
||||||
price = 0,
|
price,
|
||||||
balance,
|
balance,
|
||||||
onAddTokenToWallet,
|
onAddTokenToWallet,
|
||||||
expanded,
|
expanded,
|
||||||
@ -136,7 +188,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>
|
||||||
@ -294,7 +346,7 @@ export const useWallet = (chainId, userAddress) => {
|
|||||||
}, {});
|
}, {});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Tokens = ({ address, tokens, onClose }) => {
|
export const Tokens = ({ address, tokens, isNative, 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];
|
||||||
|
|
||||||
@ -310,7 +362,7 @@ export const Tokens = ({ address, tokens, 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)} />
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -24,6 +24,21 @@ 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';
|
||||||
@ -52,10 +67,11 @@ export const UnstableProviderProvider = ({ children }) => {
|
|||||||
providerDetail,
|
providerDetail,
|
||||||
connectProviderByIndex: setProviderIndex,
|
connectProviderByIndex: setProviderIndex,
|
||||||
chainId,
|
chainId,
|
||||||
|
account,
|
||||||
client,
|
client,
|
||||||
setChainId,
|
setChainId,
|
||||||
chainHead$
|
chainHead$
|
||||||
}), [providerDetails, providerDetail, chainId, client, chainHead$]);
|
}), [providerDetails, providerDetail, chainId, client, account, chainHead$]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UnstableProvider.Provider value={value}>
|
<UnstableProvider.Provider value={value}>
|
||||||
|
|||||||
@ -14,3 +14,5 @@ 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";
|
||||||
|
|||||||
31
src/hooks/ghost/useChainSpec.js
Normal file
31
src/hooks/ghost/useChainSpec.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
41
src/hooks/ghost/useSystemAccount.js
Normal file
41
src/hooks/ghost/useSystemAccount.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
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