autoconf

package
v0.35.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 6, 2025 License: Apache-2.0, MIT Imports: 18 Imported by: 4

README

AutoConf Library

This package provides a client library for fetching and caching IPFS autoconf.json files.

Features

  • HTTP Client: Configurable HTTP client with timeout, user-agent, and TLS options
  • Caching: Intelligent caching with ETag/Last-Modified support and version rotation
  • Version Management: Automatic cleanup of old cached versions
  • Path Safety: Sanitized cache directory structure based on URL hostname
  • Error Handling: Graceful fallback to cached versions when remote fetch fails

Usage

For most applications, use the "Must" methods that provide graceful fallbacks and never fail:

import "github.com/ipfs/boxo/autoconf"

// Create a client with default options (uses mainnet URL and fallback)
client, err := autoconf.NewClient()
if err != nil {
    // handle
}

// Cache-first approach: use cached config, no network requests
config := client.GetCached()

// Use the config data
nativelySupported := []string{"AminoDHT"}  // Systems your node runs locally (natively)
bootstrapPeers := config.GetBootstrapPeers(nativelySupported...) // Bootstrap every native system
delegatedEndpoints := config.GetDelegatedEndpoints(nativelySupported...) // Excludes native systems
dnsResolvers := config.GetDNSResolvers()

fmt.Printf("Bootstrap peers: %v\n", bootstrapPeers)
fmt.Printf("Delegated endpoints: %v\n", delegatedEndpoints)
fmt.Printf("DNS resolvers: %v\n", dnsResolvers)
// With refresh: attempt network update, fall back to cache or defaults
config := client.GetCachedOrRefresh(ctx)

// Access config the same way - guaranteed to never be nil
nativelySupported := []string{"AminoDHT"}  // Systems your node runs locally (natively)
bootstrapPeers := config.GetBootstrapPeers(nativelySupported...) // Bootstrap every native system
fmt.Printf("Bootstrap peers: %v\n", bootstrapPeers)
Fine-Grained Control

For applications that need explicit error handling and network control:

// Create client with custom 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.WithCacheSize(autoconf.DefaultCacheSize),
    autoconf.WithTimeout(autoconf.DefaultTimeout),
    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)
        // Trigger application restart or reload config
    }),
    autoconf.WithOnRefresh(func(resp *autoconf.Response) {
        log.Printf("Config refreshed: v%s at %s", resp.Version, resp.FetchTime)
        // Could persist metadata or trigger dependent operations
    }),
    autoconf.WithOnRefreshError(func(err error) {
        log.Printf("Refresh failed: %v", err)
        // Could send alert or switch to backup endpoint
    }),
)
if err != nil {
    // handle
}

// GetLatest returns errors for explicit handling
response, err := client.GetLatest(ctx)
if err != nil {
    // handle
    return err
}

// Access the config and metadata
config := response.Config
fmt.Printf("Config: %+v\n", config)
fmt.Printf("FetchTime: %v\n", response.FetchTime)
fmt.Printf("Version: %s\n", response.Version)
fmt.Printf("FromCache: %v\n", response.FromCache)
fmt.Printf("CacheAge: %v\n", response.CacheAge)

// Use all available getters
nativelySupported := []string{"AminoDHT"}  // Systems your node runs locally (natively)
bootstrapPeers := config.GetBootstrapPeers(nativelySupported...) // Bootstrap every native system
delegatedEndpoints := config.GetDelegatedEndpoints(nativelySupported...) // Excludes native systems
allEndpoints := config.GetDelegatedEndpoints() // All endpoints
dnsResolvers := config.GetDNSResolvers()

fmt.Printf("Bootstrap peers: %v\n", bootstrapPeers)
fmt.Printf("Delegated endpoints: %v\n", delegatedEndpoints)
fmt.Printf("All endpoints: %v\n", allEndpoints)
fmt.Printf("DNS resolvers: %v\n", dnsResolvers)
Integration with Applications

This library is designed to be integrated into applications that need autoconf functionality. The client is generic and does not depend on any specific application framework.

func main() {
    client, err := autoconf.NewClient(
        autoconf.WithCacheDir("/app/data/autoconf"),
        autoconf.WithUserAgent("myapp/1.2.3"),
        autoconf.WithTimeout(autoconf.DefaultTimeout),
    )
    if err != nil {
        // handle
    }

    // Use turn-key solution with refresh - never fails, always returns usable config
    config := client.MustGetConfigWithRefresh(context.Background(),
        autoconfURL,
        autoconf.DefaultRefreshInterval,
        autoconf.GetMainnetFallbackConfig)

    // Access all config types
    nativelySupported := []string{"AminoDHT"}  // Systems your node runs locally (natively)
    bootstrapPeers := config.GetBootstrapPeers(nativelySupported...) // Bootstrap every native system
    delegatedEndpoints := config.GetDelegatedEndpoints(nativelySupported...)
    dnsResolvers := config.GetDNSResolvers()

    fmt.Printf("Bootstrap peers: %v\n", bootstrapPeers)
    fmt.Printf("Delegated endpoints: %v\n", delegatedEndpoints)
    fmt.Printf("DNS resolvers: %v\n", dnsResolvers)
}
Background Updates

For long-running applications that need periodic config updates:

func runService(ctx context.Context) error {
    client, err := autoconf.NewClient(
        autoconf.WithCacheDir("/app/data/autoconf"),
        autoconf.WithUserAgent("myapp/1.2.3"),
        autoconf.WithRefreshInterval(12*time.Hour),
        
        // Custom callbacks for monitoring
        autoconf.WithOnNewVersion(func(oldVer, newVer int64, url string) {
            metrics.RecordConfigUpdate(oldVer, newVer)
            log.Infof("New config version %d available", newVer)
        }),
        autoconf.WithOnRefreshError(func(err error) {
            metrics.RecordConfigError()
            alerting.SendAlert("AutoConf refresh failed", err)
        }),
    )
    if err != nil {
        return err
    }

    // Start primes cache and starts background updater
    // Updater will stop automatically when ctx is cancelled
    config, err := client.Start(ctx)
    if err != nil {
        return err
    }
    
    // Use the config immediately
    bootstrapPeers := config.GetBootstrapPeers("AminoDHT")
    
    // Your service logic here...
    // When ctx is cancelled, the updater stops automatically
    return nil
}
func main() {
    client, err := autoconf.NewClient(
        autoconf.WithCacheDir("/app/data/autoconf"),
        autoconf.WithUserAgent("myapp/1.2.3"),
    )
    if err != nil {
        log.Fatal(err)
    }

    // Start with background context since we'll use Stop()
    config, err := client.Start(context.Background())
    if err != nil {
        log.Fatal(err)
    }
    
    // Ensure clean shutdown
    defer client.Stop()
    
    // Set up signal handling
    sigCh := make(chan os.Signal, 1)
    signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
    
    // Your application logic here...
    <-sigCh
    
    // Stop() will be called by defer, ensuring graceful shutdown
}

Both patterns are idiomatic in Go. Use context cancellation when integrating with existing service frameworks, and use Stop() when you need explicit control over the updater lifecycle.

Cache Structure

The cache is organized by hostname and version for efficient management:

$CACHE_DIR/
  autoconf/
    example.com/                    # Hostname-based directory
      autoconf-2025071801.json      # Versioned config files
      autoconf-2025071802.json      # Multiple versions kept for reliability
      .etag                         # HTTP ETag for conditional requests
      .last-modified                # HTTP Last-Modified for cache validation
      .last-refresh                 # Timestamp of last refresh attempt
    conf.ipfs-mainnet.org/
      autoconf-2025072301.json
      .etag
      .last-modified
      .last-refresh
  • Version-based files: Each AutoConfVersion gets its own JSON file
  • Metadata files: Store HTTP headers for efficient conditional requests
  • Automatic cleanup: Old versions are automatically removed (default: keep 3 versions)
  • Hostname separation: Multiple URLs cached independently

Configuration Options

Client Options
Basic Configuration
  • WithURL(url): Add an autoconf URL (can be called multiple times for load balancing)
  • WithRefreshInterval(duration): Set refresh interval for autoconf data (default: 24h)
  • WithCacheDir(dir): Set custom cache directory
  • WithCacheSize(n): Set maximum cached versions (default: 3)
  • WithFallback(func): Set fallback function that returns config when fetch fails
HTTP Configuration
  • WithHTTPClient(client): Use custom HTTP client
  • WithUserAgent(ua): Set HTTP user-agent
  • WithTimeout(duration): Set HTTP timeout (default: 5s)
  • WithTLSInsecureSkipVerify(bool): Skip TLS verification (for testing)
Background Refresh Callbacks
  • WithOnNewVersion(func(oldVersion, newVersion int64, configURL string)): Called when new config version is detected during refresh
  • WithOnRefresh(func(*Response)): Called after successful refresh with response metadata
  • WithOnRefreshError(func(error)): Called when refresh fails with the error

These callbacks are optional. If not provided, the client will use default callbacks that log to the configured logger.

Error Handling

The client implements graceful fallback:

  1. Try to fetch from remote URL
  2. If remote fails, fall back to latest cached version
  3. If no cache exists, fall back to configured fallback function

Note: GetLatest() returns errors for explicit handling, while GetCached() and GetCachedOrRefresh() never fail and always return usable configuration (using the fallback if necessary).

API Overview

Client Methods
  • NewClient(options...): Create configurable client with cache dir, timeouts, user-agent
  • GetCached(): Returns cached config or fallback, no network requests
  • GetCachedOrRefresh(ctx): Returns latest config if stale, falls back to cache/default
  • GetLatest(ctx): Explicitly fetches from network, returns error for handling
  • Start(ctx): Primes cache and starts background updater, returns initial config
  • Stop(): Gracefully stops the background updater (alternative to context cancellation)
Config Data Access Methods
  • GetBootstrapPeers(systems...): Extract bootstrap peers for specified systems
  • GetDelegatedEndpoints(ignoredSystems...): Get HTTP endpoints (optionally excluding native systems)
  • GetDNSResolvers(): Get all DNS-over-HTTPS resolver mappings

Testing

Run tests with:

go test .

License

This package is part of the boxo project and follows the same licensing terms.

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

View Source
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"
)
View Source
const (
	RoutingV1ProvidersPath = "/routing/v1/providers"
	RoutingV1PeersPath     = "/routing/v1/peers"
	RoutingV1IPNSPath      = "/routing/v1/ipns"
)

Routing path constants (with leading slash for proper URL construction)

View Source
const (
	SystemAminoDHT = "AminoDHT"
	SystemIPNI     = "IPNI"
)

System constants for routing behavior classification

View Source
const AutoPlaceholder = "auto"

AutoPlaceholder is the string used as a placeholder for autoconf values

View Source
const (
	// SupportedAutoConfSchema is the schema version this client supports
	// This matches the current mainnet autoconf.json schema version
	SupportedAutoConfSchema = 1
)

Schema version constants

Variables

View Source
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

func ExpandBootstrapPeers(configPeers []string, autoConf *Config, nativeSystems []string) []string

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

func ExpandDNSResolvers(configResolvers map[string]string, autoConf *Config) map[string]string

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 NewClient

func NewClient(options ...Option) (*Client, error)

NewClient creates a new autoconf client with the given options

func (*Client) GetCached

func (c *Client) GetCached() *Config

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

func (c *Client) GetCachedOrRefresh(ctx context.Context) *Config

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

func (c *Client) GetLatest(ctx context.Context) (*Response, error)

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

func (c *Client) HasCachedConfig() bool

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

func (c *Client) Start(ctx context.Context) (*Config, error)

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.

func (*Client) Stop

func (c *Client) Stop()

Stop gracefully stops the background updater if it's running. This is an alternative to cancelling the context passed to Start(). It's safe to call Stop() multiple times.

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

func (c *Config) GetBootstrapPeers(nativeSystems ...string) []string

GetBootstrapPeers returns deduplicated bootstrap peers from the specified native systems

func (*Config) GetDNSResolvers

func (c *Config) GetDNSResolvers() map[string][]string

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

func (c *Config) WithSupportedPathsOnly(supportedPaths ...string) *Config

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:

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

type Option func(*Client) error

Option is a function that configures the client

func WithCacheDir

func WithCacheDir(dir string) Option

WithCacheDir sets the cache directory

func WithCacheSize

func WithCacheSize(size int) Option

WithCacheSize sets the maximum number of versions to keep in cache

func WithFallback

func WithFallback(fallbackFunc func() *Config) Option

WithFallback sets a fallback function that returns config when fetch fails

func WithHTTPClient

func WithHTTPClient(client *http.Client) Option

WithHTTPClient sets a custom HTTP client

func WithOnNewVersion

func WithOnNewVersion(callback func(oldVersion, newVersion int64, configURL string)) Option

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

func WithOnRefresh(callback func(*Response)) Option

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

func WithOnRefreshError(callback func(error)) Option

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

func WithRefreshInterval(interval time.Duration) Option

WithRefreshInterval sets the refresh interval for autoconf data

func WithTLSInsecureSkipVerify

func WithTLSInsecureSkipVerify(skip bool) Option

WithTLSInsecureSkipVerify sets whether to skip TLS verification (for testing)

func WithTimeout

func WithTimeout(timeout time.Duration) Option

WithTimeout sets the HTTP client timeout

func WithURL

func WithURL(url string) Option

WithURL adds an autoconf URL to the client. Can be called multiple times to add multiple URLs for load balancing.

func WithUserAgent

func WithUserAgent(ua string) Option

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

func (*Response) FromCache

func (r *Response) FromCache() bool

FromCache returns true if the response was served from cache

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL