StaticGatewaysProvider

Overview

The StaticGatewaysProvider uses a predefined list of gateway URLs, making it ideal for development, testing, or when you need to use specific trusted gateways. It provides fast, predictable gateway discovery without network calls.

Installation

npm install @ar.io/wayfinder-core

Basic Usage

import { StaticGatewaysProvider } from '@ar.io/wayfinder-core'

const provider = new StaticGatewaysProvider({
  gateways: [
    'https://arweave.net',
    'https://ar-io.net',
    'https://permagate.io',
  ],
})

const gateways = await provider.getGateways()
console.log('Available gateways:', gateways)

Configuration Options

StaticGatewaysProviderOptions

interface StaticGatewaysProviderOptions {
  gateways: string[]
  shuffle?: boolean
  healthCheck?: boolean
  healthCheckTimeout?: number
}

Parameters

← Swipe to see more →
ParameterTypeDefaultDescription
gatewaysstring[]RequiredArray of gateway URLs
shufflebooleanfalseRandomly shuffle gateway order
healthCheckbooleanfalsePerform health checks on gateways
healthCheckTimeoutnumber5000Health check timeout in milliseconds
← Swipe to see more →

Configuration Examples

Development Configuration

import { StaticGatewaysProvider } from '@ar.io/wayfinder-core'

// Development with local and fallback gateways
const provider = new StaticGatewaysProvider({
  gateways: [
    'http://localhost:3000', // Local development gateway
    'https://arweave.net', // Fallback to public gateway
    'https://ar-io.net', // Secondary fallback
  ],
})

Production Configuration

import { StaticGatewaysProvider } from '@ar.io/wayfinder-core'

// Production with trusted gateways and health checks
const provider = new StaticGatewaysProvider({
  gateways: [
    'https://my-trusted-gateway.com',
    'https://backup-gateway.com',
    'https://arweave.net',
  ],
  healthCheck: true,
  healthCheckTimeout: 3000,
})

Testing Configuration

import { StaticGatewaysProvider } from '@ar.io/wayfinder-core'

// Testing with mock gateways
const provider = new StaticGatewaysProvider({
  gateways: [
    'https://test-gateway-1.example.com',
    'https://test-gateway-2.example.com',
  ],
  shuffle: true, // Randomize for testing different scenarios
})

Advanced Usage

Environment-Based Configuration

import { StaticGatewaysProvider } from '@ar.io/wayfinder-core'

class EnvironmentStaticProvider extends StaticGatewaysProvider {
  constructor(options) {
    const environment =
      options.environment || process.env.NODE_ENV || 'development'
    const gateways =
      options.gateways ||
      EnvironmentStaticProvider.getDefaultGateways(environment)

    super({ ...options, gateways })
    this.environment = environment
  }

  static getDefaultGateways(environment) {
    const configs = {
      development: ['http://localhost:3000', 'https://arweave.net'],
      testing: ['https://test-gateway.example.com', 'https://arweave.net'],
      production: ['https://gateway.company.com', 'https://arweave.net'],
    }
    return configs[environment] || configs.development
  }
}

// Usage
const envProvider = new EnvironmentStaticProvider({
  environment: 'production',
  healthCheck: true,
})

Health-Checked Provider

import { StaticGatewaysProvider } from '@ar.io/wayfinder-core'

class HealthCheckedStaticProvider extends StaticGatewaysProvider {
  constructor(options) {
    super(options)
    this.healthyGateways = new Set()
    this.unhealthyGateways = new Set()

    if (options.healthCheck) {
      this.performHealthChecks()
    }
  }

  async getGateways() {
    const allGateways = await super.getGateways()

    if (!this.options.healthCheck) {
      return allGateways
    }

    // Return healthy gateways first
    const healthy = allGateways.filter((g) => this.healthyGateways.has(g))
    const unhealthy = allGateways.filter((g) => this.unhealthyGateways.has(g))

    return [...healthy, ...unhealthy]
  }

  async performHealthChecks() {
    const healthChecks = await Promise.allSettled(
      this.options.gateways.map((gateway) => this.checkGatewayHealth(gateway)),
    )

    healthChecks.forEach((result, index) => {
      const gateway = this.options.gateways[index]
      if (result.status === 'fulfilled' && result.value.healthy) {
        this.healthyGateways.add(gateway)
      } else {
        this.unhealthyGateways.add(gateway)
      }
    })
  }

  async checkGatewayHealth(gateway) {
    try {
      const response = await fetch(`${gateway}/ar-io/info`, {
        method: 'HEAD',
        signal: AbortSignal.timeout(this.options.healthCheckTimeout || 5000),
      })
      return { healthy: response.ok }
    } catch (error) {
      return { healthy: false, error: error.message }
    }
  }
}

Error Handling

import { StaticGatewaysProvider } from '@ar.io/wayfinder-core'

const provider = new StaticGatewaysProvider({
  gateways: ['https://gateway1.com', 'https://gateway2.com'],
})

try {
  const gateways = await provider.getGateways()
  console.log('Available gateways:', gateways)
} catch (error) {
  switch (error.constructor.name) {
    case 'InvalidConfigurationError':
      console.error('Invalid gateway configuration')
      break
    case 'HealthCheckError':
      console.error('Health check failed for all gateways')
      break
    default:
      console.error('Unknown error:', error.message)
  }
}

Testing

Unit Tests

import { StaticGatewaysProvider } from '@ar.io/wayfinder-core'

describe('StaticGatewaysProvider', () => {
  test('should return configured gateways', async () => {
    const gateways = ['https://gateway1.com', 'https://gateway2.com']
    const provider = new StaticGatewaysProvider({ gateways })
    const result = await provider.getGateways()

    expect(result).toEqual(gateways)
  })

  test('should handle empty gateway list', async () => {
    const provider = new StaticGatewaysProvider({ gateways: [] })
    const result = await provider.getGateways()

    expect(result).toEqual([])
  })

  test('should shuffle gateways when enabled', async () => {
    const gateways = [
      'https://gateway1.com',
      'https://gateway2.com',
      'https://gateway3.com',
    ]
    const provider = new StaticGatewaysProvider({ gateways, shuffle: true })
    const result = await provider.getGateways()

    expect(result).toHaveLength(gateways.length)
    expect(result).toEqual(expect.arrayContaining(gateways))
  })
})

Best Practices

  1. Use for Development and Testing: Static providers are perfect for predictable environments
  2. Include Fallback Gateways: Always include reliable public gateways as fallbacks
  3. Enable Health Checks for Production: Use health checks when reliability is critical
  4. Maintain Gateway Lists: Keep your static gateway lists up to date
  5. Use Environment-Specific Configs: Different gateway lists for different environments
  6. Validate URLs: Ensure all gateway URLs are valid and accessible

Comparison with Other Providers

← Swipe to see more →
FeatureStaticGatewaysProviderNetworkGatewaysProviderSimpleCacheGatewaysProvider
PerformanceHigh (no network calls)Medium (network calls)High (cached)
ReliabilityMedium (static data)High (real network data)High (cached + fallback)
MaintenanceHigh (manual updates)Low (automatic updates)Low (automatic + cached)
PredictabilityHigh (fixed list)Low (dynamic list)Medium (cached but updates)
Use CaseDevelopment/TestingProductionProduction (performance)
← Swipe to see more →

Was this page helpful?