feat(bridge): migrate rainbowkit to reown#293
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
181a591 to
72a7bf0
Compare
There was a problem hiding this comment.
Pull request overview
This PR migrates wallet-connection UX and configuration from RainbowKit to Reown AppKit across both the bridge UI and the main app shell, along with related dependency/config updates.
Changes:
- Replace RainbowKit usage (
ConnectButton,useConnectModal, wallet lists/config) with Reown AppKit + WagmiAdapter, and introduce a shareduseWalletModalhook. - Refactor chain/network setup and wallet analytics tagging to use AppKit (
useWalletInfo) and updatedwagmi/viemversions. - Update TypeScript target to
es2020and adjust app layouts/providers to remove RainbowKit styling/providers.
Reviewed changes
Copilot reviewed 23 out of 24 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| yarn.lock | Updates/realigns dependency graph for AppKit + wagmi/viem changes. |
| tsconfig.base.json | Bumps TS compilation target to ES2020. |
| packages/arb-token-bridge-ui/src/wallet/hooks/useWalletModal.ts | Adds AppKit-based connect modal helper. |
| packages/arb-token-bridge-ui/src/util/walletConnectUtils.ts | Removes WalletConnect v2 disconnect cleanup helper. |
| packages/arb-token-bridge-ui/src/util/wagmi/wagmiAdditionalNetworks.ts | Switches Chain typing to viem. |
| packages/arb-token-bridge-ui/src/util/wagmi/setup.ts | Replaces RainbowKit config with AppKit + WagmiAdapter initialization and exports wagmiConfig. |
| packages/arb-token-bridge-ui/src/util/AnalyticsUtils.ts | Loosens wallet name typing for connect event payload. |
| packages/arb-token-bridge-ui/src/hooks/useAccountType.ts | Adds optional chainId override for account type resolution. |
| packages/arb-token-bridge-ui/src/hooks/useAccountMenu.ts | Removes RainbowKit/WC disconnect integration. |
| packages/arb-token-bridge-ui/src/components/Widget/WidgetHeaderAccountButton.tsx | Uses useWalletModal + disconnectAsync instead of RainbowKit modal. |
| packages/arb-token-bridge-ui/src/components/TransferPanel/ConnectWalletButton.tsx | Uses useWalletModal instead of RainbowKit. |
| packages/arb-token-bridge-ui/src/components/TransactionHistory/TransactionsTableRowAction.tsx | Replaces RainbowKit ConnectButton.Custom with AppKit modal hook. |
| packages/arb-token-bridge-ui/src/components/App/useSyncConnectedChainToQueryParams.ts | Refactors SCW chain-sync behavior; removes disconnect/reload path. |
| packages/arb-token-bridge-ui/src/components/App/useSyncConnectedChainToAnalytics.ts | Uses AppKit wallet metadata instead of wagmi connector name mapping. |
| packages/arb-token-bridge-ui/package.json | Swaps RainbowKit dependency for AppKit + updates wagmi/viem. |
| packages/app/src/components/earn/YourHoldingsEmptyState.tsx | Uses bridge useWalletModal for connect action. |
| packages/app/src/components/earn/EarnActionPanel/EarnActionSubmitButton.tsx | Uses useWalletModal instead of RainbowKit ConnectButton.Custom. |
| packages/app/src/components/AppShell/providers/wagmi/setup.ts | Removes now-obsolete re-export shim. |
| packages/app/src/components/AppShell/providers/AppProviders.tsx | Drops RainbowKit provider/theme; uses bridge wagmiConfig. |
| packages/app/src/components/AppShell/components/NavWallet.tsx | Replaces RainbowKit ConnectButton.Custom with wagmi + useWalletModal. |
| packages/app/src/app/layout.tsx | Removes RainbowKit styles; adds AppKit-related font CSS variables. |
| packages/app/src/app/(with-sidebar)/bridge/layout.tsx | Removes RainbowKit styles import. |
| packages/app/src/app/(embed)/bridge/embed/layout.tsx | Removes RainbowKit styles import. |
| packages/app/package.json | Removes RainbowKit and adds AppKit-related dependencies + bumps wagmi/viem. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| )} | ||
|
|
||
| <button onClick={() => disconnect()} className={MENU_ITEM_BUTTON_CLASSES}> | ||
| <button onClick={() => disconnectAsync()} className={MENU_ITEM_BUTTON_CLASSES}> |
There was a problem hiding this comment.
disconnectAsync() is called without awaiting/handling errors. If it rejects, it can result in an unhandled promise rejection in the browser. Consider using void disconnectAsync().catch(...) (or wrapping in an async handler with try/catch).
| <button onClick={() => disconnectAsync()} className={MENU_ITEM_BUTTON_CLASSES}> | |
| <button | |
| onClick={() => { | |
| void disconnectAsync().catch((error) => { | |
| console.error('Failed to disconnect wallet', error); | |
| }); | |
| }} | |
| className={MENU_ITEM_BUTTON_CLASSES} | |
| > |
| const projectId = process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID!; | ||
|
|
||
| if (!projectId) { | ||
| logger.error('NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID variable missing.'); | ||
| } | ||
|
|
There was a problem hiding this comment.
projectId is asserted as non-null (process.env...!) but execution continues even when it’s missing (only logs an error). This can pass an invalid projectId into WagmiAdapter / createAppKit and crash at runtime. Consider failing fast (throw) or skipping initialization when NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID is not set.
| useEffect(() => { | ||
| if (isConnected && connector) { | ||
| const walletName = getWalletName(connector.name); | ||
| if (isConnected) { | ||
| const walletName = walletInfo?.name ?? 'Other'; | ||
| trackEvent('Connect Wallet Click', { walletName }); | ||
|
|
There was a problem hiding this comment.
This effect will fire once when isConnected flips true (often before walletInfo is populated) and then again when walletInfo?.name becomes available, which can double-log the 'Connect Wallet Click' event. Consider gating the event to only run once per connection (e.g., track the last connected session/address in a ref) or only firing when walletInfo?.name is defined.
| const openConnectModal = useCallback(async () => { | ||
| await switchNetwork(networks.sourceChain); | ||
| await open({ view: 'Connect', namespace: 'eip155' }); |
There was a problem hiding this comment.
openConnectModal is an async callback that awaits switchNetwork and open but doesn’t handle errors. When used directly as an onClick handler throughout the UI, any rejection can become an unhandled promise rejection. Consider wrapping the body in try/catch (and possibly returning a non-async function that internally voids the async work) so UI callers don’t need to remember to handle failures.
| const openConnectModal = useCallback(async () => { | |
| await switchNetwork(networks.sourceChain); | |
| await open({ view: 'Connect', namespace: 'eip155' }); | |
| const openConnectModal = useCallback(() => { | |
| void (async () => { | |
| try { | |
| await switchNetwork(networks.sourceChain); | |
| await open({ view: 'Connect', namespace: 'eip155' }); | |
| } catch (error) { | |
| console.error('Failed to open connect modal.', error); | |
| } | |
| })(); |
| variant="secondary" | ||
| className="flex w-full items-center justify-center border-none bg-white/5" | ||
| onClick={() => disconnect()} | ||
| onClick={() => disconnectAsync()} |
There was a problem hiding this comment.
disconnectAsync() returns a promise and is invoked without awaiting/handling errors. If the disconnect mutation rejects, this can surface as an unhandled promise rejection. Consider using void disconnectAsync().catch(...) (or a small async handler with try/catch) to keep failures contained.
| onClick={() => disconnectAsync()} | |
| onClick={() => { | |
| void disconnectAsync().catch(() => {}); | |
| }} |
1e945fb to
5b700e6
Compare
Summary
Steps to test