Batching Transactions
This guide is an extension of our Gasless transaction guide with the addition of bundling multiple transactions together.
This guide assumes you have already initialized the Biconomy SDK and just need to understand how to execute a user paid transaction. See our tutorials for step by step setups.
Before using these code snippets make sure to set up a paymaster and register any smart contracts for sponsorship.
Imports
These are the imports needed for the code snippets below:
import { ethers } from "ethers";
import abi from "some abi location";
import {
IHybridPaymaster,
SponsorUserOperationDto,
PaymasterMode,
} from "@biconomy/paymaster";
Additionally an Instance of the BiconomySmartAccount is needed as mentioned above.
Connect to Contract
Connect to an instance of a contract, below is an example of using ethers JS to connect to an NFT contract.
const nftAddress = "0x0a7755bDfb86109D9D403005741b415765EAf1Bc";
const contract = new ethers.Contract(nftAddress, abi, provider);
Build Useroperation
Using an instance of the smart account use the buildUserOp method to create a userOp.
// use the ethers populateTransaction method to create a raw transaction
const minTx = await contract.populateTransaction.safeMint(address);
const tx1 = {
to: nftAddress,
data: minTx.data,
};
let userOp = await smartAccount.buildUserOp([tx1, tx1.tx1]);
Note that the buildUserOp takes an array of transactions. In this example we simply batch together multiple NFT mints however you can contruct multiple different transactions and pass them all here to the array.
Request Paymaster Data
We now need to construct the paymasterAndData
field of our userOp. This is done by making a request to the paymaster with the Paymaster mode set to sponsored and updating the userOp with the returned paymasterAndData
response.
const biconomyPaymaster = smartAccount.paymaster as IHybridPaymaster<SponsorUserOperationDto>;
let paymasterServiceData: SponsorUserOperationDto = {
mode: PaymasterMode.SPONSORED,
smartAccountInfo: {
name: 'BICONOMY',
version: '2.0.0'
},
};
const paymasterAndDataResponse = await biconomyPaymaster.getPaymasterAndData(
userOp,
paymasterServiceData
);
userOp.paymasterAndData = paymasterAndDataResponse.paymasterAndData;
Send UserOperation
Send your userOp to our Bundler which will send the userOp to the entry point contract to handle executing it as a transaction on chain.
const userOpResponse = await smartAccount.sendUserOp(userOp);
console.log("userOpHash", userOpResponse);
const { receipt } = await userOpResponse.wait(1);
console.log("txHash", receipt.transactionHash);
Mint NFT Function
const handleMint = async () => {
const contract = new ethers.Contract(
nftAddress,
abi,
provider,
)
try {
const minTx = await contract.populateTransaction.safeMint(address);
const tx1 = {
to: nftAddress,
data: minTx.data,
};
let userOp = await smartAccount.buildUserOp([tx1]);
const biconomyPaymaster =
smartAccount.paymaster as IHybridPaymaster<SponsorUserOperationDto>;
let paymasterServiceData: SponsorUserOperationDto = {
mode: PaymasterMode.SPONSORED,
smartAccountInfo: {
name: 'BICONOMY',
version: '2.0.0'
},
};
const paymasterAndDataResponse =
await biconomyPaymaster.getPaymasterAndData(
userOp,
paymasterServiceData
);
userOp.paymasterAndData = paymasterAndDataResponse.paymasterAndData;
const userOpResponse = await smartAccount.sendUserOp(userOp);
console.log("userOpHash", userOpResponse);
const { receipt } = await userOpResponse.wait(1);
console.log("txHash", receipt.transactionHash);
} catch (err: any) {
console.error(err);
console.log(err)
}
}