How to Use PkarrResolver with Iroh: Publishing and Resolving DHT Records
The PkarrResolver in Iroh enables DNS-style lookups for mutable DHT entries using cryptographically signed packets, implemented through the iroh-dns crate by creating SignedPacket instances, publishing them via relays, and resolving TXT records through the high-level resolver API.
The Iroh networking stack implements the pkarr protocol to provide decentralized, mutable name resolution over a distributed hash table. Using PkarrResolver with Iroh, you can publish DNS records that are signed by Ed25519 keys and resolve them using standard DNS semantics, with all verification handled automatically by the library.
Understanding PkarrResolver in Iroh
The PkarrResolver is the component that handles DNS-style lookups for mutable entries stored in the DHT using the pkarr packet format. A pkarr packet consists of a 32-byte public key, a 64-byte Ed25519 signature, an 8-byte monotonic timestamp, and a compressed DNS message containing the actual records.
According to the Iroh source code, this functionality resides primarily in the iroh-dns crate, where the core SignedPacket type in iroh-dns/src/pkarr.rs manages cryptographic signing and verification, while the resolver logic in iroh-dns/src/dns.rs orchestrates queries through the relay network.
Creating Signed Packets
To publish data, you first create a SignedPacket using the SignedPacket::from_txt_strings method defined in iroh-dns/src/pkarr.rs. This method takes a secret key, a DNS name, the TXT record values, and a TTL.
use iroh_dns::pkarr::SignedPacket;
use iroh_base::SecretKey;
// Generate a new secret key
let secret = SecretKey::generate();
// Create a signed packet with TXT records
let packet = SignedPacket::from_txt_strings(
&secret,
"_iroh", // DNS name relative to the key zone
vec!["value=example"], // TXT record content
300, // TTL in seconds
)?;
For loading packets from storage or handling raw bytes, use the lower-level SignedPacket::from_parts_unchecked method:
let restored = SignedPacket::from_parts_unchecked(
public_key_bytes,
signature_bytes,
Timestamp::from_micros(ts),
&dns_bytes,
)?;
Publishing Packets via Relay
Once created, the packet must be published to the DHT through an Iroh relay. The SignedPacket::to_relay_payload method serializes the packet (everything after the public key), which is then sent via the relay client defined in iroh-relay/src/client.rs.
use iroh_relay::client::RelayClient;
// Connect to a relay
let relay = RelayClient::new("wss://relay.iroh.example".parse()?)?;
// Serialize to relay payload format
let payload = packet.to_relay_payload();
// Publish to the DHT keyed by the public key
relay.publish(&secret.public(), &payload).await?;
Resolving Names with PkarrResolver
To resolve published records, instantiate the Resolver from iroh-dns and use the resolve_txt method. This constructs a DNS query, sends it through the relay network, and returns the parsed TXT records after verifying the signature using SignedPacket::from_relay_payload.
// Create a resolver instance
let resolver = iroh_dns::Resolver::new(relay);
// Resolve a specific DNS name
let txts = resolver
.resolve_txt("_iroh")
.await?; // Returns Vec<String>
println!("Resolved TXT records: {:?}", txts);
After verification, you can also extract all records using SignedPacket::txt_records(name) for specific names or SignedPacket::all_txt_records() to list every record in the packet.
Key Source Files
The implementation of PkarrResolver spans several key files in the Iroh repository:
iroh-dns/src/pkarr.rs: DefinesSignedPacket, including signing, verification, and record extraction methods.iroh-dns/src/dns.rs: Contains the high-level resolver that builds DNS queries and parses responses.iroh-relay/src/client.rs: Implements the relay client used to publish and fetch pkarr payloads.iroh-base/src/lib.rs: Provides core cryptographic types includingPublicKey,SecretKey, andSignature.
Summary
- PkarrResolver with Iroh provides DNS-style resolution over a DHT using cryptographically signed packets.
- Create packets using
SignedPacket::from_txt_stringsiniroh-dns/src/pkarr.rs. - Publish payloads via
RelayClient::publishafter serializing withto_relay_payload. - Resolve records using
iroh_dns::Resolverandresolve_txt, which automatically verifies Ed25519 signatures. - The packet format includes a 32-byte public key, 64-byte signature, 8-byte timestamp, and compressed DNS message.
Frequently Asked Questions
How does PkarrResolver verify the authenticity of DHT records?
The resolver verifies records by reconstructing the SignedPacket using SignedPacket::from_relay_payload, which validates the 64-byte Ed25519 signature against the 32-byte public key embedded in the packet. This ensures that only the holder of the corresponding secret key could have published the data, providing cryptographic authenticity for all resolved TXT records.
Can I use PkarrResolver without running a relay?
While the resolver architecture is designed to work with relays for reliable DHT access, the underlying SignedPacket logic in iroh-dns/src/pkarr.rs is network-agnostic. You could theoretically resolve packets directly from DHT nodes if you implement the gossip protocol, but the standard iroh_dns::Resolver in iroh-dns/src/dns.rs expects a RelayClient for query routing and response handling.
What DNS record types does PkarrResolver support?
The current implementation focuses primarily on TXT records through methods like txt_records() and all_txt_records(). The pkarr packet format uses standard DNS message compression, so the underlying structure supports various record types, but the Iroh resolver API specifically exposes TXT record resolution for mutable key-value mappings in the DHT.
How do I handle packet updates with rotating timestamps?
Pkarr packets include an 8-byte monotonic timestamp that ensures newer records overwrite older ones in the DHT. When creating packets with SignedPacket::from_txt_strings or from_parts_unchecked, the timestamp is automatically set to the current time. To update a record, simply create a new packet with the same secret key and a newer timestamp, then republish it—the DHT will retain only the latest version based on the timestamp ordering.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →