WebSocket Protocol
Connect, subscribe, and reconnect cleanly over Honeycluster WebSockets — the same XRP Ledger protocol, behind a globally routed edge.

Honeycluster's WebSocket endpoint is a thin wrapper over the XRP Ledger WebSocket protocol. Anything you'd send to rippled or Clio directly, you can send through wss://honeycluster.io (or the testnet / devnet subdomains) — with the added benefit of regional routing and health-checked failover.

The public endpoint is open and keyless. Enterprise and private plans use the same protocol behind an authenticated hostname; see Authentication for the details.

Connecting
##
TypeScript
import { Client } from 'xrpl'

const client = new Client('wss://honeycluster.io')

client.on('connected', () => console.log('ws open'))
client.on('disconnected', (code) => console.log('ws closed', code))

await client.connect()

For testnet or devnet, point at the matching hostname:

TypeScript
const testnetClient = new Client('wss://testnet.honeycluster.io')
const devnetClient = new Client('wss://devnet.honeycluster.io')

The xrpl client takes care of the framing; you issue commands through client.request({ command, ...params }) and receive streams through client.on(eventName, handler).

Subscribing to streams
##

The subscribe command opens one or more event streams over the same socket:

TypeScript
await client.request({
  command: 'subscribe',
  streams: ['ledger', 'transactions'],
})

client.on('ledgerClosed', (ledger) => {
  console.log('ledger', ledger.ledger_index, 'tx count', ledger.txn_count)
})

client.on('transaction', (tx) => {
  console.log(tx.transaction?.TransactionType, tx.transaction?.hash)
})

Available streams include ledger, transactions, transactions_proposed, validations, peer_status, and the per-account accounts filter:

TypeScript
await client.request({
  command: 'subscribe',
  accounts: ['rExampleAccountAddressXXXXXXXX', 'rAnotherAccountXXXXXXXXXXXXXX'],
})
Selective subscriptions
##

You can unsubscribe from a specific stream without closing the socket:

TypeScript
await client.request({
  command: 'unsubscribe',
  accounts: ['rExampleAccountAddressXXXXXXXX'],
})

This is the preferred pattern for long-lived workers that rotate which accounts they monitor — it's cheaper than tearing down and re-establishing the connection.

Reconnect strategy
##

The xrpl.js client auto-reconnects with exponential backoff by default, but your application needs to re-subscribe after a reconnection — the upstream doesn't remember prior subscriptions:

TypeScript
let watchedAccounts: string[] = []

async function watch(accounts: string[]) {
  watchedAccounts = accounts
  await client.request({ command: 'subscribe', accounts })
}

client.on('connected', async () => {
  if (watchedAccounts.length > 0) {
    await client.request({ command: 'subscribe', accounts: watchedAccounts })
  }
})

For production workers, persist the watched set somewhere durable (Redis, Postgres) so a pod restart doesn't lose state.

Disconnecting cleanly

Always call await client.disconnect() on shutdown — it emits a clean close frame upstream and frees regional-proxy resources faster than a dropped TCP connection.