ghost connect button added

Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
This commit is contained in:
Uncle Fatso 2026-04-08 07:32:53 +03:00
parent 4c455bd1f5
commit 153749606f
Signed by: f4ts0
GPG Key ID: 565F4F2860226EBB
4 changed files with 88 additions and 6 deletions

View File

@ -1,7 +1,7 @@
{ {
"name": "ghost-dao-interface", "name": "ghost-dao-interface",
"private": true, "private": true,
"version": "0.7.7", "version": "0.7.8",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

View File

@ -0,0 +1,52 @@
import { Box, Typography, SvgIcon, useTheme } from "@mui/material";
import { parseKnownToken } from "../../components/Token/Token";
import { useUnstableProvider } from "../../hooks/ghost";
import { PrimaryButton } from "../Button"
const GHOST_CONNECT = 'https://git.ghostchain.io/ghostchain/ghost-extension-wallet/releases';
function GhostChainSelect() {
const { providerDetail, isConnected } = useUnstableProvider();
const theme = useTheme();
if (providerDetail) {
return (
<Box
height="39px"
width="155px"
borderRadius="4px"
padding="0 14px"
border="1px solid #50759e"
>
<Box
display="flex"
flexDirection="row"
alignItems="center"
justifyContent="space-between"
width="100%"
height="100%"
>
<Box display="flex" flexDirection="row">
<SvgIcon component={parseKnownToken("CSPR")} inheritViewBox />
<Typography sx={{ paddingLeft: "6px"}}>CASPER</Typography>
</Box>
<Box
width="21px"
height="21px"
backgroundColor={isConnected ? theme.colors.feedback.success : theme.colors.feedback.error}
borderRadius="50%"
></Box>
</Box>
</Box>
)
}
return (
<PrimaryButton onClick={() => window.open(GHOST_CONNECT, '_blank', 'noopener,noreferrer')} width="155px">
Get GHOST Connect
</PrimaryButton>
)
}
export default GhostChainSelect;

View File

@ -2,7 +2,7 @@ import { Box, Button, SvgIcon, useMediaQuery, useTheme } from "@mui/material";
import MenuIcon from "../../assets/icons/hamburger.svg?react"; import MenuIcon from "../../assets/icons/hamburger.svg?react";
import Wallet from "./Wallet" import Wallet from "./Wallet"
import SelectNetwork from "./SelectNetwork"; import SelectNetwork from "./SelectNetwork";
import GhostChainSelect from "./GhostChainSelect";
const PREFIX = "TopBar"; const PREFIX = "TopBar";
@ -34,7 +34,13 @@ function TopBar({
marginRight={desktop ? "33px" : "0px"} marginRight={desktop ? "33px" : "0px"}
> >
<Box display="flex" alignItems="center"> <Box display="flex" alignItems="center">
<Box display="flex" justifyContent="space-between" alignItems="center" width={small ? "calc(100vw - 78px)" : "320px"}> <Box
display="flex"
justifyContent="space-between"
alignItems="center"
width={small ? "calc(100vw - 78px)" : "520px"}
>
<GhostChainSelect />
<SelectNetwork <SelectNetwork
wrongNetworkToastId={wrongNetworkToastId} wrongNetworkToastId={wrongNetworkToastId}
setWrongNetworkToastId={setWrongNetworkToastId} setWrongNetworkToastId={setWrongNetworkToastId}

View File

@ -1,4 +1,4 @@
import { createContext, useContext, useState, useMemo } from "react" import { createContext, useEffect, useContext, useState, useMemo, useCallback } from "react"
import { Unstable } from "@substrate/connect-discovery" import { Unstable } from "@substrate/connect-discovery"
import { createClient } from "@polkadot-api/substrate-client" import { createClient } from "@polkadot-api/substrate-client"
import { getObservableClient } from "@polkadot-api/observable-client" import { getObservableClient } from "@polkadot-api/observable-client"
@ -20,13 +20,24 @@ export const UnstableProviderProvider = ({ children }) => {
); );
const [chainId, setChainId] = useState(DEFAULT_CHAIN_ID); 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(() => { const client = useMemo(() => {
if (!provider || !chainId) return undefined; if (!provider || !chainId) return undefined;
const chain = provider.getChains()[chainId]; const chain = provider.getChains()[chainId];
if (!chain) return undefined; if (!chain) return undefined;
return createClient(chain.connect); const wrappedConnect = createConnectWithStatus(chain.connect, setIsConnected);
}, [provider, chainId]); return createClient(wrappedConnect);
}, [provider, chainId, reconnectTicket]);
const observableClient = useMemo(() => { const observableClient = useMemo(() => {
return client ? getObservableClient(client) : undefined; return client ? getObservableClient(client) : undefined;
@ -36,9 +47,22 @@ export const UnstableProviderProvider = ({ children }) => {
return observableClient ? observableClient.chainHead$() : undefined; return observableClient ? observableClient.chainHead$() : undefined;
}, [observableClient]); }, [observableClient]);
useEffect(() => {
if (!chainHead$) return;
const sub = chainHead$.runtime$.subscribe({
next: () => setIsConnected(true),
error: (err) => {
setIsConnected(false);
setTimeout(reconnect, 3000);
}
});
return () => sub.unsubscribe();
}, [chainHead$, reconnect]);
return ( return (
<UnstableProvider.Provider <UnstableProvider.Provider
value={{ value={{
isConnected,
providerDetails, providerDetails,
providerDetail, providerDetail,
connectProviderDetail: setProviderDetail, connectProviderDetail: setProviderDetail,