# Understanding the Endpoint Module in Iroh: Core Identity and Networking

> Discover the iroh endpoint module and its Endpoint struct. Learn how to create P2P connections with unique EndpointIds derived from Ed25519 keys for core identity and networking.

- Repository: [number zero/iroh](https://github.com/n0-computer/iroh)
- Tags: deep-dive
- Published: 2026-07-03

---

**The endpoint module in iroh provides the `Endpoint` struct, which serves as the primary API for creating peer-to-peer connections, with each instance identified by a unique `EndpointId` derived from its Ed25519 public key.**

The iroh networking library (n0-computer/iroh) centers around the endpoint module, which exposes the main `Endpoint` API for establishing secure connections between peers. This module defines how endpoints are constructed, cryptographically identified, and addressed across the network, forming the foundation of iroh's peer-to-peer communication stack.

## What Is the Endpoint Module in Iroh?

The endpoint module serves as the primary entry point for applications using the iroh networking stack. Located in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs), this module exports the `Endpoint` struct and its associated `Builder`, which handle the lifecycle of network connections.

An **Endpoint** represents a single node in the iroh network capable of initiating outgoing connections and accepting incoming ones. According to the source code in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs), the `Endpoint` struct maintains the cryptographic identity and transport configuration required for QUIC-based communication.

## EndpointId: The Cryptographic Identity

Central to the endpoint module is the **EndpointId**, a type alias that serves as the unique identifier for every endpoint in the network.

In [`iroh-base/src/key.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/key.rs), the `EndpointId` is defined as a direct alias for `PublicKey`:

```rust
pub type EndpointId = PublicKey;

```

This definition appears in lines 58-70 of the key module, where `PublicKey` represents a compressed Ed25519 public key. When an endpoint is instantiated, the `Builder` either accepts a user-provided secret key or generates a fresh one using `SecretKey::generate`. The corresponding public key derived via `SecretKey::public` becomes the endpoint's permanent `EndpointId`.

As implemented in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs), the `Endpoint::id()` method (lines 66-72) returns this identifier, allowing applications to retrieve their own network identity or verify the identity of remote peers.

## Creating an Endpoint with the Builder Pattern

The endpoint module utilizes a builder pattern for construction, defined in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs). The `Builder` struct collects configuration parameters before binding to network interfaces.

Key aspects of endpoint creation include:

- **Secret Key Generation**: If no secret key is supplied to `Builder::bind`, the method automatically generates a new `SecretKey` (lines 24-27)
- **Identity Derivation**: The builder derives the `EndpointId` from the secret key's public component during the bind operation
- **Presets**: The module supports configuration presets such as `presets::N0` for bootstrap node connectivity

The construction process ensures that every endpoint possesses a globally unique, cryptographically secure identifier without requiring centralized registration.

## Endpoint Addressing and Network Communication

While the `EndpointId` identifies the peer, the **EndpointAddr** struct (defined in [`iroh-base/src/endpoint_addr.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/endpoint_addr.rs)) combines this identifier with network-level addressing information.

According to lines 42-46 of [`endpoint_addr.rs`](https://github.com/n0-computer/iroh/blob/main/endpoint_addr.rs), `EndpointAddr` always contains an `EndpointId` along with optional relay addresses or direct IP addresses. This structure enables the `Endpoint::connect` method to establish authenticated connections to remote peers using their cryptographic identifiers.

The endpoint module also integrates with TLS verification through [`iroh/src/tls/name.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/tls/name.rs), where the `EndpointId` is encoded as a DNS-compatible string for certificate validation, ensuring that transport-layer security cryptographically binds to the endpoint's public key.

## Practical Example: Creating and Identifying an Endpoint

The following example demonstrates how to create an endpoint using the builder pattern and retrieve its `EndpointId`:

```rust
use iroh::{Endpoint, endpoint::presets};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Build a default endpoint (generates a fresh secret key)
    let ep = Endpoint::builder(presets::N0).bind().await?;

    // Retrieve the Endpoint Id (public key)
    let id = ep.id();
    println!("My Endpoint Id: {}", id); // hex encoding of the public key

    // Use the id to connect to a remote peer (requires the remote's EndpointId)
    // let remote_id: iroh_base::EndpointId = …;
    // let remote_addr = iroh_base::EndpointAddr::from_parts(remote_id, vec![]);
    // let conn = ep.connect(remote_addr, b"my-alpn").await?;
    Ok(())
}

```

In this code:
- `Endpoint::builder(presets::N0).bind().await?` creates the endpoint, generating a secret key and deriving the `EndpointId`
- `ep.id()` returns the `EndpointId` (public key), which implements `Display` for hex output
- The same identifier forms the basis for creating `EndpointAddr` instances when dialing remote peers

## Summary

The endpoint module in iroh provides the foundational networking primitives for peer-to-peer communication:

- **Cryptographic Identity**: The `EndpointId` type alias in [`iroh-base/src/key.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/key.rs) binds each endpoint to a unique Ed25519 public key
- **Builder Construction**: The `Builder` pattern in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) handles endpoint instantiation and automatic key generation
- **Addressing**: `EndpointAddr` combines the `EndpointId` with network addresses for routing
- **TLS Integration**: The module supports DNS-encoded endpoint identities for transport security verification

## Frequently Asked Questions

### How is the EndpointId generated when creating a new endpoint?

When you call `Builder::bind()` in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs), the builder checks for a provided secret key. If none exists, it invokes `SecretKey::generate()` to create a fresh Ed25519 keypair. The `EndpointId` is then derived by calling `SecretKey::public()` to obtain the public key, which serves as the permanent identifier.

### What is the relationship between EndpointId and PublicKey?

`EndpointId` is a type alias for `PublicKey`, defined in [`iroh-base/src/key.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/key.rs) at lines 58-70. This means they are identical types at the Rust level, with `EndpointId` serving as a semantic marker indicating the public key's role as a network endpoint identifier rather than just a generic cryptographic key.

### How do I use the endpoint module to connect to remote peers?

To connect to a remote peer, you need the remote's `EndpointId` (their public key). You construct an `EndpointAddr` using `iroh_base::EndpointAddr::from_parts(remote_id, relay_addresses)`, then pass this to `Endpoint::connect()` along with an ALPN protocol identifier. The connection attempt will verify that the remote peer possesses the corresponding private key for the provided `EndpointId`.

### Is the EndpointId stable across application restarts?

The `EndpointId` remains stable only if you reuse the same secret key across restarts. If you allow the `Builder` to generate a new secret key on each launch (the default behavior when no key is provided), the endpoint will receive a new `EndpointId`. To maintain a persistent identity, persist the secret key generated by `SecretKey::generate()` and supply it to the builder on subsequent runs.