Skip to content

Commit 8ff34c8

Browse files
Add deprecation notices to chains (#2211)
* Add deprecation alert warning to ChainPage * Add deprecation alert to contracts pages * Add deprecation notice to chainlist and rpc-edge list * chain id -> chain ID * Add deprecation notice to chain selection * Save status * Remove log * Fix feedback * Disable txn button, add alert to deployment form
1 parent d17ad23 commit 8ff34c8

File tree

12 files changed

+412
-140
lines changed

12 files changed

+412
-140
lines changed

@3rdweb-sdk/react/components/popularChains.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
11
import {
22
Arbitrum,
3-
ArbitrumGoerli,
3+
ArbitrumSepolia,
44
Avalanche,
55
AvalancheFuji,
6-
BaseGoerli,
6+
BaseSepoliaTestnet,
77
Binance,
88
Ethereum,
99
Fantom,
1010
FantomTestnet,
11-
Goerli,
1211
Localhost,
1312
Mumbai,
13+
OpSepoliaTestnet,
1414
Optimism,
15-
OptimismGoerli,
1615
Polygon,
16+
Sepolia,
1717
} from "@thirdweb-dev/chains";
1818

1919
export const popularChains = [
2020
Ethereum,
21-
Goerli,
21+
Sepolia,
2222
Polygon,
2323
Mumbai,
24-
BaseGoerli,
24+
BaseSepoliaTestnet,
2525
Arbitrum,
26-
ArbitrumGoerli,
26+
ArbitrumSepolia,
2727
Optimism,
28-
OptimismGoerli,
28+
OpSepoliaTestnet,
2929
Binance,
3030
Fantom,
3131
FantomTestnet,

components/buttons/TransactionButton.tsx

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616

1717
import {
1818
useAddress,
19+
useChain,
1920
useChainId,
2021
useInstalledWallets,
2122
useWallet,
@@ -68,6 +69,12 @@ export const TransactionButton: React.FC<TransactionButtonProps> = ({
6869
const walletRequiresExternalConfirmation = useWalletRequiresConfirmation();
6970
const initialFocusRef = useRef<HTMLButtonElement>(null);
7071

72+
const chain = useChain();
73+
const isChainDeprecated = useMemo(
74+
() => chain?.status === "deprecated",
75+
[chain],
76+
);
77+
7178
const ColorModeComp =
7279
colorMode.colorMode === "dark" ? DarkMode : React.Fragment;
7380

@@ -114,6 +121,7 @@ export const TransactionButton: React.FC<TransactionButtonProps> = ({
114121
size === "sm" ? 3 : size === "lg" ? 6 : size === "xs" ? 2 : 4
115122
}))`
116123
}
124+
isDisabled={isChainDeprecated}
117125
>
118126
{children}
119127
<Tooltip
@@ -122,14 +130,25 @@ export const TransactionButton: React.FC<TransactionButtonProps> = ({
122130
p={0}
123131
w="auto"
124132
label={
125-
<ColorModeComp>
126-
<Card w="auto" py={2} bgColor="backgroundHighlight">
127-
<Text>
128-
This action will trigger {transactionCount}{" "}
129-
{transactionCount > 1 ? "transactions" : "transaction"}.
130-
</Text>
131-
</Card>
132-
</ColorModeComp>
133+
isChainDeprecated ? (
134+
<ColorModeComp>
135+
<Card w="auto" py={2} bgColor="backgroundHighlight">
136+
<Text>
137+
This chain is deprecated so you cannot execute
138+
transactions on it.
139+
</Text>
140+
</Card>
141+
</ColorModeComp>
142+
) : (
143+
<ColorModeComp>
144+
<Card w="auto" py={2} bgColor="backgroundHighlight">
145+
<Text>
146+
This action will trigger {transactionCount}{" "}
147+
{transactionCount > 1 ? "transactions" : "transaction"}.
148+
</Text>
149+
</Card>
150+
</ColorModeComp>
151+
)
133152
}
134153
>
135154
<Center

components/configure-networks/ConfigureNetworkForm.tsx

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { useAllChainsData } from "hooks/chains/allChains";
2121
import { useSupportedChainsNameRecord } from "hooks/chains/configureChains";
2222
import { useRemoveChainModification } from "hooks/chains/useModifyChain";
2323
import { getDashboardChainRpc } from "lib/rpc";
24-
import React, { useEffect } from "react";
24+
import { useEffect } from "react";
2525
import { useForm } from "react-hook-form";
2626
import { Button, FormErrorMessage, FormLabel, Text } from "tw-components";
2727

@@ -33,6 +33,7 @@ export type NetworkConfigFormData = {
3333
type: "testnet" | "mainnet";
3434
icon: string;
3535
slug: string;
36+
status: string;
3637
};
3738

3839
// lowercase it, replace all spaces with hyphens, and then strip all non-alphanumeric characters
@@ -64,14 +65,18 @@ export const ConfigureNetworkForm: React.FC<NetworkConfigFormProps> = ({
6465
const form = useForm<NetworkConfigFormData>({
6566
values: {
6667
name: editingChain?.name || "",
67-
rpcUrl: editingChain ? getDashboardChainRpc(editingChain) : "" || "",
68+
rpcUrl:
69+
editingChain && editingChain?.status !== "deprecated"
70+
? getDashboardChainRpc(editingChain)
71+
: "" || "",
6872
chainId: editingChain?.chainId
6973
? `${editingChain?.chainId}`
7074
: "" || prefillChainId || "",
7175
currencySymbol: editingChain?.nativeCurrency.symbol || "",
7276
type: editingChain?.testnet ? "testnet" : "mainnet",
7377
icon: editingChain?.icon?.url || "",
7478
slug: editingChain?.slug || "",
79+
status: editingChain?.status === "deprecated" ? "deprecated" : "active",
7580
},
7681
mode: "onChange",
7782
});
@@ -148,6 +153,7 @@ export const ConfigureNetworkForm: React.FC<NetworkConfigFormProps> = ({
148153
format: "",
149154
},
150155
testnet: data.type === "testnet",
156+
status: data.status,
151157
};
152158
} else {
153159
configuredNetwork = {
@@ -172,6 +178,7 @@ export const ConfigureNetworkForm: React.FC<NetworkConfigFormProps> = ({
172178
format: "",
173179
}
174180
: undefined,
181+
status: data.status,
175182
};
176183
}
177184

@@ -347,6 +354,29 @@ export const ConfigureNetworkForm: React.FC<NetworkConfigFormProps> = ({
347354
</FormControl>
348355
</SimpleGrid>
349356

357+
{editingChain?.status === "deprecated" && (
358+
<SimpleGrid columns={{ md: 2, base: 1 }} gap={4}>
359+
{/* Active / Deprecated */}
360+
<FormControl>
361+
<FormLabel display="flex">Network status</FormLabel>
362+
<RadioGroup
363+
onChange={(value: "active" | "deprecated") => {
364+
form.setValue("status", value, {
365+
shouldValidate: true,
366+
shouldDirty: true,
367+
});
368+
}}
369+
value={form.watch("status")}
370+
>
371+
<Stack direction="row" gap={4} mt={3}>
372+
<Radio value="active">Live</Radio>
373+
<Radio value="deprecated">Deprecated</Radio>
374+
</Stack>
375+
</RadioGroup>
376+
</FormControl>
377+
</SimpleGrid>
378+
)}
379+
350380
{/* RPC URL */}
351381
<RpcInput form={form} />
352382

components/configure-networks/Form/RpcInput.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@ export const RpcInput: React.FC<{
2222
});
2323

2424
return (
25-
<FormControl isRequired isInvalid={!!form.formState.errors.rpcUrl}>
25+
<FormControl
26+
isRequired
27+
isInvalid={!!form.formState.errors.rpcUrl}
28+
isDisabled={form.watch("status") !== "active"}
29+
>
2630
<FormLabel>RPC URL</FormLabel>
2731
<Input
2832
autoComplete="off"

components/contract-components/contract-deploy-form/custom-contract.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import {
5050
TrackedLink,
5151
} from "tw-components";
5252
import { TrustedForwardersFieldset } from "./trusted-forwarders-fieldset";
53+
import { DeprecatedAlert } from "components/shared/DeprecatedAlert";
5354

5455
interface CustomContractFormProps {
5556
ipfsHash: string;
@@ -69,7 +70,6 @@ const CustomContractForm: React.FC<CustomContractFormProps> = ({
6970
walletAddress,
7071
}) => {
7172
const { data: transactions } = useTransactionsForDeploy(ipfsHash);
72-
7373
const networkInfo = useSupportedChain(selectedChain || -1);
7474
const ensQuery = useEns(walletAddress);
7575
const connectedWallet = ensQuery.data?.address || walletAddress;
@@ -585,6 +585,9 @@ const CustomContractForm: React.FC<CustomContractFormProps> = ({
585585
Deploy Now
586586
</TransactionButton>
587587
</Flex>
588+
{networkInfo?.status === "deprecated" && networkInfo?.name && (
589+
<DeprecatedAlert chainName={networkInfo?.name} />
590+
)}
588591
</Flex>
589592
</FormProvider>
590593
);

components/contract-components/import-contract/modal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export const ImportModal: React.FC<ImportModalProps> = (props) => {
5151
as="form"
5252
onSubmit={form.handleSubmit(async (data) => {
5353
if (!chainId) {
54-
throw new Error("No chain id");
54+
throw new Error("No chain ID");
5555
}
5656

5757
try {

components/selects/CustomChainRenderer.tsx

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
useSetIsNetworkConfigModalOpen,
88
} from "hooks/networkConfigModal";
99
import { RxGear } from "react-icons/rx";
10-
import { Text } from "tw-components";
10+
import { Heading, Text } from "tw-components";
1111

1212
export const CustomChainRenderer: NetworkSelectorProps["renderChain"] = ({
1313
chain,
@@ -20,6 +20,8 @@ export const CustomChainRenderer: NetworkSelectorProps["renderChain"] = ({
2020
const addRecentlyUsedChain = useAddRecentlyUsedChainId();
2121
const setEditChain = useSetEditChain();
2222

23+
const isDeprecated = chain.status === "deprecated";
24+
2325
return (
2426
<Flex
2527
w="100%"
@@ -35,15 +37,42 @@ export const CustomChainRenderer: NetworkSelectorProps["renderChain"] = ({
3537
<Flex role="group" flexGrow={1} alignItems="center">
3638
<Flex
3739
onClick={() => {
38-
switchChain();
40+
if (!isDeprecated) {
41+
switchChain();
42+
}
3943
}}
4044
flexGrow={1}
4145
gap={4}
4246
alignItems="center"
47+
cursor={isDeprecated ? "not-allowed" : "pointer"}
4348
>
4449
<ChainIcon ipfsSrc={chain.icon?.url} size={32} />
4550
<Flex gap={1} flexDir="column" alignItems="start">
46-
<Text fontWeight={500}>{chain.name}</Text>
51+
<Flex gap={2}>
52+
<Text fontWeight={500} color={isDeprecated ? "faded" : "inherit"}>
53+
{chain.name}
54+
</Text>
55+
{isDeprecated && (
56+
<Flex alignItems="center">
57+
<Flex
58+
borderRadius="full"
59+
align="center"
60+
border="1px solid"
61+
borderColor="borderColor"
62+
overflow="hidden"
63+
flexShrink={0}
64+
py={{ base: 1.5, md: 1 }}
65+
px={{ base: 1.5, md: 2 }}
66+
gap={3}
67+
cursor="not-allowed"
68+
>
69+
<Heading size="label.sm" as="label" cursor="not-allowed">
70+
Deprecated
71+
</Heading>
72+
</Flex>
73+
</Flex>
74+
)}
75+
</Flex>
4776
{switching && (
4877
<Flex
4978
color="blue.500"

components/shared/DeprecatedAlert.tsx

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import {
2+
Alert,
3+
AlertIcon,
4+
Flex,
5+
AlertTitle,
6+
AlertDescription,
7+
} from "@chakra-ui/react";
8+
import { getChainByChainId } from "@thirdweb-dev/chains";
9+
import { Text } from "tw-components";
10+
11+
interface DeprecatedAlertProps {
12+
chainName: string;
13+
description?: string;
14+
recommendedChainId?: number;
15+
}
16+
17+
export const DeprecatedAlert: React.FC<DeprecatedAlertProps> = ({
18+
chainName,
19+
description = "thirdweb services are not available on this network.",
20+
recommendedChainId,
21+
}) => {
22+
const recommendedChainName = recommendedChainId
23+
? getChainByChainId(recommendedChainId).name
24+
: undefined;
25+
26+
return (
27+
<Alert
28+
status="error"
29+
borderRadius="lg"
30+
backgroundColor="backgroundCardHighlight"
31+
borderLeftColor="red.500"
32+
borderLeftWidth={4}
33+
as={Flex}
34+
gap={1}
35+
>
36+
<AlertIcon />
37+
<Flex flexDir="column">
38+
<AlertTitle>{chainName} is deprecated</AlertTitle>
39+
<AlertDescription as={Text}>
40+
{description}{" "}
41+
{recommendedChainId && (
42+
<>
43+
We recommend switching to <strong>{recommendedChainName}</strong>{" "}
44+
to continue testing your smart contracts.
45+
</>
46+
)}
47+
</AlertDescription>
48+
</Flex>
49+
</Alert>
50+
);
51+
};

pages/[chainSlug]/[...paths].tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import { shortenIfAddress } from "utils/usedapp-external";
4141
import { ClientOnly } from "../../components/ClientOnly/ClientOnly";
4242
import { THIRDWEB_DOMAIN } from "constants/urls";
4343
import { getAddress } from "ethers/lib/utils";
44+
import { DeprecatedAlert } from "components/shared/DeprecatedAlert";
4445

4546
type EVMContractProps = {
4647
contractInfo?: EVMContractInfo;
@@ -217,7 +218,7 @@ const EVMContractPage: ThirdwebNextPage = () => {
217218
>
218219
<Box borderColor="borderColor" borderBottomWidth={1} w="full" pb={8}>
219220
<Container maxW="container.page">
220-
<Flex direction="column">
221+
<Flex direction="column" gap={4}>
221222
<Flex
222223
justify="space-between"
223224
align={{ base: "inherit", md: "center" }}
@@ -231,6 +232,12 @@ const EVMContractPage: ThirdwebNextPage = () => {
231232
/>
232233
<PrimaryDashboardButton contractAddress={contractAddress} />
233234
</Flex>
235+
{chain?.name && (
236+
<DeprecatedAlert
237+
chainName={chain.name}
238+
description="You can't interact with this contract through the dashboard as this chain has been deprecated."
239+
/>
240+
)}
234241
</Flex>
235242
</Container>
236243
</Box>

0 commit comments

Comments
 (0)