Skip to content

Multiple Contract Calls ​

You can execute multiple contract calls in a single transaction, either to the same contract or to different contracts. This can improve efficiency and reduce the overall transaction costs.

Same Contract multi calls ​

Use the multiCall method to call multiple functions on the same contract in a single transaction:

ts

const { waitForResult } = await counterContract
  .multiCall([
    counterContract.functions.get_count(),
    counterContract.functions.increment_count(2),
    counterContract.functions.increment_count(4),
  ])
  .call();

const { value: results } = await waitForResult();

const initialValue = new BN(results[0]).toNumber();
const incrementedValue1 = new BN(results[1]).toNumber();
const incrementedValue2 = new BN(results[2]).toNumber();

expect(incrementedValue1).toEqual(initialValue + 2);
expect(incrementedValue2).toEqual(incrementedValue1 + 4);
See code in context

Different contracts multi calls ​

The multiCall method also allows you to execute multiple contract calls to distinct contracts within a single transaction:

ts

const chain = echoContract.multiCall([
  echoContract.functions.echo_u8(17),
  counterContract.functions.get_count(),
  counterContract.functions.increment_count(5),
]);

const { waitForResult } = await chain.call();
const { value: results } = await waitForResult();

const echoedValue = results[0];
const initialCounterValue = new BN(results[1]).toNumber();
const counterIncrementedValue = new BN(results[2]).toNumber();

expect(echoedValue).toEqual(17);
expect(counterIncrementedValue).toEqual(initialCounterValue + 5);
See code in context

You can also chain supported contract call methods, like callParams, for each contract call:

ts

const { waitForResult } = await contextContract
  .multiCall([
    echoContract.functions.echo_u8(10),
    contextContract.functions.return_context_amount().callParams({
      forward: [100, baseAssetId],
    }),
  ])
  .call();

const { value: results } = await waitForResult();

const echoedValue = results[0];
const fowardedValue = new BN(results[1]).toNumber();

expect(echoedValue).toEqual(10);
expect(fowardedValue).toEqual(100);
See code in context

When chaining contract call methods within multiCall, avoid executing the contract functions themselves, such as .call, .get, and .simulate.

The multiCall method creates a scope for all contract calls, which will only be executed after invoking the .call method.