# Relayer WebSocket API

The XOXNO Relayer is a high-performance transaction co-signing and broadcast service for the MultiversX blockchain. It exposes a WebSocket API for real-time data subscriptions and transaction submission, and a REST API for batch operations.

**Core capabilities:**

* Co-sign transactions using shard-specific Ed25519 relayer keys (Relayer V3 pattern)
* Broadcast fully signed or co-signed transactions via P2P gossipsub directly to validators
* Stream real-time gas statistics, network state, account updates, and transaction status

***

## Connection Endpoints

| Endpoint                           | Purpose                                            |
| ---------------------------------- | -------------------------------------------------- |
| `wss://relayer.xoxno.com/ws`       | Full-duplex WebSocket: subscribe, relay, broadcast |
| `wss://relayer.xoxno.com/ws/stats` | Read-only network stats stream, pushed every 250ms |

All messages are JSON. The `/ws/stats` endpoint requires no authentication and delivers `networkStats` messages unconditionally — no subscribe action needed.

***

## Connection Limits

| Parameter                     | Value                  |
| ----------------------------- | ---------------------- |
| Max topics per connection     | 64                     |
| Rate limit (control messages) | 64 per 5-second window |
| Max message size              | 4 MB                   |
| Ping/pong heartbeat interval  | 30 seconds             |

{% hint style="warning" %}
Exceeding 64 control messages within a 5-second window will result in a rate-limit error. Subscribe and unsubscribe actions count against this limit.
{% endhint %}

***

## Supported Topics

| Topic              | Delivery                                   | Update Frequency |
| ------------------ | ------------------------------------------ | ---------------- |
| `gasStats`         | Broadcast to all subscribers               | Every 50ms       |
| `networkStats`     | Broadcast to all subscribers               | Every 250ms      |
| `accounts`         | Broadcast, global account updates          | Event-driven     |
| `address/{bech32}` | Unicast to the subscribing connection only | Event-driven     |
| `tx-status/{hash}` | Unicast, auto-expires after 60 seconds     | Event-driven     |

***

## Client Actions

| Action        | Description                                                                |
| ------------- | -------------------------------------------------------------------------- |
| `subscribe`   | Subscribe to a topic                                                       |
| `unsubscribe` | Unsubscribe from a topic                                                   |
| `relay`       | Co-sign a transaction using the shard-specific relayer key, then broadcast |
| `broadcast`   | Broadcast a pre-signed transaction (no co-signing)                         |

***

## Quick Start

The example below opens a connection, subscribes to gas statistics, and submits a relayed transaction.

```javascript
const ws = new WebSocket('wss://relayer.xoxno.com/ws');

ws.onopen = () => {
  // Subscribe to gas statistics for all shards
  ws.send(JSON.stringify({
    action: 'subscribe',
    topic: 'gasStats'
  }));

  // Submit a relayed (co-signed) transaction
  // The `relayer` field must match the shard-specific relayer address for the sender
  ws.send(JSON.stringify({
    action: 'relay',
    requestId: 'relay-001',
    tx: {
      nonce: 42,
      value: '0',
      receiver: 'erd1qqqqqqqqqqqqqpgq...',
      sender: 'erd1user...',
      gasPrice: 1000000000,
      gasLimit: 50000000,
      data: 'c3dhcA==',
      chainID: '1',
      version: 2,
      signature: 'user-hex-signature...',
      relayer: 'erd1l0x0n5yxsfcy93gm0vyvx9m9f7cte9h9vuq4am33ugpw3d5r3hvqx6f59h'
    }
  }));
};

ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);

  if (msg.type === 'gasStats') {
    console.log('Gas stats for shard', msg.data.shard, msg.data.gasPrice);
  }

  if (msg.action === 'relay' && msg.requestId === 'relay-001') {
    console.log('Relay result:', msg.status, msg.hashes);
  }
};

ws.onerror = (err) => console.error('WebSocket error:', err);
ws.onclose = () => console.log('Connection closed');
```

{% hint style="info" %}
Always include a unique `requestId` in relay and broadcast actions so you can correlate asynchronous responses when multiple requests are in-flight.
{% endhint %}

***

## REST Endpoints

| Method | Path                        | Description                            |
| ------ | --------------------------- | -------------------------------------- |
| `POST` | `/v1/sign`                  | Sign a batch of transactions           |
| `POST` | `/v1/broadcast`             | Broadcast pre-signed transactions      |
| `GET`  | `/v1/network-stats/history` | Retrieve historical network statistics |

***

## Documentation

* [Gas Statistics](https://docs.xoxno.com/developers/relayer-api/gas-stats) — Per-shard gas price and PPU streams
* [Network Statistics](https://github.com/XOXNO/docs/blob/main/developers/relayer-api/network-stats.md) — Full network state stream via `/ws/stats`
* [Account Subscriptions](https://docs.xoxno.com/developers/relayer-api/account-subscriptions) — Real-time balance and nonce updates
* [Transaction Broadcasting](https://docs.xoxno.com/developers/relayer-api/transaction-broadcasting) — Submit pre-signed transactions
* [Transaction Relaying](https://docs.xoxno.com/developers/relayer-api/transaction-relaying) — Co-signed relayed transactions
* [Error Reference](https://github.com/XOXNO/docs/blob/main/developers/relayer-api/error-reference.md) — All error codes and resolutions
