openzeppelin_relayer/domain/relayer/
util.rs

1/// This module provides utility functions and structures for managing and interacting
2/// with relayers within the application. It includes functions to retrieve relayers
3/// by ID, construct network relayers, and handle unsupported operations for specific
4/// relayer types.
5///
6/// The primary components of this module are:
7/// - `get_relayer_by_id`: Retrieves a relayer from the repository using its ID.
8/// - `get_network_relayer`: Constructs a network relayer using a relayer ID.
9/// - `get_network_relayer_by_model`: Constructs a network relayer using a relayer model.
10/// - `solana_not_supported`: Returns an error for unsupported Solana relayer operations.
11///
12/// These utilities are essential for the application's relayer management and
13/// interaction with the underlying repositories and factories.
14use crate::{
15    domain::relayer::{RelayerFactory, RelayerFactoryTrait},
16    jobs::JobProducerTrait,
17    models::{
18        ApiError, NetworkRepoModel, NotificationRepoModel, RelayerError, RelayerRepoModel,
19        SignerRepoModel, ThinDataAppState, TransactionRepoModel,
20    },
21    repositories::{
22        ApiKeyRepositoryTrait, NetworkRepository, PluginRepositoryTrait, RelayerRepository,
23        Repository, TransactionCounterTrait, TransactionRepository,
24    },
25};
26
27use super::NetworkRelayer;
28use tracing::instrument;
29
30/// Retrieves a relayer by its ID from the repository.
31///
32/// # Arguments
33///
34/// * `relayer_id` - A string slice that holds the ID of the relayer.
35/// * `state` - A reference to the application state.
36///
37/// # Returns
38///
39/// * `Result<RelayerRepoModel, ApiError>` - Returns a `RelayerRepoModel` on success, or an
40///   `ApiError` on failure.
41#[instrument(
42    level = "debug",
43    skip(state),
44    fields(
45        request_id = ?crate::observability::request_id::get_request_id(),
46        relayer_id = %relayer_id,
47    )
48)]
49pub async fn get_relayer_by_id<J, RR, TR, NR, NFR, SR, TCR, PR, AKR>(
50    relayer_id: String,
51    state: &ThinDataAppState<J, RR, TR, NR, NFR, SR, TCR, PR, AKR>,
52) -> Result<RelayerRepoModel, ApiError>
53where
54    J: JobProducerTrait + Send + Sync + 'static,
55    RR: RelayerRepository + Repository<RelayerRepoModel, String> + Send + Sync + 'static,
56    TR: TransactionRepository + Repository<TransactionRepoModel, String> + Send + Sync + 'static,
57    NR: NetworkRepository + Repository<NetworkRepoModel, String> + Send + Sync + 'static,
58    NFR: Repository<NotificationRepoModel, String> + Send + Sync + 'static,
59    SR: Repository<SignerRepoModel, String> + Send + Sync + 'static,
60    TCR: TransactionCounterTrait + Send + Sync + 'static,
61    PR: PluginRepositoryTrait + Send + Sync + 'static,
62    AKR: ApiKeyRepositoryTrait + Send + Sync + 'static,
63{
64    state
65        .relayer_repository
66        .get_by_id(relayer_id)
67        .await
68        .map_err(|e| e.into())
69}
70
71/// Retrieves a network relayer by its ID, constructing it using the relayer and signer models.
72///
73/// # Arguments
74///
75/// * `relayer_id` - A string slice that holds the ID of the relayer.
76/// * `state` - A reference to the application state.
77///
78/// # Returns
79///
80/// * `Result<NetworkRelayer, ApiError>` - Returns a `NetworkRelayer` on success, or an `ApiError`
81///   on failure.
82#[instrument(
83    level = "debug",
84    skip(state),
85    fields(
86        request_id = ?crate::observability::request_id::get_request_id(),
87        relayer_id = %relayer_id,
88    )
89)]
90pub async fn get_network_relayer<J, RR, TR, NR, NFR, SR, TCR, PR, AKR>(
91    relayer_id: String,
92    state: &ThinDataAppState<J, RR, TR, NR, NFR, SR, TCR, PR, AKR>,
93) -> Result<NetworkRelayer<J, TR, RR, NR, TCR>, ApiError>
94where
95    J: JobProducerTrait + Send + Sync + 'static,
96    RR: RelayerRepository + Repository<RelayerRepoModel, String> + Send + Sync + 'static,
97    TR: TransactionRepository + Repository<TransactionRepoModel, String> + Send + Sync + 'static,
98    NR: NetworkRepository + Repository<NetworkRepoModel, String> + Send + Sync + 'static,
99    NFR: Repository<NotificationRepoModel, String> + Send + Sync + 'static,
100    SR: Repository<SignerRepoModel, String> + Send + Sync + 'static,
101    TCR: TransactionCounterTrait + Send + Sync + 'static,
102    PR: PluginRepositoryTrait + Send + Sync + 'static,
103    AKR: ApiKeyRepositoryTrait + Send + Sync + 'static,
104{
105    let relayer_model = get_relayer_by_id(relayer_id.clone(), state).await?;
106    let signer_model = state
107        .signer_repository
108        .get_by_id(relayer_model.signer_id.clone())
109        .await?;
110
111    RelayerFactory::create_relayer(relayer_model, signer_model, state)
112        .await
113        .map_err(|e| e.into())
114}
115
116/// Constructs a network relayer using a given relayer model.
117///
118/// # Arguments
119///
120/// * `relayer_model` - A `RelayerRepoModel` that holds the relayer data.
121/// * `state` - A reference to the application state.
122///
123/// # Returns
124///
125/// * `Result<NetworkRelayer, ApiError>` - Returns a `NetworkRelayer` on success, or an `ApiError`
126///   on failure.
127#[instrument(
128    level = "debug",
129    skip(state, relayer_model),
130    fields(
131        request_id = ?crate::observability::request_id::get_request_id(),
132        relayer_id = %relayer_model.id,
133    )
134)]
135pub async fn get_network_relayer_by_model<J, RR, TR, NR, NFR, SR, TCR, PR, AKR>(
136    relayer_model: RelayerRepoModel,
137    state: &ThinDataAppState<J, RR, TR, NR, NFR, SR, TCR, PR, AKR>,
138) -> Result<NetworkRelayer<J, TR, RR, NR, TCR>, ApiError>
139where
140    J: JobProducerTrait + Send + Sync + 'static,
141    RR: RelayerRepository + Repository<RelayerRepoModel, String> + Send + Sync + 'static,
142    TR: TransactionRepository + Repository<TransactionRepoModel, String> + Send + Sync + 'static,
143    NR: NetworkRepository + Repository<NetworkRepoModel, String> + Send + Sync + 'static,
144    NFR: Repository<NotificationRepoModel, String> + Send + Sync + 'static,
145    SR: Repository<SignerRepoModel, String> + Send + Sync + 'static,
146    TCR: TransactionCounterTrait + Send + Sync + 'static,
147    PR: PluginRepositoryTrait + Send + Sync + 'static,
148    AKR: ApiKeyRepositoryTrait + Send + Sync + 'static,
149{
150    let signer_model = state
151        .signer_repository
152        .get_by_id(relayer_model.signer_id.clone())
153        .await?;
154
155    RelayerFactory::create_relayer(relayer_model, signer_model, state)
156        .await
157        .map_err(|e| e.into())
158}
159
160/// Returns an error indicating that the endpoint is not supported for Solana relayers.
161///
162/// # Returns
163///
164/// * `Result<T, RelayerError>` - Always returns a `RelayerError::NotSupported`.
165pub fn solana_not_supported_relayer<T>() -> Result<T, RelayerError> {
166    Err(RelayerError::NotSupported(
167        "Endpoint is not supported for Solana relayers".to_string(),
168    ))
169}