> For the complete documentation index, see [llms.txt](https://docs.gammaswap.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.gammaswap.com/developers/api-reference/oracle-methods.md).

# Oracle Methods

`OracleWebSocketClient` manages the oracle WebSocket connection and subscribes to real-time price updates by `symbolId`.

```ts
import {
  createOracleWebSocketClient,
} from "@gammaswap/v2-exchange-sdk";

const oracleStream = createOracleWebSocketClient({
  websocketUrl: "wss://exchange-api.gammaswap.com/oracle-ws/",
  stalePriceTimeoutMs: 30_000,
  onError: (error) => console.error(error),
});
```

### `connectionState`

Returns the current state of the oracle WebSocket connection.

```ts
const state = oracleStream.connectionState;
```

### `connect`

Opens the oracle WebSocket connection.

```ts
const result = await oracleStream.connect();
```

After the socket opens, the WebSocket service sends a `connected` control message:

```json
{
  "type": "connected",
  "message": "Send {\"type\":\"subscribe\",\"symbolId\":\"...\"} to receive prices"
}
```

Calling `connect()` before subscribing is optional. `subscribePrice` establishes the connection when necessary.

### `subscribePrice`

Subscribes to live oracle prices for a `symbolId`.

```ts
const unsubscribe =
  await oracleStream.subscribePrice("1", {
    onPrice: (update) => {
      console.log(
        "Price update",
        update.symbolId,
        update.price,
        update.ts,
      );
    },
    onError: (error) => {
      console.error("Subscription error", error);
    },
    onStale: (symbolId) => {
      console.warn("Oracle price is stale", symbolId);
    },
  });
```

The resolved value is an asynchronous unsubscribe function:

```ts
await unsubscribe();
```

The underlying WebSocket subscription message is:

```json
{
  "type": "subscribe",
  "symbolId": "1"
}
```

After the subscription is accepted, the service sends:

```json
{
  "type": "subscribed",
  "symbolId": "1"
}
```

### Price updates

Price updates are delivered to the subscription’s `onPrice` handler.

```json
{
  "type": "price",
  "symbolId": "1",
  "price": "123456789",
  "ts": 1730000000
}
```

The update contains:

<table><thead><tr><th width="114.5859375">Field</th><th width="97.921875">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>type</code></td><td>string</td><td>Always <code>price</code> for a price update</td></tr><tr><td><code>symbolId</code></td><td>string</td><td>Subscribed oracle symbol ID</td></tr><tr><td><code>price</code></td><td>string</td><td>Current oracle price</td></tr><tr><td><code>ts</code></td><td>number</td><td>Price timestamp</td></tr></tbody></table>

Example handler:

```ts
onPrice: (update) => {
  if (update.symbolId === "1") {
    console.log(update.price);
  }
}
```

Handler input:

```ts
{
  type: "price",
  symbolId: "1",
  price: "123456789",
  ts: 1730000000,
}
```

### `unsubscribePrice`

Removes all local handlers for a `symbolId` and unsubscribes from that symbol’s server-side price feed.

```ts
const result =
  await oracleStream.unsubscribePrice("1");
```

The underlying WebSocket unsubscribe message is:

```json
{
  "type": "unsubscribe",
  "symbolId": "1"
}
```

After the subscription is removed, the service sends:

```json
{
  "type": "unsubscribed",
  "symbolId": "1"
}
```

`unsubscribePrice` removes every local handler for the symbol.

The unsubscribe function returned by `subscribePrice` removes only the handler associated with that call.

### Unavailable symbols

If a symbol becomes unavailable after subscription, the service can send:

```json
{
  "type": "unsubscribed",
  "symbolId": "1",
  "reason": "symbol unavailable"
}
```

The symbol is no longer subscribed after this message.

### `close`

Closes the oracle WebSocket connection.

```ts
const result = oracleStream.close();
```

An optional WebSocket close code and reason can be supplied:

```ts
oracleStream.close(1000, "Client shutdown");
```

The client does not reconnect after an intentional close unless a new connection or subscription is started.

### Error messages

If a subscription message cannot be processed, the service sends an error message:

```json
{
  "type": "error",
  "message": "SymbolId 123 is not available"
}
```

Errors are delivered to:

* The subscription’s `onError` handler
* The client-level `onError` handler, where applicable

### Stale prices

`stalePriceTimeoutMs` defines the maximum time the client waits without receiving a price update for a subscribed symbol.

The default is:

```ts
30_000
```

If no price arrives before the timeout, the client calls:

```ts
onStale("1");
```

The handler receives the stale `symbolId`:

```ts
"1"
```

The client also:

1. Emits an error.
2. Abandons the unhealthy socket.
3. Reconnects when active subscriptions remain.

The oracle stream does not provide sequence IDs or REST catch-up.

After reconnecting or receiving `onStale`, accept the next live price update for the symbol.

### Subscription behavior

One client can subscribe to multiple symbol IDs.

When multiple handlers subscribe to the same symbol:

1. The client creates one server subscription.
2. Price updates are distributed to every local handler.
3. The returned unsubscribe function removes only its handler.
4. The server subscription is removed after the last handler unsubscribes.

### Reconnection defaults

| Option                | Default |
| --------------------- | ------: |
| `reconnect`           |  `true` |
| `reconnectDelayMs`    |  `1000` |
| `maxReconnectDelayMs` | `30000` |
| `ackTimeoutMs`        | `15000` |
| `stalePriceTimeoutMs` | `30000` |

### Heartbeats

The server sends protocol-level WebSocket ping frames.

Browser WebSockets and the Node `ws` client respond with protocol pong frames automatically.

Do not send an application-level pong message:

```json
{
  "type": "pong"
}
```

### Available methods and properties

<table><thead><tr><th width="181.1953125">Name</th><th>SDK response</th></tr></thead><tbody><tr><td><code>connectionState</code></td><td>Current connection-state value</td></tr><tr><td><code>connect</code></td><td><code>Promise&#x3C;void></code></td></tr><tr><td><code>close</code></td><td><code>void</code></td></tr><tr><td><code>subscribePrice</code></td><td><code>Promise&#x3C;unsubscribe function></code></td></tr><tr><td><code>unsubscribePrice</code></td><td><code>Promise&#x3C;void></code></td></tr></tbody></table>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.gammaswap.com/developers/api-reference/oracle-methods.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
