use crate::users::{TEST_SIGNERS, TEST_USERS};
use alloy::{
network::{Ethereum, EthereumWallet},
primitives::{Address, U256},
providers::{Provider, ProviderBuilder},
signers::local::PrivateKeySigner,
transports::TransportError,
};
use signet_constants::parmigiana::{HOST_CHAIN_ID, RU_CHAIN_ID};
pub const HOST_RPC_URL: &str = "https://host-rpc.parmigiana.signet.sh";
pub const RU_RPC_URL: &str = "https://rpc.parmigiana.signet.sh";
pub const RU_WS_URL: &str = "wss://rpc.parmigiana.signet.sh";
#[derive(Debug, Clone, Copy, Default)]
pub enum RollupTransport {
#[default]
Https,
Wss,
}
impl RollupTransport {
pub const fn url(&self) -> &'static str {
match self {
Self::Https => RU_RPC_URL,
Self::Wss => RU_WS_URL,
}
}
}
#[derive(Debug, thiserror::Error)]
pub enum ParmTestError {
#[error("failed to connect to host RPC: {0}")]
HostConnect(TransportError),
#[error("failed to connect to rollup RPC: {0}")]
RollupConnect(TransportError),
#[error("failed to fetch host chain ID: {0}")]
HostChainId(TransportError),
#[error("failed to fetch rollup chain ID: {0}")]
RollupChainId(TransportError),
#[error("host chain ID mismatch: expected {expected}, got {actual}")]
HostChainIdMismatch {
expected: u64,
actual: u64,
},
#[error("rollup chain ID mismatch: expected {expected}, got {actual}")]
RollupChainIdMismatch {
expected: u64,
actual: u64,
},
#[error("failed to fetch host balance: {0}")]
HostBalance(TransportError),
#[error("failed to fetch rollup balance: {0}")]
RollupBalance(TransportError),
}
pub struct ParmigianaContext<H, R>
where
H: Provider<Ethereum>,
R: Provider<Ethereum>,
{
pub host_provider: H,
pub ru_provider: R,
pub signers: &'static [PrivateKeySigner; 10],
pub users: &'static [Address; 10],
}
impl<H, R> ParmigianaContext<H, R>
where
H: Provider<Ethereum>,
R: Provider<Ethereum>,
{
pub fn primary_signer(&self) -> &PrivateKeySigner {
&self.signers[0]
}
pub fn primary_user(&self) -> Address {
self.users[0]
}
pub fn wallet(&self, index: usize) -> EthereumWallet {
EthereumWallet::from(self.signers[index].clone())
}
pub async fn host_balance(&self, index: usize) -> Result<U256, ParmTestError> {
self.host_provider.get_balance(self.users[index]).await.map_err(ParmTestError::HostBalance)
}
pub async fn ru_balance(&self, index: usize) -> Result<U256, ParmTestError> {
self.ru_provider.get_balance(self.users[index]).await.map_err(ParmTestError::RollupBalance)
}
}
pub async fn new_parmigiana_context(
ru_transport: RollupTransport,
) -> Result<ParmigianaContext<impl Provider<Ethereum>, impl Provider<Ethereum>>, ParmTestError> {
let host_provider =
ProviderBuilder::new().connect(HOST_RPC_URL).await.map_err(ParmTestError::HostConnect)?;
let ru_provider = ProviderBuilder::new()
.connect(ru_transport.url())
.await
.map_err(ParmTestError::RollupConnect)?;
let host_chain = host_provider.get_chain_id().await.map_err(ParmTestError::HostChainId)?;
if host_chain != HOST_CHAIN_ID {
return Err(ParmTestError::HostChainIdMismatch {
expected: HOST_CHAIN_ID,
actual: host_chain,
});
}
let ru_chain = ru_provider.get_chain_id().await.map_err(ParmTestError::RollupChainId)?;
if ru_chain != RU_CHAIN_ID {
return Err(ParmTestError::RollupChainIdMismatch {
expected: RU_CHAIN_ID,
actual: ru_chain,
});
}
Ok(ParmigianaContext { host_provider, ru_provider, signers: &TEST_SIGNERS, users: &TEST_USERS })
}