Add to Existing Next.js Project (with Wagmi)
This option guides you through adding Smart Wallet to an existing Next.js application using Wagmi.
Step 1: Install Dependencies
Let's start by navigating to your project directory and installing the dependencies:
npm
npm install @coinbase/wallet-sdk wagmi viem @tanstack/react-query
Step 2: Create Wagmi Config
If your project does not have a Wagmi Config, create a file called wagmi.ts
in the root directory of your project:
import { http, createConfig } from "wagmi";
import { baseSepolia } from "wagmi/chains";
import { coinbaseWallet } from "wagmi/connectors";
export const cbWalletConnector = coinbaseWallet({
appName: "Wagmi Smart Wallet",
preference: "smartWalletOnly",
});
export const config = createConfig({
chains: [baseSepolia],
// turn off injected provider discovery
multiInjectedProviderDiscovery: false,
connectors: [cbWalletConnector],
ssr: true,
transports: {
[baseSepolia.id]: http(),
},
});
declare module "wagmi" {
interface Register {
config: typeof config;
}
}
Step 3: Create Providers Component
Create a file called providers.tsx
in your app/
directory:
"use client";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { useState, type ReactNode } from "react";
import { WagmiProvider } from "wagmi";
import { config } from "@/wagmi";
export function Providers(props: { children: ReactNode }) {
const [queryClient] = useState(() => new QueryClient());
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
{props.children}
</QueryClientProvider>
</WagmiProvider>
);
}
Step 4: Add Providers to Root Layout
Update your root layout file (app/layout.tsx
):
import "./globals.css";
import type { Metadata } from "next";
import type { ReactNode } from "react";
import { Providers } from "./providers";
export const metadata: Metadata = {
title: "Smart Wallet App",
description: "Smart Wallet Next.js integration",
};
export default function RootLayout(props: { children: ReactNode }) {
return (
<html lang="en">
<body>
<Providers>{props.children}</Providers>
</body>
</html>
);
}
Step 5: Create ConnectAndSIWE
Component
Create a component for wallet connection and Sign-In With Ethereum (SIWE):
import { useCallback, useEffect, useState } from "react";
import type { Hex } from "viem";
import { useAccount, useConnect, usePublicClient, useSignMessage } from "wagmi";
import { SiweMessage } from "siwe";
import { cbWalletConnector } from "@/wagmi";
export function ConnectAndSIWE() {
const { connect } = useConnect({
mutation: {
onSuccess: (data) => {
const address = data.accounts[0];
const chainId = data.chainId;
const m = new SiweMessage({
domain: document.location.host,
address,
chainId,
uri: document.location.origin,
version: "1",
statement: "Smart Wallet SIWE Example",
nonce: "12345678",
});
setMessage(m);
signMessage({ message: m.prepareMessage() });
},
},
});
const account = useAccount();
const client = usePublicClient();
const [signature, setSignature] = useState<Hex | undefined>(undefined);
const { signMessage } = useSignMessage({
mutation: { onSuccess: (sig) => setSignature(sig) },
});
const [message, setMessage] = useState<SiweMessage | undefined>(undefined);
const [valid, setValid] = useState<boolean | undefined>(undefined);
const checkValid = useCallback(async () => {
if (!signature || !account.address || !client || !message) return;
client
.verifyMessage({
address: account.address,
message: message.prepareMessage(),
signature,
})
.then((v) => setValid(v));
}, [signature, account]);
useEffect(() => {
checkValid();
}, [signature, account]);
useEffect(() => {});
return (
<div>
<button onClick={() => connect({ connector: cbWalletConnector })}>
Connect + SIWE
</button>
<p>{}</p>
{valid != undefined && <p> Is valid: {valid.toString()} </p>}
</div>
);
}
Step 6: Use the Component in a Page
Add the component to app/page.tsx
:
import { ConnectAndSIWE } from '../components/ConnectAndSIWE'
export default function Home() {
return (
<main>
<h1>Smart Wallet Integration</h1>
<ConnectAndSIWE />
</main>
)
}