mint-snipe/src/lib.rs
2023-03-06 19:51:16 +01:00

126 lines
4.2 KiB
Rust

pub mod helpers;
pub mod mint;
pub mod receipt;
pub mod block_scanner;
pub mod mempool;
use clap::Parser;
use std::sync::Arc;
use ethers::prelude::{k256::ecdsa::SigningKey, *};
use crate::mint::Mint;
use crate::mempool::loop_mempool;
use crate::block_scanner::loop_blocks;
use crate::helpers::{setup_signer, user_balance, wei_to_float, wei_to_gwei};
use colored::*;
#[macro_export]
macro_rules! timestamp_print {
($color: expr, $message: expr) => {
println!(
"{} {} {}",
chrono::Local::now()
.format("[%Y-%m-%d]")
.to_string()
.color($color),
chrono::Local::now()
.format("[%H:%M:%S]")
.to_string()
.color($color),
$message.color($color)
);
};
}
pub struct Config {
#[allow(dead_code)]
pub http: Arc<SignerMiddleware<Provider<Http>, Wallet<SigningKey>>>,
#[allow(dead_code)]
pub wss: Arc<Provider<Ws>>,
}
impl Config {
pub async fn new() -> Self {
let network = std::env::var("NETWORK_RPC").expect("NETWORK_RPC missing");
let provider = Provider::<Http>::try_from(network).unwrap();
let middleware = Arc::new(setup_signer(provider.clone()).await);
let ws_network = std::env::var("NETWORK_WSS").expect("NETWORK_WS missing");
let ws_provider = Provider::<Ws>::connect(ws_network).await.unwrap();
Self {
http: middleware,
wss: Arc::new(ws_provider),
}
}
}
pub async fn run() {
let config = Arc::new(Config::new().await);
let mint = Mint::parse();
mint.check_requirements(config.clone()).await.unwrap();
let config_clone = config.clone();
if mint.backrun {
let handle_blocks = tokio::spawn(async move {
loop_blocks(config_clone.http.clone()).await;
});
let owner_tx = Arc::new(
loop_mempool(
config.wss.clone(),
mint.contract)
.await
.unwrap());
let config_clone = config.clone();
let last_block_price = config.http.get_gas_price().await.unwrap();
let sniper_gas_price = last_block_price.as_u64() * 125 / 100;
let handle = tokio::spawn(async move {
let sniping_receipt = mint.sniping(
config_clone,
U256::from(sniper_gas_price),
).await.unwrap();
sniping_receipt
});
timestamp_print!(Color::Green, format!("Owner's tx detected: {:#?}", owner_tx.hash));
timestamp_print!(Color::Blue, format!("Last block gas price: {} Gwei", wei_to_gwei(last_block_price.as_u64())));
timestamp_print!(Color::Blue, format!("Setting Sniping gas price to: {} Gwei", wei_to_gwei(sniper_gas_price)));
timestamp_print!(Color::Blue, "SNIPIIIIIIIIING.".to_string());
timestamp_print!(Color::White, "Waiting for tx to be mined...".to_string());
let tx_receipt = handle.await.unwrap();
handle_blocks.abort();
let mint_receipt = receipt::Transaction::new(tx_receipt);
let owner_tx_position = config.http.get_transaction_receipt(owner_tx.hash).await.unwrap().unwrap().transaction_index;
timestamp_print!(Color::Blue, format!("Owner's tx position in block: {}", owner_tx_position));
mint_receipt.print();
} else {
mint.trigger_timestamp().unwrap();
let last_block_price = config.http.get_gas_price().await.unwrap();
let sniper_gas_price = last_block_price.as_u64() * 125 / 100;
let handle = tokio::spawn(async move {
let sniping_receipt = mint.sniping(
config_clone,
U256::from(sniper_gas_price),
).await.unwrap();
sniping_receipt
});
timestamp_print!(Color::Blue, "SNIPIIIIIIIIING.".to_string());
timestamp_print!(Color::White, "Waiting for tx to be mined...".to_string());
let tx_receipt = handle.await.unwrap();
let mint_receipt = receipt::Transaction::new(tx_receipt);
mint_receipt.print();
}
let balance = user_balance(config.http.clone()).await.unwrap();
timestamp_print!(Color::White, format!("Balance after mint: {} ETH", wei_to_float(balance.as_u64())));
}