diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ddf6c74b68..ca2e9c5609 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -36,5 +36,7 @@ jobs:
run: pnpm build
- name: Lint and format
run: pnpm lint
+ - name: Install playwright browser
+ run: pnpm exec playwright install
- name: Run tests
run: pnpm test && pnpm test:cli
diff --git a/package.json b/package.json
index cc9fb53cd3..791db7aa5f 100644
--- a/package.json
+++ b/package.json
@@ -55,6 +55,7 @@
"@types/react-dom": "^18.3.0",
"@vanilla-extract/esbuild-plugin": "^2.3.5",
"@vanilla-extract/vite-plugin": "^4.0.9",
+ "@vitest/browser": "2.0.4",
"autoprefixer": "^10.4.16",
"dotenv": "^16.4.5",
"esbuild": "^0.20.2",
@@ -65,6 +66,7 @@
"lokijs": "^1.5.12",
"next": "^14.2.3",
"next-auth": "4.24.5",
+ "playwright": "1.45.3",
"postcss": "^8.4.32",
"postcss-prefix-selector": "^1.16.0",
"react": "^18.3.0",
diff --git a/packages/rainbowkit/package.json b/packages/rainbowkit/package.json
index ff82838744..43336d62b4 100644
--- a/packages/rainbowkit/package.json
+++ b/packages/rainbowkit/package.json
@@ -62,7 +62,9 @@
"postcss": "^8.4.32",
"react": "^18.3.0",
"vitest": "2.0.4",
- "dotenv": "^16.4.5"
+ "dotenv": "^16.4.5",
+ "@vitest/browser": "2.0.4",
+ "playwright": "1.45.3"
},
"dependencies": {
"@vanilla-extract/css": "1.14.0",
diff --git a/packages/rainbowkit/src/components/ConnectModal/ConnectModal.tsx b/packages/rainbowkit/src/components/ConnectModal/ConnectModal.tsx
index 3a8ed45c69..ec6f1a6781 100644
--- a/packages/rainbowkit/src/components/ConnectModal/ConnectModal.tsx
+++ b/packages/rainbowkit/src/components/ConnectModal/ConnectModal.tsx
@@ -4,6 +4,7 @@ import { useConnectionStatus } from '../../hooks/useConnectionStatus';
import ConnectOptions from '../ConnectOptions/ConnectOptions';
import { Dialog } from '../Dialog/Dialog';
import { DialogContent } from '../Dialog/DialogContent';
+import { useWalletConnectStore } from '../RainbowKitProvider/WalletConnectStoreProvider';
import { SignIn } from '../SignIn/SignIn';
export interface ConnectModalProps {
@@ -15,9 +16,10 @@ export function ConnectModal({ onClose, open }: ConnectModalProps) {
const titleId = 'rk_connect_title';
const connectionStatus = useConnectionStatus();
+ const { resetWalletConnectUri } = useWalletConnectStore();
+
const { disconnect } = useDisconnect();
const { isConnecting } = useAccount();
-
// when a user cancels or dismisses the SignIn modal for SIWE, disconnect and call onClose
const onAuthCancel = React.useCallback(() => {
onClose();
@@ -29,9 +31,9 @@ export function ConnectModal({ onClose, open }: ConnectModalProps) {
// the user closes it, we need to know the wallet isn't connecting anymore.
// So if it's connecting, we disconnect it.
if (isConnecting) disconnect();
-
+ resetWalletConnectUri();
onClose();
- }, [onClose, disconnect, isConnecting]);
+ }, [onClose, disconnect, resetWalletConnectUri, isConnecting]);
if (connectionStatus === 'disconnected') {
return (
diff --git a/packages/rainbowkit/src/components/ConnectOptions/ConnectDetails.tsx b/packages/rainbowkit/src/components/ConnectOptions/ConnectDetails.tsx
index fe9b15524e..cf95e930d1 100644
--- a/packages/rainbowkit/src/components/ConnectOptions/ConnectDetails.tsx
+++ b/packages/rainbowkit/src/components/ConnectOptions/ConnectDetails.tsx
@@ -5,6 +5,7 @@ import { BrowserType, getBrowser, isSafari } from '../../utils/browsers';
import { getGradientRGBAs } from '../../utils/colors';
import { PlatformType, getPlatform } from '../../utils/platforms';
import { InstructionStepName } from '../../wallets/Wallet';
+import { useWalletConnectModal } from '../../wallets/useWalletConnectModal';
import {
WalletConnector,
useWalletConnectors,
@@ -212,12 +213,15 @@ export function ConnectDetail({
name,
qrCode,
ready,
- showWalletConnectModal,
getDesktopUri,
} = wallet;
const isDesktopDeepLinkAvailable = !!getDesktopUri;
const safari = isSafari();
+ const isWalletConnectWallet = wallet.id === 'walletConnect';
+
+ const { openWalletConnectModal } = useWalletConnectModal();
+
const { i18n } = useContext(I18nContext);
const hasExtension = !!wallet.extensionDownloadUrl;
@@ -236,7 +240,7 @@ export function ConnectDetail({
label: string;
onClick?: () => void;
href?: string;
- } | null = showWalletConnectModal
+ } | null = isWalletConnectWallet
? {
description: !compactModeEnabled
? i18n.t('connect.walletconnect.description.full')
@@ -244,7 +248,7 @@ export function ConnectDetail({
label: i18n.t('connect.walletconnect.open.label'),
onClick: () => {
onClose();
- showWalletConnectModal();
+ openWalletConnectModal();
},
}
: hasQrCode
diff --git a/packages/rainbowkit/src/components/ConnectOptions/ConnectOptions.tsx b/packages/rainbowkit/src/components/ConnectOptions/ConnectOptions.tsx
index ca084c1c6e..83136f3fe4 100644
--- a/packages/rainbowkit/src/components/ConnectOptions/ConnectOptions.tsx
+++ b/packages/rainbowkit/src/components/ConnectOptions/ConnectOptions.tsx
@@ -1,4 +1,5 @@
import React, { useContext } from 'react';
+import { useRequestWalletConnectUri } from '../../hooks/useRequestWalletConnectUri';
import { isMobile } from '../../utils/isMobile';
import { WalletButtonContext } from '../RainbowKitProvider/WalletButtonContext';
import { DesktopOptions } from './DesktopOptions';
@@ -7,6 +8,8 @@ import { MobileStatus } from './MobileStatus';
export default function ConnectOptions({ onClose }: { onClose: () => void }) {
const { connector } = useContext(WalletButtonContext);
+ // Prefetch WalletConnect URI
+ useRequestWalletConnectUri();
return isMobile() ? (
connector ? (
diff --git a/packages/rainbowkit/src/components/ConnectOptions/DesktopOptions.tsx b/packages/rainbowkit/src/components/ConnectOptions/DesktopOptions.tsx
index c78b5703aa..75d71b0eeb 100644
--- a/packages/rainbowkit/src/components/ConnectOptions/DesktopOptions.tsx
+++ b/packages/rainbowkit/src/components/ConnectOptions/DesktopOptions.tsx
@@ -30,6 +30,7 @@ import { WalletButtonContext } from '../RainbowKitProvider/WalletButtonContext';
import { Text } from '../Text/Text';
import { addLatestWalletId } from '../../wallets/latestWalletId';
+import { useWalletConnectStore } from '../RainbowKitProvider/WalletConnectStoreProvider';
import {
ConnectDetail,
DownloadDetail,
@@ -75,6 +76,7 @@ export function DesktopOptions({ onClose }: { onClose: () => void }) {
const initialized = useRef(false);
const { connector } = useContext(WalletButtonContext);
+ const { onWalletConnectUri } = useWalletConnectStore();
// The `WalletButton` component made the connect modal appear empty when trying to connect.
// This happened because of a mix up between EIP-6963 and RainbowKit connectors.
@@ -87,6 +89,8 @@ export function DesktopOptions({ onClose }: { onClose: () => void }) {
.filter((wallet) => wallet.ready || !!wallet.extensionDownloadUrl)
.sort((a, b) => a.groupIndex - b.groupIndex);
+ useEffect(() => onWalletConnectUri(setQrCodeUri), [onWalletConnectUri]);
+
const groupedWallets = groupBy(wallets, (wallet) => wallet.groupName);
const supportedI18nGroupNames = [
@@ -111,7 +115,7 @@ export function DesktopOptions({ onClose }: { onClose: () => void }) {
const connectToWallet = (wallet: WalletConnector) => {
setConnectionError(false);
if (wallet.ready) {
- wallet?.connect?.()?.catch(() => {
+ wallet?.connectWallet?.()?.catch(() => {
setConnectionError(true);
});
}
diff --git a/packages/rainbowkit/src/components/ConnectOptions/MobileOptions.tsx b/packages/rainbowkit/src/components/ConnectOptions/MobileOptions.tsx
index 276b3ba651..347fd82669 100644
--- a/packages/rainbowkit/src/components/ConnectOptions/MobileOptions.tsx
+++ b/packages/rainbowkit/src/components/ConnectOptions/MobileOptions.tsx
@@ -7,6 +7,7 @@ import React, {
} from 'react';
import { touchableStyles } from '../../css/touchableStyles';
import { isIOS } from '../../utils/isMobile';
+import { useWalletConnectModal } from '../../wallets/useWalletConnectModal';
import {
WalletConnector,
useWalletConnectors,
@@ -65,8 +66,12 @@ export function WalletButton({
onClose: () => void;
connecting?: boolean;
}) {
+ const isWalletConnectWallet = wallet.id === 'walletConnect';
+
+ const { openWalletConnectModal } = useWalletConnectModal();
+
const {
- connect,
+ connectWallet,
iconBackground,
iconUrl,
id,
@@ -74,7 +79,6 @@ export function WalletButton({
getMobileUri,
ready,
shortName,
- showWalletConnectModal,
} = wallet;
const coolModeRef = useCoolMode(iconUrl);
@@ -112,17 +116,21 @@ export function WalletButton({
}
};
- if (id !== 'walletConnect') onMobileUri();
-
- // If the id is "walletConnect" then "showWalletConnectModal" will always be true
- if (showWalletConnectModal) {
- showWalletConnectModal();
- onClose?.();
- return;
+ if (isWalletConnectWallet) {
+ onClose();
+ openWalletConnectModal();
+ } else {
+ onMobileUri();
+ connectWallet();
}
-
- connect?.();
- }, [connect, getMobileUri, showWalletConnectModal, onClose, name, id]);
+ }, [
+ connectWallet,
+ isWalletConnectWallet,
+ openWalletConnectModal,
+ getMobileUri,
+ onClose,
+ name,
+ ]);
useEffect(() => {
// When using `reactStrictMode: true` in development mode the useEffect hook
diff --git a/packages/rainbowkit/src/components/RainbowKitProvider/RainbowKitProvider.tsx b/packages/rainbowkit/src/components/RainbowKitProvider/RainbowKitProvider.tsx
index fde6e7d5b6..54b51518d2 100644
--- a/packages/rainbowkit/src/components/RainbowKitProvider/RainbowKitProvider.tsx
+++ b/packages/rainbowkit/src/components/RainbowKitProvider/RainbowKitProvider.tsx
@@ -20,6 +20,7 @@ import { RainbowKitChainProvider } from './RainbowKitChainContext';
import { ShowBalanceProvider } from './ShowBalanceContext';
import { ShowRecentTransactionsContext } from './ShowRecentTransactionsContext';
import { WalletButtonProvider } from './WalletButtonContext';
+import { WalletConnectStoreProvider } from './WalletConnectStoreProvider';
import { useFingerprint } from './useFingerprint';
import { usePreloadImages } from './usePreloadImages';
import { clearWalletConnectDeepLink } from './walletConnectDeepLink';
@@ -103,60 +104,62 @@ export function RainbowKitProvider({
return (
-
-
-
-
-
-
-
-
-
-
-
- {theme ? (
-
-
- {children}
-
- ) : (
- children
- )}
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+ {theme ? (
+
+
+ {children}
+
+ ) : (
+ children
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
);
}
diff --git a/packages/rainbowkit/src/components/RainbowKitProvider/WalletConnectStoreProvider.tsx b/packages/rainbowkit/src/components/RainbowKitProvider/WalletConnectStoreProvider.tsx
new file mode 100644
index 0000000000..6112cfeb2c
--- /dev/null
+++ b/packages/rainbowkit/src/components/RainbowKitProvider/WalletConnectStoreProvider.tsx
@@ -0,0 +1,73 @@
+import React, {
+ ReactNode,
+ createContext,
+ useContext,
+ useEffect,
+ useMemo,
+ useState,
+} from 'react';
+import { useConfig, useConnect } from 'wagmi';
+import {
+ WalletConnectStore,
+ createWalletConnectStore,
+} from '../../core/walletConnect/walletConnectStore';
+import {
+ getWalletConnectWallet,
+ getWalletsFromConnectors,
+} from '../../utils/wallets';
+
+const WalletConnectStoreContext = createContext(
+ createWalletConnectStore(),
+);
+
+interface WalletConnectStoreProviderProps {
+ children: ReactNode;
+}
+
+let walletConnectStoreSingleton: WalletConnectStore;
+
+export function WalletConnectStoreProvider({
+ children,
+}: WalletConnectStoreProviderProps) {
+ const config = useConfig();
+ const { connectors } = useConnect();
+
+ // Use existing WalletConnect store if it exists, or lazily create one
+ const [walletConnectStore] = useState(
+ () =>
+ walletConnectStoreSingleton ??
+ (walletConnectStoreSingleton = createWalletConnectStore()),
+ );
+
+ // biome-ignore lint/correctness/useExhaustiveDependencies: prevent new reference on every re-render
+ const wallets = useMemo(() => getWalletsFromConnectors({ connectors }), []);
+
+ const createWalletConnectModalConnector = useMemo(
+ () =>
+ getWalletConnectWallet({
+ walletId: 'walletConnect',
+ wallets,
+ })?.createWalletConnectModalConnector,
+ [wallets],
+ );
+
+ // Preload WalletConnect modal
+ useEffect(() => {
+ if (createWalletConnectModalConnector) {
+ walletConnectStore.createWalletConnectModalConnector({
+ config,
+ createConnector: createWalletConnectModalConnector,
+ });
+ }
+ }, [walletConnectStore, config, createWalletConnectModalConnector]);
+
+ return (
+
+ {children}
+
+ );
+}
+
+export function useWalletConnectStore(): WalletConnectStore {
+ return useContext(WalletConnectStoreContext);
+}
diff --git a/packages/rainbowkit/src/components/WalletButton/WalletButtonRenderer.tsx b/packages/rainbowkit/src/components/WalletButton/WalletButtonRenderer.tsx
index 3c2d8d1515..4cf46352be 100644
--- a/packages/rainbowkit/src/components/WalletButton/WalletButtonRenderer.tsx
+++ b/packages/rainbowkit/src/components/WalletButton/WalletButtonRenderer.tsx
@@ -102,7 +102,7 @@ export function WalletButtonRenderer({
try {
setLoading(true);
if (isError) setIsError(false);
- await firstConnector?.connect?.();
+ await firstConnector?.connectWallet?.();
} catch {
setIsError(true);
} finally {
diff --git a/packages/rainbowkit/src/core/walletConnect/walletConnectStore.test.tsx b/packages/rainbowkit/src/core/walletConnect/walletConnectStore.test.tsx
new file mode 100644
index 0000000000..63f578e39f
--- /dev/null
+++ b/packages/rainbowkit/src/core/walletConnect/walletConnectStore.test.tsx
@@ -0,0 +1,139 @@
+import { describe, expect, it, vi } from 'vitest';
+import { base, mainnet } from 'wagmi/chains';
+import { connectMutationOptions } from 'wagmi/query';
+import { RainbowKitChain } from '../../components/RainbowKitProvider/RainbowKitChainContext';
+import { getDefaultConfig } from '../../config/getDefaultConfig';
+import {
+ getWalletConnectWallet,
+ getWalletsFromConnectors,
+} from '../../utils/wallets';
+import {
+ WalletConnectStore,
+ createWalletConnectStore,
+} from './walletConnectStore';
+
+const PROJECT_ID = '21fef48091f12692cad574a6f7753643';
+const APP_NAME = 'My RainbowKit App';
+const TIMEOUT = 5000;
+const INTERVAL = 500;
+
+const chains: [RainbowKitChain, ...RainbowKitChain[]] = [mainnet, base];
+
+const config = getDefaultConfig({
+ chains,
+ projectId: PROJECT_ID,
+ appName: APP_NAME,
+});
+
+const { connectors } = config;
+
+const wallets = getWalletsFromConnectors({ connectors });
+const walletConnectWallet = getWalletConnectWallet({
+ wallets,
+});
+
+if (!walletConnectWallet) {
+ throw new Error('WalletConnect wallet not found');
+}
+
+const { mutationFn: connectAsync } = connectMutationOptions(config);
+
+const waitForWalletConnectUri = (
+ getWalletConnectUri: WalletConnectStore['getWalletConnectUri'],
+) => {
+ return vi.waitFor(
+ () => {
+ if (!getWalletConnectUri()) {
+ throw new Error('WalletConnect URI generation timed out');
+ }
+ },
+ { timeout: TIMEOUT, interval: INTERVAL },
+ );
+};
+
+describe('walletConnectStore', () => {
+ it('should receive WalletConnect URI upon request', async () => {
+ let hasReceivedWalletConnectUri = false;
+
+ const { requestWalletConnectUri, onWalletConnectUri, getWalletConnectUri } =
+ createWalletConnectStore();
+
+ onWalletConnectUri((uri) => {
+ if (uri) hasReceivedWalletConnectUri = true;
+ });
+
+ requestWalletConnectUri({
+ config,
+ walletConnectWallet,
+ chains,
+ connectAsync,
+ });
+
+ await waitForWalletConnectUri(getWalletConnectUri);
+
+ expect(hasReceivedWalletConnectUri).toBe(true);
+ expect(getWalletConnectUri()).toMatch(/^wc:/);
+ });
+
+ it('should receive new WalletConnect URIs upon multiple requests', async () => {
+ let hasReceivedWalletConnectUri = false;
+
+ const { requestWalletConnectUri, onWalletConnectUri, getWalletConnectUri } =
+ createWalletConnectStore();
+
+ const unsubscribe = onWalletConnectUri((uri) => {
+ if (uri) hasReceivedWalletConnectUri = true;
+ });
+
+ requestWalletConnectUri({
+ config,
+ walletConnectWallet,
+ chains,
+ connectAsync,
+ });
+
+ await waitForWalletConnectUri(getWalletConnectUri);
+
+ expect(hasReceivedWalletConnectUri).toBe(true);
+ expect(getWalletConnectUri()).toMatch(/^wc:/);
+
+ hasReceivedWalletConnectUri = false;
+ unsubscribe();
+
+ onWalletConnectUri((uri) => {
+ if (uri) hasReceivedWalletConnectUri = true;
+ });
+
+ // Request new WalletConnect URI
+ requestWalletConnectUri({
+ config,
+ walletConnectWallet,
+ chains,
+ connectAsync,
+ });
+
+ expect(getWalletConnectUri()).toBeNull();
+
+ await waitForWalletConnectUri(getWalletConnectUri);
+
+ expect(hasReceivedWalletConnectUri).toBe(true);
+ expect(getWalletConnectUri()).toMatch(/^wc:/);
+ });
+
+ it('should update and get current wallet id', () => {
+ const { setCurrentWalletId, getCurrentWalletId } =
+ createWalletConnectStore();
+
+ setCurrentWalletId('rainbow');
+ expect(getCurrentWalletId()).toBe('rainbow');
+
+ setCurrentWalletId('metamask');
+ expect(getCurrentWalletId()).toBe('metamask');
+
+ setCurrentWalletId('trust');
+ expect(getCurrentWalletId()).toBe('trust');
+
+ setCurrentWalletId();
+ expect(getCurrentWalletId()).toBeNull();
+ });
+});
diff --git a/packages/rainbowkit/src/core/walletConnect/walletConnectStore.ts b/packages/rainbowkit/src/core/walletConnect/walletConnectStore.ts
new file mode 100644
index 0000000000..0a1f162a9e
--- /dev/null
+++ b/packages/rainbowkit/src/core/walletConnect/walletConnectStore.ts
@@ -0,0 +1,139 @@
+import { Connector, CreateConnectorFn, useConfig, useConnect } from 'wagmi';
+import { connectMutationOptions } from 'wagmi/query';
+import { RainbowKitChain } from '../../components/RainbowKitProvider/RainbowKitChainContext';
+import { WalletInstance } from '../../wallets/Wallet';
+import { addRecentWalletId } from '../../wallets/recentWalletIds';
+
+const MAX_REFETCH_ATTEMPTS = 5;
+
+type WalletConnectUriListener = (uri: string) => void;
+
+interface ConnectParameters {
+ config: ReturnType;
+ walletConnectWallet: WalletInstance;
+ chainId?: number;
+ chains: RainbowKitChain[];
+ connectAsync:
+ | ReturnType['mutationFn']
+ | ReturnType['connectAsync'];
+}
+
+interface CreateWalletConnectModalConnectorParameters {
+ config: ReturnType;
+ createConnector: CreateConnectorFn;
+}
+
+export function createWalletConnectStore() {
+ const walletConnectUriListeners: Set = new Set();
+ let walletConnectUri: string | null = null;
+ let walletId: string | null = null;
+ let refetchAttempts = 0;
+ let walletConnectModalConnector: Connector | null = null;
+
+ function notifyWalletConnectUriListeners(uri: string): void {
+ for (const transactionListener of walletConnectUriListeners) {
+ transactionListener(uri);
+ }
+ }
+
+ function requestWalletConnectUri({
+ config,
+ walletConnectWallet,
+ chainId,
+ chains,
+ connectAsync,
+ }: ConnectParameters) {
+ walletConnectUri = null;
+
+ const connectAsyncPromise = async () => {
+ const provider = await walletConnectWallet.getProvider();
+
+ // @ts-expect-error
+ provider.once('display_uri', (uri: string) => {
+ if (uri) {
+ walletConnectUri = uri;
+ notifyWalletConnectUriListeners(uri);
+ }
+ });
+
+ const walletChainId = await walletConnectWallet.getChainId();
+
+ try {
+ const result = await connectAsync({
+ chainId:
+ chainId ??
+ chains.find(({ id }) => id === walletChainId)?.id ??
+ chains[0]?.id,
+ connector: walletConnectWallet,
+ });
+
+ if (result) {
+ const currentWalletId = getCurrentWalletId();
+ if (currentWalletId) addRecentWalletId(currentWalletId);
+ walletId = null;
+ walletConnectUri = null;
+ refetchAttempts = 0;
+ }
+ } catch {
+ const isConnected = config.state.status === 'connected';
+ if (!isConnected && refetchAttempts < MAX_REFETCH_ATTEMPTS) {
+ walletConnectUri = null;
+ refetchAttempts++;
+ connectAsyncPromise();
+ }
+ }
+ };
+
+ connectAsyncPromise();
+ }
+
+ function onWalletConnectUri(listener: WalletConnectUriListener) {
+ walletConnectUriListeners.add(listener);
+ return () => {
+ walletConnectUriListeners.delete(listener);
+ };
+ }
+
+ function createWalletConnectModalConnector({
+ createConnector,
+ config,
+ }: CreateWalletConnectModalConnectorParameters) {
+ if (!walletConnectModalConnector) {
+ const connector = config._internal.connectors.setup(createConnector);
+ walletConnectModalConnector = connector;
+ }
+ }
+
+ function getWalletConnectUri() {
+ return walletConnectUri;
+ }
+
+ function getWalletConnectModalConnector() {
+ return walletConnectModalConnector;
+ }
+
+ function setCurrentWalletId(id?: string) {
+ walletId = id ?? null;
+ }
+
+ function getCurrentWalletId() {
+ return walletId;
+ }
+
+ function resetWalletConnectUri() {
+ walletConnectUri = null;
+ }
+
+ return {
+ createWalletConnectModalConnector,
+ requestWalletConnectUri,
+ onWalletConnectUri,
+ getWalletConnectUri,
+ setCurrentWalletId,
+ getCurrentWalletId,
+ getWalletConnectModalConnector,
+ resetWalletConnectUri,
+ };
+}
+
+export type WalletConnectStore = ReturnType;
diff --git a/packages/rainbowkit/src/hooks/useRequestWalletConnectUri.ts b/packages/rainbowkit/src/hooks/useRequestWalletConnectUri.ts
new file mode 100644
index 0000000000..62d19c3a98
--- /dev/null
+++ b/packages/rainbowkit/src/hooks/useRequestWalletConnectUri.ts
@@ -0,0 +1,52 @@
+import { useEffect, useMemo } from 'react';
+import { useConfig, useConnect } from 'wagmi';
+import {
+ useInitialChainId,
+ useRainbowKitChains,
+} from '../components/RainbowKitProvider/RainbowKitChainContext';
+import { useWalletConnectStore } from '../components/RainbowKitProvider/WalletConnectStoreProvider';
+import {
+ getWalletConnectWallet,
+ getWalletsFromConnectors,
+} from '../utils/wallets';
+
+export function useRequestWalletConnectUri() {
+ const { requestWalletConnectUri: requestWalletConnectUriStore } =
+ useWalletConnectStore();
+
+ const config = useConfig();
+ const rainbowKitChains = useRainbowKitChains();
+ const initialChainId = useInitialChainId();
+
+ const { connectAsync, connectors } = useConnect();
+
+ // biome-ignore lint/correctness/useExhaustiveDependencies: prevent new reference on every re-render
+ const wallets = useMemo(() => getWalletsFromConnectors({ connectors }), []);
+
+ const walletConnectWallet = useMemo(
+ () =>
+ getWalletConnectWallet({
+ wallets,
+ }),
+ [wallets],
+ );
+
+ useEffect(() => {
+ if (walletConnectWallet) {
+ requestWalletConnectUriStore({
+ config,
+ walletConnectWallet,
+ chainId: initialChainId,
+ chains: rainbowKitChains,
+ connectAsync,
+ });
+ }
+ }, [
+ config,
+ walletConnectWallet,
+ initialChainId,
+ rainbowKitChains,
+ requestWalletConnectUriStore,
+ connectAsync,
+ ]);
+}
diff --git a/packages/rainbowkit/src/utils/ens.test.ts b/packages/rainbowkit/src/utils/ens.test.ts
index d3c0b86b9b..ac36edb7db 100644
--- a/packages/rainbowkit/src/utils/ens.test.ts
+++ b/packages/rainbowkit/src/utils/ens.test.ts
@@ -1,38 +1,14 @@
-import { beforeAll, describe, expect, it, vi } from 'vitest';
+import { describe, expect, it, vi } from 'vitest';
import { addEnsName, getEnsName, getStorageEnsNameKey } from './ens';
// vitalik.eth
const mockAddress = '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045';
const mockEnsName = 'vitalik.eth';
-const store: Record = {};
-
-const localStorageMock: Storage = {
- getItem: (key: string): string => store[key] ?? null,
- setItem: (key: string, value: string): void => {
- store[key] = value.toString();
- },
- removeItem: (key: string): void => {
- delete store[key];
- },
- clear: (): void => {},
- // biome-ignore lint/correctness/noUnusedVariables:
- key: (index: number): string | null => '',
- length: Object.keys(store).length,
- // Easier to get number realtime, due to single object
- // reference not allowing us to use localStorage.length realtime
- total: () => Object.keys(store).length,
-};
-
-beforeAll((): void => {
- localStorage = localStorageMock;
-});
-
describe('ens', () => {
it('should return null if ens name is not found', () => {
const ensName = getEnsName(mockAddress);
- expect(localStorage.total()).toBe(0);
expect(ensName).toBeNull();
});
@@ -41,7 +17,6 @@ describe('ens', () => {
const ensName = getEnsName(mockAddress);
- expect(localStorage.total()).toBe(1);
expect(ensName).toBe(mockEnsName);
});
@@ -56,41 +31,40 @@ describe('ens', () => {
const ensName = getEnsName(mockAddress);
- expect(localStorage.total()).toBe(0);
expect(ensName).toBeNull();
});
it('should return null if ens name from localStorage is not a string', () => {
addEnsName(mockAddress, mockEnsName);
- expect(localStorage.total()).toBe(1);
-
// Pretend someone messed up the localStorage by putting null on ensName field
- store[getStorageEnsNameKey(mockAddress)] = JSON.stringify({
- ensName: null,
- expires: 0,
- });
+ localStorage.setItem(
+ getStorageEnsNameKey(mockAddress),
+ JSON.stringify({
+ ensName: null,
+ expires: 0,
+ }),
+ );
const ensName = getEnsName(mockAddress);
- expect(localStorage.total()).toBe(0);
expect(ensName).toBeNull();
});
it('should return null if ens name expiration from localStorage is NaN', () => {
addEnsName(mockAddress, mockEnsName);
- expect(localStorage.total()).toBe(1);
-
- // Pretend someone messed up the localStorage by putting undefined on expires field
- store[getStorageEnsNameKey(mockAddress)] = JSON.stringify({
- ensName: mockEnsName,
- expires: undefined,
- });
+ // Pretend someone messed up the localStorage by putting null on ensName field
+ localStorage.setItem(
+ getStorageEnsNameKey(mockAddress),
+ JSON.stringify({
+ ensName: mockEnsName,
+ expires: undefined,
+ }),
+ );
const ensName = getEnsName(mockAddress);
- expect(localStorage.total()).toBe(0);
expect(ensName).toBeNull();
});
});
diff --git a/packages/rainbowkit/src/utils/strings.ts b/packages/rainbowkit/src/utils/strings.ts
new file mode 100644
index 0000000000..281ce42dc9
--- /dev/null
+++ b/packages/rainbowkit/src/utils/strings.ts
@@ -0,0 +1,2 @@
+export const isLowerCaseMatch = (a?: string, b?: string) =>
+ a?.toLowerCase() === b?.toLowerCase();
diff --git a/packages/rainbowkit/src/utils/wallets.ts b/packages/rainbowkit/src/utils/wallets.ts
new file mode 100644
index 0000000000..9eb20b509d
--- /dev/null
+++ b/packages/rainbowkit/src/utils/wallets.ts
@@ -0,0 +1,38 @@
+import { useConnect } from 'wagmi';
+import { WagmiConnectorInstance, WalletInstance } from '../wallets/Wallet';
+import { isLowerCaseMatch } from './strings';
+
+interface GetWalletsFromConnectorsParameters {
+ connectors: ReturnType['connectors'];
+}
+
+interface GetWalletConnectWalletParameters {
+ walletId?: string;
+ wallets: WalletInstance[];
+}
+
+export function getWalletsFromConnectors({
+ connectors,
+}: GetWalletsFromConnectorsParameters): WalletInstance[] {
+ return connectors.map((connector) => {
+ const walletInstance = connector as WagmiConnectorInstance;
+ return {
+ connectorId: walletInstance.id,
+ ...walletInstance,
+ ...(walletInstance.rkDetails || {}),
+ } as WalletInstance;
+ });
+}
+
+export function getWalletConnectWallet({
+ walletId,
+ wallets,
+}: GetWalletConnectWalletParameters) {
+ return (
+ wallets.find(({ id, connectorId }) =>
+ walletId
+ ? isLowerCaseMatch(walletId, id)
+ : isLowerCaseMatch(connectorId, 'walletConnect'),
+ ) ?? null
+ );
+}
diff --git a/packages/rainbowkit/src/wallets/Wallet.ts b/packages/rainbowkit/src/wallets/Wallet.ts
index eaf6b7e30d..fa603a8442 100644
--- a/packages/rainbowkit/src/wallets/Wallet.ts
+++ b/packages/rainbowkit/src/wallets/Wallet.ts
@@ -107,12 +107,9 @@ export type RainbowKitDetails = Omit & {
index: number;
groupIndex: number;
groupName: string;
- isWalletConnectModalConnector?: boolean;
isRainbowKitConnector: boolean;
- walletConnectModalConnector?: Connector;
- // Used specifically in `connectorsForWallets` logic
- // to make sure we can also get WalletConnect modal in rainbowkit
- showQrModal?: true;
+ // Only used for "walletConnectWallet" connector
+ createWalletConnectModalConnector?: CreateConnectorFn;
};
export type WalletDetailsParams = { rkDetails: RainbowKitDetails };
@@ -131,4 +128,5 @@ export type WagmiConnectorInstance = Connector & {
// This will be the wallet instance we will return
// in the rainbowkit connect modal
-export type WalletInstance = Connector & RainbowKitDetails;
+export type WalletInstance = Connector &
+ RainbowKitDetails & { connectorId: string };
diff --git a/packages/rainbowkit/src/wallets/connectorsForWallets.ts b/packages/rainbowkit/src/wallets/connectorsForWallets.ts
index 085074bec1..93087063f9 100644
--- a/packages/rainbowkit/src/wallets/connectorsForWallets.ts
+++ b/packages/rainbowkit/src/wallets/connectorsForWallets.ts
@@ -3,12 +3,13 @@ import { isHexString } from '../utils/colors';
import { omitUndefinedValues } from '../utils/omitUndefinedValues';
import { uniqueBy } from '../utils/uniqueBy';
import type {
+ RainbowKitDetails,
RainbowKitWalletConnectParameters,
Wallet,
- WalletDetailsParams,
WalletList,
} from './Wallet';
import { computeWalletConnectMetaData } from './computeWalletConnectMetaData';
+import { getWalletConnectConnector } from './getWalletConnectConnector';
interface WalletListItem extends Wallet {
index: number;
@@ -29,7 +30,7 @@ export const connectorsForWallets = (
walletList: WalletList,
{
projectId,
- walletConnectParameters,
+ walletConnectParameters = {},
appName,
appDescription,
appUrl,
@@ -129,42 +130,29 @@ export const connectorsForWallets = (
}
}
- const walletMetaData = (
- // For now we should only use these as the additional parameters
- additionalRkParams?: Pick<
- WalletDetailsParams['rkDetails'],
- 'isWalletConnectModalConnector' | 'showQrModal'
- >,
- ) => {
- return {
- rkDetails: omitUndefinedValues({
- ...walletMeta,
- groupIndex,
- groupName,
- isRainbowKitConnector: true,
- // These additional params will be used in rainbowkit react tree to
- // merge `walletConnectWallet` and `walletConnect` connector from wagmi with
- // showQrModal: true. This way we can let the user choose if they want to
- // connect via QR code or open the official walletConnect modal instead
- ...(additionalRkParams ? additionalRkParams : {}),
- }),
- };
- };
-
const isWalletConnectConnector = walletMeta.id === 'walletConnect';
+ const metadata = omitUndefinedValues({
+ ...walletMeta,
+ groupIndex,
+ groupName,
+ isRainbowKitConnector: true,
+ });
+
+ const rkDetails: RainbowKitDetails = { ...metadata };
+
if (isWalletConnectConnector) {
- connectors.push(
- createConnector(
- walletMetaData({
- isWalletConnectModalConnector: true,
- showQrModal: true,
- }),
- ),
- );
+ rkDetails.createWalletConnectModalConnector = getWalletConnectConnector({
+ projectId,
+ showQrModal: true,
+ walletConnectParameters: {
+ metadata: walletConnectMetaData,
+ ...walletConnectParameters,
+ },
+ })({ rkDetails: metadata });
}
- const connector = createConnector(walletMetaData());
+ const connector = createConnector({ rkDetails });
connectors.push(connector);
}
diff --git a/packages/rainbowkit/src/wallets/getWalletConnectConnector.ts b/packages/rainbowkit/src/wallets/getWalletConnectConnector.ts
index a4f31b473b..e9bd8bff57 100644
--- a/packages/rainbowkit/src/wallets/getWalletConnectConnector.ts
+++ b/packages/rainbowkit/src/wallets/getWalletConnectConnector.ts
@@ -3,7 +3,6 @@ import type { CreateConnectorFn } from 'wagmi';
import { WalletConnectParameters, walletConnect } from 'wagmi/connectors';
import type {
CreateConnector,
- RainbowKitDetails,
RainbowKitWalletConnectParameters,
WalletDetailsParams,
} from './Wallet';
@@ -11,18 +10,20 @@ import type {
interface GetWalletConnectConnectorParams {
projectId: string;
walletConnectParameters?: RainbowKitWalletConnectParameters;
+ showQrModal?: boolean;
}
interface CreateWalletConnectConnectorParams {
projectId: string;
walletDetails: WalletDetailsParams;
walletConnectParameters?: RainbowKitWalletConnectParameters;
+ showQrModal?: boolean;
}
interface GetOrCreateWalletConnectInstanceParams {
projectId: string;
walletConnectParameters?: RainbowKitWalletConnectParameters;
- rkDetailsShowQrModal?: RainbowKitDetails['showQrModal'];
+ showQrModal?: boolean;
}
const walletConnectInstances = new Map<
@@ -34,21 +35,16 @@ const walletConnectInstances = new Map<
const getOrCreateWalletConnectInstance = ({
projectId,
walletConnectParameters,
- rkDetailsShowQrModal,
+ showQrModal = false,
}: GetOrCreateWalletConnectInstanceParams): ReturnType<
typeof walletConnect
> => {
- let config: WalletConnectParameters = {
+ const config: WalletConnectParameters = {
...(walletConnectParameters ? walletConnectParameters : {}),
projectId,
- showQrModal: false, // Required. Otherwise WalletConnect modal (Web3Modal) will popup during time of connection for a wallet
+ showQrModal,
};
- // `rkDetailsShowQrModal` should always be `true`
- if (rkDetailsShowQrModal) {
- config = { ...config, showQrModal: true };
- }
-
const serializedConfig = JSON.stringify(config);
const sharedWalletConnector = walletConnectInstances.get(serializedConfig);
@@ -70,15 +66,14 @@ function createWalletConnectConnector({
projectId,
walletDetails,
walletConnectParameters,
+ showQrModal,
}: CreateWalletConnectConnectorParams): CreateConnectorFn {
// Create and configure the WalletConnect connector with project ID and options.
return createConnector((config) => ({
...getOrCreateWalletConnectInstance({
projectId,
walletConnectParameters,
- // Used in `connectorsForWallets` to add another
- // walletConnect wallet into rainbowkit with modal popup option
- rkDetailsShowQrModal: walletDetails.rkDetails.showQrModal,
+ showQrModal,
})(config),
...walletDetails,
}));
@@ -88,6 +83,7 @@ function createWalletConnectConnector({
export function getWalletConnectConnector({
projectId,
walletConnectParameters,
+ showQrModal,
}: GetWalletConnectConnectorParams): CreateConnector {
// We use this projectId in place of YOUR_PROJECT_ID for our examples.
// This allows us our examples and templates to be functional with WalletConnect v2.
@@ -110,5 +106,6 @@ export function getWalletConnectConnector({
projectId,
walletDetails,
walletConnectParameters,
+ showQrModal,
});
}
diff --git a/packages/rainbowkit/src/wallets/groupedWallets.ts b/packages/rainbowkit/src/wallets/groupedWallets.ts
index 3c41a493d8..027c9b3767 100644
--- a/packages/rainbowkit/src/wallets/groupedWallets.ts
+++ b/packages/rainbowkit/src/wallets/groupedWallets.ts
@@ -33,19 +33,6 @@ export const isEIP6963Connector = (wallet: WalletInstance) => {
);
};
-export const rainbowKitConnectorWithWalletConnect = (
- wallet: WalletInstance,
- walletConnectModalConnector: WalletInstance,
-) => {
- // Check if we should use the walletConnectModalConnector for this instance
- const shouldUseWalletConnectModal =
- wallet.id === 'walletConnect' && walletConnectModalConnector;
-
- // Include the walletConnectModalConnector in the result
- return shouldUseWalletConnectModal
- ? { ...wallet, walletConnectModalConnector }
- : wallet;
-};
interface ConnectorsWithWalletsParams {
wallets: WalletInstance[];
recentWallets: WalletInstance[];
diff --git a/packages/rainbowkit/src/wallets/useWalletConnectModal.ts b/packages/rainbowkit/src/wallets/useWalletConnectModal.ts
new file mode 100644
index 0000000000..626ac03dfa
--- /dev/null
+++ b/packages/rainbowkit/src/wallets/useWalletConnectModal.ts
@@ -0,0 +1,71 @@
+import { useCallback } from 'react';
+import { Connector, useConnect } from 'wagmi';
+import { useWalletConnectOpenState } from '../components/RainbowKitProvider/ModalContext';
+import {
+ useInitialChainId,
+ useRainbowKitChains,
+} from '../components/RainbowKitProvider/RainbowKitChainContext';
+
+import { useWalletConnectStore } from '../components/RainbowKitProvider/WalletConnectStoreProvider';
+import { addRecentWalletId } from './recentWalletIds';
+
+export function useWalletConnectModal() {
+ const rainbowKitChains = useRainbowKitChains();
+ const initialChainId = useInitialChainId();
+ const { setIsWalletConnectModalOpen } = useWalletConnectOpenState();
+
+ const { connectAsync } = useConnect();
+
+ const { getWalletConnectModalConnector, resetWalletConnectUri } =
+ useWalletConnectStore();
+
+ async function connectWallet(connector: Connector) {
+ const walletChainId = await connector.getChainId();
+
+ const result = await connectAsync({
+ chainId:
+ initialChainId ??
+ rainbowKitChains.find(({ id }) => id === walletChainId)?.id ??
+ rainbowKitChains[0]?.id,
+ connector,
+ });
+
+ if (result) {
+ addRecentWalletId(connector.id);
+ }
+ }
+
+ const openWalletConnectModal = useCallback(async () => {
+ const walletConnectModalConnector = getWalletConnectModalConnector();
+
+ if (walletConnectModalConnector) {
+ try {
+ setIsWalletConnectModalOpen(true);
+ await connectWallet({
+ ...walletConnectModalConnector,
+ id: 'walletConnect',
+ });
+ resetWalletConnectUri();
+ setIsWalletConnectModalOpen(false);
+ } catch (err) {
+ const isUserRejection =
+ // @ts-expect-error - Web3Modal v1 error name
+ err.name === 'UserRejectedRequestError' ||
+ // @ts-expect-error - Web3Modal v2 error message on desktop
+ err.message === 'Connection request reset. Please try again.';
+
+ setIsWalletConnectModalOpen(false);
+
+ if (!isUserRejection) {
+ throw err;
+ }
+ }
+ }
+ }, [
+ getWalletConnectModalConnector,
+ resetWalletConnectUri,
+ setIsWalletConnectModalOpen,
+ ]);
+
+ return { openWalletConnectModal };
+}
diff --git a/packages/rainbowkit/src/wallets/useWalletConnectors.ts b/packages/rainbowkit/src/wallets/useWalletConnectors.ts
index fba9375e2c..eac26208d5 100644
--- a/packages/rainbowkit/src/wallets/useWalletConnectors.ts
+++ b/packages/rainbowkit/src/wallets/useWalletConnectors.ts
@@ -1,12 +1,12 @@
-import { Config, Connector, useConnect } from 'wagmi';
-import { ConnectMutateAsync } from 'wagmi/query';
-import { useWalletConnectOpenState } from '../components/RainbowKitProvider/ModalContext';
+import { Connector, useConfig, useConnect } from 'wagmi';
+import { useWalletConnectStore } from '../components/RainbowKitProvider/WalletConnectStoreProvider';
import { indexBy } from '../utils/indexBy';
+import { getWalletsFromConnectors } from '../utils/wallets';
import {
useInitialChainId,
useRainbowKitChains,
} from './../components/RainbowKitProvider/RainbowKitChainContext';
-import { WagmiConnectorInstance, WalletInstance } from './Wallet';
+import { WalletInstance } from './Wallet';
import {
getDesktopDownloadUrl,
getExtensionDownloadUrl,
@@ -17,14 +17,12 @@ import {
isEIP6963Connector,
isRainbowKitConnector,
isRecentWallet,
- rainbowKitConnectorWithWalletConnect,
} from './groupedWallets';
import { addRecentWalletId, getRecentWalletIds } from './recentWalletIds';
export interface WalletConnector extends WalletInstance {
ready?: boolean;
- connect: () => ReturnType>;
- showWalletConnectModal?: () => void;
+ connectWallet: () => Promise;
recent: boolean;
mobileDownloadUrl?: string;
extensionDownloadUrl?: string;
@@ -37,21 +35,16 @@ export interface WalletConnector extends WalletInstance {
export function useWalletConnectors(
mergeEIP6963WithRkConnectors = false,
): WalletConnector[] {
+ const config = useConfig();
const rainbowKitChains = useRainbowKitChains();
- const intialChainId = useInitialChainId();
+ const initialChainId = useInitialChainId();
const { connectAsync, connectors: defaultConnectors_untyped } = useConnect();
- const defaultCreatedConnectors =
- defaultConnectors_untyped as WagmiConnectorInstance[];
- const { setIsWalletConnectModalOpen } = useWalletConnectOpenState();
+ const { getWalletConnectUri, setCurrentWalletId } = useWalletConnectStore();
- const defaultConnectors = defaultCreatedConnectors.map((connector) => ({
- ...connector,
- // rkDetails is optional it does not exist in eip6963 connectors.
- // We only inject `rkDetails` in `connectorsForWallets` when we
- // want to have additional information in the connector.
- ...(connector.rkDetails || {}),
- })) as WalletInstance[];
+ const defaultConnectors = getWalletsFromConnectors({
+ connectors: defaultConnectors_untyped,
+ });
async function connectWallet(connector: Connector) {
const walletChainId = await connector.getChainId();
@@ -59,7 +52,7 @@ export function useWalletConnectors(
chainId:
// The goal here is to ensure users are always on a supported chain when connecting.
// If an `initialChain` prop was provided to RainbowKitProvider, use that.
- intialChainId ??
+ initialChainId ??
// Otherwise, if the wallet is already on a supported chain, use that to avoid a chain switch prompt.
rainbowKitChains.find(({ id }) => id === walletChainId)?.id ??
// Finally, fall back to the first chain provided to RainbowKitProvider.
@@ -70,57 +63,56 @@ export function useWalletConnectors(
if (result) {
addRecentWalletId(connector.id);
}
-
- return result;
}
- async function connectToWalletConnectModal(
- walletConnectModalConnector: Connector,
- ) {
- try {
- setIsWalletConnectModalOpen(true);
- await connectWallet(walletConnectModalConnector);
- setIsWalletConnectModalOpen(false);
- } catch (err) {
- const isUserRejection =
- // @ts-expect-error - Web3Modal v1 error name
- err.name === 'UserRejectedRequestError' ||
- // @ts-expect-error - Web3Modal v2 error message on desktop
- err.message === 'Connection request reset. Please try again.';
-
- setIsWalletConnectModalOpen(false);
-
- if (!isUserRejection) {
- throw err;
- }
- }
- }
+ const pollForWalletConnectUri = (
+ uriConverter: (uri: string) => string,
+ ): Promise => {
+ // If WalletConnect URI is not found, then poll for it.
+ return new Promise((resolve) => {
+ const intervalId = setInterval(() => {
+ const walletConnectUri = getWalletConnectUri();
+ if (walletConnectUri) {
+ clearInterval(intervalId);
+ resolve(
+ uriConverter ? uriConverter(walletConnectUri) : walletConnectUri,
+ );
+ }
+ }, 1000);
+ });
+ };
- const getWalletConnectUri = async (
+ const getUri = async (
connector: Connector,
uriConverter: (uri: string) => string,
): Promise => {
- const provider = await connector.getProvider();
-
if (connector.id === 'coinbase') {
+ const provider = await connector.getProvider();
// @ts-expect-error
return provider.qrUrl;
}
- return new Promise((resolve) =>
- // Wagmi v2 doesn't have a return type for provider yet
- // @ts-expect-error
- provider.once('display_uri', (uri) => {
- resolve(uriConverter(uri));
- }),
- );
+ const walletConnectUri = getWalletConnectUri();
+
+ if (walletConnectUri) {
+ return uriConverter(walletConnectUri);
+ }
+
+ return pollForWalletConnectUri(uriConverter);
};
- const walletConnectModalConnector = defaultConnectors.find(
- (connector) =>
- connector.id === 'walletConnect' &&
- connector.isWalletConnectModalConnector,
- );
+ const waitUntilConnected = async (id: string): Promise => {
+ setCurrentWalletId(id);
+ return new Promise((resolve) => {
+ const intervalId = setInterval(() => {
+ const isConnected = config.state.status === 'connected';
+ if (isConnected) {
+ clearInterval(intervalId);
+ resolve();
+ }
+ }, 1000);
+ });
+ };
const eip6963Connectors = defaultConnectors
.filter(isEIP6963Connector)
@@ -133,7 +125,6 @@ export function useWalletConnectors(
const rainbowKitConnectors = defaultConnectors
.filter(isRainbowKitConnector)
- .filter((wallet) => !wallet.isWalletConnectModalConnector)
.filter((wallet) => {
if (!mergeEIP6963WithRkConnectors) return true;
@@ -142,13 +133,7 @@ export function useWalletConnectors(
);
return !existsInEIP6963Connectors;
- })
- .map((wallet) =>
- rainbowKitConnectorWithWalletConnect(
- wallet,
- walletConnectModalConnector!,
- ),
- );
+ });
const combinedConnectors = [...eip6963Connectors, ...rainbowKitConnectors];
@@ -183,7 +168,7 @@ export function useWalletConnectors(
...wallet,
iconUrl: wallet.icon!,
ready: true,
- connect: () => connectWallet(wallet),
+ connectWallet: () => connectWallet(wallet),
groupName: 'Installed',
recent,
});
@@ -191,27 +176,29 @@ export function useWalletConnectors(
continue;
}
+ const isWalletConnectConnector = wallet.connectorId === 'walletConnect';
+
walletConnectors.push({
...wallet,
ready: wallet.installed ?? true,
- connect: () => connectWallet(wallet),
+ connectWallet: () =>
+ isWalletConnectConnector
+ ? waitUntilConnected(wallet.id)
+ : connectWallet(wallet),
desktopDownloadUrl: getDesktopDownloadUrl(wallet),
extensionDownloadUrl: getExtensionDownloadUrl(wallet),
groupName: wallet.groupName,
mobileDownloadUrl: getMobileDownloadUrl(wallet),
getQrCodeUri: wallet.qrCode?.getUri
- ? () => getWalletConnectUri(wallet, wallet.qrCode!.getUri!)
+ ? () => getUri(wallet, wallet.qrCode!.getUri!)
: undefined,
getDesktopUri: wallet.desktop?.getUri
- ? () => getWalletConnectUri(wallet, wallet.desktop!.getUri!)
+ ? () => getUri(wallet, wallet.desktop!.getUri!)
: undefined,
getMobileUri: wallet.mobile?.getUri
- ? () => getWalletConnectUri(wallet, wallet.mobile?.getUri!)
+ ? () => getUri(wallet, wallet.mobile?.getUri!)
: undefined,
recent,
- showWalletConnectModal: wallet.walletConnectModalConnector
- ? () => connectToWalletConnectModal(wallet.walletConnectModalConnector!)
- : undefined,
});
}
return walletConnectors;
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index fc14da5932..b2bdc2ed00 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -30,13 +30,13 @@ importers:
version: 5.51.11(react@18.3.0)
'@testing-library/jest-dom':
specifier: ^6.2.0
- version: 6.2.0(@types/jest@29.5.12)(vitest@2.0.4(@types/node@18.19.4)(jsdom@23.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.0))
+ version: 6.2.0(@types/jest@29.5.12)(vitest@2.0.4(@types/node@18.19.4)(@vitest/browser@2.0.4)(jsdom@23.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.0))
'@testing-library/react':
specifier: ^14.1.2
version: 14.1.2(react-dom@18.3.0(react@18.3.0))(react@18.3.0)
'@testing-library/user-event':
specifier: ^14.5.2
- version: 14.5.2(@testing-library/dom@9.3.1)
+ version: 14.5.2(@testing-library/dom@10.4.0)
'@types/node':
specifier: ^18.19.3
version: 18.19.4
@@ -52,6 +52,9 @@ importers:
'@vanilla-extract/vite-plugin':
specifier: ^4.0.9
version: 4.0.9(@types/node@18.19.4)(babel-plugin-macros@3.1.0)(terser@5.31.0)(vite@5.2.11(@types/node@18.19.4)(terser@5.31.0))
+ '@vitest/browser':
+ specifier: 2.0.4
+ version: 2.0.4(bufferutil@4.0.8)(playwright@1.45.3)(typescript@5.4.2)(utf-8-validate@5.0.10)(vitest@2.0.4)
autoprefixer:
specifier: ^10.4.16
version: 10.4.16(postcss@8.4.32)
@@ -82,6 +85,9 @@ importers:
next-auth:
specifier: 4.24.5
version: 4.24.5(next@14.2.3(@babel/core@7.24.5)(@opentelemetry/api@1.8.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.0(react@18.3.0))(react@18.3.0))(react-dom@18.3.0(react@18.3.0))(react@18.3.0)
+ playwright:
+ specifier: 1.45.3
+ version: 1.45.3
postcss:
specifier: ^8.4.32
version: 8.4.32
@@ -105,7 +111,7 @@ importers:
version: 2.17.0(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10)
vitest:
specifier: 2.0.4
- version: 2.0.4(@types/node@18.19.4)(jsdom@23.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.0)
+ version: 2.0.4(@types/node@18.19.4)(@vitest/browser@2.0.4)(jsdom@23.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.0)
wagmi:
specifier: ^2.12.0
version: 2.12.0(@react-native-async-storage/async-storage@1.21.0(react-native@0.73.3(@babel/core@7.24.5)(@babel/preset-env@7.16.4(@babel/core@7.24.5))(bufferutil@4.0.8)(react@18.3.0)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.51.9)(@tanstack/react-query@5.51.11(react@18.3.0))(@types/react@18.3.0)(bufferutil@4.0.8)(immer@9.0.21)(react-dom@18.3.0(react@18.3.0))(react-native@0.73.3(@babel/core@7.24.5)(@babel/preset-env@7.16.4(@babel/core@7.24.5))(bufferutil@4.0.8)(react@18.3.0)(utf-8-validate@5.0.10))(react@18.3.0)(rollup@4.17.2)(typescript@5.4.2)(utf-8-validate@5.0.10)(viem@2.17.0(bufferutil@4.0.8)(typescript@5.4.2)(utf-8-validate@5.0.10))
@@ -214,7 +220,7 @@ importers:
devDependencies:
'@remix-run/dev':
specifier: ^2.9.2
- version: 2.9.2(@remix-run/react@2.9.2(react-dom@18.3.0(react@18.3.0))(react@18.3.0)(typescript@5.4.2))(@remix-run/serve@2.9.2(typescript@5.4.2))(@types/node@20.12.12)(babel-plugin-macros@3.1.0)(bufferutil@4.0.8)(terser@5.31.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(vite@5.2.11(@types/node@20.12.12)(terser@5.31.0))
+ version: 2.9.2(@remix-run/react@2.9.2(react-dom@18.3.0(react@18.3.0))(react@18.3.0)(typescript@5.4.2))(@remix-run/serve@2.9.2(typescript@5.4.2))(@types/node@20.14.12)(babel-plugin-macros@3.1.0)(bufferutil@4.0.8)(terser@5.31.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(vite@5.2.11(@types/node@20.14.12)(terser@5.31.0))
examples/with-vite:
dependencies:
@@ -224,10 +230,10 @@ importers:
devDependencies:
'@vitejs/plugin-react':
specifier: ^4.2.1
- version: 4.2.1(vite@5.2.11(@types/node@20.12.12)(terser@5.31.0))
+ version: 4.2.1(vite@5.2.11(@types/node@20.14.12)(terser@5.31.0))
vite:
specifier: ^5.2.11
- version: 5.2.11(@types/node@20.12.12)(terser@5.31.0)
+ version: 5.2.11(@types/node@20.14.12)(terser@5.31.0)
packages/create-rainbowkit:
dependencies:
@@ -370,13 +376,13 @@ importers:
devDependencies:
'@testing-library/jest-dom':
specifier: ^6.2.0
- version: 6.2.0(@types/jest@29.5.12)(vitest@2.0.4(@types/node@20.12.12)(jsdom@23.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.0))
+ version: 6.2.0(@types/jest@29.5.12)(vitest@2.0.4(@types/node@20.14.12)(@vitest/browser@2.0.4)(jsdom@23.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.0))
'@testing-library/react':
specifier: ^14.1.2
version: 14.1.2(react-dom@18.3.0(react@18.3.0))(react@18.3.0)
'@testing-library/user-event':
specifier: ^14.5.2
- version: 14.5.2(@testing-library/dom@9.3.1)
+ version: 14.5.2(@testing-library/dom@10.4.0)
'@types/qrcode':
specifier: ^1.5.5
version: 1.5.5
@@ -389,6 +395,9 @@ importers:
'@vanilla-extract/private':
specifier: ^1.0.3
version: 1.0.3
+ '@vitest/browser':
+ specifier: 2.0.4
+ version: 2.0.4(bufferutil@4.0.8)(playwright@1.45.3)(typescript@5.4.2)(utf-8-validate@5.0.10)(vitest@2.0.4)
autoprefixer:
specifier: ^10.4.16
version: 10.4.16(postcss@8.4.32)
@@ -401,6 +410,9 @@ importers:
nock:
specifier: ^13.4.0
version: 13.4.0
+ playwright:
+ specifier: 1.45.3
+ version: 1.45.3
postcss:
specifier: ^8.4.32
version: 8.4.32
@@ -409,7 +421,7 @@ importers:
version: 18.3.0
vitest:
specifier: 2.0.4
- version: 2.0.4(@types/node@20.12.12)(jsdom@23.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.0)
+ version: 2.0.4(@types/node@20.14.12)(@vitest/browser@2.0.4)(jsdom@23.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.0)
packages/rainbowkit-siwe-next-auth:
dependencies:
@@ -467,7 +479,7 @@ importers:
version: 0.1.3
'@vanilla-extract/next-plugin':
specifier: 2.4.0
- version: 2.4.0(@types/node@18.19.4)(babel-plugin-macros@3.1.0)(next@14.2.3(@babel/core@7.24.5)(@opentelemetry/api@1.8.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.0(react@18.3.0))(react@18.3.0))(terser@5.31.0)(webpack@5.82.0(esbuild@0.20.2))
+ version: 2.4.0(@types/node@20.14.12)(babel-plugin-macros@3.1.0)(next@14.2.3(@babel/core@7.24.5)(@opentelemetry/api@1.8.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.0(react@18.3.0))(react@18.3.0))(terser@5.31.0)(webpack@5.82.0(esbuild@0.20.2))
'@vanilla-extract/recipes':
specifier: ^0.5.2
version: 0.5.2(@vanilla-extract/css@1.15.1(babel-plugin-macros@3.1.0))
@@ -1785,6 +1797,15 @@ packages:
cpu: [x64]
os: [win32]
+ '@bundled-es-modules/cookie@2.0.0':
+ resolution: {integrity: sha512-Or6YHg/kamKHpxULAdSqhGqnWFneIXu1NKvvfBBzKGwpVsYuFIQ5aBPHDnnoR3ghW1nvSkALd+EF9iMtY7Vjxw==}
+
+ '@bundled-es-modules/statuses@1.0.1':
+ resolution: {integrity: sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==}
+
+ '@bundled-es-modules/tough-cookie@0.1.6':
+ resolution: {integrity: sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==}
+
'@changesets/apply-release-plan@7.0.0':
resolution: {integrity: sha512-vfi69JR416qC9hWmFGSxj7N6wA5J222XNBmezSVATPWDVPIF7gkd4d8CpbEbXmRWbVrkoli3oerGS6dcL/BGsQ==}
@@ -2909,6 +2930,22 @@ packages:
resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
deprecated: Use @eslint/object-schema instead
+ '@inquirer/confirm@3.1.17':
+ resolution: {integrity: sha512-qCpt/AABzPynz8tr69VDvhcjwmzAryipWXtW8Vi6m651da4H/d0Bdn55LkxXD7Rp2gfgxvxzTdb66AhIA8gzBA==}
+ engines: {node: '>=18'}
+
+ '@inquirer/core@9.0.5':
+ resolution: {integrity: sha512-QWG41I7vn62O9stYKg/juKXt1PEbr/4ZZCPb4KgXDQGwgA9M5NBTQ7FnOvT1ridbxkm/wTxLCNraUs7y47pIRQ==}
+ engines: {node: '>=18'}
+
+ '@inquirer/figures@1.0.5':
+ resolution: {integrity: sha512-79hP/VWdZ2UVc9bFGJnoQ/lQMpL74mGgzSYX1xUqCVk7/v73vJCMw1VuyWN1jGkZ9B3z7THAbySqGbCNefcjfA==}
+ engines: {node: '>=18'}
+
+ '@inquirer/type@1.5.1':
+ resolution: {integrity: sha512-m3YgGQlKNS0BM+8AFiJkCsTqHEFCWn6s/Rqye3mYwvqY6LdfUv12eSwbsgNzrYyrLXiy7IrrjDLPysaSBwEfhw==}
+ engines: {node: '>=18'}
+
'@ioredis/commands@1.2.0':
resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==}
@@ -3199,6 +3236,10 @@ packages:
'@motionone/vue@10.16.2':
resolution: {integrity: sha512-7/dEK/nWQXOkJ70bqb2KyNfSWbNvWqKKq1C8juj+0Mg/AorgD8O5wE3naddK0G+aXuNMqRuc4jlsYHHWHtIzVw==}
+ '@mswjs/interceptors@0.29.1':
+ resolution: {integrity: sha512-3rDakgJZ77+RiQUuSK69t1F0m8BQKA8Vh5DCS5V0DWvNY67zob2JhhQrhCO0AKLGINTRSFd1tBaHcJTkhefoSw==}
+ engines: {node: '>=18'}
+
'@next/env@13.4.19':
resolution: {integrity: sha512-FsAT5x0jF2kkhNkKkukhsyYOrRqtSxrEhfliniIq0bwWbuXLgyt3Gv0Ml+b91XwjwArmuP7NxCiGd++GGKdNMQ==}
@@ -3304,6 +3345,15 @@ packages:
resolution: {integrity: sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+ '@open-draft/deferred-promise@2.2.0':
+ resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==}
+
+ '@open-draft/logger@0.3.0':
+ resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==}
+
+ '@open-draft/until@2.1.0':
+ resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==}
+
'@opentelemetry/api-logs@0.39.1':
resolution: {integrity: sha512-9BJ8lMcOzEN0lu+Qji801y707oFO4xT3db6cosPvl+k7ItUHKN5ofWqtSbM9gbt1H4JJ/4/2TVrqI9Rq7hNv6Q==}
engines: {node: '>=14'}
@@ -3543,6 +3593,9 @@ packages:
webpack-plugin-serve:
optional: true
+ '@polka/url@1.0.0-next.25':
+ resolution: {integrity: sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==}
+
'@protobufjs/aspromise@1.1.2':
resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==}
@@ -4243,6 +4296,10 @@ packages:
peerDependencies:
react: ^18.0.0
+ '@testing-library/dom@10.4.0':
+ resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==}
+ engines: {node: '>=18'}
+
'@testing-library/dom@9.3.1':
resolution: {integrity: sha512-0DGPd9AR3+iDTjGoMpxIkAsUihHZ3Ai6CneU6bRRrffXMgzCdlNk43jTrD2/5LT6CBb3MWTP8v510JzYtahD2w==}
engines: {node: '>=14'}
@@ -4442,6 +4499,9 @@ packages:
'@types/ms@0.7.34':
resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==}
+ '@types/mute-stream@0.0.4':
+ resolution: {integrity: sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==}
+
'@types/node@12.20.55':
resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==}
@@ -4460,8 +4520,8 @@ packages:
'@types/node@18.19.4':
resolution: {integrity: sha512-xNzlUhzoHotIsnFoXmJB+yWmBvFZgKCI9TtPIEdYIMM1KWfwuY8zh7wvc1u1OAXlC7dlf6mZVx/s+Y5KfFz19A==}
- '@types/node@20.12.12':
- resolution: {integrity: sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==}
+ '@types/node@20.14.12':
+ resolution: {integrity: sha512-r7wNXakLeSsGT0H1AU863vS2wa5wBOK4bWMjZz2wj+8nBx+m5PeIn0k8AloSLpRuiwdRQZwarZqHE4FNArPuJQ==}
'@types/normalize-package-data@2.4.1':
resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==}
@@ -4538,6 +4598,12 @@ packages:
'@types/stack-utils@2.0.3':
resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==}
+ '@types/statuses@2.0.5':
+ resolution: {integrity: sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==}
+
+ '@types/tough-cookie@4.0.5':
+ resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==}
+
'@types/trusted-types@2.0.3':
resolution: {integrity: sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==}
@@ -4550,6 +4616,9 @@ packages:
'@types/validate-npm-package-name@3.0.3':
resolution: {integrity: sha512-dLhCHEIjf9++/vHaHCo/ngJzGqGGbPh/f7HKwznEk3WFL64t/VKuRiVpyQH4afX93YkCV94I9M0Cx+DBLk1Dsg==}
+ '@types/wrap-ansi@3.0.0':
+ resolution: {integrity: sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==}
+
'@types/ws@8.5.5':
resolution: {integrity: sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==}
@@ -4701,6 +4770,21 @@ packages:
peerDependencies:
vite: ^4.2.0 || ^5.0.0
+ '@vitest/browser@2.0.4':
+ resolution: {integrity: sha512-QsIkbqPqHsXvgxjCjjgKjuWKmrC0VJgpaDkuEmOy5gTnErhhifWIfp3HpH92K7cscfaIao+RlKv5f8nUMgjfmA==}
+ peerDependencies:
+ playwright: '*'
+ safaridriver: '*'
+ vitest: 2.0.4
+ webdriverio: '*'
+ peerDependenciesMeta:
+ playwright:
+ optional: true
+ safaridriver:
+ optional: true
+ webdriverio:
+ optional: true
+
'@vitest/expect@2.0.4':
resolution: {integrity: sha512-39jr5EguIoanChvBqe34I8m1hJFI4+jxvdOpD7gslZrVQBKhh8H9eD7J/LJX4zakrw23W+dITQTDqdt43xVcJw==}
@@ -5619,6 +5703,14 @@ packages:
resolution: {integrity: sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==}
engines: {node: '>=6'}
+ cli-spinners@2.9.2:
+ resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==}
+ engines: {node: '>=6'}
+
+ cli-width@4.1.0:
+ resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==}
+ engines: {node: '>= 12'}
+
client-only@0.0.1:
resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
@@ -7034,6 +7126,11 @@ packages:
fs.realpath@1.0.0:
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
+ fsevents@2.3.2:
+ resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@@ -7178,6 +7275,10 @@ packages:
grapheme-splitter@1.0.4:
resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==}
+ graphql@16.9.0:
+ resolution: {integrity: sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==}
+ engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0}
+
gray-matter@4.0.3:
resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==}
engines: {node: '>=6.0'}
@@ -7275,6 +7376,9 @@ packages:
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
hasBin: true
+ headers-polyfill@4.0.3:
+ resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==}
+
hermes-estree@0.15.0:
resolution: {integrity: sha512-lLYvAd+6BnOqWdnNbP/Q8xfl8LOGw4wVjfrNd9Gt8eoFzhNBRVD95n4l2ksfMVOoxuVyegs85g83KS9QOsxbVQ==}
@@ -7672,6 +7776,9 @@ packages:
resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==}
engines: {node: '>= 0.4'}
+ is-node-process@1.2.0:
+ resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==}
+
is-number-object@1.0.7:
resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==}
engines: {node: '>= 0.4'}
@@ -8819,6 +8926,10 @@ packages:
resolution: {integrity: sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==}
engines: {node: '>=10'}
+ mrmime@2.0.0:
+ resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==}
+ engines: {node: '>=10'}
+
ms@2.0.0:
resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
@@ -8828,6 +8939,16 @@ packages:
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+ msw@2.3.4:
+ resolution: {integrity: sha512-sHMlwrajgmZSA2l1o7qRSe+azm/I+x9lvVVcOxAzi4vCtH8uVPJk1K5BQYDkzGl+tt0RvM9huEXXdeGrgcc79g==}
+ engines: {node: '>=18'}
+ hasBin: true
+ peerDependencies:
+ typescript: '>= 4.7.x'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
multicast-dns@7.2.5:
resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==}
hasBin: true
@@ -8835,6 +8956,10 @@ packages:
multiformats@9.9.0:
resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==}
+ mute-stream@1.0.0:
+ resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==}
+ engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+
mz@2.7.0:
resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
@@ -9194,6 +9319,9 @@ packages:
outdent@0.8.0:
resolution: {integrity: sha512-KiOAIsdpUTcAXuykya5fnVVT+/5uS0Q1mrkRHcF89tpieSmY33O/tmc54CqwA+bfhbtEfZUNLHaPUiB9X3jt1A==}
+ outvariant@1.4.3:
+ resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==}
+
p-event@4.2.0:
resolution: {integrity: sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==}
engines: {node: '>=8'}
@@ -9325,6 +9453,9 @@ packages:
path-to-regexp@0.1.7:
resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==}
+ path-to-regexp@6.2.2:
+ resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==}
+
path-type@4.0.0:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'}
@@ -9416,6 +9547,16 @@ packages:
resolution: {integrity: sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==}
engines: {node: '>=8'}
+ playwright-core@1.45.3:
+ resolution: {integrity: sha512-+ym0jNbcjikaOwwSZycFbwkWgfruWvYlJfThKYAlImbxUgdWFO2oW70ojPm4OpE4t6TAo2FY/smM+hpVTtkhDA==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ playwright@1.45.3:
+ resolution: {integrity: sha512-QhVaS+lpluxCaioejDZ95l4Y4jSFCsBvl2UZkpeXlzxmqS+aABr5c82YmfMHrL6x27nvrvykJAFpkzT2eWdJww==}
+ engines: {node: '>=18'}
+ hasBin: true
+
pngjs@5.0.0:
resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==}
engines: {node: '>=10.13.0'}
@@ -10706,6 +10847,10 @@ packages:
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
engines: {node: '>=14'}
+ sirv@2.0.4:
+ resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==}
+ engines: {node: '>= 10'}
+
sisteransi@1.0.5:
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
@@ -10875,6 +11020,9 @@ packages:
resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
engines: {node: '>=10.0.0'}
+ strict-event-emitter@0.5.1:
+ resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==}
+
strict-uri-encode@2.0.0:
resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==}
engines: {node: '>=4'}
@@ -11220,6 +11368,10 @@ packages:
toml@3.0.0:
resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==}
+ totalist@3.0.1:
+ resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
+ engines: {node: '>=6'}
+
tough-cookie@4.1.2:
resolution: {integrity: sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==}
engines: {node: '>=6'}
@@ -11228,6 +11380,10 @@ packages:
resolution: {integrity: sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==}
engines: {node: '>=6'}
+ tough-cookie@4.1.4:
+ resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==}
+ engines: {node: '>=6'}
+
tr46@0.0.3:
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
@@ -11342,6 +11498,10 @@ packages:
resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==}
engines: {node: '>=14.16'}
+ type-fest@4.23.0:
+ resolution: {integrity: sha512-ZiBujro2ohr5+Z/hZWHESLz3g08BBdrdLMieYFULJO+tWc437sn8kQsWLJoZErY8alNhxre9K4p3GURAG11n+w==}
+ engines: {node: '>=16'}
+
type-is@1.6.18:
resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==}
engines: {node: '>= 0.6'}
@@ -12126,6 +12286,18 @@ packages:
utf-8-validate:
optional: true
+ ws@8.18.0:
+ resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==}
+ engines: {node: '>=10.0.0'}
+ peerDependencies:
+ bufferutil: ^4.0.1
+ utf-8-validate: '>=5.0.2'
+ peerDependenciesMeta:
+ bufferutil:
+ optional: true
+ utf-8-validate:
+ optional: true
+
xml-name-validator@3.0.0:
resolution: {integrity: sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==}
@@ -12197,6 +12369,10 @@ packages:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
+ yoctocolors-cjs@2.1.2:
+ resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==}
+ engines: {node: '>=18'}
+
zod@3.21.4:
resolution: {integrity: sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==}
@@ -14426,6 +14602,19 @@ snapshots:
'@biomejs/cli-win32-x64@1.4.1':
optional: true
+ '@bundled-es-modules/cookie@2.0.0':
+ dependencies:
+ cookie: 0.5.0
+
+ '@bundled-es-modules/statuses@1.0.1':
+ dependencies:
+ statuses: 2.0.1
+
+ '@bundled-es-modules/tough-cookie@0.1.6':
+ dependencies:
+ '@types/tough-cookie': 4.0.5
+ tough-cookie: 4.1.4
+
'@changesets/apply-release-plan@7.0.0':
dependencies:
'@babel/runtime': 7.23.4
@@ -15850,6 +16039,33 @@ snapshots:
'@humanwhocodes/object-schema@1.2.1': {}
+ '@inquirer/confirm@3.1.17':
+ dependencies:
+ '@inquirer/core': 9.0.5
+ '@inquirer/type': 1.5.1
+
+ '@inquirer/core@9.0.5':
+ dependencies:
+ '@inquirer/figures': 1.0.5
+ '@inquirer/type': 1.5.1
+ '@types/mute-stream': 0.0.4
+ '@types/node': 20.14.12
+ '@types/wrap-ansi': 3.0.0
+ ansi-escapes: 4.3.2
+ cli-spinners: 2.9.2
+ cli-width: 4.1.0
+ mute-stream: 1.0.0
+ signal-exit: 4.1.0
+ strip-ansi: 6.0.1
+ wrap-ansi: 6.2.0
+ yoctocolors-cjs: 2.1.2
+
+ '@inquirer/figures@1.0.5': {}
+
+ '@inquirer/type@1.5.1':
+ dependencies:
+ mute-stream: 1.0.0
+
'@ioredis/commands@1.2.0': {}
'@isaacs/cliui@8.0.2':
@@ -16397,6 +16613,15 @@ snapshots:
'@motionone/dom': 10.16.2
tslib: 2.6.2
+ '@mswjs/interceptors@0.29.1':
+ dependencies:
+ '@open-draft/deferred-promise': 2.2.0
+ '@open-draft/logger': 0.3.0
+ '@open-draft/until': 2.1.0
+ is-node-process: 1.2.0
+ outvariant: 1.4.3
+ strict-event-emitter: 0.5.1
+
'@next/env@13.4.19': {}
'@next/env@14.2.3': {}
@@ -16489,6 +16714,15 @@ snapshots:
dependencies:
which: 3.0.1
+ '@open-draft/deferred-promise@2.2.0': {}
+
+ '@open-draft/logger@0.3.0':
+ dependencies:
+ is-node-process: 1.2.0
+ outvariant: 1.4.3
+
+ '@open-draft/until@2.1.0': {}
+
'@opentelemetry/api-logs@0.39.1':
dependencies:
'@opentelemetry/api': 1.8.0
@@ -16707,6 +16941,8 @@ snapshots:
type-fest: 3.13.1
webpack-dev-server: 4.15.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)(webpack@5.82.0(esbuild@0.20.2))
+ '@polka/url@1.0.0-next.25': {}
+
'@protobufjs/aspromise@1.1.2': {}
'@protobufjs/base64@1.1.2': {}
@@ -17292,7 +17528,7 @@ snapshots:
react-dom: 18.3.0(react@18.3.0)
react-native: 0.73.3(@babel/core@7.24.5)(@babel/preset-env@7.16.4(@babel/core@7.24.5))(bufferutil@4.0.8)(react@18.3.0)(utf-8-validate@5.0.10)
- '@remix-run/dev@2.9.2(@remix-run/react@2.9.2(react-dom@18.3.0(react@18.3.0))(react@18.3.0)(typescript@5.4.2))(@remix-run/serve@2.9.2(typescript@5.4.2))(@types/node@20.12.12)(babel-plugin-macros@3.1.0)(bufferutil@4.0.8)(terser@5.31.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(vite@5.2.11(@types/node@20.12.12)(terser@5.31.0))':
+ '@remix-run/dev@2.9.2(@remix-run/react@2.9.2(react-dom@18.3.0(react@18.3.0))(react@18.3.0)(typescript@5.4.2))(@remix-run/serve@2.9.2(typescript@5.4.2))(@types/node@20.14.12)(babel-plugin-macros@3.1.0)(bufferutil@4.0.8)(terser@5.31.0)(typescript@5.4.2)(utf-8-validate@5.0.10)(vite@5.2.11(@types/node@20.14.12)(terser@5.31.0))':
dependencies:
'@babel/core': 7.24.5
'@babel/generator': 7.24.5
@@ -17309,7 +17545,7 @@ snapshots:
'@remix-run/router': 1.16.1
'@remix-run/server-runtime': 2.9.2(typescript@5.4.2)
'@types/mdx': 2.0.5
- '@vanilla-extract/integration': 6.2.4(@types/node@20.12.12)(babel-plugin-macros@3.1.0)(terser@5.31.0)
+ '@vanilla-extract/integration': 6.2.4(@types/node@20.14.12)(babel-plugin-macros@3.1.0)(terser@5.31.0)
arg: 5.0.2
cacache: 17.1.4
chalk: 4.1.2
@@ -17351,7 +17587,7 @@ snapshots:
optionalDependencies:
'@remix-run/serve': 2.9.2(typescript@5.4.2)
typescript: 5.4.2
- vite: 5.2.11(@types/node@20.12.12)(terser@5.31.0)
+ vite: 5.2.11(@types/node@20.14.12)(terser@5.31.0)
transitivePeerDependencies:
- '@types/node'
- babel-plugin-macros
@@ -17793,6 +18029,17 @@ snapshots:
'@tanstack/query-core': 5.51.9
react: 18.3.0
+ '@testing-library/dom@10.4.0':
+ dependencies:
+ '@babel/code-frame': 7.24.2
+ '@babel/runtime': 7.24.5
+ '@types/aria-query': 5.0.1
+ aria-query: 5.3.0
+ chalk: 4.1.2
+ dom-accessibility-api: 0.5.16
+ lz-string: 1.5.0
+ pretty-format: 27.5.1
+
'@testing-library/dom@9.3.1':
dependencies:
'@babel/code-frame': 7.22.5
@@ -17804,7 +18051,7 @@ snapshots:
lz-string: 1.5.0
pretty-format: 27.5.1
- '@testing-library/jest-dom@6.2.0(@types/jest@29.5.12)(vitest@2.0.4(@types/node@18.19.4)(jsdom@23.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.0))':
+ '@testing-library/jest-dom@6.2.0(@types/jest@29.5.12)(vitest@2.0.4(@types/node@18.19.4)(@vitest/browser@2.0.4)(jsdom@23.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.0))':
dependencies:
'@adobe/css-tools': 4.3.2
'@babel/runtime': 7.23.4
@@ -17816,9 +18063,9 @@ snapshots:
redent: 3.0.0
optionalDependencies:
'@types/jest': 29.5.12
- vitest: 2.0.4(@types/node@18.19.4)(jsdom@23.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.0)
+ vitest: 2.0.4(@types/node@18.19.4)(@vitest/browser@2.0.4)(jsdom@23.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.0)
- '@testing-library/jest-dom@6.2.0(@types/jest@29.5.12)(vitest@2.0.4(@types/node@20.12.12)(jsdom@23.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.0))':
+ '@testing-library/jest-dom@6.2.0(@types/jest@29.5.12)(vitest@2.0.4(@types/node@20.14.12)(@vitest/browser@2.0.4)(jsdom@23.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.0))':
dependencies:
'@adobe/css-tools': 4.3.2
'@babel/runtime': 7.23.4
@@ -17830,7 +18077,7 @@ snapshots:
redent: 3.0.0
optionalDependencies:
'@types/jest': 29.5.12
- vitest: 2.0.4(@types/node@20.12.12)(jsdom@23.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.0)
+ vitest: 2.0.4(@types/node@20.14.12)(@vitest/browser@2.0.4)(jsdom@23.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.0)
'@testing-library/react@14.1.2(react-dom@18.3.0(react@18.3.0))(react@18.3.0)':
dependencies:
@@ -17840,9 +18087,9 @@ snapshots:
react: 18.3.0
react-dom: 18.3.0(react@18.3.0)
- '@testing-library/user-event@14.5.2(@testing-library/dom@9.3.1)':
+ '@testing-library/user-event@14.5.2(@testing-library/dom@10.4.0)':
dependencies:
- '@testing-library/dom': 9.3.1
+ '@testing-library/dom': 10.4.0
'@tootallnate/once@1.1.2': {}
@@ -18042,6 +18289,10 @@ snapshots:
'@types/ms@0.7.34': {}
+ '@types/mute-stream@0.0.4':
+ dependencies:
+ '@types/node': 18.19.33
+
'@types/node@12.20.55': {}
'@types/node@17.0.35': {}
@@ -18060,10 +18311,9 @@ snapshots:
dependencies:
undici-types: 5.26.5
- '@types/node@20.12.12':
+ '@types/node@20.14.12':
dependencies:
undici-types: 5.26.5
- optional: true
'@types/normalize-package-data@2.4.1': {}
@@ -18142,6 +18392,10 @@ snapshots:
'@types/stack-utils@2.0.3': {}
+ '@types/statuses@2.0.5': {}
+
+ '@types/tough-cookie@4.0.5': {}
+
'@types/trusted-types@2.0.3': {}
'@types/ua-parser-js@0.7.39': {}
@@ -18150,6 +18404,8 @@ snapshots:
'@types/validate-npm-package-name@3.0.3': {}
+ '@types/wrap-ansi@3.0.0': {}
+
'@types/ws@8.5.5':
dependencies:
'@types/node': 18.19.4
@@ -18324,7 +18580,7 @@ snapshots:
- supports-color
- terser
- '@vanilla-extract/integration@6.2.4(@types/node@20.12.12)(babel-plugin-macros@3.1.0)(terser@5.31.0)':
+ '@vanilla-extract/integration@6.2.4(@types/node@20.14.12)(babel-plugin-macros@3.1.0)(terser@5.31.0)':
dependencies:
'@babel/core': 7.24.5
'@babel/plugin-syntax-typescript': 7.24.1(@babel/core@7.24.5)
@@ -18337,8 +18593,8 @@ snapshots:
lodash: 4.17.21
mlly: 1.4.2
outdent: 0.8.0
- vite: 4.4.7(@types/node@20.12.12)(terser@5.31.0)
- vite-node: 0.28.5(@types/node@20.12.12)(terser@5.31.0)
+ vite: 4.4.7(@types/node@20.14.12)(terser@5.31.0)
+ vite-node: 0.28.5(@types/node@20.14.12)(terser@5.31.0)
transitivePeerDependencies:
- '@types/node'
- babel-plugin-macros
@@ -18375,9 +18631,34 @@ snapshots:
- supports-color
- terser
- '@vanilla-extract/next-plugin@2.4.0(@types/node@18.19.4)(babel-plugin-macros@3.1.0)(next@14.2.3(@babel/core@7.24.5)(@opentelemetry/api@1.8.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.0(react@18.3.0))(react@18.3.0))(terser@5.31.0)(webpack@5.82.0(esbuild@0.20.2))':
+ '@vanilla-extract/integration@7.1.4(@types/node@20.14.12)(babel-plugin-macros@3.1.0)(terser@5.31.0)':
+ dependencies:
+ '@babel/core': 7.24.5
+ '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.24.5)
+ '@vanilla-extract/babel-plugin-debug-ids': 1.0.5
+ '@vanilla-extract/css': 1.15.1(babel-plugin-macros@3.1.0)
+ dedent: 1.5.3(babel-plugin-macros@3.1.0)
+ esbuild: 0.19.9
+ eval: 0.1.8
+ find-up: 5.0.0
+ javascript-stringify: 2.1.0
+ mlly: 1.4.2
+ vite: 5.2.11(@types/node@20.14.12)(terser@5.31.0)
+ vite-node: 1.6.0(@types/node@20.14.12)(terser@5.31.0)
+ transitivePeerDependencies:
+ - '@types/node'
+ - babel-plugin-macros
+ - less
+ - lightningcss
+ - sass
+ - stylus
+ - sugarss
+ - supports-color
+ - terser
+
+ '@vanilla-extract/next-plugin@2.4.0(@types/node@20.14.12)(babel-plugin-macros@3.1.0)(next@14.2.3(@babel/core@7.24.5)(@opentelemetry/api@1.8.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.0(react@18.3.0))(react@18.3.0))(terser@5.31.0)(webpack@5.82.0(esbuild@0.20.2))':
dependencies:
- '@vanilla-extract/webpack-plugin': 2.3.8(@types/node@18.19.4)(babel-plugin-macros@3.1.0)(terser@5.31.0)(webpack@5.82.0(esbuild@0.20.2))
+ '@vanilla-extract/webpack-plugin': 2.3.8(@types/node@20.14.12)(babel-plugin-macros@3.1.0)(terser@5.31.0)(webpack@5.82.0(esbuild@0.20.2))
next: 14.2.3(@babel/core@7.24.5)(@opentelemetry/api@1.8.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.0(react@18.3.0))(react@18.3.0)
transitivePeerDependencies:
- '@types/node'
@@ -18422,9 +18703,9 @@ snapshots:
- supports-color
- terser
- '@vanilla-extract/webpack-plugin@2.3.8(@types/node@18.19.4)(babel-plugin-macros@3.1.0)(terser@5.31.0)(webpack@5.82.0(esbuild@0.20.2))':
+ '@vanilla-extract/webpack-plugin@2.3.8(@types/node@20.14.12)(babel-plugin-macros@3.1.0)(terser@5.31.0)(webpack@5.82.0(esbuild@0.20.2))':
dependencies:
- '@vanilla-extract/integration': 7.1.4(@types/node@18.19.4)(babel-plugin-macros@3.1.0)(terser@5.31.0)
+ '@vanilla-extract/integration': 7.1.4(@types/node@20.14.12)(babel-plugin-macros@3.1.0)(terser@5.31.0)
debug: 4.3.4
loader-utils: 2.0.4
picocolors: 1.0.0
@@ -18440,17 +18721,34 @@ snapshots:
- supports-color
- terser
- '@vitejs/plugin-react@4.2.1(vite@5.2.11(@types/node@20.12.12)(terser@5.31.0))':
+ '@vitejs/plugin-react@4.2.1(vite@5.2.11(@types/node@20.14.12)(terser@5.31.0))':
dependencies:
'@babel/core': 7.23.6
'@babel/plugin-transform-react-jsx-self': 7.23.3(@babel/core@7.23.6)
'@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.23.6)
'@types/babel__core': 7.20.5
react-refresh: 0.14.0
- vite: 5.2.11(@types/node@20.12.12)(terser@5.31.0)
+ vite: 5.2.11(@types/node@20.14.12)(terser@5.31.0)
transitivePeerDependencies:
- supports-color
+ '@vitest/browser@2.0.4(bufferutil@4.0.8)(playwright@1.45.3)(typescript@5.4.2)(utf-8-validate@5.0.10)(vitest@2.0.4)':
+ dependencies:
+ '@testing-library/dom': 10.4.0
+ '@testing-library/user-event': 14.5.2(@testing-library/dom@10.4.0)
+ '@vitest/utils': 2.0.4
+ magic-string: 0.30.10
+ msw: 2.3.4(typescript@5.4.2)
+ sirv: 2.0.4
+ vitest: 2.0.4(@types/node@20.14.12)(@vitest/browser@2.0.4)(jsdom@23.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.0)
+ ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)
+ optionalDependencies:
+ playwright: 1.45.3
+ transitivePeerDependencies:
+ - bufferutil
+ - typescript
+ - utf-8-validate
+
'@vitest/expect@2.0.4':
dependencies:
'@vitest/spy': 2.0.4
@@ -19842,6 +20140,10 @@ snapshots:
cli-spinners@2.9.0: {}
+ cli-spinners@2.9.2: {}
+
+ cli-width@4.1.0: {}
+
client-only@0.0.1: {}
clipanion@3.2.1(typanion@3.12.1):
@@ -21676,6 +21978,9 @@ snapshots:
fs.realpath@1.0.0: {}
+ fsevents@2.3.2:
+ optional: true
+
fsevents@2.3.3:
optional: true
@@ -21832,6 +22137,8 @@ snapshots:
grapheme-splitter@1.0.4: {}
+ graphql@16.9.0: {}
+
gray-matter@4.0.3:
dependencies:
js-yaml: 3.14.1
@@ -21972,6 +22279,8 @@ snapshots:
he@1.2.0: {}
+ headers-polyfill@4.0.3: {}
+
hermes-estree@0.15.0: {}
hermes-estree@0.20.1: {}
@@ -22368,6 +22677,8 @@ snapshots:
is-negative-zero@2.0.2: {}
+ is-node-process@1.2.0: {}
+
is-number-object@1.0.7:
dependencies:
has-tostringtag: 1.0.0
@@ -24131,12 +24442,36 @@ snapshots:
mrmime@1.0.1: {}
+ mrmime@2.0.0: {}
+
ms@2.0.0: {}
ms@2.1.2: {}
ms@2.1.3: {}
+ msw@2.3.4(typescript@5.4.2):
+ dependencies:
+ '@bundled-es-modules/cookie': 2.0.0
+ '@bundled-es-modules/statuses': 1.0.1
+ '@bundled-es-modules/tough-cookie': 0.1.6
+ '@inquirer/confirm': 3.1.17
+ '@mswjs/interceptors': 0.29.1
+ '@open-draft/until': 2.1.0
+ '@types/cookie': 0.6.0
+ '@types/statuses': 2.0.5
+ chalk: 4.1.2
+ graphql: 16.9.0
+ headers-polyfill: 4.0.3
+ is-node-process: 1.2.0
+ outvariant: 1.4.3
+ path-to-regexp: 6.2.2
+ strict-event-emitter: 0.5.1
+ type-fest: 4.23.0
+ yargs: 17.7.2
+ optionalDependencies:
+ typescript: 5.4.2
+
multicast-dns@7.2.5:
dependencies:
dns-packet: 5.6.0
@@ -24144,6 +24479,8 @@ snapshots:
multiformats@9.9.0: {}
+ mute-stream@1.0.0: {}
+
mz@2.7.0:
dependencies:
any-promise: 1.3.0
@@ -24529,6 +24866,8 @@ snapshots:
outdent@0.8.0: {}
+ outvariant@1.4.3: {}
+
p-event@4.2.0:
dependencies:
p-timeout: 3.2.0
@@ -24654,6 +24993,8 @@ snapshots:
path-to-regexp@0.1.7: {}
+ path-to-regexp@6.2.2: {}
+
path-type@4.0.0: {}
pathe@1.1.2: {}
@@ -24737,6 +25078,14 @@ snapshots:
dependencies:
find-up: 3.0.0
+ playwright-core@1.45.3: {}
+
+ playwright@1.45.3:
+ dependencies:
+ playwright-core: 1.45.3
+ optionalDependencies:
+ fsevents: 2.3.2
+
pngjs@5.0.0: {}
pony-cause@2.1.11: {}
@@ -26282,6 +26631,12 @@ snapshots:
signal-exit@4.1.0: {}
+ sirv@2.0.4:
+ dependencies:
+ '@polka/url': 1.0.0-next.25
+ mrmime: 2.0.0
+ totalist: 3.0.1
+
sisteransi@1.0.5: {}
siwe@2.1.4(ethers@5.6.8(bufferutil@4.0.8)(utf-8-validate@5.0.10)):
@@ -26469,6 +26824,8 @@ snapshots:
streamsearch@1.1.0: {}
+ strict-event-emitter@0.5.1: {}
+
strict-uri-encode@2.0.0: {}
string-hash@1.1.3: {}
@@ -26857,10 +27214,12 @@ snapshots:
toml@3.0.0: {}
+ totalist@3.0.1: {}
+
tough-cookie@4.1.2:
dependencies:
psl: 1.9.0
- punycode: 2.3.0
+ punycode: 2.3.1
universalify: 0.2.0
url-parse: 1.5.10
@@ -26871,6 +27230,13 @@ snapshots:
universalify: 0.2.0
url-parse: 1.5.10
+ tough-cookie@4.1.4:
+ dependencies:
+ psl: 1.9.0
+ punycode: 2.3.1
+ universalify: 0.2.0
+ url-parse: 1.5.10
+
tr46@0.0.3: {}
tr46@1.0.1:
@@ -26879,7 +27245,7 @@ snapshots:
tr46@2.1.0:
dependencies:
- punycode: 2.3.0
+ punycode: 2.3.1
tr46@5.0.0:
dependencies:
@@ -26963,6 +27329,8 @@ snapshots:
type-fest@3.13.1: {}
+ type-fest@4.23.0: {}
+
type-is@1.6.18:
dependencies:
media-typer: 0.3.0
@@ -27316,7 +27684,7 @@ snapshots:
- utf-8-validate
- zod
- vite-node@0.28.5(@types/node@20.12.12)(terser@5.31.0):
+ vite-node@0.28.5(@types/node@20.14.12)(terser@5.31.0):
dependencies:
cac: 6.7.14
debug: 4.3.5
@@ -27325,7 +27693,7 @@ snapshots:
picocolors: 1.0.1
source-map: 0.6.1
source-map-support: 0.5.21
- vite: 4.4.7(@types/node@20.12.12)(terser@5.31.0)
+ vite: 4.4.7(@types/node@20.14.12)(terser@5.31.0)
transitivePeerDependencies:
- '@types/node'
- less
@@ -27353,6 +27721,23 @@ snapshots:
- supports-color
- terser
+ vite-node@1.6.0(@types/node@20.14.12)(terser@5.31.0):
+ dependencies:
+ cac: 6.7.14
+ debug: 4.3.5
+ pathe: 1.1.2
+ picocolors: 1.0.0
+ vite: 5.2.11(@types/node@20.14.12)(terser@5.31.0)
+ transitivePeerDependencies:
+ - '@types/node'
+ - less
+ - lightningcss
+ - sass
+ - stylus
+ - sugarss
+ - supports-color
+ - terser
+
vite-node@2.0.4(@types/node@18.19.4)(terser@5.31.0):
dependencies:
cac: 6.7.14
@@ -27370,13 +27755,13 @@ snapshots:
- supports-color
- terser
- vite-node@2.0.4(@types/node@20.12.12)(terser@5.31.0):
+ vite-node@2.0.4(@types/node@20.14.12)(terser@5.31.0):
dependencies:
cac: 6.7.14
debug: 4.3.5
pathe: 1.1.2
tinyrainbow: 1.2.0
- vite: 5.2.11(@types/node@20.12.12)(terser@5.31.0)
+ vite: 5.2.11(@types/node@20.14.12)(terser@5.31.0)
transitivePeerDependencies:
- '@types/node'
- less
@@ -27387,13 +27772,13 @@ snapshots:
- supports-color
- terser
- vite@4.4.7(@types/node@20.12.12)(terser@5.31.0):
+ vite@4.4.7(@types/node@20.14.12)(terser@5.31.0):
dependencies:
esbuild: 0.18.17
postcss: 8.4.38
rollup: 3.26.3
optionalDependencies:
- '@types/node': 20.12.12
+ '@types/node': 20.14.12
fsevents: 2.3.3
terser: 5.31.0
@@ -27407,17 +27792,17 @@ snapshots:
fsevents: 2.3.3
terser: 5.31.0
- vite@5.2.11(@types/node@20.12.12)(terser@5.31.0):
+ vite@5.2.11(@types/node@20.14.12)(terser@5.31.0):
dependencies:
esbuild: 0.20.2
postcss: 8.4.38
rollup: 4.17.2
optionalDependencies:
- '@types/node': 20.12.12
+ '@types/node': 20.14.12
fsevents: 2.3.3
terser: 5.31.0
- vitest@2.0.4(@types/node@18.19.4)(jsdom@23.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.0):
+ vitest@2.0.4(@types/node@18.19.4)(@vitest/browser@2.0.4)(jsdom@23.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.0):
dependencies:
'@ampproject/remapping': 2.3.0
'@vitest/expect': 2.0.4
@@ -27440,6 +27825,7 @@ snapshots:
why-is-node-running: 2.3.0
optionalDependencies:
'@types/node': 18.19.4
+ '@vitest/browser': 2.0.4(bufferutil@4.0.8)(playwright@1.45.3)(typescript@5.4.2)(utf-8-validate@5.0.10)(vitest@2.0.4)
jsdom: 23.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)
transitivePeerDependencies:
- less
@@ -27450,7 +27836,7 @@ snapshots:
- supports-color
- terser
- vitest@2.0.4(@types/node@20.12.12)(jsdom@23.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.0):
+ vitest@2.0.4(@types/node@20.14.12)(@vitest/browser@2.0.4)(jsdom@23.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(terser@5.31.0):
dependencies:
'@ampproject/remapping': 2.3.0
'@vitest/expect': 2.0.4
@@ -27468,11 +27854,12 @@ snapshots:
tinybench: 2.8.0
tinypool: 1.0.0
tinyrainbow: 1.2.0
- vite: 5.2.11(@types/node@20.12.12)(terser@5.31.0)
- vite-node: 2.0.4(@types/node@20.12.12)(terser@5.31.0)
+ vite: 5.2.11(@types/node@20.14.12)(terser@5.31.0)
+ vite-node: 2.0.4(@types/node@20.14.12)(terser@5.31.0)
why-is-node-running: 2.3.0
optionalDependencies:
- '@types/node': 20.12.12
+ '@types/node': 20.14.12
+ '@vitest/browser': 2.0.4(bufferutil@4.0.8)(playwright@1.45.3)(typescript@5.4.2)(utf-8-validate@5.0.10)(vitest@2.0.4)
jsdom: 23.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)
transitivePeerDependencies:
- less
@@ -27977,6 +28364,11 @@ snapshots:
bufferutil: 4.0.8
utf-8-validate: 5.0.10
+ ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10):
+ optionalDependencies:
+ bufferutil: 4.0.8
+ utf-8-validate: 5.0.10
+
xml-name-validator@3.0.0: {}
xml-name-validator@5.0.0: {}
@@ -28046,6 +28438,8 @@ snapshots:
yocto-queue@0.1.0: {}
+ yoctocolors-cjs@2.1.2: {}
+
zod@3.21.4: {}
zustand@3.7.2(react@18.3.0):
diff --git a/vitest.config.ts b/vitest.config.ts
index 0de8a6bc0c..423db2bbfc 100644
--- a/vitest.config.ts
+++ b/vitest.config.ts
@@ -22,5 +22,12 @@ export default {
globals: true,
setupFiles: ['./packages/rainbowkit/test/setup.ts'],
watch: false,
+ browser: {
+ provider: 'playwright',
+ name: 'chromium',
+ enabled: true,
+ headless: true,
+ screenshotFailures: false,
+ },
},
};