use {
juniper::{graphql_object, FieldResult},
std::str::FromStr,
};
pub struct QueryRoot;
#[graphql_object(context = crate::graphql::context::GraphQLContext)]
impl QueryRoot {
async fn pool_account(
context: &crate::graphql::context::GraphQLContext,
pubkey: String,
) -> FieldResult<Option<crate::accounts::graphql::PoolAccountGraphQL>> {
use carbon_core::postgres::{operations::Lookup, primitives::Pubkey as PgPubkey};
let pk = PgPubkey(
solana_pubkey::Pubkey::from_str(&pubkey)
.map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?,
);
let row = crate::accounts::postgres::PoolAccountRow::lookup(pk, &context.pool)
.await
.map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
Ok(row.and_then(|row| row.try_into().ok()))
}
async fn list_pool_account(
context: &crate::graphql::context::GraphQLContext,
limit: i32,
offset: i32,
) -> FieldResult<Vec<crate::accounts::graphql::PoolAccountGraphQL>> {
let rows: Vec<crate::accounts::postgres::PoolAccountRow> = sqlx::query_as(
r#"SELECT * FROM pool_account_account ORDER BY __slot DESC LIMIT $1 OFFSET $2"#,
)
.bind(limit)
.bind(offset)
.fetch_all(&*context.pool)
.await
.map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
Ok(rows
.into_iter()
.filter_map(|row| row.try_into().ok())
.collect())
}
async fn lp_position_account(
context: &crate::graphql::context::GraphQLContext,
pubkey: String,
) -> FieldResult<Option<crate::accounts::graphql::LpPositionAccountGraphQL>> {
use carbon_core::postgres::{operations::Lookup, primitives::Pubkey as PgPubkey};
let pk = PgPubkey(
solana_pubkey::Pubkey::from_str(&pubkey)
.map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?,
);
let row = crate::accounts::postgres::LpPositionAccountRow::lookup(pk, &context.pool)
.await
.map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
Ok(row.and_then(|row| row.try_into().ok()))
}
async fn list_lp_position_account(
context: &crate::graphql::context::GraphQLContext,
limit: i32,
offset: i32,
) -> FieldResult<Vec<crate::accounts::graphql::LpPositionAccountGraphQL>> {
let rows: Vec<crate::accounts::postgres::LpPositionAccountRow> = sqlx::query_as(
r#"SELECT * FROM lp_position_account_account ORDER BY __slot DESC LIMIT $1 OFFSET $2"#,
)
.bind(limit)
.bind(offset)
.fetch_all(&*context.pool)
.await
.map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
Ok(rows
.into_iter()
.filter_map(|row| row.try_into().ok())
.collect())
}
async fn swap(
context: &crate::graphql::context::GraphQLContext,
signature: String,
instruction_index: i32,
) -> FieldResult<Vec<crate::instructions::graphql::SwapGraphQL>> {
let rows: Vec<crate::instructions::postgres::SwapRow> = sqlx::query_as(
r#"SELECT * FROM swap_instruction WHERE __signature = $1 AND __instruction_index = $2 ORDER BY __stack_height ASC"#,
)
.bind(signature)
.bind(instruction_index)
.fetch_all(&*context.pool)
.await
.map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
Ok(rows
.into_iter()
.filter_map(|row| row.try_into().ok())
.collect())
}
async fn list_swap(
context: &crate::graphql::context::GraphQLContext,
limit: i32,
offset: i32,
) -> FieldResult<Vec<crate::instructions::graphql::SwapGraphQL>> {
let rows: Vec<crate::instructions::postgres::SwapRow> = sqlx::query_as(
r#"SELECT * FROM swap_instruction ORDER BY __slot DESC, __signature DESC, __instruction_index ASC LIMIT $1 OFFSET $2"#,
)
.bind(limit)
.bind(offset)
.fetch_all(&*context.pool)
.await
.map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
Ok(rows
.into_iter()
.filter_map(|row| row.try_into().ok())
.collect())
}
async fn add_liquidity(
context: &crate::graphql::context::GraphQLContext,
signature: String,
instruction_index: i32,
) -> FieldResult<Vec<crate::instructions::graphql::AddLiquidityGraphQL>> {
let rows: Vec<crate::instructions::postgres::AddLiquidityRow> = sqlx::query_as(
r#"SELECT * FROM add_liquidity_instruction WHERE __signature = $1 AND __instruction_index = $2 ORDER BY __stack_height ASC"#,
)
.bind(signature)
.bind(instruction_index)
.fetch_all(&*context.pool)
.await
.map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
Ok(rows
.into_iter()
.filter_map(|row| row.try_into().ok())
.collect())
}
async fn list_add_liquidity(
context: &crate::graphql::context::GraphQLContext,
limit: i32,
offset: i32,
) -> FieldResult<Vec<crate::instructions::graphql::AddLiquidityGraphQL>> {
let rows: Vec<crate::instructions::postgres::AddLiquidityRow> = sqlx::query_as(
r#"SELECT * FROM add_liquidity_instruction ORDER BY __slot DESC, __signature DESC, __instruction_index ASC LIMIT $1 OFFSET $2"#,
)
.bind(limit)
.bind(offset)
.fetch_all(&*context.pool)
.await
.map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
Ok(rows
.into_iter()
.filter_map(|row| row.try_into().ok())
.collect())
}
async fn remove_liquidity(
context: &crate::graphql::context::GraphQLContext,
signature: String,
instruction_index: i32,
) -> FieldResult<Vec<crate::instructions::graphql::RemoveLiquidityGraphQL>> {
let rows: Vec<crate::instructions::postgres::RemoveLiquidityRow> = sqlx::query_as(
r#"SELECT * FROM remove_liquidity_instruction WHERE __signature = $1 AND __instruction_index = $2 ORDER BY __stack_height ASC"#,
)
.bind(signature)
.bind(instruction_index)
.fetch_all(&*context.pool)
.await
.map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
Ok(rows
.into_iter()
.filter_map(|row| row.try_into().ok())
.collect())
}
async fn list_remove_liquidity(
context: &crate::graphql::context::GraphQLContext,
limit: i32,
offset: i32,
) -> FieldResult<Vec<crate::instructions::graphql::RemoveLiquidityGraphQL>> {
let rows: Vec<crate::instructions::postgres::RemoveLiquidityRow> = sqlx::query_as(
r#"SELECT * FROM remove_liquidity_instruction ORDER BY __slot DESC, __signature DESC, __instruction_index ASC LIMIT $1 OFFSET $2"#,
)
.bind(limit)
.bind(offset)
.fetch_all(&*context.pool)
.await
.map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
Ok(rows
.into_iter()
.filter_map(|row| row.try_into().ok())
.collect())
}
async fn renounce_liquidity(
context: &crate::graphql::context::GraphQLContext,
signature: String,
instruction_index: i32,
) -> FieldResult<Vec<crate::instructions::graphql::RenounceLiquidityGraphQL>> {
let rows: Vec<crate::instructions::postgres::RenounceLiquidityRow> = sqlx::query_as(
r#"SELECT * FROM renounce_liquidity_instruction WHERE __signature = $1 AND __instruction_index = $2 ORDER BY __stack_height ASC"#,
)
.bind(signature)
.bind(instruction_index)
.fetch_all(&*context.pool)
.await
.map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
Ok(rows
.into_iter()
.filter_map(|row| row.try_into().ok())
.collect())
}
async fn list_renounce_liquidity(
context: &crate::graphql::context::GraphQLContext,
limit: i32,
offset: i32,
) -> FieldResult<Vec<crate::instructions::graphql::RenounceLiquidityGraphQL>> {
let rows: Vec<crate::instructions::postgres::RenounceLiquidityRow> = sqlx::query_as(
r#"SELECT * FROM renounce_liquidity_instruction ORDER BY __slot DESC, __signature DESC, __instruction_index ASC LIMIT $1 OFFSET $2"#,
)
.bind(limit)
.bind(offset)
.fetch_all(&*context.pool)
.await
.map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
Ok(rows
.into_iter()
.filter_map(|row| row.try_into().ok())
.collect())
}
async fn withdraw_lp_fees(
context: &crate::graphql::context::GraphQLContext,
signature: String,
instruction_index: i32,
) -> FieldResult<Vec<crate::instructions::graphql::WithdrawLpFeesGraphQL>> {
let rows: Vec<crate::instructions::postgres::WithdrawLpFeesRow> = sqlx::query_as(
r#"SELECT * FROM withdraw_lp_fees_instruction WHERE __signature = $1 AND __instruction_index = $2 ORDER BY __stack_height ASC"#,
)
.bind(signature)
.bind(instruction_index)
.fetch_all(&*context.pool)
.await
.map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
Ok(rows
.into_iter()
.filter_map(|row| row.try_into().ok())
.collect())
}
async fn list_withdraw_lp_fees(
context: &crate::graphql::context::GraphQLContext,
limit: i32,
offset: i32,
) -> FieldResult<Vec<crate::instructions::graphql::WithdrawLpFeesGraphQL>> {
let rows: Vec<crate::instructions::postgres::WithdrawLpFeesRow> = sqlx::query_as(
r#"SELECT * FROM withdraw_lp_fees_instruction ORDER BY __slot DESC, __signature DESC, __instruction_index ASC LIMIT $1 OFFSET $2"#,
)
.bind(limit)
.bind(offset)
.fetch_all(&*context.pool)
.await
.map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
Ok(rows
.into_iter()
.filter_map(|row| row.try_into().ok())
.collect())
}
async fn initialize_lp_position(
context: &crate::graphql::context::GraphQLContext,
signature: String,
instruction_index: i32,
) -> FieldResult<Vec<crate::instructions::graphql::InitializeLpPositionGraphQL>> {
let rows: Vec<crate::instructions::postgres::InitializeLpPositionRow> = sqlx::query_as(
r#"SELECT * FROM initialize_lp_position_instruction WHERE __signature = $1 AND __instruction_index = $2 ORDER BY __stack_height ASC"#,
)
.bind(signature)
.bind(instruction_index)
.fetch_all(&*context.pool)
.await
.map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
Ok(rows
.into_iter()
.filter_map(|row| row.try_into().ok())
.collect())
}
async fn list_initialize_lp_position(
context: &crate::graphql::context::GraphQLContext,
limit: i32,
offset: i32,
) -> FieldResult<Vec<crate::instructions::graphql::InitializeLpPositionGraphQL>> {
let rows: Vec<crate::instructions::postgres::InitializeLpPositionRow> = sqlx::query_as(
r#"SELECT * FROM initialize_lp_position_instruction ORDER BY __slot DESC, __signature DESC, __instruction_index ASC LIMIT $1 OFFSET $2"#,
)
.bind(limit)
.bind(offset)
.fetch_all(&*context.pool)
.await
.map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
Ok(rows
.into_iter()
.filter_map(|row| row.try_into().ok())
.collect())
}
async fn initialize_pool(
context: &crate::graphql::context::GraphQLContext,
signature: String,
instruction_index: i32,
) -> FieldResult<Vec<crate::instructions::graphql::InitializePoolGraphQL>> {
let rows: Vec<crate::instructions::postgres::InitializePoolRow> = sqlx::query_as(
r#"SELECT * FROM initialize_pool_instruction WHERE __signature = $1 AND __instruction_index = $2 ORDER BY __stack_height ASC"#,
)
.bind(signature)
.bind(instruction_index)
.fetch_all(&*context.pool)
.await
.map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
Ok(rows
.into_iter()
.filter_map(|row| row.try_into().ok())
.collect())
}
async fn list_initialize_pool(
context: &crate::graphql::context::GraphQLContext,
limit: i32,
offset: i32,
) -> FieldResult<Vec<crate::instructions::graphql::InitializePoolGraphQL>> {
let rows: Vec<crate::instructions::postgres::InitializePoolRow> = sqlx::query_as(
r#"SELECT * FROM initialize_pool_instruction ORDER BY __slot DESC, __signature DESC, __instruction_index ASC LIMIT $1 OFFSET $2"#,
)
.bind(limit)
.bind(offset)
.fetch_all(&*context.pool)
.await
.map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
Ok(rows
.into_iter()
.filter_map(|row| row.try_into().ok())
.collect())
}
async fn withdraw_protocol_fees(
context: &crate::graphql::context::GraphQLContext,
signature: String,
instruction_index: i32,
) -> FieldResult<Vec<crate::instructions::graphql::WithdrawProtocolFeesGraphQL>> {
let rows: Vec<crate::instructions::postgres::WithdrawProtocolFeesRow> = sqlx::query_as(
r#"SELECT * FROM withdraw_protocol_fees_instruction WHERE __signature = $1 AND __instruction_index = $2 ORDER BY __stack_height ASC"#,
)
.bind(signature)
.bind(instruction_index)
.fetch_all(&*context.pool)
.await
.map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
Ok(rows
.into_iter()
.filter_map(|row| row.try_into().ok())
.collect())
}
async fn list_withdraw_protocol_fees(
context: &crate::graphql::context::GraphQLContext,
limit: i32,
offset: i32,
) -> FieldResult<Vec<crate::instructions::graphql::WithdrawProtocolFeesGraphQL>> {
let rows: Vec<crate::instructions::postgres::WithdrawProtocolFeesRow> = sqlx::query_as(
r#"SELECT * FROM withdraw_protocol_fees_instruction ORDER BY __slot DESC, __signature DESC, __instruction_index ASC LIMIT $1 OFFSET $2"#,
)
.bind(limit)
.bind(offset)
.fetch_all(&*context.pool)
.await
.map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
Ok(rows
.into_iter()
.filter_map(|row| row.try_into().ok())
.collect())
}
async fn log(
context: &crate::graphql::context::GraphQLContext,
signature: String,
instruction_index: i32,
) -> FieldResult<Vec<crate::instructions::graphql::LogGraphQL>> {
let rows: Vec<crate::instructions::postgres::LogRow> = sqlx::query_as(
r#"SELECT * FROM log_instruction WHERE __signature = $1 AND __instruction_index = $2 ORDER BY __stack_height ASC"#,
)
.bind(signature)
.bind(instruction_index)
.fetch_all(&*context.pool)
.await
.map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
Ok(rows
.into_iter()
.filter_map(|row| row.try_into().ok())
.collect())
}
async fn list_log(
context: &crate::graphql::context::GraphQLContext,
limit: i32,
offset: i32,
) -> FieldResult<Vec<crate::instructions::graphql::LogGraphQL>> {
let rows: Vec<crate::instructions::postgres::LogRow> = sqlx::query_as(
r#"SELECT * FROM log_instruction ORDER BY __slot DESC, __signature DESC, __instruction_index ASC LIMIT $1 OFFSET $2"#,
)
.bind(limit)
.bind(offset)
.fetch_all(&*context.pool)
.await
.map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
Ok(rows
.into_iter()
.filter_map(|row| row.try_into().ok())
.collect())
}
async fn transfer_liquidity(
context: &crate::graphql::context::GraphQLContext,
signature: String,
instruction_index: i32,
) -> FieldResult<Vec<crate::instructions::graphql::TransferLiquidityGraphQL>> {
let rows: Vec<crate::instructions::postgres::TransferLiquidityRow> = sqlx::query_as(
r#"SELECT * FROM transfer_liquidity_instruction WHERE __signature = $1 AND __instruction_index = $2 ORDER BY __stack_height ASC"#,
)
.bind(signature)
.bind(instruction_index)
.fetch_all(&*context.pool)
.await
.map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
Ok(rows
.into_iter()
.filter_map(|row| row.try_into().ok())
.collect())
}
async fn list_transfer_liquidity(
context: &crate::graphql::context::GraphQLContext,
limit: i32,
offset: i32,
) -> FieldResult<Vec<crate::instructions::graphql::TransferLiquidityGraphQL>> {
let rows: Vec<crate::instructions::postgres::TransferLiquidityRow> = sqlx::query_as(
r#"SELECT * FROM transfer_liquidity_instruction ORDER BY __slot DESC, __signature DESC, __instruction_index ASC LIMIT $1 OFFSET $2"#,
)
.bind(limit)
.bind(offset)
.fetch_all(&*context.pool)
.await
.map_err(|e| juniper::FieldError::new(e.to_string(), juniper::Value::null()))?;
Ok(rows
.into_iter()
.filter_map(|row| row.try_into().ok())
.collect())
}
}