hopr_api/chain/
accounts.rs

1use std::fmt::Formatter;
2
3use futures::{future::BoxFuture, stream::BoxStream};
4use hopr_crypto_types::prelude::{OffchainKeypair, OffchainPublicKey};
5pub use hopr_internal_types::prelude::AccountEntry;
6use hopr_primitive_types::prelude::Address;
7pub use hopr_primitive_types::prelude::{Balance, Currency};
8pub use multiaddr::Multiaddr;
9
10use crate::chain::ChainReceipt;
11
12/// Error that can occur when making a node announcement.
13///
14/// See [`ChainWriteAccountOperations::announce`]
15#[derive(Debug, strum::EnumIs, strum::EnumTryAs)]
16pub enum AnnouncementError<E> {
17    /// Special error when an account is already announced.
18    AlreadyAnnounced,
19    /// Error that can occur when processing an announcement.
20    ProcessingError(E),
21}
22
23impl<E: std::fmt::Display> std::fmt::Display for AnnouncementError<E> {
24    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
25        match self {
26            AnnouncementError::AlreadyAnnounced => f.write_str("already announced"),
27            AnnouncementError::ProcessingError(e) => write!(f, "account processing error: {e}"),
28        }
29    }
30}
31
32impl<E: std::error::Error> std::error::Error for AnnouncementError<E> {}
33
34/// On-chain write operations regarding on-chain node accounts.
35#[async_trait::async_trait]
36pub trait ChainWriteAccountOperations {
37    type Error: std::error::Error + Send + Sync + 'static;
38
39    /// Announces transport key and list of multi addresses.
40    async fn announce(
41        &self,
42        multiaddrs: &[Multiaddr],
43        key: &OffchainKeypair,
44    ) -> Result<BoxFuture<'_, Result<ChainReceipt, Self::Error>>, AnnouncementError<Self::Error>>;
45
46    /// Withdraws native or token currency.
47    async fn withdraw<C: Currency + Send>(
48        &self,
49        balance: Balance<C>,
50        recipient: &Address,
51    ) -> Result<BoxFuture<'_, Result<ChainReceipt, Self::Error>>, Self::Error>;
52
53    /// Registers Safe address with the current node.
54    async fn register_safe(
55        &self,
56        safe_address: &Address,
57    ) -> Result<BoxFuture<'_, Result<ChainReceipt, Self::Error>>, Self::Error>;
58}
59
60/// Selector for on-chain node accounts.
61///
62/// See [`ChainReadAccountOperations::stream_accounts`].
63#[derive(Clone, Debug, PartialEq, Eq, Default)]
64pub struct AccountSelector {
65    /// Selects accounts that are announced with multi-addresses.
66    pub public_only: bool,
67    /// Selects accounts bound with the given chain key.
68    pub chain_key: Option<Address>,
69    /// Selects accounts bound with the given off-chain key.
70    pub offchain_key: Option<OffchainPublicKey>,
71}
72
73/// Chain operations that read on-chain node accounts.
74#[async_trait::async_trait]
75pub trait ChainReadAccountOperations {
76    type Error: std::error::Error + Send + Sync + 'static;
77
78    /// Returns the native or token currency balance of the current node's account.
79    async fn node_balance<C: Currency>(&self) -> Result<Balance<C>, Self::Error>;
80
81    /// Returns the native or token currency balance of the current node's Safe.
82    async fn safe_balance<C: Currency>(&self) -> Result<Balance<C>, Self::Error>;
83
84    /// Returns the native or token currency Safe allowance.
85    async fn safe_allowance<C: Currency>(&self) -> Result<Balance<C>, Self::Error>;
86
87    /// Returns account entry given the on-chain `address`.
88    async fn find_account_by_address(&self, address: &Address) -> Result<Option<AccountEntry>, Self::Error>;
89
90    /// Returns account entry given the off-chain `packet_key`.
91    async fn find_account_by_packet_key(
92        &self,
93        packet_key: &OffchainPublicKey,
94    ) -> Result<Option<AccountEntry>, Self::Error>;
95
96    /// Validates the node's Safe setup.
97    async fn check_node_safe_module_status(&self) -> Result<bool, Self::Error>;
98
99    /// Checks if the given safe address can be registered with the current node.
100    async fn can_register_with_safe(&self, safe_address: &Address) -> Result<bool, Self::Error>;
101
102    /// Returns on-chain node accounts with the given [`AccountSelector`].
103    async fn stream_accounts<'a>(
104        &'a self,
105        selector: AccountSelector,
106    ) -> Result<BoxStream<'a, AccountEntry>, Self::Error>;
107
108    /// Counts the accounts with the given [`AccountSelector`].
109    ///
110    /// This is potentially done more effectively than counting more elements of
111    /// the stream returned by [`ChainReadAccountOperations::stream_accounts`].
112    async fn count_accounts(&self, selector: AccountSelector) -> Result<usize, Self::Error>;
113}