Compare commits
3 Commits
843093915f
...
3316f7640e
| Author | SHA1 | Date | |
|---|---|---|---|
| 3316f7640e | |||
| 18ba617a43 | |||
| f7198b9e3f |
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "ghost-dao-interface",
|
||||
"private": true,
|
||||
"version": "0.5.36",
|
||||
"version": "0.5.39",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@ -34,6 +34,7 @@ const Select = ({
|
||||
inputWidth,
|
||||
renderValue = null,
|
||||
width = "100%",
|
||||
maxWidth = "100%"
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
@ -41,6 +42,7 @@ const Select = ({
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
width={width}
|
||||
maxWidth={maxWidth}
|
||||
sx={{ backgroundColor: theme.colors.gray[750] }}
|
||||
borderRadius="12px"
|
||||
padding="15px"
|
||||
|
||||
@ -10,6 +10,7 @@ import {
|
||||
useMediaQuery,
|
||||
} from "@mui/material";
|
||||
import { decodeAddress } from "@polkadot/util-crypto";
|
||||
import { fromHex } from "@polkadot-api/utils";
|
||||
import { getBlockNumber } from "@wagmi/core";
|
||||
import { useTransaction } from "wagmi";
|
||||
import { keccak256 } from "viem";
|
||||
@ -42,6 +43,8 @@ import {
|
||||
useCurrentSlot,
|
||||
useGenesisSlot,
|
||||
useErasTotalStake,
|
||||
useLatestBlockNumber,
|
||||
useEraIndex,
|
||||
} from "../../hooks/ghost";
|
||||
|
||||
import { ValidatorTable } from "./ValidatorTable";
|
||||
@ -102,24 +105,28 @@ const Bridge = ({ chainId, address, config, connect }) => {
|
||||
const networkIdEncoded = u64.enc(BigInt(chainId));
|
||||
const amountEncoded = u128.enc(BigInt(watchTransaction.amount));
|
||||
const addressEncoded = decodeAddress(watchTransaction.receiverAddress, false, 1996);
|
||||
const transactionHashEncoded = fromHex(watchTransaction.transactionHash);
|
||||
const blockNumber = u64.enc(watchTransactionInfo?.blockNumber ?? 0n);
|
||||
|
||||
const clapArgsStr = new Uint8Array([
|
||||
...addressEncoded,
|
||||
...amountEncoded,
|
||||
...blockNumber,
|
||||
...transactionHashEncoded,
|
||||
...networkIdEncoded
|
||||
]);
|
||||
return keccak256(clapArgsStr)
|
||||
}, [watchTransaction, watchTransactionInfo])
|
||||
|
||||
const latestBlockNumber = useLatestBlockNumber();
|
||||
const eraIndex = useEraIndex();
|
||||
const currentSlot = useCurrentSlot();
|
||||
const genesisSlot = useGenesisSlot();
|
||||
const currentSession = useCurrentIndex();
|
||||
const applauseThreshold = useApplauseThreshold();
|
||||
const evmNetwork = useEvmNetwork({ evmChainId: chainId });
|
||||
const totalStakedAmount = useErasTotalStake({
|
||||
eraIndex: Math.floor((watchTransaction?.sessionIndex ?? currentSession) / 6)
|
||||
eraIndex: eraIndex?.index ?? 0,
|
||||
});
|
||||
const authorities = useAuthorities({
|
||||
currentSession: watchTransaction?.sessionIndex ?? currentSession
|
||||
@ -205,16 +212,20 @@ const Bridge = ({ chainId, address, config, connect }) => {
|
||||
|
||||
const latestCommits = useMemo(() => {
|
||||
return validators?.map((validator, index) => {
|
||||
const lastUpdatedNumber = Number(blockCommitments?.at(index)?.last_updated ?? 0);
|
||||
const timestampDelta = (latestBlockNumber - lastUpdatedNumber) * 6000; // ideal 6 seconds for block
|
||||
const lastUpdatedTimestamp = Math.floor(currentTime - timestampDelta);
|
||||
|
||||
return {
|
||||
validator: validator,
|
||||
lastActive: currentTime - Number(blockCommitments?.at(index)?.last_updated ?? 0),
|
||||
lastUpdated: blockCommitments?.at(index)?.last_updated,
|
||||
lastActive: timestampDelta,
|
||||
lastUpdated: lastUpdatedTimestamp,
|
||||
lastStoredBlock: blockCommitments?.at(index)?.last_stored_block,
|
||||
storedBlockTime: (blockCommitments?.at(index)?.last_stored_block ?? 0n) * networkAvgBlockSpeed(chainId),
|
||||
disabled: disabledValidators?.includes(index),
|
||||
}
|
||||
})
|
||||
}, [blockCommitments, disabledValidators, validators, chainId]);
|
||||
}, [blockCommitments, disabledValidators, validators, latestBlockNumber, chainId]);
|
||||
|
||||
const latestUpdate = useMemo(() => {
|
||||
const validCommits = latestCommits?.filter(commit =>
|
||||
|
||||
@ -311,6 +311,7 @@ const TokenAndBooleansArguments = ({
|
||||
value={selectedOption ?? ""}
|
||||
onChange={handleChange}
|
||||
options={possibleTokens}
|
||||
maxWidth="calc(100vw - 70px)"
|
||||
inputWidth="100%"
|
||||
renderValue={(selected) => {
|
||||
if (!selected || selected.length === 0) {
|
||||
|
||||
@ -55,7 +55,7 @@ export const SetAdjustmentSteps = ({ chainId, toInitialStep, addCalldata, args }
|
||||
|
||||
const [rate, setRate] = useState(args?.at(0));
|
||||
const [target, setTarget] = useState(args?.at(1));
|
||||
const [increase, setIncrease] = useState(args?.at(1) ?? true);
|
||||
const [increase, setIncrease] = useState(args === undefined ? true : args.at(2));
|
||||
|
||||
const handleProceed = () => {
|
||||
addCalldata(prepareSetAdjustmentCalldata(chainId, rate, target, increase));
|
||||
|
||||
@ -257,7 +257,6 @@ export const ArgumentInput = ({
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: rename
|
||||
export const ParsedCell = (props) => {
|
||||
const [isCopied, setIsCopied] = useState(false);
|
||||
|
||||
|
||||
@ -8,15 +8,24 @@ import { useUnstableProvider } from "./UnstableProvider"
|
||||
const MetadataProvider = createContext(null)
|
||||
export const useMetadata = () => useContext(MetadataProvider)
|
||||
|
||||
const CACHE_VERSION = "v2"
|
||||
|
||||
export const MetadataProviderProvider = ({ children }) => {
|
||||
const { client, chainId } = useUnstableProvider()
|
||||
const { data: metadata } = useSWR(
|
||||
client && chainId ? ["metadata", client, chainId] : null,
|
||||
async ([_, client]) => {
|
||||
const storageKey = `metadata-${chainId}`
|
||||
const storageKey = `metadata-${chainId}-${CACHE_VERSION}`
|
||||
const storedMetadata = sessionStorage.getItem(storageKey)
|
||||
|
||||
if (storedMetadata) return unifyMetadata(decAnyMetadata(storedMetadata))
|
||||
|
||||
Object.keys(sessionStorage).forEach(key => {
|
||||
if (key.startsWith("metadata-")) {
|
||||
sessionStorage.removeItem(key);
|
||||
}
|
||||
});
|
||||
|
||||
const metadata = await new Promise((resolve, reject) =>
|
||||
client._request("state_getMetadata", [], {
|
||||
onSuccess: resolve,
|
||||
|
||||
@ -12,3 +12,5 @@ export * from "./useBlockCommitments";
|
||||
export * from "./useApplauseDetails";
|
||||
export * from "./useBabeSlots";
|
||||
export * from "./useErasTotalStaked";
|
||||
export * from "./useLatestBlockNumber";
|
||||
export * from "./useEraIndex";
|
||||
|
||||
41
src/hooks/ghost/useEraIndex.js
Normal file
41
src/hooks/ghost/useEraIndex.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 useEraIndex = () => {
|
||||
const { chainHead$, chainId } = useUnstableProvider()
|
||||
const metadata = useMetadata()
|
||||
const { data: eraIndex } = useSWRSubscription(
|
||||
chainHead$ && chainId && metadata
|
||||
? ["eraIndex", chainHead$, chainId, metadata]
|
||||
: null,
|
||||
([_, chainHead$, chainId, metadata], { next }) => {
|
||||
const { finalized$, storage$ } = chainHead$
|
||||
const subscription = finalized$.pipe(
|
||||
filter(Boolean),
|
||||
mergeMap((blockInfo) => {
|
||||
const builder = getDynamicBuilder(getLookupFn(metadata))
|
||||
const eraIndex = builder.buildStorage("Staking", "ActiveEra")
|
||||
return storage$(blockInfo?.hash, "value", () =>
|
||||
eraIndex?.keys.enc()
|
||||
).pipe(
|
||||
filter(Boolean),
|
||||
distinct(),
|
||||
map((value) => eraIndex?.value.dec(value))
|
||||
)
|
||||
}),
|
||||
)
|
||||
.subscribe({
|
||||
next(eraIndex) {
|
||||
next(null, eraIndex)
|
||||
},
|
||||
error: next,
|
||||
})
|
||||
return () => subscription.unsubscribe()
|
||||
}
|
||||
)
|
||||
return eraIndex;
|
||||
}
|
||||
@ -5,14 +5,14 @@ import { distinct, filter, map, mergeMap } from "rxjs"
|
||||
import { useUnstableProvider } from "./UnstableProvider"
|
||||
import { useMetadata } from "./MetadataProvider"
|
||||
|
||||
export const useErasTotalStake = ({ eraIndex }) => {
|
||||
export const useErasTotalStake = ({ epochIndex }) => {
|
||||
const { chainHead$, chainId } = useUnstableProvider()
|
||||
const metadata = useMetadata()
|
||||
const { data: eraTotalStake } = useSWRSubscription(
|
||||
chainHead$ && chainId && metadata
|
||||
? ["eraTotalStake", chainHead$, eraIndex, chainId, metadata]
|
||||
? ["eraTotalStake", chainHead$, epochIndex, chainId, metadata]
|
||||
: null,
|
||||
([_, chainHead$, eraIndex, chainId, metadata], { next }) => {
|
||||
([_, chainHead$, epochIndex, chainId, metadata], { next }) => {
|
||||
const { finalized$, storage$ } = chainHead$
|
||||
const subscription = finalized$.pipe(
|
||||
filter(Boolean),
|
||||
@ -20,7 +20,7 @@ export const useErasTotalStake = ({ eraIndex }) => {
|
||||
const builder = getDynamicBuilder(getLookupFn(metadata))
|
||||
const eraTotalStake = builder.buildStorage("Staking", "ErasTotalStake")
|
||||
return storage$(blockInfo?.hash, "value", () =>
|
||||
eraTotalStake?.keys.enc(eraIndex)
|
||||
eraTotalStake?.keys.enc(epochIndex)
|
||||
).pipe(
|
||||
filter(Boolean),
|
||||
distinct(),
|
||||
|
||||
18
src/hooks/ghost/useLatestBlockNumber.js
Normal file
18
src/hooks/ghost/useLatestBlockNumber.js
Normal file
@ -0,0 +1,18 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import useSWRSubscription from "swr/subscription"
|
||||
import { useUnstableProvider } from "./UnstableProvider"
|
||||
|
||||
export const useLatestBlockNumber = () => {
|
||||
const { chainHead$ } = useUnstableProvider();
|
||||
const [blockNumber, setBlockNumber] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!chainHead$) return;
|
||||
const subscription = chainHead$.best$.subscribe((block) => {
|
||||
setBlockNumber(block.number);
|
||||
});
|
||||
return () => subscription.unsubscribe();
|
||||
}, [chainHead$]);
|
||||
|
||||
return blockNumber;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user