thirdweb 5.32.0 → 5.32.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/chains/utils.js +9 -7
- package/dist/cjs/chains/utils.js.map +1 -1
- package/dist/cjs/exports/react.js +3 -0
- package/dist/cjs/exports/react.js.map +1 -1
- package/dist/cjs/exports/wallets/smart.js +3 -1
- package/dist/cjs/exports/wallets/smart.js.map +1 -1
- package/dist/cjs/react/core/hooks/others/useChainQuery.js +104 -33
- package/dist/cjs/react/core/hooks/others/useChainQuery.js.map +1 -1
- package/dist/cjs/react/native/ui/components/ChainIcon.js +2 -3
- package/dist/cjs/react/native/ui/components/ChainIcon.js.map +1 -1
- package/dist/cjs/react/native/ui/connect/ConnectedModal.js +2 -2
- package/dist/cjs/react/native/ui/connect/ConnectedModal.js.map +1 -1
- package/dist/cjs/react/native/ui/connect/SendScreen.js +2 -2
- package/dist/cjs/react/native/ui/connect/SendScreen.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/Details.js +6 -5
- package/dist/cjs/react/web/ui/ConnectWallet/Details.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/NetworkSelector.js +217 -188
- package/dist/cjs/react/web/ui/ConnectWallet/NetworkSelector.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js +2 -4
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatSteps.js +12 -10
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatSteps.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatTxDetailsTable.js +2 -2
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatTxDetailsTable.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/BuyTokenInput.js +2 -2
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/BuyTokenInput.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js +2 -2
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.js +2 -2
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/tx-history/BuyTxHistory.js +2 -2
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/tx-history/BuyTxHistory.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/tx-history/SwapDetailsScreen.js +8 -6
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/tx-history/SwapDetailsScreen.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/tx-history/TokenInfoRow.js +2 -2
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/tx-history/TokenInfoRow.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/TokenSelector.js +3 -2
- package/dist/cjs/react/web/ui/ConnectWallet/screens/TokenSelector.js.map +1 -1
- package/dist/cjs/react/web/ui/components/ChainIcon.js +1 -1
- package/dist/cjs/react/web/ui/components/ChainIcon.js.map +1 -1
- package/dist/cjs/react/web/ui/components/ChainName.js +3 -5
- package/dist/cjs/react/web/ui/components/ChainName.js.map +1 -1
- package/dist/cjs/react/web/ui/components/TokenIcon.js +3 -3
- package/dist/cjs/react/web/ui/components/TokenIcon.js.map +1 -1
- package/dist/cjs/react/web/ui/components/token/TokenSymbol.js +3 -3
- package/dist/cjs/react/web/ui/components/token/TokenSymbol.js.map +1 -1
- package/dist/cjs/react/web/wallets/ecosystem/EcosystemWalletFormUI.js +1 -1
- package/dist/cjs/react/web/wallets/ecosystem/EcosystemWalletFormUI.js.map +1 -1
- package/dist/cjs/utils/extensions/drops/get-claim-params.js +3 -2
- package/dist/cjs/utils/extensions/drops/get-claim-params.js.map +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/wallets/in-app/web/ecosystem.js +3 -14
- package/dist/cjs/wallets/in-app/web/ecosystem.js.map +1 -1
- package/dist/cjs/wallets/smart/index.js +3 -17
- package/dist/cjs/wallets/smart/index.js.map +1 -1
- package/dist/cjs/wallets/smart/lib/bundler.js +1 -1
- package/dist/cjs/wallets/smart/lib/bundler.js.map +1 -1
- package/dist/cjs/wallets/smart/lib/userop.js +63 -8
- package/dist/cjs/wallets/smart/lib/userop.js.map +1 -1
- package/dist/esm/chains/utils.js +9 -7
- package/dist/esm/chains/utils.js.map +1 -1
- package/dist/esm/exports/react.js +1 -0
- package/dist/esm/exports/react.js.map +1 -1
- package/dist/esm/exports/wallets/smart.js +1 -0
- package/dist/esm/exports/wallets/smart.js.map +1 -1
- package/dist/esm/react/core/hooks/others/useChainQuery.js +101 -33
- package/dist/esm/react/core/hooks/others/useChainQuery.js.map +1 -1
- package/dist/esm/react/native/ui/components/ChainIcon.js +3 -4
- package/dist/esm/react/native/ui/components/ChainIcon.js.map +1 -1
- package/dist/esm/react/native/ui/connect/ConnectedModal.js +3 -3
- package/dist/esm/react/native/ui/connect/ConnectedModal.js.map +1 -1
- package/dist/esm/react/native/ui/connect/SendScreen.js +3 -3
- package/dist/esm/react/native/ui/connect/SendScreen.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/Details.js +7 -6
- package/dist/esm/react/web/ui/ConnectWallet/Details.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/NetworkSelector.js +219 -191
- package/dist/esm/react/web/ui/ConnectWallet/NetworkSelector.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js +3 -5
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatSteps.js +13 -11
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatSteps.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatTxDetailsTable.js +3 -3
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatTxDetailsTable.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/BuyTokenInput.js +3 -3
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/BuyTokenInput.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js +3 -3
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.js +3 -3
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/tx-history/BuyTxHistory.js +3 -3
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/tx-history/BuyTxHistory.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/tx-history/SwapDetailsScreen.js +9 -7
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/tx-history/SwapDetailsScreen.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/tx-history/TokenInfoRow.js +3 -3
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/tx-history/TokenInfoRow.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/TokenSelector.js +4 -3
- package/dist/esm/react/web/ui/ConnectWallet/screens/TokenSelector.js.map +1 -1
- package/dist/esm/react/web/ui/components/ChainIcon.js +1 -1
- package/dist/esm/react/web/ui/components/ChainIcon.js.map +1 -1
- package/dist/esm/react/web/ui/components/ChainName.js +4 -6
- package/dist/esm/react/web/ui/components/ChainName.js.map +1 -1
- package/dist/esm/react/web/ui/components/TokenIcon.js +4 -4
- package/dist/esm/react/web/ui/components/TokenIcon.js.map +1 -1
- package/dist/esm/react/web/ui/components/token/TokenSymbol.js +4 -4
- package/dist/esm/react/web/ui/components/token/TokenSymbol.js.map +1 -1
- package/dist/esm/react/web/wallets/ecosystem/EcosystemWalletFormUI.js +2 -2
- package/dist/esm/react/web/wallets/ecosystem/EcosystemWalletFormUI.js.map +1 -1
- package/dist/esm/utils/extensions/drops/get-claim-params.js +3 -2
- package/dist/esm/utils/extensions/drops/get-claim-params.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/wallets/in-app/web/ecosystem.js +3 -14
- package/dist/esm/wallets/in-app/web/ecosystem.js.map +1 -1
- package/dist/esm/wallets/smart/index.js +4 -18
- package/dist/esm/wallets/smart/index.js.map +1 -1
- package/dist/esm/wallets/smart/lib/bundler.js +1 -1
- package/dist/esm/wallets/smart/lib/bundler.js.map +1 -1
- package/dist/esm/wallets/smart/lib/userop.js +63 -9
- package/dist/esm/wallets/smart/lib/userop.js.map +1 -1
- package/dist/types/chains/chain-definitions/anvil.d.ts +1 -0
- package/dist/types/chains/chain-definitions/anvil.d.ts.map +1 -1
- package/dist/types/chains/chain-definitions/arbitrum-nova.d.ts +1 -0
- package/dist/types/chains/chain-definitions/arbitrum-nova.d.ts.map +1 -1
- package/dist/types/chains/chain-definitions/arbitrum-sepolia.d.ts +1 -0
- package/dist/types/chains/chain-definitions/arbitrum-sepolia.d.ts.map +1 -1
- package/dist/types/chains/chain-definitions/arbitrum.d.ts +1 -0
- package/dist/types/chains/chain-definitions/arbitrum.d.ts.map +1 -1
- package/dist/types/chains/chain-definitions/avalanche-fuji.d.ts +1 -0
- package/dist/types/chains/chain-definitions/avalanche-fuji.d.ts.map +1 -1
- package/dist/types/chains/chain-definitions/avalanche.d.ts +1 -0
- package/dist/types/chains/chain-definitions/avalanche.d.ts.map +1 -1
- package/dist/types/chains/chain-definitions/base-sepolia.d.ts +1 -0
- package/dist/types/chains/chain-definitions/base-sepolia.d.ts.map +1 -1
- package/dist/types/chains/chain-definitions/base.d.ts +1 -0
- package/dist/types/chains/chain-definitions/base.d.ts.map +1 -1
- package/dist/types/chains/chain-definitions/bsc-testnet.d.ts +1 -0
- package/dist/types/chains/chain-definitions/bsc-testnet.d.ts.map +1 -1
- package/dist/types/chains/chain-definitions/bsc.d.ts +1 -0
- package/dist/types/chains/chain-definitions/bsc.d.ts.map +1 -1
- package/dist/types/chains/chain-definitions/ethereum.d.ts +2 -0
- package/dist/types/chains/chain-definitions/ethereum.d.ts.map +1 -1
- package/dist/types/chains/chain-definitions/hardhat.d.ts +1 -0
- package/dist/types/chains/chain-definitions/hardhat.d.ts.map +1 -1
- package/dist/types/chains/chain-definitions/linea-sepolia.d.ts +1 -0
- package/dist/types/chains/chain-definitions/linea-sepolia.d.ts.map +1 -1
- package/dist/types/chains/chain-definitions/linea.d.ts +1 -0
- package/dist/types/chains/chain-definitions/linea.d.ts.map +1 -1
- package/dist/types/chains/chain-definitions/optimism-sepolia.d.ts +1 -0
- package/dist/types/chains/chain-definitions/optimism-sepolia.d.ts.map +1 -1
- package/dist/types/chains/chain-definitions/optimism.d.ts +1 -0
- package/dist/types/chains/chain-definitions/optimism.d.ts.map +1 -1
- package/dist/types/chains/chain-definitions/polygon-amoy.d.ts +1 -0
- package/dist/types/chains/chain-definitions/polygon-amoy.d.ts.map +1 -1
- package/dist/types/chains/chain-definitions/polygon-mumbai.d.ts +2 -0
- package/dist/types/chains/chain-definitions/polygon-mumbai.d.ts.map +1 -1
- package/dist/types/chains/chain-definitions/polygon.d.ts +1 -0
- package/dist/types/chains/chain-definitions/polygon.d.ts.map +1 -1
- package/dist/types/chains/chain-definitions/sepolia.d.ts +1 -0
- package/dist/types/chains/chain-definitions/sepolia.d.ts.map +1 -1
- package/dist/types/chains/chain-definitions/zksync-sepolia.d.ts +1 -0
- package/dist/types/chains/chain-definitions/zksync-sepolia.d.ts.map +1 -1
- package/dist/types/chains/chain-definitions/zksync.d.ts +1 -0
- package/dist/types/chains/chain-definitions/zksync.d.ts.map +1 -1
- package/dist/types/chains/chain-definitions/zora-sepolia.d.ts +1 -0
- package/dist/types/chains/chain-definitions/zora-sepolia.d.ts.map +1 -1
- package/dist/types/chains/chain-definitions/zora.d.ts +1 -0
- package/dist/types/chains/chain-definitions/zora.d.ts.map +1 -1
- package/dist/types/chains/types.d.ts +1 -0
- package/dist/types/chains/types.d.ts.map +1 -1
- package/dist/types/chains/utils.d.ts +1 -0
- package/dist/types/chains/utils.d.ts.map +1 -1
- package/dist/types/exports/react.d.ts +1 -0
- package/dist/types/exports/react.d.ts.map +1 -1
- package/dist/types/exports/wallets/smart.d.ts +1 -0
- package/dist/types/exports/wallets/smart.d.ts.map +1 -1
- package/dist/types/react/core/connectionManager.d.ts +1 -0
- package/dist/types/react/core/connectionManager.d.ts.map +1 -1
- package/dist/types/react/core/hooks/others/useChainQuery.d.ts +24 -10
- package/dist/types/react/core/hooks/others/useChainQuery.d.ts.map +1 -1
- package/dist/types/react/core/hooks/wallets/useActiveWalletChain.d.ts +1 -0
- package/dist/types/react/core/hooks/wallets/useActiveWalletChain.d.ts.map +1 -1
- package/dist/types/react/native/hooks/wallets/useActiveWalletChain.d.ts +1 -0
- package/dist/types/react/native/hooks/wallets/useActiveWalletChain.d.ts.map +1 -1
- package/dist/types/react/native/index.d.ts +1 -0
- package/dist/types/react/native/index.d.ts.map +1 -1
- package/dist/types/react/native/ui/components/ChainIcon.d.ts.map +1 -1
- package/dist/types/react/web/hooks/wallets/useActiveWalletChain.d.ts +1 -0
- package/dist/types/react/web/hooks/wallets/useActiveWalletChain.d.ts.map +1 -1
- package/dist/types/react/web/index.d.ts +1 -0
- package/dist/types/react/web/index.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/Details.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/NetworkSelector.d.ts +142 -0
- package/dist/types/react/web/ui/ConnectWallet/NetworkSelector.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatSteps.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatTxDetailsTable.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.d.ts +4 -0
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/main/useUISelectionStates.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/useSwapSupportedChains.d.ts +1 -0
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/useSwapSupportedChains.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/tx-history/SwapDetailsScreen.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/tx-history/TokenInfoRow.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/TokenSelector.d.ts.map +1 -1
- package/dist/types/react/web/ui/components/ChainIcon.d.ts +1 -2
- package/dist/types/react/web/ui/components/ChainIcon.d.ts.map +1 -1
- package/dist/types/react/web/ui/components/ChainName.d.ts.map +1 -1
- package/dist/types/react/web/wallets/ecosystem/EcosystemWalletFormUI.d.ts.map +1 -1
- package/dist/types/utils/extensions/drops/get-claim-params.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/wallets/in-app/web/ecosystem.d.ts +3 -14
- package/dist/types/wallets/in-app/web/ecosystem.d.ts.map +1 -1
- package/dist/types/wallets/manager/index.d.ts +1 -0
- package/dist/types/wallets/manager/index.d.ts.map +1 -1
- package/dist/types/wallets/smart/index.d.ts.map +1 -1
- package/dist/types/wallets/smart/lib/bundler.d.ts +1 -2
- package/dist/types/wallets/smart/lib/bundler.d.ts.map +1 -1
- package/dist/types/wallets/smart/lib/userop.d.ts +53 -8
- package/dist/types/wallets/smart/lib/userop.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/chains/types.ts +1 -1
- package/src/chains/utils.ts +9 -7
- package/src/exports/react.ts +5 -0
- package/src/exports/wallets/smart.ts +2 -0
- package/src/extensions/erc1155/drop1155.test.ts +7 -0
- package/src/extensions/erc20/drop20.test.ts +55 -0
- package/src/extensions/erc721/drop721.test.ts +28 -0
- package/src/react/core/hooks/others/useChainQuery.ts +116 -35
- package/src/react/native/ui/components/ChainIcon.tsx +3 -4
- package/src/react/native/ui/connect/ConnectedModal.tsx +4 -4
- package/src/react/native/ui/connect/SendScreen.tsx +3 -3
- package/src/react/web/ui/ConnectWallet/Details.tsx +13 -12
- package/src/react/web/ui/ConnectWallet/NetworkSelector.tsx +421 -323
- package/src/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.tsx +4 -10
- package/src/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatSteps.tsx +17 -15
- package/src/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatTxDetailsTable.tsx +6 -4
- package/src/react/web/ui/ConnectWallet/screens/Buy/swap/BuyTokenInput.tsx +4 -4
- package/src/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.tsx +4 -4
- package/src/react/web/ui/ConnectWallet/screens/Buy/swap/PayWithCrypto.tsx +4 -4
- package/src/react/web/ui/ConnectWallet/screens/Buy/tx-history/BuyTxHistory.tsx +3 -3
- package/src/react/web/ui/ConnectWallet/screens/Buy/tx-history/SwapDetailsScreen.tsx +14 -9
- package/src/react/web/ui/ConnectWallet/screens/Buy/tx-history/TokenInfoRow.tsx +3 -4
- package/src/react/web/ui/ConnectWallet/screens/TokenSelector.tsx +10 -6
- package/src/react/web/ui/components/ChainIcon.tsx +2 -3
- package/src/react/web/ui/components/ChainName.tsx +4 -6
- package/src/react/web/ui/components/TokenIcon.tsx +4 -4
- package/src/react/web/ui/components/token/TokenSymbol.tsx +4 -4
- package/src/react/web/wallets/ecosystem/EcosystemWalletFormUI.tsx +6 -10
- package/src/utils/extensions/drops/get-claim-params.ts +4 -2
- package/src/version.ts +1 -1
- package/src/wallets/in-app/web/ecosystem.ts +3 -14
- package/src/wallets/smart/index.ts +7 -24
- package/src/wallets/smart/lib/bundler.ts +6 -5
- package/src/wallets/smart/lib/userop.ts +81 -11
@@ -2,13 +2,24 @@
|
|
2
2
|
import styled from "@emotion/styled";
|
3
3
|
import { CrossCircledIcon, MagnifyingGlassIcon } from "@radix-ui/react-icons";
|
4
4
|
import Fuse from "fuse.js";
|
5
|
-
import {
|
5
|
+
import {
|
6
|
+
Fragment,
|
7
|
+
memo,
|
8
|
+
useCallback,
|
9
|
+
useContext,
|
10
|
+
useEffect,
|
11
|
+
useMemo,
|
12
|
+
useState,
|
13
|
+
} from "react";
|
6
14
|
import type React from "react";
|
7
|
-
import type { Chain
|
8
|
-
import { convertApiChainToChain } from "../../../../chains/utils.js";
|
15
|
+
import type { Chain } from "../../../../chains/types.js";
|
9
16
|
import type { ThirdwebClient } from "../../../../client/client.js";
|
10
|
-
import { useCustomTheme } from "../../../core/design-system/CustomThemeProvider.js";
|
11
17
|
import {
|
18
|
+
CustomThemeProvider,
|
19
|
+
useCustomTheme,
|
20
|
+
} from "../../../core/design-system/CustomThemeProvider.js";
|
21
|
+
import {
|
22
|
+
type Theme,
|
12
23
|
fontSize,
|
13
24
|
iconSize,
|
14
25
|
media,
|
@@ -16,12 +27,14 @@ import {
|
|
16
27
|
spacing,
|
17
28
|
} from "../../../core/design-system/index.js";
|
18
29
|
import {
|
19
|
-
|
20
|
-
|
30
|
+
useChainIconUrl,
|
31
|
+
useChainName,
|
21
32
|
} from "../../../core/hooks/others/useChainQuery.js";
|
33
|
+
import { SetRootElementContext } from "../../../core/providers/RootElementContext.js";
|
22
34
|
import { useActiveWalletChain } from "../../hooks/wallets/useActiveWalletChain.js";
|
23
35
|
import { useSwitchActiveWalletChain } from "../../hooks/wallets/useSwitchActiveWalletChain.js";
|
24
36
|
import { ChainIcon } from "../components/ChainIcon.js";
|
37
|
+
import { Modal } from "../components/Modal.js";
|
25
38
|
import { Skeleton } from "../components/Skeleton.js";
|
26
39
|
import { Spacer } from "../components/Spacer.js";
|
27
40
|
import { Spinner } from "../components/Spinner.js";
|
@@ -33,10 +46,10 @@ import { Text } from "../components/text.js";
|
|
33
46
|
import { StyledButton, StyledP, StyledUl } from "../design-system/elements.js";
|
34
47
|
import { useDebouncedValue } from "../hooks/useDebouncedValue.js";
|
35
48
|
import { useShowMore } from "../hooks/useShowMore.js";
|
49
|
+
import type { LocaleId } from "../types.js";
|
50
|
+
import { getConnectLocale } from "./locale/getConnectLocale.js";
|
36
51
|
import type { ConnectLocale } from "./locale/types.js";
|
37
52
|
|
38
|
-
// Note: Must not use useConnectUI here, because this component is also used outside of Connect UI context
|
39
|
-
|
40
53
|
type NetworkSelectorChainProps = {
|
41
54
|
/**
|
42
55
|
* `Chain` object to be displayed
|
@@ -60,20 +73,47 @@ type NetworkSelectorChainProps = {
|
|
60
73
|
close?: () => void;
|
61
74
|
};
|
62
75
|
|
76
|
+
type ChainSection = {
|
77
|
+
label: string;
|
78
|
+
chains: Chain[];
|
79
|
+
};
|
80
|
+
|
63
81
|
/**
|
64
82
|
* @connectWallet
|
65
83
|
*/
|
66
84
|
export type NetworkSelectorProps = {
|
67
85
|
/**
|
68
86
|
* Chains to be displayed as "Popular"
|
87
|
+
* @deprecated Use `sections` prop instead
|
88
|
+
*
|
89
|
+
* If `sections` prop is provided, this prop will be ignored
|
69
90
|
*/
|
70
91
|
popularChainIds?: number[];
|
71
92
|
|
72
93
|
/**
|
73
94
|
* Chains to be displayed as "Recent"
|
95
|
+
* @deprecated Use `sections` prop instead
|
96
|
+
*
|
97
|
+
* If `sections` prop is provided, this prop will be ignored
|
74
98
|
*/
|
75
99
|
recentChainIds?: number[];
|
76
100
|
|
101
|
+
/**
|
102
|
+
* Specify sections of chains to be displayed in the Network Selector Modal
|
103
|
+
*
|
104
|
+
* @example
|
105
|
+
* To display "Polygon", "Avalanche" chains under "Recently used" section and "Ethereum", "Arbitrum" chains under "Popular" section, you can set the prop with the following value
|
106
|
+
* ```ts
|
107
|
+
* import { arbitrum, base, ethereum, polygon } from "thirdweb/chains";
|
108
|
+
*
|
109
|
+
* const sections = [
|
110
|
+
* { label: 'Recently used', chains: [arbitrum, polygon] },
|
111
|
+
* { label: 'Popular', chains: [base, ethereum] },
|
112
|
+
* ]
|
113
|
+
* ```
|
114
|
+
*/
|
115
|
+
sections?: Array<ChainSection>;
|
116
|
+
|
77
117
|
/**
|
78
118
|
* Override how the chain button is rendered in the Modal
|
79
119
|
*/
|
@@ -93,121 +133,6 @@ export type NetworkSelectorProps = {
|
|
93
133
|
onCustomClick?: () => void;
|
94
134
|
};
|
95
135
|
|
96
|
-
let fuseInstances:
|
97
|
-
| {
|
98
|
-
all: Fuse<ChainMetadata>;
|
99
|
-
popular: Fuse<ChainMetadata>;
|
100
|
-
recent: Fuse<ChainMetadata>;
|
101
|
-
}
|
102
|
-
| undefined = undefined;
|
103
|
-
|
104
|
-
let fuseInitializationStarted = false;
|
105
|
-
|
106
|
-
// initialize fuse instances if not already initialized
|
107
|
-
function initializeFuseInstances() {
|
108
|
-
if (fuseInitializationStarted) {
|
109
|
-
return;
|
110
|
-
}
|
111
|
-
|
112
|
-
fuseInitializationStarted = true;
|
113
|
-
|
114
|
-
const fuseConfig = {
|
115
|
-
threshold: 0.4,
|
116
|
-
keys: [
|
117
|
-
{
|
118
|
-
name: "name",
|
119
|
-
weight: 1,
|
120
|
-
},
|
121
|
-
{
|
122
|
-
name: "chainId",
|
123
|
-
weight: 1,
|
124
|
-
},
|
125
|
-
],
|
126
|
-
};
|
127
|
-
|
128
|
-
fuseInstances = {
|
129
|
-
all: new Fuse([], fuseConfig),
|
130
|
-
popular: new Fuse([], fuseConfig),
|
131
|
-
recent: new Fuse([], fuseConfig),
|
132
|
-
};
|
133
|
-
}
|
134
|
-
|
135
|
-
type ChainData = {
|
136
|
-
allChains: ChainMetadata[];
|
137
|
-
popularChains: ChainMetadata[];
|
138
|
-
recentChains: ChainMetadata[];
|
139
|
-
isLoading: boolean;
|
140
|
-
};
|
141
|
-
|
142
|
-
function useLoadChains(
|
143
|
-
allChainsInput: Chain[],
|
144
|
-
popularChainIds: number[],
|
145
|
-
recentChainIds: number[],
|
146
|
-
): ChainData {
|
147
|
-
// load all chains with react query
|
148
|
-
const chainsQueries = useChainsQuery(allChainsInput, 50);
|
149
|
-
|
150
|
-
const isLoading = chainsQueries.some((q) => q.isLoading);
|
151
|
-
|
152
|
-
const { allChains, chainsMap } = useMemo(() => {
|
153
|
-
const _chains: ChainMetadata[] = [];
|
154
|
-
const _chainsMap = new Map<number, ChainMetadata>();
|
155
|
-
|
156
|
-
if (isLoading) {
|
157
|
-
return { allChains: [], chainsMap: _chainsMap };
|
158
|
-
}
|
159
|
-
|
160
|
-
for (const chainQuery of chainsQueries) {
|
161
|
-
if (chainQuery.data) {
|
162
|
-
_chains.push({
|
163
|
-
...chainQuery.data,
|
164
|
-
} as ChainMetadata);
|
165
|
-
}
|
166
|
-
}
|
167
|
-
|
168
|
-
for (const chain of _chains) {
|
169
|
-
_chainsMap.set(chain.chainId, chain);
|
170
|
-
}
|
171
|
-
|
172
|
-
return { allChains: _chains, chainsMap: _chainsMap, isLoading: false };
|
173
|
-
}, [chainsQueries, isLoading]);
|
174
|
-
|
175
|
-
const recentChains = useMemo(() => {
|
176
|
-
if (!recentChainIds) {
|
177
|
-
return [];
|
178
|
-
}
|
179
|
-
const _recentChains: ChainMetadata[] = [];
|
180
|
-
for (const chainId of recentChainIds) {
|
181
|
-
const _chain = chainsMap.get(chainId);
|
182
|
-
if (_chain) {
|
183
|
-
_recentChains.push(_chain);
|
184
|
-
}
|
185
|
-
}
|
186
|
-
return _recentChains;
|
187
|
-
}, [recentChainIds, chainsMap]);
|
188
|
-
|
189
|
-
const popularChains = useMemo(() => {
|
190
|
-
if (!popularChainIds) {
|
191
|
-
return [];
|
192
|
-
}
|
193
|
-
const _popularChains: ChainMetadata[] = [];
|
194
|
-
for (const chainId of popularChainIds) {
|
195
|
-
const _chain = chainsMap.get(chainId);
|
196
|
-
if (_chain) {
|
197
|
-
_popularChains.push(_chain);
|
198
|
-
}
|
199
|
-
}
|
200
|
-
return _popularChains;
|
201
|
-
}, [popularChainIds, chainsMap]);
|
202
|
-
|
203
|
-
return {
|
204
|
-
allChains,
|
205
|
-
popularChains,
|
206
|
-
recentChains,
|
207
|
-
isLoading,
|
208
|
-
};
|
209
|
-
}
|
210
|
-
|
211
136
|
type NetworkSelectorContentProps = {
|
212
137
|
onBack?: () => void;
|
213
138
|
closeModal: () => void;
|
@@ -221,36 +146,9 @@ type NetworkSelectorContentProps = {
|
|
221
146
|
/**
|
222
147
|
* @internal
|
223
148
|
*/
|
224
|
-
export function NetworkSelectorContent(props: NetworkSelectorContentProps) {
|
225
|
-
const chainsData = useLoadChains(
|
226
|
-
props.chains,
|
227
|
-
props.networkSelector?.popularChainIds || [],
|
228
|
-
props.networkSelector?.recentChainIds || [],
|
229
|
-
);
|
230
149
|
|
231
|
-
|
232
|
-
|
233
|
-
return <NetworkSelectorContentInner {...props} chainsData={chainsData} />;
|
234
|
-
}
|
235
|
-
|
236
|
-
function NetworkSelectorContentInner(
|
237
|
-
props: NetworkSelectorContentProps & {
|
238
|
-
chainsData: ChainData;
|
239
|
-
connectLocale: ConnectLocale;
|
240
|
-
client: ThirdwebClient;
|
241
|
-
},
|
242
|
-
) {
|
243
|
-
const { chainsData, connectLocale } = props;
|
244
|
-
|
245
|
-
const chainMap = useMemo(() => {
|
246
|
-
const _chainMap = new Map<number, Chain>();
|
247
|
-
for (const chain of props.chains) {
|
248
|
-
_chainMap.set(chain.id, chain);
|
249
|
-
}
|
250
|
-
return _chainMap;
|
251
|
-
}, [props.chains]);
|
252
|
-
|
253
|
-
const locale = connectLocale.networkSelector;
|
150
|
+
export function NetworkSelectorContent(props: NetworkSelectorContentProps) {
|
151
|
+
const locale = props.connectLocale.networkSelector;
|
254
152
|
const [searchTerm, setSearchTerm] = useState("");
|
255
153
|
const [selectedTab, setSelectedTab] = useState<"all" | "mainnet" | "testnet">(
|
256
154
|
"all",
|
@@ -259,57 +157,182 @@ function NetworkSelectorContentInner(
|
|
259
157
|
|
260
158
|
const { onSwitch, onCustomClick } = props.networkSelector || {};
|
261
159
|
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
const popularChainsTab = useMemo(() => {
|
267
|
-
return filterChainByType(chainsData.popularChains, selectedTab);
|
268
|
-
}, [chainsData.popularChains, selectedTab]);
|
160
|
+
// labels
|
161
|
+
const othersLabel = locale.categoryLabel.others;
|
162
|
+
const popularLabel = locale.categoryLabel.popular;
|
163
|
+
const recentLabel = locale.categoryLabel.recentlyUsed;
|
269
164
|
|
270
|
-
|
271
|
-
|
272
|
-
|
165
|
+
// create sections, chainToSectionMap and allChains
|
166
|
+
const { chainSections, allChains, allChainsToSectionMap } = useMemo(() => {
|
167
|
+
const chainSectionsValue: ChainSection[] = [];
|
168
|
+
const allChainsValue: Chain[] = [];
|
169
|
+
const allChainsToSectionMapValue: Map<number, string> = new Map();
|
273
170
|
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
return allChainsTab;
|
171
|
+
function addChain(c: Chain, section: string) {
|
172
|
+
allChainsToSectionMapValue.set(c.id, section);
|
173
|
+
allChainsValue.push(c);
|
278
174
|
}
|
279
175
|
|
280
|
-
if
|
281
|
-
|
176
|
+
// if new API is used
|
177
|
+
if (props.networkSelector?.sections) {
|
178
|
+
for (const s of props.networkSelector.sections) {
|
179
|
+
const chainsToAdd = s.chains.filter(
|
180
|
+
(c) => !allChainsToSectionMapValue.has(c.id),
|
181
|
+
);
|
182
|
+
if (chainsToAdd.length > 0) {
|
183
|
+
chainSectionsValue.push({
|
184
|
+
label: s.label,
|
185
|
+
chains: chainsToAdd,
|
186
|
+
});
|
187
|
+
for (const c of chainsToAdd) {
|
188
|
+
addChain(c, s.label);
|
189
|
+
}
|
190
|
+
}
|
191
|
+
}
|
282
192
|
}
|
283
193
|
|
284
|
-
|
285
|
-
|
286
|
-
|
194
|
+
// if old API is used
|
195
|
+
else {
|
196
|
+
const allChainsMap = new Map(props.chains.map((c) => [c.id, c]));
|
197
|
+
// add all recent chains
|
198
|
+
if (
|
199
|
+
props.networkSelector?.recentChainIds &&
|
200
|
+
props.networkSelector?.recentChainIds.length > 0
|
201
|
+
) {
|
202
|
+
const recentChains = props.networkSelector.recentChainIds
|
203
|
+
.map((id) => allChainsMap.get(id))
|
204
|
+
.filter((c) => c !== undefined);
|
205
|
+
|
206
|
+
chainSectionsValue.push({
|
207
|
+
label: recentLabel,
|
208
|
+
chains: recentChains,
|
209
|
+
});
|
210
|
+
for (const c of recentChains) {
|
211
|
+
addChain(c, recentLabel);
|
212
|
+
}
|
213
|
+
}
|
287
214
|
|
288
|
-
|
289
|
-
|
290
|
-
|
215
|
+
// then add all popular chains ( exclude already added chains )
|
216
|
+
if (
|
217
|
+
props.networkSelector?.popularChainIds &&
|
218
|
+
props.networkSelector.popularChainIds.length > 0
|
219
|
+
) {
|
220
|
+
const popularChains = props.networkSelector.popularChainIds
|
221
|
+
.map((id) => allChainsMap.get(id))
|
222
|
+
.filter((c) => c !== undefined);
|
223
|
+
|
224
|
+
const chainsToAdd = popularChains.filter(
|
225
|
+
(c) => !allChainsToSectionMapValue.has(c.id),
|
226
|
+
);
|
227
|
+
if (chainsToAdd.length > 0) {
|
228
|
+
chainSectionsValue.push({
|
229
|
+
label: popularLabel,
|
230
|
+
chains: chainsToAdd,
|
231
|
+
});
|
232
|
+
for (const c of chainsToAdd) {
|
233
|
+
addChain(c, popularLabel);
|
234
|
+
}
|
235
|
+
}
|
236
|
+
}
|
291
237
|
}
|
292
238
|
|
293
|
-
|
294
|
-
|
239
|
+
// add all other chains ( exclude already added chains )
|
240
|
+
const otherChainsToAdd = props.chains.filter(
|
241
|
+
(c) => !allChainsToSectionMapValue.has(c.id),
|
242
|
+
);
|
243
|
+
if (otherChainsToAdd.length > 0) {
|
244
|
+
chainSectionsValue.push({
|
245
|
+
label: othersLabel,
|
246
|
+
chains: otherChainsToAdd,
|
247
|
+
});
|
248
|
+
for (const c of otherChainsToAdd) {
|
249
|
+
addChain(c, othersLabel);
|
250
|
+
}
|
295
251
|
}
|
296
252
|
|
297
|
-
|
298
|
-
|
299
|
-
|
253
|
+
return {
|
254
|
+
chainSections: chainSectionsValue,
|
255
|
+
allChains: allChainsValue,
|
256
|
+
allChainsToSectionMap: allChainsToSectionMapValue,
|
257
|
+
};
|
258
|
+
}, [
|
259
|
+
props.networkSelector?.sections,
|
260
|
+
props.networkSelector?.recentChainIds,
|
261
|
+
props.networkSelector?.popularChainIds,
|
262
|
+
props.chains,
|
263
|
+
recentLabel,
|
264
|
+
popularLabel,
|
265
|
+
othersLabel,
|
266
|
+
]);
|
300
267
|
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
268
|
+
// fuse instance for searching
|
269
|
+
const fuse = useMemo(() => {
|
270
|
+
return new Fuse(allChains, {
|
271
|
+
threshold: 0.4,
|
272
|
+
keys: [
|
273
|
+
{
|
274
|
+
name: "name",
|
275
|
+
weight: 1,
|
276
|
+
},
|
277
|
+
{
|
278
|
+
name: "chainId",
|
279
|
+
weight: 1,
|
280
|
+
},
|
281
|
+
],
|
282
|
+
});
|
283
|
+
}, [allChains]);
|
284
|
+
|
285
|
+
// chains filtered by search term
|
286
|
+
const searchedChainSections =
|
287
|
+
useMemo(() => {
|
288
|
+
if (deferredSearchTerm === "") {
|
289
|
+
return undefined;
|
290
|
+
}
|
291
|
+
|
292
|
+
const filteredChainSectionsValue: ChainSection[] = [];
|
293
|
+
|
294
|
+
const filteredAllChains = fuse
|
295
|
+
.search(deferredSearchTerm)
|
296
|
+
.map((r) => r.item);
|
297
|
+
|
298
|
+
for (const c of filteredAllChains) {
|
299
|
+
const label = allChainsToSectionMap.get(c.id);
|
300
|
+
if (!label) {
|
301
|
+
return; // just a type guard, this never happens
|
302
|
+
}
|
303
|
+
|
304
|
+
const section = filteredChainSectionsValue.find(
|
305
|
+
(s) => s.label === label,
|
306
|
+
);
|
307
|
+
if (section) {
|
308
|
+
section.chains.push(c);
|
309
|
+
} else {
|
310
|
+
filteredChainSectionsValue.push({
|
311
|
+
label,
|
312
|
+
chains: [c],
|
313
|
+
});
|
314
|
+
}
|
315
|
+
|
316
|
+
return filteredChainSectionsValue;
|
317
|
+
}
|
305
318
|
|
306
|
-
|
307
|
-
|
319
|
+
return filteredChainSectionsValue;
|
320
|
+
}, [deferredSearchTerm, fuse, allChainsToSectionMap]) || chainSections;
|
321
|
+
|
322
|
+
const filteredChainSections = useMemo(() => {
|
323
|
+
if (selectedTab === "all") {
|
324
|
+
return searchedChainSections;
|
308
325
|
}
|
309
326
|
|
310
|
-
|
311
|
-
|
312
|
-
|
327
|
+
return searchedChainSections.map((section) => ({
|
328
|
+
label: section.label,
|
329
|
+
chains: section.chains.filter(
|
330
|
+
(c) =>
|
331
|
+
(selectedTab === "mainnet" && !c.testnet) ||
|
332
|
+
(selectedTab === "testnet" && c.testnet),
|
333
|
+
),
|
334
|
+
}));
|
335
|
+
}, [searchedChainSections, selectedTab]);
|
313
336
|
|
314
337
|
const handleSwitch = useCallback(
|
315
338
|
(chain: Chain) => {
|
@@ -321,45 +344,6 @@ function NetworkSelectorContentInner(
|
|
321
344
|
[onSwitch, props],
|
322
345
|
);
|
323
346
|
|
324
|
-
const allChainsToShow = useMemo(() => {
|
325
|
-
if (chainsData.isLoading) {
|
326
|
-
return props.chains;
|
327
|
-
}
|
328
|
-
return allChainsFiltered.map(convertApiChainToChain);
|
329
|
-
}, [allChainsFiltered, chainsData.isLoading, props.chains]);
|
330
|
-
|
331
|
-
const popularChainsToShow = useMemo(() => {
|
332
|
-
if (chainsData.isLoading) {
|
333
|
-
return (
|
334
|
-
props.networkSelector?.popularChainIds?.map(
|
335
|
-
(id) => chainMap.get(id) as Chain,
|
336
|
-
) || []
|
337
|
-
);
|
338
|
-
}
|
339
|
-
return popularChainsFiltered.map(convertApiChainToChain);
|
340
|
-
}, [
|
341
|
-
chainMap,
|
342
|
-
chainsData.isLoading,
|
343
|
-
popularChainsFiltered,
|
344
|
-
props.networkSelector?.popularChainIds,
|
345
|
-
]);
|
346
|
-
|
347
|
-
const recentChainsToShow = useMemo(() => {
|
348
|
-
if (chainsData.isLoading) {
|
349
|
-
return (
|
350
|
-
props.networkSelector?.recentChainIds?.map(
|
351
|
-
(id) => chainMap.get(id) as Chain,
|
352
|
-
) || []
|
353
|
-
);
|
354
|
-
}
|
355
|
-
return recentChainsFiltered.map(convertApiChainToChain);
|
356
|
-
}, [
|
357
|
-
chainMap,
|
358
|
-
chainsData.isLoading,
|
359
|
-
props.networkSelector?.recentChainIds,
|
360
|
-
recentChainsFiltered,
|
361
|
-
]);
|
362
|
-
|
363
347
|
return (
|
364
348
|
<Container>
|
365
349
|
<Container p="lg">
|
@@ -418,19 +402,14 @@ function NetworkSelectorContentInner(
|
|
418
402
|
}}
|
419
403
|
tabIndex={-1}
|
420
404
|
variant="outline"
|
421
|
-
|
422
|
-
placeholder={
|
423
|
-
chainsData.isLoading
|
424
|
-
? "Loading chains..."
|
425
|
-
: locale.inputPlaceholder
|
426
|
-
}
|
405
|
+
placeholder={locale.inputPlaceholder}
|
427
406
|
value={searchTerm}
|
428
407
|
onChange={(e) => {
|
429
408
|
setSearchTerm(e.target.value);
|
430
409
|
}}
|
431
410
|
/>
|
432
411
|
{/* Searching Spinner */}
|
433
|
-
{
|
412
|
+
{deferredSearchTerm !== searchTerm && (
|
434
413
|
<div
|
435
414
|
style={{
|
436
415
|
position: "absolute",
|
@@ -445,12 +424,10 @@ function NetworkSelectorContentInner(
|
|
445
424
|
<Spacer y="lg" />
|
446
425
|
<Container px="md">
|
447
426
|
<NetworkTabContent
|
448
|
-
|
449
|
-
popularChainIds={popularChainsToShow}
|
450
|
-
recentChainIds={recentChainsToShow}
|
427
|
+
chainSections={filteredChainSections}
|
451
428
|
onSwitch={handleSwitch}
|
452
429
|
renderChain={props.networkSelector?.renderChain}
|
453
|
-
connectLocale={connectLocale}
|
430
|
+
connectLocale={props.connectLocale}
|
454
431
|
client={props.client}
|
455
432
|
close={props.closeModal}
|
456
433
|
/>
|
@@ -480,47 +457,23 @@ function NetworkSelectorContentInner(
|
|
480
457
|
);
|
481
458
|
}
|
482
459
|
|
483
|
-
/**
|
484
|
-
*
|
485
|
-
* @internal
|
486
|
-
*/
|
487
|
-
const filterChainByType = (
|
488
|
-
chains: ChainMetadata[],
|
489
|
-
type: "testnet" | "mainnet" | "all",
|
490
|
-
) => {
|
491
|
-
if (type === "all") {
|
492
|
-
return chains;
|
493
|
-
}
|
494
|
-
|
495
|
-
if (type === "testnet") {
|
496
|
-
return chains.filter((c) => c.testnet);
|
497
|
-
}
|
498
|
-
|
499
|
-
return chains.filter((c) => !c.testnet);
|
500
|
-
};
|
501
|
-
|
502
460
|
/**
|
503
461
|
*
|
504
462
|
* @internal
|
505
463
|
*/
|
506
464
|
const NetworkTabContent = (props: {
|
507
|
-
|
508
|
-
recentChainIds?: Chain[];
|
509
|
-
popularChainIds?: Chain[];
|
465
|
+
chainSections: Array<ChainSection>;
|
510
466
|
onSwitch: (chain: Chain) => void;
|
511
467
|
renderChain?: React.FC<NetworkSelectorChainProps>;
|
512
468
|
close?: () => void;
|
513
469
|
connectLocale: ConnectLocale;
|
514
470
|
client: ThirdwebClient;
|
515
471
|
}) => {
|
516
|
-
const
|
517
|
-
|
518
|
-
const { recentChainIds, popularChainIds, allChainIds } = props;
|
472
|
+
const { chainSections } = props;
|
519
473
|
|
520
|
-
const noChainsToShow =
|
521
|
-
|
522
|
-
|
523
|
-
allChainIds.length === 0;
|
474
|
+
const noChainsToShow = chainSections.every(
|
475
|
+
(section) => section.chains.length === 0,
|
476
|
+
);
|
524
477
|
|
525
478
|
return (
|
526
479
|
<Container
|
@@ -531,62 +484,34 @@ const NetworkTabContent = (props: {
|
|
531
484
|
paddingBottom: spacing.lg,
|
532
485
|
}}
|
533
486
|
>
|
534
|
-
{
|
535
|
-
|
536
|
-
<SectionLabel>{locale.recentlyUsed}</SectionLabel>
|
537
|
-
<Spacer y="sm" />
|
538
|
-
<NetworkList
|
539
|
-
chains={recentChainIds}
|
540
|
-
onSwitch={props.onSwitch}
|
541
|
-
renderChain={props.renderChain}
|
542
|
-
close={props.close}
|
543
|
-
client={props.client}
|
544
|
-
connectLocale={props.connectLocale}
|
545
|
-
/>
|
546
|
-
<Spacer y="lg" />
|
547
|
-
</div>
|
548
|
-
)}
|
549
|
-
|
550
|
-
{popularChainIds && popularChainIds.length > 0 && (
|
551
|
-
<div>
|
552
|
-
<SectionLabel>{locale.popular}</SectionLabel>
|
553
|
-
<Spacer y="sm" />
|
554
|
-
<NetworkList
|
555
|
-
chains={popularChainIds}
|
556
|
-
onSwitch={props.onSwitch}
|
557
|
-
renderChain={props.renderChain}
|
558
|
-
close={props.close}
|
559
|
-
client={props.client}
|
560
|
-
connectLocale={props.connectLocale}
|
561
|
-
/>
|
562
|
-
<Spacer y="lg" />
|
563
|
-
</div>
|
564
|
-
)}
|
565
|
-
|
566
|
-
{/* separator */}
|
567
|
-
{((popularChainIds && popularChainIds.length > 0) ||
|
568
|
-
(recentChainIds && recentChainIds.length > 0)) && (
|
569
|
-
<>
|
570
|
-
<SectionLabel>{locale.others}</SectionLabel>
|
571
|
-
<Spacer y="sm" />
|
572
|
-
</>
|
573
|
-
)}
|
574
|
-
|
575
|
-
<NetworkList
|
576
|
-
chains={allChainIds}
|
577
|
-
onSwitch={props.onSwitch}
|
578
|
-
renderChain={props.renderChain}
|
579
|
-
close={props.close}
|
580
|
-
client={props.client}
|
581
|
-
connectLocale={props.connectLocale}
|
582
|
-
/>
|
583
|
-
|
584
|
-
{noChainsToShow && (
|
487
|
+
{/* empty state */}
|
488
|
+
{noChainsToShow ? (
|
585
489
|
<Container flex="column" gap="md" center="both" color="secondaryText">
|
586
490
|
<Spacer y="xl" />
|
587
491
|
<CrossCircledIcon width={iconSize.xl} height={iconSize.xl} />
|
588
492
|
<Text> No Results </Text>
|
589
493
|
</Container>
|
494
|
+
) : (
|
495
|
+
chainSections.map((section, idx) => {
|
496
|
+
if (section.chains.length === 0) {
|
497
|
+
return null;
|
498
|
+
}
|
499
|
+
return (
|
500
|
+
<Fragment key={section.label}>
|
501
|
+
{idx !== 0 && <Spacer y="lg" />}
|
502
|
+
<SectionLabel>{section.label}</SectionLabel>
|
503
|
+
<Spacer y="xs" />
|
504
|
+
<NetworkList
|
505
|
+
chains={section.chains}
|
506
|
+
onSwitch={props.onSwitch}
|
507
|
+
renderChain={props.renderChain}
|
508
|
+
close={props.close}
|
509
|
+
client={props.client}
|
510
|
+
connectLocale={props.connectLocale}
|
511
|
+
/>
|
512
|
+
</Fragment>
|
513
|
+
);
|
514
|
+
})
|
590
515
|
)}
|
591
516
|
</Container>
|
592
517
|
);
|
@@ -691,11 +616,13 @@ export const ChainButton = /* @__PURE__ */ memo(function ChainButton(props: {
|
|
691
616
|
const { chain, confirming, switchingFailed } = props;
|
692
617
|
|
693
618
|
const activeChain = useActiveWalletChain();
|
694
|
-
|
619
|
+
|
620
|
+
const chainNameQuery = useChainName(chain);
|
621
|
+
const chainIconQuery = useChainIconUrl(chain);
|
695
622
|
|
696
623
|
let chainName: React.ReactNode;
|
697
|
-
if (
|
698
|
-
chainName = <span>{
|
624
|
+
if (chainNameQuery.name) {
|
625
|
+
chainName = <span>{chainNameQuery.name} </span>;
|
699
626
|
} else {
|
700
627
|
chainName = <Skeleton width="150px" height="20px" />;
|
701
628
|
}
|
@@ -705,9 +632,9 @@ export const ChainButton = /* @__PURE__ */ memo(function ChainButton(props: {
|
|
705
632
|
data-active={activeChain?.id === chain.id}
|
706
633
|
onClick={props.onClick}
|
707
634
|
>
|
708
|
-
{
|
635
|
+
{!chainIconQuery.isLoading ? (
|
709
636
|
<ChainIcon
|
710
|
-
|
637
|
+
chainIconUrl={chainIconQuery.url}
|
711
638
|
size={iconSize.lg}
|
712
639
|
active={activeChain?.id === chain.id}
|
713
640
|
loading="lazy"
|
@@ -830,3 +757,174 @@ const StyledMagnifyingGlassIcon = /* @__PURE__ */ styled(MagnifyingGlassIcon)(
|
|
830
757
|
};
|
831
758
|
},
|
832
759
|
);
|
760
|
+
|
761
|
+
/**
|
762
|
+
* Options for the `useNetworkSwitcherModal` hook's returned `open` function
|
763
|
+
* @connectWallet
|
764
|
+
*/
|
765
|
+
export type UseNetworkSwitcherModalOptions = {
|
766
|
+
/**
|
767
|
+
* Set the theme for the `NetworkSwitcher` Modal. By default it is set to `"dark"`
|
768
|
+
*
|
769
|
+
* theme can be set to either `"dark"`, `"light"` or a custom theme object.
|
770
|
+
*
|
771
|
+
* You can also import [`lightTheme`](https://portal.thirdweb.com/references/typescript/v5/lightTheme)
|
772
|
+
* or [`darkTheme`](https://portal.thirdweb.com/references/typescript/v5/darkTheme)
|
773
|
+
* functions from `thirdweb/react` to use the default themes as base and overrides parts of it.
|
774
|
+
* @example
|
775
|
+
* ```ts
|
776
|
+
* import { lightTheme } from "thirdweb/react";
|
777
|
+
*
|
778
|
+
* const customTheme = lightTheme({
|
779
|
+
* colors: {
|
780
|
+
* modalBg: 'red'
|
781
|
+
* }
|
782
|
+
* })
|
783
|
+
* ```
|
784
|
+
*/
|
785
|
+
theme?: Theme | "dark" | "light";
|
786
|
+
|
787
|
+
/**
|
788
|
+
* Specify sections of chains to be displayed in the Network Selector Modal
|
789
|
+
*
|
790
|
+
* @example
|
791
|
+
* To display "Polygon", "Avalanche" chains under "Recently used" section and "Ethereum", "Arbitrum" chains under "Popular" section, you can set the prop with the following value
|
792
|
+
* ```ts
|
793
|
+
* import { arbitrum, base, ethereum, polygon } from "thirdweb/chains";
|
794
|
+
*
|
795
|
+
* const sections = [
|
796
|
+
* { label: 'Recently used', chains: [arbitrum, polygon] },
|
797
|
+
* { label: 'Popular', chains: [base, ethereum] },
|
798
|
+
* ]
|
799
|
+
* ```
|
800
|
+
*/
|
801
|
+
sections?: Array<ChainSection>;
|
802
|
+
|
803
|
+
/**
|
804
|
+
* Override how the chain button is rendered in the Modal
|
805
|
+
*/
|
806
|
+
renderChain?: React.FC<NetworkSelectorChainProps>;
|
807
|
+
|
808
|
+
/**
|
809
|
+
* Callback to be called when a chain is successfully switched
|
810
|
+
* @param chain - The `Chain` of the chain that was switched to
|
811
|
+
*/
|
812
|
+
onSwitch?: (chain: Chain) => void;
|
813
|
+
|
814
|
+
/**
|
815
|
+
* Callback to be called when the "Add Custom Network" button is clicked
|
816
|
+
*
|
817
|
+
* The "Add Custom Network" button is displayed at the bottom of the modal - only if this prop is provided
|
818
|
+
*/
|
819
|
+
onCustomClick?: () => void;
|
820
|
+
|
821
|
+
/**
|
822
|
+
* A client is the entry point to the thirdweb SDK.
|
823
|
+
* It is required for all other actions.
|
824
|
+
* You can create a client using the `createThirdwebClient` function. Refer to the [Creating a Client](https://portal.thirdweb.com/typescript/v5/client) documentation for more information.
|
825
|
+
*
|
826
|
+
* You must provide a `clientId` or `secretKey` in order to initialize a client. Pass `clientId` if you want for client-side usage and `secretKey` for server-side usage.
|
827
|
+
*
|
828
|
+
* ```tsx
|
829
|
+
* import { createThirdwebClient } from "thirdweb";
|
830
|
+
*
|
831
|
+
* const client = createThirdwebClient({
|
832
|
+
* clientId: "<your_client_id>",
|
833
|
+
* })
|
834
|
+
* ```
|
835
|
+
*/
|
836
|
+
client: ThirdwebClient;
|
837
|
+
|
838
|
+
/**
|
839
|
+
* By default - NetworkSwitcher UI uses the `en-US` locale for english language users.
|
840
|
+
*
|
841
|
+
* You can customize the language used in the ConnectButton UI by setting the `locale` prop.
|
842
|
+
*
|
843
|
+
* Refer to the [`LocaleId`](https://portal.thirdweb.com/references/typescript/v5/LocaleId) type for supported locales.
|
844
|
+
*/
|
845
|
+
locale?: LocaleId;
|
846
|
+
};
|
847
|
+
|
848
|
+
/**
|
849
|
+
* Hook to open the Wallet Network Switcher Modal that shows allows users to switch to different network.
|
850
|
+
*
|
851
|
+
* @example
|
852
|
+
* ```tsx
|
853
|
+
* import { createThirdwebClient } from "thirdweb";
|
854
|
+
* import { useNetworkSwitcherModal } from "thirdweb/react";
|
855
|
+
* import { base, ethereum, polygon, sepolia, arbitrum } from "thirdweb/chains";
|
856
|
+
*
|
857
|
+
* const client = createThirdwebClient({
|
858
|
+
* clientId: "<your_client_id>",
|
859
|
+
* });
|
860
|
+
*
|
861
|
+
* function Example() {
|
862
|
+
* const networkSwitcher = useNetworkSwitcherModal();
|
863
|
+
*
|
864
|
+
* function handleClick() {
|
865
|
+
* networkSwitcher.open({
|
866
|
+
* client,
|
867
|
+
* theme: 'light'
|
868
|
+
* sections: [
|
869
|
+
* { label: 'Recently used', chains: [arbitrum, polygon] },
|
870
|
+
* { label: 'Popular', chains: [base, ethereum, sepolia] },
|
871
|
+
* ]
|
872
|
+
* });
|
873
|
+
* }
|
874
|
+
*
|
875
|
+
* return <button onClick={handleClick}> Switch Network </button>
|
876
|
+
* }
|
877
|
+
* ```
|
878
|
+
*/
|
879
|
+
export function useNetworkSwitcherModal() {
|
880
|
+
const activeChain = useActiveWalletChain();
|
881
|
+
const setRootEl = useContext(SetRootElementContext);
|
882
|
+
|
883
|
+
const closeModal = useCallback(() => {
|
884
|
+
setRootEl(null);
|
885
|
+
}, [setRootEl]);
|
886
|
+
|
887
|
+
const openNetworkSwitcher = useCallback(
|
888
|
+
async (props: UseNetworkSwitcherModalOptions) => {
|
889
|
+
if (!activeChain) {
|
890
|
+
throw new Error("No active wallet found");
|
891
|
+
}
|
892
|
+
const locale = await getConnectLocale(props.locale || "en_US");
|
893
|
+
setRootEl(
|
894
|
+
<CustomThemeProvider theme={props.theme}>
|
895
|
+
<Modal
|
896
|
+
size={"compact"}
|
897
|
+
open={true}
|
898
|
+
setOpen={(value) => {
|
899
|
+
if (!value) {
|
900
|
+
closeModal();
|
901
|
+
}
|
902
|
+
}}
|
903
|
+
style={{
|
904
|
+
paddingBottom: props.onCustomClick ? spacing.md : "0px",
|
905
|
+
}}
|
906
|
+
>
|
907
|
+
<NetworkSelectorContent
|
908
|
+
client={props.client}
|
909
|
+
closeModal={closeModal}
|
910
|
+
chains={[activeChain]}
|
911
|
+
connectLocale={locale}
|
912
|
+
networkSelector={{
|
913
|
+
onCustomClick: props.onCustomClick,
|
914
|
+
onSwitch: props.onSwitch,
|
915
|
+
renderChain: props.renderChain,
|
916
|
+
sections: props.sections,
|
917
|
+
}}
|
918
|
+
/>
|
919
|
+
</Modal>
|
920
|
+
</CustomThemeProvider>,
|
921
|
+
);
|
922
|
+
},
|
923
|
+
[setRootEl, closeModal, activeChain],
|
924
|
+
);
|
925
|
+
|
926
|
+
return {
|
927
|
+
open: openNetworkSwitcher,
|
928
|
+
close: closeModal,
|
929
|
+
};
|
930
|
+
}
|