mirror of
https://github.com/0xfnzero/solana-streamer.git
synced 2026-08-24 14:28:10 +00:00
add tokens_subscription
This commit is contained in:
@@ -8,9 +8,14 @@ use anchor_client::solana_sdk::commitment_config::CommitmentConfig;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::task::JoinHandle;
|
||||
use futures::{future::BoxFuture, Future, StreamExt};
|
||||
use futures::StreamExt;
|
||||
use crate::instruction::{
|
||||
logs_events::DexEvent,
|
||||
logs_data::DexInstruction,
|
||||
logs_filters::LogFilter
|
||||
};
|
||||
|
||||
/// 订阅结果,包含订阅任务和取消订阅逻辑
|
||||
/// Subscription handle containing task and unsubscribe logic
|
||||
pub struct SubscriptionHandle {
|
||||
pub task: JoinHandle<()>,
|
||||
pub unsub_fn: Box<dyn Fn() + Send>,
|
||||
@@ -28,14 +33,14 @@ pub async fn create_pubsub_client(ws_url: &str) -> PubsubClient {
|
||||
}
|
||||
|
||||
/// 启动订阅
|
||||
pub async fn start_subscription<F>(
|
||||
pub async fn tokens_subscription<F>(
|
||||
ws_url: &str,
|
||||
program_address: &str,
|
||||
commitment: CommitmentConfig,
|
||||
subscription_callback: F,
|
||||
callback: F,
|
||||
) -> Result<SubscriptionHandle, Box<dyn std::error::Error>>
|
||||
where
|
||||
F: Fn(&str, Vec<String>) + Send + Sync + 'static,
|
||||
F: Fn(DexEvent) + Send + Sync + 'static,
|
||||
{
|
||||
let logs_filter = RpcTransactionLogsFilter::Mentions(vec![program_address.to_string()]);
|
||||
|
||||
@@ -43,17 +48,17 @@ where
|
||||
commitment: Some(commitment),
|
||||
};
|
||||
|
||||
// 创建 PubsubClient
|
||||
// Create PubsubClient
|
||||
let sub_client = Arc::new(PubsubClient::new(ws_url).await.unwrap());
|
||||
|
||||
let sub_client_clone = Arc::clone(&sub_client);
|
||||
|
||||
// 创建一个通道用于取消订阅
|
||||
let (unsub_tx, mut unsub_rx) = mpsc::channel(1);
|
||||
// Create channel for unsubscribe
|
||||
let (unsub_tx, _) = mpsc::channel(1);
|
||||
|
||||
// 启动订阅任务
|
||||
// Start subscription task
|
||||
let task = tokio::spawn(async move {
|
||||
let (mut stream, unsub) = sub_client_clone.logs_subscribe(logs_filter, logs_config).await.unwrap();
|
||||
let (mut stream, _) = sub_client_clone.logs_subscribe(logs_filter, logs_config).await.unwrap();
|
||||
|
||||
loop {
|
||||
let msg = stream.next().await;
|
||||
@@ -62,22 +67,32 @@ where
|
||||
if let Some(_err) = msg.value.err {
|
||||
continue;
|
||||
}
|
||||
|
||||
subscription_callback(&msg.value.signature.as_str(), msg.value.logs);
|
||||
|
||||
let instructions = LogFilter::parse_instruction(&msg.value.logs).unwrap();
|
||||
for instruction in instructions {
|
||||
match instruction {
|
||||
DexInstruction::CreateToken(token_info) => {
|
||||
callback(DexEvent::NewToken(token_info));
|
||||
}
|
||||
DexInstruction::Trade(trade_info) => {
|
||||
callback(DexEvent::NewTrade(trade_info));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {
|
||||
println!("Token subscription stream ended");
|
||||
// break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 返回订阅句柄和取消逻辑
|
||||
// Return subscription handle and unsubscribe logic
|
||||
Ok(SubscriptionHandle {
|
||||
task,
|
||||
unsub_fn: Box::new(move || {
|
||||
let _ = unsub_tx.try_send(()); // 发送取消信号
|
||||
let _ = unsub_tx.try_send(());
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user