Add RainbowKit to Your Nexus SDK Project
PREREQUISITE
This tutorial assumes you have already completed the basic Nexus SDK tutorial.
If you haven’t, please go through that first to set up your base project.
What You’ll Learn
By the end of this tutorial you will have:
- Enhanced your existing Nexus SDK project with RainbowKit
- Improved the wallet connection experience with better UI
- Added support for multiple wallet providers
- Maintained all existing Nexus SDK functionality
Check out the RainbowKit docs for latest information on how to use and customize it.
Install RainbowKit Dependencies
Navigate to the root of your project that you created in the basic Nexus SDK tutorial.
Add the required packages to your existing project:
pnpm add @rainbow-me/rainbowkit wagmi viem @tanstack/react-query
Configure RainbowKit
1. Create Wagmi Configuration
Create a new file at src/lib/wagmi.ts
:
import { getDefaultConfig } from '@rainbow-me/rainbowkit';
import { mainnet, arbitrum, polygon, optimism, base, avalanche } from 'wagmi/chains';
export const config = getDefaultConfig({
appName: 'Nexus SDK with RainbowKit',
projectId: 'YOUR_PROJECT_ID', // Get this from https://cloud.walletconnect.com/
chains: [mainnet, arbitrum, polygon, optimism, base, avalanche],
ssr: true, // If your dApp uses server side rendering (SSR)
});
You need to get a Project ID from WalletConnect Cloud for RainbowKit to work properly. This is free and only takes a few minutes to set up.
2. Create Providers Component
Create a new file at src/components/providers.tsx
:
'use client';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { WagmiProvider } from 'wagmi';
import { RainbowKitProvider } from '@rainbow-me/rainbowkit';
import { config } from '@/lib/wagmi';
import '@rainbow-me/rainbowkit/styles.css';
const queryClient = new QueryClient();
export function Providers({ children }: { children: React.ReactNode }) {
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
<RainbowKitProvider>
{children}
</RainbowKitProvider>
</QueryClientProvider>
</WagmiProvider>
);
}
3. Update Layout
Update your src/app/layout.tsx
to wrap your app with the providers:
import { Providers } from '@/components/providers';
import './globals.css';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<Providers>
{children}
</Providers>
</body>
</html>
);
}
Update Your Components
1. Replace Connect Button
Update your src/components/connect-button.tsx
to use RainbowKit:
'use client';
import { ConnectButton } from '@rainbow-me/rainbowkit';
export default function ConnectWalletButton({ className }: { className?: string }) {
return (
<ConnectButton.Custom>
{({
account,
chain,
openAccountModal,
openChainModal,
openConnectModal,
authenticationStatus,
mounted,
}) => {
const ready = mounted && authenticationStatus !== 'loading';
const connected =
ready &&
account &&
chain &&
(!authenticationStatus ||
authenticationStatus === 'authenticated');
return (
<div
{...(!ready && {
'aria-hidden': 'true',
'style': {
opacity: 0,
pointerEvents: 'none',
userSelect: 'none',
},
})}
>
{(() => {
if (!connected) {
return (
<button className={className} onClick={openConnectModal} type="button">
Connect Wallet
</button>
);
}
if (chain.unsupported) {
return (
<button className={className} onClick={openChainModal} type="button">
Wrong network
</button>
);
}
return (
<div style={{ display: 'flex', gap: 12 }}>
<button
className={className}
onClick={openChainModal}
style={{ display: 'flex', alignItems: 'center' }}
type="button"
>
{chain.hasIcon && (
<div
style={{
background: chain.iconBackground,
width: 12,
height: 12,
borderRadius: 999,
overflow: 'hidden',
marginRight: 4,
}}
>
{chain.iconUrl && (
<img
alt={chain.name ?? 'Chain icon'}
src={chain.iconUrl}
style={{ width: 12, height: 12 }}
/>
)}
</div>
)}
{chain.name}
</button>
<button className={className} onClick={openAccountModal} type="button">
{account.displayName}
{account.displayBalance
? ` (${account.displayBalance})`
: ''}
</button>
</div>
);
})()}
</div>
);
}}
</ConnectButton.Custom>
);
}
2. Update Init Button
Update your src/components/init-button.tsx
to use Wagmi’s connector:
'use client';
import { useAccount } from 'wagmi';
import { initializeWithProvider, isInitialized } from '../lib/nexus';
export default function InitButton({
className,
onReady,
}: { className?: string; onReady?: () => void }) {
const { connector } = useAccount();
const onClick = async () => {
try {
// Get the provider from the connected wallet
const provider = await connector?.getProvider();
if (!provider) throw new Error('No provider found');
// We're calling our wrapper function from the lib/nexus.ts file here.
await initializeWithProvider(provider);
onReady?.();
alert('Nexus initialized');
} catch (e: any) {
alert(e?.message ?? 'Init failed');
}
};
return <button className={className} onClick={onClick} disabled={isInitialized()}>Initialize Nexus</button>;
}
The lines of interest for us is majorly what’s here below:
const provider = await connector?.getProvider();
if (!provider) throw new Error('No provider found');
// We're calling our wrapper function from the lib/nexus.ts file here.
await initializeWithProvider(provider);
- Since RainbowKit uses
wagmi
, you can easily get the EIP-1193 Provider of your connected wallet withuseAccount
- Here, we import
useAccount
hook fromwagmi
, and get theconnector
property from which we can callgetProvider()
which returns the EIP-1193 Provider for the connected wallet. This makes it very easy for any RainbowKit connected wallet to initialize the Nexus SDK and unlock crosschain features. - Once we have the
provider
, we can pass it into our helper function to initialize Nexus.
3. Update Main Page
Update your src/app/page.tsx
to show wallet connection status:
'use client';
import { useState } from 'react';
import { useAccount } from 'wagmi';
import ConnectWalletButton from '@/components/connect-button';
import InitButton from '@/components/init-button';
import FetchUnifiedBalanceButton from '@/components/fetch-unified-balance-button';
import DeinitButton from '@/components/de-init-button';
import { isInitialized } from '@/lib/nexus';
export default function Page() {
const { isConnected } = useAccount();
const [initialized, setInitialized] = useState(isInitialized());
const [balances, setBalances] = useState<any>(null);
const btn =
'px-4 py-2 rounded-md bg-blue-600 text-white hover:bg-blue-700 ' +
'disabled:opacity-50 disabled:cursor-not-allowed';
return (
<main className="min-h-screen flex items-center justify-center">
<div className="flex flex-col items-center gap-4">
<ConnectWalletButton className={btn} />
<InitButton className={btn} onReady={() => setInitialized(true)} />
<FetchUnifiedBalanceButton className={btn} onResult={(r) => setBalances(r)} />
<DeinitButton className={btn} onDone={() => { setInitialized(false); setBalances(null); }} />
<div className="mt-2">
<b>Wallet Status:</b> {isConnected ? 'Connected' : 'Not connected'}
</div>
<div className="mt-2">
<b>Nexus SDK Initialization Status:</b> {initialized ? 'Initialized' : 'Not initialized'}
</div>
{balances && (
<pre className="whitespace-pre-wrap">{JSON.stringify(balances, null, 2)}</pre>
)}
</div>
</main>
);
}
What Changed?
The only changes from your basic tutorial are:
- Added RainbowKit packages - 4 new dependencies
- Created Wagmi config - Chain and app configuration
- Added providers - RainbowKit and Wagmi providers
- Updated connect button - Now uses RainbowKit’s ConnectButton
- Updated init button - Uses Wagmi’s connector instead of window.ethereum
- Added wallet status - Shows connection status
Everything else stays exactly the same! Your Nexus SDK setup, balance fetching, and de-initialization all work identically.
Next Steps
Your Nexus SDK project now has a much better wallet connection experience while maintaining all the same functionality. You can continue building with the same Nexus SDK methods you learned in the basic tutorial!
Want to learn more?
Check out the RainbowKit documentation for more customization options and advanced features.