Skip to main content

blokli_client/api/v1/graphql/
accounts.rs

1use hex::ToHex;
2
3use super::{CountResult, InvalidAddressError, MissingFilterError, QueryFailedError, Uint64, schema};
4use crate::{
5    api::v1::AccountSelector,
6    errors::{BlokliClientError, ErrorKind},
7};
8
9#[derive(cynic::QueryVariables, Default)]
10pub struct AccountVariables {
11    pub keyid: Option<i32>,
12    pub packet_key: Option<String>,
13    pub chain_key: Option<String>,
14}
15
16impl From<AccountSelector> for AccountVariables {
17    fn from(value: AccountSelector) -> Self {
18        match value {
19            AccountSelector::KeyId(keyid) => AccountVariables {
20                keyid: Some(keyid as i32),
21                ..Default::default()
22            },
23            AccountSelector::Address(address) => AccountVariables {
24                chain_key: Some(address.encode_hex()),
25                ..Default::default()
26            },
27            AccountSelector::PacketKey(address) => AccountVariables {
28                packet_key: Some(address.encode_hex()),
29                ..Default::default()
30            },
31            AccountSelector::Any => AccountVariables::default(),
32        }
33    }
34}
35
36#[derive(cynic::QueryFragment, Debug)]
37#[cynic(graphql_type = "QueryRoot", variables = "AccountVariables")]
38pub struct QueryAccounts {
39    #[arguments(keyid: $keyid, packetKey: $packet_key, chainKey: $chain_key)]
40    pub accounts: AccountsResult,
41}
42
43#[derive(cynic::QueryFragment, Debug)]
44#[cynic(graphql_type = "SubscriptionRoot", variables = "AccountVariables")]
45pub struct SubscribeAccounts {
46    #[arguments(keyid: $keyid, packetKey: $packet_key, chainKey: $chain_key)]
47    pub account_updated: Account,
48}
49
50#[derive(cynic::QueryFragment, Debug)]
51#[cynic(graphql_type = "QueryRoot", variables = "AccountVariables")]
52pub struct QueryAccountCount {
53    #[arguments(keyid: $keyid, packetKey: $packet_key, chainKey: $chain_key)]
54    pub account_count: CountResult,
55}
56
57/// List of accounts returned by an account query.
58#[derive(cynic::QueryFragment, Debug)]
59pub struct AccountsList {
60    /// GraphQL concrete type name.
61    pub __typename: String,
62    /// Matching accounts.
63    pub accounts: Vec<Account>,
64}
65
66/// Account indexed by Blokli.
67///
68/// Accounts connect a Blokli key id to the chain key, packet key, advertised multiaddresses, and optional safe
69/// address associated with a node.
70#[derive(cynic::QueryFragment, Debug, Clone, PartialEq, Eq)]
71#[cfg_attr(feature = "serde", derive(serde::Serialize))]
72pub struct Account {
73    /// On-chain address for this account, encoded as a hex string.
74    pub chain_key: String,
75    /// Numeric Blokli key id.
76    pub keyid: i32,
77    /// Advertised libp2p multiaddresses associated with the account.
78    pub multi_addresses: Vec<String>,
79    /// Packet key encoded as a hex string.
80    pub packet_key: String,
81    /// Safe contract address associated with this account, when one is known.
82    pub safe_address: Option<String>,
83}
84
85#[derive(cynic::InlineFragments, Debug)]
86pub enum AccountsResult {
87    AccountsList(AccountsList),
88    MissingFilterError(MissingFilterError),
89    QueryFailedError(QueryFailedError),
90    #[cynic(fallback)]
91    Unknown,
92}
93
94impl From<AccountsResult> for Result<Vec<Account>, BlokliClientError> {
95    fn from(value: AccountsResult) -> Self {
96        match value {
97            AccountsResult::AccountsList(list) => Ok(list.accounts),
98            AccountsResult::MissingFilterError(e) => Err(e.into()),
99            AccountsResult::QueryFailedError(e) => Err(e.into()),
100            AccountsResult::Unknown => Err(ErrorKind::NoData.into()),
101        }
102    }
103}
104
105#[derive(cynic::QueryVariables, Debug)]
106pub struct TxCountVariables {
107    pub address: String,
108}
109
110/// Transaction count payload for an address.
111#[derive(cynic::QueryFragment, Debug)]
112pub struct TransactionCount {
113    /// GraphQL concrete type name.
114    pub __typename: String,
115    /// Number of transactions encoded as a GraphQL `UInt64` string.
116    pub count: Uint64,
117}
118
119#[derive(cynic::QueryFragment, Debug)]
120#[cynic(graphql_type = "QueryRoot", variables = "TxCountVariables")]
121pub struct QueryTxCount {
122    #[arguments(address: $address)]
123    pub transaction_count: TransactionCountResult,
124}
125
126#[derive(cynic::InlineFragments, Debug)]
127pub enum TransactionCountResult {
128    TransactionCount(TransactionCount),
129    InvalidAddressError(InvalidAddressError),
130    QueryFailedError(QueryFailedError),
131    #[cynic(fallback)]
132    Unknown,
133}
134
135impl From<TransactionCountResult> for Result<u64, BlokliClientError> {
136    fn from(value: TransactionCountResult) -> Self {
137        match value {
138            TransactionCountResult::TransactionCount(count) => {
139                Ok(count.count.0.parse().map_err(|_| ErrorKind::ParseError)?)
140            }
141            TransactionCountResult::InvalidAddressError(e) => Err(e.into()),
142            TransactionCountResult::QueryFailedError(e) => Err(e.into()),
143            TransactionCountResult::Unknown => Err(ErrorKind::NoData.into()),
144        }
145    }
146}