Skip to content

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

Install
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

Initialize Infrastructure
// 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...

Dummy Transaction
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:

  1. Instructions - which function calls need to be executed and on which chains

  2. Fee Token - which native or ERC20 token and on which chain will be used to pay for the Supertransaction

Encode 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:

  1. The user send the Supertransaction to the MEE Node
  2. The MEE nodes gives back a quote - saying for how much it's willing to execute the Supertransaction
  3. 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:

Get Quote
const quote = await meeClient.getQuote(supertransaction)

Checking the Execution Cost

Check the cost of the execution from the quote given by the MEE Node:

Check Execution Cost
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.

Execute 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

Tracking Link
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.

Concise Implementation
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
})