1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
use crate::provider::{Provider, RemoteProvider};
use crate::{error::Result, UrlExt};
use cubist_config::{
network::{CommonConfig, EndpointConfig, NetworkProfile},
Target,
};
pub fn endpoints(profile: &NetworkProfile) -> impl Iterator<Item = EndpointConfig> {
[
profile.get(Target::Ethereum),
profile.get(Target::Polygon),
profile.get(Target::Avalanche),
profile.get(Target::AvaSubnet),
]
.into_iter()
.flatten()
}
impl From<EndpointConfig> for Box<dyn Config> {
fn from(endpoint: EndpointConfig) -> Self {
match endpoint {
EndpointConfig::Eth(c) => Box::new(c),
EndpointConfig::Poly(c) => Box::new(c),
EndpointConfig::Ava(c) => Box::new(c),
EndpointConfig::AvaSub(c) => Box::new(c.with_default_subnet()),
}
}
}
impl TryFrom<EndpointConfig> for Box<dyn Provider> {
type Error = crate::Error;
fn try_from(endpoint: EndpointConfig) -> Result<Self, Self::Error> {
let config: Box<dyn Config> = endpoint.into();
config.provider()
}
}
pub(crate) fn configs(profile: &NetworkProfile) -> impl Iterator<Item = Box<dyn Config>> {
endpoints(profile).map(From::from)
}
pub(crate) trait Config {
fn name(&self) -> &str;
fn common(&self) -> CommonConfig;
fn provider(&self) -> Result<Box<dyn Provider>> {
let cfg = self.common();
let is_local = cfg.url.is_loopback()?;
if is_local && cfg.autostart {
self.local_provider()
} else {
Ok(Box::new(RemoteProvider {
name: format!("(remote) {}", self.name()),
config: cfg,
}))
}
}
fn local_provider(&self) -> Result<Box<dyn Provider>>;
}