Skip to content

Bun quickstart ​

Run a public BTC REST request and a WebSocket subscription with @siebly/hyperliquid-api. No API key is needed. Prices are BTC mid prices.

Create the project ​

Install Bun first. The runtime compatibility report records the versions exercised with this SDK.

Download the complete Bun starter, or create an empty directory and copy the files below. The archive contains the same files shown on this page.

sh
mkdir hyperliquid-bun-quickstart
cd hyperliquid-bun-quickstart

Copy the files below, or extract the downloaded archive into this directory (adjust the download path if needed):

sh
tar -xzf ~/Downloads/bun.tar.gz

Install the dependencies after saving or extracting the files:

sh
bun install

The SDK dependency uses latest, so a new installation selects the current npm release.

Project files ​

package.json ​

json
{
  "name": "hyperliquid-bun-quickstart",
  "private": true,
  "type": "module",
  "scripts": {
    "start": "bun prices.js"
  },
  "dependencies": {
    "@siebly/hyperliquid-api": "latest"
  }
}

market.js ​

js
export const endpoints = {"rest": "https://api.hyperliquid.xyz/info", "websocket": "wss://api.hyperliquid.xyz/ws"};
export function client(sdk) { return new sdk.RestClient({}, {timeout:15000}); }
export async function read(client) { return (await client.getAllMids()).BTC; }
export function stream(sdk, logger) { return new sdk.WebsocketClient({}, logger); }
export const event = 'message';
export function value(message) { return message.channel === 'allMids' ? message.data?.mids?.BTC : undefined; }
export async function subscribe(ws) { await ws.subscribe({ type: 'allMids' }); }

price.js ​

js
import * as sdk from '@siebly/hyperliquid-api';
import * as market from './market.js';

function positivePrice(value) {
  if (!Number.isFinite(Number(value)) || Number(value) <= 0) {
    throw new Error('The exchange did not return a positive BTC price.');
  }
  return String(value);
}

export async function readPrice() {
  return positivePrice(await market.read(market.client(sdk)));
}

// Returns cleanup without waiting for subscription acknowledgement.
export function watchPrice(onPrice, onError) {
  const ws = market.stream(sdk);
  let stopped = false;
  const receive = message => {
    const value = market.value(message);
    if (!stopped && value !== undefined) {
      clearTimeout(deadline);
      try { onPrice(positivePrice(value)); } catch (error) { fail(error); }
    }
  };
  const fail = error => { if (!stopped) onError(error); };
  const deadline = setTimeout(() => fail(new Error('No BTC update within 30 seconds. Check network access.')), 30000);
  ws.on(market.event, receive);
  ws.on('exception', fail);
  // React may clean up an effect before its queued subscription starts.
  Promise.resolve().then(async () => {
    if (stopped) return;
    try {
      await market.subscribe(ws);
    } finally {
      // A connection may finish opening after cleanup was requested.
      if (stopped) ws.closeAll();
    }
  }).catch(fail);
  return () => {
    if (stopped) return;
    stopped = true;
    clearTimeout(deadline);
    ws.closeAll();
    ws.removeListener(market.event, receive);
    ws.removeListener('exception', fail);
  };
}

prices.js ​

js
import process from 'node:process';
import { readPrice, watchPrice } from './price.js';

async function main() {
  console.log('BTC REST price:', await readPrice());
  let stop;
  try {
    const price = await new Promise((resolve, reject) => {
      stop = watchPrice(resolve, reject);
    });
    console.log('BTC WebSocket price:', price);
  } finally {
    stop?.();
    console.log('WebSocket closed.');
  }
}
main().catch(error => {
  console.error(error.message || String(error));
  process.exitCode = 1;
});

Run ​

sh
bun run start

Alongside SDK connection logs, the script prints one REST price and the first valid WebSocket price, closes the WebSocket client in finally, and exits. Prices change continuously; the two values may differ.

text
BTC REST price: 65000.5
BTC WebSocket price: 65001.2
WebSocket closed.

Troubleshooting ​

  • Run bun install in the directory containing package.json if the SDK import cannot be resolved.

  • A rejected HTTP request or no WebSocket update within 30 seconds usually needs a network check. Allow outbound HTTPS and WSS to the exchange endpoints in market.js. An exchange may restrict access from your region.

  • For API errors, see Troubleshooting. For continuous subscriptions and shutdown, see WebSocket subscriptions.

Built by Siebly. Open source SDKs for exchange APIs.