Skip to content

Execute an Intent

About Intents

AbstractJS enables developers to provide extremely quick chain abstracted experiences to their users by leveraging industry-leading intent solvers.

By encoding an intent into a Supertransaction, developers can move funds from one chain to another in record times (even under a second), without the user ever needing to see the "bridging" operation. AbstractJS is able to execute multiple intents, moving funds from multiple chains, in a single operation.

Open, Secure and liquid

Guide

Using Intents in AbstractJS is extremely easy, as it comes with utility functions which enable developers to encode intents in just a few lines of code.

This guide will explore a case where the developer will use intent based execution to:

  • Move USDC to Optimism
  • Supply the received amount to AAVE

For the purposes of this guide, we'll assume that the user doesn't have any funds on Optimism.

Install AbstractJS and viem

Install AbstractJS
npm install @biconomy/abstractjs viem

Initialize the infrastructure

In execute intents, users need to intialize the MultichainSmartAccount and connect to the Biconomy Superbundler. Connecting to the Superbundler is done by creating an meeClient. To learn more about the setup, read our Building a Chain Abstracted App guide.

Connect the infrastructure
// Initialize the MultichainSmartAccount
const mcNexus = await toMultichainNexusAccount({
  chains: [optimism, base, polygon],
  signer: eoaAccount
})
 
// Connect to the Superbundler
const meeClient = createMeeClient({
  account: mcNexus
})

Encode an Intent

To encode an intent, simply call the buildIntent function provided by the SDK. This function will check where your user has funds, and encode the optimal set of instructions to move their funds.

const intent = await buildIntent(meeClient, {
  mcToken: mcUSDC,
  amount: parseUnits('100', 6),
  chain: optimism
})

Prepare post-intent actions

Often times, after an intent has been executed - the user wants to execute additional actions. For this example, we'll use supplying to AAVE as an example.

First, instantiate the AAVE contract. This can be done by using the AbstractJS utility type MultichainContract - click here to learn how AbstractJS multichain utilities simplify the moden onchain DevEx

const mcAaveV3Pool = getMultichainContract({
  abi: parseAbi([
      "function supply(address asset, uint256 amount, address onBehalfOf, uint16 referralCode)",
  ]),
  deployments: [
      ["0x794a61358D6845594F94dc1DB02A252b5b4814aD", optimism.id],
  ],
});

Then, encode the approve and supply functions to be executed on the AAVE contract on Optimism:

const supplyToAaveOp: Instruction[] = [
  // Approve USDC to AAVE
  mcUSDC.on(optimism.id).approve({
    args: [
      mcUSDC.addressOn(optimism.id),
      parseUnits('99', 6)
    ],
    gasLimit: 100_000n
  }),
  // Call `Supply` on AAVE
  mcAAVE.on(optimism.id).supply({
    args: [
      mcUSDC.addressOn(optimism.id),
      parseUnits('99', 6),
      zeroAddress,
      0
    ],
    gasLimit: 100_000n
  })
]

Then, encode a Supertransaction containing the instructions from the intent and the instructions for supplying to AAVE:

const superTx: SuperTransaction = {
  instructions: [
    intent,
    ...supplyToAaveOp
  ],
  feeToken: toFeeToken({
    chain: optimism,
    token: mcUSDC
  })
}