Replace `boxed_trait` macro (#467)
* remove macro * Cleanup * refactoring * Cleanup * Minor refactor * minor cleanup * more refactoring * dedup a bit * Attempt to fix pipelinepull/482/head
parent
87909f397c
commit
36cb6296ce
@ -1,48 +0,0 @@ |
||||
macro_rules! boxed_trait { |
||||
(@finish $provider:expr, $abi:ident, $signer:ident, $($tail:tt)*) => {{ |
||||
if let Some(signer) = $signer { |
||||
// If there's a provided signer, we want to manage every aspect
|
||||
// locally
|
||||
|
||||
// First set the chain ID locally
|
||||
let provider_chain_id = $provider.get_chainid().await?; |
||||
let signer = ethers::signers::Signer::with_chain_id(signer, provider_chain_id.as_u64()); |
||||
|
||||
// Manage the nonce locally
|
||||
let address = ethers::prelude::Signer::address(&signer); |
||||
let provider = |
||||
ethers::middleware::nonce_manager::NonceManagerMiddleware::new($provider, address); |
||||
|
||||
// Manage signing locally
|
||||
let signing_provider = ethers::middleware::SignerMiddleware::new(provider, signer); |
||||
|
||||
Box::new(crate::$abi::new(signing_provider.into(), $($tail)*)) |
||||
} else { |
||||
Box::new(crate::$abi::new($provider, $($tail)*)) |
||||
} |
||||
}}; |
||||
(@ws $url:expr, $($tail:tt)*) => {{ |
||||
let ws = ethers::providers::Ws::connect($url).await?; |
||||
let provider = Arc::new(ethers::providers::Provider::new(ws)); |
||||
boxed_trait!(@finish provider, $($tail)*) |
||||
}}; |
||||
(@http $url:expr, $($tail:tt)*) => {{ |
||||
let provider: crate::RetryingProvider<ethers::providers::Http> = $url.parse()?; |
||||
let provider = Arc::new(ethers::providers::Provider::new(provider)); |
||||
boxed_trait!(@finish provider, $($tail)*) |
||||
}}; |
||||
($name:ident, $abi:ident, $trait:ident, $($n:ident:$t:ty),*) => { |
||||
#[doc = "Cast a contract locator to a live contract handle"] |
||||
pub async fn $name(conn: Connection, locator: &ContractLocator, signer: Option<Signers>, $($n:$t),*) -> eyre::Result<Box<dyn $trait>> { |
||||
let b: Box<dyn $trait> = match conn { |
||||
Connection::Http { url } => { |
||||
boxed_trait!(@http url, $abi, signer, locator, $($n),*) |
||||
} |
||||
Connection::Ws { url } => { |
||||
boxed_trait!(@ws url, $abi, signer, locator, $($n),*) |
||||
} |
||||
}; |
||||
Ok(b) |
||||
} |
||||
}; |
||||
} |
@ -0,0 +1,69 @@ |
||||
use std::sync::Arc; |
||||
|
||||
use async_trait::async_trait; |
||||
use ethers::prelude::*; |
||||
|
||||
use abacus_core::{ContractLocator, Signers}; |
||||
|
||||
use crate::Connection; |
||||
|
||||
/// A trait for dynamic trait creation with provider initialization.
|
||||
#[async_trait] |
||||
pub trait MakeableWithProvider { |
||||
/// The type that will be created.
|
||||
type Output; |
||||
|
||||
/// Construct a new instance of the associated trait using a connection config.
|
||||
async fn make_with_connection( |
||||
&self, |
||||
conn: Connection, |
||||
locator: &ContractLocator, |
||||
signer: Option<Signers>, |
||||
) -> eyre::Result<Self::Output> { |
||||
Ok(match conn { |
||||
Connection::Http { url } => { |
||||
let provider: crate::RetryingProvider<Http> = url.parse()?; |
||||
let provider = Arc::new(Provider::new(provider)); |
||||
|
||||
if let Some(signer) = signer { |
||||
let signing_provider = make_signing_provider(provider, signer).await?; |
||||
self.make_with_provider(signing_provider, locator) |
||||
} else { |
||||
self.make_with_provider(provider, locator) |
||||
} |
||||
} |
||||
Connection::Ws { url } => { |
||||
let ws = Ws::connect(url).await?; |
||||
let provider = Arc::new(Provider::new(ws)); |
||||
|
||||
if let Some(signer) = signer { |
||||
let signing_provider = make_signing_provider(provider, signer).await?; |
||||
self.make_with_provider(signing_provider, locator) |
||||
} else { |
||||
self.make_with_provider(provider, locator) |
||||
} |
||||
} |
||||
}) |
||||
} |
||||
|
||||
/// Construct a new instance of the associated trait using a provider.
|
||||
fn make_with_provider<M: Middleware + 'static>( |
||||
&self, |
||||
provider: M, |
||||
locator: &ContractLocator, |
||||
) -> Self::Output; |
||||
} |
||||
|
||||
async fn make_signing_provider<M: Middleware>( |
||||
provider: M, |
||||
signer: Signers, |
||||
) -> Result<SignerMiddleware<NonceManagerMiddleware<M>, Signers>, M::Error> { |
||||
let provider_chain_id = provider.get_chainid().await?; |
||||
let signer = ethers::signers::Signer::with_chain_id(signer, provider_chain_id.as_u64()); |
||||
|
||||
let address = ethers::prelude::Signer::address(&signer); |
||||
let provider = NonceManagerMiddleware::new(provider, address); |
||||
|
||||
let signing_provider = SignerMiddleware::new(provider, signer); |
||||
Ok(signing_provider) |
||||
} |
Loading…
Reference in new issue