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 [providerIndex, setProviderIndex] = useState(0); const { data: providerDetails } = useSWR("getGhostProviders", () => Unstable.getSubstrateConnectExtensionProviders() ); const providerDetail = useMemo(() => providerDetails?.at(providerIndex), [providerDetails, providerIndex]); const { data: provider } = useSWR( () => providerDetail ? `ghostProviderDetail.${providerDetail.info.uuid}.provider` : null, () => providerDetail ? providerDetail.provider : null ); const connectionState = useMemo(() => { if (!providerDetail) return 'no-extension'; if (!provider) return 'loading'; const chains = provider.getChains(); if (chains[chainId]) return 'connected'; return 'wrong-network'; }, [providerDetail, provider, chainId]); const client = useMemo(() => { if (!provider || !chainId) return undefined; const chain = provider.getChains()[chainId]; if (!chain) return undefined; return createClient(chain.connect) }, [provider, chainId]); const observableClient = useMemo(() => client ? getObservableClient(client) : undefined, [client]); const chainHead$ = useMemo(() => observableClient?.chainHead$(), [observableClient]); const value = useMemo(() => ({ isExtensionMissing: connectionState === "no-extension", providerDetails, providerDetail, connectProviderByIndex: setProviderIndex, chainId, client, setChainId, chainHead$ }), [providerDetails, providerDetail, chainId, client, chainHead$]); return ( {children} ); };