中文 | English
A powerful Rust SDK for real-time listening and parsing Fourmeme contract events on BSC, with automatic tracking of token lifecycle from launch to DEX.
- 🔌 Real-time Listening - WebSocket-based event streaming
- 📦 Type-safe - Strongly-typed event structures, zero runtime errors
- 🎯 Smart Tracking - Auto-discover and track graduated tokens on DEX
- 🔄 Dynamic Monitoring - Automatically add PancakeSwap listeners on graduation
- 📝 JSON Output - Standard single-line JSON format for easy integration
- 🚀 Zero Config - Pure code configuration, works out of the box
- 💰 Internal Trading - Fourmeme bonding curve trading support (v0.1.1)
- 💱 External Trading - PancakeSwap DEX trading support (v0.1.1)
[dependencies]
fourmeme_parser_sdk = { git = "https://github.com/vnxfsc/fourmeme_parser_sdk" }
tokio = { version = "1", features = ["full"] }
anyhow = "1.0"cargo run --example parser_examplecargo run --example trading_examplecargo run --example dex_trading_examplecargo run --example auto_trade_exampleFor detailed trading guide, see TRADING_GUIDE_EN.md
Edit the config section at the top of examples/parser_example.rs:
// Select Fourmeme event types to listen
let fourmeme_events = vec![
"TokenCreate", // New token creation
"TokenPurchase", // Platform buy
"TokenSale", // Platform sell
"LiquidityAdded", // Token graduation
];
// Auto-track graduated tokens on DEX
let track_dex = true; // true = track, false = don't track| Use Case | Configuration |
|---|---|
| Full Monitoring | All events + track_dex = true |
| Token Discovery | ["TokenCreate"] + track_dex = false |
| Platform Trading | ["TokenPurchase", "TokenSale"] + track_dex = false |
| Graduated Tokens | ["LiquidityAdded"] + track_dex = true |
| Complete Lifecycle | All events + track_dex = true ⭐ |
TokenCreate {"block":63946320,"tx":"0xe4f92188...","index":27,"creator":"0xc0fd8c54...","token":"0x2e32c942...","request_id":"100826165","name":"Instant60066","symbol":"I0066","total_supply":"1000000000000000000000000000","launch_time":"1759959160","launch_fee":"0"}Fields:
creator- Creator addresstoken- New token contract addressname/symbol- Token name and symboltotal_supply- Total supplylaunch_time- Launch timestamp
TokenPurchase {"block":63946320,"tx":"0xe4f92188...","index":27,"token":"0x2e32c942...","account":"0xc0fd8c54...","price":"6114480183","amount":"33425708807475417000000000","cost":"198019801980198016","fee":"1980198019801980","offers":"766574291192524583000000000","funds":"198019801980198016"}Fields:
token- Token addressaccount- Buyer addressamount- Token amount purchasedcost- BNB spent (in wei)price- Price per tokenoffers/funds- Pool state
TokenSale {"block":63946321,"tx":"0xf6831c3a...","index":1,"token":"0x2e32c942...","account":"0x3d81936...","price":"6114480183","amount":"65261577661154695000000000","cost":"425742574257425736","fee":"4257425742574257","offers":"766574291192524583000000000","funds":"198019801980198016"}Fields:
token- Token addressaccount- Seller addressamount- Token amount soldcost- BNB received (in wei)fee- Trading fee
LiquidityAdded {"block":63940346,"tx":"0x7651602f...","index":1,"base":"0xecc67bd9...","offers":"200000000000000000000000000","quote":"0x0000000000000000000000000000000000000000","funds":"17639999998157599996"}Fields:
base- Graduated token addressoffers- Token amount added to DEXquote- Quote token (zero address = BNB)funds- BNB amount added
DEX_BUY {"block":63940350,"tx":"0xabcd1234...","index":42,"pair":"0x12345678...","token":"0xecc67bd9...","sender":"0x987654...","to":"0xabcdef...","amount":"5000000000000000000000000","bnb":"2500000000000000000"}DEX_SELL {"block":63940351,"tx":"0xef123456...","index":55,"pair":"0x12345678...","token":"0xecc67bd9...","sender":"0x456789...","to":"0xfedcba...","amount":"3000000000000000000000000","bnb":"1800000000000000000"}SDK now supports both internal and external trading!
For newly created tokens before graduation.
use fourmeme_parser_sdk::{create_ws_provider, FourmemeTrader};
use ethers::prelude::*;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Create Provider
let provider = create_ws_provider("wss://...").await?;
// Create internal trader
let trader = FourmemeTrader::new(provider, "YOUR_PRIVATE_KEY")?;
let token: Address = "0x...".parse()?;
let bnb_amount = U256::from_dec_str("100000000000000000")?; // 0.1 BNB
// Query price
let price = trader.quote_buy(token, bnb_amount).await?;
println!("0.1 BNB buys: {} tokens", price.token_amount);
// Buy tokens
let result = trader.buy(token, bnb_amount, 1.0).await?;
println!("✅ Buy success: {}", result.tx_hash);
// Sell tokens
let token_amount = U256::from_dec_str("1000000000000000000000")?;
let result = trader.sell(token, token_amount, 1.0).await?;
println!("✅ Sell success: {}", result.tx_hash);
Ok(())
}For graduated tokens.
use fourmeme_parser_sdk::{create_ws_provider, DexTrader, WBNB};
use ethers::prelude::*;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let provider = create_ws_provider("wss://...").await?;
// Create DEX trader
let trader = DexTrader::new(provider, "YOUR_PRIVATE_KEY")?;
let token: Address = "0x...".parse()?;
let wbnb: Address = WBNB.parse()?;
let bnb_amount = U256::from_dec_str("100000000000000000")?;
// Buy
let tx = trader.buy_token(token, wbnb, bnb_amount, 1.0).await?;
println!("✅ DEX buy: {}", tx);
// Sell (approve first)
trader.approve_token(token).await?;
let token_amount = U256::from_dec_str("1000000000000000000000")?;
let tx = trader.sell_token(token, wbnb, token_amount, 1.0).await?;
println!("✅ DEX sell: {}", tx);
Ok(())
}let internal_trader = FourmemeTrader::new(provider.clone(), "KEY")?;
let external_trader = DexTrader::new(provider.clone(), "KEY")?;
// Query token status
let token_info = internal_trader.get_token_info(token).await?;
if token_info.is_tradable() {
// Internal stage → Use FourmemeTrader
internal_trader.buy(token, bnb, 1.0).await?;
} else if token_info.is_graduated() {
// External stage → Use DexTrader
external_trader.buy_token(token, wbnb, bnb, 1.0).await?;
}Start Listener
↓
Monitor Fourmeme Contract Events
↓
Detect TokenCreate
→ Output new token info
→ Can use FourmemeTrader for internal buy
↓
Detect TokenPurchase/TokenSale
→ Output trading info
↓
Detect LiquidityAdded (Token Graduation)
→ Output graduation info
→ Query PancakeSwap Pair address
→ Dynamically add Swap event listener (if track_dex = true)
→ Can use DexTrader for external trading
↓
Output real-time DEX trades for this token
↓
Continue monitoring next token...
use fourmeme_parser_sdk::{create_ws_provider, EventListener, EventFilter, FOURMEME_CONTRACT, WBNB};
use std::sync::Arc;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Create WebSocket Provider
let provider = create_ws_provider("wss://bsc-mainnet.nodereal.io/ws/v1/YOUR_KEY").await?;
// Parse contract addresses
let fourmeme = FOURMEME_CONTRACT.parse()?;
let wbnb = WBNB.parse()?;
// Select event types
let filter = EventFilter::new(vec!["TokenCreate", "LiquidityAdded"]);
// Create listener
let listener = Arc::new(EventListener::with_filter(
provider,
fourmeme,
wbnb,
filter,
true, // Track DEX
));
// Start
listener.start().await?;
Ok(())
}// Don't track DEX, only platform trades
let filter = EventFilter::new(vec!["TokenPurchase", "TokenSale"]);
let listener = Arc::new(EventListener::with_filter(
provider,
fourmeme,
wbnb,
filter,
false, // Disable DEX tracking
));// Only graduation events and DEX trades
let filter = EventFilter::new(vec!["LiquidityAdded"]);
let listener = Arc::new(EventListener::with_filter(
provider,
fourmeme,
wbnb,
filter,
true, // Auto-track DEX
));fourmeme_parser_sdk/
├── Cargo.toml # Project config
├── README.md # Documentation (English)
├── README_CN.md # Documentation (Chinese)
├── TRADING_GUIDE_EN.md # Trading guide (English)
├── TRADING_GUIDE_CN.md # Trading guide (Chinese)
├── examples/
│ ├── parser_example.rs # Event listening example
│ ├── trading_example.rs # Internal trading example
│ ├── dex_trading_example.rs # External trading example
│ └── auto_trade_example.rs # Auto trading framework
├── test/
│ ├── test_trade.rs # Internal trading test (detailed)
│ └── test_dex_trade.rs # External trading test (detailed)
└── src/
├── lib.rs # Library entry
├── error.rs # Error types
├── client/ # Client module
│ ├── mod.rs
│ ├── listener.rs # Event listener
│ └── provider.rs # WebSocket provider
├── events/ # Events module
│ ├── mod.rs
│ ├── types.rs # Event type definitions
│ └── parser.rs # Event parser
├── dex/ # DEX integration module
│ ├── mod.rs
│ ├── types.rs # DEX type definitions
│ └── pair.rs # PancakeSwap Pair listener
└── trading/ # Trading module (v0.1.1)
├── mod.rs
├── types.rs # Trading type definitions
├── price.rs # Price calculator
├── trader.rs # Internal trader
└── dex_trader.rs # External trader
FOURMEME_CONTRACT // Fourmeme contract address
PANCAKESWAP_FACTORY // PancakeSwap Factory address
WBNB // WBNB token address// Create listener (default: all events + DEX tracking)
pub fn new(
provider: Arc<Provider<Ws>>,
fourmeme_contract: Address,
wbnb: Address
) -> Self
// Create listener with filter
pub fn with_filter(
provider: Arc<Provider<Ws>>,
fourmeme_contract: Address,
wbnb: Address,
event_filter: EventFilter,
track_dex: bool,
) -> Self
// Start listening (runs forever)
pub async fn start(self: Arc<Self>) -> Result<()>
// Get number of tracked tokens
pub async fn tracked_count(&self) -> usize// Create filter
pub fn new<T: Into<String>>(events: Vec<T>) -> Self
// Listen to all events
pub fn all() -> Self
// Check if event is enabled
pub fn is_enabled(&self, event_type: &str) -> boolpub enum FourmemeEvent {
TokenCreate(TokenCreate),
TokenPurchase(TokenPurchase),
TokenSale(TokenSale),
LiquidityAdded(LiquidityAdded),
}pub struct SwapEvent {
pub sender: Address,
pub amount0_in: U256,
pub amount1_in: U256,
pub amount0_out: U256,
pub amount1_out: U256,
pub to: Address,
}// Create WebSocket Provider
create_ws_provider(url: &str) -> Result<Arc<Provider<Ws>>>
// Parse event
parse_event(log: &Log) -> Option<FourmemeEvent>
// Parse Swap event
parse_swap_event(log: &Log) -> Option<SwapEvent>
// Get PancakeSwap Pair address
get_pair_address(provider, token, wbnb) -> Result<Address>// Create trader
pub fn new(provider: Arc<Provider<Ws>>, private_key: &str) -> Result<Self>
// Query token info
pub async fn get_token_info(&self, token: Address) -> Result<TokenInfo>
// Quote buy price (how many tokens can BNB buy)
pub async fn quote_buy(&self, token: Address, bnb_amount: U256) -> Result<PriceInfo>
// Quote sell price (how much BNB can tokens get)
pub async fn quote_sell(&self, token: Address, token_amount: U256) -> Result<PriceInfo>
// Buy tokens (use BNB to buy as many tokens as possible)
pub async fn buy(&self, token: Address, bnb_amount: U256, slippage: f64) -> Result<TradeResult>
// Sell tokens (swap for BNB)
pub async fn sell(&self, token: Address, token_amount: U256, slippage: f64) -> Result<TradeResult>
// Buy exact amount of tokens
pub async fn buy_exact_amount(&self, token: Address, token_amount: U256, slippage: f64) -> Result<TradeResult>
// Get wallet address
pub fn address(&self) -> Address// Create DEX trader
pub fn new(provider: Arc<Provider<Ws>>, private_key: &str) -> Result<Self>
// Quote DEX buy price
pub async fn quote_buy(&self, token: Address, wbnb: Address, bnb_amount: U256) -> Result<U256>
// DEX buy tokens
pub async fn buy_token(&self, token: Address, wbnb: Address, bnb_amount: U256, slippage: f64) -> Result<String>
// DEX sell tokens
pub async fn sell_token(&self, token: Address, wbnb: Address, token_amount: U256, slippage: f64) -> Result<String>
// Approve token to Router (must call before selling)
pub async fn approve_token(&self, token: Address) -> Result<String>
// Get wallet address
pub fn address(&self) -> Address// Token information
pub struct TokenInfo {
pub offers: U256, // Token reserves
pub funds: U256, // BNB reserves
pub last_price: U256, // Last price
pub status: U256, // Status (0=trading, 2=graduated)
// ...
}
// Price information
pub struct PriceInfo {
pub token_amount: U256, // Token amount
pub bnb_cost: U256, // BNB cost
pub price_per_token: f64, // Price (BNB/Token)
pub fee: U256, // Trading fee
}
// Trade result
pub struct TradeResult {
pub tx_hash: String, // Transaction hash
pub trade_type: TradeType, // Trade type (Buy/Sell)
pub token: Address, // Token address
pub amount: U256, // Token amount
pub cost: U256, // BNB cost
pub price: f64, // Average price
}let filter = EventFilter::new(vec!["TokenCreate"]);
let listener = EventListener::with_filter(provider, fourmeme, wbnb, filter, false);
// Output: All newly created token infolet filter = EventFilter::new(vec!["TokenPurchase", "TokenSale"]);
let listener = EventListener::with_filter(provider, fourmeme, wbnb, filter, false);
// Output: All platform buy/sell tradeslet filter = EventFilter::new(vec!["LiquidityAdded"]);
let listener = EventListener::with_filter(provider, fourmeme, wbnb, filter, true);
// Output:
// 1. Token graduation events
// 2. Automatically start tracking DEX trades
// 3. Real-time DEX buy/sell datalet filter = EventFilter::all();
let listener = EventListener::with_filter(provider, fourmeme, wbnb, filter, true);
// Output:
// 1. Token creation
// 2. Platform trades
// 3. Token graduation
// 4. DEX trades
// Complete token lifecycle!if let FourmemeEvent::LiquidityAdded(e) = event {
let msg = format!(
"🎉 Token Graduated!\nAddress: {:?}\nLiquidity: {} BNB",
e.base,
e.funds.as_u128() / 1e18 as u128
);
send_telegram(msg).await?;
}match event {
FourmemeEvent::TokenCreate(e) => {
db.save_token_creation(&e).await?;
}
FourmemeEvent::LiquidityAdded(e) => {
db.mark_token_graduated(&e.base).await?;
}
_ => {}
}if let FourmemeEvent::TokenPurchase(e) = event {
let price_bnb = e.cost.as_u128() as f64 / e.amount.as_u128() as f64;
if price_bnb > threshold {
alert("Price anomaly detected!").await?;
}
}| Event | Signature Hash |
|---|---|
| TokenCreate | 0x396d5e902b675b032348d3d2e9517ee8f0c4a926603fbc075d3d282ff00cad20 |
| TokenPurchase | 0x7db52723a3b2cdd6164364b3b766e65e540d7be48ffa89582956d8eaebe62942 |
| TokenSale | 0x0a5575b3648bae2210cee56bf33254cc1ddfbc7bf637c0af2ac18b14fb1bae19 |
| LiquidityAdded | 0xc18aa71171b358b706fe3dd345299685ba21a5316c66ffa9e319268b033c44b0 |
| Swap (PancakeSwap) | 0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822 |
Fourmeme: 0x5c952063c7fc8610FFDB798152D69F0B9550762b
PancakeSwap Factory: 0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73
WBNB: 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c
1. Subscribe to all Fourmeme contract logs
↓
2. Parse each log as event
↓
3. If LiquidityAdded & track_dex = true:
a. Extract token address
b. Call PancakeSwap Factory.getPair(token, WBNB)
c. Get Pair contract address
d. Create new WebSocket subscription for this Pair
e. Parse Swap events and output
↓
4. Each graduated token has independent monitoring task
- Memory: Base ~10MB, +1-2MB per tracked token
- Network: WebSocket long connection, avg 1-5 KB/s
- CPU: Very low, event-driven
- Concurrency: Supports tracking hundreds of tokens simultaneously
-
WebSocket Stability
- Use paid RPC nodes (NodeReal, QuickNode) for production
- Free nodes may have rate limits and connection issues
-
Resource Management
- Each tracked token creates new WebSocket subscription
- Consider implementing max tracking limit for production
-
Data Volume
- TokenPurchase/TokenSale events are very frequent
- Filter event types based on your needs
# Build library
cargo build --lib
# Run examples
cargo run --example parser_example
cargo run --example trading_example
cargo run --example dex_trading_example
cargo run --example auto_trade_example
# Run detailed tests (complete trading flow)
# Note: Update private key and token address before running
cargo run --bin test_trade # Internal trading test
cargo run --bin test_dex_trade # External trading test
# Run unit tests
cargo test
# Generate documentation
cargo doc --lib --open
# Code linting
cargo clippy
# Format code
cargo fmtThe test/ directory contains detailed trading test scripts:
- test_trade.rs - Complete internal trading flow test (buy → approve → sell)
- test_dex_trade.rs - Complete external trading flow test (buy → approve → sell)
These scripts provide step-by-step testing with detailed output for real-world trading validation.
- GitHub: https://github.com/vnxfsc/fourmeme_parser_sdk
- Fourmeme Contract: https://bscscan.com/address/0x5c952063c7fc8610FFDB798152D69F0B9550762b
- PancakeSwap: https://pancakeswap.finance
- BSC Docs: https://docs.bnbchain.org
MIT License
Issues and Pull Requests are welcome!
Built for BSC Meme Coin Ecosystem 🚀🌙