With MultiContractCallHandler
, you can execute multiple contract calls within a single transaction. To achieve this, you first prepare all the contract calls that you want to bundle:
let contract_methods = MyContract::new(contract_id, wallet.clone()).methods();
let call_handler_1 = contract_methods.initialize_counter(42);
let call_handler_2 = contract_methods.get_array([42; 2]);
You can also set call parameters, variable outputs, or external contracts for every contract call, as long as you don't execute it with call()
or simulate()
.
Next, you provide the prepared calls to your MultiContractCallHandler
and optionally configure transaction policies:
let mut multi_call_handler = MultiContractCallHandler::new(wallet.clone());
multi_call_handler
.add_call(call_handler_1)
.add_call(call_handler_2);
Note: any transaction policies configured on separate contract calls are disregarded in favor of the parameters provided to
MultiContractCallHandler
.
Furthermore, if you need to separate submission from value retrieval for any reason, you can do so as follows:
let submitted_tx = multi_call_handler.submit().await?;
let (counter, array): (u64, [u64; 2]) = submitted_tx.response().await?.value;
To get the output values of the bundled calls, you need to provide explicit type annotations when saving the result of call()
or simulate()
to a variable:
let (counter, array): (u64, [u64; 2]) = multi_call_handler.call().await?.value;
You can also interact with the FuelCallResponse
by moving the type annotation to the invoked method:
let response = multi_call_handler.call::<(u64, [u64; 2])>().await?;
Note: The
MultiContractCallHandler
supports only one contract call that returns a heap type. Because of the way heap types are handled, this contract call needs to be at the last position, i.e., added last withadd_call
. This is a temporary limitation that we hope to lift soon. In the meantime, if you have multiple calls handling heap types, split them across multiple regular, single calls.