pump_trades/
token_trades.rs

1use chrono::Utc;
2use hyperstack_sdk::HyperStackClient;
3use serde::{Deserialize, Serialize};
4use std::collections::VecDeque;
5use tokio::time::{sleep, Duration};
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8struct TradeInfo {
9    wallet: String,
10    direction: String,
11    amount_sol: f64,
12}
13
14#[derive(Serialize, Deserialize, Debug, Clone, Default)]
15struct PumpToken {
16    #[serde(skip_serializing_if = "Option::is_none")]
17    mint: Option<String>,
18    #[serde(skip_serializing_if = "Option::is_none")]
19    name: Option<String>,
20    #[serde(skip_serializing_if = "Option::is_none")]
21    symbol: Option<String>,
22    #[serde(skip_serializing_if = "Option::is_none")]
23    creator: Option<String>,
24    #[serde(skip_serializing_if = "Option::is_none")]
25    last_trade: Option<TradeInfo>,
26}
27
28#[tokio::main]
29async fn main() -> anyhow::Result<()> {
30    let url = std::env::args().nth(1).unwrap_or_else(|| "ws://127.0.0.1:8080".to_string());
31    let mint = std::env::var("KEY").expect("KEY env var required (token mint address)");
32    
33    let client = HyperStackClient::<PumpToken>::new(url, "PumpToken/kv")
34        .with_key(&mint);
35    
36    let store = client.connect().await?;
37    
38    println!("watching trades for token {}...\n", mint);
39    
40    let mut updates = store.subscribe();
41    let mut trade_history: VecDeque<TradeInfo> = VecDeque::with_capacity(100);
42    
43    loop {
44        tokio::select! {
45            Ok((_key, token)) = updates.recv() => {
46                if let Some(trade) = token.last_trade {
47                    trade_history.push_back(trade.clone());
48                    if trade_history.len() > 100 {
49                        trade_history.pop_front();
50                    }
51                    
52                    println!("[{}] {} | {}... | {:.4} SOL (total: {} trades)", 
53                        Utc::now().format("%H:%M:%S"),
54                        trade.direction,
55                        &trade.wallet[..8],
56                        trade.amount_sol,
57                        trade_history.len());
58                }
59            }
60            _ = sleep(Duration::from_secs(60)) => {
61                println!("No trades for 60s...");
62            }
63        }
64    }
65}