Skip to content
minip2p
Esc
navigateopen⌘Jpreview
On this page

Concepts

Endpoint, PeerId, PeerAddr, PeerReady, dial versus connect, and where events go.

An Endpoint is the main application API. Five ideas explain most code built on it.

Endpoint

Endpoint owns an Ed25519 identity, the transports you bound, and the connection state. It is the app-facing entrypoint for listening, dialing, Ping, Identify, and application streams. QUIC is on by default; add the tcp feature to use QUIC and TCP together, or bind only TCP.

An endpoint does not spawn a runtime. Your code makes progress by calling:

  • poll() for one non-blocking driving step;
  • next_event(deadline) to drive until an application event or deadline;
  • a focused wait such as wait_peer_ready or wait_path.

PeerId

A PeerId identifies a node’s authenticated public key. QUIC proves it with mutual libp2p TLS; TCP uses Noise XX, then Yamux. Either way, connection events carry the verified remote identity, not a label you passed in.

Endpoint::peer_id() returns the local identity.

PeerAddr and Multiaddr

A Multiaddr is a sequence of transport components:

/ip4/127.0.0.1/udp/4001/quic-v1

A PeerAddr pairs that transport with a terminal peer identity:

/ip4/127.0.0.1/udp/4001/quic-v1/p2p/12D3KooW…

Use Multiaddr when choosing where to bind. Use PeerAddr when dialing a specific authenticated peer. See Identity for circuit addresses and wildcards.

Connection readiness

ConnectionEstablished means the transport finished connecting and authenticated the peer. PeerReady comes later, after the first Identify exchange has supplied the peer’s supported protocols and advertised addresses.

Wait for PeerReady before opening an application stream. This avoids racing protocol-support discovery.

Dial versus connect

These are separate paths with different policy:

Goal Start with Wait for
Direct QUIC or TCP to a known address dial, dial_ip4, or dial_ip6 PeerReady
NAT-aware attempt with optional relay connect, connect_addr, or connect_with_addrs wait_path or NatEvent

The base dial* methods only start direct dials. The address picks QUIC or TCP. They do not reserve on a relay or perform DCUtR.

With the nat capability enabled, connect* can race direct candidates against a relay leg. The first usable result is:

  • Path::DirectDialed: a supplied direct address connected;
  • Path::DirectPunched: DCUtR established a direct connection;
  • Path::Relayed { relay }: an end-to-end protected circuit is usable.

A relayed path can later emit NatEvent::PathUpgraded when hole punching lands.

Where events go

Ordinary connection, Identify, Ping, and application stream events come from poll or next_event. Enabled capabilities expose their own event queues:

  • take_nat_events / next_nat_event;
  • take_pubsub_events / next_pubsub_event;
  • take_discovery_events / next_discovery_event.

Continue with Listen and dial or the glossary.

Last updated on September 7, 2026

Was this page helpful?