Learn how to create and manage Sub Accounts using Wagmi hooks and Base Account provider methods.Documentation Index
Fetch the complete documentation index at: https://docs.base.org/llms.txt
Use this file to discover all available pages before exploring further.
Prerequisites
Make sure you have:Overview
Sub Accounts allow you to create child accounts that can spend from the parent account’s balance using Spend Permissions. This reduces the need for frequent user signatures and improves the user experience.Creating Sub Accounts
Use the Base Account provider to create Sub Accounts:import { useAccount, useConnector } from 'wagmi'
import { useState } from 'react'
export function CreateSubAccount() {
const { address, isConnected } = useAccount()
const connector = useConnector()
const [subAccount, setSubAccount] = useState<string | null>(null)
const [isCreating, setIsCreating] = useState(false)
const createSubAccount = async () => {
if (!connector || !isConnected) return
setIsCreating(true)
try {
const provider = connector.provider
// Create a new Sub Account
const result = await provider?.request({
method: 'wallet_addSubAccount',
params: [{
version: '1.0',
chainId: `0x${Number(8453).toString(16)}`, // Base mainnet
from: address,
}]
})
if (result?.subAccount) {
setSubAccount(result.subAccount)
console.log('Sub Account created:', result.subAccount)
}
} catch (error) {
console.error('Failed to create Sub Account:', error)
} finally {
setIsCreating(false)
}
}
return (
<div className="space-y-4">
<h3 className="text-lg font-semibold">Sub Account Management</h3>
{!subAccount ? (
<button
onClick={createSubAccount}
disabled={!isConnected || isCreating}
className="px-4 py-2 bg-blue-500 text-white rounded disabled:opacity-50"
>
{isCreating ? 'Creating Sub Account...' : 'Create Sub Account'}
</button>
) : (
<div className="p-4 bg-green-50 border border-green-200 rounded">
<p className="text-sm text-green-700">
Sub Account created: <span className="font-mono">{subAccount}</span>
</p>
</div>
)}
</div>
)
}
Listing Sub Accounts
Retrieve existing Sub Accounts for the connected wallet:import { useAccount, useConnector } from 'wagmi'
import { useState, useEffect } from 'react'
export function SubAccountsList() {
const { address, isConnected } = useAccount()
const connector = useConnector()
const [subAccounts, setSubAccounts] = useState<string[]>([])
const [isLoading, setIsLoading] = useState(false)
const fetchSubAccounts = async () => {
if (!connector || !isConnected) return
setIsLoading(true)
try {
const provider = connector.provider
const result = await provider?.request({
method: 'wallet_getSubAccounts',
params: [{
version: '1.0',
chainId: `0x${Number(8453).toString(16)}`,
from: address,
}]
})
if (result?.subAccounts) {
setSubAccounts(result.subAccounts)
}
} catch (error) {
console.error('Failed to fetch Sub Accounts:', error)
} finally {
setIsLoading(false)
}
}
useEffect(() => {
if (isConnected) {
fetchSubAccounts()
}
}, [isConnected, address])
return (
<div className="space-y-4">
<div className="flex items-center justify-between">
<h3 className="text-lg font-semibold">Your Sub Accounts</h3>
<button
onClick={fetchSubAccounts}
disabled={isLoading}
className="px-3 py-1 bg-gray-500 text-white rounded text-sm"
>
{isLoading ? 'Loading...' : 'Refresh'}
</button>
</div>
{subAccounts.length === 0 ? (
<p className="text-gray-500">No Sub Accounts found</p>
) : (
<div className="space-y-2">
{subAccounts.map((subAccount, index) => (
<div
key={subAccount}
className="p-3 bg-blue-50 border border-blue-200 rounded"
>
<div className="flex items-center justify-between">
<span className="font-mono text-sm">{subAccount}</span>
<span className="text-xs text-blue-600">Sub Account #{index + 1}</span>
</div>
</div>
))}
</div>
)}
</div>
)
}
Using Sub Accounts for Transactions
Once you have Sub Accounts, you can use them to perform transactions:import { useAccount, useConnector, useWriteContract } from 'wagmi'
import { useState } from 'react'
export function SubAccountTransactions() {
const { address } = useAccount()
const connector = useConnector()
const [selectedSubAccount, setSelectedSubAccount] = useState('')
const [isLoading, setIsLoading] = useState(false)
const sendTransactionFromSubAccount = async () => {
if (!connector || !selectedSubAccount) return
setIsLoading(true)
try {
const provider = connector.provider
// Send transaction using Sub Account
const result = await provider?.request({
method: 'wallet_sendCalls',
params: [{
version: '1.0',
chainId: `0x${Number(8453).toString(16)}`,
from: selectedSubAccount, // Use Sub Account as sender
calls: [{
to: '0x...' as `0x${string}`,
value: '0x0',
data: '0x' as `0x${string}`
}]
}]
})
console.log('Transaction sent from Sub Account:', result)
} catch (error) {
console.error('Sub Account transaction failed:', error)
} finally {
setIsLoading(false)
}
}
return (
<div className="space-y-4">
<h3 className="text-lg font-semibold">Sub Account Transactions</h3>
<div>
<label className="block mb-2">Select Sub Account:</label>
<input
type="text"
value={selectedSubAccount}
onChange={(e) => setSelectedSubAccount(e.target.value)}
className="w-full p-2 border rounded"
placeholder="0x... (Sub Account address)"
/>
</div>
<button
onClick={sendTransactionFromSubAccount}
disabled={!selectedSubAccount || isLoading}
className="px-4 py-2 bg-green-500 text-white rounded disabled:opacity-50"
>
{isLoading ? 'Sending...' : 'Send from Sub Account'}
</button>
</div>
)
}
Complete Example
Here’s a complete component that combines all Sub Account functionality:import { useAccount, useConnector } from 'wagmi'
import { useState, useEffect } from 'react'
export function SubAccountManager() {
const { address, isConnected } = useAccount()
const connector = useConnector()
const [subAccounts, setSubAccounts] = useState<string[]>([])
const [isCreating, setIsCreating] = useState(false)
const [isLoading, setIsLoading] = useState(false)
const fetchSubAccounts = async () => {
if (!connector || !isConnected) return
setIsLoading(true)
try {
const provider = connector.provider
const result = await provider?.request({
method: 'wallet_getSubAccounts',
params: [{
version: '1.0',
chainId: `0x${Number(8453).toString(16)}`,
from: address,
}]
})
if (result?.subAccounts) {
setSubAccounts(result.subAccounts)
}
} catch (error) {
console.error('Failed to fetch Sub Accounts:', error)
} finally {
setIsLoading(false)
}
}
const createSubAccount = async () => {
if (!connector || !isConnected) return
setIsCreating(true)
try {
const provider = connector.provider
const result = await provider?.request({
method: 'wallet_addSubAccount',
params: [{
version: '1.0',
chainId: `0x${Number(8453).toString(16)}`,
from: address,
}]
})
if (result?.subAccount) {
// Refresh the list
await fetchSubAccounts()
}
} catch (error) {
console.error('Failed to create Sub Account:', error)
} finally {
setIsCreating(false)
}
}
useEffect(() => {
if (isConnected) {
fetchSubAccounts()
}
}, [isConnected])
if (!isConnected) {
return <p>Please connect your wallet first</p>
}
return (
<div className="space-y-6">
<div className="flex items-center justify-between">
<h2 className="text-xl font-bold">Sub Account Manager</h2>
<button
onClick={createSubAccount}
disabled={isCreating}
className="px-4 py-2 bg-blue-500 text-white rounded disabled:opacity-50"
>
{isCreating ? 'Creating...' : 'Create Sub Account'}
</button>
</div>
<div className="space-y-4">
<div className="flex items-center justify-between">
<h3 className="text-lg font-semibold">Your Sub Accounts ({subAccounts.length})</h3>
<button
onClick={fetchSubAccounts}
disabled={isLoading}
className="px-3 py-1 bg-gray-500 text-white rounded text-sm"
>
{isLoading ? 'Loading...' : 'Refresh'}
</button>
</div>
{subAccounts.length === 0 ? (
<p className="text-gray-500">No Sub Accounts found. Create one to get started!</p>
) : (
<div className="grid gap-3">
{subAccounts.map((subAccount, index) => (
<div
key={subAccount}
className="p-4 bg-blue-50 border border-blue-200 rounded-lg"
>
<div className="flex items-center justify-between">
<div>
<p className="font-mono text-sm">{subAccount}</p>
<p className="text-xs text-blue-600">Sub Account #{index + 1}</p>
</div>
</div>
</div>
))}
</div>
)}
</div>
</div>
)
}