Execute a Simple Supertransaction
In this tutorial, we will use the Biconomy Modular Execution Environment to execute a very simple Supertransaction.
Goals
The goal of this tutorial is to learn the flow of executing a Supertransaction. This tutorial will not cover the functionalities which Supertransactions unlock - such as multichain orchestration, intent execution or cross-chain gas abstraction.
Getting Started
Install AbstractJS and viem
npm install @biconomy/abstractjs viem @rhinestone/module-sdk
Initialize the MEE Infrastructure
Supertransactions are powered by the Biconomy Modular Execution
Environment (MEE). To connect to MEE, we need to initialize
an meeClient
// Create an account owner - signer
const eoaSigner = privateKeyToAccount("Your private key here")
// Create a connector to Biconomy Nexus account
// implementations across multiple chains
// with the multichain account utility function
const mcNexus = await toMultichainNexusAccount({
chains: [optimism, base, polygon, arbitrum],
signer: eoaSigner
})
// Create the connection to the MEE
const meeClient = createMeeClient({
account: mcNexus
})
Encode a Dummy Transaction
For the purposes of this tutorial, we'll encode a dummy
transaction which simply send 0ETH to 0x000000...
const emptyTx: AbstractCall = {
to: zeroAddress,
value: 0n,
gasLimit: 50_000n
}
Encode a Supertransaction
Now we will encode an instance of the Supertransaction object. The Supertransaction object contains two fields:
-
Instructions - which function calls need to be executed and on which chains
-
Fee Token - which native or ERC20 token and on which chain will be used to pay for the Supertransaction
const supertransaction: Supertransaction = {
// Transactions to be executed within a
// Supertransaction
instructions: [
{
// Function calls to execute within a transaction
calls: [emptyTx],
// Chain on which to execute the transaction
chainId: optimism.id
}
],
feeToken: toFeeToken({
chainId: optimism.id,
token: mcUSDC
})
}
Executing the Supertransaction
The way Supertransaction execution goes is as follows:
- The user send the Supertransaction to the MEE Node
- The MEE nodes gives back a quote - saying for how much it's willing to execute the Supertransaction
- The user either confirms or declines the quote
Getting a Quote from the MEE Node
In order to get the Quote from the MEE Node, we call the
getQuote
function:
const quote = await meeClient.getQuote(supertransaction)
Checking the Execution Cost
Check the cost of the execution from the quote given by the MEE Node:
quote.paymentInfo.tokenValue // execution price in USD (from chainlink feed)
quote.paymentInfo.tokenWeiAmount // execution price in token base units
quote.paymentInfo.tokenAmount // execution price in token decimal units
Execute the Supertransaction
If you're OK with the quoted execution cost, execute the Supertransaction.
const { hash } = await meeClient.executeQuote({
quote
})
Get a Tracking Link for the MEE Explorer
You can track the execution of the Supertransaction by visiting the MEE Explorer
console.log("Link: ", getMeeScanLink(hash))
Wait for the Supertransaction to Execute
// Wait for the MEE Node to commit the transactions
// within the Supertransaction onchain
const reciept = await meeClient.waitForSupertransactionReceipt({
hash
})
Concise Implementation
The previous implementation went step by step. Now we will show the concise implementation of this exact same execution.
const meeClient = createMeeClient({
account: await toMultichainNexusAccount({
chains: [optimism, base, polygon, arbitrum],
signer: eoaSigner
})
})
const { hash } = await meeClient.executeQuote({
quote: await meeClient.getQuote({
instructions: [
{
chainId: optimism.id,
calls: [{ to: zeroAddress, value: 0n, gasLimit: 50_000n }]
}
],
feeToken: toFeeToken({
chainId: optimism.id,
token: mcUSDC
})
})
})
const reciept = await meeClient.waitForSupertransactionReceipt({
hash
})