Multicalls

Smart accounts can have the ability to execute multiple transactions at once, greatly improving the user experience of dapps (for example, when you have to send 2 transactions for approve + swap on DEXes).

The following SDK bundles a multi-transaction flow into a single transaction if the user is connected with a compatible account like Argent, and gracefully degrades to sending multiple transactions if multicall is not supported. This way your dapp stays backwards compatible and no need for complex if/else branching in code.

yarn add @argent/era-multicall

Assume you have the following dapp and want to deposit a pair of tokens into a pool:

const signer = provider.getSigner()
const dai = new ethers.Contract(..., ..., signer);
const usdc = new ethers.Contract(..., ..., signer);
const pool = new ethers.Contract(..., ..., signer);

With multicall:

import { multicall } from "@argent/era-multicall";

const calls = [
    await dai.populateTransaction.approve(pool.address, daiAmount),
    await usdc.populateTransaction.approve(pool.address, usdcAmount),
    await pool.populateTransaction.depositPair(dai.address, daiAmount, usdc.address, usdcAmount),
];
const results = await multicall(signer, calls);

Without multicall:

let response = await dai.approve(pool.address, INFINITE_AMOUNT); // !!
// user has to approve 1st transaction in his wallet
let result = await response.wait();
// user waits...

response = await usdc.approve(pool.address, INFINITE_AMOUNT); // !!
// user has to approve 2nd transaction in his wallet
result = await response.wait();
// user waits...

response = await pool.depositPair(dai.address, daiAmount, usdc.address, usdcAmount);
// user has to approve a 3rd transaction in his wallet
result = await response.wait();
// user waits again...

Using multicall, the user always sends a single transaction to swap, add liquidity, etc (as it should be), and there are no risks of lingering approvals being exploited later on.

Last updated

#72: adding network switcher

Change request updated