How to use Privy signer with Biconomy
Privy is a platform that provides user onboarding and embedded wallet infrastructure for applications built on blockchain technology.
Read below to learn how to configure your app to create Nexus smart accounts for all your users using Privy signers.
Install the dependencies
npm i @privy-io/react-auth @biconomy/sdk viem @tanstack/react-query
Wrap your app with the PrivyProvider
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { type ReactNode, useState } from 'react'
import { PrivyProvider } from '@privy-io/react-auth';
export function App {
const [queryClient] = useState(() => new QueryClient())
return (
<PrivyProvider
appId="APP_ID"
config={{
/* Replace this with your desired login methods */
loginMethods: ['email', 'wallet'],
/* Replace this with your desired appearance configuration */
appearance: {
theme: 'light',
accentColor: '#676FFF',
logo: 'your-logo-url'
},
embeddedWallets: {
createOnLogin: 'users-without-wallets',
noPromptOnSignature: true
}
}}
>
<QueryClientProvider client={queryClient}>
{props.children}
</QueryClientProvider>
</PrivyProvider>
)
}
Login with your Privy embedded wallet
import { http } from "viem";
import { baseSepolia } from "viem/chains";
import { createSmartAccountClient, NexusClient } from "@biconomy/sdk";
import { useWallets, usePrivy } from '@privy-io/react-auth';
export default function Home() {
const { login } = usePrivy();
return (
<div className="min-h-screen py-12 px-4 sm:px-6 lg:px-8">
<button className="bg-blue-500 text-white p-2 rounded-md" onClick={login}>Login</button>
</div>
);
}
Connect the Privy signer with Nexus
import { http } from "viem";
import { baseSepolia } from "viem/chains";
import { createSmartAccountClient, NexusClient } from "@biconomy/sdk";
import { useWallets, usePrivy } from '@privy-io/react-auth';
export default function Home() {
const { login } = usePrivy();
const { wallets } = useWallets();
const [nexusClient, setNexusClient] = useState<NexusClient | null>(null);
useEffect(() => {
const embeddedWallet = wallets.find((wallet) => (wallet.walletClientType === 'privy'));
if (embeddedWallet) {
(async () => {
const provider = await embeddedWallet.getEthersProvider();
const signer = provider.getSigner();
const nexusClient = await createSmartAccountClient({
signer,
chain: baseSepolia,
transport: http(),
bundlerTransport: http(BUNDLER_URL), // Get your BUNDLER_URL from the Biconomy Dashboard
});
setNexusClient(nexusClient);
})();
}
}, [wallets]);
return (
<div className="min-h-screen py-12 px-4 sm:px-6 lg:px-8">
{nexusClient && <div>Nexus Client: {nexusClient.account.address}</div>}
<button className="bg-blue-500 text-white p-2 rounded-md" onClick={login}>Login</button>
</div>
);
}
Send a transaction with Nexus and Privy
import { http } from "viem";
import { baseSepolia } from "viem/chains";
import { createSmartAccountClient, NexusClient } from "@biconomy/sdk";
import { useWallets, usePrivy } from '@privy-io/react-auth';
export default function Home() {
const { login } = usePrivy();
const { wallets } = useWallets();
const [nexusClient, setNexusClient] = useState<NexusClient | null>(null);
useEffect(() => {
const embeddedWallet = wallets.find((wallet) => (wallet.walletClientType === 'privy'));
if (embeddedWallet) {
(async () => {
const provider = await embeddedWallet.getEthersProvider();
const signer = provider.getSigner();
const nexusClient = await createSmartAccountClient({
signer,
chain: baseSepolia,
transport: http(),
bundlerTransport: http(BUNDLER_URL),
});
setNexusClient(nexusClient);
})();
}
}, [wallets]);
const sendDummyTx = async () => {
if (!nexusClient) return;
const hash = await nexusClient?.sendTransaction({
calls: [
{
to: "0x0000000000000000000000000000000000000000",
data: "0x",
value: BigInt(1),
}
]
});
}
return (
<div className="min-h-screen py-12 px-4 sm:px-6 lg:px-8">
{nexusClient && <div>Nexus Client: {nexusClient.account.address}</div>}
<button className="bg-blue-500 text-white p-2 rounded-md" onClick={login}>Login</button>
{nexusClient && <button className="bg-blue-500 text-white p-2 rounded-md" onClick={sendDummyTx}>Send Dummy Tx</button>}
</div>
);
}