From a86007447aa1f07ff43f6650c96a89cc63ecf8b0 Mon Sep 17 00:00:00 2001 From: Lyka Labrada Date: Fri, 16 Dec 2022 10:57:34 +0800 Subject: [PATCH] feature(context): move StoreServiceProvider inside walletkit-ui (#31) * feature(context): move StoreServiceProvider inside walletkit-ui * feature(context): update storeservice provider --- packages/walletkit-core/src/api/whale.ts | 5 + packages/walletkit-core/src/api/whale.unit.ts | 31 ++++- .../src/contexts/StoreServiceProvider.tsx | 114 ++++++++++++++++++ packages/walletkit-ui/src/contexts/index.ts | 1 + 4 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 packages/walletkit-ui/src/contexts/StoreServiceProvider.tsx diff --git a/packages/walletkit-core/src/api/whale.ts b/packages/walletkit-core/src/api/whale.ts index 96e4d95..92d5ed6 100644 --- a/packages/walletkit-core/src/api/whale.ts +++ b/packages/walletkit-core/src/api/whale.ts @@ -51,3 +51,8 @@ export function newWhaleRpcClient( `${options.url}/${options.version}/${options.network}/rpc` ); } + +export function getDefaultDefiChainURL(network: EnvironmentNetwork): string { + const { url } = newOceanOptions(network); + return url as string; +} diff --git a/packages/walletkit-core/src/api/whale.unit.ts b/packages/walletkit-core/src/api/whale.unit.ts index a6d983f..f733751 100644 --- a/packages/walletkit-core/src/api/whale.unit.ts +++ b/packages/walletkit-core/src/api/whale.unit.ts @@ -1,5 +1,10 @@ import { EnvironmentNetwork } from "./environment"; -import { newOceanOptions, newWhaleAPIClient, newWhaleRpcClient } from "./whale"; +import { + getDefaultDefiChainURL, + newOceanOptions, + newWhaleAPIClient, + newWhaleRpcClient, +} from "./whale"; describe("whale", () => { it("should match ocean options for local playground", () => { @@ -49,4 +54,28 @@ describe("whale", () => { const whaleApiClient = newWhaleRpcClient(oceanOptions); expect(whaleApiClient).toBeDefined(); }); + + it("should match default ocean url for local playground", () => { + const defaultURL = getDefaultDefiChainURL( + EnvironmentNetwork.LocalPlayground + ); + expect(defaultURL).toStrictEqual("http://localhost:19553"); + }); + + it("should match default ocean url for remote playground", () => { + const defaultURL = getDefaultDefiChainURL( + EnvironmentNetwork.RemotePlayground + ); + expect(defaultURL).toStrictEqual("https://playground.jellyfishsdk.com"); + }); + + it("should match default ocean url for testnet", () => { + const defaultURL = getDefaultDefiChainURL(EnvironmentNetwork.TestNet); + expect(defaultURL).toStrictEqual("https://testnet.ocean.jellyfishsdk.com"); + }); + + it("should match default ocean url for mainnet", () => { + const defaultURL = getDefaultDefiChainURL(EnvironmentNetwork.MainNet); + expect(defaultURL).toStrictEqual("https://ocean.defichain.com"); + }); }); diff --git a/packages/walletkit-ui/src/contexts/StoreServiceProvider.tsx b/packages/walletkit-ui/src/contexts/StoreServiceProvider.tsx new file mode 100644 index 0000000..2998eb7 --- /dev/null +++ b/packages/walletkit-ui/src/contexts/StoreServiceProvider.tsx @@ -0,0 +1,114 @@ +import { + EnvironmentNetwork, + getDefaultDefiChainURL, +} from "@waveshq/walletkit-core"; +import React, { + createContext, + PropsWithChildren, + useContext, + useEffect, + useMemo, + useState, +} from "react"; + +import { BaseLogger } from "./logger"; +import { useNetworkContext } from "./NetworkContext"; + +interface ServiceProviderContextProps { + api: { + get: () => Promise; + set: (url: NonNullable) => Promise; + }; + logger: BaseLogger; +} + +interface ServiceProviderURLProps extends ServiceProviderContextProps { + network: EnvironmentNetwork; +} + +interface ServiceProviderLoader { + isUrlLoaded: boolean; + url: NonNullable; +} + +function useServiceProviderUrl({ + api, + network, + logger, +}: ServiceProviderURLProps): ServiceProviderLoader { + const [isUrlLoaded, setIsUrlLoaded] = useState(false); + const defaultDefichainURL = getDefaultDefiChainURL(network); + const [url, setUrl] = useState>(defaultDefichainURL); + + useEffect(() => { + api + .get() + .then((val) => { + setUrl(val !== undefined ? val : defaultDefichainURL); + }) + .catch((err) => logger.error(err)) + .finally(() => setIsUrlLoaded(true)); + }, [url, network]); + + return { + isUrlLoaded, + url, + }; +} + +interface ServiceProviderContextI { + url: NonNullable; + defaultUrl: string; + isCustomUrl: boolean; + setUrl: (val: NonNullable) => Promise; +} + +const ServiceProviderContext = createContext( + undefined as any +); + +export function useServiceProviderContext(): ServiceProviderContextI { + return useContext(ServiceProviderContext); +} + +export function StoreServiceProvider( + props: ServiceProviderContextProps & PropsWithChildren +): JSX.Element | null { + const { api, children, logger } = props; + const { network } = useNetworkContext(); + const { url } = useServiceProviderUrl({ + api, + network, + logger, + }); + const defaultUrl = getDefaultDefiChainURL(network); + const [currentUrl, setCurrentUrl] = useState(url); + + useEffect(() => { + setCurrentUrl(url); + }, [url]); + + const isCustomUrl = useMemo( + () => currentUrl !== defaultUrl, + [currentUrl, defaultUrl] + ); + + const setUrl = async (newUrl: string): Promise => { + setCurrentUrl(newUrl); + await api.set(newUrl); + }; + + // eslint-disable-next-line react/jsx-no-constructed-context-values + const context: ServiceProviderContextI = { + url: currentUrl === undefined ? defaultUrl : currentUrl, + isCustomUrl, + defaultUrl, + setUrl, + }; + + return ( + + {children} + + ); +} diff --git a/packages/walletkit-ui/src/contexts/index.ts b/packages/walletkit-ui/src/contexts/index.ts index 76006cf..d57097e 100644 --- a/packages/walletkit-ui/src/contexts/index.ts +++ b/packages/walletkit-ui/src/contexts/index.ts @@ -1,3 +1,4 @@ export * from "./NetworkContext"; +export * from "./StoreServiceProvider"; export * from "./ThemeProvider"; export * from "./WhaleContext";