Initializing Nexus with RainbowKit
Replace window.ethereum with RainbowKit for a polished wallet connection experience.
In this guide you will add RainbowKit to an existing Nexus SDK project and retrieve the EIP-1193 provider from wagmi's connector instead of
Everything else — the SDK instance, helper functions, balance fetching, and de-initialization — stays exactly the same.
Add the required packages to your project:
Create a config file that defines the supported chains and your WalletConnect project ID.
src/lib/wagmi.ts
Wrap your app with wagmi, React Query, and RainbowKit providers.
src/components/providers.tsx
Wrap your root layout with the new providers component:
src/app/layout.tsx
Replace the manual src/components/connect-button.tsx
The key change: instead of reading src/components/init-button.tsx
Add wallet status display using wagmi's src/app/page.tsx
Your project now has a production-quality wallet connection experience. Next, add cross-chain bridging functionality.
window.ethereum. By the end you will have a full wallet connection modal, multi-wallet support, and all existing SDK functionality intact.
What changes
| Before (basic setup) | After (RainbowKit) |
|---|---|
window.ethereum for wallet connection | RainbowKit modal with multi-wallet support |
Manual eth_requestAccounts call | wagmi handles connection state |
| Single injected provider only | WalletConnect, Coinbase, and more |
Step 1 — Install RainbowKit dependencies
pnpm add @rainbow-me/rainbowkit wagmi viem @tanstack/react-query
Step 2 — Create the wagmi configuration
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: process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID!,
chains: [mainnet, arbitrum, polygon, optimism, base, avalanche],
ssr: true,
});WalletConnect Project ID required
Get a free Project ID at cloud.walletconnect.com. Add it to your
.env.local as NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID.Step 3 — Create the providers component
"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>
);
}Step 4 — Update the layout
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>
);
}Step 5 — Update the connect button
window.ethereum approach with RainbowKit's ConnectButton:
"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>
);
}Step 6 — Update the init button
window.ethereum, use wagmi's useAccount hook to get the provider from the connected wallet's connector.
"use client";
import { useAccount } from "wagmi";
import { initializeWithProvider, client } from "../lib/nexus";
export default function InitButton({
className,
onReady,
}: {
className?: string;
onReady?: () => void;
}) {
const { connector } = useAccount();
const onClick = async () => {
try {
const provider = await connector?.getProvider();
if (!provider) throw new Error("No provider found");
await initializeWithProvider(provider);
onReady?.();
alert("Nexus initialized");
} catch (e: any) {
alert(e?.message ?? "Init failed");
}
};
return (
<button
className={className}
onClick={onClick}
disabled={client.hasEvmProvider}
>
Initialize Nexus
</button>
);
}How the provider retrieval works
const { connector } = useAccount();
const provider = await connector?.getProvider();
await initializeWithProvider(provider);useAccount()— wagmi hook that returns the current connection state and active connectorconnector.getProvider()— returns the EIP-1193 provider for whichever wallet the user connected (MetaMask, WalletConnect, Coinbase, etc.)initializeWithProvider(provider)— your existing helper function runsclient.initialize()and then passes the provider toclient.setEVMProvider()
Step 7 — Update the main page
useAccount hook:
"use client";
import { useState } from "react";
import { useAccount } from "wagmi";
import ConnectWalletButton from "@/components/connect-button";
import InitButton from "@/components/init-button";
import FetchBalancesButton from "@/components/fetch-balances-button";
import DeinitButton from "@/components/de-init-button";
import { client } from "@/lib/nexus";
export default function Page() {
const { isConnected } = useAccount();
const [initialized, setInitialized] = useState(client.hasEvmProvider);
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)}
/>
<FetchBalancesButton
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>SDK Status:</b>{" "}
{initialized ? "Initialized" : "Not initialized"}
</div>
{balances && (
<pre className="whitespace-pre-wrap">
{JSON.stringify(balances, null, 2)}
</pre>
)}
</div>
</main>
);
}Summary of changes
| File | What changed |
|---|---|
src/lib/wagmi.ts | New — wagmi + RainbowKit config |
src/components/providers.tsx | New — provider wrapper component |
src/app/layout.tsx | Wrapped with Providers |
src/components/connect-button.tsx | Replaced window.ethereum with RainbowKit ConnectButton.Custom |
src/components/init-button.tsx | Replaced window.ethereum with connector.getProvider() from wagmi |
src/app/page.tsx | Added useAccount for wallet status display |
src/lib/nexus.ts | No changes — SDK setup is the same |
Next step
How is this guide?
What changesStep 1 — Install RainbowKit dependenciesStep 2 — Create the wagmi configurationStep 3 — Create the providers componentStep 4 — Update the layoutStep 5 — Update the connect buttonStep 6 — Update the init buttonHow the provider retrieval worksStep 7 — Update the main pageSummary of changesNext step