use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use crate::{
client::{node_manager::node::Node, secret::SecretManage},
types::{
api::plugins::participation::{
responses::TrackedParticipation,
types::{ParticipationEventData, ParticipationEventId, PARTICIPATION_TAG},
},
block::output::{unlock_condition::UnlockCondition, Output, OutputId},
},
wallet::{core::WalletLedger, types::OutputData, Wallet},
};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ParticipationOverview {
pub participations: HashMap<ParticipationEventId, HashMap<OutputId, TrackedParticipation>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
pub struct ParticipationEventWithNodes {
pub id: ParticipationEventId,
pub data: ParticipationEventData,
pub nodes: Vec<Node>,
}
impl<S: 'static + SecretManage> Wallet<S> {
pub async fn get_voting_output(&self) -> Option<OutputData> {
self.ledger().await.get_voting_output()
}
}
impl WalletLedger {
pub(crate) fn get_voting_output(&self) -> Option<OutputData> {
log::debug!("[get_voting_output]");
self.unspent_outputs
.values()
.filter(|output_data| is_valid_participation_output(&output_data.output))
.max_by_key(|output_data| output_data.output.amount())
.cloned()
}
}
fn is_valid_participation_output(output: &Output) -> bool {
if let Output::Basic(basic_output) = &output {
let [UnlockCondition::Address(_)] = basic_output.unlock_conditions().as_ref() else {
return false;
};
basic_output
.features()
.tag()
.map_or(false, |tag| tag.tag() == PARTICIPATION_TAG.as_bytes())
} else {
false
}
}
#[cfg(test)]
impl ParticipationEventWithNodes {
pub fn mock() -> Self {
Self {
id: ParticipationEventId::new([42; 32]),
data: ParticipationEventData::mock(),
nodes: Vec::new(),
}
}
}