Table of Contents
Concepts and terminology
Endpoint, endpoint ID, ALPN, transport address, relay, path, discovery, ticket — the vocabulary go-iroh uses.
These are the terms the rest of the site assumes. Where a term belongs to the iroh protocol rather than to Go, this page gives the Go spelling and links upstream for the protocol definition.
Endpoint
An endpoint is “a bound iroh node: it owns a secret key, a UDP socket, and the
QUIC transport used to dial and accept connections” (iroh.Endpoint’s doc
comment). It is created with iroh.Bind and closed with
Endpoint.Shutdown — there is no Close method and no NewEndpoint
constructor.
An Endpoint is safe for concurrent use.
Endpoint ID
The public half of the endpoint’s ed25519 key, spelled key.EndpointID. It is
the peer’s name: everything else about an address is just a hint about how to
reach it.
Two textual forms appear in the tooling: 64 hex characters, and the
z-base-32 form produced by EndpointID.Z32(). The iroh command converts
between them.
Upstream Rust iroh calls this a NodeId and its address a NodeAddr. go-iroh uses EndpointID and EndpointAddr. The wire encoding is the same; the Go names are not aliases of the Rust ones. This is the single most common source of confusion when reading upstream docs alongside Go code.
Transport address and endpoint address
A netaddr.TransportAddr is one way to reach a peer. Three kinds ship:
| Kind | Go type | String form |
|---|---|---|
| Direct IP | netaddr.IPAddr |
ip:127.0.0.1:4433 |
| Relay | netaddr.RelayAddr |
relay:https://use1-1.relay.iroh.network./ |
| Custom transport | netaddr.CustomAddr |
custom:… |
A netaddr.EndpointAddr combines an endpoint ID with zero or more transport
addresses. Its doc comment states the rule: “To establish a connection both the
key.EndpointID and at least one path (a relay URL or a direct IP address) are
needed; an EndpointAddr with no addresses is still usable together with an
address-lookup service.”
Build one with netaddr.NewEndpointAddr(id) and the WithIP, WithRelayURL,
and WithAddrs builders.
ALPN
ALPN is Application-Layer Protocol Negotiation, the TLS extension that lets peers agree which application protocol a QUIC connection carries. go-iroh routes incoming connections to handlers by ALPN.
The Go API takes ALPN values as strings — TLS ALPN values are byte strings on
the wire, and Go strings preserve arbitrary bytes while keeping the common
printable-ASCII case simple. Protocol ALPNs in the ecosystem look like
/iroh-gossip/1 or n0/tracker/1; pick a namespaced value for your own.
Path
A path is a concrete network route in use by a connection: a direct UDP path
between two addresses, or a path through a relay. Conn.Paths() returns the
current set and Conn.WatchPaths observes changes. go-iroh’s QUIC layer
supports multipath, so a connection can hold more than one at a time and
migrate between them — typically starting on a relay path and upgrading to a
direct path once hole punching succeeds.
Relay
A relay is a public server that forwards packets between endpoints that cannot
yet (or ever) reach each other directly, and helps them discover their own
observed addresses. The relay package holds the public configuration types —
relay URLs grouped into a Map, per-relay Config, and a Mode selecting
which relays an endpoint uses. The client and wire protocol are internal.
See Relays and discovery, and upstream’s relay documentation for the protocol.
Discovery / address lookup
Given only an endpoint ID, an address-lookup service answers “where is this
peer?”. go-iroh calls the abstraction AddressLookupServices in the iroh
package, with pluggable AddressPublisher and AddressResolver halves.
Shipped backends: DNS, pkarr (signed DNS records published to a relay), static,
in-memory, and mDNS for local networks.
Ticket
A ticket is the compact string form of an address for out-of-band sharing. An
endpoint ticket “starts with endpoint followed by lowercase base32 without
padding” (endpointticket package doc). The blobs package defines the
corresponding blob tickets.
Wire compatibility
go-iroh’s stated goal is wire compatibility with Rust iroh: the same QUIC, TLS, relay, and protocol bytes, not a shared codebase. The README describes the module as “a clean-room Go port targeting wire compatibility with upstream Rust iroh. It is not affiliated with the n0 team.”
What is mechanically proven, and by which test gate, is covered in Testing and interop.
Next steps
- How go-iroh works — how these pieces fit together at runtime.
- Endpoints and connections — the API that uses this vocabulary.
- API map — which package holds which type.