2. Endpoints
The journey of a connection starts with an endpoint. An endpoint is one of the two termination points for a connection. It’s one of the tin cans that the wire is connected to. Because this is peer-2-peer, endpoints both initiate and accept connections. The endpoint handles both.
Let's first add iroh to our project. From the project root run cargo add iroh
to install the latest version:
$ cargo add iroh
Updating crates.io index
Adding iroh v0.31.0 to dependencies
Features:
+ discovery-pkarr-dht
+ metrics
- discovery-local-network
- examples
- test-utils
Updating crates.io index
Locking 432 packages to latest compatible versions
We're also going to need a few supporting libraries so let's add those as well:
cargo add tokio anyhow rand
In the end your Cargo.toml
file's [dependencies]
section should look something like this. It's ok if the version numbers are slightly different:
[dependencies]
anyhow = "1.0.95"
iroh = "0.31.0"
rand = "0.8.5"
tokio = "1.43.0"
Starting an Endpoint
With our dependencies added, open up src/main.rs
and add the following code:
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Create an endpoint
let builder = iroh::Endpoint::builder();
// bind it to a socket
let endpoint = builder.bind().await?;
// print this endpoint's node id
println!("node id: {:?}", endpoint.node_id());
// exit the program
Ok(())
}
Then save and run your program with cargo run
. You should see output similar to this:
b5 at number-0 in ~/code/iroh-tour (main●)
$ cargo run
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.80s
Running `/Users/b5/.cargo/build/debug/iroh-tour`
node id: PublicKey(95224c92856163add8a9cb68a81183aa5d9881c4def58625a9f4266a0743b479)
This code just prints it's ID & exits. For a more complete example, check out the connect example
The non-setup part of this program adds up to 3 lines of code, and one of them is a print statement! The first line constructs an endpoint. 99% of apps will have a single endpoint in the entire app, so you’ll build the endpoint once, and refer to it a bunch. Then we call bind to ask the operating system for a networking port. This calling bind will kick off work in the background that we’ll talk about in a bit.
Those three lines are the beating heart of adding iroh to an app. Once the node ID prints we have an active endpoint that's ready to connect & (if configured to) accept connections. Everything else builds up from here.