yellowstone-vixen-pumpfun-parser 0.5.1

Vixen program parser for Pumpfun program
Documentation
//! This code was AUTOGENERATED using the codama library.
//! Please DO NOT EDIT THIS FILE, instead use visitors
//! to add features, then rerun codama to update it.
//!
//! <https://github.com/codama-idl/codama>
//!

use crate::{
    accounts::{BondingCurve, Global},
    deserialize_checked, ID,
};

/// Pump Program State
#[allow(clippy::large_enum_variant)]
#[derive(Debug)]
#[cfg_attr(feature = "tracing", derive(strum_macros::Display))]
pub enum PumpProgramState {
    BondingCurve(BondingCurve),
    Global(Global),
}

impl PumpProgramState {
    pub fn try_unpack(data_bytes: &[u8]) -> yellowstone_vixen_core::ParseResult<Self> {
        let acc_discriminator: [u8; 8] = data_bytes[0..8].try_into()?;
        let acc = match acc_discriminator {
            [23, 183, 248, 55, 96, 216, 172, 96] => Ok(PumpProgramState::BondingCurve(
                deserialize_checked(data_bytes, &acc_discriminator)?,
            )),
            [167, 232, 232, 177, 200, 108, 114, 127] => Ok(PumpProgramState::Global(
                deserialize_checked(data_bytes, &acc_discriminator)?,
            )),
            _ => Err(yellowstone_vixen_core::ParseError::from(
                "Invalid Account discriminator".to_owned(),
            )),
        };

        #[cfg(feature = "tracing")]
        match &acc {
            Ok(acc) => {
                tracing::info!(
                    name: "correctly_parsed_account",
                    name = "account_update",
                    program = ID.to_string(),
                    account = acc.to_string()
                );
            },
            Err(e) => {
                tracing::info!(
                    name: "incorrectly_parsed_account",
                    name = "account_update",
                    program = ID.to_string(),
                    account = "error",
                    discriminator = ?acc_discriminator,
                    error = ?e
                );
            },
        }

        acc
    }
}

#[derive(Debug, Copy, Clone)]
pub struct AccountParser;

impl yellowstone_vixen_core::Parser for AccountParser {
    type Input = yellowstone_vixen_core::AccountUpdate;
    type Output = PumpProgramState;

    fn id(&self) -> std::borrow::Cow<'static, str> { "pump::AccountParser".into() }

    fn prefilter(&self) -> yellowstone_vixen_core::Prefilter {
        yellowstone_vixen_core::Prefilter::builder()
            .account_owners([ID])
            .build()
            .unwrap()
    }

    async fn parse(
        &self,
        acct: &yellowstone_vixen_core::AccountUpdate,
    ) -> yellowstone_vixen_core::ParseResult<Self::Output> {
        let inner = acct
            .account
            .as_ref()
            .ok_or(solana_program_error::ProgramError::InvalidArgument)?;
        let res = PumpProgramState::try_unpack(&inner.data);

        #[cfg(feature = "tracing")]
        if let Err(e) = &res {
            let acc_discriminator: [u8; 8] = inner.data[0..8].try_into()?;
            tracing::info!(
                name: "incorrectly_parsed_account",
                name = "account_update",
                program = ID.to_string(),
                account = "deserialization_error",
                discriminator = ?acc_discriminator,
                error = ?e
            );
        }

        res
    }
}

impl yellowstone_vixen_core::ProgramParser for AccountParser {
    #[inline]
    fn program_id(&self) -> yellowstone_vixen_core::Pubkey { ID.to_bytes().into() }
}

// #[cfg(feature = "proto")]
mod proto_parser {
    use yellowstone_vixen_core::proto::ParseProto;

    use super::{AccountParser, BondingCurve, PumpProgramState};
    use crate::{proto_def, proto_helpers::proto_types_parsers::IntoProto};
    impl IntoProto<proto_def::BondingCurve> for BondingCurve {
        fn into_proto(self) -> proto_def::BondingCurve {
            proto_def::BondingCurve {
                virtual_token_reserves: self.virtual_token_reserves,
                virtual_sol_reserves: self.virtual_sol_reserves,
                real_token_reserves: self.real_token_reserves,
                real_sol_reserves: self.real_sol_reserves,
                token_total_supply: self.token_total_supply,
                complete: self.complete,
                creator: self.creator.to_string(),
            }
        }
    }
    use super::Global;
    impl IntoProto<proto_def::Global> for Global {
        fn into_proto(self) -> proto_def::Global {
            proto_def::Global {
                initialized: self.initialized,
                authority: self.authority.to_string(),
                fee_recipient: self.fee_recipient.to_string(),
                initial_virtual_token_reserves: self.initial_virtual_token_reserves,
                initial_virtual_sol_reserves: self.initial_virtual_sol_reserves,
                initial_real_token_reserves: self.initial_real_token_reserves,
                token_total_supply: self.token_total_supply,
                fee_basis_points: self.fee_basis_points,
                withdraw_authority: self.withdraw_authority.to_string(),
                enable_migrate: self.enable_migrate,
                pool_migration_fee: self.pool_migration_fee,
                creator_fee_basis_points: self.creator_fee_basis_points,
                fee_recipients: self
                    .fee_recipients
                    .into_iter()
                    .map(|x| x.to_string())
                    .collect(),
                set_creator_authority: self.set_creator_authority.to_string(),
            }
        }
    }

    impl IntoProto<proto_def::ProgramState> for PumpProgramState {
        fn into_proto(self) -> proto_def::ProgramState {
            let state_oneof = match self {
                PumpProgramState::BondingCurve(data) => {
                    proto_def::program_state::StateOneof::BondingCurve(data.into_proto())
                },
                PumpProgramState::Global(data) => {
                    proto_def::program_state::StateOneof::Global(data.into_proto())
                },
            };

            proto_def::ProgramState {
                state_oneof: Some(state_oneof),
            }
        }
    }

    impl ParseProto for AccountParser {
        type Message = proto_def::ProgramState;

        fn output_into_message(value: Self::Output) -> Self::Message { value.into_proto() }
    }
}