Batch Transactions with the Smart Wallet
In this guide we will go through how to batch multiple transactions into a single transaction with smart wallet in a backend script.
The full source-code for this guide is available on GitHub:
Batching Transactions
One of the main benefits of a smart wallet is that code determines how it functions because it is a smart contract wallet. We have added a function to the smart wallet to enable batching transactions - executeBatch()
. This means that only one signature is required from the personal wallet in order to execute multiple transactions. This streamlines the user experience significantly as user flows which would previously have been tedious, now become simplified. For example, you could deploy an NFT contract, mint an NFT and transfer the NFT all in a single user click and single transaction.
Creating a Smart Wallet Script
To demonstrate batching transactions, we are going to perform two transactions in a single batch:
- Claim a token from a
TokenDrop
contract. - Claim an edition NFT from an
EditionDrop
contract.
To get started, we first need to setup a script which initializes a personal wallet, creates a smart wallet and then gets instances of each drop contract:
import { config } from "dotenv";
import { ThirdwebSDK } from "@thirdweb-dev/sdk";
import { readFileSync } from "fs";
import { Goerli } from "@thirdweb-dev/chains";
import {
SmartWallet,
SmartWalletConfig,
} from "@thirdweb-dev/wallets";
import { LocalWalletNode } from "@thirdweb-dev/wallets/evm/wallets/local-wallet-node";
config();
const chain = Goerli;
const factoryAddress = "0x3c115305ecC8119D9517BB67a5B3D4073Bc9CffF";
const secretKey = process.env.THIRDWEB_SECRET_KEY as string;
const main = async () => {
if (!secretKey) {
throw new Error(
"No API Key found, get one from https://thirdweb.com/dashboard"
);
}
console.log("Running on", chain.slug, "with factory", factoryAddress);
// Load or create personal wallet
// here we generate LocalWallet that will be stored in wallet.json
const personalWallet = new LocalWalletNode();
await personalWallet.loadOrCreate({
strategy: "encryptedJson",
password: "password",
});
const personalWalletAddress = await personalWallet.getAddress();
console.log("Personal wallet address:", personalWalletAddress);
// Configure the smart wallet
const config: SmartWalletConfig = {
chain,
factoryAddress,
secretKey,
gasless: true,
};
// Connect the smart wallet
const smartWallet = new SmartWallet(config);
await smartWallet.connect({
personalWallet,
});
// now use the SDK normally to perform transactions with the smart wallet
const sdk = await ThirdwebSDK.fromWallet(smartWallet, chain, {
secretKey: secretKey,
});
console.log("Smart Account addr:", await sdk.wallet.getAddress());
console.log("balance:", (await sdk.wallet.balance()).displayValue);
// Claim a ERC20 token
const contract = await sdk.getContract(
"0xc54414e0E2DBE7E9565B75EFdC495c7eD12D3823" // TokenDrop on goerli
);
const editionContract = await sdk.getContract(
"0x8096C71f400984C3C1B7F3a79Ab0C0EaC417b91c"
); // EditionDrop on goerli
const tokenBalance = await contract.erc20.balance();
const editionBalance = await editionContract.erc1155.balance(0);
console.log("ERC20 token balance:", tokenBalance.displayValue);
console.log("Edition NFT balance:", editionBalance.toNumber());
};
main();
Here, we have used LocalWalletNode
as the personal wallet or key. This is to keep things simple however, you could use any other EOA wallet from the wallet SDK including MetaMask
EmailWallet
or CoinbaseWallet
.
If this seems complicated or you are confused at this point, check out this guide which explains how to use smart wallet in a backend:
Batching Transactions
To batch our transactions, we first need to prepare an array of transactions to execute using the Transaction Builder from the thirdweb SDK. To do this, we will use the function prepare()
// Execute multiple transactions at once
const tx1 = await contract.erc20.claim.prepare(1);
const tx2 = await editionContract.erc1155.claim.prepare(0, 1);
const transactions = [tx1, tx2];
Now, we need to use the method executeBatch
on the SmartWallet
instance we created earlier and pass the transactions
to be executed:
const batchTx = await smartWallet.executeBatch(transactions);
console.log(
"Claimed 1 ERC20 token & 1 Edition NFT, tx hash:",
batchTx.receipt.transactionHash
);
const tokenBalanceAfter = await contract.erc20.balance();
const editionBalanceAfter = await editionContract.erc1155.balance(0);
console.log("ERC20 token balance:", tokenBalanceAfter.displayValue);
console.log("Edition NFT balance:", editionBalanceAfter.toNumber());
This will return a TransactionResult
containing the transaction receipt.
Running the script in your terminal using the command yarn start
will yield the following output:
As you can see from the token and edition NFT balances, we have successfully executed both transactions in a  single transaction!
For the full source code, check out this GitHub repository.
Wrapping Up
Smart wallet is a smart contract wallet meaning that code defines the functionality. This means we can create a streamlined user experience by creating functions to, for example, execute multiple transactions while only requiring one signature from the personal wallet.
This guide has demonstrated how using thirdweb's smart wallet, the batching transaction is super easy!
If you have any questions or would like to share anything, please reach out on Discord where you can speak directly to the thirdweb team.