From b3944823b03b7f01faeda9efc27fae5090d6e8ec Mon Sep 17 00:00:00 2001 From: Pablo Deymonnaz Date: Tue, 24 Sep 2024 13:18:53 -0300 Subject: [PATCH] Add docs and error handling improved (#125) Co-authored-by: tomasarrachea --- README.md | 14 +-- crates/chainio/README.md | 4 +- .../chainio/clients/avsregistry/src/reader.rs | 15 +-- .../chainio/clients/elcontracts/src/reader.rs | 117 +++++++++++++++++- .../chainio/clients/elcontracts/src/writer.rs | 85 ++++++++----- .../clients/eth/src/instrumented_client.rs | 12 ++ crates/chainio/clients/mocks/fireblocks.rs | 0 crates/chainio/clients/mocks/lib.rs | 9 -- crates/chainio/clients/mocks/wallet.rs | 0 .../txmanager/src/simple_tx_manager.rs | 71 +++++++---- .../bindings/src/generate_bindings.rs | 18 ++- crates/crypto/bls/README.md | 15 +-- crates/crypto/bn254/README.md | 2 +- crates/eigen-cli/src/generate.rs | 12 +- crates/eigensdk/README.md | 6 +- crates/metrics/README.md | 2 +- crates/services/README.md | 11 +- .../services/avsregistry/src/chaincaller.rs | 23 ++++ .../src/fake_avs_registry_service.rs | 11 ++ .../services/bls_aggregation/src/bls_agg.rs | 22 ++-- crates/services/bls_aggregation/src/lib.rs | 4 + .../operatorsinfo/src/fake_operator_info.rs | 1 + crates/services/operatorsinfo/src/lib.rs | 2 + .../src/operatorsinfo_inmemory.rs | 65 +++++++--- crates/signer/README.md | 4 +- crates/signer/src/web3_signer.rs | 1 + crates/types/README.md | 2 +- crates/types/src/avs.rs | 2 + crates/types/src/operator.rs | 8 +- crates/types/src/test.rs | 2 + examples/README.md | 13 +- .../examples/get_operator_info.rs | 25 ++-- testing/testing-utils/README.md | 27 ++-- 33 files changed, 424 insertions(+), 181 deletions(-) delete mode 100644 crates/chainio/clients/mocks/fireblocks.rs delete mode 100644 crates/chainio/clients/mocks/lib.rs delete mode 100644 crates/chainio/clients/mocks/wallet.rs diff --git a/README.md b/README.md index d2af8aaa..a6963f9d 100644 --- a/README.md +++ b/README.md @@ -17,15 +17,15 @@ List of crates in the repository :- - [eigen-contracts-bindings](https://github.com/Layr-Labs/eigensdk-rs/tree/main/crates/contracts/bindings) - Generate ethers bindings for Eigen Layer. - [eigen-crypto-bls](https://github.com/Layr-Labs/eigensdk-rs/tree/main/crates/crypto/bls) - New bls key pair, sign message, conversion utilites between alloy and arkworks bn254. - [eigen-crypto-bn254](https://github.com/Layr-Labs/eigensdk-rs/tree/main/crates/crypto/bn254) - verify message on G2, map to curve. -- [eigen-metrics](https://github.com/Layr-Labs/eigensdk-rs/tree/main/crates/metrics) - performance , rpc and economic metrics -- [eigen-services](https://github.com/Layr-Labs/eigensdk-rs/tree/main/crates/services) - Spawn tokio services for operators info , bls aggregation +- [eigen-metrics](https://github.com/Layr-Labs/eigensdk-rs/tree/main/crates/metrics) - performance, rpc and economic metrics +- [eigen-services](https://github.com/Layr-Labs/eigensdk-rs/tree/main/crates/services) - Spawn tokio services for operators info, bls aggregation - [eigen-types](https://github.com/Layr-Labs/eigensdk-rs/tree/main/crates/types) - Common types - [eigen-utils](https://github.com/Layr-Labs/eigensdk-rs/tree/main/crates/utils) - Publicly exportable `m2-mainnet` compatible alloy bindings. -- [eigen-testing-utils](https://github.com/Layr-Labs/eigensdk-rs/tree/main/testing/testing-utils) - Contains publicly exportable anvil , holesky , mainnet addresses for eigen contracts . +- [eigen-testing-utils](https://github.com/Layr-Labs/eigensdk-rs/tree/main/testing/testing-utils) - Contains publicly exportable anvil, holesky, mainnet addresses for eigen contracts. ## Examples -You can run any [example](https://github.com/Layr-Labs/eigensdk-rs/tree/main/examples) using the command cargo run --example +You can run any [example](https://github.com/Layr-Labs/eigensdk-rs/tree/main/examples) using the command `cargo run --example ` Example : @@ -35,7 +35,7 @@ cargo run --example get_quorum_count ## Contributor Guidelines -We are actively looking for contributors. Thank you for your interest. We have strict ci checks in place. In case of any questions and support , feel free to raise an issue. +We are actively looking for contributors. Thank you for your interest. We have strict ci checks in place. In case of any questions and support, feel free to raise an issue. ### PR To test locally :- @@ -100,11 +100,11 @@ Rolling `MSRV` policy of 6 months. The current `MSRV` is 1.79 This software is `unaudited`.This is experimental software and is provided on an "as is" and "as available" basis and may not work at all. It should not be used in production. -# Credits +## Credits - [eigensdk-go](https://github.com/Layr-Labs/eigensdk-go/tree/master) -# Security Bugs +## Security Bugs Please report security vulnerabilities to . Do NOT report security bugs via Github Issues. diff --git a/crates/chainio/README.md b/crates/chainio/README.md index f76f470a..46bfa45f 100644 --- a/crates/chainio/README.md +++ b/crates/chainio/README.md @@ -1,5 +1,3 @@ # ChainIo -Read / write / subscribe to eigen core contract and avs contract. - - \ No newline at end of file +Read / write / subscribe to eigen core contract and avs contract. diff --git a/crates/chainio/clients/avsregistry/src/reader.rs b/crates/chainio/clients/avsregistry/src/reader.rs index ff845bab..006e9c9b 100644 --- a/crates/chainio/clients/avsregistry/src/reader.rs +++ b/crates/chainio/clients/avsregistry/src/reader.rs @@ -93,19 +93,14 @@ impl AvsRegistryReader for AvsRegistryChainReader { let contract_operator_state_retriever = OperatorStateRetriever::new(self.operator_state_retriever, provider); - let operator_state_result = contract_operator_state_retriever + let operator_state = contract_operator_state_retriever .getOperatorState_0(self.registry_coordinator_addr, quorum_numbers, block_number) .call() - .await; + .await + .map_err(|_| AvsRegistryError::GetOperatorState)?; - match operator_state_result { - Ok(operator_state) => { - let OperatorStateRetriever::getOperatorState_0Return { _0: quorum } = - operator_state; - Ok(quorum) - } - Err(_) => Err(AvsRegistryError::GetOperatorState), - } + let OperatorStateRetriever::getOperatorState_0Return { _0: quorum } = operator_state; + Ok(quorum) } async fn get_check_signatures_indices( diff --git a/crates/chainio/clients/elcontracts/src/reader.rs b/crates/chainio/clients/elcontracts/src/reader.rs index d567165b..b97af92c 100644 --- a/crates/chainio/clients/elcontracts/src/reader.rs +++ b/crates/chainio/clients/elcontracts/src/reader.rs @@ -17,6 +17,19 @@ pub struct ELChainReader { } impl ELChainReader { + /// Creates a new `ELChainReader` instance with the given parameters. + /// + /// # Arguments + /// + /// * `_logger` - The logger to use for logging. + /// * `slasher` - The address of the slasher contract. + /// * `delegation_manager` - The address of the delegation manager contract. + /// * `avs_directory` - The address of the avs directory contract. + /// * `provider` - The provider to use for the RPC client. + /// + /// # Returns + /// + /// A new `ELChainReader` instance. pub fn new( _logger: SharedLogger, slasher: Address, @@ -33,7 +46,21 @@ impl ELChainReader { } } - /// Builds a new [`ELChainReader`] instance . + /// Builds a new `ELChainReader` instance, getting the slasher address from the delegation manager + /// by calling the `slasher()` function and the corresponding Contract function. + /// + /// # Arguments + /// + /// * `_logger` - The logger to use for logging. + /// * `delegation_manager` - The address of the delegation manager contract. + /// * `avs_directory` - The address of the avs directory contract. + /// * `client` - The provider to use for the RPC client to call the contracts. + /// + /// # Returns + /// + /// A new `ELChainReader` instance. + /// + /// # Errors pub async fn build( _logger: SharedLogger, delegation_manager: Address, @@ -61,6 +88,23 @@ impl ELChainReader { }) } + /// Calculate the delegation approval digest hash + /// + /// # Arguments + /// + /// * `staker` - The staker's address + /// * `operator` - The operator's address + /// * `delegation_approver` - The delegation approver's address + /// * `approve_salt` - The approve salt + /// * `expiry` - The expiry + /// + /// # Returns + /// + /// * `FixedBytes<32>` - The delegation approval digest hash + /// + /// # Errors + /// + /// * `ElContractsError` - if the call to the contract fails pub async fn calculate_delegation_approval_digest_hash( &self, staker: Address, @@ -89,6 +133,22 @@ impl ELChainReader { Ok(digest_hash) } + /// Calculate the operator avs registration digest hash + /// + /// # Arguments + /// + /// * `operator` - The operator's address + /// * `avs` - The avs's address + /// * `salt` - The salt + /// * `expiry` - The expiry + /// + /// # Returns + /// + /// * `FixedBytes<32>` - The operator avs registration digest hash + /// + /// # Errors + /// + /// * `ElContractsError` - if the call to the contract fails pub async fn calculate_operator_avs_registration_digest_hash( &self, operator: Address, @@ -122,6 +182,10 @@ impl ELChainReader { /// # Returns /// /// * `U256` - The operator's shares in the strategy + /// + /// # Errors + /// + /// * `ElContractsError` - if the call to the contract fails pub async fn get_operator_shares_in_strategy( &self, operator_addr: Address, @@ -141,6 +205,17 @@ impl ELChainReader { Ok(shares) } + /// Check if the operator is frozen + /// + /// # Arguments + /// + /// * `operator_addr` - The operator's address + /// + /// # Returns + /// + /// * `bool` - True if the operator is frozen, false otherwise + /// + /// # Errors pub async fn operator_is_frozen( &self, operator_addr: Address, @@ -159,6 +234,20 @@ impl ELChainReader { Ok(is_froze) } + /// Check if the service manager can slash the operator + /// + /// # Arguments + /// + /// * `operator_addr` - The operator's address + /// * `service_manager_addr` - The service manager's address + /// + /// # Returns + /// + /// * `u32` - The block number until the operator can be slashed + /// + /// # Errors + /// + /// * `ElContractsError` - if the call to the contract fails pub async fn service_manager_can_slash_operator_until_block( &self, operator_addr: Address, @@ -222,6 +311,19 @@ impl ELChainReader { )) } + /// Get the operator's details + /// + /// # Arguments + /// + /// * `operator` - The operator's address + /// + /// # Returns + /// + /// * `Operator` - The operator's details + /// + /// # Errors + /// + /// * `ElContractsError` - if the call to the contract fails pub async fn get_operator_details( &self, operator: Address, @@ -250,6 +352,19 @@ impl ELChainReader { }) } + /// Check if the operator is registered + /// + /// # Arguments + /// + /// * `operator` - The operator's address + /// + /// # Returns + /// + /// * `bool` - true if the operator is registered, false otherwise + /// + /// # Errors + /// + /// * `ElContractsError` - if the call to the contract fails pub async fn is_operator_registered( &self, operator: Address, diff --git a/crates/chainio/clients/elcontracts/src/writer.rs b/crates/chainio/clients/elcontracts/src/writer.rs index 2765941a..9c58b698 100644 --- a/crates/chainio/clients/elcontracts/src/writer.rs +++ b/crates/chainio/clients/elcontracts/src/writer.rs @@ -13,6 +13,7 @@ use DelegationManager::OperatorDetails; /// Gas limit for registerAsOperator in [`DelegationManager`] pub const GAS_LIMIT_REGISTER_AS_OPERATOR_DELEGATION_MANAGER: u128 = 300000; +/// Chain Writer to interact with EigenLayer contracts onchain #[derive(Debug, Clone)] pub struct ELChainWriter { delegation_manager: Address, @@ -39,6 +40,19 @@ impl ELChainWriter { } } + /// Register an operator to EigenLayer + /// + /// # Arguments + /// + /// * `operator` - The operator to register + /// + /// # Returns + /// + /// * `FixedBytes<32>` - The transaction hash if successful, otherwise an error + /// + /// # Errors + /// + /// * `ElContractsError` - if the call to the contract fails pub async fn register_as_operator( &self, operator: Operator, @@ -78,6 +92,19 @@ impl ELChainWriter { Ok(hash) } + /// Update operator details on EigenLayer + /// + /// # Arguments + /// + /// * `operator` - The operator to update + /// + /// # Returns + /// + /// * `TxHash` - The transaction hash if successful, otherwise an error + /// + /// # Errors + /// + /// * `ElContractsError` - if the call to the contract fails pub async fn update_operator_details( &self, operator: Operator, @@ -113,50 +140,48 @@ impl ELChainWriter { Ok(*metadata_tx.tx_hash()) } + /// Deposit ERC20 tokens into a strategy on EigenLayer + /// + /// # Arguments + /// + /// * `strategy_addr` - The address of the strategy to deposit into + /// * `amount` - The amount of tokens to deposit + /// + /// # Returns + /// + /// * `TxHash` - The transaction hash if successful, otherwise an error + /// + /// # Errors + /// + /// * `ElContractsError` - if the call to the contract fails pub async fn deposit_erc20_into_strategy( &self, strategy_addr: Address, amount: U256, ) -> Result { - info!( - "depositing {:?} tokens into strategy {:?}", - amount, strategy_addr - ); - let tokens_result = self + info!("depositing {amount:?} tokens into strategy {strategy_addr:?}"); + let tokens = self .el_chain_reader .get_strategy_and_underlying_erc20_token(strategy_addr) - .await; - match tokens_result { - Ok(tokens) => { - let (_, underlying_token_contract, underlying_token) = tokens; - let provider = get_signer(self.signer.clone(), &self.provider); + .await?; + let (_, underlying_token_contract, underlying_token) = tokens; + let provider = get_signer(self.signer.clone(), &self.provider); - let contract_underlying_token = IERC20::new(underlying_token_contract, &provider); + let contract_underlying_token = IERC20::new(underlying_token_contract, &provider); - let contract_call = - contract_underlying_token.approve(self.strategy_manager, amount); + let contract_call = contract_underlying_token.approve(self.strategy_manager, amount); - let _approve = contract_call.send().await?; + let _approve = contract_call.send().await?; - let contract_strategy_manager = - StrategyManager::new(self.strategy_manager, &provider); + let contract_strategy_manager = StrategyManager::new(self.strategy_manager, &provider); - let deposit_contract_call = contract_strategy_manager.depositIntoStrategy( - strategy_addr, - underlying_token, - amount, - ); + let deposit_contract_call = + contract_strategy_manager.depositIntoStrategy(strategy_addr, underlying_token, amount); - let tx = deposit_contract_call.send().await?; + let tx = deposit_contract_call.send().await?; - info!( - "deposited {:?} tokens into strategy {:?}", - amount, strategy_addr - ); - Ok(*tx.tx_hash()) - } - Err(e) => Err(e), - } + info!("deposited {amount:?} tokens into strategy {strategy_addr:?}"); + Ok(*tx.tx_hash()) } } diff --git a/crates/chainio/clients/eth/src/instrumented_client.rs b/crates/chainio/clients/eth/src/instrumented_client.rs index 920f6446..6120cd8c 100644 --- a/crates/chainio/clients/eth/src/instrumented_client.rs +++ b/crates/chainio/clients/eth/src/instrumented_client.rs @@ -50,6 +50,10 @@ impl BackendClient for InstrumentedClient { /// # Returns /// /// The latest block number. + /// + /// # Errors + /// + /// Returns an error if the RPC call fails. async fn block_number(&self) -> Result { self.instrument_function("eth_blockNumber", ()) .await @@ -71,6 +75,10 @@ impl BackendClient for InstrumentedClient { /// # Returns /// /// The block having the given block number. + /// + /// # Errors + /// + /// Returns an error if the RPC call fails. async fn block_by_number( &self, number: BlockNumberOrTag, @@ -184,6 +192,10 @@ impl InstrumentedClient { /// # Returns /// /// The chain ID. + /// + /// # Errors + /// + /// Returns an error if the RPC call fails. pub async fn chain_id(&self) -> TransportResult { self.instrument_function("eth_chainId", ()) .await diff --git a/crates/chainio/clients/mocks/fireblocks.rs b/crates/chainio/clients/mocks/fireblocks.rs deleted file mode 100644 index e69de29b..00000000 diff --git a/crates/chainio/clients/mocks/lib.rs b/crates/chainio/clients/mocks/lib.rs deleted file mode 100644 index 411a4606..00000000 --- a/crates/chainio/clients/mocks/lib.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![doc( - html_logo_url = "https://github.com/Layr-Labs/eigensdk-rs/assets/91280922/bd13caec-3c00-4afc-839a-b83d2890beb5", - issue_tracker_base_url = "https://github.com/Layr-Labs/eigensdk-rs/issues/" -)] -#![cfg_attr(not(test), warn(unused_crate_dependencies))] - -mod fireblocks; - -mod wallet; diff --git a/crates/chainio/clients/mocks/wallet.rs b/crates/chainio/clients/mocks/wallet.rs deleted file mode 100644 index e69de29b..00000000 diff --git a/crates/chainio/txmanager/src/simple_tx_manager.rs b/crates/chainio/txmanager/src/simple_tx_manager.rs index 7ef58a4f..3c0ac2c2 100644 --- a/crates/chainio/txmanager/src/simple_tx_manager.rs +++ b/crates/chainio/txmanager/src/simple_tx_manager.rs @@ -29,6 +29,7 @@ pub enum TxManagerError { InvalidUrlError, } +/// A simple transaction manager that encapsulates operations to send transactions to an Ethereum node. pub struct SimpleTxManager { logger: SharedLogger, gas_limit_multiplier: f64, @@ -41,18 +42,18 @@ impl SimpleTxManager { /// /// # Arguments /// - /// - `logger`: The logger to be used. - /// - `gas_limit_multiplier`: The gas limit multiplier. - /// - `private_key`: The private key of the wallet. - /// - `rpc_url`: The RPC URL. It could be an anvil node or any other node. + /// * `logger`: The logger to be used. + /// * `gas_limit_multiplier`: The gas limit multiplier. + /// * `private_key`: The private key of the wallet. + /// * `rpc_url`: The RPC URL. It could be an anvil node or any other node. /// /// # Returns /// - /// - The SimpleTxManager created. + /// * The SimpleTxManager created. /// /// # Errors /// - /// - If the URL is invalid. + /// * If the URL is invalid. pub fn new( logger: SharedLogger, gas_limit_multiplier: f64, @@ -90,10 +91,24 @@ impl SimpleTxManager { Ok(Address::from_private_key(&private_key_signing_key)) } + /// Sets the gas limit multiplier. + /// + /// # Arguments + /// + /// * `multiplier` - The gas limit multiplier. pub fn with_gas_limit_multiplier(&mut self, multiplier: f64) { self.gas_limit_multiplier = multiplier; } + /// Creates a local signer. + /// + /// # Returns + /// + /// * `PrivateKeySigner` The local signer. + /// + /// # Errors + /// + /// * If the signer cannot be created. fn create_local_signer(&self) -> Result { let config = Config::PrivateKey(self.private_key.clone()); Config::signer_from_config(config) @@ -111,11 +126,16 @@ impl SimpleTxManager { /// /// # Arguments /// - /// - `tx`: The transaction to be sent. + /// * `tx`: The transaction to be sent. /// /// # Returns /// - /// - The transaction receipt. + /// * `TransactionReceipt` The transaction receipt. + /// + /// # Errors + /// + /// * `TxManagerError` - If the transaction cannot be sent, or there is an error + /// signing the transaction or estimating gas and nonce. pub async fn send_tx( &self, tx: &mut TransactionRequest, @@ -160,19 +180,19 @@ impl SimpleTxManager { /// /// # Arguments /// - /// - `tx`: The transaction for which we want to estimate the gas and nonce. + /// * `tx`: The transaction for which we want to estimate the gas and nonce. /// /// # Returns /// - /// - The transaction request with the gas and nonce estimated. + /// * The transaction request with the gas and nonce estimated. /// /// # Errors /// - /// - If the transaction request could not sent of gives an error. - /// - If the latest block header could not be retrieved. - /// - If the gas price could not be estimated. - /// - If the gas limit could not be estimated. - /// - If the destination address could not be retrieved. + /// * If the transaction request could not sent of gives an error. + /// * If the latest block header could not be retrieved. + /// * If the gas price could not be estimated. + /// * If the gas limit could not be estimated. + /// * If the destination address could not be retrieved. async fn estimate_gas_and_nonce( &self, tx: &TransactionRequest, @@ -203,10 +223,8 @@ impl SimpleTxManager { // we only estimate if gas_limit is not already set if let Some(0) = gas_limit { let from = self.get_address()?; - let to = match tx.to() { - Some(c) => c, - None => return Err(TxManagerError::SendTxError), - }; + let to = tx.to().ok_or(TxManagerError::SendTxError)?; + let mut tx_request = TransactionRequest::default() .to(to) .from(from) @@ -226,10 +244,7 @@ impl SimpleTxManager { tx.gas_price().unwrap_or_default() as f64 * self.gas_limit_multiplier; let gas_price = gas_price_multiplied as u128; - let to = match tx.to() { - None => return Err(TxManagerError::SendTxError), - Some(adress) => adress, - }; + let to = tx.to().ok_or(TxManagerError::SendTxError)?; let new_tx = TransactionRequest::default() .with_to(to) @@ -251,12 +266,16 @@ impl SimpleTxManager { /// /// # Arguments /// - /// - `pending_tx`: The pending transaction builder we want to wait for. + /// * `pending_tx`: The pending transaction builder we want to wait for. /// /// # Returns /// - /// - The block number in which the transaction was included. - /// - `None` if the transaction was not included in a block or an error ocurred. + /// * The block number in which the transaction was included. + /// * `None` if the transaction was not included in a block or an error ocurred. + /// + /// # Errors + /// + /// * `TxManagerError` - If the transaction receipt cannot be retrieved. pub async fn wait_for_receipt( &self, pending_tx: PendingTransactionBuilder<'_, Transport, Ethereum>, diff --git a/crates/contracts/bindings/src/generate_bindings.rs b/crates/contracts/bindings/src/generate_bindings.rs index 136e2ddb..7ff51fce 100644 --- a/crates/contracts/bindings/src/generate_bindings.rs +++ b/crates/contracts/bindings/src/generate_bindings.rs @@ -6,17 +6,13 @@ mod tests { fn generate_bindings(contract_name: &str, input_path: &str, output_path: &str) { let coontract: String = format!("../bindings/utils/json/{input_path}").to_string(); - match Abigen::new(&contract_name, coontract) { - Ok(v) => { - let _ = v - .generate() - .expect("failed to abigen") - .write_to_file(format!("{output_path}/src/{contract_name}.rs")); - } - Err(e) => { - println!("abigenerr{}", e); - } - } + let v = Abigen::new(&contract_name, coontract) + .inspect_err(|e| println!("abigenerr{}", e)) + .unwrap(); + let _ = v + .generate() + .expect("failed to abigen") + .write_to_file(format!("{output_path}/src/{contract_name}.rs")); } #[test] diff --git a/crates/crypto/bls/README.md b/crates/crypto/bls/README.md index da57cf08..45a699f4 100644 --- a/crates/crypto/bls/README.md +++ b/crates/crypto/bls/README.md @@ -1,14 +1,15 @@ -# Eigen Layer Bls +# Eigen Layer Bls This crate contains the following utilities: -- New bls key pair generation +- New bls key pair generation - Get Public Key on G1 and G2 - Helper functions to convert Arkworks parameters to alloy compatible . Ex: - - convert_to_g1_point : Converts G1Affine to Alloy compatible G1Point - - convert_to_g2_point : Converts G2Affine to Alloy compatible G2Point - - alloy_g1_point_to_g1_affine: Converts Alloy G1Point to G1Affine + - convert_to_g1_point : Converts G1Affine to Alloy compatible G1Point + - convert_to_g2_point : Converts G2Affine to Alloy compatible G2Point + - alloy_g1_point_to_g1_affine: Converts Alloy G1Point to G1Affine - Signing a message using the keypair -## Example -- [Registering an operator](https://github.com/Layr-Labs/eigensdk-rs/blob/main/examples/avsregistry-write/examples/register_operator_in_quorum_with_avs_registry_coordinator.rs) \ No newline at end of file +## Example + +- [Registering an operator](https://github.com/Layr-Labs/eigensdk-rs/blob/main/examples/avsregistry-write/examples/register_operator_in_quorum_with_avs_registry_coordinator.rs) diff --git a/crates/crypto/bn254/README.md b/crates/crypto/bn254/README.md index 608616c3..0656c6d8 100644 --- a/crates/crypto/bn254/README.md +++ b/crates/crypto/bn254/README.md @@ -1 +1 @@ -# Eigen SDk Bn254 utilities \ No newline at end of file +# Eigen SDk Bn254 utilities diff --git a/crates/eigen-cli/src/generate.rs b/crates/eigen-cli/src/generate.rs index 8056111a..0a204941 100644 --- a/crates/eigen-cli/src/generate.rs +++ b/crates/eigen-cli/src/generate.rs @@ -34,13 +34,11 @@ impl KeyGenerator { num_keys: u32, output_dir: Option, ) -> Result<(), EigenKeyCliError> { - let dir_name = match output_dir { - None => { - let id = Uuid::new_v4(); - format!("{}-{}", self.key_name(), id) - } - Some(dir) => dir, - }; + let dir_name = output_dir.unwrap_or_else(|| { + let id = Uuid::new_v4(); + format!("{}-{}", self.key_name(), id) + }); + let dir_path = Path::new(&dir_name); let key_path = dir_path.join(DEFAULT_KEY_FOLDER); fs::create_dir_all(key_path).map_err(EigenKeyCliError::FileError)?; diff --git a/crates/eigensdk/README.md b/crates/eigensdk/README.md index 0feec9a8..8e250cf0 100644 --- a/crates/eigensdk/README.md +++ b/crates/eigensdk/README.md @@ -21,7 +21,7 @@ List of crates in the repository :- ## Examples -You can run any [example](https://github.com/Layr-Labs/eigensdk-rs/tree/main/examples) using the command cargo run --example +You can run any [example](https://github.com/Layr-Labs/eigensdk-rs/tree/main/examples) using the command `cargo run --example ` Example : @@ -94,11 +94,11 @@ Rolling `MSRV` policy of 6 months. The current `MSRV` is 1.79 This software is `unaudited`.This is experimental software and is provided on an "as is" and "as available" basis and may not work at all. It should not be used in production. -# Credits +## Credits - [Layer-labs](https://github.com/Layr-Labs/eigensdk-go/tree/master) -# Security Bugs +## Security Bugs Please report security vulnerabilities to . Do NOT report security bugs via Github Issues. diff --git a/crates/metrics/README.md b/crates/metrics/README.md index 4827e6af..231a67c5 100644 --- a/crates/metrics/README.md +++ b/crates/metrics/README.md @@ -1,3 +1,3 @@ # EigenMetrics -Implementation of EigenLayer AVS node [spec](https://docs.eigenlayer.xyz/category/metrics) \ No newline at end of file +Implementation of EigenLayer AVS node [spec](https://docs.eigenlayer.xyz/category/metrics) diff --git a/crates/services/README.md b/crates/services/README.md index dd0f65af..369183c3 100644 --- a/crates/services/README.md +++ b/crates/services/README.md @@ -1,9 +1,8 @@ -# SDK services +# SDK services -The eigensdk provides 3 services , namely : +The eigensdk provides 3 services, namely : -- OperatorInfoServiceInMemory +- **OperatorInfoServiceInMemory** - The `eigen-services-operatorsinfo` crate provides functionalities to manage and track operator information using an in-memory database. It supports querying past operato registrations, subscribing to new operator registration events, and retrieving operator information efficiently. - -- eigen-services-avsregistry - - The `eigen-services-avsregistry` crate is a wrapper around AvsRegistryReader. \ No newline at end of file +- `eigen-services-avsregistry` + - The `eigen-services-avsregistry` crate is a wrapper around AvsRegistryReader. diff --git a/crates/services/avsregistry/src/chaincaller.rs b/crates/services/avsregistry/src/chaincaller.rs index 087385ad..285d94ac 100644 --- a/crates/services/avsregistry/src/chaincaller.rs +++ b/crates/services/avsregistry/src/chaincaller.rs @@ -137,6 +137,19 @@ impl AvsRegistryServ } impl AvsRegistryServiceChainCaller { + /// Returns the operator info for the given operator id + /// + /// # Arguments + /// + /// * `operator_id` - The operator id + /// + /// # Returns + /// + /// The operator info + /// + /// # Errors + /// + /// An error is returned if the operator info is not found or can not be retrieved async fn get_operator_info( &self, operator_id: [u8; 32], @@ -190,6 +203,16 @@ mod tests { const OPERATOR_ID: &str = "48beccce16ccdf8000c13d5af5f91c7c3dac6c47b339d993d229af1500dbe4a9"; const OPERATOR_ADDRESS: &str = "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720"; + /// Helper function to build a TestOperator given a private key and an operator id + /// + /// # Arguments + /// + /// * `private_key_decimal` - The private key of the operator in decimal format + /// * `operator_id` - The operator id + /// + /// # Returns + /// + /// The TestOperator element fn build_test_operator(private_key_decimal: &str, operator_id: &str) -> TestOperator { let bls_keypair = BlsKeyPair::new(private_key_decimal.into()).unwrap(); let operator_id = diff --git a/crates/services/avsregistry/src/fake_avs_registry_service.rs b/crates/services/avsregistry/src/fake_avs_registry_service.rs index 07e613f2..5543b03a 100644 --- a/crates/services/avsregistry/src/fake_avs_registry_service.rs +++ b/crates/services/avsregistry/src/fake_avs_registry_service.rs @@ -14,12 +14,23 @@ use eigen_utils::binding::OperatorStateRetriever::CheckSignaturesIndices; use crate::AvsRegistryService; +/// A fake implementation of the `AvsRegistryService` trait that can be used for testing or debug purposes. #[derive(Clone)] pub struct FakeAvsRegistryService { operators: HashMap>, } impl FakeAvsRegistryService { + /// Create a new instance of the `FakeAvsRegistryService` with the given `block_number` and `test_operators`. + /// + /// # Arguments + /// + /// * `block_number` - The block number at which the operators are registered. + /// * `test_operators` - A list of `TestOperator` instances to be included in the registry. + /// + /// # Returns + /// + /// A new instance of the `FakeAvsRegistryService`. pub fn new(block_number: BlockNumber, test_operators: Vec) -> Self { let mut state_per_operator_id: HashMap = HashMap::new(); diff --git a/crates/services/bls_aggregation/src/bls_agg.rs b/crates/services/bls_aggregation/src/bls_agg.rs index 0a13f34e..3c8f9c5a 100644 --- a/crates/services/bls_aggregation/src/bls_agg.rs +++ b/crates/services/bls_aggregation/src/bls_agg.rs @@ -1,13 +1,11 @@ use alloy_primitives::{FixedBytes, U256}; use ark_bn254::G2Affine; use ark_ec::AffineRepr; -use eigen_crypto_bls::BlsG1Point; -use eigen_crypto_bls::{BlsG2Point, Signature}; +use eigen_crypto_bls::{BlsG1Point, BlsG2Point, Signature}; use eigen_crypto_bn254::utils::verify_message; use eigen_services_avsregistry::AvsRegistryService; -use eigen_types::avs::SignatureVerificationError; use eigen_types::{ - avs::{SignedTaskResponseDigest, TaskIndex, TaskResponseDigest}, + avs::{SignatureVerificationError, SignedTaskResponseDigest, TaskIndex, TaskResponseDigest}, operator::{OperatorAvsState, QuorumThresholdPercentage, QuorumThresholdPercentages}, }; use parking_lot::RwLock; @@ -15,12 +13,15 @@ use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::sync::Arc; use thiserror::Error; -use tokio::sync::{ - mpsc::{self, UnboundedReceiver, UnboundedSender}, - Mutex, +use tokio::{ + sync::{ + mpsc::{self, UnboundedReceiver, UnboundedSender}, + Mutex, + }, + time::{timeout, Duration}, }; -use tokio::time::{timeout, Duration}; +/// The response from the BLS aggregation service #[allow(unused)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct BlsAggregationServiceResponse { @@ -55,6 +56,7 @@ pub enum BlsAggregationServiceError { DuplicateTaskIndex, } +/// Contains the aggregated operators signers information #[derive(Debug, Clone)] pub struct AggregatedOperators { signers_apk_g2: BlsG2Point, @@ -63,6 +65,7 @@ pub struct AggregatedOperators { pub signers_operator_ids_set: HashMap, bool>, } +/// The BLS Aggregator Service main struct #[derive(Debug)] pub struct BlsAggregatorService where @@ -536,6 +539,7 @@ impl BlsAggregatorService #[cfg(test)] mod tests { + use super::{BlsAggregationServiceError, BlsAggregationServiceResponse, BlsAggregatorService}; use alloy_primitives::{B256, U256}; use eigen_crypto_bls::{BlsG1Point, BlsG2Point, BlsKeyPair, Signature}; use eigen_services_avsregistry::fake_avs_registry_service::FakeAvsRegistryService; @@ -546,13 +550,13 @@ mod tests { use std::collections::HashMap; use std::time::Duration; use std::vec; + const PRIVATE_KEY_1: &str = "13710126902690889134622698668747132666439281256983827313388062967626731803599"; const PRIVATE_KEY_2: &str = "14610126902690889134622698668747132666439281256983827313388062967626731803500"; const PRIVATE_KEY_3: &str = "15610126902690889134622698668747132666439281256983827313388062967626731803501"; - use super::{BlsAggregationServiceError, BlsAggregationServiceResponse, BlsAggregatorService}; fn hash(task_response: u64) -> B256 { let mut hasher = Sha256::new(); diff --git a/crates/services/bls_aggregation/src/lib.rs b/crates/services/bls_aggregation/src/lib.rs index 670d4d9f..669a6aa2 100644 --- a/crates/services/bls_aggregation/src/lib.rs +++ b/crates/services/bls_aggregation/src/lib.rs @@ -1,3 +1,7 @@ +//! BLS Agreggation Service crate. +//! +//! This crate provides a BLS Aggregation Service that can be used to aggregate BLS signatures. + #![doc( html_logo_url = "https://github.com/Layr-Labs/eigensdk-rs/assets/91280922/bd13caec-3c00-4afc-839a-b83d2890beb5", issue_tracker_base_url = "https://github.com/Layr-Labs/eigensdk-rs/issues/" diff --git a/crates/services/operatorsinfo/src/fake_operator_info.rs b/crates/services/operatorsinfo/src/fake_operator_info.rs index 41f9be75..b9f8d97a 100644 --- a/crates/services/operatorsinfo/src/fake_operator_info.rs +++ b/crates/services/operatorsinfo/src/fake_operator_info.rs @@ -5,6 +5,7 @@ use eigen_types::operator::{OperatorInfo, OperatorPubKeys}; use crate::{operator_info::OperatorInfoService, operatorsinfo_inmemory::OperatorInfoServiceError}; +/// A fake implementation of the `OperatorInfoService` trait that can be used for testing or debug purposes. pub struct FakeOperatorInfoService { pub pubkeys: OperatorInfo, } diff --git a/crates/services/operatorsinfo/src/lib.rs b/crates/services/operatorsinfo/src/lib.rs index 762a720f..1806a518 100644 --- a/crates/services/operatorsinfo/src/lib.rs +++ b/crates/services/operatorsinfo/src/lib.rs @@ -1,3 +1,5 @@ +//! This crate provides traits and methods to get operator information. + #![doc( html_logo_url = "https://github.com/Layr-Labs/eigensdk-rs/assets/91280922/bd13caec-3c00-4afc-839a-b83d2890beb5", issue_tracker_base_url = "https://github.com/Layr-Labs/eigensdk-rs/issues/" diff --git a/crates/services/operatorsinfo/src/operatorsinfo_inmemory.rs b/crates/services/operatorsinfo/src/operatorsinfo_inmemory.rs index f622e793..9d5d8366 100644 --- a/crates/services/operatorsinfo/src/operatorsinfo_inmemory.rs +++ b/crates/services/operatorsinfo/src/operatorsinfo_inmemory.rs @@ -26,6 +26,8 @@ use tokio_util::sync::CancellationToken; use crate::operator_info::OperatorInfoService; +/// Fetches operator information from the registry. +/// Loads and stores operators info (addresses and public key) in memory. #[allow(dead_code)] #[derive(Debug, Clone)] pub struct OperatorInfoServiceInMemory { @@ -35,12 +37,14 @@ pub struct OperatorInfoServiceInMemory { pub_keys: UnboundedSender, } +/// State of the operator info service. #[derive(Debug, Clone)] struct OperatorState { operator_info_data: Arc>>, operator_addr_to_id: Arc>>>, } +/// Error type for the operator info service. #[derive(Error, Debug, Clone, PartialEq, Eq)] pub enum OperatorInfoServiceError { #[error("failed to retrieve operator info")] @@ -85,6 +89,17 @@ impl OperatorInfoService for OperatorInfoServiceInMemory { } impl OperatorInfoServiceInMemory { + /// Creates a new operator info service given a logger, an avs registry chain reader and a web socket. + /// + /// # Arguments + /// + /// * `logger` - A shared logger. + /// * `avs_registry_chain_reader` - An avs registry chain reader. + /// * `web_socket` - A web socket. + /// + /// # Returns + /// + /// A new operator info service. pub async fn new( logger: SharedLogger, avs_registry_chain_reader: AvsRegistryChainReader, @@ -131,6 +146,17 @@ impl OperatorInfoServiceInMemory { } } + /// Starts the operator info service. + /// + /// # Arguments + /// + /// * `cancellation_token` - A cancellation token than can be used to stop the service. + /// * `start_block` - The start block to query for past operator registrations. + /// * `end_block` - The end block to query for past operator registrations. + /// + /// # Returns + /// + /// Ok(()) if successful, otherwise an error. pub async fn start_service( &self, cancellation_token: &CancellationToken, @@ -215,6 +241,18 @@ impl OperatorInfoServiceInMemory { Ok(()) } + /// Queries past operator registration events and fills the database by sending messages + /// to the operator info service channel. + /// This information is then stored in OperatorState`. + /// + /// # Arguments + /// + /// * `start_block` - The start block to query for past operator registrations. + /// * `end_block` - The end block to query for past operator registrations. + /// + /// # Returns + /// + /// Ok(()) if successful, otherwise an error. pub async fn query_past_registered_operator_events_and_fill_db( &self, start_block: u64, @@ -470,23 +508,20 @@ mod tests { .unwrap(); let bls_key_pair = BlsKeyPair::new(bls_key.to_string()).unwrap(); - let salt: FixedBytes<32> = FixedBytes::from([ - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, - ]); + let salt: FixedBytes<32> = FixedBytes::from([0x02; 32]); let now = SystemTime::now(); - let mut expiry: U256 = U256::from(0); + // Convert SystemTime to a Duration since the UNIX epoch - if let Ok(duration_since_epoch) = now.duration_since(UNIX_EPOCH) { - // Convert the duration to seconds - let seconds = duration_since_epoch.as_secs(); // Returns a u64 - - // Convert seconds to U256 - expiry = U256::from(seconds) + U256::from(10000); - } else { - println!("System time seems to be before the UNIX epoch."); - } + let duration_since_epoch = now + .duration_since(UNIX_EPOCH) + .inspect_err(|_| println!("System time seems to be before the UNIX epoch.")) + .unwrap(); + // Convert the duration to seconds + let seconds = duration_since_epoch.as_secs(); // Returns a u64 + + // Convert seconds to U256 + let expiry = U256::from(seconds) + U256::from(10000); + let quorum_numbers = Bytes::from_str("0x00").unwrap(); let socket = "socket"; diff --git a/crates/signer/README.md b/crates/signer/README.md index 87687eb8..c3a66cbd 100644 --- a/crates/signer/README.md +++ b/crates/signer/README.md @@ -1,6 +1,6 @@ # Eigen Signer -The `eigen-signer` crates provides utilities for creating and managing different types of signers for Ethereum transactions. +The `eigen-signer` crates provides utilities for creating and managing different types of signers for Ethereum transactions. This includes Private Key signers, keystore signers, AWS KMS-based signers and Web3Signer. -## Example \ No newline at end of file +## Example diff --git a/crates/signer/src/web3_signer.rs b/crates/signer/src/web3_signer.rs index ee82ff08..b43ea9b9 100644 --- a/crates/signer/src/web3_signer.rs +++ b/crates/signer/src/web3_signer.rs @@ -19,6 +19,7 @@ pub struct Web3Signer { pub address: Address, } +/// Parameters for the `eth_signTransaction` method #[derive(Serialize, Clone, Debug)] #[serde(rename_all = "camelCase")] struct SignTransactionParams { diff --git a/crates/types/README.md b/crates/types/README.md index baaab39a..67f02461 100644 --- a/crates/types/README.md +++ b/crates/types/README.md @@ -1,3 +1,3 @@ # Eigen types -This crate contains commonly used type definitions used across the SDK. \ No newline at end of file +This crate contains commonly used type definitions used across the SDK. diff --git a/crates/types/src/avs.rs b/crates/types/src/avs.rs index 186a5139..24a457c5 100644 --- a/crates/types/src/avs.rs +++ b/crates/types/src/avs.rs @@ -6,6 +6,7 @@ pub type TaskIndex = u32; pub type TaskResponseDigest = FixedBytes<32>; +/// Error type for signature verification #[derive(Error, Debug, Clone, PartialEq, Eq)] pub enum SignatureVerificationError { #[error("incorrect signature error")] @@ -16,6 +17,7 @@ pub enum SignatureVerificationError { OperatorNotFound, } +/// Represents a signed task response digest #[derive(Debug, Clone)] pub struct SignedTaskResponseDigest { pub task_response_digest: TaskResponseDigest, diff --git a/crates/types/src/operator.rs b/crates/types/src/operator.rs index 3208a49b..ada37dda 100644 --- a/crates/types/src/operator.rs +++ b/crates/types/src/operator.rs @@ -5,19 +5,19 @@ use ethers::{types::U64, utils::keccak256}; use num_bigint::BigUint; use std::collections::HashMap; -const MAX_NUMBER_OF_QUORUMS: usize = 192; +const MAX_NUMBER_OF_QUORUMS: u8 = 192; pub type OperatorId = FixedBytes<32>; pub fn bitmap_to_quorum_ids(quorum_bitmaps: U256) -> Vec { let bytes = quorum_bitmaps.to_be_bytes::<32>(); - let mut quorum_ids: Vec = Vec::with_capacity(MAX_NUMBER_OF_QUORUMS); + let mut quorum_ids: Vec = Vec::with_capacity(usize::from(MAX_NUMBER_OF_QUORUMS)); for i in 0..MAX_NUMBER_OF_QUORUMS { let bitmap = BigUint::from_bytes_be(&bytes); - if bitmap.bit(i.try_into().unwrap()) { - quorum_ids.push(i.try_into().unwrap()); + if bitmap.bit(u64::from(i)) { + quorum_ids.push(i); } } quorum_ids diff --git a/crates/types/src/test.rs b/crates/types/src/test.rs index 543c4cf6..54d1dc0a 100644 --- a/crates/types/src/test.rs +++ b/crates/types/src/test.rs @@ -5,6 +5,7 @@ use std::collections::HashMap; type StakeAmount = U256; +/// Test operator for testing purposes #[derive(Clone)] pub struct TestOperator { pub operator_id: B256, @@ -13,6 +14,7 @@ pub struct TestOperator { } impl TestOperator { + /// Get the BLS keypair of the operator pub fn get_bls_keypair(&self) -> &BlsKeyPair { &self.bls_keypair } diff --git a/examples/README.md b/examples/README.md index 693d9c98..04d1d482 100644 --- a/examples/README.md +++ b/examples/README.md @@ -3,22 +3,27 @@ Examples demonstrating how to interact with Eigen layer contracts using eigen-rs crates. ## OperatorsInfo + Get all the operators registered at a block range and get the operator info using an async channel. -``` + +```sh cargo run -p info-operator-service ``` ## AvsRegistry Read + Example : Getting an operator address from the operator id -``` + +```sh cargo run --example get_operator_from_id ``` ## Anvil utils(This requires a local anvil instance running using docker ) + Get EigenLayer contract addresses for local anvil testing . These are predetermined addresses that are stored in a mapping using these [scripts](https://github.com/Layr-Labs/eigensdk-rs/blob/d9b40d806b4939c64bb7d3df0f6f2a542499bd27/crates/contracts/script/DeployMockAvsRegistries.s.sol#L202). -``` + +```sh make start-anvil-chain-with-contracts-deployed make start-anvil cargo run --example get_contracts_from_registry ``` - diff --git a/examples/info-operator-service/examples/get_operator_info.rs b/examples/info-operator-service/examples/get_operator_info.rs index 6b069c27..ff56c8d0 100644 --- a/examples/info-operator-service/examples/get_operator_info.rs +++ b/examples/info-operator-service/examples/get_operator_info.rs @@ -1,9 +1,15 @@ -use alloy_primitives::{address, Bytes, FixedBytes}; -use alloy_primitives::{Address, U256}; +use alloy_primitives::{address, Address, Bytes, FixedBytes, U256}; use alloy_signer_local::PrivateKeySigner; use eigen_client_avsregistry::{reader::AvsRegistryChainReader, writer::AvsRegistryChainWriter}; -use eigen_services_operatorsinfo::operator_info::OperatorInfoService; -use eigen_services_operatorsinfo::operatorsinfo_inmemory::OperatorInfoServiceInMemory; +use eigen_client_elcontracts::{ + reader::ELChainReader, + writer::{ELChainWriter, Operator}, +}; +use eigen_crypto_bls::BlsKeyPair; +use eigen_logging::get_test_logger; +use eigen_services_operatorsinfo::{ + operator_info::OperatorInfoService, operatorsinfo_inmemory::OperatorInfoServiceInMemory, +}; use eigen_testing_utils::anvil_constants::{ get_avs_directory_address, get_delegation_manager_address, get_operator_state_retriever_address, get_registry_coordinator_address, @@ -13,17 +19,12 @@ use std::{ str::FromStr, time::{SystemTime, UNIX_EPOCH}, }; -use tokio::task; -use tokio::time::Duration; +use tokio::{task, time::Duration}; use tokio_util::sync::CancellationToken; + const ANVIL_HTTP_URL: &str = "http://localhost:8545"; const ANVIL_WS_URL: &str = "ws://localhost:8545"; -use eigen_client_elcontracts::{ - reader::ELChainReader, - writer::{ELChainWriter, Operator}, -}; -use eigen_crypto_bls::BlsKeyPair; -use eigen_logging::get_test_logger; + #[tokio::main] async fn main() { let avs_registry_chain_reader = AvsRegistryChainReader::new( diff --git a/testing/testing-utils/README.md b/testing/testing-utils/README.md index 629a3bdd..eb64d33b 100644 --- a/testing/testing-utils/README.md +++ b/testing/testing-utils/README.md @@ -1,18 +1,18 @@ # Eigen Testing Utils +The `eigen-testing-utils` crate provides a set of utilities for testing Ethereum-based contracts and services within the Eigen ecosystem. This crate is designed to simplify interactions with local Anvil instances and Holesky/Mainnet environments by providing constant addresses and helper functions to retrieve important contract addresses. -## Eigen Testing Utils -The eigen-testing-utils crate provides a set of utilities for testing Ethereum-based contracts and services within the Eigen ecosystem. This crate is designed to simplify interactions with local Anvil instances and Holesky/Mainnet environments by providing constant addresses and helper functions to retrieve important contract addresses. +## Anvil Utilities -### Anvil Utilities +### Anvil Constants -#### Anvil Constants Provides utilities for interacting with local Anvil instances. Key components include: - CONTRACTS_REGISTRY: The address of the local Anvil Contracts Registry. - ANVIL_RPC_URL: A static instance of the local Anvil RPC URL configured with required fillers. -#### Key Functions +### Key Functions + - get_service_manager_address(): Retrieves the address of the service manager contract. - get_registry_coordinator_address(): Retrieves the address of the registry coordinator contract. - get_operator_state_retriever_address(): Retrieves the address of the operator state retriever contract. @@ -21,10 +21,12 @@ Provides utilities for interacting with local Anvil instances. Key components in - get_erc20_mock_strategy(): Retrieves the address of the ERC20 mock strategy contract. - get_proxy_admin(): Retrieves the address of the proxy admin contract. -### Holesky Constants +## Holesky Constants + Contains predefined addresses for various contracts on the Holesky test network. -#### Key Addresses +### Holesky Key Addresses + - DELEGATION_MANAGER_ADDRESS: Address of the delegation manager. - STRATEGY_MANAGER_ADDRESS: Address of the strategy manager. - EIGENPOD_MANAGER_ADDRESS: Address of the Eigenpod manager. @@ -33,10 +35,12 @@ Contains predefined addresses for various contracts on the Holesky test network. - REWARDS_COORDINATOR: Address of the rewards coordinator. And various strategy base addresses. -### Mainnet Constants +## Mainnet Constants + Contains predefined addresses for various contracts on the Ethereum mainnet. -#### Key Addresses +### Mainnet Key Addresses + - DELEGATION_MANAGER_ADDRESS: Address of the delegation manager. - STRATEGY_MANAGER_ADDRESS: Address of the strategy manager. - EIGENPOD_MANAGER_ADDRESS: Address of the Eigenpod manager. @@ -46,7 +50,6 @@ Contains predefined addresses for various contracts on the Ethereum mainnet. - StrategyBase_stETH: Address of the stETH strategy base. And various other strategy base addresses. +## Example -## Example - -- [get_contracts_from_registry](https://github.com/Layr-Labs/eigensdk-rs/blob/main/examples/anvil-utils/examples/get_contracts_from_registry.rs) \ No newline at end of file +- [get_contracts_from_registry](https://github.com/Layr-Labs/eigensdk-rs/blob/main/examples/anvil-utils/examples/get_contracts_from_registry.rs)