Learning to bring gasless transactions to a dapp has been a dream of mine for a while. Today, I am thrilled to finally share my learnings & experiences that I have successfully achieved while conducting this gasless transaction experiment within a project.
The project itself is a platform designed to distribute NFT certificates to English For IT (EFIT) students. It was launched in December 2022 and serves as the backdrop for this exploration. If you'd like more context, I previously wrote an article detailing the development process of the NFT Certificates platform, which was specifically tailored for EFIT. Feel free to check it out!
Since its inception, this platform has garnered immense success, captivating students who consistently express their admiration for its unique and innovative approach.
Up until now, the distribution of certificates involved minting NFTs directly to the students' wallets, incurring gas costs for each issuance. Although the gas cost is negligible due to the contract being deployed on Polygon, it would be even more advantageous if the gas costs were fully sponsored. Moreover, the prospect of acquiring a new skill while undertaking this experiment adds an element of excitement.
* Note*: All this experiments were carried on a testnet version of EFIT & Biconomy.*
When it comes to implementing gasless transactions, the widely recommended approach involves utilizing ERC2771 meta transactions and ensuring that the smart contract is meta transaction compatible. However, this method presents challenges for contracts that are already deployed, as it requires a redeployment. This can be particularly frustrating when there is a dependent platform relying on the existing contract state, as is the case with the NFT certificate distribution system at hand.
Nevertheless, a viable workaround emerges in the form of Account Abstraction. By employing a Smart Account that acts as a contract, it becomes feasible to fund and facilitate the relay of transactions from an Externally Owned Account (EOA) to the destination contract without the need for redeploying the latter to achieve meta transaction compliance.
To explore this solution, I experimented with the Biconomy SDK (Biconomy is a comprehensive toolkit designed to leverage smart contract wallets and construct customized transaction journeys), utilizing its Smart Account feature in conjunction with gasless batch transactions.
Here are the steps I particularly went through for testing the functionality in EFIT testnet,
Registering the Dapp on the Biconomy dashboard with Paymaster.
Creating the Gas-Tank & depositing gas funds.
Whitelisting the EFIT contract (Goerli) and enabling the use of gas sponsorship for the issueCertificate
function.
Initialize a Smart Account using the SDK.
Prepare the function call for a gasless batch transaction.
The process of registering a PayMaster for the dApp and setting up the gas tank was seamless. I easily deposited the required gas funds and enabled gas sponsorship for the issueCertificate
function.
To know more about PayMaster, check here.
To leverage the gas tank and enable gasless transactions, it was necessary to initialize and deploy a smart account through which the function call for minting certificates would be processed.
This initialization process required passing a wallet provider to the Smart Account constructor SDK function. However, since I was using viem as the primary web3 library within wagmi, the wallet provider wasn't readily available like it is with ethers.js.
Fortunately, wagmi offers an adapter that can convert viem's public client into an ethers.js wallet provider. Utilizing the wagmi - ethers.js adapter, I was able to initialize the Smart Account for an EOA.
const { chain } = useNetwork();
const publicClient = usePublicClient({ chainId: chain?.id});
const { data: walletClient } = useWalletClient({ chainId: chain?.id });
const smartAccount = new SmartAccount(_web3Provider, {
activeNetworkId: ChainId.GOERLI,
supportedNetworksIds: [ChainId.GOERLI],
networkConfig: [
{
chainId: ChainId.GOERLI,
dappAPIKey: BICONOMY_GOERLI_KEY
}
]
});
await smartAccount.init();
An API Key from Biconomy was necessary, which can be obtained by setting up a PayMaster in the Biconomy dashboard mentioned above.
With all the necessary configurations and initialization procedures in place, it was time to put the functionality to the test by triggering a call for certificate minting.
Gasless Minting
After connecting my wallet, I used the above code snippet to initialize the Smart Account for the connected address. Behind the scenes, this action created a Smart Account with an address, but it wasn't immediately deployed.
I had two options:
either deploy the account alone by triggering an single gasless SDK function or
batch the deployment with the first gasless transaction made from the EOA.
I found option 2 to be particularly suitable for my requirement.
Sending a Single Gasless Batch Transaction
To send a gasless batch transaction, it was crucial to prepare the function call by encoding the data that needed to be sent. In this case, I utilized an EFIT-specific function responsible for minting certificates.
const efitInterface = new ethers.utils.Interface(ABI);
const issueCertificateEncodedData = efitInterface.encodeFunctionData(
'issueCertificate',
[
studentWallet,
tokenMetadataHash
]
);
const issueCertificateTransaction = {
to: EFIT_CONTRACT_ADDRESS,
data: issueCertificateEncodedData
};
const txResponse = await smartAccount.sendTransactionBatch({
transactions: [issueCertificateTransaction]
});
const txReciept = await txResponse.wait();
This sends the transaction via the initialized smart account & if the account is not deployed, the sendTransactionBatch
will batch the deployment along with the function call.
Although there were some initial challenges with gas estimations, they were resolved, and the transaction successfully went through without requiring a gas fee. It was a moment of triumph.
While the current experimentation was conducted on a testnet version of the EFIT Certificates platform, the potential of gasless transactions extends far beyond. This innovation brings forth new possibilities and conveniences for teachers in minting those certificates, eliminating the requirement of holding gas funds and providing a seamless experience if moved to production.
The journey of experimenting with gasless transactions was rich with valuable experiences and lessons. From registering the PayMaster and setting up the gas tank to initializing Smart Accounts and preparing function calls, each step presented its own unique learning curve. These insights will undoubtedly serve as a solid foundation for my continued exploration and future endeavors.