use crate::{eth_to_fil_amount, ethers_address_to_fil_address};
use ethers::utils::hex;
use fvm_shared::address::Address;
use fvm_shared::econ::TokenAmount;
use recall_ipc_actors_abis::{lib_staking_change_log, subnet_actor_getter_facet};
use serde::{Deserialize, Serialize};
use std::fmt::{Display, Formatter};
pub type ConfigurationNumber = u64;
#[derive(Clone, Debug, num_enum::TryFromPrimitive, Deserialize, Serialize)]
#[non_exhaustive]
#[repr(u8)]
pub enum StakingOperation {
Deposit = 0,
Withdraw = 1,
SetMetadata = 2,
SetFederatedPower = 3,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct StakingChangeRequest {
pub configuration_number: ConfigurationNumber,
pub change: StakingChange,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct StakingChange {
pub op: StakingOperation,
pub payload: Vec<u8>,
pub validator: Address,
}
impl TryFrom<lib_staking_change_log::NewStakingChangeRequestFilter> for StakingChangeRequest {
type Error = anyhow::Error;
fn try_from(
value: lib_staking_change_log::NewStakingChangeRequestFilter,
) -> Result<Self, Self::Error> {
Ok(Self {
configuration_number: value.configuration_number,
change: StakingChange {
op: StakingOperation::try_from(value.op)?,
payload: value.payload.to_vec(),
validator: ethers_address_to_fil_address(&value.validator)?,
},
})
}
}
#[derive(Clone, Debug)]
pub struct ValidatorStakingInfo {
confirmed_collateral: TokenAmount,
total_collateral: TokenAmount,
metadata: Vec<u8>,
}
impl Display for ValidatorStakingInfo {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"ValidatorStaking(confirmed_collateral: {}, total_collateral: {}, metadata: 0x{})",
self.confirmed_collateral,
self.total_collateral,
hex::encode(&self.metadata)
)
}
}
impl TryFrom<subnet_actor_getter_facet::ValidatorInfo> for ValidatorStakingInfo {
type Error = anyhow::Error;
fn try_from(value: subnet_actor_getter_facet::ValidatorInfo) -> Result<Self, Self::Error> {
Ok(Self {
confirmed_collateral: eth_to_fil_amount(&value.confirmed_collateral)?,
total_collateral: eth_to_fil_amount(&value.total_collateral)?,
metadata: value.metadata.to_vec(),
})
}
}
#[derive(Clone, Debug)]
pub struct ValidatorInfo {
pub staking: ValidatorStakingInfo,
pub is_active: bool,
pub is_waiting: bool,
}
impl Display for ValidatorInfo {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"ValidatorInfo(staking: {}, is_active: {}, is_waiting: {})",
self.staking, self.is_active, self.is_waiting
)
}
}