hopr_api/chain/
channels.rs

1use std::{
2    error::Error,
3    ops::{Bound, RangeBounds},
4};
5
6use futures::{future::BoxFuture, stream::BoxStream};
7use hopr_internal_types::prelude::ChannelStatus;
8pub use hopr_internal_types::prelude::{ChannelDirection, ChannelEntry, ChannelId, ChannelStatusDiscriminants};
9use hopr_primitive_types::prelude::Address;
10pub use hopr_primitive_types::prelude::HoprBalance;
11pub type DateTime = chrono::DateTime<chrono::Utc>;
12pub use chrono::Utc;
13
14use crate::chain::ChainReceipt;
15
16/// Selector for channels.
17///
18/// See [`ChainReadChannelOperations::stream_channels`].
19#[derive(Debug, Clone, PartialEq, Eq)]
20pub struct ChannelSelector {
21    /// Filter by source address.
22    pub source: Option<Address>,
23    /// Filter by destination address
24    pub destination: Option<Address>,
25    /// Filter by possible channel states.
26    pub allowed_states: Vec<ChannelStatusDiscriminants>,
27    /// Range of closure times if `PendingToClose` was specified in `allowed_states`,
28    /// otherwise has no effect.
29    pub closure_time_range: (Bound<DateTime>, Bound<DateTime>),
30}
31
32impl Default for ChannelSelector {
33    fn default() -> Self {
34        Self {
35            source: None,
36            destination: None,
37            allowed_states: vec![],
38            closure_time_range: (Bound::Unbounded, Bound::Unbounded),
39        }
40    }
41}
42
43impl ChannelSelector {
44    /// Sets the `source` bound on channel.
45    #[must_use]
46    pub fn with_source<A: Into<Address>>(mut self, address: A) -> Self {
47        self.source = Some(address.into());
48        self
49    }
50
51    /// Sets the `destination` bound on channel.
52    #[must_use]
53    pub fn with_destination<A: Into<Address>>(mut self, address: A) -> Self {
54        self.destination = Some(address.into());
55        self
56    }
57
58    /// Sets the allowed channel states.
59    #[must_use]
60    pub fn with_allowed_states(mut self, allowed_states: &[ChannelStatusDiscriminants]) -> Self {
61        self.allowed_states.extend_from_slice(allowed_states);
62        self
63    }
64
65    /// Sets the channel closure range.
66    ///
67    /// This has effect only if `PendingToClose` is set in the allowed states.
68    #[must_use]
69    pub fn with_closure_time_range<T: RangeBounds<DateTime>>(mut self, range: T) -> Self {
70        self.closure_time_range = (range.start_bound().cloned(), range.end_bound().cloned());
71        self
72    }
73}
74
75/// On-chain read operations regarding channels.
76#[async_trait::async_trait]
77pub trait ChainReadChannelOperations {
78    type Error: Error + Send + Sync + 'static;
79
80    /// Returns on-chain [`Address`] of the current node.
81    fn me(&self) -> &Address;
82
83    /// Returns a single channel given `src` and `dst`.
84    async fn channel_by_parties(&self, src: &Address, dst: &Address) -> Result<Option<ChannelEntry>, Self::Error>;
85
86    /// Returns a single channel given `channel_id`.
87    async fn channel_by_id(&self, channel_id: &ChannelId) -> Result<Option<ChannelEntry>, Self::Error>;
88
89    /// Returns a stream of channels given the [`ChannelSelector`].
90    async fn stream_channels<'a>(
91        &'a self,
92        selector: ChannelSelector,
93    ) -> Result<BoxStream<'a, ChannelEntry>, Self::Error>;
94}
95
96/// On-chain write operations regarding channels.
97#[async_trait::async_trait]
98pub trait ChainWriteChannelOperations {
99    type Error: Error + Send + Sync + 'static;
100    /// Opens a channel with `dst` and `amount`.
101    async fn open_channel<'a>(
102        &'a self,
103        dst: &'a Address,
104        amount: HoprBalance,
105    ) -> Result<BoxFuture<'a, Result<(ChannelId, ChainReceipt), Self::Error>>, Self::Error>;
106
107    /// Funds an existing channel.
108    async fn fund_channel<'a>(
109        &'a self,
110        channel_id: &'a ChannelId,
111        amount: HoprBalance,
112    ) -> Result<BoxFuture<'a, Result<ChainReceipt, Self::Error>>, Self::Error>;
113
114    /// Closes an existing channel.
115    async fn close_channel<'a>(
116        &'a self,
117        channel_id: &'a ChannelId,
118    ) -> Result<BoxFuture<'a, Result<(ChannelStatus, ChainReceipt), Self::Error>>, Self::Error>;
119}