Language
Docs

Documentation

Contributors: bobinstein
Last Updated:

Fetching Data with ARIO Wayfinder

ARIO Wayfinder is a protocol that provides decentralized, cryptographically verified access to data stored on Arweave via the AR.IO Network. It automatically selects the best gateway for each request and ensures data integrity.

Overview

Wayfinder solves the challenge of reliable data access on the permaweb by providing:

  • Intelligent Routing: Automatically selects the best gateway based on performance and availability
  • Data Verification: Cryptographically verifies data integrity
  • Decentralized Access: Distributes requests across multiple AR.IO gateways
  • Seamless Integration: Works behind the scenes for fast, reliable access

Advantages:

  • Production-grade reliability
  • Automatic gateway selection
  • Built-in data verification
  • Performance monitoring
  • Developer-friendly APIs

Use cases:

  • Production applications
  • When you need guaranteed data integrity
  • Applications requiring high availability
  • Building robust decentralized applications

Installation

Core Library (JavaScript/TypeScript)

npm install @ar.io/wayfinder-core
# or
yarn add @ar.io/wayfinder-core

React Integration

npm install @ar.io/wayfinder-react @ar.io/wayfinder-core
# or
yarn add @ar.io/wayfinder-react @ar.io/wayfinder-core

Basic Usage

JavaScript/TypeScript

import { Wayfinder, NetworkGatewaysProvider } from "@ar.io/wayfinder-core";
import { ARIO } from "@ar.io/sdk";

// Initialize Wayfinder with default settings
const wayfinder = new Wayfinder({
  gatewaysProvider: new NetworkGatewaysProvider({ ario: ARIO.mainnet() }),
});

// Replace with your transaction ID
const txId = "sHqUBKFeS42-CMCvNqPR31yEP63qSJG3ImshfwzJJF8";

(async () => {
  try {
    const response = await wayfinder.request(`ar://${txId}`);
    const data = await response.text();
    console.log("Data:", data);
  } catch (error) {
    console.error("Failed to fetch data:", error);
  }
})();

React Integration

import { WayfinderProvider, useWayfinderRequest } from "@ar.io/wayfinder-react";
import { NetworkGatewaysProvider } from "@ar.io/wayfinder-core";
import { ARIO } from "@ar.io/sdk";

function App() {
  return (
    <WayfinderProvider
      gatewaysProvider={new NetworkGatewaysProvider({ ario: ARIO.mainnet() })}
    >
      <MyComponent />
    </WayfinderProvider>
  );
}

function MyComponent() {
  const request = useWayfinderRequest();
  const txId = "sHqUBKFeS42-CMCvNqPR31yEP63qSJG3ImshfwzJJF8";
  const [data, setData] = React.useState(null);

  React.useEffect(() => {
    (async () => {
      try {
        const response = await request(`ar://${txId}`);
        setData(await response.text());
      } catch (e) {
        setData("Error: " + e.message);
      }
    })();
  }, [request, txId]);

  return <pre>{data}</pre>;
}

Advanced Configuration

Custom Gateway Providers

import {
  Wayfinder,
  NetworkGatewaysProvider,
  StaticGatewaysProvider,
  SimpleCacheGatewaysProvider,
} from "@ar.io/wayfinder-core";
import { ARIO } from "@ar.io/sdk";

// Use a predefined list of gateways
const staticGateways = new StaticGatewaysProvider({
  gateways: [
    "https://arweave.net",
    "https://permagate.io",
    "https://g8way.io",
  ],
});

// Cache gateway lists for performance
const cachedGateways = new SimpleCacheGatewaysProvider({
  gatewaysProvider: new NetworkGatewaysProvider({ ario: ARIO.mainnet() }),
});

const wayfinder = new Wayfinder({
  gatewaysProvider: cachedGateways,
});

Routing Strategies

import {
  FastestPingRoutingStrategy,
  PreferredWithFallbackRoutingStrategy,
  RoundRobinRoutingStrategy,
  RandomRoutingStrategy,
} from "@ar.io/wayfinder-core";

// Fastest ping (recommended for performance)
const wayfinder = new Wayfinder({
  gatewaysProvider: new NetworkGatewaysProvider({ ario: ARIO.mainnet() }),
  routingSettings: {
    strategy: new FastestPingRoutingStrategy({ timeoutMs: 500 }),
  },
});

// Preferred gateway with fallback
const wayfinder = new Wayfinder({
  gatewaysProvider: new NetworkGatewaysProvider({ ario: ARIO.mainnet() }),
  routingSettings: {
    strategy: new PreferredWithFallbackRoutingStrategy({
      preferredGateways: ["https://arweave.net"],
    }),
  },
});

// Round-robin for load balancing
const wayfinder = new Wayfinder({
  gatewaysProvider: new NetworkGatewaysProvider({ ario: ARIO.mainnet() }),
  routingSettings: {
    strategy: new RoundRobinRoutingStrategy(),
  },
});

Verification Settings

import {
  HashVerificationStrategy,
  SignatureVerificationStrategy,
  DataRootVerificationStrategy,
} from "@ar.io/wayfinder-core";

const wayfinder = new Wayfinder({
  gatewaysProvider: new NetworkGatewaysProvider({ ario: ARIO.mainnet() }),
  verificationSettings: {
    enabled: true,
    strategy: new HashVerificationStrategy({
      trustedGateways: ["https://arweave.net"],
    }),
    events: {
      onVerificationSucceeded: (event) => {
        console.log("Verification passed for:", event.txId);
      },
      onVerificationFailed: (event) => {
        console.log("Verification failed for:", event.txId);
      },
    },
  },
});

Telemetry and Monitoring

const wayfinder = new Wayfinder({
  gatewaysProvider: new NetworkGatewaysProvider({ ario: ARIO.mainnet() }),
  telemetrySettings: {
    enabled: true,
    clientName: "my-app",
    clientVersion: "1.0.0",
    sampleRate: 0.1, // 10% sampling
  },
  routingSettings: {
    events: {
      onRoutingSucceeded: (event) => {
        console.log("Selected gateway:", event.selectedGateway);
      },
      onRoutingFailed: (event) => {
        console.log("Routing failed:", event.error);
      },
    },
  },
});

Working with Different Data Types

JSON Data

const response = await wayfinder.request(`ar://${txId}`);
const contentType = response.headers.get("content-type");

if (contentType.includes("application/json")) {
  const data = await response.json();
  console.log("JSON data:", data);
} else {
  const data = await response.text();
  console.log("Text data:", data);
}

Binary Data

const response = await wayfinder.request(`ar://${txId}`);
const data = await response.arrayBuffer();
console.log("Binary data size:", data.byteLength);

Streaming Large Files

const response = await wayfinder.request(`ar://${txId}`);
const reader = response.body.getReader();
const chunks = [];

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  chunks.push(value);
}

const data = new Uint8Array(
  chunks.reduce((acc, chunk) => acc + chunk.length, 0)
);
let offset = 0;
for (const chunk of chunks) {
  data.set(chunk, offset);
  offset += chunk.length;
}

Error Handling

Basic Error Handling

async function fetchWithWayfinder(txId) {
  try {
    const response = await wayfinder.request(`ar://${txId}`);

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const data = await response.text();
    return data;
  } catch (error) {
    console.error("Failed to fetch data:", error);
    throw error;
  }
}

Retry Logic

async function fetchWithRetry(txId, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const response = await wayfinder.request(`ar://${txId}`);
      return await response.text();
    } catch (error) {
      console.log(`Attempt ${attempt} failed:`, error.message);

      if (attempt === maxRetries) {
        throw new Error(
          `Failed to fetch transaction after ${maxRetries} attempts`
        );
      }

      // Wait before retrying
      await new Promise((resolve) =>
        setTimeout(resolve, Math.pow(2, attempt) * 1000)
      );
    }
  }
}

Best Practices

Performance

  • Use appropriate timeout values for your use case
  • Implement caching for frequently accessed data
  • Monitor telemetry data to optimize performance

Reliability

  • Enable data verification for critical applications
  • Use multiple gateway providers for redundancy
  • Implement proper error handling and retry logic

Security

  • Always verify data integrity for sensitive content
  • Use trusted gateway lists when possible
  • Monitor verification events for anomalies

Troubleshooting

Common Issues

Gateway selection failures:

// Check if gateways are available
const gateways = await wayfinder.gatewaysProvider.getGateways();
console.log("Available gateways:", gateways.length);

// Use fallback routing strategy
const wayfinder = new Wayfinder({
  gatewaysProvider: new NetworkGatewaysProvider({ ario: ARIO.mainnet() }),
  routingSettings: {
    strategy: new PreferredWithFallbackRoutingStrategy({
      preferredGateways: ["https://arweave.net"],
    }),
  },
});

Verification failures:

// Disable verification temporarily for debugging
const wayfinder = new Wayfinder({
  gatewaysProvider: new NetworkGatewaysProvider({ ario: ARIO.mainnet() }),
  verificationSettings: {
    enabled: false,
  },
});

Resources