hopr_api/chain/
accounts.rs1use futures::{future::BoxFuture, stream::BoxStream};
2use hopr_crypto_types::prelude::{OffchainKeypair, OffchainPublicKey};
3pub use hopr_internal_types::prelude::AccountEntry;
4use hopr_primitive_types::prelude::Address;
5pub use hopr_primitive_types::prelude::{Balance, Currency};
6pub use multiaddr::Multiaddr;
7
8use crate::chain::ChainReceipt;
9
10#[derive(Debug, strum::EnumIs, strum::EnumTryAs, thiserror::Error)]
14pub enum AnnouncementError<E> {
15 #[error("already announced")]
17 AlreadyAnnounced,
18 #[error("account announcement error: {0}")]
20 ProcessingError(E),
21}
22#[derive(Debug, strum::EnumIs, strum::EnumTryAs, thiserror::Error)]
24pub enum SafeRegistrationError<E> {
25 #[error("safe {0} is already registered with this node")]
27 AlreadyRegistered(Address),
28 #[error("safe registration error: {0}")]
30 ProcessingError(E),
31}
32
33#[async_trait::async_trait]
35#[auto_impl::auto_impl(&, Box, Arc)]
36pub trait ChainWriteAccountOperations {
37 type Error: std::error::Error + Send + Sync + 'static;
38
39 async fn announce(
41 &self,
42 multiaddrs: &[Multiaddr],
43 key: &OffchainKeypair,
44 ) -> Result<BoxFuture<'life0, Result<ChainReceipt, Self::Error>>, AnnouncementError<Self::Error>>;
45
46 async fn withdraw<C: Currency + Send>(
48 &self,
49 balance: Balance<C>,
50 recipient: &Address,
51 ) -> Result<BoxFuture<'life0, Result<ChainReceipt, Self::Error>>, Self::Error>;
52
53 async fn register_safe(
55 &self,
56 safe_address: &Address,
57 ) -> Result<BoxFuture<'life0, Result<ChainReceipt, Self::Error>>, SafeRegistrationError<Self::Error>>;
58}
59
60#[derive(Clone, Debug, PartialEq, Eq, Default)]
64pub struct AccountSelector {
65 pub public_only: bool,
67 pub chain_key: Option<Address>,
69 pub offchain_key: Option<OffchainPublicKey>,
71}
72
73impl AccountSelector {
74 #[must_use]
76 pub fn with_public_only(mut self, public_only: bool) -> Self {
77 self.public_only = public_only;
78 self
79 }
80
81 #[must_use]
83 pub fn with_chain_key(mut self, chain_key: Address) -> Self {
84 self.chain_key = Some(chain_key);
85 self
86 }
87
88 #[must_use]
90 pub fn with_offchain_key(mut self, offchain_key: OffchainPublicKey) -> Self {
91 self.offchain_key = Some(offchain_key);
92 self
93 }
94
95 pub fn satisfies(&self, account: &AccountEntry) -> bool {
97 if self.public_only && !account.has_announced_with_routing_info() {
98 return false;
99 }
100
101 if let Some(chain_key) = &self.chain_key {
102 if &account.chain_addr != chain_key {
103 return false;
104 }
105 }
106
107 if let Some(packet_key) = &self.offchain_key {
108 if &account.public_key != packet_key {
109 return false;
110 }
111 }
112
113 true
114 }
115}
116
117#[async_trait::async_trait]
119#[auto_impl::auto_impl(&, Box, Arc)]
120pub trait ChainReadAccountOperations {
121 type Error: std::error::Error + Send + Sync + 'static;
122
123 async fn get_balance<C: Currency, A: Into<Address> + Send>(&self, address: A) -> Result<Balance<C>, Self::Error>;
125
126 async fn safe_allowance<C: Currency, A: Into<Address> + Send>(
128 &self,
129 safe_address: A,
130 ) -> Result<Balance<C>, Self::Error>;
131
132 async fn stream_accounts<'a>(
134 &'a self,
135 selector: AccountSelector,
136 ) -> Result<BoxStream<'a, AccountEntry>, Self::Error>;
137
138 async fn count_accounts(&self, selector: AccountSelector) -> Result<usize, Self::Error>;
143}