Repository navigation
Pyth
Typed Pyth Pro (formerly Pyth
Lazer) price stream for Deno, Bun, Node.js, browsers and Cloudflare Workers:
connects to all of Pyth Pro's redundant WebSocket endpoints at once and
merges them into one Guardian-validated stream of real-time prices, with
per-endpoint health and gap detection. An alternative to the official
@pythnetwork/pyth-lazer-sdk stream client.
PythProSocket (from @tundraconnect/pyth/sockets, or the package root):
- All three endpoints at once — Pyth says to connect to every one, because each restarts briefly during deployments. Each connection has its own reconnect, backoff and liveness; every subscription change goes to all of them.
-
One merged stream — a feed's update is identified by
priceFeedId+timestampUs, and the first endpoint to deliver it wins. Eachpriceevent says whichendpointthat was and when it arrived (receivedAt, read before parsing).emitDuplicates: trueemits every endpoint's copy instead — tagged with the first copy's arrival — for latency research. -
Lowest grain by default — the
real_timechannel and every price property (price,bestBidPrice,bestAskPrice,confidence,exponent,publisherCount, EMA, funding,marketSession,feedUpdateTimestamp). i64 mantissas stay exact strings. -
Health —
connected/disconnected/errorper endpoint, plushealthevents and ahealthgetter:up,degraded(some endpoints down, still streaming) ordown(none — the stream is stale). -
Gaps — on fixed-rate channels a tick that no endpoint delivered is a
gapevent.
import { PythProSocket } from '@tundraconnect/pyth';
const socket = new PythProSocket({
auth: { type: 'BEARER', token: '<access token>' },
subscriptions: [{ symbols: ['Crypto.BTC/USD', 'Crypto.ETH/USD'] }],
});
for await (const event of socket) {
if (event.type === 'price') {
const { priceFeedId, price, exponent } = event.data;
console.log(priceFeedId, price, exponent, event.endpoint);
}
}The token comes from a Pyth Pro distributor. By default it travels as the
pyth-lazer-auth WebSocket subprotocol, which works on every runtime —
browsers and Workers included; authTransport: 'header' sends
Authorization: Bearer instead. It is never logged or put in an error.
- Hermes (Pyth Core) REST and streaming — planned for this package.
- The Pyth Pro HTTP API (latest price, historical price, symbols) and on-chain verification of the signed payloads (they are delivered, not verified).
Have your code take an AsyncIterable of events and feed it a stand-in that
yields shapes from @tundraconnect/pyth/schemas, or pass webSocket a
factory that returns a test double:
import { PythError } from '@tundraconnect/pyth/errors';
const missing = new PythError('SOCKET_MISSING_CREDENTIALS');
console.log(missing.code);| Topic | Description |
|---|---|
| Sockets | The Pyth Pro socket and its events |
| Errors | Error codes and diagnostic metadata |
| Schemas | Public Guardian schemas and inferred types |
Deno:
deno add jsr:@tundraconnect/pythBun:
bunx jsr add @tundraconnect/pythNode.js:
npx jsr add @tundraconnect/pythRecord every BTC/USD print with the endpoint that delivered it first, and know when the stream was stale:
import { PythProSocket } from '@tundraconnect/pyth/sockets';
const socket = new PythProSocket({
auth: { type: 'BEARER', token: '<access token>' },
subscriptions: [{ symbols: ['Crypto.BTC/USD'] }],
includeRaw: true, // keep the exact frame text
signal: AbortSignal.timeout(60_000),
});
for await (const event of socket) {
switch (event.type) {
case 'price':
console.log(
event.timestampUs,
event.data.price,
event.endpoint,
event.receivedAt,
);
break;
case 'health':
console.log(
`health: ${event.state} (${event.endpointsUp}/${event.endpointsTotal})`,
);
break;
case 'error':
if (event.fatal) console.error(event.endpoint, event.error.message);
break;
}
}MIT. Part of Tundra Connect, typed vendor API clients for Deno, Bun, Node.js and Cloudflare Workers.
- Algolia
- AzureBlob
- Binance
- CloudflareDNS
- CloudflareEmail
- CloudflareSaaS
- CloudflareTurnstile
- CoinGecko
- Discord
- DodoPayments
- GCS
- GoogleAnalytics
- GoogleCertificateManager
- GoogleWebRisk
- Kalshi
- ntfy
- OpenExchange
- OpenWeatherMap
- PayPal
- Polymarket
- Pyth
- Razorpay
- Resend
- S3
- SendGrid
- Sentry
- Slack
- Stripe
- Telegram
- Twilio
- UpstashRedis
- URLhaus