Documentation
¶
Overview ¶
Package autoconf provides a client for fetching and caching IPFS network configurations.
The client supports intelligent caching with HTTP conditional requests (ETags/Last-Modified), automatic fallbacks to cached or default configurations, and background updates. Multiple configuration versions are kept locally to ensure reliability during network issues.
Basic Usage ¶
The simplest way to use autoconf is with the default client:
client, err := autoconf.NewClient()
if err != nil {
// handle error
}
// Get cached config or fallback (no network)
config := client.GetCached()
// Get latest within refresh interval, with fallbacks
config := client.GetCachedOrRefresh(ctx)
Configuration Options ¶
The client can be customized with various options:
client, err := autoconf.NewClient(
autoconf.WithURL("https://conf.ipfs-mainnet.org/autoconf.json"),
autoconf.WithRefreshInterval(24*time.Hour),
autoconf.WithCacheDir("/path/to/cache"),
autoconf.WithUserAgent("my-app/1.0"),
autoconf.WithFallback(autoconf.GetMainnetFallbackConfig), // Explicit fallback
// Optional callbacks for background refresh checks
autoconf.WithOnNewVersion(func(oldVer, newVer int64, url string) {
log.Printf("Config updated from v%d to v%d at %s", oldVer, newVer, url)
}),
autoconf.WithOnRefresh(func(resp *autoconf.Response) {
log.Printf("Config refreshed: v%s", resp.Version)
}),
autoconf.WithOnRefreshError(func(err error) {
log.Printf("Refresh failed: %v", err)
}),
)
Method Overview ¶
The client provides three main methods for retrieving configuration:
- GetCached(): Returns cached config or fallback, never makes network requests
- GetCachedOrRefresh(ctx): Returns latest config if stale, falls back to cache/default
- GetLatest(ctx): Explicitly fetches from network, returns error for handling
Background Updates ¶
For long-running applications, use Start to prime cache and start background updater:
config, err := client.Start(ctx)
if err != nil {
// handle error
}
// config is immediately available for use
// The updater can be stopped in two ways:
// 1. Cancel the context passed to Start() (automatic)
// 2. Call client.Stop() explicitly (manual)
defer client.Stop() // Optional: explicit shutdown
This primes the cache with the latest config and starts a background service that periodically checks for updates. If no callbacks were configured via WithOnNewVersion, WithOnRefresh, or WithOnRefreshError, default callbacks will be used for logging.
Config Expansion ¶
The package also provides utilities to expand "auto" placeholders in configuration:
// Expand bootstrap peers peers := autoconf.ExpandBootstrapPeers(configPeers, autoConfData, nativeSystems) // Expand DNS resolvers resolvers := autoconf.ExpandDNSResolvers(configResolvers, autoConfData) // Expand delegated endpoints endpoints := autoconf.ExpandDelegatedEndpoints(configEndpoints, autoConfData, nativeSystems)
Index ¶
- Constants
- Variables
- func ExpandBootstrapPeers(configPeers []string, autoConf *Config, nativeSystems []string) []string
- func ExpandDNSResolvers(configResolvers map[string]string, autoConf *Config) map[string]string
- func ExpandDelegatedEndpoints(configEndpoints []string, autoConf *Config, nativeSystems []string, ...) []string
- func GroupByKnownCapabilities(endpoints []string, supportsRead, supportsWrite bool) (map[string]EndpointCapabilities, error)
- type Client
- type Config
- func (c *Config) DelegatedEndpointsForRead(ignoredNativeSystems ...string) map[string]EndpointConfig
- func (c *Config) DelegatedEndpointsForWrite(ignoredNativeSystems ...string) map[string]EndpointConfig
- func (c *Config) GetBootstrapPeers(nativeSystems ...string) []string
- func (c *Config) GetDNSResolvers() map[string][]string
- func (c *Config) GetDelegatedEndpoints(ignoredNativeSystems ...string) map[string]EndpointConfig
- func (c *Config) WithSupportedPathsOnly(supportedPaths ...string) *Config
- type DelegatedConfig
- type DelegatedRoutingEndpoint
- type EndpointCapabilities
- type EndpointConfig
- type NativeConfig
- type Option
- func WithCacheDir(dir string) Option
- func WithCacheSize(size int) Option
- func WithFallback(fallbackFunc func() *Config) Option
- func WithHTTPClient(client *http.Client) Option
- func WithOnNewVersion(callback func(oldVersion, newVersion int64, configURL string)) Option
- func WithOnRefresh(callback func(*Response)) Option
- func WithOnRefreshError(callback func(error)) Option
- func WithRefreshInterval(interval time.Duration) Option
- func WithTLSInsecureSkipVerify(skip bool) Option
- func WithTimeout(timeout time.Duration) Option
- func WithURL(url string) Option
- func WithUserAgent(ua string) Option
- type Response
- type SystemConfig
Constants ¶
const ( // DefaultTimeout is the default HTTP timeout for autoconf requests. // This timeout balances responsiveness with reliability for most network conditions. DefaultTimeout = 5 * time.Second // DefaultCacheSize is the default number of cached autoconf versions to keep. // Keeping multiple versions provides resilience against corrupted cache files // and allows for safe rollback during updates. DefaultCacheSize = 3 // DefaultRefreshInterval is the default interval for refreshing autoconf data. // This interval strikes a balance between staying up-to-date with network changes // and avoiding excessive HTTP requests to the autoconf server. Most IPFS nodes // can operate effectively with daily configuration refreshes. DefaultRefreshInterval = 24 * time.Hour // MainnetAutoConfURL is the default URL for fetching autoconf for the IPFS Mainnet. // See https://docs.ipfs.tech/concepts/glossary/#mainnet for more information about IPFS Mainnet. MainnetAutoConfURL = "https://conf.ipfs-mainnet.org/autoconf.json" )
const ( RoutingV1ProvidersPath = "/routing/v1/providers" RoutingV1PeersPath = "/routing/v1/peers" RoutingV1IPNSPath = "/routing/v1/ipns" )
Routing path constants (with leading slash for proper URL construction)
const ( SystemAminoDHT = "AminoDHT" SystemIPNI = "IPNI" )
System constants for routing behavior classification
const AutoPlaceholder = "auto"
AutoPlaceholder is the string used as a placeholder for autoconf values
const ( // SupportedAutoConfSchema is the schema version this client supports // This matches the current mainnet autoconf.json schema version SupportedAutoConfSchema = 1 )
Schema version constants
Variables ¶
var ( // FallbackBootstrapPeers are the default bootstrap peers from Kubo 0.36 // Used as last-resort fallback when autoconf fetch fails FallbackBootstrapPeers = []string{ "/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN", "/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa", "/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb", "/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt", "/dnsaddr/va1.bootstrap.libp2p.io/p2p/12D3KooWKnDdG3iXw9eTFijk3EWSunZcFi54Zka4wmtqtt6rPxc8", "/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", "/ip4/104.131.131.82/udp/4001/quic-v1/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", } // FallbackDNSResolvers are the default DNS resolvers matching mainnet autoconf // Used as last-resort fallback when autoconf fetch fails // Only "eth." has explicit fallbacks - no "." (root domain) fallback is intentional // to ensure users' OS DNS resolver is used by default, allowing browser clients // to make their own DoH decisions based on privacy preferences FallbackDNSResolvers = map[string][]string{ "eth.": { "https://dns.eth.limo/dns-query", "https://dns.eth.link/dns-query", }, } )
Fallback defaults matching Kubo 0.36 These are used as last-resort fallback when autoconf fetch fails and no cache exists
Functions ¶
func ExpandBootstrapPeers ¶
ExpandBootstrapPeers expands bootstrap peers with "auto" values replaced by autoconf values.
Parameters:
- configPeers: The user's configured bootstrap peers list, may contain "auto" placeholders to be expanded
- autoConf: The autoconf.json configuration fetched from network; nil disables expansion
- nativeSystems: List of systems to run natively (e.g., ["AminoDHT"]); used to select appropriate bootstrap peers for those native systems
Returns expanded list of bootstrap peer multiaddrs with "auto" replaced by peers from native systems.
func ExpandDNSResolvers ¶
ExpandDNSResolvers expands DNS resolvers with "auto" values replaced by autoconf values.
Parameters:
- configResolvers: Map of domain patterns to DNS resolver URLs (e.g., {"eth.": "auto", ".": "https://dns.google/dns-query"}); values can be "auto" to use autoconf-provided resolvers
- autoConf: The autoconf.json configuration containing DNS resolver mappings; nil disables expansion
Returns map of domains to DNS-over-HTTPS resolver URLs with "auto" expanded. When wildcard domain "." is set to "auto", all autoconf resolvers are added.
func ExpandDelegatedEndpoints ¶
func ExpandDelegatedEndpoints(configEndpoints []string, autoConf *Config, nativeSystems []string, supportedPaths ...string) []string
ExpandDelegatedEndpoints expands delegated endpoints with "auto" values replaced by autoconf values.
Parameters:
- configEndpoints: The user's configured endpoints list, may contain "auto" placeholders to be expanded
- autoConf: The autoconf.json configuration fetched from network; nil disables expansion
- nativeSystems: List of systems to run natively (e.g., ["AminoDHT"]); these systems are excluded from delegated endpoints to avoid duplication
- supportedPaths: Optional filter for which routing paths to include (e.g., "/routing/v1/providers"); if empty, all paths are included
Returns expanded list of endpoint URLs with "auto" replaced by filtered autoconf endpoints. Endpoints are filtered to exclude those overlapping with native systems and unsupported paths.
func GroupByKnownCapabilities ¶
func GroupByKnownCapabilities(endpoints []string, supportsRead, supportsWrite bool) (map[string]EndpointCapabilities, error)
GroupByKnownCapabilities processes a list of endpoint URLs and groups them by base URL, merging capabilities for endpoints that share the same base URL. This is useful when multiple path-specific URLs point to the same server.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client fetches, caches, and manages AutoConf configurations from HTTP endpoints.
The client implements intelligent caching with HTTP conditional requests (ETags/Last-Modified), version-based storage, and graceful fallback to cached data when remote servers are unreachable. Multiple configuration versions are kept locally to ensure reliability during network issues.
Key features:
- HTTP conditional requests to minimize bandwidth
- Version-based caching with automatic cleanup
- Thread-safe operations with concurrent read support
- Graceful fallback to cached data when networks fail
- Hostname-based cache separation for multiple URLs
func (*Client) GetCached ¶
GetCached returns config from cache or fallback without any network I/O.
This method guarantees no network operations will be performed, making it safe to call from any context where network access should be avoided. It only uses locally cached data or the configured fallback. It follows this priority order:
1. Return cached config if available (regardless of age) 2. Use configured fallback function (defaults to mainnet fallback)
This method is essential for preventing network blocking during config reads, especially in scenarios where autoconf is enabled but network access should be avoided (e.g., config validation, offline node construction).
func (*Client) GetCachedOrRefresh ¶
GetCachedOrRefresh fetches the latest config from network with fallback handling.
This method will attempt to fetch fresh config from the network, respecting the refreshInterval for cache freshness. If network fetch fails, it falls back to: 1. Cached config (even if stale) 2. Configured fallback function (defaults to mainnet fallback)
This method may block on network I/O and should be used when network operations are acceptable. For config reads that must avoid network I/O, use GetCached.
func (*Client) GetLatest ¶
GetLatest fetches the latest config with metadata, using cache when possible. This is the public API method that returns errors for proper error handling.
func (*Client) HasCachedConfig ¶
HasCachedConfig checks if there's a cached config available.
This method performs a quick filesystem check to determine if cached autoconf data exists. It does not validate the cached data or check if it's fresh - it only verifies that cache files are present and readable.
Returns:
- true: if cached config files exist and are accessible
- false: if no cache exists, cache is unreadable, or any error occurs
This method is useful for determining whether to perform cache priming or for conditional logic that depends on cache availability.
func (*Client) Start ¶
Start primes the cache with the latest config and starts a background updater. It returns the primed config for immediate use. The updater can be stopped either by cancelling the context or calling Stop(). If no callbacks were configured via WithOnNewVersion, WithOnRefresh, or WithOnRefreshError, default callbacks will be used for logging. Returns an error if the updater is already running.
type Config ¶
type Config struct {
AutoConfVersion int64 `json:"AutoConfVersion"`
AutoConfSchema int `json:"AutoConfSchema"`
// AutoConfTTL specifies the server-recommended cache TTL in seconds.
// The effective refresh interval will be the minimum of this value and the user-configured RefreshInterval.
// If AutoConfTTL is 0 or negative, only the user RefreshInterval is used.
// This allows servers to specify shorter cache periods during network transitions or configuration updates.
AutoConfTTL int `json:"AutoConfTTL"`
// SystemRegistry catalogs known routing systems and their supported operations.
// Each system defines what delegated routing paths it supports and may include
// native configuration like bootstrap peers for systems that run locally.
SystemRegistry map[string]SystemConfig `json:"SystemRegistry"`
// DNSResolvers maps DNS domains to their DoH (DNS-over-HTTPS) resolver URLs.
// Used for resolving non-ICANN TLDs or forcing all DNSLink resolution over specific DoH endpoint (in private swarms).
DNSResolvers map[string][]string `json:"DNSResolvers"`
// DelegatedEndpoints maps HTTP base URLs to their supported operations and protocols.
// Each server can support multiple endpoints, and while /routing/v1 is the most popular,
// other protocols can be added and communicated this way, and may not be specific to routing
// but serve other purposes. The Systems field indicates which entries from SystemRegistry use this endpoint.
DelegatedEndpoints map[string]EndpointConfig `json:"DelegatedEndpoints"`
}
Config represents the full autoconf.json structure that defines network configuration for IPFS nodes.
The configuration defines three main components:
- SystemRegistry: Catalogs of known routing systems and their capabilities
- DelegatedEndpoints: HTTP endpoints that implement specific routing operations
- DNSResolvers: DNS-over-HTTPS resolvers for .eth and other domains
Key relationship: SystemRegistry lists what operations each system supports (via DelegatedConfig), while DelegatedEndpoints maps HTTP base URLs to the actual routing paths they serve. A single HTTP endpoint in DelegatedEndpoints can serve multiple systems, or a system can use endpoints from multiple HTTP servers.
func GetMainnetFallbackConfig ¶
func GetMainnetFallbackConfig() *Config
GetMainnetFallbackConfig returns a complete fallback config matching current mainnet values This mirrors https://conf.ipfs-mainnet.org/autoconf.json exactly
func (*Config) DelegatedEndpointsForRead ¶
func (c *Config) DelegatedEndpointsForRead(ignoredNativeSystems ...string) map[string]EndpointConfig
DelegatedEndpointsForRead returns delegated endpoints configured for read operations, filtering out those that overlap with native systems
func (*Config) DelegatedEndpointsForWrite ¶
func (c *Config) DelegatedEndpointsForWrite(ignoredNativeSystems ...string) map[string]EndpointConfig
DelegatedEndpointsForWrite returns delegated endpoints configured for write operations, filtering out those that overlap with native systems
func (*Config) GetBootstrapPeers ¶
GetBootstrapPeers returns deduplicated bootstrap peers from the specified native systems
func (*Config) GetDNSResolvers ¶
GetDNSResolvers returns the DNS resolvers map
func (*Config) GetDelegatedEndpoints ¶
func (c *Config) GetDelegatedEndpoints(ignoredNativeSystems ...string) map[string]EndpointConfig
GetDelegatedEndpoints returns endpoints that don't overlap with the specified native systems
func (*Config) WithSupportedPathsOnly ¶
WithSupportedPathsOnly returns a new Config with DelegatedEndpoints filtered to only include endpoints that have at least one path matching the supported paths list. This allows applications to filter endpoints based on their specific needs.
type DelegatedConfig ¶
type DelegatedConfig struct {
Read []string `json:"Read"` // HTTP paths for read operations (e.g., ["/routing/v1/providers", "/routing/v1/peers"])
Write []string `json:"Write"` // HTTP paths for write operations (e.g., ["/routing/v1/ipns"])
}
DelegatedConfig specifies which HTTP routing operations a system supports when delegated. These paths define the system's capabilities and must be implemented by endpoints in DelegatedEndpoints.
type DelegatedRoutingEndpoint ¶
type DelegatedRoutingEndpoint struct {
BaseURL string // Base URL without path (e.g., "https://example.com")
Capabilities EndpointCapabilities // What operations this endpoint supports
}
DelegatedRoutingEndpoint represents a parsed routing endpoint with its capabilities
func DetermineKnownCapabilities ¶
func DetermineKnownCapabilities(endpoint string, supportsRead, supportsWrite bool) (*DelegatedRoutingEndpoint, error)
DetermineKnownCapabilities parses a routing URL and determines its capabilities It accepts both base URLs and URLs with specific routing paths:
- https://example.com → all operations
- https://example.com/routing/v1/providers → only provider lookups
- https://example.com/routing/v1/peers → only peer lookups
- https://example.com/routing/v1/ipns → only IPNS operations
The supportsRead and supportsWrite parameters indicate whether the endpoint should be used for read operations (GET) and/or write operations (PUT).
type EndpointCapabilities ¶
type EndpointCapabilities struct {
Providers bool // GET /routing/v1/providers
Peers bool // GET /routing/v1/peers
IPNSGet bool // GET /routing/v1/ipns (IPNS resolution)
IPNSPut bool // PUT /routing/v1/ipns (IPNS publishing)
}
EndpointCapabilities represents which routing operations are supported by an endpoint
func (EndpointCapabilities) IsEmpty ¶
func (ec EndpointCapabilities) IsEmpty() bool
IsEmpty returns true if no capabilities are enabled
func (*EndpointCapabilities) Merge ¶
func (ec *EndpointCapabilities) Merge(other EndpointCapabilities)
Merge combines capabilities from another EndpointCapabilities
type EndpointConfig ¶
type EndpointConfig struct {
Systems []string `json:"Systems"` // Names of systems from SystemRegistry that use this endpoint
Read []string `json:"Read"` // HTTP paths this endpoint supports for read operations
Write []string `json:"Write"` // HTTP paths this endpoint supports for write operations
}
EndpointConfig describes an HTTP endpoint that implements delegated operations. The key relationship: Systems lists which SystemRegistry entries use this endpoint, while Read/Write list the actual HTTP paths this endpoint serves.
Read and Write endpoints can be a subset of endpoints defined in SystemRegistry, meaning HTTP endpoints may only support a subset of features that a system offers.
Example: An endpoint at "https://delegated-ipfs.dev" might serve operations for both "IPNI" and "CustomIPNS" systems, implementing paths like "/routing/v1/providers" and "/routing/v1/ipns".
type NativeConfig ¶
type NativeConfig struct {
Bootstrap []string `json:"Bootstrap"` // Bootstrap peer multiaddrs for connecting to this system
}
NativeConfig contains settings for running a routing system locally on the node.
type Option ¶
Option is a function that configures the client
func WithCacheSize ¶
WithCacheSize sets the maximum number of versions to keep in cache
func WithFallback ¶
WithFallback sets a fallback function that returns config when fetch fails
func WithHTTPClient ¶
WithHTTPClient sets a custom HTTP client
func WithOnNewVersion ¶
WithOnNewVersion sets a callback for when a new config version is detected during background refresh. The callback receives the old version, new version, and the config URL that was used. This is useful for logging or triggering application restarts when configuration changes.
func WithOnRefresh ¶
WithOnRefresh sets a callback for successful background refresh checks. The callback receives the Response containing the refreshed config and metadata. This is useful for persisting metadata or triggering dependent operations.
func WithOnRefreshError ¶
WithOnRefreshError sets a callback for background refresh errors. The callback receives the error that occurred during the refresh attempt. This is useful for custom error handling, alerting, or fallback strategies.
func WithRefreshInterval ¶
WithRefreshInterval sets the refresh interval for autoconf data
func WithTLSInsecureSkipVerify ¶
WithTLSInsecureSkipVerify sets whether to skip TLS verification (for testing)
func WithTimeout ¶
WithTimeout sets the HTTP client timeout
func WithURL ¶
WithURL adds an autoconf URL to the client. Can be called multiple times to add multiple URLs for load balancing.
func WithUserAgent ¶
WithUserAgent sets the user agent for HTTP requests
type Response ¶
type Response struct {
Config *Config
FetchTime time.Time
Version string // AutoConfVersion as string, or ETag, or Last-Modified
CacheAge time.Duration // non-zero when response is from cache
}
Response contains the config and metadata from the fetch
type SystemConfig ¶
type SystemConfig struct {
URL string `json:"URL"` // Documentation URL for this system
Description string `json:"Description"` // Human-readable description
// NativeConfig contains bootstrap peers and other settings for running this system locally.
// Present when the system can/should run natively on the node (e.g., AminoDHT).
NativeConfig *NativeConfig `json:"NativeConfig,omitempty"`
// DelegatedConfig lists the HTTP routing paths this system supports when used through delegation.
// These paths correspond to entries that should exist in DelegatedEndpoints.
DelegatedConfig *DelegatedConfig `json:"DelegatedConfig,omitempty"`
}
SystemConfig represents configuration for a routing system like AminoDHT or IPNI. Systems can operate natively (with local bootstrap peers) and/or through delegated HTTP endpoints.