eigenlayer_contract_deployer/
helpers.rs1use std::str::FromStr;
2
3use crate::bindings::{EmptyContract, ProxyAdmin, TransparentUpgradeableProxy};
4use alloy::{
5 network::EthereumWallet,
6 signers::local::PrivateKeySigner,
7 transports::{TransportErrorKind, http::reqwest::Url},
8};
9use alloy_primitives::{Address, Bytes, FixedBytes};
10use alloy_provider::{
11 PendingTransactionBuilder, PendingTransactionError, ProviderBuilder, RootProvider,
12};
13use color_eyre::eyre::eyre;
14use tracing::error;
15
16pub async fn deploy_empty_proxy(
21 wallet: &RootProvider,
22 proxy_admin: Address,
23) -> color_eyre::eyre::Result<Address> {
24 let data = Bytes::new();
25
26 let empty_contract = EmptyContract::deploy(wallet).await?;
27 let &empty_contract_addr = empty_contract.address();
28
29 let proxy =
30 TransparentUpgradeableProxy::deploy(wallet, empty_contract_addr, proxy_admin, data).await?;
31
32 Ok(*proxy.address())
33}
34
35pub async fn upgrade_proxy(
40 wallet: &RootProvider,
41 proxy_admin_addr: Address,
42 proxy_addr: Address,
43 implementation_addr: Address,
44 data: Bytes,
45) -> color_eyre::eyre::Result<()> {
46 let proxy_admin = ProxyAdmin::new(proxy_admin_addr, wallet.clone());
47
48 let receipt = if data.is_empty() {
49 let call = proxy_admin.upgrade(proxy_addr, implementation_addr);
50 get_receipt(call).await?
51 } else {
52 let call = proxy_admin.upgradeAndCall(proxy_addr, implementation_addr, data);
53 get_receipt(call).await?
54 };
55
56 if !receipt.status() {
57 return Err(eyre!("Failed to upgrade proxy"));
58 }
59
60 Ok(())
61}
62
63use alloy_contract::{CallBuilder, CallDecoder};
66use alloy_provider::Provider;
67use alloy_provider::network::Ethereum;
68use alloy_rpc_types_eth::TransactionReceipt;
69#[allow(clippy::missing_errors_doc)]
80pub async fn get_receipt<P, D>(
81 call: CallBuilder<P, D, Ethereum>,
82) -> Result<TransactionReceipt, color_eyre::eyre::Error>
83where
84 P: Provider<Ethereum>,
85 D: CallDecoder,
86{
87 let pending_tx = match call.send().await {
88 Ok(tx) => tx,
89 Err(e) => {
90 error!("Failed to send transaction: {:?}", e);
91 return Err(e.into());
92 }
93 };
94
95 let receipt = match pending_tx.get_receipt().await {
96 Ok(receipt) => receipt,
97 Err(e) => {
98 error!("Failed to get transaction receipt: {:?}", e);
99 return Err(e.into());
100 }
101 };
102
103 Ok(receipt)
104}
105
106#[allow(clippy::type_complexity)]
107#[must_use]
115pub fn get_provider_from_signer(key: &str, rpc_url: &str) -> RootProvider {
116 let signer = PrivateKeySigner::from_str(key).expect("wrong key ");
117 let wallet = EthereumWallet::from(signer);
118 let url = Url::parse(rpc_url).expect("Wrong rpc url");
119 ProviderBuilder::new()
120 .wallet(wallet.clone())
121 .connect_http(url)
122 .root()
123 .clone()
124}
125
126#[allow(clippy::missing_errors_doc)]
137pub async fn wait_transaction(
138 rpc_url: &str,
139 tx_hash: FixedBytes<32>,
140) -> Result<TransactionReceipt, PendingTransactionError> {
141 let url = Url::parse(rpc_url).map_err(|_| TransportErrorKind::custom_str("Invalid RPC URL"))?;
142 let root_provider = ProviderBuilder::new()
143 .disable_recommended_fillers()
144 .connect_http(url);
145 let pending_tx = PendingTransactionBuilder::new(root_provider, tx_hash);
146 pending_tx.get_receipt().await
147}