[React] Feature: Can hide certain wallets in the wallet switcher (#4582)

Adds the ability to hide certain wallets in the wallet switcher

```tsx
      <ConnectButton
        client={client}
        detailsModal={{
          // We hide the in-app wallet so they can't switch to it
          hiddenWallets: ["inApp"],
        }}
        accountAbstraction={{
          chain: baseSepolia,
          sponsorGas: true,
        }}
      />
```

<!-- start pr-codex -->

---

## PR-Codex overview
The focus of this PR is to add the ability to hide specific wallets in the wallet switcher UI component.

### Detailed summary
- Added `hiddenWallets` prop to `ConnectButton`, `DetailsModal`, `WalletSwitcherConnectionScreen`, `BuyScreen`, and `PayEmbed` components.
- Implemented filtering of connected wallets based on `hiddenWallets` in `WalletManagerScreen` and `WalletSwitcherDrawerContent`.
- Updated types to include `WalletId` for consistency across components.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
This commit is contained in:
gregfromstl
2024-09-13 18:37:29 +00:00
parent 53015711fe
commit 5d3b39587b
10 changed files with 87 additions and 33 deletions
+19
View File
@@ -0,0 +1,19 @@
---
"thirdweb": patch
---
Adds the ability to hide certain wallets in the wallet switcher
```tsx
<ConnectButton
client={client}
detailsModal={{
// We hide the in-app wallet so they can't switch to it
hiddenWallets: ["inApp"],
}}
accountAbstraction={{
chain: baseSepolia,
sponsorGas: true,
}}
/>
```
@@ -18,6 +18,10 @@ export function ConnectSmartAccountPreview() {
return (
<div className="flex flex-col">
<StyledConnectButton
detailsModal={{
// We hide the in-app wallet so they can't switch to it
hiddenWallets: ["inApp"],
}}
accountAbstraction={{
chain: baseSepolia,
sponsorGas: true,
@@ -8,6 +8,7 @@ import type { Prettify } from "../../../../utils/type-utils.js";
import type { Account, Wallet } from "../../../../wallets/interfaces/wallet.js";
import type { SmartWalletOptions } from "../../../../wallets/smart/types.js";
import type { AppMetadata } from "../../../../wallets/types.js";
import type { WalletId } from "../../../../wallets/wallet-types.js";
import type { NetworkSelectorProps } from "../../../web/ui/ConnectWallet/NetworkSelector.js";
import type { WelcomeScreen } from "../../../web/ui/ConnectWallet/screens/types.js";
import type { LocaleId } from "../../../web/ui/types.js";
@@ -312,6 +313,11 @@ export type ConnectButton_detailsModalOptions = {
* By default the "Buy Funds" button is shown.
*/
hideBuyFunds?: boolean;
/**
* All wallet IDs included in this array will be hidden from wallet selection when connected.
*/
hiddenWallets?: WalletId[];
};
/**
@@ -544,6 +544,7 @@ function ConnectButtonInner(
showAllWallets: props.showAllWallets,
walletConnect: props.walletConnect,
wallets: props.wallets,
hiddenWallets: props.detailsModal?.hiddenWallets,
}}
/>
);
@@ -19,6 +19,7 @@ import { formatNumber } from "../../../../utils/formatNumber.js";
import type { Account, Wallet } from "../../../../wallets/interfaces/wallet.js";
import type { SmartWalletOptions } from "../../../../wallets/smart/types.js";
import type { AppMetadata } from "../../../../wallets/types.js";
import type { WalletId } from "../../../../wallets/wallet-types.js";
import {
CustomThemeProvider,
parseTheme,
@@ -744,6 +745,7 @@ function DetailsModal(props: {
chain={props.connectOptions?.chain}
chains={props.connectOptions?.chains}
client={client}
hiddenWallets={props.connectOptions?.hiddenWallets}
connectLocale={locale}
recommendedWallets={props.connectOptions?.recommendedWallets}
showAllWallets={!!props.connectOptions?.showAllWallets}
@@ -924,6 +926,7 @@ function DetailsModal(props: {
mode: "fund_wallet",
}
}
hiddenWallets={props.detailsModal?.hiddenWallets}
theme={typeof props.theme === "string" ? props.theme : props.theme.type}
onDone={closeModal}
connectOptions={undefined}
@@ -1156,6 +1159,7 @@ export type DetailsModalConnectOptions = {
chain?: Chain;
chains?: Chain[];
recommendedWallets?: Wallet[];
hiddenWallets?: WalletId[];
showAllWallets?: boolean;
};
@@ -10,6 +10,7 @@ import type { BuyWithFiatStatus } from "../../../../../../pay/buyWithFiat/getSta
import { isSwapRequiredPostOnramp } from "../../../../../../pay/buyWithFiat/isSwapRequiredPostOnramp.js";
import { formatNumber } from "../../../../../../utils/formatNumber.js";
import type { Account } from "../../../../../../wallets/interfaces/wallet.js";
import type { WalletId } from "../../../../../../wallets/wallet-types.js";
import {
type Theme,
iconSize,
@@ -91,6 +92,7 @@ export type BuyScreenProps = {
theme: "light" | "dark" | Theme;
onDone: () => void;
connectOptions: PayEmbedConnectOptions | undefined;
hiddenWallets?: WalletId[];
isEmbed: boolean;
};
@@ -128,6 +130,7 @@ type BuyScreenContentProps = {
theme: "light" | "dark" | Theme;
payOptions: PayUIOptions;
onDone: () => void;
hiddenWallets?: WalletId[];
connectOptions: PayEmbedConnectOptions | undefined;
isEmbed: boolean;
};
@@ -265,6 +268,7 @@ function BuyScreenContent(props: BuyScreenContentProps) {
});
}
}}
hiddenWallets={props.hiddenWallets}
recommendedWallets={props.connectOptions?.recommendedWallets}
showAllWallets={
props.connectOptions?.showAllWallets === undefined
@@ -541,6 +545,7 @@ function BuyScreenContent(props: BuyScreenContentProps) {
{screen.id === "select-wallet" && (
<WalletSwitcherDrawerContent
client={client}
hiddenWallets={props.hiddenWallets}
onSelect={(w) => {
const chain = w.getChain();
const account = w.getAccount();
@@ -1,6 +1,7 @@
import { PlusIcon } from "@radix-ui/react-icons";
import type { ThirdwebClient } from "../../../../../../../client/client.js";
import type { Wallet } from "../../../../../../../wallets/interfaces/wallet.js";
import type { WalletId } from "../../../../../../../wallets/wallet-types.js";
import { useCustomTheme } from "../../../../../../core/design-system/CustomThemeProvider.js";
import {
iconSize,
@@ -22,6 +23,7 @@ export function WalletSwitcherDrawerContent(props: {
onBack: () => void;
onConnect: () => void;
selectedAddress: string;
hiddenWallets?: WalletId[];
}) {
const theme = useCustomTheme();
const connectedWallets = useConnectedWallets();
@@ -34,23 +36,25 @@ export function WalletSwitcherDrawerContent(props: {
return (
<Container>
<Container flex="column" gap="xs">
{connectedWallets.map((w) => {
const address = w.getAccount()?.address;
return (
<WalletSelectorButton
key={w.id}
walletId={w.id}
client={props.client}
address={address || ""}
onClick={() => {
props.onSelect(w);
props.onBack();
}}
disableChevron
checked={false}
/>
);
})}
{connectedWallets
.filter((w) => !props.hiddenWallets?.includes(w.id))
.map((w) => {
const address = w.getAccount()?.address;
return (
<WalletSelectorButton
key={w.id}
walletId={w.id}
client={props.client}
address={address || ""}
onClick={() => {
props.onSelect(w);
props.onBack();
}}
disableChevron
checked={false}
/>
);
})}
{!hideConnectButton && (
<Button
variant="secondary"
@@ -80,21 +80,23 @@ export function WalletManagerScreen(
}}
>
<Container flex="column" gap="xs">
{connectedWallets.map((w) => {
return (
<WalletManangerButton
key={w.id}
client={props.client}
// address={address || ""}
onClick={() => {
setActive(w);
props.onBack();
}}
chain={props.activeChain}
wallet={w}
/>
);
})}
{connectedWallets
.filter((w) => !props.hiddenWallets?.includes(w.id))
.map((w) => {
return (
<WalletManangerButton
key={w.id}
client={props.client}
// address={address || ""}
onClick={() => {
setActive(w);
props.onBack();
}}
chain={props.activeChain}
wallet={w}
/>
);
})}
</Container>
</Container>
@@ -3,6 +3,7 @@ import type { ThirdwebClient } from "../../../../../client/client.js";
import type { Wallet } from "../../../../../wallets/interfaces/wallet.js";
import type { SmartWalletOptions } from "../../../../../wallets/smart/types.js";
import type { AppMetadata } from "../../../../../wallets/types.js";
import type { WalletId } from "../../../../../wallets/wallet-types.js";
import { useConnectedWallets } from "../../../../core/hooks/wallets/useConnectedWallets.js";
import { getDefaultWallets } from "../../../wallets/defaultWallets.js";
import { ConnectModalContent } from "../Modal/ConnectModalContent.js";
@@ -21,6 +22,7 @@ export type WalletSwitcherConnectionScreenProps = {
onSelect: (wallet: Wallet) => void;
recommendedWallets: Wallet[] | undefined;
showAllWallets: boolean;
hiddenWallets?: WalletId[];
walletConnect:
| {
projectId?: string;
@@ -6,6 +6,7 @@ import type { ThirdwebClient } from "../../../client/client.js";
import type { Wallet } from "../../../wallets/interfaces/wallet.js";
import type { SmartWalletOptions } from "../../../wallets/smart/types.js";
import type { AppMetadata } from "../../../wallets/types.js";
import type { WalletId } from "../../../wallets/wallet-types.js";
import { CustomThemeProvider } from "../../core/design-system/CustomThemeProvider.js";
import type { Theme } from "../../core/design-system/index.js";
import type { SiweAuthOptions } from "../../core/hooks/auth/useSiweAuth.js";
@@ -119,12 +120,17 @@ export type PayEmbedProps = {
theme?: "light" | "dark" | Theme;
/**
* Customize the options for "Connect" Button showin in the PayEmbed UI when the user is not connected to a wallet.
* Customize the options for "Connect" Button showing in the PayEmbed UI when the user is not connected to a wallet.
*
* Refer to the [`PayEmbedConnectOptions`](https://portal.thirdweb.com/references/typescript/v5/PayEmbedConnectOptions) type for more details.
*/
connectOptions?: PayEmbedConnectOptions;
/**
* All wallet IDs included in this array will be hidden from wallet selection when connected.
*/
hiddenWallets?: WalletId[];
style?: React.CSSProperties;
className?: string;
@@ -201,6 +207,7 @@ export function PayEmbed(props: PayEmbedProps) {
theme={theme}
client={props.client}
connectLocale={localeQuery.data}
hiddenWallets={props.hiddenWallets}
payOptions={
props.payOptions || {
mode: "fund_wallet",