WebSocket Streaming

Monitor order events in real-time with WebSocket connections. The Aori SDK provides powerful tools to subscribe to order updates, filter events, and handle real-time data streams.


WebSocket Event Types

WebSocket events provide real-time updates about order lifecycle changes. Each event contains specific data relevant to that stage of execution.

created

Order has been created
{
  "eventType": "created",
  "timestamp": 1703001600,
  "order": {
    "orderHash": "0x1234...",
    "offerer": "0x742d...",
    "inputToken": "0x4200...",
    "outputToken": "0xaf88...",
    "inputAmount": "1000000000000000000",
    "outputAmount": "3200000000",
    "inputChain": "ethereum",
    "outputChain": "base",
    "startTime": 1703001600,
    "endTime": 1703005200,
    "srcTx": "",
    "dstTx": ""
  }
}

received

Order received on source chain
{
  "eventType": "received",
  "timestamp": 1703001650,
  "order": {
    "orderHash": "0x1234...",
    "offerer": "0x742d...",
    "recipient": "0x742d...",
    "inputToken": "0x4200...",
    "inputAmount": "1000000000000000000",
    "inputChain": "ethereum",
    "outputToken": "0xaf88...",
    "outputAmount": "3200000000",
    "outputChain": "base",
    "startTime": 1703001600,
    "endTime": 1703005200,
    "srcTx": "0xabc123...",
    "dstTx": ""
  }
}

completed

Order successfully executed
{
  "eventType": "completed",
  "timestamp": 1703001780,
  "order": {
    "orderHash": "0x1234...",
    "offerer": "0x742d...",
    "recipient": "0x742d...",
    "inputToken": "0x4200...",
    "inputAmount": "1000000000000000000",
    "inputChain": "ethereum",
    "outputToken": "0xaf88...",
    "outputAmount": "3200000000",
    "outputChain": "base",
    "startTime": 1703001600,
    "endTime": 1703005200,
    "srcTx": "0xabc123...",
    "dstTx": "0xdef456..."
  }
}

failed

Order execution failed
{
  "eventType": "failed",
  "timestamp": 1703001720,
  "order": {
    "orderHash": "0x1234...",
    "offerer": "0x742d...",
    "recipient": "0x742d...",
    "inputToken": "0x4200...",
    "inputAmount": "1000000000000000000",
    "inputChain": "ethereum",
    "outputToken": "0xaf88...",
    "outputAmount": "3200000000",
    "outputChain": "base",
    "startTime": 1703001600,
    "endTime": 1703005200,
    "srcTx": "0xabc123...",
    "dstTx": ""
  }
}

WebSocket Type Definitions

enum WSEventType {
  Created = "created",
  Received = "received", 
  Completed = "completed",
  Failed = "failed"
}

interface WSEvent {
  eventType: WSEventType;
  timestamp: number;
  order: WSOrder;
}

interface WSOrder {
  orderHash: string;
  offerer: string;
  recipient: string;
  inputToken: string;
  inputAmount: string;
  inputChain: string;
  outputToken: string;
  outputAmount: string;
  outputChain: string;
  startTime: number;
  srcTx: string;
  dstTx: string;
  endTime: number;
}

WebSocket Connection

AoriWebSocket

The AoriWebSocket class provides a managed WebSocket connection to the Aori API for real-time order event streaming.

Basic WebSocket Usage

import { AoriWebSocket } from '@aori/aori-ts';

const ws = new AoriWebSocket('wss://api.aori.io/stream', {
  onMessage: (event) => {
    console.log('Order event:', event.eventType);
    console.log('Order hash:', event.order.orderHash);
  },
  onConnect: () => {
    console.log('WebSocket connected');
  },
  onDisconnect: (event) => {
    console.log('WebSocket disconnected');
  },
  onError: (error) => {
    console.error('WebSocket error:', error);
  }
});

// Connect to the WebSocket
await ws.connect();

// Check connection status
console.log('Connected:', ws.isConnected());

// Disconnect when done
ws.disconnect();

Constructor Options

ParameterTypeDescription
baseUrlstringWebSocket endpoint URL (default: wss://api.aori.io/stream)
optionsWebSocketOptionsEvent handlers and configuration
apiKeystringOptional API key for authentication

WebSocketOptions

PropertyTypeDescription
onMessage(event: WSEvent) => voidCallback for incoming order events
onConnect() => voidCallback when connection is established
onDisconnect(event: CloseEvent) => voidCallback when connection is closed
onError(error: Event) => voidCallback for connection errors

Event Filtering

Currently, the WebSocket streams all order events. You can implement client-side filtering based on the event data:

Available Filter Parameters

ParameterTypeDescriptionExample
orderHashstringFilter by specific order hash0x1234567890abcdef...
offererstringFilter by order creator address0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b
recipientstringFilter by order recipient address0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b
inputTokenstringFilter by input token address0x4200000000000000000000000000000000000006
inputChainstringFilter by source chainethereum
outputTokenstringFilter by output token address0xaf88d065e77c8cc2239327c5edb3a432268e5831
outputChainstringFilter by destination chainbase
eventTypestringFilter by event typecreated, received, completed, failed

Common Filter Patterns

Client-Side Event Filtering

import { AoriWebSocket, WSEvent } from '@aori/aori-ts';

// Create a filtered event handler
function createFilteredHandler(filters: Partial<WSEvent['order']> & { eventType?: string }) {
  return (event: WSEvent) => {
    // Filter by event type
    if (filters.eventType && event.eventType !== filters.eventType) {
      return;
    }

    // Filter by order properties
    const order = event.order;
    if (filters.orderHash && order.orderHash !== filters.orderHash) return;
    if (filters.offerer && order.offerer !== filters.offerer) return;
    if (filters.recipient && order.recipient !== filters.recipient) return;
    if (filters.inputToken && order.inputToken !== filters.inputToken) return;
    if (filters.inputChain && order.inputChain !== filters.inputChain) return;
    if (filters.outputToken && order.outputToken !== filters.outputToken) return;
    if (filters.outputChain && order.outputChain !== filters.outputChain) return;

    // Event matches filters - process it
    console.log('Filtered event:', event);
  };
}

// Example: Track specific user's completed orders
const ws = new AoriWebSocket('wss://api.aori.io/stream', {
  onMessage: createFilteredHandler({
    offerer: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b',
    eventType: 'completed'
  })
});

await ws.connect();


Example

Production-Ready WebSocket Manager

class WebSocketManager {
  private ws: AoriWebSocket | null = null;
  private reconnectAttempts = 0;
  private maxReconnectAttempts = 5;
  private reconnectDelay = 1000;
  private reconnectTimeout: NodeJS.Timeout | null = null;

  async connect(url: string, onEvent: (event: WSEvent) => void, apiKey?: string) {
    try {
      this.ws = new AoriWebSocket(url, {
        onMessage: onEvent,
        onConnect: () => {
          console.log('WebSocket connected');
          this.reconnectAttempts = 0;
        },
        onDisconnect: () => {
          console.log('WebSocket disconnected');
          this.attemptReconnect(url, onEvent, apiKey);
        },
        onError: this.handleError.bind(this)
      }, apiKey);

      await this.ws.connect();
    } catch (error) {
      this.handleError(error as Event);
    }
  }

  private attemptReconnect(url: string, onEvent: (event: WSEvent) => void, apiKey?: string) {
    if (this.reconnectAttempts < this.maxReconnectAttempts) {
      this.reconnectAttempts++;
      const delay = this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1);
      
      this.reconnectTimeout = setTimeout(() => {
        console.log(`Reconnecting... (attempt ${this.reconnectAttempts})`);
        this.connect(url, onEvent, apiKey);
      }, delay);
    } else {
      console.error('Max reconnection attempts reached');
    }
  }

  private handleError(error: Event) {
    console.error('WebSocket error:', error);
  }

  disconnect() {
    if (this.reconnectTimeout) {
      clearTimeout(this.reconnectTimeout);
      this.reconnectTimeout = null;
    }
    
    if (this.ws) {
      this.ws.disconnect();
      this.ws = null;
    }
  }
}

// Usage
const manager = new WebSocketManager();
await manager.connect('wss://api.aori.io/stream', (event) => {
  console.log('Event received:', event);
}, 'your-api-key');

Best Practices

Connection Management

  • Reconnection Logic: Implement automatic reconnection with exponential backoff
  • Connection Limits: Avoid creating multiple connections for the same filters
  • Cleanup: Always close WebSocket connections when components unmount
  • Error Handling: Handle connection errors gracefully with user feedback

Performance Optimization

  • Efficient Filtering: Use specific filters to reduce unnecessary events
  • Event Batching: Consider batching rapid events for UI updates
  • Memory Management: Limit stored events to prevent memory leaks
  • Debouncing: Debounce UI updates for high-frequency events