From d74c506424a6cd7ce2d63a20562e142fd9f770e1 Mon Sep 17 00:00:00 2001 From: bkioshn Date: Thu, 18 May 2023 15:53:09 +0700 Subject: [PATCH 1/7] feat: use faucet info from chain config --- src/config/index.ts | 2 ++ src/config/types.ts | 2 ++ src/lib/components/button/FaucetButton.tsx | 12 +++++-- src/lib/pages/faucet/index.tsx | 38 ++++++++++++++-------- src/lib/utils/formatter/text.ts | 3 ++ 5 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/config/index.ts b/src/config/index.ts index 021fa0240..8db86e043 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -88,6 +88,8 @@ export const CHAIN_CONFIGS: ChainConfigs = { faucet: { enabled: true, url: "https://faucet.alleslabs.dev", + denom: "osmo", + amount: 10, }, wasm: { enabled: true, diff --git a/src/config/types.ts b/src/config/types.ts index 539277bc6..d1eab6924 100644 --- a/src/config/types.ts +++ b/src/config/types.ts @@ -4,6 +4,8 @@ type FaucetConfig = | { enabled: true; url: string; + denom: string; + amount: number; } | { enabled: false }; diff --git a/src/lib/components/button/FaucetButton.tsx b/src/lib/components/button/FaucetButton.tsx index b5c4ec7ab..ae71e9f6d 100644 --- a/src/lib/components/button/FaucetButton.tsx +++ b/src/lib/components/button/FaucetButton.tsx @@ -2,11 +2,17 @@ import { Button, Text } from "@chakra-ui/react"; import type { MouseEventHandler } from "react"; import { CustomIcon } from "../icon"; -import { useCurrentNetwork, useInternalNavigate } from "lib/app-provider"; +import { useCelatoneApp, useInternalNavigate } from "lib/app-provider"; export const FaucetBtn = () => { const navigate = useInternalNavigate(); - const { isTestnet } = useCurrentNetwork(); + const { + chainConfig: { + features: { + faucet: { enabled }, + }, + }, + } = useCelatoneApp(); const onClick: MouseEventHandler = async (e) => { e.preventDefault(); @@ -15,7 +21,7 @@ export const FaucetBtn = () => { }); }; - return isTestnet ? ( + return enabled ? ( {result.status && ( diff --git a/src/lib/utils/formatter/text.ts b/src/lib/utils/formatter/text.ts index 87d32ff52..d4da03649 100644 --- a/src/lib/utils/formatter/text.ts +++ b/src/lib/utils/formatter/text.ts @@ -1,2 +1,5 @@ +export const capitalize = (text: string) => + text.charAt(0).toUpperCase() + text.slice(1).toLowerCase(); + export const removeSpecialChars = (text: string) => text.replace(/[^a-zA-Z0-9]/g, ""); From 8cc82fe1a198ea01a433ade328e2721287b0da1b Mon Sep 17 00:00:00 2001 From: bkioshn Date: Thu, 18 May 2023 16:11:08 +0700 Subject: [PATCH 2/7] chore: add changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd8114b1a..0b6e8faf2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -124,6 +124,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Improvements +- [#341](https://github.com/alleslabs/celatone-frontend/pull/341) Apply faucet info from chain config - [#234](https://github.com/alleslabs/celatone-frontend/pull/234) Fix faucet wording - [#216](https://github.com/alleslabs/celatone-frontend/pull/216) Change icon to Alles Labs icon set - [#227](https://github.com/alleslabs/celatone-frontend/pull/227) Refactor directory structure and components e.g. various tables From 8f0d73c5144e81be63cb9c6114e72598d5a4830d Mon Sep 17 00:00:00 2001 From: bkioshn Date: Mon, 22 May 2023 11:04:58 +0700 Subject: [PATCH 3/7] fix: add useFaucetConfig --- src/lib/app-provider/hooks/index.ts | 1 + src/lib/app-provider/hooks/useFaucetConfig.ts | 17 ++++++++++++++++ src/lib/pages/faucet/index.tsx | 20 ++++++++----------- 3 files changed, 26 insertions(+), 12 deletions(-) create mode 100644 src/lib/app-provider/hooks/useFaucetConfig.ts diff --git a/src/lib/app-provider/hooks/index.ts b/src/lib/app-provider/hooks/index.ts index 38e2212c1..673a419c0 100644 --- a/src/lib/app-provider/hooks/index.ts +++ b/src/lib/app-provider/hooks/index.ts @@ -13,3 +13,4 @@ export * from "./useSimulateFee"; export * from "./useTokensInfo"; export * from "./useCurrentNetwork"; export * from "./useRPCEndpoint"; +export * from "./useFaucetConfig"; diff --git a/src/lib/app-provider/hooks/useFaucetConfig.ts b/src/lib/app-provider/hooks/useFaucetConfig.ts new file mode 100644 index 000000000..cdc2800da --- /dev/null +++ b/src/lib/app-provider/hooks/useFaucetConfig.ts @@ -0,0 +1,17 @@ +import { useCelatoneApp } from "../contexts"; + +export const useFaucetConfig = () => { + const { + chainConfig: { + features: { faucet }, + }, + } = useCelatoneApp(); + + if (!faucet.enabled) { + throw new Error( + "Cannot access faucet configs when faucet feature is disabled." + ); + } + + return faucet; +}; diff --git a/src/lib/pages/faucet/index.tsx b/src/lib/pages/faucet/index.tsx index 38048429c..ced7ec236 100644 --- a/src/lib/pages/faucet/index.tsx +++ b/src/lib/pages/faucet/index.tsx @@ -14,6 +14,7 @@ import { useEffect, useState } from "react"; import { useCelatoneApp, + useFaucetConfig, useInternalNavigate, useValidateAddress, } from "lib/app-provider"; @@ -55,19 +56,14 @@ const Faucet = () => { const router = useRouter(); const openTxTab = useOpenTxTab("tx-page"); const { - chainConfig: { - features: { faucet }, - chain, - }, + chainConfig: { chain }, } = useCelatoneApp(); - - const { faucetUrl, faucetDenom, faucetAmount } = faucet.enabled - ? { - faucetUrl: faucet.url, - faucetDenom: faucet.denom.toUpperCase(), - faucetAmount: faucet.amount, - } - : { faucetUrl: "", faucetDenom: "", faucetAmount: 0 }; + const faucet = useFaucetConfig(); + const { faucetUrl, faucetDenom, faucetAmount } = { + faucetUrl: faucet.url, + faucetDenom: faucet.denom.toUpperCase(), + faucetAmount: faucet.amount, + }; useEffect(() => { if (!faucet.enabled) navigate({ pathname: "/", replace: true }); From 03a9232ffc5dacb7851eaa3175aeb54a07a04c8d Mon Sep 17 00:00:00 2001 From: evilpeach Date: Tue, 23 May 2023 11:39:59 +0700 Subject: [PATCH 4/7] chore: refactor --- src/lib/app-provider/contexts/app.tsx | 15 ++++++----- src/lib/app-provider/hooks/useFaucetConfig.ts | 6 ----- src/lib/app-provider/hooks/useWasmConfig.ts | 6 ----- src/lib/app-provider/tx/clearAdmin.ts | 18 ++++++++++--- src/lib/pages/faucet/index.tsx | 26 ++++++++++++++----- 5 files changed, 42 insertions(+), 29 deletions(-) diff --git a/src/lib/app-provider/contexts/app.tsx b/src/lib/app-provider/contexts/app.tsx index 6c3b2d521..32535e064 100644 --- a/src/lib/app-provider/contexts/app.tsx +++ b/src/lib/app-provider/contexts/app.tsx @@ -17,7 +17,7 @@ import { useInternalNavigate } from "../hooks/useInternalNavigate"; import { useNetworkChange } from "../hooks/useNetworkChange"; import { CHAIN_CONFIGS, DEFAULT_CHAIN_CONFIG, PROJECT_CONSTANTS } from "config"; import type { ChainConfig, ProjectConstants } from "config/types"; -import { DEFAULT_SUPPORTED_CHAIN_ID, SUPPORTED_CHAIN_IDS } from "env"; +import { SUPPORTED_CHAIN_IDS } from "env"; import { LoadingOverlay } from "lib/components/LoadingOverlay"; import { DEFAULT_ADDRESS } from "lib/data"; import { @@ -58,9 +58,7 @@ export const AppProvider = observer(({ children }: AppProviderProps) => { const { setContractUserKey, isContractUserKeyExist } = useContractStore(); const { setProjectUserKey, isProjectUserKeyExist } = usePublicProjectStore(); - const [currentChainId, setCurrentChainId] = useState( - DEFAULT_SUPPORTED_CHAIN_ID - ); + const [currentChainId, setCurrentChainId] = useState(""); const handleOnChainIdChange = useCallback( (newChainId: string) => { @@ -76,10 +74,12 @@ export const AppProvider = observer(({ children }: AppProviderProps) => { }, }); }, - [navigate, router, setCurrentChain] + [navigate, router.pathname, router.query, setCurrentChain] ); - const chainConfig = CHAIN_CONFIGS[currentChainId]; + const chainConfig = currentChainId + ? CHAIN_CONFIGS[currentChainId] + : DEFAULT_CHAIN_CONFIG; const indexerGraphClient = useMemo( () => new GraphQLClient(chainConfig.indexer), @@ -114,7 +114,8 @@ export const AppProvider = observer(({ children }: AppProviderProps) => { if ( !isCodeUserKeyExist() || !isContractUserKeyExist() || - !isProjectUserKeyExist() + !isProjectUserKeyExist() || + !currentChainId ) return ; diff --git a/src/lib/app-provider/hooks/useFaucetConfig.ts b/src/lib/app-provider/hooks/useFaucetConfig.ts index cdc2800da..a8310b21c 100644 --- a/src/lib/app-provider/hooks/useFaucetConfig.ts +++ b/src/lib/app-provider/hooks/useFaucetConfig.ts @@ -7,11 +7,5 @@ export const useFaucetConfig = () => { }, } = useCelatoneApp(); - if (!faucet.enabled) { - throw new Error( - "Cannot access faucet configs when faucet feature is disabled." - ); - } - return faucet; }; diff --git a/src/lib/app-provider/hooks/useWasmConfig.ts b/src/lib/app-provider/hooks/useWasmConfig.ts index aa7cff64d..60c19e6f3 100644 --- a/src/lib/app-provider/hooks/useWasmConfig.ts +++ b/src/lib/app-provider/hooks/useWasmConfig.ts @@ -7,11 +7,5 @@ export const useWasmConfig = () => { }, } = useCelatoneApp(); - if (!wasm.enabled) { - throw new Error( - "Cannot access Wasm configs when Wasm feature is disabled." - ); - } - return wasm; }; diff --git a/src/lib/app-provider/tx/clearAdmin.ts b/src/lib/app-provider/tx/clearAdmin.ts index 5713b907e..ab749f505 100644 --- a/src/lib/app-provider/tx/clearAdmin.ts +++ b/src/lib/app-provider/tx/clearAdmin.ts @@ -16,14 +16,19 @@ export const useClearAdminTx = (contractAddress: ContractAddr) => { const fabricateFee = useFabricateFee(); const wasm = useWasmConfig(); - const clearAdminFee = fabricateFee(wasm.clearAdminGas); - return useCallback( async ({ onTxSucceed }: ClearAdminStreamParams) => { const client = await getCosmWasmClient(); if (!address || !client) throw new Error("Please check your wallet connection."); + if (!wasm.enabled) + throw new Error( + "Wasm config isn't loaded or Wasm feature is disabled." + ); + + const clearAdminFee = fabricateFee(wasm.clearAdminGas); + return clearAdminTx({ address: address as HumanAddr, contractAddress, @@ -42,6 +47,13 @@ export const useClearAdminTx = (contractAddress: ContractAddr) => { }, }); }, - [address, clearAdminFee, queryClient, contractAddress, getCosmWasmClient] + [ + getCosmWasmClient, + address, + wasm, + fabricateFee, + contractAddress, + queryClient, + ] ); }; diff --git a/src/lib/pages/faucet/index.tsx b/src/lib/pages/faucet/index.tsx index ced7ec236..95978527e 100644 --- a/src/lib/pages/faucet/index.tsx +++ b/src/lib/pages/faucet/index.tsx @@ -10,7 +10,7 @@ import { useWallet } from "@cosmos-kit/react"; import type { AxiosError, AxiosResponse } from "axios"; import axios from "axios"; import { useRouter } from "next/router"; -import { useEffect, useState } from "react"; +import { useEffect, useMemo, useState } from "react"; import { useCelatoneApp, @@ -59,16 +59,28 @@ const Faucet = () => { chainConfig: { chain }, } = useCelatoneApp(); const faucet = useFaucetConfig(); - const { faucetUrl, faucetDenom, faucetAmount } = { - faucetUrl: faucet.url, - faucetDenom: faucet.denom.toUpperCase(), - faucetAmount: faucet.amount, - }; + + const { faucetUrl, faucetDenom, faucetAmount } = useMemo(() => { + if (!faucet.enabled) + // Remark: this shouldn't be used as the faucet is disabled + return { + faucetUrl: "", + faucetDenom: "", + faucetAmount: "", + }; + + return { + faucetUrl: faucet.url, + faucetDenom: faucet.denom.toUpperCase(), + faucetAmount: faucet.amount, + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [faucet.enabled]); useEffect(() => { if (!faucet.enabled) navigate({ pathname: "/", replace: true }); else if (router.isReady) AmpTrack(AmpEvent.TO_FAUCET); - }, [faucet.enabled, navigate, router]); + }, [faucet, navigate, router]); useEffect(() => { if (address) { From 256393c5522113e75d09bf81d03a030783efd320 Mon Sep 17 00:00:00 2001 From: evilpeach Date: Wed, 24 May 2023 18:57:45 +0700 Subject: [PATCH 5/7] feat: refactor app --- src/lib/app-provider/contexts/app.tsx | 37 +++++-------------- .../app-provider/hooks/useNetworkChange.ts | 21 ++++++++++- src/lib/app-provider/hooks/useSelectChain.ts | 14 ++++++- 3 files changed, 42 insertions(+), 30 deletions(-) diff --git a/src/lib/app-provider/contexts/app.tsx b/src/lib/app-provider/contexts/app.tsx index 32535e064..5c4a68cc4 100644 --- a/src/lib/app-provider/contexts/app.tsx +++ b/src/lib/app-provider/contexts/app.tsx @@ -1,7 +1,6 @@ import { useWallet } from "@cosmos-kit/react"; import { GraphQLClient } from "graphql-request"; import { observer } from "mobx-react-lite"; -import { useRouter } from "next/router"; import type { ReactNode } from "react"; import { useCallback, @@ -13,7 +12,6 @@ import { } from "react"; import { useAmplitude } from "../hooks/useAmplitude"; -import { useInternalNavigate } from "../hooks/useInternalNavigate"; import { useNetworkChange } from "../hooks/useNetworkChange"; import { CHAIN_CONFIGS, DEFAULT_CHAIN_CONFIG, PROJECT_CONSTANTS } from "config"; import type { ChainConfig, ProjectConstants } from "config/types"; @@ -50,8 +48,6 @@ const AppContext = createContext({ }); export const AppProvider = observer(({ children }: AppProviderProps) => { - const router = useRouter(); - const navigate = useInternalNavigate(); const { currentChainName, setCurrentChain } = useWallet(); const { setCodeUserKey, isCodeUserKeyExist } = useCodeStore(); @@ -60,43 +56,30 @@ export const AppProvider = observer(({ children }: AppProviderProps) => { const [currentChainId, setCurrentChainId] = useState(""); + // Remark: this function is only used in useSelectChain. Do not use in other places. const handleOnChainIdChange = useCallback( (newChainId: string) => { const config = CHAIN_CONFIGS[newChainId]; setCurrentChainId(newChainId); setCurrentChain(config?.registryChainName); - - navigate({ - pathname: router.pathname.replace("/[network]", ""), - query: { - ...router.query, - network: newChainId, - }, - }); }, - [navigate, router.pathname, router.query, setCurrentChain] + [setCurrentChain, setCurrentChainId] ); - const chainConfig = currentChainId - ? CHAIN_CONFIGS[currentChainId] - : DEFAULT_CHAIN_CONFIG; - - const indexerGraphClient = useMemo( - () => new GraphQLClient(chainConfig.indexer), - [chainConfig.indexer] - ); + const states = useMemo(() => { + const chainConfig = currentChainId + ? CHAIN_CONFIGS[currentChainId] + : DEFAULT_CHAIN_CONFIG; - const states = useMemo( - () => ({ + return { availableChainIds: SUPPORTED_CHAIN_IDS, currentChainId, chainConfig, - indexerGraphClient, + indexerGraphClient: new GraphQLClient(chainConfig.indexer), constants: PROJECT_CONSTANTS, handleOnChainIdChange, - }), - [chainConfig, currentChainId, handleOnChainIdChange, indexerGraphClient] - ); + }; + }, [currentChainId, handleOnChainIdChange]); useEffect(() => { if (currentChainName) { diff --git a/src/lib/app-provider/hooks/useNetworkChange.ts b/src/lib/app-provider/hooks/useNetworkChange.ts index 672f1d194..a480e341d 100644 --- a/src/lib/app-provider/hooks/useNetworkChange.ts +++ b/src/lib/app-provider/hooks/useNetworkChange.ts @@ -11,12 +11,23 @@ export const useNetworkChange = ( const networkRef = useRef(); useEffect(() => { + let networkRoute = router.asPath.split("/")[1]; + + // TODO: refactor later if (router.isReady) { - let networkRoute = getFirstQueryParam( + networkRoute = getFirstQueryParam( router.query.network, DEFAULT_SUPPORTED_CHAIN_ID ); + // Redirect to default chain if the chain is not supported by the app + if (!SUPPORTED_CHAIN_IDS.includes(networkRoute)) + networkRoute = DEFAULT_SUPPORTED_CHAIN_ID; + if (networkRoute !== networkRef.current) { + networkRef.current = networkRoute; + handleOnChainIdChange(networkRoute); + } + } else if (router.pathname === "/404") { // Redirect to default chain if the chain is not supported by the app if (!SUPPORTED_CHAIN_IDS.includes(networkRoute)) networkRoute = DEFAULT_SUPPORTED_CHAIN_ID; @@ -26,5 +37,11 @@ export const useNetworkChange = ( handleOnChainIdChange(networkRoute); } } - }, [handleOnChainIdChange, router.isReady, router.query.network]); + }, [ + handleOnChainIdChange, + router.asPath, + router.isReady, + router.pathname, + router.query.network, + ]); }; diff --git a/src/lib/app-provider/hooks/useSelectChain.ts b/src/lib/app-provider/hooks/useSelectChain.ts index f455b293e..d6b70be41 100644 --- a/src/lib/app-provider/hooks/useSelectChain.ts +++ b/src/lib/app-provider/hooks/useSelectChain.ts @@ -3,16 +3,28 @@ import { useCallback } from "react"; import { useCelatoneApp } from "../contexts/app"; +import { useInternalNavigate } from "./useInternalNavigate"; + export const useSelectChain = () => { const router = useRouter(); + const navigator = useInternalNavigate(); const { handleOnChainIdChange } = useCelatoneApp(); return useCallback( (chainId: string) => { if (router.query.network === chainId) return; + // Remark: This is workaround solution to set new chainId and replace the pathname handleOnChainIdChange(chainId); + + navigator({ + pathname: router.pathname.replace("/[network]", ""), + query: { + ...router.query, + network: chainId, + }, + }); }, - [handleOnChainIdChange, router.query.network] + [handleOnChainIdChange, navigator, router.pathname, router.query] ); }; From 257994b55c575c77fe22ce77622472cd7dfebd0f Mon Sep 17 00:00:00 2001 From: evilpeach Date: Wed, 24 May 2023 19:07:25 +0700 Subject: [PATCH 6/7] chore: refactor again --- .../app-provider/hooks/useNetworkChange.ts | 32 ++++++------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/src/lib/app-provider/hooks/useNetworkChange.ts b/src/lib/app-provider/hooks/useNetworkChange.ts index a480e341d..edaad7058 100644 --- a/src/lib/app-provider/hooks/useNetworkChange.ts +++ b/src/lib/app-provider/hooks/useNetworkChange.ts @@ -11,31 +11,17 @@ export const useNetworkChange = ( const networkRef = useRef(); useEffect(() => { - let networkRoute = router.asPath.split("/")[1]; + let networkRoute = router.query.network + ? getFirstQueryParam(router.query.network, DEFAULT_SUPPORTED_CHAIN_ID) + : router.asPath.split("/")[1]; - // TODO: refactor later - if (router.isReady) { - networkRoute = getFirstQueryParam( - router.query.network, - DEFAULT_SUPPORTED_CHAIN_ID - ); - // Redirect to default chain if the chain is not supported by the app - if (!SUPPORTED_CHAIN_IDS.includes(networkRoute)) - networkRoute = DEFAULT_SUPPORTED_CHAIN_ID; + // Redirect to default chain if the chain is not supported by the app + if (!SUPPORTED_CHAIN_IDS.includes(networkRoute)) + networkRoute = DEFAULT_SUPPORTED_CHAIN_ID; - if (networkRoute !== networkRef.current) { - networkRef.current = networkRoute; - handleOnChainIdChange(networkRoute); - } - } else if (router.pathname === "/404") { - // Redirect to default chain if the chain is not supported by the app - if (!SUPPORTED_CHAIN_IDS.includes(networkRoute)) - networkRoute = DEFAULT_SUPPORTED_CHAIN_ID; - - if (networkRoute !== networkRef.current) { - networkRef.current = networkRoute; - handleOnChainIdChange(networkRoute); - } + if (networkRoute !== networkRef.current) { + networkRef.current = networkRoute; + handleOnChainIdChange(networkRoute); } }, [ handleOnChainIdChange, From fc16281f3d0cae4b19be7435a339c788c2295969 Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Thu, 25 May 2023 11:07:48 +0700 Subject: [PATCH 7/7] fix: faucet --- src/lib/app-provider/hooks/useNetworkChange.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/lib/app-provider/hooks/useNetworkChange.ts b/src/lib/app-provider/hooks/useNetworkChange.ts index edaad7058..76c512961 100644 --- a/src/lib/app-provider/hooks/useNetworkChange.ts +++ b/src/lib/app-provider/hooks/useNetworkChange.ts @@ -15,13 +15,15 @@ export const useNetworkChange = ( ? getFirstQueryParam(router.query.network, DEFAULT_SUPPORTED_CHAIN_ID) : router.asPath.split("/")[1]; - // Redirect to default chain if the chain is not supported by the app - if (!SUPPORTED_CHAIN_IDS.includes(networkRoute)) - networkRoute = DEFAULT_SUPPORTED_CHAIN_ID; + if (router.isReady || router.pathname === "/404") { + // Redirect to default chain if the chain is not supported by the app + if (!SUPPORTED_CHAIN_IDS.includes(networkRoute)) + networkRoute = DEFAULT_SUPPORTED_CHAIN_ID; - if (networkRoute !== networkRef.current) { - networkRef.current = networkRoute; - handleOnChainIdChange(networkRoute); + if (networkRoute !== networkRef.current) { + networkRef.current = networkRoute; + handleOnChainIdChange(networkRoute); + } } }, [ handleOnChainIdChange,