Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: disable custom network logic #1059

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Features

- [#1059](https://github.com/alleslabs/celatone-frontend/pull/1059) Disable add custom networks on non initia deployments
- [#1052](https://github.com/alleslabs/celatone-frontend/pull/1052) Add entry point to add custom minitias network in network selector
- [#1038](https://github.com/alleslabs/celatone-frontend/pull/1038) Add custom networks options page to navigate between manual and upload json
- [#1054](https://github.com/alleslabs/celatone-frontend/pull/1054) Add chain config store, useChainConfig hook, and apply it all places
Expand Down
15 changes: 6 additions & 9 deletions src/lib/app-provider/contexts/app.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useModalTheme } from "@cosmos-kit/react";
import { GraphQLClient } from "graphql-request";
import { observer } from "mobx-react-lite";
import type { ReactNode } from "react";
import {
createContext,
Expand All @@ -11,19 +12,17 @@ import {

import { useChainConfigs } from "../hooks/useChainConfigs";
import { useNetworkChange } from "../hooks/useNetworkChange";
import { FALLBACK_CHAIN_CONFIG } from "config/chain";
import type { ChainConfig } from "config/chain";
import { PROJECT_CONSTANTS } from "config/project";
import { FALLBACK_CHAIN_CONFIG } from "config/chain";
import type { ProjectConstants } from "config/project";
import { PROJECT_CONSTANTS } from "config/project";
import { FALLBACK_THEME, getTheme } from "config/theme";
import type { ThemeConfig } from "config/theme/types";
import {
FALLBACK_SUPPORTED_CHAIN_ID,
HASURA_ADMIN_SECRET,
SUPPORTED_CHAIN_IDS,
} from "env";
import { LoadingOverlay } from "lib/components/LoadingOverlay";
import { useChainConfigStore } from "lib/providers/store";
import { changeFavicon } from "lib/utils";

interface AppProviderProps {
Expand Down Expand Up @@ -58,14 +57,13 @@ const DEFAULT_STATES: AppContextInterface = {

const AppContext = createContext<AppContextInterface>(DEFAULT_STATES);

export const AppProvider = ({ children }: AppProviderProps) => {
export const AppProvider = observer(({ children }: AppProviderProps) => {
const { setModalTheme } = useModalTheme();
const { chainConfigs } = useChainConfigs();
const { isHydrated: isChainConfigStoreHydrated } = useChainConfigStore();

const [states, setStates] = useState<AppContextInterface>(DEFAULT_STATES);

// Remark: this function is only used in useSelectChain. Do not use in other places.
// Remark: this function is only used in useNetworkChange. Do not use in other places.
const handleOnChainIdChange = useCallback(
(newChainId: string) => {
const chainConfig = chainConfigs[newChainId] ?? FALLBACK_CHAIN_CONFIG;
Expand Down Expand Up @@ -110,9 +108,8 @@ export const AppProvider = ({ children }: AppProviderProps) => {

useNetworkChange(handleOnChainIdChange);

if (!isChainConfigStoreHydrated) return <LoadingOverlay />;
return <AppContext.Provider value={states}>{children}</AppContext.Provider>;
};
});

export const useCelatoneApp = (): AppContextInterface => {
return useContext(AppContext);
Expand Down
1 change: 1 addition & 0 deletions src/lib/app-provider/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ export * from "./usePlatform";
export * from "./useInitia";
export * from "./useIsConnected";
export * from "./useChainConfigs";
export * from "./useAllowCustomNetworks";
19 changes: 19 additions & 0 deletions src/lib/app-provider/hooks/useAllowCustomNetworks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { SUPPORTED_CHAIN_IDS } from "env";

import { useInternalNavigate } from "./useInternalNavigate";

export const useAllowCustomNetworks = ({
shouldRedirect,
}: {
shouldRedirect: boolean;
}) => {
const navigate = useInternalNavigate();

const isAllow = SUPPORTED_CHAIN_IDS.some(
(chainId) => chainId === "initiation-1"
);

if (!isAllow && shouldRedirect) navigate({ pathname: "/", replace: true });

return isAllow;
};
23 changes: 10 additions & 13 deletions src/lib/app-provider/hooks/useChainConfigs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { wallets as initiaWallets } from "@cosmos-kit/initia";
import { wallets as keplrWallets } from "@cosmos-kit/keplr";
import { wallets as staionWallets } from "@cosmos-kit/station";
import { assets, chains } from "chain-registry";
import _ from "lodash";
import { useEffect, useMemo } from "react";

import type { ChainConfig, ChainConfigs } from "config/chain";
Expand Down Expand Up @@ -194,15 +193,15 @@ export const useChainConfigs = (): {
() =>
Object.values(chainConfigs).reduce(
(acc, each) => {
if (!each) {
return acc;
}

const localChainConfig: ChainConfig = {
tier: each.tier,
chain: each.chain,
registryChainName: each.registryChainName,
prettyName: each.prettyName,
logoUrl:
each.logo_URIs?.png ??
each.logo_URIs?.svg ??
each.logo_URIs?.jpeg,
networkType: each.network_type,
lcd: each.lcd,
rpc: each.rpc,
Expand All @@ -211,12 +210,8 @@ export const useChainConfigs = (): {
features: each.features,
gas: {
gasPrice: {
tokenPerGas: _.get(
each,
"fees.fee_tokens[0].fixed_min_gas_price",
0
),
denom: _.get(each, "fees.fee_tokens[0].denom", ""),
tokenPerGas: each.fees?.fee_tokens[0]?.fixed_min_gas_price ?? 0,
denom: each.fees?.fee_tokens[0]?.denom ?? "",
},
gasAdjustment: each.gas.gasAdjustment,
maxGasLimit: each.gas.maxGasLimit,
Expand Down Expand Up @@ -244,7 +239,6 @@ export const useChainConfigs = (): {
};

return {
...acc,
chainConfigs: {
...acc.chainConfigs,
[each.chainId]: localChainConfig,
Expand All @@ -263,7 +257,10 @@ export const useChainConfigs = (): {
);

return {
chainConfigs: _.merge(CHAIN_CONFIGS, local.chainConfigs),
chainConfigs: {
...CHAIN_CONFIGS,
...local.chainConfigs,
},
registryChains: [
...chains,
localosmosis,
Expand Down
5 changes: 4 additions & 1 deletion src/lib/app-provider/hooks/useNetworkChange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useRouter } from "next/router";
import { useEffect, useRef } from "react";

import { FALLBACK_SUPPORTED_CHAIN_ID, SUPPORTED_CHAIN_IDS } from "env";
import { useChainConfigStore } from "lib/providers/store";
import { getFirstQueryParam } from "lib/utils";

import { useInternalNavigate } from "./useInternalNavigate";
Expand All @@ -12,9 +13,10 @@ export const useNetworkChange = (
const router = useRouter();
const networkRef = useRef<string>();
const navigate = useInternalNavigate();
const { isHydrated: isChainConfigStoreHydrated } = useChainConfigStore();

useEffect(() => {
if (router.isReady) {
if (router.isReady && isChainConfigStoreHydrated) {
const networkRoute = getFirstQueryParam(router.query.network);
// Redirect to default chain if there is no network query provided
if (!router.query.network) {
Expand Down Expand Up @@ -53,6 +55,7 @@ export const useNetworkChange = (
}
}, [
handleOnChainIdChange,
isChainConfigStoreHydrated,
navigate,
router.asPath,
router.isReady,
Expand Down
145 changes: 81 additions & 64 deletions src/lib/layout/network-menu/NetworkMenuBody.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Accordion, Button, Divider, Flex } from "@chakra-ui/react";
import { observer } from "mobx-react-lite";

import { useAllowCustomNetworks } from "lib/app-provider";
import { AppLink } from "lib/components/AppLink";
import { CustomIcon } from "lib/components/icon";
import { EmptyState } from "lib/components/state";
Expand All @@ -26,69 +27,85 @@ export const NetworkMenuBody = observer(
filteredMainnetChains,
filteredTestnetChains,
onClose,
}: NetworkMenuBodyProps) => (
<>
<Accordion
variant="transparent"
allowMultiple
defaultIndex={[0, 1, 2]}
p={0}
>
<Flex direction="column" gap={4}>
<NetworkAccodionPinned
pinnedNetworks={filteredPinnedChains}
cursor={cursor}
setCursor={setCursor}
onClose={onClose}
/>
{!!filteredPinnedChains.length && <Divider borderColor="gray.700" />}
<NetworkAccordion
title="Mainnet"
networks={filteredMainnetChains}
cursor={cursor}
setCursor={setCursor}
startIndex={filteredPinnedChains.length}
onClose={onClose}
/>
{!!filteredMainnetChains.length && <Divider borderColor="gray.700" />}
<NetworkAccordion
title="Testnet"
networks={filteredTestnetChains}
cursor={cursor}
setCursor={setCursor}
startIndex={
filteredPinnedChains.length + filteredMainnetChains.length
}
onClose={onClose}
/>
<Divider borderColor="gray.700" />
<AppLink href="/add-network">
<Button
variant="outline-gray"
justifyContent="flex-start"
leftIcon={<CustomIcon name="plus" boxSize={4} color="gray.600" />}
onClick={onClose}
w="full"
h={12}
>
Add custom Minitia
</Button>
</AppLink>
</Flex>
</Accordion>
{filteredPinnedChains.length +
filteredMainnetChains.length +
filteredTestnetChains.length ===
0 && (
<EmptyState
my={0}
imageVariant="empty"
imageWidth={40}
textVariant="body2"
message="No matched result found.
}: NetworkMenuBodyProps) => {
const isAllowCustomNetworks = useAllowCustomNetworks({
shouldRedirect: false,
});

return (
<>
<Accordion
variant="transparent"
allowMultiple
defaultIndex={[0, 1, 2]}
p={0}
>
<Flex direction="column" gap={4}>
<NetworkAccodionPinned
pinnedNetworks={filteredPinnedChains}
cursor={cursor}
setCursor={setCursor}
onClose={onClose}
/>
{!!filteredPinnedChains.length && (
<Divider borderColor="gray.700" />
)}
<NetworkAccordion
title="Mainnet"
networks={filteredMainnetChains}
cursor={cursor}
setCursor={setCursor}
startIndex={filteredPinnedChains.length}
onClose={onClose}
/>
{!!filteredMainnetChains.length && (
<Divider borderColor="gray.700" />
)}
<NetworkAccordion
title="Testnet"
networks={filteredTestnetChains}
cursor={cursor}
setCursor={setCursor}
startIndex={
filteredPinnedChains.length + filteredMainnetChains.length
}
onClose={onClose}
/>
{isAllowCustomNetworks && (
<>
<Divider borderColor="gray.700" />
<AppLink href="/add-network">
<Button
variant="outline-gray"
justifyContent="flex-start"
leftIcon={
<CustomIcon name="plus" boxSize={4} color="gray.600" />
}
onClick={onClose}
w="full"
h={12}
>
Add custom Minitia
</Button>
</AppLink>
</>
)}
</Flex>
</Accordion>
{filteredPinnedChains.length +
filteredMainnetChains.length +
filteredTestnetChains.length ===
0 && (
<EmptyState
my={0}
imageVariant="empty"
imageWidth={40}
textVariant="body2"
message="No matched result found.
Please check your keyword."
/>
)}
</>
)
/>
)}
</>
);
}
);
37 changes: 21 additions & 16 deletions src/lib/layout/network-menu/NetworkMenuTop.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Box, Flex, Heading, Kbd, Text } from "@chakra-ui/react";
import type { KeyboardEvent as ReactKeyboardEvent } from "react";

import { useIsMac, useMobile } from "lib/app-provider";
import { useAllowCustomNetworks, useIsMac, useMobile } from "lib/app-provider";
import { AppLink } from "lib/components/AppLink";
import InputWithIcon from "lib/components/InputWithIcon";

Expand All @@ -20,6 +20,9 @@ export const NetworkMenuTop = ({
}: NetworkMenuTopProps) => {
const isMobile = useMobile();
const isMac = useIsMac();
const isAllowCustomNetworks = useAllowCustomNetworks({
shouldRedirect: false,
});

return (
<Flex direction="column" gap={4} width="100%">
Expand All @@ -43,21 +46,23 @@ export const NetworkMenuTop = ({
</Flex>
)}
</Flex>
<Box>
<Text as="span" variant="body3" color="text.dark">
Want to add your network?
</Text>{" "}
<AppLink href="/add-network" onClick={onClose}>
<Text
as="span"
variant="body3"
color="secondary.main"
_hover={{ textDecoration: "underline" }}
>
Add a custom chain.
</Text>
</AppLink>
</Box>
{isAllowCustomNetworks && (
<Box>
<Text as="span" variant="body3" color="text.dark">
Want to add your network?
</Text>{" "}
<AppLink href="/add-network" onClick={onClose}>
<Text
as="span"
variant="body3"
color="secondary.main"
_hover={{ textDecoration: "underline" }}
>
Add a custom chain.
</Text>
</AppLink>
</Box>
)}
</Flex>
<InputWithIcon
placeholder="Search by Name or Chain ID"
Expand Down
Loading