openzeppelin_relayer/domain/relayer/stellar/
mod.rs1mod stellar_relayer;
2pub use stellar_relayer::*;
3
4mod gas_abstraction;
5mod token_swap;
6
7pub mod xdr_utils;
8pub use xdr_utils::*;
9
10pub use crate::services::stellar_dex::StellarDexServiceTrait;
11
12use std::sync::Arc;
13
14use crate::{
15 constants::{STELLAR_HORIZON_MAINNET_URL, STELLAR_HORIZON_TESTNET_URL},
16 jobs::JobProducerTrait,
17 models::{
18 NetworkRepoModel, NetworkType, RelayerError, RelayerRepoModel, SignerRepoModel,
19 StellarNetwork, StellarSwapStrategy, TransactionRepoModel,
20 },
21 repositories::{
22 NetworkRepository, RelayerRepository, Repository, TransactionCounterTrait,
23 TransactionRepository,
24 },
25 services::{
26 provider::get_network_provider,
27 signer::StellarSignerFactory,
28 stellar_dex::{DexServiceWrapper, OrderBookService, StellarDexService},
29 TransactionCounterService,
30 },
31};
32
33pub async fn create_stellar_relayer<
35 J: JobProducerTrait + 'static,
36 TR: TransactionRepository + Repository<TransactionRepoModel, String> + Send + Sync + 'static,
37 NR: NetworkRepository + Repository<NetworkRepoModel, String> + Send + Sync + 'static,
38 RR: RelayerRepository + Repository<RelayerRepoModel, String> + Send + Sync + 'static,
39 TCR: TransactionCounterTrait + Send + Sync + 'static,
40>(
41 relayer: RelayerRepoModel,
42 signer: SignerRepoModel,
43 relayer_repository: Arc<RR>,
44 network_repository: Arc<NR>,
45 transaction_repository: Arc<TR>,
46 job_producer: Arc<J>,
47 transaction_counter_store: Arc<TCR>,
48) -> Result<DefaultStellarRelayer<J, TR, NR, RR, TCR>, RelayerError> {
49 let network_repo = network_repository
50 .get_by_name(NetworkType::Stellar, &relayer.network)
51 .await
52 .ok()
53 .flatten()
54 .ok_or_else(|| {
55 RelayerError::NetworkConfiguration(format!("Network {} not found", relayer.network))
56 })?;
57
58 let network = StellarNetwork::try_from(network_repo.clone())?;
59 let provider = get_network_provider(&network, relayer.custom_rpc_urls.clone())
60 .map_err(|e| RelayerError::NetworkConfiguration(e.to_string()))?;
61
62 let stellar_signer = Arc::new(StellarSignerFactory::create_stellar_signer(&signer.into())?);
64
65 let transaction_counter_service = Arc::new(TransactionCounterService::new(
66 relayer.id.clone(),
67 relayer.address.clone(),
68 transaction_counter_store,
69 ));
70
71 let horizon_url = network.horizon_url.clone().unwrap_or_else(|| {
73 if network.is_testnet() {
74 STELLAR_HORIZON_TESTNET_URL.to_string()
75 } else {
76 STELLAR_HORIZON_MAINNET_URL.to_string()
77 }
78 });
79 let provider_arc = Arc::new(provider.clone());
80 let signer_arc = stellar_signer.clone();
81
82 let strategies = relayer
84 .policies
85 .get_stellar_policy()
86 .get_swap_config()
87 .and_then(|config| {
88 if config.strategies.is_empty() {
89 None
90 } else {
91 Some(config.strategies.clone())
92 }
93 })
94 .unwrap_or_else(|| vec![StellarSwapStrategy::OrderBook]);
95
96 let mut dex_services: Vec<DexServiceWrapper<_, _>> = Vec::new();
99 for strategy in &strategies {
100 match strategy {
101 StellarSwapStrategy::OrderBook => {
102 let order_book_service = Arc::new(
103 OrderBookService::new(
104 horizon_url.clone(),
105 provider_arc.clone(),
106 signer_arc.clone(),
107 )
108 .map_err(|e| {
109 RelayerError::NetworkConfiguration(format!(
110 "Failed to create OrderBook DEX service: {e}"
111 ))
112 })?,
113 );
114 dex_services.push(DexServiceWrapper::OrderBook(order_book_service));
115 }
116 StellarSwapStrategy::Soroswap => {
117 tracing::warn!("Soroswap strategy is not yet implemented, skipping");
120 }
121 }
122 }
123
124 let dex_service = Arc::new(StellarDexService::new(dex_services));
126
127 let relayer = DefaultStellarRelayer::<J, TR, NR, RR, TCR>::new(
128 relayer,
129 stellar_signer.clone(),
130 provider,
131 StellarRelayerDependencies::new(
132 relayer_repository,
133 network_repository,
134 transaction_repository,
135 transaction_counter_service,
136 job_producer,
137 ),
138 dex_service,
139 )
140 .await?;
141
142 Ok(relayer)
143}