use super::{Requirement, TransactionBuilder, TransactionBuilderError};
use crate::types::block::output::{AccountId, Output, OutputId};
pub(crate) fn is_account_with_id(output: &Output, account_id: &AccountId, output_id: &OutputId) -> bool {
match output {
Output::Basic(basic) => basic.is_implicit_account() && &AccountId::from(output_id) == account_id,
Output::Account(account) => &account.account_id_non_null(output_id) == account_id,
_ => false,
}
}
pub(crate) fn is_account_with_id_non_null(output: &Output, account_id: &AccountId) -> bool {
if let Output::Account(account) = output {
account.account_id() == account_id
} else {
false
}
}
impl TransactionBuilder {
pub(crate) fn fulfill_account_requirement(&mut self, account_id: AccountId) -> Result<(), TransactionBuilderError> {
if let Some(input) = self
.selected_inputs
.iter()
.find(|input| is_account_with_id(&input.output, &account_id, input.output_id()))
{
log::debug!(
"{account_id:?} requirement already fulfilled by {:?}",
input.output_id()
);
return Ok(());
}
if !self.allow_additional_input_selection {
return Err(TransactionBuilderError::AdditionalInputsRequired(Requirement::Account(
account_id,
)));
}
let index = self
.available_inputs
.iter()
.position(|input| is_account_with_id(&input.output, &account_id, input.output_id()))
.ok_or(TransactionBuilderError::UnfulfillableRequirement(Requirement::Account(
account_id,
)))?;
let input = self.available_inputs.swap_remove(index);
log::debug!("{account_id:?} requirement fulfilled by {:?}", input.output_id());
self.select_input(input)?;
Ok(())
}
}