1mod backend;
2mod connector;
3pub mod errors;
4mod reader;
5#[cfg(any(test, feature = "testing"))]
6pub mod testing;
7
8pub(crate) mod utils;
9
10#[cfg(any(test, feature = "testing"))]
11pub use backend::InMemoryBackend;
12pub use backend::{Backend, TempDbBackend, TempDbError};
13pub use connector::{BlockchainConnectorConfig, HoprBlockchainConnector};
14pub use hopr_api::{
15 chain as api,
16 types::chain::payload::{BasicPayloadGenerator, SafePayloadGenerator},
17};
18pub use reader::HoprBlockchainReader;
19
20pub mod blokli_client {
22 pub use blokli_client::{
23 BlokliClient, BlokliClientConfig, BlokliDnsOverride,
24 api::{BlokliQueryClient, BlokliSubscriptionClient, BlokliTransactionClient, types},
25 exports::Url,
26 };
27}
28
29#[derive(Clone, Debug, validator::Validate)]
49pub struct HoprBlokliClientConfig {
50 pub url: blokli_client::Url,
52 pub dns_override: Option<(std::net::IpAddr, Option<u16>)>,
59}
60
61impl HoprBlokliClientConfig {
62 pub fn new(url: blokli_client::Url) -> Self {
64 Self {
65 url,
66 dns_override: None,
67 }
68 }
69}
70
71pub fn create_blokli_client(cfg: HoprBlokliClientConfig) -> blokli_client::BlokliClient {
76 blokli_client::BlokliClient::new(
77 cfg.url,
78 blokli_client::BlokliClientConfig {
79 timeout: std::time::Duration::from_secs(3),
80 stream_reconnect_timeout: std::time::Duration::from_secs(30),
81 dns_override: cfg
82 .dns_override
83 .map(|(ip, port)| ::blokli_client::BlokliDnsOverride { ip, port }),
84 ..Default::default()
85 },
86 )
87}
88
89#[doc(hidden)]
90pub mod reexports {
91 pub use hopr_api::types::chain;
92}
93
94use hopr_api::types::crypto::prelude::Keypair;
95pub use hopr_api::types::{
96 chain::prelude::{ContractAddresses, PayloadGenerator},
97 crypto::prelude::ChainKeypair,
98 primitive::prelude::Address,
99};
100
101pub type HoprBlockchainSafeConnector<C> = HoprBlockchainConnector<
103 C,
104 TempDbBackend,
105 SafePayloadGenerator,
106 <SafePayloadGenerator as PayloadGenerator>::TxRequest,
107>;
108
109pub type HoprBlockchainBasicConnector<C> = HoprBlockchainConnector<
111 C,
112 TempDbBackend,
113 BasicPayloadGenerator,
114 <BasicPayloadGenerator as PayloadGenerator>::TxRequest,
115>;
116
117pub fn create_trustless_hopr_blokli_connector<C>(
122 chain_key: &ChainKeypair,
123 cfg: BlockchainConnectorConfig,
124 client: C,
125 module_address: Address,
126 contracts: ContractAddresses,
127) -> Result<HoprBlockchainSafeConnector<C>, errors::ConnectorError>
128where
129 C: blokli_client::BlokliSubscriptionClient
130 + blokli_client::BlokliQueryClient
131 + blokli_client::BlokliTransactionClient
132 + Send
133 + Sync
134 + 'static,
135{
136 let payload_gen = SafePayloadGenerator::new(chain_key, contracts, module_address);
137
138 Ok(HoprBlockchainConnector::new(
139 chain_key.clone(),
140 cfg,
141 client,
142 TempDbBackend::new().map_err(errors::ConnectorError::backend)?,
143 payload_gen,
144 ))
145}
146
147pub fn create_trustless_safeless_hopr_blokli_connector<C>(
153 chain_key: &ChainKeypair,
154 cfg: BlockchainConnectorConfig,
155 client: C,
156 contracts: ContractAddresses,
157) -> Result<HoprBlockchainBasicConnector<C>, errors::ConnectorError>
158where
159 C: blokli_client::BlokliSubscriptionClient
160 + blokli_client::BlokliQueryClient
161 + blokli_client::BlokliTransactionClient
162 + Send
163 + Sync
164 + 'static,
165{
166 let payload_gen = BasicPayloadGenerator::new(chain_key.public().to_address(), contracts);
167
168 Ok(HoprBlockchainConnector::new(
169 chain_key.clone(),
170 cfg,
171 client,
172 TempDbBackend::new().map_err(errors::ConnectorError::backend)?,
173 payload_gen,
174 ))
175}
176
177pub async fn create_trustful_hopr_blokli_connector<C>(
186 chain_key: &ChainKeypair,
187 cfg: BlockchainConnectorConfig,
188 client: C,
189 module_address: Address,
190) -> Result<HoprBlockchainSafeConnector<C>, errors::ConnectorError>
191where
192 C: blokli_client::BlokliSubscriptionClient
193 + blokli_client::BlokliQueryClient
194 + blokli_client::BlokliTransactionClient
195 + Send
196 + Sync
197 + 'static,
198{
199 let info = client.query_chain_info().await?;
200 let contract_addrs = serde_json::from_str(&info.contract_addresses.0)
201 .map_err(|e| errors::ConnectorError::TypeConversion(format!("contract addresses not a valid JSON: {e}")))?;
202
203 let payload_gen = SafePayloadGenerator::new(chain_key, contract_addrs, module_address);
204
205 Ok(HoprBlockchainConnector::new(
206 chain_key.clone(),
207 cfg,
208 client,
209 TempDbBackend::new().map_err(errors::ConnectorError::backend)?,
210 payload_gen,
211 ))
212}
213
214pub async fn create_trustful_safeless_hopr_blokli_connector<C>(
226 chain_key: &ChainKeypair,
227 cfg: BlockchainConnectorConfig,
228 client: C,
229) -> Result<HoprBlockchainBasicConnector<C>, errors::ConnectorError>
230where
231 C: blokli_client::BlokliSubscriptionClient
232 + blokli_client::BlokliQueryClient
233 + blokli_client::BlokliTransactionClient
234 + Send
235 + Sync
236 + 'static,
237{
238 let info = client.query_chain_info().await?;
239 let contract_addrs = serde_json::from_str(&info.contract_addresses.0)
240 .map_err(|e| errors::ConnectorError::TypeConversion(format!("contract addresses not a valid JSON: {e}")))?;
241
242 let payload_gen = BasicPayloadGenerator::new(chain_key.public().to_address(), contract_addrs);
243
244 Ok(HoprBlockchainConnector::new(
245 chain_key.clone(),
246 cfg,
247 client,
248 TempDbBackend::new().map_err(errors::ConnectorError::backend)?,
249 payload_gen,
250 ))
251}