import { Bee } from '@ethersphere/bee-js' import { providers } from 'ethers' import { ReactElement, ReactNode, createContext, useEffect, useState } from 'react' import { DEFAULT_BEE_API_HOST, DEFAULT_RPC_URL } from '../constants' import { useGetBeeConfig } from '../hooks/apiHooks' const LocalStorageKeys = { providerUrl: 'json-rpc-provider', } interface ContextInterface { apiUrl: string beeApi: Bee | null lockedApiSettings: boolean desktopApiKey: string isDesktop: boolean desktopUrl: string rpcProviderUrl: string rpcProvider: providers.JsonRpcProvider | null cors: string | null dataDir: string | null ensResolver: string | null setApiUrl: (url: string) => void setAndPersistJsonRpcProvider: (url: string) => void isLoading: boolean error: Error | null } const initialValues: ContextInterface = { beeApi: null, apiUrl: DEFAULT_BEE_API_HOST, setApiUrl: () => {}, // eslint-disable-line lockedApiSettings: false, isDesktop: false, desktopApiKey: '', desktopUrl: window.location.origin, setAndPersistJsonRpcProvider: async () => {}, // eslint-disable-line rpcProviderUrl: '', rpcProvider: null, cors: null, dataDir: null, ensResolver: null, isLoading: true, error: null, } export const Context = createContext(initialValues) export const Consumer = Context.Consumer interface InitialSettings { beeApiUrl?: string lockedApiSettings?: boolean isDesktop?: boolean desktopUrl?: string defaultRpcUrl?: string } interface Props extends InitialSettings { children: ReactNode } export function Provider({ children, ...propsSettings }: Props): ReactElement { const desktopUrl = propsSettings.desktopUrl ?? initialValues.desktopUrl const isDesktop = Boolean(propsSettings.isDesktop) const propsProviderUrl = localStorage.getItem(LocalStorageKeys.providerUrl) || propsSettings.defaultRpcUrl || DEFAULT_RPC_URL const [apiUrl, setApiUrl] = useState( sessionStorage.getItem('api_host') ?? propsSettings.beeApiUrl ?? initialValues.apiUrl, ) const [beeApi, setBeeApi] = useState(null) const [desktopApiKey, setDesktopApiKey] = useState(initialValues.desktopApiKey) const [rpcProviderUrl, setRpcProviderUrl] = useState(propsProviderUrl) const [rpcProvider, setRpcProvider] = useState(new providers.JsonRpcProvider(propsProviderUrl)) const { config, isLoading, error } = useGetBeeConfig(desktopUrl) useEffect(() => { const urlSearchParams = new URLSearchParams(window.location.search) const newApiKey = urlSearchParams.get('v') if (newApiKey) { localStorage.setItem('apiKey', newApiKey) window.location.search = '' setDesktopApiKey(newApiKey) } }, []) useEffect(() => { const url = makeHttpUrl(config?.['api-addr'] ?? apiUrl) try { setBeeApi(new Bee(url)) sessionStorage.setItem('api_host', url) } catch (e) { setBeeApi(null) } }, [config, apiUrl]) return ( {children} ) } function makeHttpUrl(string: string): string { if (!string.startsWith('http')) { return `http://${string}` } return string } function setAndPersistJsonRpcProviderClosure( setProviderUrl: (url: string) => void, setProvider: (prov: providers.JsonRpcProvider) => void, ) { return (providerUrl: string) => { localStorage.setItem(LocalStorageKeys.providerUrl, providerUrl) setProviderUrl(providerUrl) setProvider(new providers.JsonRpcProvider(providerUrl)) } }