| Crates.io | helia-dnslink |
| lib.rs | helia-dnslink |
| version | 0.1.3 |
| created_at | 2025-10-08 12:21:02.354963+00 |
| updated_at | 2025-10-11 03:52:33.110005+00 |
| description | DNSLink resolution for Helia |
| homepage | https://github.com/cyberfly-io/rust-helia |
| repository | https://github.com/cyberfly-io/rust-helia |
| max_upload_size | |
| id | 1873946 |
| size | 144,507 |
DNSLink resolution for Helia - enables domain names to point to IPFS content using DNS TXT records.
_dnslink. subdomain per spec/ipfs/, /ipns/, /dnslink/Add to your Cargo.toml:
[dependencies]
helia-dnslink = "0.1.2"
use helia_dnslink::{dns_link, DnsLinkInit, DnsLinkResult};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create DNSLink resolver
let dnslink = dns_link(DnsLinkInit::default())?;
// Resolve a domain with DNSLink record
let result = dnslink.resolve("ipfs.tech").await?;
// Handle the result
match result {
DnsLinkResult::IPFS { cid, path, .. } => {
println!("Resolved to CID: {}", cid);
if !path.is_empty() {
println!("With path: {}", path);
}
}
DnsLinkResult::IPNS { peer_id, path, .. } => {
println!("Resolved to Peer ID: {}", peer_id);
}
DnsLinkResult::Other { namespace, value, .. } => {
println!("Custom namespace: {} -> {}", namespace, value);
}
}
Ok(())
}
use helia_dnslink::{dns_link, DnsLinkInit, ResolveOptions};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let dnslink = dns_link(DnsLinkInit::default())?;
// Custom resolution options
let options = ResolveOptions {
nocache: true, // Don't use DNS cache
offline: false, // Allow network queries
max_recursive_depth: Some(10), // Limit recursion depth
};
let result = dnslink.resolve_with_options("example.com", options).await?;
Ok(())
}
use helia_dnslink::{dns_link, DnsLinkInit};
let dnslink = dns_link(DnsLinkInit {
use_https: true, // Use DNS-over-HTTPS
cache_enabled: true, // Enable DNS caching
})?;
DNSLink uses DNS TXT records to point domains to IPFS content:
_dnslink.example.com. 60 IN TXT "dnslink=/ipfs/bafybei..."
Supported formats:
dnslink=/ipfs/<cid> - Points to IPFS contentdnslink=/ipfs/<cid>/path/to/file - With path componentdnslink=/ipns/<peer-id> - Points to IPNS namednslink=/dnslink/other.com - Recursive DNSLinkpub enum DnsLinkResult {
IPFS {
answer: TxtRecord, // DNS TXT record
namespace: String, // "ipfs"
cid: Cid, // Resolved CID
path: String, // Optional path
},
IPNS {
answer: TxtRecord,
namespace: String, // "ipns"
peer_id: PeerId, // Resolved peer ID
path: String,
},
Other {
answer: TxtRecord,
namespace: String, // Custom namespace
value: String, // Raw value
},
}
pub enum DnsLinkError {
NotFound(String), // No DNSLink record found
InvalidFormat(String), // Invalid DNSLink format
RecursionLimit(u32), // Recursion limit exceeded
InvalidCid(String), // Invalid CID
InvalidNamespace(String), // Unknown namespace
InvalidPeerId(String), // Invalid peer ID
DnsResolutionFailed(String), // DNS query failed
InvalidDomain(String), // Invalid domain name
OfflineMode, // Offline mode enabled
}
_dnslink.{domain} TXT records_dnslink. failsdnslink=/namespace/value format/ipfs/<cid> → Parse CID and return/ipns/<peer-id> → Parse peer ID and return/dnslink/<domain> → Recursively resolveSuccessfully resolves:
ipfs.tech → bafybeibb7bijpaz4kp5qrde45ui66lrzeqdb6kjabyorafmfzc6v6cls7qdocs.ipfs.tech → bafybeihc3gzbj642jgt4dkgxebvnzoww53oahwvfbpxbmiiotajrpx6ujaRun tests:
cargo test -p helia-dnslink
Run network tests:
cargo test -p helia-dnslink -- --ignored --nocapture
Licensed under either of:
at your option.