Skip to main content

eth_prices/network/
mod.rs

1/*!
2Network timekeeping for multi-chain quoting.
3
4`eth-prices` splits network state into two complementary types:
5
6- [`NetworkTime`] — a single point-in-time on one network (EVM block or fiat timestamp).
7- [`NetworkInstant`] — a snapshot of multiple network times, keyed by [`NetworkId`].
8
9Because a single route can hop across different chains (e.g. swap on Ethereum, bridge to
10Arbitrum, swap again), the `Quoter::rate` method always receives a
11[`NetworkInstant`] so each step can look up the correct provider and block height.
12
13# Construction
14
15There are two entry points:
16
17**1. From a single network** — use [`NetworkTime::instant()`]:
18
19```rust,ignore
20use eth_prices::network::NetworkTime;
21use alloy::primitives::BlockNumber;
22
23let network = NetworkTime::EVM(1, BlockNumber::from(20_000_000), provider).instant();
24```
25
26**2. From scratch using the builder pattern** — chain multiple
27[`NetworkInstant`] builder methods together:
28
29```rust,ignore
30use eth_prices::network::NetworkInstant;
31
32let networks = NetworkInstant::default()
33    .with_fiat_timestamp(1_700_000_000)
34    .with_evm_block(1, 20_000_000, eth_provider)
35    .with_evm_block(42161, 200_000_000, arb_provider);
36```
37
38The async builders `with_evm_latest` and `with_evm_provider` fetch the latest block
39height from the RPC before inserting:
40
41```rust,ignore
42let networks = NetworkInstant::default()
43    .with_evm_latest(1, eth_provider)
44    .await?
45    .with_fiat_timestamp(now);
46```
47*/
48
49pub mod instant;
50pub mod time;
51
52use alloy::providers::Provider;
53pub use instant::NetworkInstant;
54pub use time::NetworkTime;
55
56use crate::{EthPricesError, provider::RpcProvider};
57
58#[derive(Debug, Clone, PartialEq, Eq, Hash)]
59pub enum Network {
60    EVM(NetworkId),
61    Fiat,
62}
63
64impl Network {
65    pub async fn from_provider(provider: &RpcProvider) -> Result<Self, EthPricesError> {
66        NetworkId::from_provider(provider).await.map(Network::EVM)
67    }
68}
69
70impl From<NetworkId> for Network {
71    fn from(network_id: NetworkId) -> Self {
72        Network::EVM(network_id)
73    }
74}
75
76impl From<&Network> for NetworkId {
77    fn from(network: &Network) -> Self {
78        match network {
79            Network::EVM(network_id) => network_id.clone(),
80            Network::Fiat => NetworkId(0),
81        }
82    }
83}
84
85#[derive(Debug, Clone, PartialEq, Eq, Hash)]
86pub struct NetworkId(pub u64);
87
88impl NetworkId {
89    pub async fn from_provider(provider: &RpcProvider) -> Result<Self, EthPricesError> {
90        provider
91            .get_chain_id()
92            .await
93            .map(NetworkId)
94            .map_err(EthPricesError::from)
95    }
96}
97
98impl From<&NetworkId> for Network {
99    fn from(network_id: &NetworkId) -> Self {
100        Network::EVM(network_id.clone())
101    }
102}
103
104impl From<u64> for NetworkId {
105    fn from(network_id: u64) -> Self {
106        NetworkId(network_id)
107    }
108}