bun-polymarket-rtds
v1.0.0
Published
A Bun-native TypeScript client for Polymarket real-time data streaming
Maintainers
Readme
bun-polymarket-rtds
A Bun-native TypeScript client for Polymarket real-time data streaming. This is a fast, lightweight WebSocket client built specifically for the Bun runtime.
⚠️ Bun-only: This package uses Bun's native WebSocket and
Bun.sleep()APIs. It will not work in Node.js or browser environments. For Node.js, consider using the original polymarket/live-data-ws-client.
Installation
bun add bun-polymarket-rtdsRequirements
- Bun >= 1.0.0
Why Bun-native?
- Zero dependencies - Uses Bun's built-in WebSocket (no
wsorisomorphic-ws) - Minimal bundle - ~3KB ESM output
- Native performance - Leverages Bun's optimized networking stack
- TypeScript first - Full type definitions included
Quick Start
import { RealTimeDataClient, Message } from "bun-polymarket-rtds";
const onMessage = (_client: RealTimeDataClient, message: Message): void => {
console.log(message.topic, message.type, message.payload);
};
const onConnect = (client: RealTimeDataClient): void => {
// Subscribe to a topic
client.subscribe({
subscriptions: [
{
topic: "activity",
type: "trades",
},
],
});
};
new RealTimeDataClient({ onConnect, onMessage }).connect();How to subscribe and unsubscribe from messages
Once the connection is established and you have a client: RealTimeDataClient object, you can subscribe and unsubscribe to many message streams using the same connection.
Subscribe
Subscribe to 'trades' messages from the topic 'activity' and to the all comments messages.
client.subscribe({
subscriptions: [
{
topic: "activity",
type: "trades",
},
],
});
client.subscribe({
subscriptions: [
{
topic: "comments",
type: "*", // "*"" can be used to connect to all the types of the topic
},
],
});Unsubscribe
Unsubscribe from the new trades messages of the topic 'activity'. If 'activity' has more messages types and I used '*' to connect to all of them, this will only unsubscribe from the type 'trades'.
client.subscribe({
subscriptions: [
{
topic: "activity",
type: "trades",
},
],
});Disconnect
The client object provides a method to disconnect from the WebSocket server:
client.disconnect();Messages hierarchy
| Topic | Type | Auth | Filters (if it is empty the messages won't be filtered) | Schema | Subscription Handler |
| ------------------------- | ------------------ | -------- | --------------------------------------------------------------- | ----------------------------------- | ----------------------------------------------------------- |
| activity | trades | - | {"event_slug":"string"}' OR '{"market_slug":"string"} | Trade | |
| activity | orders_matched | - | {"event_slug":"string"}' OR '{"market_slug":"string"} | Trade | |
| comments | comment_created | - | {"parentEntityID":number,"parentEntityType":"Event / Series"} | Comment | |
| comments | comment_removed | - | {"parentEntityID":number,"parentEntityType":"Event / Series"} | Comment | |
| comments | reaction_created | - | {"parentEntityID":number,"parentEntityType":"Event / Series"} | Reaction | |
| comments | reaction_removed | - | {"parentEntityID":number,"parentEntityType":"Event / Series"} | Reaction | |
| rfq | request_created | - | - | Request | |
| rfq | request_edited | - | - | Request | |
| rfq | request_canceled | - | - | Request | |
| rfq | request_expired | - | - | Request | |
| rfq | quote_created | - | - | Quote | |
| rfq | quote_edited | - | - | Quote | |
| rfq | quote_canceled | - | - | Quote | |
| rfq | quote_expired | - | - | Quote | |
| crypto_prices | update | - | {"symbol":string} | CryptoPrice | CryptoPriceHistorical |
| crypto_prices_chainlink | update | - | {"symbol":string} | CryptoPrice | CryptoPriceHistorical |
| equity_prices | update | - | {"symbol":string} | EquityPrice | EquityPriceHistorical |
Auth
ClobAuth
/**
* API key credentials for CLOB authentication.
*/
export interface ClobApiKeyCreds {
/** API key used for authentication */
key: string;
/** API secret associated with the key */
secret: string;
/** Passphrase required for authentication */
passphrase: string;
}client.subscribe({
subscriptions: [
{
topic: "clob_user",
type: "*",
clob_auth: {
key: "xxxxxx-xxxx-xxxxx-xxxx-xxxxxx",
secret: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
passphrase: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
},
},
],
});Message types
Activity
Trade
| Name | Type | Description |
| ----------------- | ------- | -------------------------------------------------- |
| asset | string | ERC1155 token ID of conditional token being traded |
| bio | string | Bio of the user of the trade |
| conditionId | string | Id of market which is also the CTF condition ID |
| eventSlug | string | Slug of the event |
| icon | string | URL to the market icon image |
| name | string | Name of the user of the trade |
| outcome | string | Human readable outcome of the market |
| outcomeIndex | integer | Index of the outcome |
| price | float | Price of the trade |
| profileImage | string | URL to the user profile image |
| proxyWallet | string | Address of the user proxy wallet |
| pseudonym | string | Pseudonym of the user |
| side | string | Side of the trade (BUY/SELL) |
| size | integer | Size of the trade |
| slug | string | Slug of the market |
| timestamp | integer | Timestamp of the trade |
| title | string | Title of the event |
| transactionHash | string | Hash of the transaction |
Comments
Comment
| Name | Type | Description |
| ------------------ | ------ | ------------------------------------------- |
| id | string | Unique identifier of comment |
| body | string | Content of the comment |
| parentEntityType | string | Type of the parent entity (Event or Series) |
| parentEntityID | number | ID of the parent entity |
| parentCommentID | string | ID of the parent comment |
| userAddress | string | Address of the user |
| replyAddress | string | Address of the reply user |
| createdAt | string | Creation timestamp |
| updatedAt | string | Last update timestamp |
Reaction
| Name | Type | Description |
| -------------- | ------ | ------------------------------ |
| id | string | Unique identifier of reaction |
| commentID | number | ID of the comment |
| reactionType | string | Type of the reaction |
| icon | string | Icon representing the reaction |
| userAddress | string | Address of the user |
| createdAt | string | Creation timestamp |
RFQ
Request
| Name | Type | Description |
| -------------- | ------ | --------------------------------------------------------------- |
| requestId | string | Unique identifier for the request |
| proxyAddress | string | User proxy address |
| market | string | Id of market which is also the CTF condition ID |
| token | string | ERC1155 token ID of conditional token being traded |
| complement | string | Complement ERC1155 token ID of conditional token being traded |
| state | string | Current state of the request |
| side | string | Indicates buy or sell side |
| sizeIn | number | Input size of the request |
| sizeOut | number | Output size of the request |
| price | number | Price from in/out sizes |
| expiry | number | Expiry timestamp (UNIX format) |
Quote
| Name | Type | Description |
| -------------- | ------ | --------------------------------------------------------------- |
| quoteId | string | Unique identifier for the quote |
| requestId | string | Associated request identifier |
| proxyAddress | string | User proxy address |
| token | string | ERC1155 token ID of conditional token being traded |
| state | string | Current state of the quote |
| side | string | Indicates buy or sell side |
| sizeIn | number | Input size of the quote |
| sizeOut | number | Output size of the quote |
| sizeOut | number | Output size of the request |
| condition | string | Id of market which is also the CTF condition ID |
| complement | string | Complement ERC1155 token ID of conditional token being traded |
| expiry | number | Expiry timestamp (UNIX format) |
CryptoPrice
| Name | Type | Description |
| ----------- | ------ | ---------------------------------------- |
| symbol | string | Symbol of the asset |
| timestamp | number | Timestamp in milliseconds for the update |
| value | number | Value at the time of update |
Filters
{"symbol":"BTCUSDT"}{"symbol":"ETHUSDT"}{"symbol":"XRPUSDT"}{"symbol":"SOLUSDT"}{"symbol":"DOGEUSDT"}
EquityPrice
| Name | Type | Description |
| ----------- | ------ | ---------------------------------------- |
| symbol | string | Symbol of the asset |
| timestamp | number | Timestamp in milliseconds for the update |
| value | number | Value at the time of update |
Filters
{"symbol":"AAPL"}{"symbol":"TSLA"}{"symbol":"MSFT"}{"symbol":"GOOGL"}{"symbol":"AMZN"}{"symbol":"META"}{"symbol":"NVDA"}{"symbol":"NFLX"}{"symbol":"PLTR"}{"symbol":"OPEN"}{"symbol":"RKLB"}{"symbol":"ABNB"}
Initial data dump on connection
When the connection is stablished, if a filter is used, the server will dump an initial snapshoot of recent data. This applies to both CrytoPrice and EquityPrice.
| Name | Type | Description | | ------ | ------ | ---------------------------------------------------------------- | | symbol | string | Symbol of the asset | | data | array | Array of price data objects, each containing timestamp and value |
