use super::{InvalidAddressError, QueryFailedError, Uint64, schema};
use crate::{
api::ChainAddress,
errors::{BlokliClientError, ErrorKind},
};
#[derive(cynic::Enum, Clone, Copy, Debug, PartialEq, Eq)]
pub enum SafeSelectorInput {
#[cynic(rename = "ADDRESS")]
Address,
#[cynic(rename = "OWNER")]
Owner,
#[cynic(rename = "CHAIN_KEY")]
ChainKey,
#[cynic(rename = "REGISTERED_NODE")]
RegisteredNode,
}
#[derive(cynic::QueryVariables, Debug)]
pub struct SafeByVariables {
pub selector: SafeSelectorInput,
pub address: String,
}
#[derive(cynic::QueryFragment, Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct Safe {
pub address: String,
pub chain_key: String,
pub owners: Vec<String>,
pub module_address: String,
pub registered_nodes: Vec<String>,
pub threshold: Option<String>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "QueryRoot", variables = "SafeByVariables")]
pub struct QuerySafeBy {
#[arguments(selector: $selector, address: $address)]
pub safe_by: Option<SafeByResult>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "SubscriptionRoot")]
pub struct SubscribeSafeDeployment {
pub safe_deployed: Safe,
}
#[derive(cynic::QueryVariables, Debug)]
pub struct ModuleAddressVariables {
pub nonce: Uint64,
pub owner: String,
pub safe_address: String,
}
#[derive(cynic::QueryFragment, Debug, Clone, PartialEq, Eq)]
pub struct ModuleAddress {
pub __typename: String,
pub module_address: String,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "QueryRoot", variables = "ModuleAddressVariables")]
pub struct QueryModuleAddress {
#[arguments(nonce: $nonce, safeAddress: $safe_address, owner: $owner)]
pub calculate_module_address: CalculateModuleAddressResult,
}
#[derive(cynic::InlineFragments, Debug)]
pub enum SafeResult {
Safe(Safe),
InvalidAddressError(InvalidAddressError),
QueryFailedError(QueryFailedError),
#[cynic(fallback)]
Unknown,
}
impl From<SafeResult> for Result<Option<Safe>, BlokliClientError> {
fn from(value: SafeResult) -> Self {
match value {
SafeResult::Safe(safe) => Ok(Some(safe)),
SafeResult::InvalidAddressError(e) => Err(e.into()),
SafeResult::QueryFailedError(e) => Err(e.into()),
SafeResult::Unknown => Err(ErrorKind::NoData.into()),
}
}
}
#[derive(cynic::QueryFragment, Debug, Clone, PartialEq, Eq)]
pub struct SafesList {
pub safes: Vec<Safe>,
}
#[derive(cynic::InlineFragments, Debug)]
pub enum SafeByResult {
SafesList(SafesList),
InvalidAddressError(InvalidAddressError),
QueryFailedError(QueryFailedError),
#[cynic(fallback)]
Unknown,
}
impl From<SafeByResult> for Result<Vec<Safe>, BlokliClientError> {
fn from(value: SafeByResult) -> Self {
match value {
SafeByResult::SafesList(safes) => Ok(safes.safes),
SafeByResult::InvalidAddressError(e) => Err(e.into()),
SafeByResult::QueryFailedError(e) => Err(e.into()),
SafeByResult::Unknown => Err(ErrorKind::NoData.into()),
}
}
}
#[derive(cynic::InlineFragments, Debug)]
pub enum CalculateModuleAddressResult {
ModuleAddress(ModuleAddress),
InvalidAddressError(InvalidAddressError),
QueryFailedError(QueryFailedError),
#[cynic(fallback)]
Unknown,
}
impl From<CalculateModuleAddressResult> for Result<ChainAddress, BlokliClientError> {
fn from(value: CalculateModuleAddressResult) -> Self {
match value {
CalculateModuleAddressResult::ModuleAddress(address) => {
let address = address.module_address.to_lowercase();
Ok(hex::decode(address.trim_start_matches("0x"))
.map_err(|_| BlokliClientError::from(ErrorKind::ParseError))
.and_then(|bytes| bytes.try_into().map_err(|_| ErrorKind::ParseError.into()))?)
}
CalculateModuleAddressResult::InvalidAddressError(e) => Err(e.into()),
CalculateModuleAddressResult::QueryFailedError(e) => Err(e.into()),
CalculateModuleAddressResult::Unknown => Err(ErrorKind::NoData.into()),
}
}
}