> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polynode.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# TypeScript PN1 Orderbook

> Maintain exact local orderbooks with optional PN1 sequence and checksum verification.

Use `OrderbookEngine` when your application needs a current local book. Enable PN1 integrity for price-sensitive decisions so gaps and checksum mismatches fail closed.

```typescript theme={null}
import { OrderbookEngine } from 'polynode-sdk';

const apiKey = process.env.POLYNODE_API_KEY;
const tokenId = process.env.POLYMARKET_TOKEN_ID;
if (!apiKey || !tokenId) throw new Error('Set POLYNODE_API_KEY and POLYMARKET_TOKEN_ID');

const engine = new OrderbookEngine({
  apiKey,
  integrity: true,
  allowStaleReads: false,
});

engine.on('integrity_error', (error) => {
  console.error(error.code, error.token, error.message);
});

engine.on('ready', () => {
  console.log({
    bestBid: engine.bestBid(tokenId),
    bestAsk: engine.bestAsk(tokenId),
    midpoint: engine.midpoint(tokenId),
    spread: engine.spread(tokenId),
  });
});

await engine.subscribe([tokenId]);
```

PN1 keeps orderbook prices and sizes as exact decimal strings. It validates the full-snapshot anchor, then validates sequence continuity and a deterministic checksum on each applicable update.

The managed state moves through `initializing`, `ready`, `stale`, `resyncing`, and `failed`. With `allowStaleReads: false`, reads are unavailable until a verified anchor is ready and become unavailable again after a disconnect or integrity failure. The client requests a fresh anchor before returning to `ready`.

<Warning>
  Wildcard `"*"` subscriptions are intentionally unavailable in integrity mode. Subscribe with explicit token IDs, slugs, or condition IDs so every verified book has a bounded identity and anchor.
</Warning>

## Filtered views

```typescript theme={null}
const view = engine.view([tokenId]);
view.on('update', (update) => console.log(update.asset_id));
view.on('trade', (trade) => console.log(trade.price, trade.size));

console.log(view.book(tokenId));
view.destroy();
```

## Raw messages

Use `pn.configureOrderbook({ integrity: true })` when you want protocol messages without managed local state:

```typescript theme={null}
import { PolyNode } from 'polynode-sdk';

const pn = new PolyNode({ apiKey });
const ob = pn.configureOrderbook({ integrity: true });
ob.on('snapshot', (snapshot) => console.log(snapshot.integrity));
ob.on('resyncing', (message) => console.warn(message.markets));
ob.on('unknown', (message) => console.log(message.raw));
await ob.subscribe([tokenId]);
```

## Cleanup

```typescript theme={null}
engine.close();
// Or, for the raw client:
ob.disconnect();
```

See the [shared orderbook guide](/sdks/orderbook) and [PN1 protocol reference](/orderbook/integrity).
