Skip to content

Commit 0a4e445

Browse files
committed
Remove all chain override contexts and move to global store (#4743)
## Problem solved Short description of the bug fixed or feature added <!-- start pr-codex --> --- ## PR-Codex overview The focus of this PR is to refactor chain-related functionality and imports, update TypeScript types, and improve store management. ### Detailed summary - Refactored chain-related functionality and imports - Updated TypeScript types for chain mapping - Improved store management for chains - Updated API calls for chain data - Removed unused hooks and contexts > The following files were skipped due to too many changes: `apps/dashboard/src/components/configure-networks/ConfigureNetworkModal.tsx`, `apps/dashboard/src/contract-ui/tabs/account-permissions/components/account-signer.tsx`, `apps/dashboard/src/contract-ui/tabs/split/page.tsx`, `apps/dashboard/src/stores/SyncStoreToStorage.tsx`, `apps/dashboard/src/components/contract-components/contract-publish-form/NetworkDropdown.tsx`, `apps/dashboard/src/components/configure-networks/Form/NetworkIdInput.tsx`, `apps/dashboard/src/contract-ui/tabs/embed/components/embed-setup.tsx`, `apps/dashboard/src/contract-ui/tabs/code/components/code-overview.tsx`, `apps/dashboard/src/components/engine/contract-subscription/contract-subscriptions-table.tsx`, `apps/dashboard/src/components/buttons/MismatchButton.tsx`, `apps/dashboard/src/components/selects/NetworkSelectDropdown.tsx`, `apps/dashboard/src/components/selects/CustomChainRenderer.tsx`, `apps/dashboard/src/components/app-layouts/app.tsx`, `apps/dashboard/src/components/contract-components/published-contract/addresses-modal.tsx`, `apps/dashboard/src/components/contract-components/tables/deployed-contracts.tsx`, `apps/dashboard/src/lib/v5-adapter.ts`, `apps/dashboard/src/components/engine/overview/transactions-table.tsx`, `apps/dashboard/src/@3rdweb-sdk/react/hooks/useRegistry.ts`, `apps/dashboard/src/stores/chainStores.tsx`, `apps/dashboard/src/components/engine/relayer/relayers-table.tsx`, `apps/dashboard/src/components/configure-networks/ConfigureNetworkForm.tsx`, `apps/dashboard/src/hooks/chains/allChains.ts`, `apps/dashboard/src/pages/[chain_id]/[...paths].tsx`, `apps/dashboard/src/components/selects/NetworkSelectorButton.tsx`, `apps/dashboard/src/@3rdweb-sdk/react/components/connect-wallet/index.tsx` > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex -->
1 parent f2307fd commit 0a4e445

File tree

45 files changed

+608
-901
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+608
-901
lines changed

apps/dashboard/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"format": "biome format ./src --write",
1111
"lint": "biome check ./src && knip && eslint ./src",
1212
"fix": "biome check ./src --fix && eslint ./src --fix",
13+
"typecheck": "tsc --noEmit",
1314
"gen:theme-typings": "chakra-cli tokens src/theme/index.ts",
1415
"postinstall": "pnpm run gen:theme-typings",
1516
"postbuild": "next-sitemap",

apps/dashboard/src/@/lib/reactive.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
type Store<T> = {
1+
import { useSyncExternalStore } from "react";
2+
3+
export type Store<T> = {
24
getValue(): T;
35
setValue(newValue: T): void;
46
subscribe(listener: () => void): () => void;
@@ -45,3 +47,7 @@ export function createStore<T>(initialValue: T): Store<T> {
4547
},
4648
};
4749
}
50+
51+
export function useStore<T>(store: Store<T>): T {
52+
return useSyncExternalStore(store.subscribe, store.getValue, store.getValue);
53+
}

apps/dashboard/src/@3rdweb-sdk/react/components/connect-wallet/index.tsx

Lines changed: 73 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,31 @@
33
import { Spinner } from "@/components/ui/Spinner/Spinner";
44
import { Button } from "@/components/ui/button";
55
import { useThirdwebClient } from "@/constants/thirdweb.client";
6+
import { useStore } from "@/lib/reactive";
67
import { getSDKTheme } from "app/components/sdk-component-theme";
78
import { CustomChainRenderer } from "components/selects/CustomChainRenderer";
89
import { mapV4ChainToV5Chain } from "contexts/map-chains";
910
import { useTrack } from "hooks/analytics/useTrack";
10-
import {
11-
useSupportedChains,
12-
useSupportedChainsRecord,
13-
} from "hooks/chains/configureChains";
14-
import {
15-
useAddRecentlyUsedChainId,
16-
useRecentlyUsedChains,
17-
} from "hooks/chains/recentlyUsedChains";
1811
import { useTheme } from "next-themes";
1912
import Image from "next/image";
2013
import Link from "next/link";
2114
import { usePathname } from "next/navigation";
2215
import { useCallback, useMemo, useState } from "react";
2316
import type { Chain } from "thirdweb";
24-
import { AutoConnect, ConnectButton, useConnectModal } from "thirdweb/react";
17+
import {
18+
AutoConnect,
19+
ConnectButton,
20+
type NetworkSelectorProps,
21+
useConnectModal,
22+
} from "thirdweb/react";
23+
import { useFavoriteChainIds } from "../../../../app/(dashboard)/(chain)/components/client/star-button";
2524
import { LazyConfigureNetworkModal } from "../../../../components/configure-networks/LazyConfigureNetworkModal";
26-
import type { StoredChain } from "../../../../contexts/configured-chains";
27-
import { useFavoriteChains } from "../../hooks/useFavoriteChains";
25+
import { useAllChainsData } from "../../../../hooks/chains/allChains";
26+
import {
27+
type StoredChain,
28+
addRecentlyUsedChainId,
29+
recentlyUsedChainIdsStore,
30+
} from "../../../../stores/chainStores";
2831
import { useLoggedInUser } from "../../hooks/useLoggedInUser";
2932
import { popularChains } from "../popularChains";
3033

@@ -36,43 +39,81 @@ export const CustomConnectWallet = (props: {
3639
const thirdwebClient = useThirdwebClient();
3740
const loginRequired =
3841
props.loginRequired === undefined ? true : props.loginRequired;
42+
3943
const { theme } = useTheme();
40-
const recentChainsv4 = useRecentlyUsedChains();
41-
const addRecentlyUsedChainId = useAddRecentlyUsedChainId();
4244
const t = theme === "light" ? "light" : "dark";
43-
const allv4Chains = useSupportedChains();
44-
const chainsRecord = useSupportedChainsRecord();
45-
const favChainsQuery = useFavoriteChains();
46-
const allChains = useMemo(() => {
47-
return allv4Chains.map(mapV4ChainToV5Chain);
48-
}, [allv4Chains]);
4945

50-
const popularChainsWithMeta = useMemo(() => {
51-
return popularChains.map((x) => chainsRecord[x.id] || x);
52-
}, [chainsRecord]);
46+
// chains
47+
const favChainIdsQuery = useFavoriteChainIds();
48+
const recentChainIds = useStore(recentlyUsedChainIdsStore);
49+
const { idToChain, allChains } = useAllChainsData();
50+
51+
const allChainsWithMetadata = useMemo(
52+
() => allChains.map(mapV4ChainToV5Chain),
53+
[allChains],
54+
);
55+
56+
const recentlyUsedChainsWithMetadata = useMemo(
57+
() =>
58+
recentChainIds
59+
.map((id) => {
60+
const c = idToChain.get(id);
61+
// eslint-disable-next-line no-restricted-syntax
62+
return c ? mapV4ChainToV5Chain(c) : undefined;
63+
})
64+
.filter((x) => !!x),
65+
[recentChainIds, idToChain],
66+
);
67+
68+
const favoriteChainsWithMetadata = useMemo(() => {
69+
return (favChainIdsQuery.data || [])
70+
.map((id) => {
71+
const c = idToChain.get(Number(id));
72+
// eslint-disable-next-line no-restricted-syntax
73+
return c ? mapV4ChainToV5Chain(c) : undefined;
74+
})
75+
.filter((x) => !!x);
76+
}, [idToChain, favChainIdsQuery.data]);
77+
78+
const popularChainsWithMetadata = useMemo(() => {
79+
// eslint-disable-next-line no-restricted-syntax
80+
return popularChains.map((x) =>
81+
// eslint-disable-next-line no-restricted-syntax
82+
{
83+
const v4Chain = idToChain.get(x.id);
84+
// eslint-disable-next-line no-restricted-syntax
85+
return v4Chain ? mapV4ChainToV5Chain(v4Chain) : x;
86+
},
87+
);
88+
}, [idToChain]);
5389

90+
// Network Config Modal
5491
const [isNetworkConfigModalOpen, setIsNetworkConfigModalOpen] =
5592
useState(false);
5693
const [editChain, setEditChain] = useState<StoredChain | undefined>(
5794
undefined,
5895
);
5996

60-
const chainSections = useMemo(() => {
97+
const chainSections: NetworkSelectorProps["sections"] = useMemo(() => {
6198
return [
6299
{
63100
label: "Favorites",
64-
chains: favChainsQuery.data.map(mapV4ChainToV5Chain),
101+
chains: favoriteChainsWithMetadata,
65102
},
66103
{
67-
label: "Popular",
68-
chains: popularChainsWithMeta.map(mapV4ChainToV5Chain),
104+
label: "Recent",
105+
chains: recentlyUsedChainsWithMetadata,
69106
},
70107
{
71-
label: "Recent",
72-
chains: recentChainsv4.map(mapV4ChainToV5Chain),
108+
label: "Popular",
109+
chains: popularChainsWithMetadata,
73110
},
74111
];
75-
}, [recentChainsv4, favChainsQuery.data, popularChainsWithMeta]);
112+
}, [
113+
recentlyUsedChainsWithMetadata,
114+
favoriteChainsWithMetadata,
115+
popularChainsWithMetadata,
116+
]);
76117

77118
// ensures login status on pages that need it
78119
const { isPending, isLoggedIn } = useLoggedInUser();
@@ -84,7 +125,7 @@ export const CustomConnectWallet = (props: {
84125
<div className="w-[144px] h-[48px] bg-muted border border-border rounded-lg flex items-center justify-center">
85126
<Spinner className="size-4" />
86127
</div>
87-
{/* need autoconnect here so that we actually connect */}
128+
{/* need auto connect here so that we actually connect */}
88129
<AutoConnect client={thirdwebClient} />
89130
</>
90131
);
@@ -100,7 +141,7 @@ export const CustomConnectWallet = (props: {
100141
Sign In
101142
</Link>
102143
</Button>
103-
{/* need autoconnect here so that we actually connect */}
144+
{/* need auto connect here so that we actually connect */}
104145
<AutoConnect client={thirdwebClient} />
105146
</>
106147
);
@@ -138,7 +179,7 @@ export const CustomConnectWallet = (props: {
138179
detailsButton={{
139180
className: props.detailsButtonClassName,
140181
}}
141-
chains={allChains}
182+
chains={allChainsWithMetadata}
142183
detailsModal={{
143184
networkSelector: {
144185
sections: chainSections,

apps/dashboard/src/@3rdweb-sdk/react/hooks/useApi.ts

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {
55
useQueryClient,
66
} from "@tanstack/react-query";
77
import { THIRDWEB_ANALYTICS_API_HOST, THIRDWEB_API_HOST } from "constants/urls";
8-
import type { ChainMetadata } from "thirdweb/chains";
98
import invariant from "tiny-invariant";
109
import { accountKeys, apiKeys, authorizedWallets } from "../cache-keys";
1110
import { useMutationWithInvalidate } from "./query/useQueryWithNetwork";
@@ -947,28 +946,3 @@ export function useAuthorizedWallets() {
947946
gcTime: 0,
948947
});
949948
}
950-
951-
/**
952-
*
953-
*/
954-
async function fetchChainsFromApi() {
955-
// always fetch from prod for chains for now
956-
// TODO: re-visit this
957-
const res = await fetch("https://api.thirdweb.com/v1/chains");
958-
const json = await res.json();
959-
960-
if (json.error) {
961-
throw new Error(json.error.message);
962-
}
963-
964-
return json.data as ChainMetadata[];
965-
}
966-
967-
export function useApiChains() {
968-
return useQuery({
969-
queryKey: ["all-chains"],
970-
queryFn: () => {
971-
return fetchChainsFromApi();
972-
},
973-
});
974-
}

apps/dashboard/src/@3rdweb-sdk/react/hooks/useFavoriteChains.ts

Lines changed: 0 additions & 31 deletions
This file was deleted.

apps/dashboard/src/@3rdweb-sdk/react/hooks/useRegistry.ts

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import {
88
import type { BasicContract } from "contract-ui/types/types";
99
import { getAllMultichainRegistry } from "dashboard-extensions/common/read/getAllMultichainRegistry";
1010
import { useAllChainsData } from "hooks/chains/allChains";
11-
import { useSupportedChainsRecord } from "hooks/chains/configureChains";
1211
import { useMemo } from "react";
1312
import { sendAndConfirmTransaction } from "thirdweb";
1413
import { remove } from "thirdweb/extensions/thirdweb";
@@ -42,7 +41,8 @@ export const useAllContractList = (
4241
) => {
4342
const multiChainQuery = useMultiChainRegContractList(walletAddress);
4443

45-
const configuredChainsRecord = useSupportedChainsRecord();
44+
// TODO - instead of using ALL chains, fetch only the ones used here
45+
const { idToChain } = useAllChainsData();
4646
const contractList = useMemo(() => {
4747
const data = multiChainQuery.data || [];
4848

@@ -51,14 +51,12 @@ export const useAllContractList = (
5151

5252
// biome-ignore lint/complexity/noForEach: FIXME
5353
data.forEach((net) => {
54-
if (net.chainId in configuredChainsRecord) {
55-
const chainRecord = configuredChainsRecord[net.chainId];
56-
if (chainRecord.status !== "deprecated") {
57-
if (chainRecord.testnet) {
58-
testnets.push(net);
59-
} else {
60-
mainnets.push(net);
61-
}
54+
const chn = idToChain.get(net.chainId);
55+
if (chn && chn.status !== "deprecated") {
56+
if (chn.testnet) {
57+
testnets.push(net);
58+
} else {
59+
mainnets.push(net);
6260
}
6361
}
6462
});
@@ -71,7 +69,7 @@ export const useAllContractList = (
7169

7270
testnets.sort((a, b) => a.chainId - b.chainId);
7371
return mainnets.concat(testnets);
74-
}, [multiChainQuery.data, onlyMainnet, configuredChainsRecord]);
72+
}, [multiChainQuery.data, onlyMainnet, idToChain]);
7573

7674
return {
7775
...multiChainQuery,
@@ -85,12 +83,10 @@ type RemoveContractParams = {
8583
};
8684

8785
export function useRemoveContractMutation() {
88-
const { chainIdToChainRecord } = useAllChainsData();
8986
const queryClient = useQueryClient();
9087
const account = useActiveAccount();
9188
return useMutation({
9289
mutationFn: async (data: RemoveContractParams) => {
93-
invariant(chainIdToChainRecord, "chains not initialzed yet");
9490
invariant(data.chainId, "chainId not provided");
9591
invariant(account, "No wallet connected");
9692
const { contractAddress, chainId } = data;

apps/dashboard/src/app/(dashboard)/(chain)/components/client/star-button.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ async function removeChainFromFavorites(chainId: number) {
4242
return result?.data?.favorite;
4343
}
4444

45-
export function useFavouriteChainIds() {
45+
export function useFavoriteChainIds() {
4646
const loggedInUser = useLoggedInUser();
4747
return useQuery({
4848
queryKey: ["favoriteChains", loggedInUser.user?.address],
@@ -59,7 +59,7 @@ export function StarButton(props: {
5959
}) {
6060
const loggedInUser = useLoggedInUser();
6161
const queryClient = useQueryClient();
62-
const favChainsQuery = useFavouriteChainIds();
62+
const favChainsQuery = useFavoriteChainIds();
6363

6464
const mutation = useMutation({
6565
mutationFn: (preferred: boolean) => {

apps/dashboard/src/app/providers.tsx

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,21 @@
11
"use client";
22

33
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
4-
import { AllChainsProvider } from "contexts/all-chains";
5-
import { ChainsProvider } from "contexts/configured-chains";
64
import { ThemeProvider } from "next-themes";
75
import { ThirdwebProvider } from "thirdweb/react";
6+
import { SyncChainStores } from "../stores/chainStores";
87

98
const queryClient = new QueryClient();
109

1110
export function AppRouterProviders(props: { children: React.ReactNode }) {
1211
return (
1312
<QueryClientProvider client={queryClient}>
14-
<AllChainsProvider>
15-
<ChainsProvider>
16-
<ThirdwebProvider>
17-
<ThemeProvider attribute="class" defaultTheme="dark">
18-
{props.children}
19-
</ThemeProvider>
20-
</ThirdwebProvider>
21-
</ChainsProvider>
22-
</AllChainsProvider>
13+
<SyncChainStores />
14+
<ThirdwebProvider>
15+
<ThemeProvider attribute="class" defaultTheme="dark">
16+
{props.children}
17+
</ThemeProvider>
18+
</ThirdwebProvider>
2319
</QueryClientProvider>
2420
);
2521
}

0 commit comments

Comments
 (0)