@catalyst-team/poly-sdk 0.4.0 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/README.md +8 -1
  2. package/README.zh-CN.md +2 -0
  3. package/dist/src/__tests__/integration/data-api.integration.test.js +21 -18
  4. package/dist/src/__tests__/integration/data-api.integration.test.js.map +1 -1
  5. package/dist/src/catalyst/catalyst-query-service.d.ts +109 -0
  6. package/dist/src/catalyst/catalyst-query-service.d.ts.map +1 -0
  7. package/dist/src/catalyst/catalyst-query-service.js +141 -0
  8. package/dist/src/catalyst/catalyst-query-service.js.map +1 -0
  9. package/dist/src/catalyst/catalyst-realtime-service.d.ts +40 -0
  10. package/dist/src/catalyst/catalyst-realtime-service.d.ts.map +1 -0
  11. package/dist/src/catalyst/catalyst-realtime-service.js +125 -0
  12. package/dist/src/catalyst/catalyst-realtime-service.js.map +1 -0
  13. package/dist/src/catalyst/index.d.ts +4 -0
  14. package/dist/src/catalyst/index.d.ts.map +1 -0
  15. package/dist/src/catalyst/index.js +4 -0
  16. package/dist/src/catalyst/index.js.map +1 -0
  17. package/dist/src/catalyst/types.d.ts +178 -0
  18. package/dist/src/catalyst/types.d.ts.map +1 -0
  19. package/dist/src/catalyst/types.js +2 -0
  20. package/dist/src/catalyst/types.js.map +1 -0
  21. package/dist/src/clients/data-api.d.ts +75 -14
  22. package/dist/src/clients/data-api.d.ts.map +1 -1
  23. package/dist/src/clients/data-api.js +40 -18
  24. package/dist/src/clients/data-api.js.map +1 -1
  25. package/dist/src/clients/gamma-api.d.ts +54 -0
  26. package/dist/src/clients/gamma-api.d.ts.map +1 -1
  27. package/dist/src/clients/gamma-api.js.map +1 -1
  28. package/dist/src/index.d.ts +15 -4
  29. package/dist/src/index.d.ts.map +1 -1
  30. package/dist/src/index.js +22 -2
  31. package/dist/src/index.js.map +1 -1
  32. package/dist/src/insider-scan/index.d.ts +3 -0
  33. package/dist/src/insider-scan/index.d.ts.map +1 -0
  34. package/dist/src/insider-scan/index.js +3 -0
  35. package/dist/src/insider-scan/index.js.map +1 -0
  36. package/dist/src/insider-scan/insider-scan-service.d.ts +63 -0
  37. package/dist/src/insider-scan/insider-scan-service.d.ts.map +1 -0
  38. package/dist/src/insider-scan/insider-scan-service.js +153 -0
  39. package/dist/src/insider-scan/insider-scan-service.js.map +1 -0
  40. package/dist/src/insider-scan/types.d.ts +205 -0
  41. package/dist/src/insider-scan/types.d.ts.map +1 -0
  42. package/dist/src/insider-scan/types.js +7 -0
  43. package/dist/src/insider-scan/types.js.map +1 -0
  44. package/dist/src/services/market-service.d.ts +61 -0
  45. package/dist/src/services/market-service.d.ts.map +1 -1
  46. package/dist/src/services/market-service.js +58 -0
  47. package/dist/src/services/market-service.js.map +1 -1
  48. package/dist/src/services/onchain-service.d.ts +10 -2
  49. package/dist/src/services/onchain-service.d.ts.map +1 -1
  50. package/dist/src/services/onchain-service.js +8 -0
  51. package/dist/src/services/onchain-service.js.map +1 -1
  52. package/dist/src/services/smart-money-service.d.ts +420 -3
  53. package/dist/src/services/smart-money-service.d.ts.map +1 -1
  54. package/dist/src/services/smart-money-service.js +869 -3
  55. package/dist/src/services/smart-money-service.js.map +1 -1
  56. package/dist/src/services/trading-service.d.ts +5 -0
  57. package/dist/src/services/trading-service.d.ts.map +1 -1
  58. package/dist/src/services/trading-service.js +5 -0
  59. package/dist/src/services/trading-service.js.map +1 -1
  60. package/dist/src/services/wallet-service.d.ts +38 -2
  61. package/dist/src/services/wallet-service.d.ts.map +1 -1
  62. package/dist/src/services/wallet-service.js +72 -5
  63. package/dist/src/services/wallet-service.js.map +1 -1
  64. package/dist/src/signal/index.d.ts +8 -0
  65. package/dist/src/signal/index.d.ts.map +1 -0
  66. package/dist/src/signal/index.js +7 -0
  67. package/dist/src/signal/index.js.map +1 -0
  68. package/dist/src/signal/signal-service.d.ts +89 -0
  69. package/dist/src/signal/signal-service.d.ts.map +1 -0
  70. package/dist/src/signal/signal-service.js +226 -0
  71. package/dist/src/signal/signal-service.js.map +1 -0
  72. package/dist/src/signal/types.d.ts +280 -0
  73. package/dist/src/signal/types.d.ts.map +1 -0
  74. package/dist/src/signal/types.js +7 -0
  75. package/dist/src/signal/types.js.map +1 -0
  76. package/dist/src/wallet-report/index.d.ts +3 -0
  77. package/dist/src/wallet-report/index.d.ts.map +1 -0
  78. package/dist/src/wallet-report/index.js +3 -0
  79. package/dist/src/wallet-report/index.js.map +1 -0
  80. package/dist/src/wallet-report/types.d.ts +187 -0
  81. package/dist/src/wallet-report/types.d.ts.map +1 -0
  82. package/dist/src/wallet-report/types.js +7 -0
  83. package/dist/src/wallet-report/types.js.map +1 -0
  84. package/dist/src/wallet-report/wallet-report-service.d.ts +91 -0
  85. package/dist/src/wallet-report/wallet-report-service.d.ts.map +1 -0
  86. package/dist/src/wallet-report/wallet-report-service.js +208 -0
  87. package/dist/src/wallet-report/wallet-report-service.js.map +1 -0
  88. package/dist/src/wallets/hot-wallet-service.d.ts +162 -0
  89. package/dist/src/wallets/hot-wallet-service.d.ts.map +1 -0
  90. package/dist/src/wallets/hot-wallet-service.js +251 -0
  91. package/dist/src/wallets/hot-wallet-service.js.map +1 -0
  92. package/dist/src/wallets/index.d.ts +15 -0
  93. package/dist/src/wallets/index.d.ts.map +1 -0
  94. package/dist/src/wallets/index.js +26 -0
  95. package/dist/src/wallets/index.js.map +1 -0
  96. package/package.json +5 -5
  97. package/dist/__tests__/clob-api.test.d.ts +0 -5
  98. package/dist/__tests__/clob-api.test.d.ts.map +0 -1
  99. package/dist/__tests__/clob-api.test.js +0 -240
  100. package/dist/__tests__/clob-api.test.js.map +0 -1
  101. package/dist/__tests__/integration/arbitrage-service.integration.test.d.ts +0 -12
  102. package/dist/__tests__/integration/arbitrage-service.integration.test.d.ts.map +0 -1
  103. package/dist/__tests__/integration/arbitrage-service.integration.test.js +0 -267
  104. package/dist/__tests__/integration/arbitrage-service.integration.test.js.map +0 -1
  105. package/dist/__tests__/integration/bridge-client.integration.test.d.ts +0 -11
  106. package/dist/__tests__/integration/bridge-client.integration.test.d.ts.map +0 -1
  107. package/dist/__tests__/integration/bridge-client.integration.test.js +0 -260
  108. package/dist/__tests__/integration/bridge-client.integration.test.js.map +0 -1
  109. package/dist/__tests__/integration/clob-api.integration.test.d.ts +0 -13
  110. package/dist/__tests__/integration/clob-api.integration.test.d.ts.map +0 -1
  111. package/dist/__tests__/integration/clob-api.integration.test.js +0 -170
  112. package/dist/__tests__/integration/clob-api.integration.test.js.map +0 -1
  113. package/dist/__tests__/integration/ctf-client.integration.test.d.ts +0 -17
  114. package/dist/__tests__/integration/ctf-client.integration.test.d.ts.map +0 -1
  115. package/dist/__tests__/integration/ctf-client.integration.test.js +0 -234
  116. package/dist/__tests__/integration/ctf-client.integration.test.js.map +0 -1
  117. package/dist/__tests__/integration/data-api.integration.test.d.ts +0 -9
  118. package/dist/__tests__/integration/data-api.integration.test.d.ts.map +0 -1
  119. package/dist/__tests__/integration/data-api.integration.test.js +0 -164
  120. package/dist/__tests__/integration/data-api.integration.test.js.map +0 -1
  121. package/dist/__tests__/integration/gamma-api.integration.test.d.ts +0 -9
  122. package/dist/__tests__/integration/gamma-api.integration.test.d.ts.map +0 -1
  123. package/dist/__tests__/integration/gamma-api.integration.test.js +0 -170
  124. package/dist/__tests__/integration/gamma-api.integration.test.js.map +0 -1
  125. package/dist/__tests__/integration/market-service.integration.test.d.ts +0 -10
  126. package/dist/__tests__/integration/market-service.integration.test.d.ts.map +0 -1
  127. package/dist/__tests__/integration/market-service.integration.test.js +0 -173
  128. package/dist/__tests__/integration/market-service.integration.test.js.map +0 -1
  129. package/dist/__tests__/integration/realtime-service-v2.integration.test.d.ts +0 -10
  130. package/dist/__tests__/integration/realtime-service-v2.integration.test.d.ts.map +0 -1
  131. package/dist/__tests__/integration/realtime-service-v2.integration.test.js +0 -307
  132. package/dist/__tests__/integration/realtime-service-v2.integration.test.js.map +0 -1
  133. package/dist/__tests__/integration/trading-service.integration.test.d.ts +0 -10
  134. package/dist/__tests__/integration/trading-service.integration.test.d.ts.map +0 -1
  135. package/dist/__tests__/integration/trading-service.integration.test.js +0 -58
  136. package/dist/__tests__/integration/trading-service.integration.test.js.map +0 -1
  137. package/dist/__tests__/test-utils.d.ts +0 -92
  138. package/dist/__tests__/test-utils.d.ts.map +0 -1
  139. package/dist/__tests__/test-utils.js +0 -143
  140. package/dist/__tests__/test-utils.js.map +0 -1
  141. package/dist/clients/bridge-client.d.ts +0 -388
  142. package/dist/clients/bridge-client.d.ts.map +0 -1
  143. package/dist/clients/bridge-client.js +0 -587
  144. package/dist/clients/bridge-client.js.map +0 -1
  145. package/dist/clients/clob-api.d.ts +0 -391
  146. package/dist/clients/clob-api.d.ts.map +0 -1
  147. package/dist/clients/clob-api.js +0 -448
  148. package/dist/clients/clob-api.js.map +0 -1
  149. package/dist/clients/ctf-client.d.ts +0 -475
  150. package/dist/clients/ctf-client.d.ts.map +0 -1
  151. package/dist/clients/ctf-client.js +0 -915
  152. package/dist/clients/ctf-client.js.map +0 -1
  153. package/dist/clients/data-api.d.ts +0 -452
  154. package/dist/clients/data-api.d.ts.map +0 -1
  155. package/dist/clients/data-api.js +0 -637
  156. package/dist/clients/data-api.js.map +0 -1
  157. package/dist/clients/gamma-api.d.ts +0 -406
  158. package/dist/clients/gamma-api.d.ts.map +0 -1
  159. package/dist/clients/gamma-api.js +0 -354
  160. package/dist/clients/gamma-api.js.map +0 -1
  161. package/dist/clients/subgraph.d.ts +0 -196
  162. package/dist/clients/subgraph.d.ts.map +0 -1
  163. package/dist/clients/subgraph.js +0 -332
  164. package/dist/clients/subgraph.js.map +0 -1
  165. package/dist/clients/trading-client.d.ts +0 -252
  166. package/dist/clients/trading-client.d.ts.map +0 -1
  167. package/dist/clients/trading-client.js +0 -543
  168. package/dist/clients/trading-client.js.map +0 -1
  169. package/dist/clients/websocket-manager.d.ts +0 -103
  170. package/dist/clients/websocket-manager.d.ts.map +0 -1
  171. package/dist/clients/websocket-manager.js +0 -200
  172. package/dist/clients/websocket-manager.js.map +0 -1
  173. package/dist/core/cache-adapter-bridge.d.ts +0 -36
  174. package/dist/core/cache-adapter-bridge.d.ts.map +0 -1
  175. package/dist/core/cache-adapter-bridge.js +0 -81
  176. package/dist/core/cache-adapter-bridge.js.map +0 -1
  177. package/dist/core/cache.d.ts +0 -43
  178. package/dist/core/cache.d.ts.map +0 -1
  179. package/dist/core/cache.js +0 -76
  180. package/dist/core/cache.js.map +0 -1
  181. package/dist/core/errors.d.ts +0 -39
  182. package/dist/core/errors.d.ts.map +0 -1
  183. package/dist/core/errors.js +0 -86
  184. package/dist/core/errors.js.map +0 -1
  185. package/dist/core/rate-limiter.d.ts +0 -33
  186. package/dist/core/rate-limiter.d.ts.map +0 -1
  187. package/dist/core/rate-limiter.js +0 -82
  188. package/dist/core/rate-limiter.js.map +0 -1
  189. package/dist/core/types.d.ts +0 -506
  190. package/dist/core/types.d.ts.map +0 -1
  191. package/dist/core/types.js +0 -49
  192. package/dist/core/types.js.map +0 -1
  193. package/dist/core/types.test.d.ts +0 -7
  194. package/dist/core/types.test.d.ts.map +0 -1
  195. package/dist/core/types.test.js +0 -122
  196. package/dist/core/types.test.js.map +0 -1
  197. package/dist/core/unified-cache.d.ts +0 -63
  198. package/dist/core/unified-cache.d.ts.map +0 -1
  199. package/dist/core/unified-cache.js +0 -114
  200. package/dist/core/unified-cache.js.map +0 -1
  201. package/dist/index.d.ts +0 -159
  202. package/dist/index.d.ts.map +0 -1
  203. package/dist/index.js +0 -262
  204. package/dist/index.js.map +0 -1
  205. package/dist/services/arbitrage-service.d.ts +0 -409
  206. package/dist/services/arbitrage-service.d.ts.map +0 -1
  207. package/dist/services/arbitrage-service.js +0 -1450
  208. package/dist/services/arbitrage-service.js.map +0 -1
  209. package/dist/services/authorization-service.d.ts +0 -97
  210. package/dist/services/authorization-service.d.ts.map +0 -1
  211. package/dist/services/authorization-service.js +0 -279
  212. package/dist/services/authorization-service.js.map +0 -1
  213. package/dist/services/binance-service.d.ts +0 -154
  214. package/dist/services/binance-service.d.ts.map +0 -1
  215. package/dist/services/binance-service.js +0 -266
  216. package/dist/services/binance-service.js.map +0 -1
  217. package/dist/services/dip-arb-service.d.ts +0 -209
  218. package/dist/services/dip-arb-service.d.ts.map +0 -1
  219. package/dist/services/dip-arb-service.js +0 -1602
  220. package/dist/services/dip-arb-service.js.map +0 -1
  221. package/dist/services/dip-arb-types.d.ts +0 -553
  222. package/dist/services/dip-arb-types.d.ts.map +0 -1
  223. package/dist/services/dip-arb-types.js +0 -164
  224. package/dist/services/dip-arb-types.js.map +0 -1
  225. package/dist/services/market-service.d.ts +0 -367
  226. package/dist/services/market-service.d.ts.map +0 -1
  227. package/dist/services/market-service.js +0 -1187
  228. package/dist/services/market-service.js.map +0 -1
  229. package/dist/services/onchain-service.d.ts +0 -309
  230. package/dist/services/onchain-service.d.ts.map +0 -1
  231. package/dist/services/onchain-service.js +0 -417
  232. package/dist/services/onchain-service.js.map +0 -1
  233. package/dist/services/realtime-service-v2.d.ts +0 -362
  234. package/dist/services/realtime-service-v2.d.ts.map +0 -1
  235. package/dist/services/realtime-service-v2.js +0 -858
  236. package/dist/services/realtime-service-v2.js.map +0 -1
  237. package/dist/services/realtime-service.d.ts +0 -82
  238. package/dist/services/realtime-service.d.ts.map +0 -1
  239. package/dist/services/realtime-service.js +0 -182
  240. package/dist/services/realtime-service.js.map +0 -1
  241. package/dist/services/smart-money-service.d.ts +0 -352
  242. package/dist/services/smart-money-service.d.ts.map +0 -1
  243. package/dist/services/smart-money-service.js +0 -582
  244. package/dist/services/smart-money-service.js.map +0 -1
  245. package/dist/services/swap-service.d.ts +0 -217
  246. package/dist/services/swap-service.d.ts.map +0 -1
  247. package/dist/services/swap-service.js +0 -695
  248. package/dist/services/swap-service.js.map +0 -1
  249. package/dist/services/trading-service.d.ts +0 -177
  250. package/dist/services/trading-service.d.ts.map +0 -1
  251. package/dist/services/trading-service.js +0 -422
  252. package/dist/services/trading-service.js.map +0 -1
  253. package/dist/services/wallet-service.d.ts +0 -316
  254. package/dist/services/wallet-service.d.ts.map +0 -1
  255. package/dist/services/wallet-service.js +0 -681
  256. package/dist/services/wallet-service.js.map +0 -1
  257. package/dist/utils/price-utils.d.ts +0 -153
  258. package/dist/utils/price-utils.d.ts.map +0 -1
  259. package/dist/utils/price-utils.js +0 -236
  260. package/dist/utils/price-utils.js.map +0 -1
  261. package/dist/utils/price-utils.test.d.ts +0 -5
  262. package/dist/utils/price-utils.test.d.ts.map +0 -1
  263. package/dist/utils/price-utils.test.js +0 -192
  264. package/dist/utils/price-utils.test.js.map +0 -1
@@ -1,858 +0,0 @@
1
- /**
2
- * RealtimeService V2
3
- *
4
- * Comprehensive real-time data service using official @polymarket/real-time-data-client.
5
- *
6
- * Supports ALL available topics:
7
- * - clob_market: price_change, agg_orderbook, last_trade_price, tick_size_change, market_created, market_resolved
8
- * - clob_user: order, trade (requires authentication)
9
- * - activity: trades, orders_matched
10
- * - crypto_prices: update (BTC, ETH, etc.)
11
- * - equity_prices: update (AAPL, etc.)
12
- * - comments: comment_created, comment_removed, reaction_created, reaction_removed
13
- * - rfq: request_*, quote_*
14
- */
15
- import { EventEmitter } from 'events';
16
- import { RealTimeDataClient, ConnectionStatus, } from '@polymarket/real-time-data-client';
17
- // ============================================================================
18
- // RealtimeServiceV2 Implementation
19
- // ============================================================================
20
- export class RealtimeServiceV2 extends EventEmitter {
21
- client = null;
22
- config;
23
- subscriptions = new Map();
24
- subscriptionIdCounter = 0;
25
- connected = false;
26
- // Store subscription messages for reconnection
27
- subscriptionMessages = new Map();
28
- // Caches
29
- priceCache = new Map();
30
- bookCache = new Map();
31
- lastTradeCache = new Map();
32
- constructor(config = {}) {
33
- super();
34
- this.config = {
35
- autoReconnect: config.autoReconnect ?? true,
36
- pingInterval: config.pingInterval ?? 5000,
37
- debug: config.debug ?? false,
38
- };
39
- }
40
- // ============================================================================
41
- // Connection Management
42
- // ============================================================================
43
- /**
44
- * Connect to WebSocket server
45
- */
46
- connect() {
47
- if (this.client) {
48
- this.log('Already connected or connecting');
49
- return this;
50
- }
51
- this.client = new RealTimeDataClient({
52
- onConnect: this.handleConnect.bind(this),
53
- onMessage: this.handleMessage.bind(this),
54
- onStatusChange: this.handleStatusChange.bind(this),
55
- autoReconnect: this.config.autoReconnect,
56
- pingInterval: this.config.pingInterval,
57
- });
58
- this.client.connect();
59
- return this;
60
- }
61
- /**
62
- * Disconnect from WebSocket server
63
- */
64
- disconnect() {
65
- if (this.client) {
66
- this.client.disconnect();
67
- this.client = null;
68
- this.connected = false;
69
- this.subscriptions.clear();
70
- this.subscriptionMessages.clear(); // Clear reconnection list
71
- }
72
- }
73
- /**
74
- * Check if connected
75
- */
76
- isConnected() {
77
- return this.connected;
78
- }
79
- // ============================================================================
80
- // Market Data Subscriptions (clob_market)
81
- // ============================================================================
82
- /**
83
- * Subscribe to market data (orderbook, prices, trades)
84
- * @param tokenIds - Array of token IDs to subscribe to
85
- * @param handlers - Event handlers
86
- */
87
- subscribeMarkets(tokenIds, handlers = {}) {
88
- const subId = `market_${++this.subscriptionIdCounter}`;
89
- const filterStr = JSON.stringify(tokenIds);
90
- // Subscribe to all market data types
91
- const subscriptions = [
92
- { topic: 'clob_market', type: 'agg_orderbook', filters: filterStr },
93
- { topic: 'clob_market', type: 'price_change', filters: filterStr },
94
- { topic: 'clob_market', type: 'last_trade_price', filters: filterStr },
95
- { topic: 'clob_market', type: 'tick_size_change', filters: filterStr },
96
- ];
97
- const subMsg = { subscriptions };
98
- this.sendSubscription(subMsg);
99
- this.subscriptionMessages.set(subId, subMsg); // Store for reconnection
100
- // Register handlers
101
- const orderbookHandler = (book) => {
102
- if (tokenIds.includes(book.assetId)) {
103
- handlers.onOrderbook?.(book);
104
- }
105
- };
106
- const priceChangeHandler = (change) => {
107
- if (tokenIds.includes(change.assetId)) {
108
- handlers.onPriceChange?.(change);
109
- }
110
- };
111
- const lastTradeHandler = (trade) => {
112
- if (tokenIds.includes(trade.assetId)) {
113
- handlers.onLastTrade?.(trade);
114
- }
115
- };
116
- const tickSizeHandler = (change) => {
117
- if (tokenIds.includes(change.assetId)) {
118
- handlers.onTickSizeChange?.(change);
119
- }
120
- };
121
- this.on('orderbook', orderbookHandler);
122
- this.on('priceChange', priceChangeHandler);
123
- this.on('lastTrade', lastTradeHandler);
124
- this.on('tickSizeChange', tickSizeHandler);
125
- const subscription = {
126
- id: subId,
127
- topic: 'clob_market',
128
- type: '*',
129
- tokenIds,
130
- unsubscribe: () => {
131
- this.off('orderbook', orderbookHandler);
132
- this.off('priceChange', priceChangeHandler);
133
- this.off('lastTrade', lastTradeHandler);
134
- this.off('tickSizeChange', tickSizeHandler);
135
- this.sendUnsubscription({ subscriptions });
136
- this.subscriptions.delete(subId);
137
- this.subscriptionMessages.delete(subId); // Remove from reconnection list
138
- },
139
- };
140
- this.subscriptions.set(subId, subscription);
141
- return subscription;
142
- }
143
- /**
144
- * Subscribe to a single market (YES + NO tokens)
145
- * Also emits derived price updates compatible with old API
146
- */
147
- subscribeMarket(yesTokenId, noTokenId, handlers = {}) {
148
- let lastYesUpdate;
149
- let lastNoUpdate;
150
- const checkPairUpdate = () => {
151
- if (lastYesUpdate && lastNoUpdate && handlers.onPairUpdate) {
152
- handlers.onPairUpdate({
153
- yes: lastYesUpdate,
154
- no: lastNoUpdate,
155
- spread: lastYesUpdate.price + lastNoUpdate.price,
156
- });
157
- }
158
- };
159
- return this.subscribeMarkets([yesTokenId, noTokenId], {
160
- onOrderbook: (book) => {
161
- handlers.onOrderbook?.(book);
162
- // Convert to BookUpdate for backward compatibility
163
- if (handlers.onBookUpdate) {
164
- const bookUpdate = {
165
- assetId: book.assetId,
166
- bids: book.bids,
167
- asks: book.asks,
168
- timestamp: book.timestamp,
169
- };
170
- handlers.onBookUpdate(bookUpdate);
171
- }
172
- // Calculate derived price (Polymarket display logic)
173
- const priceUpdate = this.calculateDerivedPrice(book.assetId, book);
174
- if (priceUpdate) {
175
- this.priceCache.set(book.assetId, priceUpdate);
176
- if (book.assetId === yesTokenId) {
177
- lastYesUpdate = priceUpdate;
178
- }
179
- else if (book.assetId === noTokenId) {
180
- lastNoUpdate = priceUpdate;
181
- }
182
- handlers.onPriceUpdate?.(priceUpdate);
183
- this.emit('priceUpdate', priceUpdate);
184
- checkPairUpdate();
185
- }
186
- },
187
- onLastTrade: (trade) => {
188
- handlers.onLastTrade?.(trade);
189
- this.lastTradeCache.set(trade.assetId, trade);
190
- // Recalculate derived price with new last trade
191
- const book = this.bookCache.get(trade.assetId);
192
- if (book) {
193
- const priceUpdate = this.calculateDerivedPrice(trade.assetId, book);
194
- if (priceUpdate) {
195
- this.priceCache.set(trade.assetId, priceUpdate);
196
- if (trade.assetId === yesTokenId) {
197
- lastYesUpdate = priceUpdate;
198
- }
199
- else if (trade.assetId === noTokenId) {
200
- lastNoUpdate = priceUpdate;
201
- }
202
- handlers.onPriceUpdate?.(priceUpdate);
203
- this.emit('priceUpdate', priceUpdate);
204
- checkPairUpdate();
205
- }
206
- }
207
- },
208
- onPriceChange: handlers.onPriceChange,
209
- onTickSizeChange: handlers.onTickSizeChange,
210
- onError: handlers.onError,
211
- });
212
- }
213
- /**
214
- * Subscribe to market lifecycle events (creation, resolution)
215
- */
216
- subscribeMarketEvents(handlers) {
217
- const subId = `market_event_${++this.subscriptionIdCounter}`;
218
- const subscriptions = [
219
- { topic: 'clob_market', type: 'market_created' },
220
- { topic: 'clob_market', type: 'market_resolved' },
221
- ];
222
- this.sendSubscription({ subscriptions });
223
- const handler = (event) => handlers.onMarketEvent?.(event);
224
- this.on('marketEvent', handler);
225
- const subscription = {
226
- id: subId,
227
- topic: 'clob_market',
228
- type: 'lifecycle',
229
- unsubscribe: () => {
230
- this.off('marketEvent', handler);
231
- this.sendUnsubscription({ subscriptions });
232
- this.subscriptions.delete(subId);
233
- },
234
- };
235
- this.subscriptions.set(subId, subscription);
236
- return subscription;
237
- }
238
- // ============================================================================
239
- // User Data Subscriptions (clob_user) - Requires Authentication
240
- // ============================================================================
241
- /**
242
- * Subscribe to user order and trade events
243
- * @param credentials - CLOB API credentials
244
- * @param handlers - Event handlers
245
- */
246
- subscribeUserEvents(credentials, handlers = {}) {
247
- const subId = `user_${++this.subscriptionIdCounter}`;
248
- const subscriptions = [
249
- { topic: 'clob_user', type: '*', clob_auth: credentials },
250
- ];
251
- this.sendSubscription({ subscriptions });
252
- const orderHandler = (order) => handlers.onOrder?.(order);
253
- const tradeHandler = (trade) => handlers.onTrade?.(trade);
254
- this.on('userOrder', orderHandler);
255
- this.on('userTrade', tradeHandler);
256
- const subscription = {
257
- id: subId,
258
- topic: 'clob_user',
259
- type: '*',
260
- unsubscribe: () => {
261
- this.off('userOrder', orderHandler);
262
- this.off('userTrade', tradeHandler);
263
- this.sendUnsubscription({ subscriptions });
264
- this.subscriptions.delete(subId);
265
- },
266
- };
267
- this.subscriptions.set(subId, subscription);
268
- return subscription;
269
- }
270
- // ============================================================================
271
- // Activity Subscriptions (trades, orders_matched)
272
- // ============================================================================
273
- /**
274
- * Subscribe to trading activity for a market or event
275
- * @param filter - Event or market slug (optional - if empty, subscribes to all activity)
276
- * @param handlers - Event handlers
277
- */
278
- subscribeActivity(filter = {}, handlers = {}) {
279
- const subId = `activity_${++this.subscriptionIdCounter}`;
280
- // Build filter object with snake_case keys (as expected by the server)
281
- // Only include filters if we have actual filter values
282
- const hasFilter = filter.eventSlug || filter.marketSlug;
283
- const filterObj = {};
284
- if (filter.eventSlug)
285
- filterObj.event_slug = filter.eventSlug;
286
- if (filter.marketSlug)
287
- filterObj.market_slug = filter.marketSlug;
288
- // Create subscription objects - only include filters field if we have filters
289
- const subscriptions = hasFilter
290
- ? [
291
- { topic: 'activity', type: 'trades', filters: JSON.stringify(filterObj) },
292
- { topic: 'activity', type: 'orders_matched', filters: JSON.stringify(filterObj) },
293
- ]
294
- : [
295
- { topic: 'activity', type: 'trades' },
296
- { topic: 'activity', type: 'orders_matched' },
297
- ];
298
- this.sendSubscription({ subscriptions });
299
- const handler = (trade) => handlers.onTrade?.(trade);
300
- this.on('activityTrade', handler);
301
- const subscription = {
302
- id: subId,
303
- topic: 'activity',
304
- type: '*',
305
- unsubscribe: () => {
306
- this.off('activityTrade', handler);
307
- this.sendUnsubscription({ subscriptions });
308
- this.subscriptions.delete(subId);
309
- },
310
- };
311
- this.subscriptions.set(subId, subscription);
312
- return subscription;
313
- }
314
- /**
315
- * Subscribe to ALL trading activity across all markets (no filtering)
316
- * This is useful for Copy Trading - monitoring Smart Money across the platform
317
- * @param handlers - Event handlers
318
- */
319
- subscribeAllActivity(handlers = {}) {
320
- return this.subscribeActivity({}, handlers);
321
- }
322
- // ============================================================================
323
- // Crypto Price Subscriptions
324
- // ============================================================================
325
- /**
326
- * Subscribe to crypto price updates
327
- * @param symbols - Array of symbols (e.g., ['BTCUSDT', 'ETHUSDT'])
328
- * @param handlers - Event handlers
329
- */
330
- subscribeCryptoPrices(symbols, handlers = {}) {
331
- const subId = `crypto_${++this.subscriptionIdCounter}`;
332
- // Subscribe to each symbol
333
- const subscriptions = symbols.map(symbol => ({
334
- topic: 'crypto_prices',
335
- type: 'update',
336
- filters: JSON.stringify({ symbol }),
337
- }));
338
- this.sendSubscription({ subscriptions });
339
- const handler = (price) => {
340
- if (symbols.includes(price.symbol)) {
341
- handlers.onPrice?.(price);
342
- }
343
- };
344
- this.on('cryptoPrice', handler);
345
- const subscription = {
346
- id: subId,
347
- topic: 'crypto_prices',
348
- type: 'update',
349
- unsubscribe: () => {
350
- this.off('cryptoPrice', handler);
351
- this.sendUnsubscription({ subscriptions });
352
- this.subscriptions.delete(subId);
353
- },
354
- };
355
- this.subscriptions.set(subId, subscription);
356
- return subscription;
357
- }
358
- /**
359
- * Subscribe to Chainlink crypto prices
360
- * @param symbols - Array of symbols (e.g., ['ETH/USD', 'BTC/USD'])
361
- */
362
- subscribeCryptoChainlinkPrices(symbols, handlers = {}) {
363
- const subId = `crypto_chainlink_${++this.subscriptionIdCounter}`;
364
- const subscriptions = symbols.map(symbol => ({
365
- topic: 'crypto_prices_chainlink',
366
- type: 'update',
367
- filters: JSON.stringify({ symbol }),
368
- }));
369
- const subMsg = { subscriptions };
370
- this.sendSubscription(subMsg);
371
- this.subscriptionMessages.set(subId, subMsg); // Store for reconnection
372
- const handler = (price) => {
373
- if (symbols.includes(price.symbol)) {
374
- handlers.onPrice?.(price);
375
- }
376
- };
377
- this.on('cryptoChainlinkPrice', handler);
378
- const subscription = {
379
- id: subId,
380
- topic: 'crypto_prices_chainlink',
381
- type: 'update',
382
- unsubscribe: () => {
383
- this.off('cryptoChainlinkPrice', handler);
384
- this.sendUnsubscription({ subscriptions });
385
- this.subscriptions.delete(subId);
386
- this.subscriptionMessages.delete(subId); // Remove from reconnection list
387
- },
388
- };
389
- this.subscriptions.set(subId, subscription);
390
- return subscription;
391
- }
392
- // ============================================================================
393
- // Equity Price Subscriptions
394
- // ============================================================================
395
- /**
396
- * Subscribe to equity price updates
397
- * @param symbols - Array of symbols (e.g., ['AAPL', 'GOOGL'])
398
- * @param handlers - Event handlers
399
- */
400
- subscribeEquityPrices(symbols, handlers = {}) {
401
- const subId = `equity_${++this.subscriptionIdCounter}`;
402
- const subscriptions = symbols.map(symbol => ({
403
- topic: 'equity_prices',
404
- type: 'update',
405
- filters: JSON.stringify({ symbol }),
406
- }));
407
- this.sendSubscription({ subscriptions });
408
- const handler = (price) => {
409
- if (symbols.includes(price.symbol)) {
410
- handlers.onPrice?.(price);
411
- }
412
- };
413
- this.on('equityPrice', handler);
414
- const subscription = {
415
- id: subId,
416
- topic: 'equity_prices',
417
- type: 'update',
418
- unsubscribe: () => {
419
- this.off('equityPrice', handler);
420
- this.sendUnsubscription({ subscriptions });
421
- this.subscriptions.delete(subId);
422
- },
423
- };
424
- this.subscriptions.set(subId, subscription);
425
- return subscription;
426
- }
427
- // ============================================================================
428
- // Comments Subscriptions
429
- // ============================================================================
430
- /**
431
- * Subscribe to comment and reaction events
432
- */
433
- subscribeComments(filter, handlers = {}) {
434
- const subId = `comments_${++this.subscriptionIdCounter}`;
435
- const filterStr = JSON.stringify({
436
- parentEntityID: filter.parentEntityId,
437
- parentEntityType: filter.parentEntityType,
438
- });
439
- const subscriptions = [
440
- { topic: 'comments', type: 'comment_created', filters: filterStr },
441
- { topic: 'comments', type: 'comment_removed', filters: filterStr },
442
- { topic: 'comments', type: 'reaction_created', filters: filterStr },
443
- { topic: 'comments', type: 'reaction_removed', filters: filterStr },
444
- ];
445
- this.sendSubscription({ subscriptions });
446
- const commentHandler = (comment) => handlers.onComment?.(comment);
447
- const reactionHandler = (reaction) => handlers.onReaction?.(reaction);
448
- this.on('comment', commentHandler);
449
- this.on('reaction', reactionHandler);
450
- const subscription = {
451
- id: subId,
452
- topic: 'comments',
453
- type: '*',
454
- unsubscribe: () => {
455
- this.off('comment', commentHandler);
456
- this.off('reaction', reactionHandler);
457
- this.sendUnsubscription({ subscriptions });
458
- this.subscriptions.delete(subId);
459
- },
460
- };
461
- this.subscriptions.set(subId, subscription);
462
- return subscription;
463
- }
464
- // ============================================================================
465
- // RFQ Subscriptions
466
- // ============================================================================
467
- /**
468
- * Subscribe to RFQ (Request for Quote) events
469
- */
470
- subscribeRFQ(handlers = {}) {
471
- const subId = `rfq_${++this.subscriptionIdCounter}`;
472
- const subscriptions = [
473
- { topic: 'rfq', type: 'request_created' },
474
- { topic: 'rfq', type: 'request_edited' },
475
- { topic: 'rfq', type: 'request_canceled' },
476
- { topic: 'rfq', type: 'request_expired' },
477
- { topic: 'rfq', type: 'quote_created' },
478
- { topic: 'rfq', type: 'quote_edited' },
479
- { topic: 'rfq', type: 'quote_canceled' },
480
- { topic: 'rfq', type: 'quote_expired' },
481
- ];
482
- this.sendSubscription({ subscriptions });
483
- const requestHandler = (request) => handlers.onRequest?.(request);
484
- const quoteHandler = (quote) => handlers.onQuote?.(quote);
485
- this.on('rfqRequest', requestHandler);
486
- this.on('rfqQuote', quoteHandler);
487
- const subscription = {
488
- id: subId,
489
- topic: 'rfq',
490
- type: '*',
491
- unsubscribe: () => {
492
- this.off('rfqRequest', requestHandler);
493
- this.off('rfqQuote', quoteHandler);
494
- this.sendUnsubscription({ subscriptions });
495
- this.subscriptions.delete(subId);
496
- },
497
- };
498
- this.subscriptions.set(subId, subscription);
499
- return subscription;
500
- }
501
- // ============================================================================
502
- // Cache Access
503
- // ============================================================================
504
- /**
505
- * Get cached derived price for an asset
506
- */
507
- getPrice(assetId) {
508
- return this.priceCache.get(assetId);
509
- }
510
- /**
511
- * Get all cached prices
512
- */
513
- getAllPrices() {
514
- return new Map(this.priceCache);
515
- }
516
- /**
517
- * Get cached orderbook for an asset
518
- */
519
- getBook(assetId) {
520
- return this.bookCache.get(assetId);
521
- }
522
- /**
523
- * Get cached last trade for an asset
524
- */
525
- getLastTrade(assetId) {
526
- return this.lastTradeCache.get(assetId);
527
- }
528
- // ============================================================================
529
- // Subscription Management
530
- // ============================================================================
531
- /**
532
- * Get all active subscriptions
533
- */
534
- getActiveSubscriptions() {
535
- return Array.from(this.subscriptions.values());
536
- }
537
- /**
538
- * Unsubscribe from all
539
- */
540
- unsubscribeAll() {
541
- for (const sub of this.subscriptions.values()) {
542
- sub.unsubscribe();
543
- }
544
- this.subscriptions.clear();
545
- this.subscriptionMessages.clear(); // Clear reconnection list
546
- }
547
- // ============================================================================
548
- // Private Methods
549
- // ============================================================================
550
- handleConnect(client) {
551
- this.connected = true;
552
- this.log('Connected to WebSocket server');
553
- // Re-subscribe to all active subscriptions on reconnect
554
- if (this.subscriptionMessages.size > 0) {
555
- this.log(`Re-subscribing to ${this.subscriptionMessages.size} subscriptions...`);
556
- for (const [subId, msg] of this.subscriptionMessages) {
557
- this.log(`Re-subscribing: ${subId}`);
558
- this.client?.subscribe(msg);
559
- }
560
- }
561
- this.emit('connected');
562
- }
563
- handleStatusChange(status) {
564
- this.log(`Connection status: ${status}`);
565
- if (status === ConnectionStatus.DISCONNECTED) {
566
- this.connected = false;
567
- this.emit('disconnected');
568
- }
569
- else if (status === ConnectionStatus.CONNECTED) {
570
- this.connected = true;
571
- }
572
- this.emit('statusChange', status);
573
- }
574
- handleMessage(client, message) {
575
- this.log(`Received: ${message.topic}:${message.type}`);
576
- const payload = message.payload;
577
- switch (message.topic) {
578
- case 'clob_market':
579
- this.handleMarketMessage(message.type, payload, message.timestamp);
580
- break;
581
- case 'clob_user':
582
- this.handleUserMessage(message.type, payload, message.timestamp);
583
- break;
584
- case 'activity':
585
- this.handleActivityMessage(message.type, payload, message.timestamp);
586
- break;
587
- case 'crypto_prices':
588
- this.handleCryptoPriceMessage(payload, message.timestamp);
589
- break;
590
- case 'crypto_prices_chainlink':
591
- this.handleCryptoChainlinkPriceMessage(payload, message.timestamp);
592
- break;
593
- case 'equity_prices':
594
- this.handleEquityPriceMessage(payload, message.timestamp);
595
- break;
596
- case 'comments':
597
- this.handleCommentMessage(message.type, payload, message.timestamp);
598
- break;
599
- case 'rfq':
600
- this.handleRFQMessage(message.type, payload, message.timestamp);
601
- break;
602
- default:
603
- this.log(`Unknown topic: ${message.topic}`);
604
- }
605
- }
606
- handleMarketMessage(type, payload, timestamp) {
607
- switch (type) {
608
- case 'agg_orderbook': {
609
- const book = this.parseOrderbook(payload, timestamp);
610
- this.bookCache.set(book.assetId, book);
611
- this.emit('orderbook', book);
612
- break;
613
- }
614
- case 'price_change': {
615
- const change = this.parsePriceChange(payload, timestamp);
616
- this.emit('priceChange', change);
617
- break;
618
- }
619
- case 'last_trade_price': {
620
- const trade = this.parseLastTrade(payload, timestamp);
621
- this.lastTradeCache.set(trade.assetId, trade);
622
- this.emit('lastTrade', trade);
623
- break;
624
- }
625
- case 'tick_size_change': {
626
- const change = this.parseTickSizeChange(payload, timestamp);
627
- this.emit('tickSizeChange', change);
628
- break;
629
- }
630
- case 'market_created':
631
- case 'market_resolved': {
632
- const event = {
633
- conditionId: payload.condition_id || '',
634
- type: type === 'market_created' ? 'created' : 'resolved',
635
- data: payload,
636
- timestamp,
637
- };
638
- this.emit('marketEvent', event);
639
- break;
640
- }
641
- }
642
- }
643
- handleUserMessage(type, payload, timestamp) {
644
- if (type === 'order') {
645
- const order = {
646
- orderId: payload.order_id || '',
647
- market: payload.market || '',
648
- asset: payload.asset || '',
649
- side: payload.side,
650
- price: Number(payload.price) || 0,
651
- originalSize: Number(payload.original_size) || 0,
652
- matchedSize: Number(payload.matched_size) || 0,
653
- eventType: payload.event_type,
654
- timestamp,
655
- };
656
- this.emit('userOrder', order);
657
- }
658
- else if (type === 'trade') {
659
- const trade = {
660
- tradeId: payload.trade_id || '',
661
- market: payload.market || '',
662
- outcome: payload.outcome || '',
663
- price: Number(payload.price) || 0,
664
- size: Number(payload.size) || 0,
665
- side: payload.side,
666
- status: payload.status,
667
- timestamp,
668
- transactionHash: payload.transaction_hash,
669
- };
670
- this.emit('userTrade', trade);
671
- }
672
- }
673
- handleActivityMessage(type, payload, timestamp) {
674
- const trade = {
675
- asset: payload.asset || '',
676
- conditionId: payload.conditionId || '',
677
- eventSlug: payload.eventSlug || '',
678
- marketSlug: payload.slug || '',
679
- outcome: payload.outcome || '',
680
- price: Number(payload.price) || 0,
681
- side: payload.side,
682
- size: Number(payload.size) || 0,
683
- timestamp: Number(payload.timestamp) || timestamp,
684
- transactionHash: payload.transactionHash || '',
685
- trader: {
686
- name: payload.name,
687
- address: payload.proxyWallet,
688
- },
689
- };
690
- this.emit('activityTrade', trade);
691
- }
692
- handleCryptoPriceMessage(payload, timestamp) {
693
- const price = {
694
- symbol: payload.symbol || '',
695
- price: Number(payload.value) || 0,
696
- timestamp: Number(payload.timestamp) || timestamp,
697
- };
698
- this.emit('cryptoPrice', price);
699
- }
700
- handleCryptoChainlinkPriceMessage(payload, timestamp) {
701
- const price = {
702
- symbol: payload.symbol || '',
703
- price: Number(payload.value) || 0,
704
- timestamp: Number(payload.timestamp) || timestamp,
705
- };
706
- this.emit('cryptoChainlinkPrice', price);
707
- }
708
- handleEquityPriceMessage(payload, timestamp) {
709
- const price = {
710
- symbol: payload.symbol || '',
711
- price: Number(payload.value) || 0,
712
- timestamp: Number(payload.timestamp) || timestamp,
713
- };
714
- this.emit('equityPrice', price);
715
- }
716
- handleCommentMessage(type, payload, timestamp) {
717
- if (type.includes('comment')) {
718
- const comment = {
719
- id: payload.id || '',
720
- parentEntityId: payload.parentEntityID || 0,
721
- parentEntityType: payload.parentEntityType,
722
- content: payload.content,
723
- author: payload.author,
724
- timestamp,
725
- };
726
- this.emit('comment', comment);
727
- }
728
- else if (type.includes('reaction')) {
729
- const reaction = {
730
- id: payload.id || '',
731
- commentId: payload.commentId || '',
732
- type: payload.type || '',
733
- author: payload.author,
734
- timestamp,
735
- };
736
- this.emit('reaction', reaction);
737
- }
738
- }
739
- handleRFQMessage(type, payload, timestamp) {
740
- if (type.startsWith('request_')) {
741
- const status = type.replace('request_', '');
742
- const request = {
743
- id: payload.id || '',
744
- market: payload.market || '',
745
- side: payload.side,
746
- size: Number(payload.size) || 0,
747
- status,
748
- timestamp,
749
- };
750
- this.emit('rfqRequest', request);
751
- }
752
- else if (type.startsWith('quote_')) {
753
- const status = type.replace('quote_', '');
754
- const quote = {
755
- id: payload.id || '',
756
- requestId: payload.request_id || '',
757
- price: Number(payload.price) || 0,
758
- size: Number(payload.size) || 0,
759
- status,
760
- timestamp,
761
- };
762
- this.emit('rfqQuote', quote);
763
- }
764
- }
765
- // Parsers
766
- parseOrderbook(payload, timestamp) {
767
- const bidsRaw = payload.bids || [];
768
- const asksRaw = payload.asks || [];
769
- // Sort bids descending, asks ascending
770
- const bids = bidsRaw
771
- .map(l => ({ price: parseFloat(l.price), size: parseFloat(l.size) }))
772
- .sort((a, b) => b.price - a.price);
773
- const asks = asksRaw
774
- .map(l => ({ price: parseFloat(l.price), size: parseFloat(l.size) }))
775
- .sort((a, b) => a.price - b.price);
776
- const tokenId = payload.asset_id || '';
777
- return {
778
- tokenId,
779
- assetId: tokenId, // Backward compatibility
780
- market: payload.market || '',
781
- bids,
782
- asks,
783
- timestamp: parseInt(payload.timestamp, 10) || timestamp,
784
- tickSize: payload.tick_size || '0.01',
785
- minOrderSize: payload.min_order_size || '1',
786
- hash: payload.hash || '',
787
- };
788
- }
789
- parsePriceChange(payload, timestamp) {
790
- const changes = payload.price_changes || [];
791
- return {
792
- assetId: payload.asset_id || '',
793
- changes,
794
- timestamp,
795
- };
796
- }
797
- parseLastTrade(payload, timestamp) {
798
- return {
799
- assetId: payload.asset_id || '',
800
- price: parseFloat(payload.price) || 0,
801
- side: payload.side || 'BUY',
802
- size: parseFloat(payload.size) || 0,
803
- timestamp: parseInt(payload.timestamp, 10) || timestamp,
804
- };
805
- }
806
- parseTickSizeChange(payload, timestamp) {
807
- return {
808
- assetId: payload.asset_id || '',
809
- oldTickSize: payload.old_tick_size || '',
810
- newTickSize: payload.new_tick_size || '',
811
- timestamp,
812
- };
813
- }
814
- /**
815
- * Calculate derived price using Polymarket's display logic:
816
- * - If spread <= 0.10: use midpoint
817
- * - If spread > 0.10: use last trade price
818
- */
819
- calculateDerivedPrice(assetId, book) {
820
- if (book.bids.length === 0 || book.asks.length === 0) {
821
- return null;
822
- }
823
- const bestBid = book.bids[0].price;
824
- const bestAsk = book.asks[0].price;
825
- const spread = bestAsk - bestBid;
826
- const midpoint = (bestBid + bestAsk) / 2;
827
- const lastTrade = this.lastTradeCache.get(assetId);
828
- const lastTradePrice = lastTrade?.price ?? midpoint;
829
- // Polymarket display logic
830
- const displayPrice = spread <= 0.10 ? midpoint : lastTradePrice;
831
- return {
832
- assetId,
833
- price: displayPrice,
834
- midpoint,
835
- spread,
836
- timestamp: book.timestamp,
837
- };
838
- }
839
- sendSubscription(msg) {
840
- if (this.client && this.connected) {
841
- this.client.subscribe(msg);
842
- }
843
- else {
844
- this.log('Cannot subscribe: not connected');
845
- }
846
- }
847
- sendUnsubscription(msg) {
848
- if (this.client && this.connected) {
849
- this.client.unsubscribe(msg);
850
- }
851
- }
852
- log(message) {
853
- if (this.config.debug) {
854
- console.log(`[RealtimeService] ${message}`);
855
- }
856
- }
857
- }
858
- //# sourceMappingURL=realtime-service-v2.js.map