Use Privy with MetaMask Smart Accounts
Privy provides an embedded wallet solution that enables seamless social login for Web3 applications making user onboarding easier. MetaMask Smart Accounts is a signer-agnostic implementation that allows you to use Privy's EOAExternally owned account (EOA) A private-key-controlled account with no built-in programmable execution logic. wallet as a signer for smart accountsMetaMask smart account A smart contract account that supports programmable behavior, delegated permissions, flexible signing options, and other advanced features..
This guide supports React and React-based frameworks.
Prerequisites
- Install Node.js v18 or later.
- Install Yarn, npm, or another package manager.
- Create a Privy App ID.
Steps
1. Install dependencies
Install the following dependencies:
- npm
- Yarn
- pnpm
- Bun
npm install @privy-io/react-auth @privy-io/wagmi @metamask/smart-accounts-kit @tanstack/react-query wagmi viem
yarn add @privy-io/react-auth @privy-io/wagmi @metamask/smart-accounts-kit @tanstack/react-query wagmi viem
pnpm add @privy-io/react-auth @privy-io/wagmi @metamask/smart-accounts-kit @tanstack/react-query wagmi viem
bun add @privy-io/react-auth @privy-io/wagmi @metamask/smart-accounts-kit @tanstack/react-query wagmi viem
2. Create the Privy provider
In this step, you'll configure the PrivyProvider component to provide the Privy's context
to your application. You'll also use the Privy's WagmiProvider component to integrate Privy with Wagmi. This
provider enables you to use Wagmi hooks with Privy.
Once you have created the PrivyAppProvider, you must wrap it at the root of your application so
that the rest of your application has access to the Privy's context.
For an advanced configuration, see Privy's configuring appearance and configuring login methods guides.
- provider.ts
- config.ts
import { QueryClientProvider } from "@tanstack/react-query";
import { ReactNode } from "react";
import { PrivyProvider } from '@privy-io/react-auth';
// Make sure to import `WagmiProvider` from `@privy-io/wagmi`, not `wagmi`
import { WagmiProvider } from '@privy-io/wagmi';
import { QueryClientProvider } from '@tanstack/react-query';
import { wagmiConfig, queryClient } from "./config.ts"
export function PrivyAppProvider({ children }: { children: ReactNode }) {
return (
<PrivyProvider appId="<YOUR_PRIVY_APP_ID>">
<QueryClientProvider client={queryClient}>
<WagmiProvider config={wagmiConfig}>
{children}
</WagmiProvider>
</QueryClientProvider>
</PrivyProvider>
);
}
import { QueryClient } from "@tanstack/react-query";
import { createConfig, http } from "wagmi";
import { sepolia } from "viem/chains";
export const queryClient = new QueryClient();
export const wagmiConfig = createConfig({
chains: [sepolia],
ssr: true,
transports: {
[sepolia.id]: http(),
},
});
3. Create a smart account
Once the user has connected their wallet, use the Wallet Client from Wagmi as the signer to create a MetaMask smart accountMetaMask smart account A smart contract account that supports programmable behavior, delegated permissions, flexible signing options, and other advanced features..
import { Implementation, toMetaMaskSmartAccount } from "@metamask/smart-accounts-kit";
import { useAccount, usePublicClient, useWalletClient } from "wagmi";
const { address } = useAccount();
const publicClient = usePublicClient();
const { data: walletClient } = useWalletClient();
// Additional check to make sure the Privy is connected
// and values are available.
if (!address || !walletClient || !publicClient ) {
// Handle the error case
}
const smartAccount = await toMetaMaskSmartAccount({
client: publicClient,
implementation: Implementation.Hybrid,
deployParams: [address, [], [], []],
deploySalt: "0x",
signer: { walletClient },
});
Next steps
- See how to send a user operation.
- To sponsor gas for end users, see how to send a gasless transaction.