stabilize connection state of the ghost connect
Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
This commit is contained in:
parent
fe71618369
commit
c2d81bc229
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "ghost-dao-interface",
|
||||
"private": true,
|
||||
"version": "0.7.9",
|
||||
"version": "0.7.10",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@ -92,7 +92,7 @@ function SelectNetwork({ chainId, wrongNetworkToastId, setWrongNetworkToastId, s
|
||||
return (
|
||||
<MenuItem key={chain.name} value={chain.id}>
|
||||
<Box gap="10px" display="flex" flexDirection="row" alignItems="center">
|
||||
<SvgIcon component={parseKnownToken(chain?.nativeCurrency?.symbol)} inheritViewBox />
|
||||
<SvgIcon sx={{ width: 22 }} component={parseKnownToken(chain?.nativeCurrency?.symbol)} inheritViewBox />
|
||||
{!small && <Typography>{chain.name}</Typography>}
|
||||
</Box>
|
||||
</MenuItem>
|
||||
|
||||
@ -1,14 +1,19 @@
|
||||
import { createContext, useEffect, useContext, useState, useMemo, useCallback } from "react"
|
||||
import { createContext, useEffect, useContext, useState, useMemo, useCallback, useRef } from "react"
|
||||
import { Unstable } from "@substrate/connect-discovery"
|
||||
import { createClient } from "@polkadot-api/substrate-client"
|
||||
import { getObservableClient } from "@polkadot-api/observable-client"
|
||||
import useSWR from "swr"
|
||||
|
||||
const MAX_BLOCK_TIMEOUT = 15000
|
||||
const DEFAULT_CHAIN_ID = "0x475e48fab52f3d0587b6b03101d224560c549e984d1dee197b7d8b55830e7da3"
|
||||
const UnstableProvider = createContext(null)
|
||||
export const useUnstableProvider = () => useContext(UnstableProvider)
|
||||
|
||||
export const UnstableProviderProvider = ({ children }) => {
|
||||
const [chainId, setChainId] = useState(DEFAULT_CHAIN_ID);
|
||||
const [isConnected, setIsConnected] = useState(false);
|
||||
const [reconnectTicket, setReconnectTicket] = useState(0);
|
||||
|
||||
const { data: providerDetails } = useSWR("getGhostProviders", () =>
|
||||
Unstable.getSubstrateConnectExtensionProviders()
|
||||
);
|
||||
@ -19,60 +24,66 @@ export const UnstableProviderProvider = ({ children }) => {
|
||||
() => providerDetail ? providerDetail.provider : null
|
||||
);
|
||||
|
||||
const [chainId, setChainId] = useState(DEFAULT_CHAIN_ID);
|
||||
const [isConnected, setIsConnected] = useState(false);
|
||||
const [reconnectTicket, setReconnectTicket] = useState(0);
|
||||
|
||||
const reconnect = () => setReconnectTicket(prev => prev + 1);
|
||||
const createConnectWithStatus = (originalConnect, onConnect) => {
|
||||
return (observer) => {
|
||||
onConnect(true);
|
||||
return originalConnect(observer);
|
||||
};
|
||||
};
|
||||
|
||||
const client = useMemo(() => {
|
||||
if (!provider || !chainId) return undefined;
|
||||
|
||||
const chain = provider.getChains()[chainId];
|
||||
if (!chain) return undefined;
|
||||
const wrappedConnect = createConnectWithStatus(chain.connect, setIsConnected);
|
||||
return createClient(wrappedConnect);
|
||||
|
||||
return createClient(chain.connect)
|
||||
}, [provider, chainId, reconnectTicket]);
|
||||
|
||||
const observableClient = useMemo(() => {
|
||||
return client ? getObservableClient(client) : undefined;
|
||||
}, [client]);
|
||||
const observableClient = useMemo(() => client ? getObservableClient(client) : undefined, [client]);
|
||||
const chainHead$ = useMemo(() => observableClient?.chainHead$(), [observableClient]);
|
||||
|
||||
const chainHead$ = useMemo(() => {
|
||||
return observableClient ? observableClient.chainHead$() : undefined;
|
||||
}, [observableClient]);
|
||||
const lastBlockNumber = useRef(0);
|
||||
|
||||
useEffect(() => {
|
||||
if (!chainHead$) return;
|
||||
const sub = chainHead$.runtime$.subscribe({
|
||||
next: () => setIsConnected(true),
|
||||
|
||||
lastBlockNumber.current = 0;
|
||||
let timeoutId;
|
||||
|
||||
const sub = chainHead$.bestBlocks$.subscribe({
|
||||
next: (blocks) => {
|
||||
const currentHeight = blocks.at(0)?.number ?? -1;
|
||||
|
||||
if (currentHeight > lastBlockNumber.current) {
|
||||
lastBlockNumber.current = currentHeight;
|
||||
setIsConnected(true);
|
||||
|
||||
clearTimeout(timeoutId);
|
||||
timeoutId = setTimeout(() => {
|
||||
setIsConnected(false);
|
||||
setReconnectTicket(t => t + 1);
|
||||
}, MAX_BLOCK_TIMEOUT);
|
||||
}
|
||||
},
|
||||
error: (err) => {
|
||||
setIsConnected(false);
|
||||
setTimeout(reconnect, 3000);
|
||||
setTimeout(() => setReconnectTicket(t => t + 1), 1000);
|
||||
}
|
||||
});
|
||||
return () => sub.unsubscribe();
|
||||
}, [chainHead$, reconnect]);
|
||||
|
||||
return (
|
||||
<UnstableProvider.Provider
|
||||
value={{
|
||||
return () => {
|
||||
sub.unsubscribe();
|
||||
clearTimeout(timeoutId);
|
||||
};
|
||||
}, [chainHead$]);
|
||||
|
||||
const value = useMemo(() => ({
|
||||
isConnected,
|
||||
providerDetails,
|
||||
providerDetail,
|
||||
connectProviderDetail: setProviderDetail,
|
||||
provider,
|
||||
chainId,
|
||||
client,
|
||||
setChainId,
|
||||
chainHead$
|
||||
}}
|
||||
>
|
||||
}), [isConnected, providerDetails, providerDetail, chainId, client, chainHead$]);
|
||||
|
||||
return (
|
||||
<UnstableProvider.Provider value={value}>
|
||||
{children}
|
||||
</UnstableProvider.Provider>
|
||||
);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user