use dexther_lib::blockchain::get_tokens_for_pairs;
use dexther_lib::types::{PairInfo, TokenInfo};
use once_cell::sync::Lazy;
use reqwest::Client;
use std::{env, result};
#[cfg(test)]
mod tests {
use dexther_lib::{blockchain::get_tokens_for_pairs_with_retry, types::PairCreated};
use dotenv::dotenv;
use tokio::test;
use super::*;
static NOT_COIN: Lazy<Vec<(PairInfo, TokenInfo, TokenInfo)>> = Lazy::new(|| {
vec![(
PairInfo {
address: "0x00cefd3cfabd8c31e2aeaec410098f7d5cdae355".to_string(),
name: "Uniswap V2".to_string(),
symbol: "UNI-V2".to_string(),
v3: None,
factory: "0x7a250d5630b4cf539739df2c5dacb4c659f2488d"
.to_lowercase()
.to_string(),
tickSpacing: None,
fee: None,
},
TokenInfo {
address: "0x7d398883082c689961aba7b8b57a17588a943b7a".to_string(),
name: "NOTCOIN".to_string(),
symbol: "CAT".to_string(),
decimals: "18".to_string(),
owner: "None".to_string(),
total_supply: "100000000000000000000000000".to_string(),
},
TokenInfo {
address: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2".to_string(),
name: "Wrapped Ether".to_string(),
symbol: "WETH".to_string(),
decimals: "18".to_string(),
owner: "None".to_string(),
total_supply: "2841754056935783958002973".to_string(),
},
)]
});
static WEEB21_COIN: Lazy<Vec<(PairInfo, TokenInfo, TokenInfo)>> = Lazy::new(|| {
vec![(
PairInfo {
address: "0x9d7c6b7b0647c963cc456f597c667d4d095b25ee"
.to_lowercase()
.to_string(),
name: "Uniswap V2".to_string(),
symbol: "UNI-V2".to_string(),
v3: None,
factory: "0x7a250d5630b4cf539739df2c5dacb4c659f2488d"
.to_lowercase()
.to_string(),
tickSpacing: None,
fee: None,
},
TokenInfo {
address: "0x0ec3f4f6277691A126AC37c1008E74fB518555E7"
.to_lowercase()
.to_string(),
name: "weeaboo".to_string(),
symbol: "WEEB".to_string(),
decimals: "18".to_string(),
owner: "None".to_string(),
total_supply: "69420000000000000000000000000".to_string(),
},
TokenInfo {
address: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
.to_lowercase()
.to_string(),
name: "Wrapped Ether".to_string(),
symbol: "WETH".to_string(),
decimals: "18".to_string(),
owner: "None".to_string(),
total_supply: "2841754056935783958002973".to_string(),
},
)]
});
static YODA_COIN: Lazy<Vec<(PairInfo, TokenInfo, TokenInfo)>> = Lazy::new(|| {
vec![(
PairInfo {
address: "0x00EF2471F89305a824c39F8CdAbFAb4D1FB963B7"
.to_lowercase()
.to_string(),
name: "Uniswap V2".to_string(),
symbol: "UNI-V2".to_string(),
v3: None,
factory: "0x7a250d5630b4cf539739df2c5dacb4c659f2488d"
.to_lowercase()
.to_string(),
tickSpacing: None,
fee: None,
},
TokenInfo {
address: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
.to_lowercase()
.to_string(),
name: "Wrapped Ether".to_string(),
symbol: "WETH".to_string(),
decimals: "18".to_string(),
owner: "None".to_string(),
total_supply: "2743795442936351426188416".to_string(),
},
TokenInfo {
address: "0xE0A236C5e26015f55c1E2522dAa24D415D62A76f"
.to_lowercase()
.to_string(),
name: "Yoda".to_string(),
symbol: "YODA".to_string(),
decimals: "18".to_string(),
owner: "0x0000000000000000000000000000000000000000".to_string(),
total_supply: "1000000000000000000000000000".to_string(),
},
)]
});
static BULLTERRIER_COIN: Lazy<Vec<(PairInfo, TokenInfo, TokenInfo)>> = Lazy::new(|| {
vec![(
PairInfo {
address: "0xbEd04CBaf2ad234e216E7fc2ba480142527412e5"
.to_lowercase()
.to_string(),
name: "None".to_string(),
symbol: "None".to_string(),
v3: None,
factory: "0x7a250d5630b4cf539739df2c5dacb4c659f2488d"
.to_lowercase()
.to_string(),
tickSpacing: None,
fee: None,
},
TokenInfo {
address: "0xa07b6ffd14f4a3d9d7d16fd934c200bd3c1987ec"
.to_lowercase()
.to_string(),
name: "Bullterrier (ETH)".to_string(),
symbol: "BETH".to_string(),
decimals: "18".to_string(),
owner: "0xf4b9A036f97679142a1A0782F964b8d2Bf424aaA"
.to_lowercase()
.to_string(),
total_supply: "420420420000000000000000000".to_string(),
},
TokenInfo {
address: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
.to_lowercase()
.to_string(),
name: "Wrapped Ether".to_string(),
symbol: "WETH".to_string(),
decimals: "18".to_string(),
owner: "None".to_string(),
total_supply: "2841754056935783958002973".to_string(),
},
)]
});
static SINTRA_AI_COIN: Lazy<Vec<(PairInfo, TokenInfo, TokenInfo)>> = Lazy::new(|| {
vec![(
PairInfo {
address: "0x69B1E8758a9B4cda0045D0129f6f7827e6386b6b"
.to_lowercase()
.to_string(),
name: "Uniswap V2".to_string(),
symbol: "UNI-V2".to_string(),
v3: None,
factory: "0x7a250d5630b4cf539739df2c5dacb4c659f2488d"
.to_lowercase()
.to_string(),
tickSpacing: None,
fee: None,
},
TokenInfo {
address: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
.to_lowercase()
.to_string(),
name: "Wrapped Ether".to_string(),
symbol: "WETH".to_string(),
decimals: "18".to_string(),
owner: "None".to_string(),
total_supply: "2841754056935783958002973".to_string(),
},
TokenInfo {
address: "0xFC335455664a8dc8A2E5E9Ab1BfC0D0bfCb1A00f"
.to_lowercase()
.to_string(),
name: "Sintra AI".to_string(),
symbol: "SNAI".to_string(),
decimals: "18".to_string(),
owner: "0x089655F87FdB2C5ECaF03d53aEa6F73652b5c3E3"
.to_lowercase()
.to_string(),
total_supply: "100000000000000000000000000 ".to_string(),
},
)]
});
static KABALA_COIN: Lazy<Vec<(PairInfo, TokenInfo, TokenInfo)>> = Lazy::new(|| {
vec![(
PairInfo {
address: "0x1531b5d71abafb38e888cf7c4278377bcf25aeff"
.to_lowercase()
.to_string(),
name: "None".to_string(),
symbol: "None".to_string(),
v3: None,
factory: "0x7a250d5630b4cf539739df2c5dacb4c659f2488d"
.to_lowercase()
.to_string(),
tickSpacing: None,
fee: None,
},
TokenInfo {
address: "0xa07b6ffd14f4a3d9d7d16fd934c200bd3c1987ec"
.to_lowercase()
.to_string(),
name: "Bullterrier (ETH)".to_string(),
symbol: "BETH".to_string(),
decimals: "18".to_string(),
owner: "0xf4b9A036f97679142a1A0782F964b8d2Bf424aaA"
.to_lowercase()
.to_string(),
total_supply: "420420420000000000000000000".to_string(),
},
TokenInfo {
address: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
.to_lowercase()
.to_string(),
name: "Wrapped Ether".to_string(),
symbol: "WETH".to_string(),
decimals: "18".to_string(),
owner: "None".to_string(),
total_supply: "2841754056935783958002973".to_string(),
},
)]
});
static V3_PAIR: Lazy<Vec<(PairInfo, TokenInfo, TokenInfo)>> = Lazy::new(|| {
vec![(
PairInfo {
address: "0x58f16891db63708ed71810060fd5b85d6cfcfa76".to_lowercase().to_string(),
name: "Uniswap V3".to_string(),
symbol: "UNI-V3".to_string(),
v3: Some(true),
factory: "0x1f98431c8ad98523631ae4a59f267346ea31f984".to_lowercase().to_string(),
tickSpacing: Some(60),
fee: Some(3000),
},
TokenInfo {
address: "0x0de50324b6960b15a5ced3d076ae314ac174da2e".to_lowercase().to_string(),
name: "Home Krypto Token".to_string(), symbol: "HKT".to_string(), decimals: "18".to_string(), owner: "None".to_string(), total_supply: "1000000000000000000000000000".to_string(), },
TokenInfo {
address: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2".to_lowercase().to_string(),
name: "Wrapped Ether".to_string(),
symbol: "WETH".to_string(),
decimals: "18".to_string(),
owner: "None".to_string(),
total_supply: "2841754056935783958002973".to_string(),
},
)]
});
fn get_rpc_provider_url() -> String {
dotenv().ok();
env::var("RPC_PROVIDER_URL").expect("RPC_PROVIDER_URL must be set")
}
async fn verify_tokens(
rpc_provider_url: &str,
pairs: Vec<(PairCreated, [String; 2])>,
expected_results: &[&Lazy<Vec<(PairInfo, TokenInfo, TokenInfo)>>],
) {
println!("Hello");
let results = get_tokens_for_pairs_with_retry(rpc_provider_url, pairs).await.unwrap();
println!("Results {:?}", results);
let combined_expected: Vec<_> = expected_results.iter().flat_map(|x| x.iter()).collect();
for (
(pair_info_expected, token_info0_expected, token_info1_expected),
(pair_info_actual, token_info0_actual, token_info1_actual),
) in combined_expected.iter().zip(results.iter())
{
assert_eq!(pair_info_expected, pair_info_actual);
assert_eq!(
token_info1_expected.address.to_lowercase(),
token_info1_actual.address.to_lowercase()
);
assert_eq!(token_info1_expected.name, token_info1_actual.name);
assert_eq!(token_info1_expected.symbol, token_info1_actual.symbol);
assert_eq!(token_info1_expected.decimals, token_info1_actual.decimals);
assert_eq!(token_info1_expected.owner, token_info1_actual.owner);
assert_eq!(
token_info0_expected.address.to_lowercase(),
token_info0_actual.address.to_lowercase()
);
assert_eq!(token_info0_expected.name, token_info0_actual.name);
assert_eq!(token_info0_expected.symbol, token_info0_actual.symbol);
assert_eq!(token_info0_expected.decimals, token_info0_actual.decimals);
assert_eq!(token_info0_expected.owner, token_info0_actual.owner);
}
}
#[test]
async fn test_not_coin() {
let RPC_PROVIDER_URL = get_rpc_provider_url();
let mut pairs = vec![];
pairs.push((
PairCreated {
token0: "0x7d398883082c689961aba7b8b57a17588a943b7a".to_string(),
token1: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2".to_string(),
pair: "0x00cefd3cfabd8c31e2aeaec410098f7d5cdae355".to_string(),
block_number: "0".to_string(),
v3: None,
factory: "0x7a250d5630b4cf539739df2c5dacb4c659f2488d".to_string(),
tickSpacing: None,
fee: None,
transaction_hash: "".to_string(),
transaction_index: "".to_string(),
deployer: "".to_string(),
timestamp: "".to_string(),
},
[
"0x7d398883082c689961aba7b8b57a17588a943b7a".to_string(),
"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2".to_string(),
],
));
verify_tokens(RPC_PROVIDER_URL.as_str(), pairs, &[&NOT_COIN]).await;
}
#[test]
async fn test_not_coin_reverse() {
let RPC_PROVIDER_URL = get_rpc_provider_url();
let mut pairs = vec![];
pairs.push((
PairCreated {
pair: "0x00cefd3cfabd8c31e2aeaec410098f7d5cdae355".to_string(),
token0: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2".to_string(),
token1: "0x7d398883082c689961aba7b8b57a17588a943b7a".to_string(),
block_number: "0".to_string(),
v3: None,
factory: "0x7a250d5630b4cf539739df2c5dacb4c659f2488d".to_string(),
tickSpacing: None,
fee: None,
transaction_hash: "".to_string(),
transaction_index: "".to_string(),
deployer: "".to_string(),
timestamp: "".to_string(),
},
[
"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2".to_string(),
"0x7d398883082c689961aba7b8b57a17588a943b7a".to_string(),
],
));
let results: Vec<(PairInfo, TokenInfo, TokenInfo)> =
get_tokens_for_pairs(RPC_PROVIDER_URL.as_str(), pairs)
.await
.unwrap();
for (
(pair_info_expected, token_info1_expected, token_info0_expected),
(pair_info_actual, token_info0_actual, token_info1_actual),
) in NOT_COIN.iter().zip(results.iter())
{
assert_eq!(token_info0_expected.address, token_info0_actual.address);
assert_eq!(token_info0_expected.name, token_info0_actual.name);
assert_eq!(token_info0_expected.symbol, token_info0_actual.symbol);
assert_eq!(token_info0_expected.decimals, token_info0_actual.decimals);
assert_eq!(token_info0_expected.owner, token_info0_actual.owner);
assert_eq!(token_info1_expected.address, token_info1_actual.address);
assert_eq!(token_info1_expected.name, token_info1_actual.name);
assert_eq!(token_info1_expected.symbol, token_info1_actual.symbol);
assert_eq!(token_info1_expected.decimals, token_info1_actual.decimals);
assert_eq!(token_info1_expected.owner, token_info1_actual.owner);
}
}
#[test]
async fn test_weeb_coin() {
let RPC_PROVIDER_URL = get_rpc_provider_url();
let mut pairs = vec![];
pairs.push((
PairCreated {
pair: "0x9d7c6b7b0647c963cc456f597c667d4d095b25ee".to_string(),
token0: "0x0ec3f4f6277691A126AC37c1008E74fB518555E7".to_string(),
token1: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2".to_string(),
block_number: "0".to_string(),
v3: None,
factory: "0x7a250d5630b4cf539739df2c5dacb4c659f2488d".to_string(),
tickSpacing: None,
fee: None,
transaction_hash: "".to_string(),
transaction_index: "".to_string(),
deployer: "".to_string(),
timestamp: "".to_string(),
},
[
"0x0ec3f4f6277691A126AC37c1008E74fB518555E7".to_string(),
"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2".to_string(),
],
));
verify_tokens(RPC_PROVIDER_URL.as_str(), pairs, &[&WEEB21_COIN]).await;
}
#[test]
async fn test_yoda_coin() {
let RPC_PROVIDER_URL = get_rpc_provider_url();
let mut pairs = vec![];
pairs.push((
PairCreated {
pair: "0x00ef2471f89305a824c39f8cdabfab4d1fb963b7".to_string(),
token0: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2".to_string(),
token1: "0xE0A236C5e26015f55c1E2522dAa24D415D62A76f".to_string(),
block_number: "0".to_string(),
v3: None,
factory: "0x7a250d5630b4cf539739df2c5dacb4c659f2488d".to_string(),
tickSpacing: None,
fee: None,
transaction_hash: "".to_string(),
transaction_index: "".to_string(),
deployer: "".to_string(),
timestamp: "".to_string(),
},
[
"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2".to_string(),
"0xE0A236C5e26015f55c1E2522dAa24D415D62A76f".to_string(),
],
));
verify_tokens(RPC_PROVIDER_URL.as_str(), pairs, &[&YODA_COIN]).await;
}
#[test]
async fn test_owner_coin() {
let RPC_PROVIDER_URL = get_rpc_provider_url();
let mut pairs = vec![];
pairs.push((
PairCreated {
pair: "0xbEd04CBaf2ad234e216E7fc2ba480142527412e5".to_string(),
token0: "0xa07b6ffd14f4a3d9d7d16fd934c200bd3c1987ec".to_string(),
token1: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2".to_string(),
block_number: "0".to_string(),
v3: None,
factory: "0x7a250d5630b4cf539739df2c5dacb4c659f2488d".to_string(),
tickSpacing: None,
fee: None,
transaction_hash: "".to_string(),
transaction_index: "".to_string(),
deployer: "".to_string(),
timestamp: "".to_string(),
},
[
"0xa07b6ffd14f4a3d9d7d16fd934c200bd3c1987ec".to_string(),
"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2".to_string(),
],
));
verify_tokens(RPC_PROVIDER_URL.as_str(), pairs, &[&BULLTERRIER_COIN]).await;
}
#[test]
async fn test_sintra_ai() {
let RPC_PROVIDER_URL = get_rpc_provider_url();
let mut pairs = vec![];
pairs.push((
PairCreated {
pair: "0x69b1e8758a9b4cda0045d0129f6f7827e6386b6b".to_string(),
token1: "0xfc335455664a8dc8a2e5e9ab1bfc0d0bfcb1a00f".to_string(),
token0: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2".to_string(),
block_number: "0".to_string(),
v3: None,
factory: "0x7a250d5630b4cf539739df2c5dacb4c659f2488d".to_string(),
tickSpacing: None,
fee: None,
transaction_hash: "".to_string(),
transaction_index: "".to_string(),
deployer: "".to_string(),
timestamp: "".to_string(),
},
[
"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2".to_string(),
"0xfc335455664a8dc8a2e5e9ab1bfc0d0bfcb1a00f".to_string(),
],
));
verify_tokens(RPC_PROVIDER_URL.as_str(), pairs, &[&SINTRA_AI_COIN]).await;
}
#[test]
async fn test_combined_coins() {
let rpc_provider_url = get_rpc_provider_url();
let pairs = vec![
(
PairCreated {
pair: "0x9d7c6b7b0647c963cc456f597c667d4d095b25ee".to_string(),
token0: "0x0ec3f4f6277691A126AC37c1008E74fB518555E7".to_string(),
token1: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2".to_string(),
block_number: "0".to_string(),
v3: None,
factory: "0x7a250d5630b4cf539739df2c5dacb4c659f2488d".to_string(),
tickSpacing: None,
fee: None,
transaction_hash: "".to_string(),
transaction_index: "".to_string(),
deployer: "".to_string(),
timestamp: "".to_string(),
},
[
"0x0ec3f4f6277691A126AC37c1008E74fB518555E7".to_string(),
"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2".to_string(),
],
),
(
PairCreated {
pair: "0x00cefd3cfabd8c31e2aeaec410098f7d5cdae355".to_string(),
token0: "0x7d398883082c689961aba7b8b57a17588a943b7a".to_string(),
token1: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2".to_string(),
block_number: "0".to_string(),
v3: None,
factory: "0x7a250d5630b4cf539739df2c5dacb4c659f2488d".to_string(),
tickSpacing: None,
fee: None,
transaction_hash: "".to_string(),
transaction_index: "".to_string(),
deployer: "".to_string(),
timestamp: "".to_string(),
},
[
"0x7d398883082c689961aba7b8b57a17588a943b7a".to_string(),
"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2".to_string(),
],
),
];
verify_tokens(&rpc_provider_url, pairs, &[&WEEB21_COIN, &NOT_COIN]).await;
}
#[test]
async fn test_combined_2() {
let rpc_provider_url = get_rpc_provider_url();
let pairs = vec![
(
PairCreated {
pair: "0x9d7c6b7b0647c963cc456f597c667d4d095b25ee".to_string(),
token0: "0x0ec3f4f6277691A126AC37c1008E74fB518555E7".to_string(),
token1: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2".to_string(),
block_number: "0".to_string(),
v3: None,
factory: "0x7a250d5630b4cf539739df2c5dacb4c659f2488d".to_string(),
tickSpacing: None,
fee: None,
transaction_hash: "".to_string(),
transaction_index: "".to_string(),
deployer: "".to_string(),
timestamp: "".to_string(),
},
[
"0x0ec3f4f6277691A126AC37c1008E74fB518555E7".to_string(),
"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2".to_string(),
],
),
(
PairCreated {
pair: "0x00cefd3cfabd8c31e2aeaec410098f7d5cdae355".to_string(),
token0: "0x7d398883082c689961aba7b8b57a17588a943b7a".to_string(),
token1: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2".to_string(),
block_number: "0".to_string(),
v3: None,
factory: "0x7a250d5630b4cf539739df2c5dacb4c659f2488d".to_string(),
tickSpacing: None,
fee: None,
transaction_hash: "".to_string(),
transaction_index: "".to_string(),
deployer: "".to_string(),
timestamp: "".to_string(),
},
[
"0x7d398883082c689961aba7b8b57a17588a943b7a".to_string(),
"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2".to_string(),
],
),
];
verify_tokens(&rpc_provider_url, pairs, &[&WEEB21_COIN, &NOT_COIN]).await;
}
#[test]
async fn test_v3_pair() {
let RPC_PROVIDER_URL = get_rpc_provider_url();
let mut pairs = vec![];
pairs.push((
PairCreated {
pair: "0x58f16891db63708ed71810060fd5b85d6cfcfa76".to_string(),
token0: "0x0de50324b6960b15a5ced3d076ae314ac174da2e".to_string(),
token1: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2".to_string(),
block_number: "22431676".to_string(),
v3: Some(true),
factory: "0x1f98431c8ad98523631ae4a59f267346ea31f984".to_string(),
tickSpacing: Some(60),
fee: Some(3000),
transaction_hash: "0x73e57adff50245633f01f9c3098afc84ea39d6ba8332562b1c1290b4bf2dacb9".to_string(),
transaction_index: "99".to_string(),
deployer: "0x2b0e01debad934b42c31cdbe9b69e14502896cd9".to_string(),
timestamp: "1746619871".to_string(),
},
[
"0x0de50324b6960b15a5ced3d076ae314ac174da2e".to_string(),
"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2".to_string(),
],
));
verify_tokens(RPC_PROVIDER_URL.as_str(), pairs, &[&V3_PAIR]).await;
}
}