use anyhow::{bail, Result};
use fuel_tx::{ConsensusParameters, ContractId};
use fuels::programs::calls::{
traits::TransactionTuner, utils::find_ids_of_missing_contracts, ContractCall,
};
use fuels_accounts::{
provider::Provider,
signers::private_key::PrivateKeySigner,
wallet::{Unlocked, Wallet},
};
use fuels_core::types::{transaction::TxPolicies, transaction_builders::VariableOutputPolicy};
pub async fn determine_missing_contracts(
call: &ContractCall,
provider: &Provider,
tx_policies: &TxPolicies,
variable_output_policy: &VariableOutputPolicy,
consensus_params: &ConsensusParameters,
log_decoder: &fuels_core::codec::LogDecoder,
account: &Wallet<Unlocked<PrivateKeySigner>>,
) -> Result<Vec<ContractId>> {
let tb = call
.transaction_builder(
*tx_policies,
*variable_output_policy,
consensus_params,
call.inputs.clone(),
account,
)
.expect("Failed to initialize transaction builder");
let tx = call
.build_tx(tb, account)
.await
.expect("Failed to build transaction");
match provider
.dry_run(tx)
.await?
.take_receipts_checked(Some(log_decoder))
{
Ok(_) => Ok(vec![]),
Err(fuels_core::types::errors::Error::Transaction(
fuels::types::errors::transaction::Reason::Failure { receipts, .. },
)) => {
let missing_contracts = find_ids_of_missing_contracts(&receipts);
Ok(missing_contracts)
}
Err(err) => bail!(err),
}
}