How to submit batch transactions
One benefit of Smart Contract Accounts is that it is possible to batch transactions in one UserOperation
(UO). Not all Smart Contract Accounts support batching. But, if the SmartContractAccount
implementation you are using has the encodeBatchExecute
method, then implementations of SmartAccountClient
will allow you to make those calls.
There are two ways you can batch transactions using SmartAccountClient
:
- via
sendUserOperation
- via
sendTransactions
Note 1: LightSmartContractAccount
, and MultiOwnerModularAccount
Both LightSmartContractAccount
and MultiOwnerModularAccount
implement encodeBatchExecute
, thus supports batching UserOperations
out of the box.
Note 2: Transactions Batched as a Single User Operation
When you batch transactions, the transaction actions (target
s and calldata
s) are batched into a single UO, where the sender is the account itself.
Note 3: Batched Transactions Ordering
The batched UO gets executed by the account calling the executeBatch
method on LightAccount
or Modular Account smart contracts. executeBatch
processes the input array of transactions data linearly, guaranteeing the execution order of those transactions to be sequential.
Batching using sendUserOperation
The SmartAccountClient
supports passing either a single UO or an array of UOs to sendUserOperation
. If you pass an array, the client will batch the transactions into a single User Operation and submit it to the bundler. Let's see an example:
import { smartAccountClient } from "./smartAccountClient";
// the hash returned here is the hash of the User Operation
const { hash } = await smartAccountClient.sendUserOperation({
uo: [
{
target: "0x...",
data: "0xcallDataTransacation1",
},
{
target: "0x...",
data: "0xcallDataTransacation2",
},
],
});
import { createModularAccountAlchemyClient } from "@alchemy/aa-alchemy";
import { LocalAccountSigner, sepolia } from "@alchemy/aa-core";
export const chain = sepolia;
export const smartAccountClient = await createModularAccountAlchemyClient({
apiKey: "YOUR_API_KEY",
chain,
// you can swap this out for any SmartAccountSigner
signer: LocalAccountSigner.mnemonicToAccountSigner("OWNER_MNEMONIC"),
});
Batching using sendTransactions
The SmartAccountClient
supports sending UOs and waiting for them to be mined in a transaction via the sendTransaction
and sendTransactions
methods. The latter allows for batching in the same way sendUserOperation
:
import { smartAccountClient } from "./smartAccountClient";
// the hash returned here is the hash of the mined Tx that includes the UserOperation
const hash = await smartAccountClient.sendTransactions({
requests: [
{
to: "0x...",
data: "0xcallDataTransacation1",
},
{
to: "0x...",
data: "0xcallDataTransacation2",
},
],
});
import { createModularAccountAlchemyClient } from "@alchemy/aa-alchemy";
import { LocalAccountSigner, sepolia } from "@alchemy/aa-core";
export const chain = sepolia;
export const smartAccountClient = await createModularAccountAlchemyClient({
apiKey: "YOUR_API_KEY",
chain,
// you can swap this out for any SmartAccountSigner
signer: LocalAccountSigner.mnemonicToAccountSigner("OWNER_MNEMONIC"),
});