Skip to content

Commit

Permalink
chore: add ignoreChainModalOnConnect
Browse files Browse the repository at this point in the history
  • Loading branch information
magiziz committed Jan 22, 2024
1 parent e1e02c1 commit f586d82
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 7 deletions.
24 changes: 24 additions & 0 deletions packages/example/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,8 @@ function RainbowKitApp({
const [coolModeEnabled, setCoolModeEnabled] = useState(false);
const [modalSize, setModalSize] = useState<ModalSize>('wide');
const [showDisclaimer, setShowDisclaimer] = useState(false);
const [ignoreChainModalOnConnect, setIgnoreChainModalOnConnect] =
useState(false);
const [customAvatar, setCustomAvatar] = useState(false);

const routerLocale = router.locale as Locale;
Expand Down Expand Up @@ -287,6 +289,7 @@ function RainbowKitApp({
...demoAppInfo,
...(showDisclaimer && { disclaimer: DisclaimerDemo }),
}}
ignoreChainModalOnConnect={ignoreChainModalOnConnect}
avatar={customAvatar ? CustomAvatar : undefined}
locale={locale}
coolMode={coolModeEnabled}
Expand Down Expand Up @@ -428,6 +431,27 @@ function RainbowKitApp({
/>
</td>
</tr>
<tr>
<td>
<label
htmlFor="ignoreModalChainOnConnect"
style={{ userSelect: 'none' }}
>
ignoreModalChainOnConnect
</label>
</td>
<td>
<input
checked={ignoreChainModalOnConnect}
id="ignoreModalChainOnConnect"
name="ignoreModalChainOnConnect"
onChange={(e) =>
setIgnoreChainModalOnConnect(e.target.checked)
}
type="checkbox"
/>
</td>
</tr>
<tr>
<td>modalSize</td>
<td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { Box } from '../Box/Box';
import { DropdownIcon } from '../Icons/Dropdown';
import { I18nContext } from '../RainbowKitProvider/I18nContext';
import {
useIgnoreChainModalOnConnect,
useInitialChainId,
useRainbowKitChains,
} from '../RainbowKitProvider/RainbowKitChainContext';
Expand Down Expand Up @@ -44,6 +45,7 @@ export function ConnectButton({
}: ConnectButtonProps) {
const chains = useRainbowKitChains();
const connectionStatus = useConnectionStatus();
const ignoreChainModalOnConnect = useIgnoreChainModalOnConnect();
const { setShowBalance } = useShowBalance();
const initialChainId = useInitialChainId();
const { i18n } = useContext(I18nContext);
Expand All @@ -67,7 +69,8 @@ export function ConnectButton({
// chain that they want to switch to. We also hide the chain button if user is using
// our authentication provider and is not yet signed in.
const shouldHideChainButton =
(initialChainId && connectionStatus !== 'connected') ||
((initialChainId || ignoreChainModalOnConnect) &&
connectionStatus !== 'connected') ||
connectionStatus === 'unauthenticated';
const ready = mounted && connectionStatus !== 'loading';
const unsupportedChain = !!chain?.unsupported;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,24 @@ export interface RainbowKitChain extends Chain {
interface RainbowKitChainContextValue {
chains: RainbowKitChain[];
initialChainId?: number;
ignoreChainModalOnConnect: boolean;
}

const RainbowKitChainContext = createContext<RainbowKitChainContextValue>({
chains: [],
ignoreChainModalOnConnect: false,
});

interface RainbowKitChainProviderProps {
initialChain?: Chain | number;
ignoreChainModalOnConnect: boolean;
children: ReactNode;
}

export function RainbowKitChainProvider({
children,
initialChain,
ignoreChainModalOnConnect,
}: RainbowKitChainProviderProps) {
const { chains } = useConfig();

Expand All @@ -35,8 +39,9 @@ export function RainbowKitChainProvider({
chains: provideRainbowKitChains(chains),
initialChainId:
typeof initialChain === 'number' ? initialChain : initialChain?.id,
ignoreChainModalOnConnect,
}),
[chains, initialChain],
[chains, initialChain, ignoreChainModalOnConnect],
)}
>
{children}
Expand All @@ -50,6 +55,9 @@ export const useRainbowKitChains = () =>
export const useInitialChainId = () =>
useContext(RainbowKitChainContext).initialChainId;

export const useIgnoreChainModalOnConnect = () =>
useContext(RainbowKitChainContext).ignoreChainModalOnConnect;

export const useRainbowKitChainsById = () => {
const rainbowkitChains = useRainbowKitChains();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export interface RainbowKitProviderProps {
avatar?: AvatarComponent;
modalSize?: ModalSizes;
locale?: Locale;
ignoreChainModalOnConnect?: boolean;
}

const defaultTheme = lightTheme();
Expand All @@ -80,6 +81,7 @@ export function RainbowKitProvider({
modalSize = ModalSizeOptions.WIDE,
showRecentTransactions = false,
theme = defaultTheme,
ignoreChainModalOnConnect = false,
}: RainbowKitProviderProps) {
usePreloadImages();
useFingerprint();
Expand All @@ -102,7 +104,10 @@ export function RainbowKitProvider({
const avatarContext = avatar ?? defaultAvatar;

return (
<RainbowKitChainProvider initialChain={initialChain}>
<RainbowKitChainProvider
initialChain={initialChain}
ignoreChainModalOnConnect={ignoreChainModalOnConnect}
>
<WalletButtonProvider>
<I18nProvider locale={locale}>
<CoolModeContext.Provider value={coolMode}>
Expand Down
36 changes: 32 additions & 4 deletions packages/rainbowkit/src/wallets/useWalletConnectors.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { Config, Connector, useChainId, useConnect } from 'wagmi';
import { ConnectMutateAsync } from 'wagmi/query';
import { useInitialChainId } from '../components/RainbowKitProvider/RainbowKitChainContext';
import {
useIgnoreChainModalOnConnect,
useInitialChainId,
useRainbowKitChains,
} from '../components/RainbowKitProvider/RainbowKitChainContext';
import { indexBy } from '../utils/indexBy';
import { WagmiConnectorInstance, WalletInstance } from './Wallet';
import {
Expand Down Expand Up @@ -33,8 +37,10 @@ export interface WalletConnector extends WalletInstance {
export function useWalletConnectors(
mergeEIP6963WithRkConnectors = false,
): WalletConnector[] {
const rainbowKitChains = useRainbowKitChains();
const currentChainId = useChainId();
const intialChainId = useInitialChainId();
const ignoreChainModalOnConnect = useIgnoreChainModalOnConnect();
const { connectAsync, connectors: defaultConnectors_untyped } = useConnect();
const defaultCreatedConnectors =
defaultConnectors_untyped as WagmiConnectorInstance[];
Expand All @@ -47,11 +53,33 @@ export function useWalletConnectors(
...(connector.rkDetails || {}),
})) as WalletInstance[];

const computeChainid = async (connector: Connector) => {
// Return inital chain if provided
if (intialChainId) return intialChainId;

// If user chooses to ignore the modal chain before connection
// we will make sure to use one of our rainbowkit chains
if (ignoreChainModalOnConnect) {
const walletChainId = await connector.getChainId();

// Otherwise, if the wallet is already on a supported chain, use that to avoid a chain switch prompt.
return (
rainbowKitChains.find(({ id }) => id === walletChainId)?.id ??
// Finally, fall back to the first chain provided to RainbowKitProvider.
rainbowKitChains[0]?.id
);
}

// Otherwise return the current chain id which wagmi v2 provides
// out of the box without having your wallet connected.
return currentChainId;
};

async function connectWallet(connector: Connector) {
const chainId = await computeChainid(connector);

const result = await connectAsync({
// We'll try to connect to "intialChainId" if specified.
// Otherwise we'll connect with the current chain id
chainId: intialChainId ?? currentChainId,
chainId,
connector,
});

Expand Down

0 comments on commit f586d82

Please sign in to comment.