Documentation Index Fetch the complete documentation index at: https://base-a060aa97-meyer9-move-azul-to-top-of-upgrades.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Learn how to create and manage Sub Accounts that provide app-specific wallet accounts embedded directly in your application.
Overview
Sub Accounts allow you to provision dedicated wallet accounts for your users within your application.
These accounts are controlled by the user’s main Base Account and provide an enhanced user experience
as the user’s interactions produce no passkey prompts or popups.
Users can manage all their Sub Accounts at account.base.app .
If you would like to see a live demo of Sub Accounts in action, check out our Sub Accounts Demo .
What you’ll achieve
By the end of this guide, you will:
Understand how Sub Accounts work with Base Account
Create new Sub Accounts for users
Retrieve and manage existing Sub Accounts
Implement Sub Account in your Privy project
The code snippets in this guide are based on the following example project:
Base Account Privy Template https://github.com/base/base-account-privy
Setup
Follow the Setup guide to set up Privy with Base Account.
Implementation
Component Setup
Sub Accounts Component (components/sections/sub-accounts.tsx)
"use client" ;
import { useState , useMemo } from "react" ;
import { useWallets } from "@privy-io/react-auth" ;
const SubAccounts = () => {
const { wallets } = useWallets ();
const [ subAccounts , setSubAccounts ] = useState <
{
address : string ;
factory : string ;
factoryData : string ;
}[]
> ([]);
const [ isLoading , setIsLoading ] = useState ( false );
// Find the Base Account wallet
const baseAccount = useMemo (() => {
return wallets . find (( wallet ) => wallet . walletClientType === 'base_account' );
}, [ wallets ]);
const handleGetSubAccounts = async () => {
if ( ! baseAccount ) return ;
setIsLoading ( true );
try {
// Switch to Base Sepolia (or Base Mainnet - use 8453 for mainnet)
await baseAccount . switchChain ( 84532 );
const provider = await baseAccount . getEthereumProvider ();
// Get existing Sub Accounts
const response = await provider . request ({
method: 'wallet_getSubAccounts' ,
params: [{
account: baseAccount . address ,
domain: window . location . origin
}]
});
const { subAccounts : existingSubAccounts } = response ;
setSubAccounts ( existingSubAccounts || []);
} catch ( error ) {
console . error ( "Error getting Sub Accounts:" , error );
} finally {
setIsLoading ( false );
}
};
const handleAddSubAccount = async () => {
if ( ! baseAccount ) return ;
setIsLoading ( true );
try {
// Switch to Base Sepolia (or Base Mainnet - use 8453 for mainnet)
await baseAccount . switchChain ( 84532 );
const provider = await baseAccount . getEthereumProvider ();
// Create new Sub Account
await provider . request ({
method: 'wallet_addSubAccount' ,
params: [{
version: '1' ,
account: {
type: 'create' ,
keys: [{
type: 'address' ,
publicKey: baseAccount . address
}]
}
}]
});
// Refresh the Sub Accounts list
await handleGetSubAccounts ();
} catch ( error ) {
console . error ( "Error creating Sub Account:" , error );
} finally {
setIsLoading ( false );
}
};
return (
< div className = "space-y-4" >
< div className = "flex gap-4" >
< button
onClick = { handleGetSubAccounts }
disabled = { ! baseAccount || isLoading }
className = "px-4 py-2 bg-blue-600 text-white rounded disabled:opacity-50"
>
Get Sub Accounts
</ button >
< button
onClick = { handleAddSubAccount }
disabled = { ! baseAccount || isLoading }
className = "px-4 py-2 bg-green-600 text-white rounded disabled:opacity-50"
>
Create Sub Account
</ button >
</ div >
{ subAccounts . length > 0 && (
< div >
< h4 className = "font-medium mb-2" > Existing Sub Accounts: </ h4 >
< div className = "space-y-2" >
{ subAccounts . map (( subAccount , index ) => (
< div key = { index } className = "p-3 border rounded-md" >
< p >< strong > Address: </ strong > { subAccount . address } </ p >
< p >< strong > Factory: </ strong > { subAccount . factory } </ p >
< p >< strong > Factory Data: </ strong > { subAccount . factoryData } </ p >
</ div >
)) }
</ div >
</ div >
) }
</ div >
);
};
See all 117 lines
Key Methods
Getting Sub Accounts
Use wallet_getSubAccounts to retrieve existing Sub Accounts for a domain:
Get Sub Accounts (components/sections/sub-accounts.tsx)
const response = await provider . request ({
method: 'wallet_getSubAccounts' ,
params: [{
account: baseAccount . address ,
domain: window . location . origin
}]
});
Creating Sub Accounts
Use wallet_addSubAccount to create new Sub Accounts:
Create Sub Account (components/sections/sub-accounts.tsx)
await provider . request ({
method: 'wallet_addSubAccount' ,
params: [{
version: '1' ,
account: {
type: 'create' ,
keys: [{
type: 'address' ,
publicKey: baseAccount . address
}]
}
}]
});
Network Configuration
Sub accounts work on both Base Mainnet and Base Sepolia:
Base Mainnet : Chain ID 8453
Base Sepolia : Chain ID 84532
Explore further