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: move network state to redux #2004

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
12 changes: 4 additions & 8 deletions src/app/_components/NavBar/NetworkLabel.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { DEFAULT_MAINNET_SERVER, DEFAULT_TESTNET_SERVER } from '@/common/constants/env';
import { Badge, Flex, Icon, Spinner, Stack } from '@chakra-ui/react';
import { Check, Trash } from '@phosphor-icons/react';
import { FC, useMemo } from 'react';

// import { Badge } from '../../../common/components/Badge';
import { DEFAULT_DEVNET_SERVER } from '../../../common/constants/constants';
import { useGlobalContext } from '../../../common/context/useGlobalContext';
import { useCustomNetworkApiInfo } from '../../../common/queries/useCustomNetworkApiInfo';
Expand All @@ -19,13 +19,9 @@ const ellipsisStyle: React.CSSProperties = {
};

export const NetworkLabel: FC<{ network: Network }> = ({ network }) => {
const {
activeNetwork,
removeCustomNetwork,
apiUrls: { mainnet, testnet },
} = useGlobalContext();
const isMainnet = network.url === mainnet;
const isTestnet = network.url === testnet;
const { activeNetwork, removeCustomNetwork } = useGlobalContext();
const isMainnet = network.url === DEFAULT_MAINNET_SERVER;
const isTestnet = network.url === DEFAULT_TESTNET_SERVER;
const isDevnet = network.url === DEFAULT_DEVNET_SERVER;
const isDefault = isMainnet || isTestnet;

Expand Down
18 changes: 12 additions & 6 deletions src/app/_components/Providers.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client';

import { ReduxStateInitializer } from '@/common/state/ReduxStateInitializer';

Check warning on line 3 in src/app/_components/Providers.tsx

View check run for this annotation

Codecov / codecov/patch

src/app/_components/Providers.tsx#L3

Added line #L3 was not covered by tests
import { ChakraProvider } from '@chakra-ui/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { useSearchParams } from 'next/navigation';
Expand Down Expand Up @@ -54,13 +55,18 @@
<ChakraProvider value={system}>
<ColorModeProvider>
<ReduxProvider store={store}>
<AppConfig // TODO: rename to something else like SessionProvider
queryNetworkMode={queryNetworkMode}
queryApiUrl={queryApiUrl}
querySubnet={querySubnet}
<ReduxStateInitializer
addedCustomNetworksCookie={addedCustomNetworksCookie}
removedCustomNetworksCookie={removedCustomNetworksCookie}
>
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
</AppConfig>
<AppConfig // TODO: rename to something else like SessionProvider
queryNetworkMode={queryNetworkMode}
queryApiUrl={queryApiUrl}
querySubnet={querySubnet}
>
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
</AppConfig>
</ReduxStateInitializer>
</ReduxProvider>
</ColorModeProvider>
</ChakraProvider>
Expand Down
46 changes: 4 additions & 42 deletions src/common/context/GlobalContextProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
useStacksApiSocketClient,
} from '../../app/_components/BlockList/Sockets/use-stacks-api-socket-client';
import { buildCustomNetworkUrl, fetchCustomNetworkId } from '../components/modals/AddNetwork/utils';
import { IS_BROWSER } from '../constants/constants';
import {
NetworkIdModeMap,
NetworkModeBtcAddressBaseUrlMap,
Expand All @@ -19,7 +18,6 @@ import {
NetworkModeUrlMap,
devnetNetwork,
mainnetNetwork,
oldTestnetNetwork,
testnetNetwork,
} from '../constants/network';
import { ONE_HOUR } from '../queries/query-stale-time';
Expand All @@ -36,10 +34,6 @@ function filterNetworks(
}

interface GlobalContext {
apiUrls: Record<NetworkModes, string>;
btcBlockBaseUrls: Record<NetworkModes, string>;
btcTxBaseUrls: Record<NetworkModes, string>;
btcAddressBaseUrls: Record<NetworkModes, string>;
activeNetwork: Network;
activeNetworkKey: string;
addCustomNetwork: (network: Network) => void;
Expand All @@ -50,10 +44,6 @@ interface GlobalContext {
}

export const GlobalContext = createContext<GlobalContext>({
apiUrls: NetworkModeUrlMap,
btcBlockBaseUrls: NetworkModeBtcBlockBaseUrlMap,
btcTxBaseUrls: NetworkModeBtcTxBaseUrlMap,
btcAddressBaseUrls: NetworkModeBtcAddressBaseUrlMap,
activeNetwork: mainnetNetwork,
activeNetworkKey: NetworkModeUrlMap[NetworkModes.Mainnet],
addCustomNetwork: (network: Network) => {},
Expand All @@ -72,7 +62,6 @@ export const GlobalContextProvider: FC<{
const searchParams = useSearchParams();
const chain = searchParams?.get('chain');
const api = searchParams?.get('api');
const subnet = searchParams?.get('subnet');
const btcBlockBaseUrl = searchParams?.get('btcBlockBaseUrl');
const btcTxBaseUrl = searchParams?.get('btcTxBaseUrl');
const btcAddressBaseUrl = searchParams?.get('btcAddressBaseUrl');
Expand All @@ -81,19 +70,14 @@ export const GlobalContextProvider: FC<{
const queryNetworkMode = ((Array.isArray(chain) ? chain[0] : chain) ||
NetworkModes.Mainnet) as NetworkModes;
const queryApiUrl = removeTrailingSlash(Array.isArray(api) ? api[0] : api);
const querySubnet = Array.isArray(subnet) ? subnet[0] : subnet;
const queryBtcBlockBaseUrl = Array.isArray(btcBlockBaseUrl)
? btcBlockBaseUrl[0]
: btcBlockBaseUrl;
const queryBtcTxBaseUrl = Array.isArray(btcTxBaseUrl) ? btcTxBaseUrl[0] : btcTxBaseUrl;
const queryBtcAddressBaseUrl = Array.isArray(btcAddressBaseUrl)
? btcAddressBaseUrl[0]
: btcAddressBaseUrl;
const activeNetworkKey = querySubnet || queryApiUrl || NetworkModeUrlMap[queryNetworkMode];

// TODO: is this needed anymore?
if (IS_BROWSER && (window as any)?.location?.search?.includes('err=1'))
throw new Error('test error');
const activeNetworkKey = queryApiUrl || NetworkModeUrlMap[queryNetworkMode];

const addedCustomNetworks: Record<string, Network> = JSON.parse(
addedCustomNetworksCookie || '{}'
Expand All @@ -104,32 +88,13 @@ export const GlobalContextProvider: FC<{
const [_, setAddedCustomNetworksCookie] = useCookies(['addedCustomNetworks']);
const [__, setRemovedCustomNetworksCookie] = useCookies(['removedCustomNetworks']);

const isUrlPassedSubnet = !!querySubnet;

const [networks, setNetworks] = useState<Record<string, Network>>(
filterNetworks(
{
[mainnetNetwork.url]: mainnetNetwork,
[testnetNetwork.url]: testnetNetwork,
[oldTestnetNetwork.url]: oldTestnetNetwork,
[devnetNetwork.url]: devnetNetwork,
...addedCustomNetworks,
...(isUrlPassedSubnet
? {
[querySubnet]: {
isSubnet: true,
url: querySubnet,
btcBlockBaseUrl:
queryBtcBlockBaseUrl || NetworkModeBtcBlockBaseUrlMap[NetworkModes.Mainnet],
btcTxBaseUrl: queryBtcTxBaseUrl || NetworkModeBtcTxBaseUrlMap[NetworkModes.Mainnet],
btcAddressBaseUrl:
queryBtcAddressBaseUrl || NetworkModeBtcAddressBaseUrlMap[NetworkModes.Mainnet],
label: 'subnet',
networkId: 1,
mode: NetworkModes.Mainnet,
} as Network,
}
: {}),
},
removedCustomNetworks
)
Expand Down Expand Up @@ -263,20 +228,17 @@ export const GlobalContextProvider: FC<{
<GlobalContext.Provider
value={{
activeNetwork: networks[activeNetworkKey] || {},
activeNetworkKey,
apiUrls: NetworkModeUrlMap, // TODO: If this is a constant, why is it in context?
btcBlockBaseUrls: NetworkModeBtcBlockBaseUrlMap, // TODO: If this is a constant, why is it in context?
btcTxBaseUrls: NetworkModeBtcTxBaseUrlMap, // TODO: If this is a constant, why is it in context?
btcAddressBaseUrls: NetworkModeBtcAddressBaseUrlMap, // TODO: If this is a constant, why is it in context?
activeNetworkKey, // TODO: rename this to activeNetworkUrl. activeNetwork should be used instead of activeNetworkKey as having the information in both places is redundant
addCustomNetwork,
removeCustomNetwork,
networks,
apiClient: getApiClient(activeNetworkKey),

stacksApiSocketClientInfo: {
client: stacksApiSocketClient,
connect: connectStacksApiSocket,
disconnect: disconnectStacksApiSocket,
},
apiClient: getApiClient(activeNetworkKey),
}}
>
{children}
Expand Down
8 changes: 4 additions & 4 deletions src/common/context/__tests__/GlobalContext.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ describe('GlobalContext', () => {
},
} as any);
render(
<GlobalContextProvider headerCookies={''}>
<GlobalContextProvider addedCustomNetworksCookie={''} removedCustomNetworksCookie={''}>
<GlobalContextTestComponent />
</GlobalContextProvider>
);
Expand All @@ -72,21 +72,21 @@ describe('GlobalContext', () => {
},
} as any);
render(
<GlobalContextProvider headerCookies={''}>
<GlobalContextProvider addedCustomNetworksCookie={''} removedCustomNetworksCookie={''}>
<GlobalContextTestComponent />
</GlobalContextProvider>
);

const networks = getContextField('networks');
expect(Object.keys(networks).length).toBe(4);
expect(Object.keys(networks).length).toBe(3);

await waitFor(() => {
expect(fetchCustomNetworkId).toHaveBeenCalledWith(customApiUrl, false);
});

await waitFor(() => {
const updatedNetworks = getContextField('networks');
expect(Object.keys(updatedNetworks).length).toBe(5);
expect(Object.keys(updatedNetworks).length).toBe(4);
expect(updatedNetworks[customApiUrl].isCustomNetwork).toBe(true);
});
});
Expand Down
44 changes: 44 additions & 0 deletions src/common/state/ReduxStateInitializer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { useSearchParams } from 'next/navigation';
import { ReactNode, useEffect, useState } from 'react';
import { useDispatch } from 'react-redux';

Check warning on line 3 in src/common/state/ReduxStateInitializer.tsx

View check run for this annotation

Codecov / codecov/patch

src/common/state/ReduxStateInitializer.tsx#L1-L3

Added lines #L1 - L3 were not covered by tests

import { initializeNetworkState, initializeNetworks } from './slices/network-slice';

Check warning on line 5 in src/common/state/ReduxStateInitializer.tsx

View check run for this annotation

Codecov / codecov/patch

src/common/state/ReduxStateInitializer.tsx#L5

Added line #L5 was not covered by tests

export const ReduxStateInitializer = ({

Check warning on line 7 in src/common/state/ReduxStateInitializer.tsx

View check run for this annotation

Codecov / codecov/patch

src/common/state/ReduxStateInitializer.tsx#L7

Added line #L7 was not covered by tests
children,
addedCustomNetworksCookie,
removedCustomNetworksCookie,
}: {
children: ReactNode;
addedCustomNetworksCookie: string | undefined;
removedCustomNetworksCookie: string | undefined;
}) => {
const dispatch = useDispatch();
const searchParams = useSearchParams();
const [isInitialized, setIsInitialized] = useState(false);

Check warning on line 18 in src/common/state/ReduxStateInitializer.tsx

View check run for this annotation

Codecov / codecov/patch

src/common/state/ReduxStateInitializer.tsx#L15-L18

Added lines #L15 - L18 were not covered by tests

useEffect(() => {
const initNetworks = async () => {
const networkState = await initializeNetworkState(

Check warning on line 22 in src/common/state/ReduxStateInitializer.tsx

View check run for this annotation

Codecov / codecov/patch

src/common/state/ReduxStateInitializer.tsx#L20-L22

Added lines #L20 - L22 were not covered by tests
searchParams,
addedCustomNetworksCookie,
removedCustomNetworksCookie
);

if (!isInitialized) {
dispatch(initializeNetworks(networkState));
setIsInitialized(true);

Check warning on line 30 in src/common/state/ReduxStateInitializer.tsx

View check run for this annotation

Codecov / codecov/patch

src/common/state/ReduxStateInitializer.tsx#L29-L30

Added lines #L29 - L30 were not covered by tests
}
};

initNetworks();

Check warning on line 34 in src/common/state/ReduxStateInitializer.tsx

View check run for this annotation

Codecov / codecov/patch

src/common/state/ReduxStateInitializer.tsx#L34

Added line #L34 was not covered by tests
}, [
dispatch,
addedCustomNetworksCookie,
removedCustomNetworksCookie,
searchParams,
isInitialized,
]);

return <>{children}</>;
};
Loading
Loading