waterpump-evm-pool-sdk 0.1.0

EVM pool SDK — viewers, infusers, harvesters, swappers for Uniswap V3/V4, PancakeSwap, Slipstream, Shadow, Algebra
Documentation
mod multi_pool_viewer;
mod pool_viewer;
mod two_pool_viewer;
pub mod utils;

pub use multi_pool_viewer::{V3MultiPoolViewer, V3MultiPoolViewerBuilder};
pub use pool_viewer::V3PoolViewer;
pub use two_pool_viewer::V3TwoPoolViewer;

// Re-export V3PoolKey for convenience
pub use crate::types::v3_pool_key::V3PoolKey;

#[cfg(test)]
mod tests {
    use std::str::FromStr;

    use alloy::{
        network::Ethereum,
        primitives::Address,
        providers::{DynProvider, ProviderBuilder},
    };
    use uniswap_sdk_core::{
        prelude::{Currency, Token},
        token,
    };
    use uniswap_v3_sdk::prelude::FeeAmount;

    use super::*;
    use crate::traits::pool_viewer::{MultiPoolViewer, PoolViewer};

    pub struct TestConfig {
        pub rpc_url: String,
        pub token_a: Currency,
        pub token_b: Currency,
        pub fee: FeeAmount,
        pub pool_address: Address,
    }

    fn setup_test_config() -> TestConfig {
        let chain_id = 130;
        let token_a: Currency = token!(
            chain_id,
            &format!(
                "{:x}",
                Address::from_str("0x078D782b760474a361dDA0AF3839290b0EF57AD6").unwrap()
            ),
            6,
            "USD",
            "USD"
        )
        .into();
        let token_b: Currency = token!(
            chain_id,
            &format!(
                "{:x}",
                Address::from_str("0x4200000000000000000000000000000000000006").unwrap()
            ),
            18,
            "WETH",
            "Wrapped Ether"
        )
        .into();
        let pool_address = Address::from_str("0x0000000000000000000000000000000000000000")
            .expect("Invalid test pool address");
        TestConfig {
            rpc_url: std::env::var("FORK_RPC_URL")
                .expect("FORK_RPC_URL env var required for fork tests"),
            token_a,
            token_b,
            fee: FeeAmount::MEDIUM,
            pool_address,
        }
    }

    #[tokio::test]
    #[ignore = "requires FORK_RPC_URL"]
    async fn test_v3_pool_viewer() {
        let config = setup_test_config();
        let provider = ProviderBuilder::new()
            .network::<Ethereum>()
            .connect_http(config.rpc_url.parse().unwrap());
        let dyn_provider = DynProvider::new(provider);
        let viewer = V3PoolViewer::new(
            config.token_a,
            config.token_b,
            config.fee,
            config.pool_address,
            dyn_provider,
        )
        .unwrap();
        let price = viewer.currency0_price(None).await.unwrap().to_significant(8, None).unwrap();
        println!("Price: {:?}", price);
        let price1 = viewer.currency1_price(None).await.unwrap().to_significant(8, None).unwrap();
        println!("Price1: {:?}", price1);
    }

    #[tokio::test]
    #[ignore = "requires FORK_RPC_URL"]
    async fn test_v3_multi_pool_viewer() {
        let config = setup_test_config();
        let provider = ProviderBuilder::new()
            .network::<Ethereum>()
            .connect_http(config.rpc_url.parse().unwrap());
        let dyn_provider = DynProvider::new(provider);
        let pool = V3PoolKey { token_a: config.token_a, token_b: config.token_b, fee: config.fee };

        let viewer =
            V3MultiPoolViewer::new(vec![(pool, config.pool_address)], dyn_provider).unwrap();
        let prices = viewer.currency0_prices(None).await.unwrap();
        for price in prices {
            let price_str = price.to_significant(8, None).unwrap();
            println!("Price: {:?}", price_str);
        }
        let prices1 = viewer.currency1_prices(None).await.unwrap();
        for price in prices1 {
            let price_str = price.to_significant(8, None).unwrap();
            println!("Price1: {:?}", price_str);
        }
    }
}