Skip to main content

hopr_api/chain/
safe.rs

1use futures::future::BoxFuture;
2use hopr_primitive_types::{
3    balance::{Balance, Currency},
4    prelude::{Address, HoprBalance},
5};
6
7use crate::chain::ChainReceipt;
8
9/// Information about a deployed Safe.
10#[derive(Clone, Debug, PartialEq, Eq)]
11pub struct DeployedSafe {
12    /// Safe address.
13    pub address: Address,
14    /// Address of the Safe owner (typically the node chain key).
15    pub owner: Address,
16    /// Address of the Safe module.
17    pub module: Address,
18    /// Addresses of nodes that have been registered with this Safe.
19    pub registered_nodes: Vec<Address>,
20}
21
22/// Selector for [deployed Safes](DeployedSafe).
23#[derive(Clone, Copy, Debug, PartialEq, Eq)]
24pub enum SafeSelector {
25    /// Selects Safes owned by the given address.
26    Owner(Address),
27    /// Selects Safes with the given address.
28    Address(Address),
29}
30
31impl SafeSelector {
32    pub fn satisfies(&self, safe: &DeployedSafe) -> bool {
33        match self {
34            SafeSelector::Owner(owner) => &safe.owner == owner,
35            SafeSelector::Address(address) => &safe.address == address,
36        }
37    }
38}
39
40/// Operations for reading Safe information.
41#[async_trait::async_trait]
42#[auto_impl::auto_impl(&, Box, Arc)]
43pub trait ChainReadSafeOperations {
44    type Error: std::error::Error + Send + Sync + 'static;
45
46    /// Returns the native or token currency Safe allowance.
47    async fn safe_allowance<C: Currency, A: Into<Address> + Send>(
48        &self,
49        safe_address: A,
50    ) -> Result<Balance<C>, Self::Error>;
51    /// Retrieves [`DeployedSafe`] information using the given [`selector`](SafeSelector).
52    ///
53    /// Returns `None` if no deployed Safe matched the given `selector`.
54    async fn safe_info(&self, selector: SafeSelector) -> Result<Option<DeployedSafe>, Self::Error>;
55    /// Waits for a Safe matching the given [`selector`](SafeSelector) to be deployed up to the given `timeout`.
56    ///
57    /// Returns immediately if the matching Safe is already deployed.
58    async fn await_safe_deployment(
59        &self,
60        selector: SafeSelector,
61        timeout: std::time::Duration,
62    ) -> Result<DeployedSafe, Self::Error>;
63    /// Predicts the Module address based on the given `nonce`, `owner` and `safe_address` of the Safe.
64    async fn predict_module_address(
65        &self,
66        nonce: u64,
67        owner: &Address,
68        safe_address: &Address,
69    ) -> Result<Address, Self::Error>;
70}
71
72/// Operations for writing Safe information.
73#[async_trait::async_trait]
74#[auto_impl::auto_impl(&, Box, Arc)]
75pub trait ChainWriteSafeOperations {
76    type Error: std::error::Error + Send + Sync + 'static;
77
78    /// Deploys Safe with the given `balance` of wxHOPR tokens.
79    ///
80    /// The admin of the deployed Safe is always only the Connector's own signer. Only one Safe
81    /// can be deployed per signer.
82    async fn deploy_safe<'a>(
83        &'a self,
84        balance: HoprBalance,
85    ) -> Result<BoxFuture<'a, Result<ChainReceipt, Self::Error>>, Self::Error>;
86}