1use chrono::Utc;
2use hyperstack_sdk::HyperStackClient;
3use serde::{Deserialize, Serialize};
4use tokio::time::{sleep, Duration};
5
6#[derive(Serialize, Deserialize, Debug, Clone, Default)]
7struct PumpToken {
8 #[serde(skip_serializing_if = "Option::is_none")]
9 mint: Option<String>,
10 #[serde(skip_serializing_if = "Option::is_none")]
11 name: Option<String>,
12 #[serde(skip_serializing_if = "Option::is_none")]
13 symbol: Option<String>,
14 #[serde(skip_serializing_if = "Option::is_none")]
15 creator: Option<String>,
16 #[serde(skip_serializing_if = "Option::is_none")]
17 virtual_sol_reserves: Option<u64>,
18}
19
20#[tokio::main]
21async fn main() -> anyhow::Result<()> {
22 let url = std::env::args()
23 .nth(1)
24 .unwrap_or_else(|| "ws://127.0.0.1:8080".to_string());
25
26 let client = HyperStackClient::<PumpToken>::new(url, "PumpToken/list");
27
28 let store = client.connect().await?;
29
30 println!("watching for new pump.fun token launches...\n");
31
32 let mut updates = store.subscribe();
33
34 loop {
35 tokio::select! {
36 Ok((mint, token)) = updates.recv() => {
37 if token.name.is_some() || token.symbol.is_some() {
38 println!("\n[{}] new token launch", Utc::now().format("%Y-%m-%d %H:%M:%S UTC"));
39 println!("mint: {}", mint);
40 if let Some(name) = &token.name {
41 println!("name: {}", name);
42 }
43 if let Some(symbol) = &token.symbol {
44 println!("symbol: {}", symbol);
45 }
46 if let Some(creator) = &token.creator {
47 println!("creator: {}", creator);
48 }
49 if let Some(sol) = token.virtual_sol_reserves {
50 println!("initial liquidity: {:.4} SOL", sol as f64 / 1e9);
51 }
52 }
53 }
54 _ = sleep(Duration::from_secs(60)) => {
55 println!("No new launches for 60s...");
56 }
57 }
58 }
59}