use af_sui_types::TransactionEffects as TransactionEffectsSdk;
use cynic::GraphQlResponse;
use sui_gql_schema::scalars;
use crate::{GraphQlClient, GraphQlErrors, GraphQlResponseExt, schema};
#[derive(cynic::QueryVariables, Clone, Debug)]
pub struct Variables {
pub tx_bytes: String,
pub signatures: Vec<String>,
}
#[derive(cynic::QueryFragment, Clone, Debug)]
#[cynic(variables = "Variables")]
pub struct Mutation {
#[arguments(transactionDataBcs: $tx_bytes, signatures: $signatures)]
pub execute_transaction: ExecutionResult,
}
impl Mutation {
#[allow(clippy::future_not_send)]
pub async fn execute<Client: GraphQlClient>(
client: &Client,
tx_bytes: String,
signatures: Vec<String>,
) -> Result<TransactionEffectsSdk, Error<Client::Error>> {
let result: GraphQlResponse<Self> = client
.mutation(Variables {
tx_bytes,
signatures,
})
.await
.map_err(Error::Client)?;
let Some(Self {
execute_transaction: ExecutionResult { effects, errors },
}) = result.try_into_data()?
else {
return Err(Error::NoData);
};
if let Some(errors) = errors {
return Err(Error::Execution(errors));
}
if let Some(eff) = effects {
if let Some(eff_bcs) = eff.effects_bcs {
Ok(eff_bcs.try_into()?)
}
} else {
return Err(Error::NoData);
}
}
}
#[derive(thiserror::Error, Debug)]
pub enum Error<T> {
#[error("No data in transaction GQL response")]
NoData,
#[error(transparent)]
Client(T),
#[error(transparent)]
GraphQlResponse(#[from] GraphQlErrors),
#[error("Executing transaction: {0:?}")]
Execution(Vec<String>),
}
#[derive(cynic::QueryFragment, Clone, Debug)]
pub struct ExecutionResult {
pub effects: Option<TransactionEffects>,
pub errors: Option<Vec<String>>,
}
#[derive(cynic::QueryFragment, Clone, Debug)]
pub struct TransactionEffects {
pub effects_bcs: Option<scalars::Base64Bcs<TransactionEffectsSdk>>,
}