rust_eigenda_v2_client/
lib.rs1pub mod accountant;
2pub mod cert_verifier;
3pub mod commitment_utils;
4pub mod core;
5pub mod disperser_client;
6pub mod errors;
7pub mod payload_disperser;
8pub mod relay_client;
9pub mod relay_payload_retriever;
10pub mod relay_registry;
11pub mod utils;
12pub use rust_eigenda_signers;
14
15#[allow(clippy::all)]
16pub(crate) mod generated {
17 pub(crate) mod common {
18 include!("generated/common.rs");
19
20 pub(crate) mod v2 {
21 include!("generated/common.v2.rs");
22 }
23 }
24
25 pub(crate) mod disperser {
26 pub(crate) mod v2 {
27 include!("generated/disperser.v2.rs");
28 }
29 }
30
31 pub(crate) mod encoder {
32 pub(crate) mod v2 {
33 include!("generated/encoder.v2.rs");
34 }
35 }
36
37 pub(crate) mod retriever {
38 pub(crate) mod v2 {
39 include!("generated/retriever.v2.rs");
40 }
41 }
42
43 pub(crate) mod validator {
44 include!("generated/validator.rs");
45 }
46
47 pub(crate) mod relay {
48 include!("generated/relay.rs");
49 }
50
51 pub(crate) mod contract_bindings {
52 alloy::sol! {
53 #[sol(rpc)]
54 IEigenDACertVerifier, concat!(env!("CARGO_MANIFEST_DIR"), "/src/generated/abi/IEigenDACertVerifier.json"),
55 }
56
57 alloy::sol! {
58 #[sol(rpc)]
59 IEigenDACertVerifierBase, concat!(env!("CARGO_MANIFEST_DIR"), "/src/generated/abi/IEigenDACertVerifierBase.json"),
60 }
61
62 alloy::sol! {
63 #[sol(rpc)]
64 IRelayRegistry, concat!(env!("CARGO_MANIFEST_DIR"), "/src/generated/abi/IEigenDARelayRegistry.json"),
65 }
66
67 alloy::sol! {
68 #[sol(rpc)]
69 IEigenDACertVerifierRouter, concat!(env!("CARGO_MANIFEST_DIR"), "/src/generated/abi/IEigenDACertVerifierRouter.json"),
70 }
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use alloy::primitives::Address;
77 use dotenv::dotenv;
78 use rust_eigenda_v2_common::{EigenDACert, Payload, PayloadForm};
79 use std::{env, str::FromStr, time::Duration};
80 use url::Url;
81
82 use crate::{
83 core::BlobKey,
84 payload_disperser::{PayloadDisperser, PayloadDisperserConfig},
85 relay_client::RelayClient,
86 relay_payload_retriever::{RelayPayloadRetriever, RelayPayloadRetrieverConfig, SRSConfig},
87 utils::SecretUrl,
88 };
89
90 use rust_eigenda_signers::signers::private_key::Signer as PrivateKeySigner;
91
92 const TEST_BLOB_FINALIZATION_TIMEOUT: u64 = 180;
93 const TEST_PAYLOAD_DATA: &[u8] = &[1, 2, 3, 4, 5];
94 pub const HOLESKY_ETH_RPC_URL: &str = "https://ethereum-holesky-rpc.publicnode.com";
95 pub const HOLESKY_DISPERSER_RPC_URL: &str = "https://disperser-testnet-holesky.eigenda.xyz";
96 pub const HOLESKY_RELAY_REGISTRY_ADDRESS: &str = "0xac8c6c7ee7572975454e2f0b5c720f9e74989254";
97 pub const CERT_VERIFIER_ROUTER_ADDRESS: &str = "0xdd735affe77a5ed5b21ed47219f95ed841f8ffbd";
98 pub const REGISTRY_COORDINATOR_ADDRESS: &str = "0x53012C69A189cfA2D9d29eb6F19B32e0A2EA3490";
99 pub const OPERATOR_STATE_RETRIEVER_ADDRESS: &str = "0xB4baAfee917fb4449f5ec64804217bccE9f46C67";
100
101 pub fn get_test_private_key_signer() -> PrivateKeySigner {
102 dotenv().ok();
103 let private_key = env::var("SIGNER_PRIVATE_KEY")
104 .expect("SIGNER_PRIVATE_KEY must be set")
105 .parse()
106 .expect("valid secret key");
107 PrivateKeySigner::new(private_key)
108 }
109
110 fn get_test_payload_disperser_config() -> PayloadDisperserConfig {
111 PayloadDisperserConfig {
112 polynomial_form: PayloadForm::Coeff,
113 blob_version: 0,
114 cert_verifier_router_address: CERT_VERIFIER_ROUTER_ADDRESS.to_string(),
115 eth_rpc_url: get_test_holesky_rpc_url(),
116 disperser_rpc: HOLESKY_DISPERSER_RPC_URL.to_string(),
117 use_secure_grpc_flag: false,
118 registry_coordinator_addr: REGISTRY_COORDINATOR_ADDRESS.to_string(),
119 operator_state_retriever_addr: OPERATOR_STATE_RETRIEVER_ADDRESS.to_string(),
120 }
121 }
122
123 pub fn get_relay_payload_retriever_test_config() -> RelayPayloadRetrieverConfig {
124 RelayPayloadRetrieverConfig {
125 payload_form: PayloadForm::Coeff,
126 retrieval_timeout_secs: Duration::from_secs(10),
127 }
128 }
129
130 pub fn get_srs_test_config() -> SRSConfig {
131 SRSConfig {
132 source_path: "../../resources/g1.point".to_string(),
133 order: 9999999,
134 points_to_load: 9999999,
135 }
136 }
137
138 pub fn get_relay_client_test_config() -> crate::relay_client::RelayClientConfig {
139 crate::relay_client::RelayClientConfig {
140 max_grpc_message_size: 9999999,
141 relay_clients_keys: vec![0, 1, 2],
142 relay_registry_address: Address::from_str(HOLESKY_RELAY_REGISTRY_ADDRESS).unwrap(),
143 eth_rpc_url: get_test_holesky_rpc_url(),
144 }
145 }
146
147 pub fn get_test_holesky_rpc_url() -> SecretUrl {
148 SecretUrl::new(Url::from_str(HOLESKY_ETH_RPC_URL).unwrap())
149 }
150
151 pub async fn get_test_relay_client() -> RelayClient {
152 RelayClient::new(get_relay_client_test_config())
153 .await
154 .unwrap()
155 }
156
157 async fn wait_for_blob_finalization_and_verification(
158 payload_disperser: &PayloadDisperser,
159 blob_key: &BlobKey,
160 ) -> EigenDACert {
161 let timeout = tokio::time::Duration::from_secs(TEST_BLOB_FINALIZATION_TIMEOUT);
162
163 let start_time = tokio::time::Instant::now();
164 loop {
165 let cert = payload_disperser.get_cert(blob_key).await.unwrap();
166 match cert {
167 Some(cert) => {
168 return cert;
169 }
170 None => {
171 let elapsed = start_time.elapsed();
172 assert!(elapsed < timeout, "Timeout waiting for certificate");
173 tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
174 }
175 }
176 }
177 }
178
179 #[ignore = "depends on external RPC"]
180 #[tokio::test]
181 async fn test_disperse_and_retrieve_blob() {
182 let payload_data = TEST_PAYLOAD_DATA.to_vec();
183 let payload = Payload::new(payload_data.clone());
184
185 let payload_disperser = PayloadDisperser::new(
187 get_test_payload_disperser_config(),
188 get_test_private_key_signer(),
189 )
190 .await
191 .unwrap();
192 let blob_key = payload_disperser.send_payload(payload).await.unwrap();
193
194 let eigenda_cert =
196 wait_for_blob_finalization_and_verification(&payload_disperser, &blob_key).await;
197
198 let relay_config = get_relay_payload_retriever_test_config();
200 let srs_config = get_srs_test_config();
201 let relay_client = get_test_relay_client().await;
202 let mut client =
203 RelayPayloadRetriever::new(relay_config, srs_config, relay_client).unwrap();
204
205 let result = client.get_payload(eigenda_cert).await;
206 let retrieved_payload = result.unwrap().serialize();
207 assert_eq!(payload_data, retrieved_payload);
208 }
209}