Management API Reference

Ecosystem wallet

Batch transactions

Smart Wallet enables you to send multiple onchain calls in a single transaction, improving UX by reducing multi-step interactions to a single click. A common example is combining an ERC-20 approve with a swap operation.

You can submit batch transactions using the new wallet_sendCalls RPC method.

1

Check wallet compatibility for atomic batching

  • First, verify if your app supports atomic batching (This step is crucial if your app supports multiple wallet types)
  • Use the useCapabilities hook from Wagmi experimental features
  • Implement fallback functionality for unsupported wallets

Note: The useWriteContracts and useCapabilities hooks rely on new wallet RPC and may not be supported in all wallets.

app.tsx

_26
import { useCapabilities } from 'wagmi/experimental'
_26
_26
function App() {
_26
const { data: capabilities } = useCapabilities()
_26
// Returns capability object per chain:
_26
// {
_26
// 84532: {
_26
// atomicBatch: {
_26
// supported: true,
_26
// },
_26
// }
_26
// }
_26
_26
// Check if atomic batching is supported
_26
const isAtomicBatchSupported = capabilities?.[84532]?.atomicBatch?.supported
_26
_26
return (
_26
<div>
_26
{isAtomicBatchSupported ? (
_26
<BatchTransactionComponent />
_26
) : (
_26
<FallbackComponent />
_26
)}
_26
</div>
_26
)
_26
}

2

Set up contract interactions

  • Import required hooks: useAccount and useWriteContracts from Wagmi
  • Define your smart contract ABI
  • Initialize the useWriteContracts hook for batch transactions
  • Create a transaction handling function that can process multiple contract calls

Important: Make sure your contract ABIs are correctly typed for better development experience.

app.tsx

_47
import { useAccount } from 'wagmi'
_47
import { useWriteContracts } from 'wagmi/experimental'
_47
_47
// Define your contract ABI
_47
const abi = [
_47
{
_47
stateMutability: 'nonpayable',
_47
type: 'function',
_47
inputs: [{ name: 'to', type: 'address' }],
_47
name: 'safeMint',
_47
outputs: [],
_47
}
_47
] as const
_47
_47
function BatchTransactionComponent() {
_47
const account = useAccount()
_47
const { writeContracts } = useWriteContracts()
_47
_47
const handleBatchTransaction = () => {
_47
writeContracts({
_47
contracts: [
_47
{
_47
address: "0x119Ea671030FBf79AB93b436D2E20af6ea469a19",
_47
abi,
_47
functionName: "safeMint",
_47
args: [account.address],
_47
},
_47
// Add more contract interactions as needed
_47
{
_47
address: "0x119Ea671030FBf79AB93b436D2E20af6ea469a19",
_47
abi,
_47
functionName: "safeMint",
_47
args: [account.address],
_47
}
_47
],
_47
})
_47
}
_47
_47
return (
_47
<button
_47
onClick={handleBatchTransaction}
_47
className="px-4 py-2 bg-blue-600 text-white rounded"
_47
>
_47
Execute Batch Transaction
_47
</button>
_47
)
_47
}

3

Implement transaction status monitoring

  • Add the useCallsStatus hook to track transaction status
  • Configure polling interval for status updates
  • Display transaction status to users
  • Handle transaction completion and errors

Pro tip: The polling interval can be adjusted based on your needs, but 1 second is a good default.

app.tsx

_57
import { useCallsStatus } from 'wagmi/experimental'
_57
_57
function BatchTransactionComponent() {
_57
const { data: id, writeContracts } = useWriteContracts()
_57
const { data: callsStatus } = useCallsStatus({
_57
id: id as string,
_57
query: {
_57
enabled: !!id,
_57
// Poll every second until confirmed
_57
refetchInterval: (data) =>
_57
data.state.data?.status === "CONFIRMED" ? false : 1000,
_57
},
_57
})
_57
_57
// Example response structure:
_57
// {
_57
// status: 'CONFIRMED',
_57
// receipts: [
_57
// {
_57
// logs: [{
_57
// address: '0x...',
_57
// topics: ['0x...'],
_57
// data: '0x...'
_57
// }],
_57
// status: 'success',
_57
// blockHash: '0x...',
_57
// blockNumber: 122414523n,
_57
// gasUsed: 390000n,
_57
// transactionHash: '0x...'
_57
// }
_57
// ]
_57
// }
_57
_57
return (
_57
<div className="space-y-4">
_57
<button
_57
onClick={handleBatchTransaction}
_57
className="px-4 py-2 bg-blue-600 text-white rounded"
_57
>
_57
Execute Batch Transaction
_57
</button>
_57
_57
{callsStatus && (
_57
<div className="p-4 border rounded">
_57
<p className="font-semibold">
_57
Status: {callsStatus.status}
_57
</p>
_57
{callsStatus.status === 'CONFIRMED' && (
_57
<p className="text-green-600">
_57
Transaction confirmed! Hash: {callsStatus.receipts[0].transactionHash}
_57
</p>
_57
)}
_57
</div>
_57
)}
_57
</div>
_57
)
_57
}