12 releases
0.1.11 | Feb 7, 2025 |
---|---|
0.1.10 | Feb 6, 2025 |
0.1.9 | Jan 26, 2025 |
#703 in Network programming
549 downloads per month
42KB
318 lines
iroh-topic-tracker
A tracker for Iroh NodeId's in GossipSub topics.
This library integrates with
iroh-gossip
to automate peer
discovery and includes a hosted BOOTSTRAP_NODE
for seamless topic tracking
without you needing to host anything. Your peers can discover each other even
if both are behind NATs.
Overview
The crate provides a
TopicTracker
to manage and discover peers participating in shared GossipSub topics. It
leverages Iroh's direct connectivity and
Router
to
handle protocol routing.
Features
- Automatic peer discovery via
iroh-gossip
(enabled withiroh-gossip-auto-discovery
feature). - Dedicated bootstrap node support for topic tracking.
- Simple API to fetch active peers for a topic.
Getting Started
Prerequisites
Add the crate to your Cargo.toml
with the required features:
[dependencies]
iroh-topic-tracker = { version = "0.1", features = ["iroh-gossip-auto-discovery"] }
Automatic Discovery
Enable iroh-gossip
integration to automate peer discovery for topics:
use futures_lite::StreamExt;
use iroh::Endpoint;
use iroh_gossip::net::{Event, Gossip, GossipEvent};
use iroh_topic_tracker::{integrations::iroh_gossip::*, topic_tracker::Topic};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Configure Iroh endpoint with discovery
let endpoint = Endpoint::builder().discovery_n0().bind().await?;
// Configure gossip protocol with auto-discovery
let gossip = Gossip::builder()
.spawn_with_auto_discovery(endpoint.clone())
.await?;
// Join a topic and start tracking
let topic = Topic::from_passphrase("my-iroh-gossip-topic");
let (sink, mut stream) = gossip.subscribe_and_join(topic.into()).await?.split();
// Read from stream ..
while let Some(event) = stream.next().await {
if let Ok(Event::Gossip(GossipEvent::Received(msg))) = event {
// Do something with msg...
let msg_text = String::from_utf8(msg.content.to_vec()).unwrap();
}
}
// .. or Send to Sink
sink.broadcast("my msg goes here".into()).await.unwrap();
Ok(())
}
Basic Setup with Iroh
use iroh::{protocol::Router, Endpoint};
use iroh_topic_tracker::topic_tracker::{Topic, TopicTracker};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Configure Iroh endpoint with discovery
let endpoint = Endpoint::builder().discovery_n0().bind().await?;
// Initialize topic tracker
let topic_tracker = TopicTracker::new(&endpoint);
// Attach to Iroh router
let router = Router::builder(endpoint.clone())
.accept(TopicTracker::ALPN, topic_tracker.clone())
.spawn()
.await?;
// Track peers in a topic
let topic = Topic::from_passphrase("my-secret-topic");
let peers = topic_tracker.get_topic_nodes(&topic).await?;
Ok(())
}
Examples
Run a Topic Tracker Node
Start a dedicated tracker node:
cargo run --example server
Note: Update secret.rs
with your SecretKey
and configure BOOTSTRAP_NODES
in topic_tracker.rs
for secure communication.
Query Active Peers
Fetch the latest NodeIds for a topic:
cargo run --example client
Building
Optimized release build for the tracker server:
cargo build --release --example server
License
This project is licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contribution
Unless explicitly stated, any contribution intentionally submitted for inclusion in this project shall be dual-licensed as above, without any additional terms or conditions.
Dependencies
~45–79MB
~1.5M SLoC