Skip to main content

blokli_client/api/v1/graphql/
channels.rs

1use hex::ToHex;
2
3use super::{
4    ChannelStatus, CountResult, DateTime, InvalidAddressError, MissingFilterError, QueryFailedError, TokenValueString,
5    Uint64, schema,
6};
7use crate::api::v1::{ChainAddress, ChannelFilter, ChannelSelector};
8
9#[derive(cynic::QueryVariables, Default)]
10pub struct ChannelsVariables {
11    pub concrete_channel_id: Option<String>,
12    pub destination_key_id: Option<i32>,
13    pub source_key_id: Option<i32>,
14    pub safe_address: Option<String>,
15    pub status: Option<ChannelStatus>,
16}
17
18impl From<ChannelSelector> for ChannelsVariables {
19    fn from(value: ChannelSelector) -> Self {
20        let safe_address = value.safe_address.map(|a: ChainAddress| hex::encode(a));
21        match value.filter {
22            Some(ChannelFilter::ChannelId(id)) => ChannelsVariables {
23                concrete_channel_id: Some(id.encode_hex()),
24                safe_address,
25                status: value.status,
26                ..Default::default()
27            },
28            Some(ChannelFilter::DestinationKeyId(dst)) => ChannelsVariables {
29                destination_key_id: Some(dst as i32),
30                safe_address,
31                status: value.status,
32                ..Default::default()
33            },
34            Some(ChannelFilter::SourceKeyId(src)) => ChannelsVariables {
35                source_key_id: Some(src as i32),
36                safe_address,
37                status: value.status,
38                ..Default::default()
39            },
40            Some(ChannelFilter::SourceAndDestinationKeyIds(src, dst)) => ChannelsVariables {
41                destination_key_id: Some(dst as i32),
42                source_key_id: Some(src as i32),
43                safe_address,
44                status: value.status,
45                ..Default::default()
46            },
47            None => ChannelsVariables {
48                safe_address,
49                status: value.status,
50                ..Default::default()
51            },
52        }
53    }
54}
55
56#[derive(cynic::QueryFragment, Debug)]
57#[cynic(graphql_type = "QueryRoot", variables = "ChannelsVariables")]
58pub struct QueryChannels {
59    #[arguments(concreteChannelId: $concrete_channel_id, destinationKeyId: $destination_key_id, sourceKeyId: $source_key_id, safeAddress: $safe_address, status: $status)]
60    pub channels: ChannelsResult,
61}
62
63#[derive(cynic::QueryFragment, Debug)]
64#[cynic(graphql_type = "SubscriptionRoot", variables = "ChannelsVariables")]
65pub struct SubscribeChannels {
66    #[arguments(concreteChannelId: $concrete_channel_id, destinationKeyId: $destination_key_id, sourceKeyId: $source_key_id, status: $status)]
67    pub channel_updated: Channel,
68}
69
70#[derive(cynic::QueryFragment, Debug)]
71#[cynic(graphql_type = "QueryRoot", variables = "ChannelsVariables")]
72pub struct QueryChannelCount {
73    #[arguments(concreteChannelId: $concrete_channel_id, destinationKeyId: $destination_key_id, sourceKeyId: $source_key_id, safeAddress: $safe_address, status: $status)]
74    pub channel_count: CountResult,
75}
76
77#[derive(cynic::QueryVariables, Default)]
78pub struct ChannelStatsVariables {
79    pub concrete_channel_id: Option<String>,
80    pub destination_key_id: Option<i32>,
81    pub safe_address: Option<String>,
82    pub source_key_id: Option<i32>,
83    pub status: Option<ChannelStatus>,
84}
85
86impl From<ChannelSelector> for ChannelStatsVariables {
87    fn from(value: ChannelSelector) -> Self {
88        let safe_address = value.safe_address.map(|a: ChainAddress| hex::encode(a));
89        match value.filter {
90            Some(ChannelFilter::ChannelId(id)) => ChannelStatsVariables {
91                concrete_channel_id: Some(id.encode_hex()),
92                safe_address,
93                status: value.status,
94                ..Default::default()
95            },
96            Some(ChannelFilter::DestinationKeyId(dst)) => ChannelStatsVariables {
97                destination_key_id: Some(dst as i32),
98                safe_address,
99                status: value.status,
100                ..Default::default()
101            },
102            Some(ChannelFilter::SourceKeyId(src)) => ChannelStatsVariables {
103                source_key_id: Some(src as i32),
104                safe_address,
105                status: value.status,
106                ..Default::default()
107            },
108            Some(ChannelFilter::SourceAndDestinationKeyIds(src, dst)) => ChannelStatsVariables {
109                destination_key_id: Some(dst as i32),
110                source_key_id: Some(src as i32),
111                safe_address,
112                status: value.status,
113                ..Default::default()
114            },
115            None => ChannelStatsVariables {
116                safe_address,
117                status: value.status,
118                ..Default::default()
119            },
120        }
121    }
122}
123
124#[derive(cynic::QueryFragment, Debug)]
125#[cynic(graphql_type = "QueryRoot", variables = "ChannelStatsVariables")]
126pub struct QueryChannelStats {
127    #[arguments(concreteChannelId: $concrete_channel_id, destinationKeyId: $destination_key_id, safeAddress: $safe_address, sourceKeyId: $source_key_id, status: $status)]
128    pub channel_stats: ChannelStatsResult,
129}
130
131/// Aggregate count and balance for a channel selector.
132#[derive(cynic::QueryFragment, Debug, Clone, PartialEq, Eq)]
133#[cfg_attr(feature = "serde", derive(serde::Serialize))]
134#[cynic(graphql_type = "ChannelStats")]
135pub struct ChannelStats {
136    /// Number of matching channels.
137    pub count: i32,
138    /// Total wxHOPR balance across the matching channels.
139    pub balance: TokenValueString,
140}
141
142#[derive(cynic::InlineFragments, Debug)]
143pub enum ChannelStatsResult {
144    ChannelStats(ChannelStats),
145    InvalidAddressError(InvalidAddressError),
146    QueryFailedError(QueryFailedError),
147    #[cynic(fallback)]
148    Unknown,
149}
150
151impl From<ChannelStatsResult> for Result<ChannelStats, crate::errors::BlokliClientError> {
152    fn from(value: ChannelStatsResult) -> Self {
153        match value {
154            ChannelStatsResult::ChannelStats(stats) => Ok(stats),
155            ChannelStatsResult::InvalidAddressError(e) => Err(e.into()),
156            ChannelStatsResult::QueryFailedError(e) => Err(e.into()),
157            ChannelStatsResult::Unknown => Err(crate::errors::ErrorKind::NoData.into()),
158        }
159    }
160}
161
162/// List of channels returned by a channel query.
163#[derive(cynic::QueryFragment, Debug)]
164#[cfg_attr(feature = "serde", derive(serde::Serialize))]
165pub struct ChannelsList {
166    /// GraphQL concrete type name.
167    pub __typename: String,
168    /// Matching channels.
169    pub channels: Vec<Channel>,
170}
171
172/// Payment channel indexed by Blokli.
173#[derive(cynic::QueryFragment, Debug, Clone, PartialEq, Eq)]
174#[cfg_attr(feature = "serde", derive(serde::Serialize))]
175pub struct Channel {
176    /// Current channel balance.
177    pub balance: TokenValueString,
178    /// Time at which the channel may close, when closure has been initiated.
179    pub closure_time: Option<DateTime>,
180    /// Concrete channel id encoded as a hex string.
181    pub concrete_channel_id: String,
182    /// Destination account key id.
183    pub destination: i32,
184    /// Current channel epoch.
185    pub epoch: i32,
186    /// Source account key id.
187    pub source: i32,
188    /// Current channel lifecycle state.
189    pub status: ChannelStatus,
190    /// Current ticket index for the channel.
191    pub ticket_index: Uint64,
192}
193
194#[derive(cynic::InlineFragments, Debug)]
195pub enum ChannelsResult {
196    ChannelsList(ChannelsList),
197    MissingFilterError(MissingFilterError),
198    QueryFailedError(QueryFailedError),
199    #[cynic(fallback)]
200    Unknown,
201}
202
203impl From<ChannelsResult> for Result<ChannelsList, crate::errors::BlokliClientError> {
204    fn from(value: ChannelsResult) -> Self {
205        match value {
206            ChannelsResult::ChannelsList(list) => Ok(ChannelsList {
207                __typename: list.__typename,
208                channels: list.channels,
209            }),
210            ChannelsResult::MissingFilterError(e) => Err(e.into()),
211            ChannelsResult::QueryFailedError(e) => Err(e.into()),
212            ChannelsResult::Unknown => Err(crate::errors::ErrorKind::NoData.into()),
213        }
214    }
215}
216
217#[derive(cynic::QueryVariables, Default)]
218pub struct SafesBalanceVariables {
219    pub owner_address: Option<String>,
220}
221
222#[derive(cynic::QueryFragment, Debug)]
223#[cynic(graphql_type = "QueryRoot", variables = "SafesBalanceVariables")]
224pub struct QuerySafesBalance {
225    #[arguments(ownerAddress: $owner_address)]
226    pub safes_balance: SafesBalanceResult,
227}
228
229/// Aggregate balance held across indexed safes.
230#[derive(cynic::QueryFragment, Debug, Clone, PartialEq, Eq)]
231#[cfg_attr(feature = "serde", derive(serde::Serialize))]
232pub struct SafesBalance {
233    /// Total wxHOPR balance across matching safes.
234    pub balance: TokenValueString,
235    /// Number of safes included in the aggregate.
236    pub count: i32,
237}
238
239#[derive(cynic::InlineFragments, Debug)]
240pub enum SafesBalanceResult {
241    InvalidAddressError(InvalidAddressError),
242    QueryFailedError(QueryFailedError),
243    SafesBalance(SafesBalance),
244    #[cynic(fallback)]
245    Unknown,
246}
247
248impl From<SafesBalanceResult> for Result<SafesBalance, crate::errors::BlokliClientError> {
249    fn from(value: SafesBalanceResult) -> Self {
250        match value {
251            SafesBalanceResult::SafesBalance(balance) => Ok(balance),
252            SafesBalanceResult::InvalidAddressError(e) => Err(e.into()),
253            SafesBalanceResult::QueryFailedError(e) => Err(e.into()),
254            SafesBalanceResult::Unknown => Err(crate::errors::ErrorKind::NoData.into()),
255        }
256    }
257}