Skip to content

Privy Integration Guide

Privy is an easy way for you to onboard users across mobile and desktop, regardless of whether they already have a wallet or not.

With Privy, you can easily provision self-custodial embedded wallets for your users when they login with email, SMS, or social logins, while also enabling web3-native users to use their existing wallets with your app, if they prefer.

Combining Privy with Account Kit allows you to seamlessly generate embedded wallets for your users and supercharge these wallets with account abstraction – setting the foundation for an innovative & delightful onchain experience.

Integration

Install the SDK

bash
npm i @privy-io/react-auth
bash
yarn add @privy-io/react-auth

Create a SmartAccountSigner

First, set up your React app with Privy following the Privy Quickstart. You should also configure your PrivyProvider to create embedded wallets for your users when they login, like below:

ts

<PrivyProvider
    appId='insert-your-privy-app-id'
    config={{
        ...insertYourPrivyProviderConfig,
        embeddedWallets: {
            createOnLogin: 'all-users'
        }
    }}
>

Then, when a user logs in to your app, Privy will create an embedded wallet for them. You can use this embedded wallet to create a LightSmartContractAccount from aa-accounts:

ts
/**
 * This example assumes your app is wrapped with the `PrivyProvider` and
 * is configured to create embedded wallets for users upon login.
 */
import { createLightAccountAlchemyClient } from "@alchemy/aa-alchemy";
import {
  WalletClientSigner,
  sepolia,
  type SmartAccountSigner,
} from "@alchemy/aa-core";
import { useWallets } from "@privy-io/react-auth";
import { createWalletClient, custom } from "viem";

// The code below makes use of Privy's React hooks. You must paste
// or use it within a React Component or Context.

// Find the user's embedded wallet
// eslint-disable-next-line react-hooks/rules-of-hooks
const { wallets } = useWallets();
const embeddedWallet = wallets.find(
  (wallet) => wallet.walletClientType === "privy"
);
if (!embeddedWallet) throw new Error("User does not have an embedded wallet");

// Switch the embedded wallet to your desired network
await embeddedWallet.switchChain(sepolia.id);

// Get a viem client from the embedded wallet
const eip1193provider = await embeddedWallet.getEthereumProvider();
const privyClient = createWalletClient({
  account: embeddedWallet.address as `0x${string}`,
  chain: sepolia,
  transport: custom(eip1193provider),
});

// Create a smart account signer from the embedded wallet's viem client
const privySigner: SmartAccountSigner = new WalletClientSigner(
  privyClient,
  "privy" // signerType
);

// Create an Alchemy Light Account Client with the privy signer
export const smartAccountClient = await createLightAccountAlchemyClient({
  account: {
    signer: privySigner,
  },
  chain: sepolia,
  apiKey: "YOUR_API_KEY",
});