init4_bin_base/utils/
provider.rs1use crate::utils::from_env::{FromEnvErr, FromEnvVar};
2use alloy::{
3 providers::{IpcConnect, RootProvider, WsConnect},
4 pubsub::{ConnectionHandle, PubSubConnect},
5 rpc::client::BuiltInConnectionString,
6 transports::{
7 BoxTransport, TransportConnect, TransportError, TransportErrorKind, TransportResult,
8 },
9};
10
11impl FromEnvVar for BuiltInConnectionString {
12 type Error = TransportError;
13
14 fn from_env_var(env_var: &str) -> Result<Self, FromEnvErr<Self::Error>> {
15 let conn_str = String::from_env_var(env_var).map_err(FromEnvErr::infallible_into)?;
16 conn_str.parse().map_err(Into::into)
17 }
18}
19
20#[derive(Debug, Clone, PartialEq, Eq)]
22pub struct ProviderConfig {
23 connection_string: BuiltInConnectionString,
24}
25
26impl ProviderConfig {
27 pub const fn new(connection_string: BuiltInConnectionString) -> Self {
29 Self { connection_string }
30 }
31
32 pub const fn connection_string(&self) -> &BuiltInConnectionString {
34 &self.connection_string
35 }
36
37 pub async fn connect(&self) -> TransportResult<RootProvider> {
39 RootProvider::connect_with(self.clone()).await
40 }
41}
42
43impl FromEnvVar for ProviderConfig {
44 type Error = TransportError;
45
46 fn from_env_var(env_var: &str) -> Result<Self, FromEnvErr<Self::Error>> {
47 let connection_string = BuiltInConnectionString::from_env_var(env_var)?;
48 Ok(Self { connection_string })
49 }
50}
51
52impl TransportConnect for ProviderConfig {
53 fn is_local(&self) -> bool {
54 self.connection_string.is_local()
55 }
56
57 fn get_transport(
58 &self,
59 ) -> alloy::transports::impl_future!(<Output = Result<BoxTransport, TransportError>>) {
60 self.connection_string.get_transport()
61 }
62}
63
64#[derive(Debug, Clone, PartialEq, Eq)]
67pub struct PubSubConfig {
68 connection_string: BuiltInConnectionString,
69}
70
71impl PubSubConfig {
72 pub const fn connection_string(&self) -> &BuiltInConnectionString {
74 &self.connection_string
75 }
76
77 pub async fn connect(&self) -> TransportResult<RootProvider> {
79 RootProvider::connect_with(self.clone()).await
80 }
81}
82
83impl TryFrom<BuiltInConnectionString> for PubSubConfig {
84 type Error = TransportError;
85
86 fn try_from(connection_string: BuiltInConnectionString) -> Result<Self, Self::Error> {
87 if !matches!(
88 connection_string,
89 BuiltInConnectionString::Ws(_, _) | BuiltInConnectionString::Ipc(_)
90 ) {
91 return Err(TransportErrorKind::pubsub_unavailable());
92 }
93 Ok(Self { connection_string })
94 }
95}
96
97impl FromEnvVar for PubSubConfig {
98 type Error = TransportError;
99
100 fn from_env_var(env_var: &str) -> Result<Self, FromEnvErr<Self::Error>> {
101 let cs = BuiltInConnectionString::from_env_var(env_var)?;
102 Self::try_from(cs).map_err(FromEnvErr::ParseError)
103 }
104}
105
106impl TransportConnect for PubSubConfig {
107 fn is_local(&self) -> bool {
108 self.connection_string.is_local()
109 }
110
111 fn get_transport(
112 &self,
113 ) -> alloy::transports::impl_future!(<Output = Result<BoxTransport, TransportError>>) {
114 self.connection_string.get_transport()
115 }
116}
117
118impl PubSubConnect for PubSubConfig {
119 fn is_local(&self) -> bool {
120 self.connection_string.is_local()
121 }
122
123 fn connect(
124 &self,
125 ) -> alloy::transports::impl_future!(<Output = TransportResult<ConnectionHandle>>) {
126 async move {
127 match &self.connection_string {
128 BuiltInConnectionString::Ws(ws, auth) => {
129 WsConnect::new(ws.as_str())
130 .with_auth_opt(auth.clone())
131 .connect()
132 .await
133 }
134 BuiltInConnectionString::Ipc(ipc) => IpcConnect::new(ipc.clone()).connect().await,
135 _ => unreachable!("can't instantiate http variant"),
136 }
137 }
138 }
139}