use super::{Requirement, TransactionBuilder, TransactionBuilderError};
use crate::{client::secret::types::InputSigningData, types::block::address::Address};
impl TransactionBuilder {
fn selected_unlocks_ed25519_address(&self, input: &InputSigningData, address: &Address) -> bool {
let required_address = input
.output
.required_address(
self.latest_slot_commitment_id.slot_index(),
self.protocol_parameters.committable_age_range(),
)
.unwrap()
.expect("expiration unlockable outputs already filtered out");
&required_address == address
}
fn available_has_ed25519_address(&self, input: &InputSigningData, address: &Address) -> bool {
let required_address = input
.output
.required_address(
self.latest_slot_commitment_id.slot_index(),
self.protocol_parameters.committable_age_range(),
)
.unwrap()
.expect("expiration unlockable outputs already filtered out");
required_address
.backing_ed25519()
.map_or(false, |a| a == address.as_ed25519())
}
pub(crate) fn fulfill_ed25519_requirement(&mut self, address: &Address) -> Result<(), TransactionBuilderError> {
if let Some(input) = self
.selected_inputs
.iter()
.find(|input| self.selected_unlocks_ed25519_address(input, address))
{
log::debug!(
"{address:?} sender requirement already fulfilled by {:?}",
input.output_id()
);
return Ok(());
}
if !self.allow_additional_input_selection {
return Err(TransactionBuilderError::AdditionalInputsRequired(Requirement::Ed25519(
address.clone(),
)));
}
let found = if let Some((index, _)) = self
.available_inputs
.iter()
.enumerate()
.find(|(_, input)| input.output.is_basic() && self.available_has_ed25519_address(input, address))
{
Some(index)
} else {
self.available_inputs.iter().enumerate().find_map(|(index, input)| {
(!input.output.is_basic() && self.available_has_ed25519_address(input, address)).then_some(index)
})
};
match found {
Some(index) => {
let input = self.available_inputs.swap_remove(index);
log::debug!("{address:?} sender requirement fulfilled by {:?}", input.output_id(),);
self.select_input(input)?;
Ok(())
}
None => Err(TransactionBuilderError::UnfulfillableRequirement(Requirement::Ed25519(
address.clone(),
))),
}
}
}