carbon-orca-whirlpool-decoder 1.0.0

Orca Whirlpool Decoder
Documentation
//! This code was AUTOGENERATED using the Codama library.
use {
    crate::types::WhirlpoolRewardInfo,
    carbon_core::{
        account::AccountMetadata,
        postgres::{
            metadata::AccountRowMetadata,
            primitives::{Pubkey, U128, U16, U64},
        },
    },
};

#[derive(sqlx::FromRow, Debug, Clone)]
pub struct WhirlpoolRow {
    #[sqlx(flatten)]
    pub account_metadata: AccountRowMetadata,
    pub whirlpools_config: Pubkey,
    pub whirlpool_bump: Vec<u8>,
    pub tick_spacing: U16,
    pub fee_tier_index_seed: Vec<u8>,
    pub fee_rate: U16,
    pub protocol_fee_rate: U16,
    pub liquidity: U128,
    pub sqrt_price: U128,
    pub tick_current_index: i32,
    pub protocol_fee_owed_a: U64,
    pub protocol_fee_owed_b: U64,
    pub token_mint_a: Pubkey,
    pub token_vault_a: Pubkey,
    pub fee_growth_global_a: U128,
    pub token_mint_b: Pubkey,
    pub token_vault_b: Pubkey,
    pub fee_growth_global_b: U128,
    pub reward_last_updated_timestamp: U64,
    pub reward_infos: sqlx::types::Json<Vec<WhirlpoolRewardInfo>>,
}

impl WhirlpoolRow {
    pub fn from_parts(
        source: crate::accounts::whirlpool::Whirlpool,
        metadata: AccountMetadata,
    ) -> Self {
        Self {
            account_metadata: metadata.into(),
            whirlpools_config: source.whirlpools_config.into(),
            whirlpool_bump: source.whirlpool_bump.to_vec(),
            tick_spacing: source.tick_spacing.into(),
            fee_tier_index_seed: source.fee_tier_index_seed.to_vec(),
            fee_rate: source.fee_rate.into(),
            protocol_fee_rate: source.protocol_fee_rate.into(),
            liquidity: source.liquidity.into(),
            sqrt_price: source.sqrt_price.into(),
            tick_current_index: source.tick_current_index,
            protocol_fee_owed_a: source.protocol_fee_owed_a.into(),
            protocol_fee_owed_b: source.protocol_fee_owed_b.into(),
            token_mint_a: source.token_mint_a.into(),
            token_vault_a: source.token_vault_a.into(),
            fee_growth_global_a: source.fee_growth_global_a.into(),
            token_mint_b: source.token_mint_b.into(),
            token_vault_b: source.token_vault_b.into(),
            fee_growth_global_b: source.fee_growth_global_b.into(),
            reward_last_updated_timestamp: source.reward_last_updated_timestamp.into(),
            reward_infos: sqlx::types::Json(source.reward_infos.to_vec()),
        }
    }
}

impl TryFrom<WhirlpoolRow> for crate::accounts::whirlpool::Whirlpool {
    type Error = carbon_core::error::Error;
    fn try_from(source: WhirlpoolRow) -> Result<Self, Self::Error> {
        Ok(Self {
            whirlpools_config: *source.whirlpools_config,
            whirlpool_bump: source.whirlpool_bump.as_slice().try_into().map_err(|_| {
                carbon_core::error::Error::Custom(
                    "Failed to convert padding from postgres primitive: expected 1 bytes"
                        .to_string(),
                )
            })?,
            tick_spacing: source.tick_spacing.try_into().map_err(|_| {
                carbon_core::error::Error::Custom(
                    "Failed to convert value from postgres primitive".to_string(),
                )
            })?,
            fee_tier_index_seed: source.fee_tier_index_seed.as_slice().try_into().map_err(
                |_| {
                    carbon_core::error::Error::Custom(
                        "Failed to convert padding from postgres primitive: expected 2 bytes"
                            .to_string(),
                    )
                },
            )?,
            fee_rate: source.fee_rate.try_into().map_err(|_| {
                carbon_core::error::Error::Custom(
                    "Failed to convert value from postgres primitive".to_string(),
                )
            })?,
            protocol_fee_rate: source.protocol_fee_rate.try_into().map_err(|_| {
                carbon_core::error::Error::Custom(
                    "Failed to convert value from postgres primitive".to_string(),
                )
            })?,
            liquidity: *source.liquidity,
            sqrt_price: *source.sqrt_price,
            tick_current_index: source.tick_current_index,
            protocol_fee_owed_a: *source.protocol_fee_owed_a,
            protocol_fee_owed_b: *source.protocol_fee_owed_b,
            token_mint_a: *source.token_mint_a,
            token_vault_a: *source.token_vault_a,
            fee_growth_global_a: *source.fee_growth_global_a,
            token_mint_b: *source.token_mint_b,
            token_vault_b: *source.token_vault_b,
            fee_growth_global_b: *source.fee_growth_global_b,
            reward_last_updated_timestamp: *source.reward_last_updated_timestamp,
            reward_infos: source
                .reward_infos
                .0
                .into_iter()
                .collect::<Vec<_>>()
                .try_into()
                .map_err(|_| {
                    carbon_core::error::Error::Custom(
                        "Failed to convert value from postgres primitive".to_string(),
                    )
                })?,
        })
    }
}

impl carbon_core::postgres::operations::Table for crate::accounts::whirlpool::Whirlpool {
    fn table() -> &'static str {
        "whirlpool_account"
    }

    fn columns() -> Vec<&'static str> {
        vec![
            "__pubkey",
            "__slot",
            "whirlpools_config",
            "whirlpool_bump",
            "tick_spacing",
            "fee_tier_index_seed",
            "fee_rate",
            "protocol_fee_rate",
            "liquidity",
            "sqrt_price",
            "tick_current_index",
            "protocol_fee_owed_a",
            "protocol_fee_owed_b",
            "token_mint_a",
            "token_vault_a",
            "fee_growth_global_a",
            "token_mint_b",
            "token_vault_b",
            "fee_growth_global_b",
            "reward_last_updated_timestamp",
            "reward_infos",
        ]
    }
}

#[async_trait::async_trait]
impl carbon_core::postgres::operations::Insert for WhirlpoolRow {
    async fn insert(&self, pool: &sqlx::PgPool) -> carbon_core::error::CarbonResult<()> {
        sqlx::query(r#"
            INSERT INTO whirlpool_account (
                "whirlpools_config",
                "whirlpool_bump",
                "tick_spacing",
                "fee_tier_index_seed",
                "fee_rate",
                "protocol_fee_rate",
                "liquidity",
                "sqrt_price",
                "tick_current_index",
                "protocol_fee_owed_a",
                "protocol_fee_owed_b",
                "token_mint_a",
                "token_vault_a",
                "fee_growth_global_a",
                "token_mint_b",
                "token_vault_b",
                "fee_growth_global_b",
                "reward_last_updated_timestamp",
                "reward_infos",
                __pubkey, __slot
            ) VALUES (
                $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21
            )"#)
        .bind(self.whirlpools_config)
        .bind(&self.whirlpool_bump)
        .bind(self.tick_spacing)
        .bind(&self.fee_tier_index_seed)
        .bind(self.fee_rate)
        .bind(self.protocol_fee_rate)
        .bind(&self.liquidity)
        .bind(&self.sqrt_price)
        .bind(self.tick_current_index)
        .bind(&self.protocol_fee_owed_a)
        .bind(&self.protocol_fee_owed_b)
        .bind(self.token_mint_a)
        .bind(self.token_vault_a)
        .bind(&self.fee_growth_global_a)
        .bind(self.token_mint_b)
        .bind(self.token_vault_b)
        .bind(&self.fee_growth_global_b)
        .bind(&self.reward_last_updated_timestamp)
        .bind(&self.reward_infos)
        .bind(self.account_metadata.pubkey)
        .bind(&self.account_metadata.slot)
        .execute(pool).await
        .map_err(|e| carbon_core::error::Error::Custom(e.to_string()))?;
        Ok(())
    }
}

#[async_trait::async_trait]
impl carbon_core::postgres::operations::Upsert for WhirlpoolRow {
    async fn upsert(&self, pool: &sqlx::PgPool) -> carbon_core::error::CarbonResult<()> {
        sqlx::query(r#"INSERT INTO whirlpool_account (
                "whirlpools_config",
                "whirlpool_bump",
                "tick_spacing",
                "fee_tier_index_seed",
                "fee_rate",
                "protocol_fee_rate",
                "liquidity",
                "sqrt_price",
                "tick_current_index",
                "protocol_fee_owed_a",
                "protocol_fee_owed_b",
                "token_mint_a",
                "token_vault_a",
                "fee_growth_global_a",
                "token_mint_b",
                "token_vault_b",
                "fee_growth_global_b",
                "reward_last_updated_timestamp",
                "reward_infos",
                __pubkey, __slot
            ) VALUES (
                $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21
            ) ON CONFLICT (
                __pubkey
            ) DO UPDATE SET
                "whirlpools_config" = EXCLUDED."whirlpools_config",
                "whirlpool_bump" = EXCLUDED."whirlpool_bump",
                "tick_spacing" = EXCLUDED."tick_spacing",
                "fee_tier_index_seed" = EXCLUDED."fee_tier_index_seed",
                "fee_rate" = EXCLUDED."fee_rate",
                "protocol_fee_rate" = EXCLUDED."protocol_fee_rate",
                "liquidity" = EXCLUDED."liquidity",
                "sqrt_price" = EXCLUDED."sqrt_price",
                "tick_current_index" = EXCLUDED."tick_current_index",
                "protocol_fee_owed_a" = EXCLUDED."protocol_fee_owed_a",
                "protocol_fee_owed_b" = EXCLUDED."protocol_fee_owed_b",
                "token_mint_a" = EXCLUDED."token_mint_a",
                "token_vault_a" = EXCLUDED."token_vault_a",
                "fee_growth_global_a" = EXCLUDED."fee_growth_global_a",
                "token_mint_b" = EXCLUDED."token_mint_b",
                "token_vault_b" = EXCLUDED."token_vault_b",
                "fee_growth_global_b" = EXCLUDED."fee_growth_global_b",
                "reward_last_updated_timestamp" = EXCLUDED."reward_last_updated_timestamp",
                "reward_infos" = EXCLUDED."reward_infos",
                __slot = EXCLUDED.__slot
            "#)
        .bind(self.whirlpools_config)
        .bind(&self.whirlpool_bump)
        .bind(self.tick_spacing)
        .bind(&self.fee_tier_index_seed)
        .bind(self.fee_rate)
        .bind(self.protocol_fee_rate)
        .bind(&self.liquidity)
        .bind(&self.sqrt_price)
        .bind(self.tick_current_index)
        .bind(&self.protocol_fee_owed_a)
        .bind(&self.protocol_fee_owed_b)
        .bind(self.token_mint_a)
        .bind(self.token_vault_a)
        .bind(&self.fee_growth_global_a)
        .bind(self.token_mint_b)
        .bind(self.token_vault_b)
        .bind(&self.fee_growth_global_b)
        .bind(&self.reward_last_updated_timestamp)
        .bind(&self.reward_infos)
        .bind(self.account_metadata.pubkey)
        .bind(&self.account_metadata.slot)
        .execute(pool).await
        .map_err(|e| carbon_core::error::Error::Custom(e.to_string()))?;
        Ok(())
    }
}

#[async_trait::async_trait]
impl carbon_core::postgres::operations::Delete for WhirlpoolRow {
    type Key = carbon_core::postgres::primitives::Pubkey;

    async fn delete(key: Self::Key, pool: &sqlx::PgPool) -> carbon_core::error::CarbonResult<()> {
        sqlx::query(
            r#"DELETE FROM whirlpool_account WHERE
                __pubkey = $1
            "#,
        )
        .bind(key)
        .execute(pool)
        .await
        .map_err(|e| carbon_core::error::Error::Custom(e.to_string()))?;
        Ok(())
    }
}

#[async_trait::async_trait]
impl carbon_core::postgres::operations::Lookup for WhirlpoolRow {
    type Key = carbon_core::postgres::primitives::Pubkey;

    async fn lookup(
        key: Self::Key,
        pool: &sqlx::PgPool,
    ) -> carbon_core::error::CarbonResult<Option<Self>> {
        let row = sqlx::query_as(
            r#"SELECT * FROM whirlpool_account WHERE
                __pubkey = $1
            "#,
        )
        .bind(key)
        .fetch_optional(pool)
        .await
        .map_err(|e| carbon_core::error::Error::Custom(e.to_string()))?;
        Ok(row)
    }
}

pub struct WhirlpoolMigrationOperation;

#[async_trait::async_trait]
impl sqlx_migrator::Operation<sqlx::Postgres> for WhirlpoolMigrationOperation {
    async fn up(
        &self,
        connection: &mut sqlx::PgConnection,
    ) -> Result<(), sqlx_migrator::error::Error> {
        sqlx::query(
            r#"CREATE TABLE IF NOT EXISTS whirlpool_account (
                -- Account data
                "whirlpools_config" BYTEA NOT NULL,
                "whirlpool_bump" BYTEA NOT NULL,
                "tick_spacing" INT4 NOT NULL,
                "fee_tier_index_seed" BYTEA NOT NULL,
                "fee_rate" INT4 NOT NULL,
                "protocol_fee_rate" INT4 NOT NULL,
                "liquidity" NUMERIC(39) NOT NULL,
                "sqrt_price" NUMERIC(39) NOT NULL,
                "tick_current_index" INT4 NOT NULL,
                "protocol_fee_owed_a" NUMERIC(20) NOT NULL,
                "protocol_fee_owed_b" NUMERIC(20) NOT NULL,
                "token_mint_a" BYTEA NOT NULL,
                "token_vault_a" BYTEA NOT NULL,
                "fee_growth_global_a" NUMERIC(39) NOT NULL,
                "token_mint_b" BYTEA NOT NULL,
                "token_vault_b" BYTEA NOT NULL,
                "fee_growth_global_b" NUMERIC(39) NOT NULL,
                "reward_last_updated_timestamp" NUMERIC(20) NOT NULL,
                "reward_infos" JSONB NOT NULL,
                -- Account metadata
                __pubkey BYTEA NOT NULL,
                __slot NUMERIC(20),
                PRIMARY KEY (__pubkey)
            )"#,
        )
        .execute(connection)
        .await?;
        Ok(())
    }

    async fn down(
        &self,
        connection: &mut sqlx::PgConnection,
    ) -> Result<(), sqlx_migrator::error::Error> {
        sqlx::query(r#"DROP TABLE IF EXISTS whirlpool_account"#)
            .execute(connection)
            .await?;
        Ok(())
    }
}