pmxt-core 2.19.6 → 2.20.1

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 (59) hide show
  1. package/dist/BaseExchange.d.ts +69 -30
  2. package/dist/BaseExchange.js +124 -82
  3. package/dist/exchanges/baozi/index.d.ts +2 -0
  4. package/dist/exchanges/baozi/index.js +2 -0
  5. package/dist/exchanges/baozi/price.d.ts +3 -0
  6. package/dist/exchanges/baozi/price.js +16 -0
  7. package/dist/exchanges/baozi/price.test.d.ts +1 -0
  8. package/dist/exchanges/baozi/price.test.js +33 -0
  9. package/dist/exchanges/baozi/utils.js +5 -9
  10. package/dist/exchanges/kalshi/api.d.ts +1 -1
  11. package/dist/exchanges/kalshi/api.js +1 -1
  12. package/dist/exchanges/kalshi/fetchOHLCV.js +5 -4
  13. package/dist/exchanges/kalshi/fetchOrderBook.js +21 -21
  14. package/dist/exchanges/kalshi/fetchTrades.js +2 -1
  15. package/dist/exchanges/kalshi/index.d.ts +3 -1
  16. package/dist/exchanges/kalshi/index.js +19 -16
  17. package/dist/exchanges/kalshi/price.d.ts +3 -0
  18. package/dist/exchanges/kalshi/price.js +14 -0
  19. package/dist/exchanges/kalshi/price.test.d.ts +1 -0
  20. package/dist/exchanges/kalshi/price.test.js +24 -0
  21. package/dist/exchanges/kalshi/utils.js +5 -4
  22. package/dist/exchanges/limitless/api.d.ts +1 -1
  23. package/dist/exchanges/limitless/api.js +1 -1
  24. package/dist/exchanges/limitless/index.d.ts +58 -19
  25. package/dist/exchanges/limitless/index.js +169 -101
  26. package/dist/exchanges/limitless/websocket.d.ts +10 -3
  27. package/dist/exchanges/limitless/websocket.js +71 -52
  28. package/dist/exchanges/myriad/api.d.ts +1 -1
  29. package/dist/exchanges/myriad/api.js +1 -1
  30. package/dist/exchanges/myriad/index.d.ts +3 -1
  31. package/dist/exchanges/myriad/index.js +7 -4
  32. package/dist/exchanges/myriad/price.d.ts +1 -0
  33. package/dist/exchanges/myriad/price.js +7 -0
  34. package/dist/exchanges/myriad/price.test.d.ts +1 -0
  35. package/dist/exchanges/myriad/price.test.js +17 -0
  36. package/dist/exchanges/polymarket/api-clob.d.ts +1 -1
  37. package/dist/exchanges/polymarket/api-clob.js +1 -1
  38. package/dist/exchanges/polymarket/api-data.d.ts +1 -1
  39. package/dist/exchanges/polymarket/api-data.js +1 -1
  40. package/dist/exchanges/polymarket/api-gamma.d.ts +1 -1
  41. package/dist/exchanges/polymarket/api-gamma.js +1 -1
  42. package/dist/exchanges/polymarket/index.d.ts +28 -15
  43. package/dist/exchanges/polymarket/index.js +217 -137
  44. package/dist/exchanges/polymarket/websocket.d.ts +11 -4
  45. package/dist/exchanges/polymarket/websocket.js +58 -36
  46. package/dist/exchanges/probable/api.d.ts +1 -1
  47. package/dist/exchanges/probable/api.js +1 -1
  48. package/dist/exchanges/probable/index.d.ts +2 -0
  49. package/dist/exchanges/probable/index.js +2 -0
  50. package/dist/subscriber/base.d.ts +82 -0
  51. package/dist/subscriber/base.js +2 -0
  52. package/dist/subscriber/external/goldsky.d.ts +96 -0
  53. package/dist/subscriber/external/goldsky.js +412 -0
  54. package/dist/subscriber/watcher.d.ts +85 -0
  55. package/dist/subscriber/watcher.js +178 -0
  56. package/dist/types.d.ts +5 -0
  57. package/dist/utils/error-mapper.d.ts +8 -0
  58. package/dist/utils/error-mapper.js +58 -26
  59. package/package.json +3 -3
@@ -1,6 +1,7 @@
1
- import { UnifiedMarket, UnifiedEvent, PriceCandle, CandleInterval, OrderBook, Trade, UserTrade, Order, Position, Balance, CreateOrderParams, BuiltOrder } from './types';
2
- import { ExecutionPriceResult } from './utils/math';
3
1
  import { AxiosInstance } from 'axios';
2
+ import { SubscribedAddressSnapshot, SubscriptionOption } from './subscriber/base';
3
+ import { Balance, BuiltOrder, CandleInterval, CreateOrderParams, Order, OrderBook, Position, PriceCandle, Trade, UnifiedEvent, UnifiedMarket, UserTrade } from './types';
4
+ import { ExecutionPriceResult } from './utils/math';
4
5
  export interface ApiEndpoint {
5
6
  method: string;
6
7
  path: string;
@@ -140,6 +141,8 @@ export interface ExchangeHas {
140
141
  fetchOpenOrders: ExchangeCapability;
141
142
  fetchPositions: ExchangeCapability;
142
143
  fetchBalance: ExchangeCapability;
144
+ watchAddress: ExchangeCapability;
145
+ unwatchAddress: ExchangeCapability;
143
146
  watchOrderBook: ExchangeCapability;
144
147
  watchTrades: ExchangeCapability;
145
148
  fetchMyTrades: ExchangeCapability;
@@ -172,24 +175,28 @@ export interface PaginatedMarketsResult {
172
175
  }
173
176
  export declare abstract class PredictionMarketExchange {
174
177
  [key: string]: any;
175
- protected credentials?: ExchangeCredentials;
176
178
  verbose: boolean;
177
179
  http: AxiosInstance;
178
180
  enableRateLimit: boolean;
179
- private _rateLimit;
180
- private _throttler;
181
- private _snapshotTTL;
182
- private _snapshot?;
183
- get rateLimit(): number;
184
- set rateLimit(value: number);
185
181
  markets: Record<string, UnifiedMarket>;
186
182
  marketsBySlug: Record<string, UnifiedMarket>;
187
183
  loadedMarkets: boolean;
184
+ readonly has: ExchangeHas;
185
+ protected credentials?: ExchangeCredentials;
188
186
  protected apiDescriptor?: ApiDescriptor;
187
+ private _throttler;
188
+ private _snapshotTTL;
189
+ private _snapshot?;
189
190
  private apiDescriptors;
190
- readonly has: ExchangeHas;
191
191
  constructor(credentials?: ExchangeCredentials, options?: ExchangeOptions);
192
+ private _rateLimit;
193
+ get rateLimit(): number;
194
+ set rateLimit(value: number);
192
195
  abstract get name(): string;
196
+ /**
197
+ * Introspection getter: returns info about all implicit API methods.
198
+ */
199
+ get implicitApi(): ImplicitApiMethodInfo[];
193
200
  /**
194
201
  * Load and cache all markets from the exchange into `this.markets` and `this.marketsBySlug`.
195
202
  * Subsequent calls return the cached result without hitting the API again.
@@ -326,17 +333,6 @@ export declare abstract class PredictionMarketExchange {
326
333
  * event = exchange.fetch_event(event_id='TRUMP25DEC')
327
334
  */
328
335
  fetchEvent(params?: EventFetchParams): Promise<UnifiedEvent>;
329
- /**
330
- * @internal
331
- * Implementation for fetching/searching markets.
332
- * Exchanges should handle query, slug, and plain fetch cases based on params.
333
- */
334
- protected fetchMarketsImpl(params?: MarketFetchParams): Promise<UnifiedMarket[]>;
335
- /**
336
- * @internal
337
- * Implementation for searching events by keyword.
338
- */
339
- protected fetchEventsImpl(params: EventFetchParams): Promise<UnifiedEvent[]>;
340
336
  /**
341
337
  * Fetch historical OHLCV (candlestick) price data for a specific market outcome.
342
338
  *
@@ -562,6 +558,7 @@ export declare abstract class PredictionMarketExchange {
562
558
  /**
563
559
  * Fetch current user positions across all markets.
564
560
  *
561
+ * @param address - Optional public wallet address
565
562
  * @returns Array of user positions
566
563
  *
567
564
  * @example-ts Fetch positions
@@ -577,10 +574,11 @@ export declare abstract class PredictionMarketExchange {
577
574
  * print(f"{pos.outcome_label}: {pos.size} @ ${pos.entry_price}")
578
575
  * print(f"Unrealized P&L: ${pos.unrealized_pnl:.2f}")
579
576
  */
580
- fetchPositions(): Promise<Position[]>;
577
+ fetchPositions(address?: string): Promise<Position[]>;
581
578
  /**
582
579
  * Fetch account balances.
583
580
  *
581
+ * @param address - Optional public wallet address
584
582
  * @returns Array of account balances
585
583
  *
586
584
  * @example-ts Fetch balance
@@ -591,7 +589,7 @@ export declare abstract class PredictionMarketExchange {
591
589
  * balances = exchange.fetch_balance()
592
590
  * print(f"Available: ${balances[0].available}")
593
591
  */
594
- fetchBalance(): Promise<Balance[]>;
592
+ fetchBalance(address?: string): Promise<Balance[]>;
595
593
  /**
596
594
  * Calculate the volume-weighted average execution price for a given order size.
597
595
  * Returns 0 if the order cannot be fully filled.
@@ -720,6 +718,7 @@ export declare abstract class PredictionMarketExchange {
720
718
  * Returns a promise that resolves with the next trade(s). Call repeatedly in a loop to stream updates (CCXT Pro pattern).
721
719
  *
722
720
  * @param id - The Outcome ID to watch
721
+ * @param address - Public wallet address
723
722
  * @param since - Optional timestamp to filter trades from
724
723
  * @param limit - Optional limit for number of trades
725
724
  * @returns Promise that resolves with recent trades
@@ -738,7 +737,40 @@ export declare abstract class PredictionMarketExchange {
738
737
  * for trade in trades:
739
738
  * print(f"{trade.side} {trade.amount} @ {trade.price}")
740
739
  */
741
- watchTrades(id: string, since?: number, limit?: number): Promise<Trade[]>;
740
+ watchTrades(id: string, address?: string, since?: number, limit?: number): Promise<Trade[]>;
741
+ /**
742
+ * Stream activity for a public wallet address
743
+ * Returns a promise that resolves with the next activity snapshot whenever a change
744
+ * is detected. Call repeatedly in a loop to stream updates (CCXT Pro pattern).
745
+ *
746
+ * @param address - Public wallet address to watch
747
+ * @param types - Subset of activity to watch (default: all types)
748
+ * @returns Promise that resolves with the latest SubscribedAddressSnapshot snapshot
749
+ *
750
+ * @example-ts Stream wallet activity
751
+ * while (true) {
752
+ * const activity = await exchange.watchAddress('0xabc...', ['trades', 'positions']);
753
+ * console.log(activity.trades, activity.positions);
754
+ * }
755
+ *
756
+ * @example-python Stream wallet activity
757
+ * while True:
758
+ * activity = exchange.watch_address('0xabc...', ['trades', 'positions'])
759
+ * print(activity.trades, activity.positions)
760
+ */
761
+ watchAddress(address: string, types?: SubscriptionOption[]): Promise<SubscribedAddressSnapshot>;
762
+ /**
763
+ * Stop watching a previously registered wallet address and release its resource updates.
764
+ *
765
+ * @param address - Public wallet address to stop watching
766
+ *
767
+ * @example-ts Stop watching
768
+ * await exchange.unwatchAddress('0xabc...');
769
+ *
770
+ * @example-python Stop watching
771
+ * exchange.unwatch_address('0xabc...')
772
+ */
773
+ unwatchAddress(address: string): Promise<void>;
742
774
  /**
743
775
  * Close all WebSocket connections and clean up resources.
744
776
  * Call this when you're done streaming to properly release connections.
@@ -750,6 +782,17 @@ export declare abstract class PredictionMarketExchange {
750
782
  * exchange.close()
751
783
  */
752
784
  close(): Promise<void>;
785
+ /**
786
+ * @internal
787
+ * Implementation for fetching/searching markets.
788
+ * Exchanges should handle query, slug, and plain fetch cases based on params.
789
+ */
790
+ protected fetchMarketsImpl(params?: MarketFetchParams): Promise<UnifiedMarket[]>;
791
+ /**
792
+ * @internal
793
+ * Implementation for searching events by keyword.
794
+ */
795
+ protected fetchEventsImpl(params: EventFetchParams): Promise<UnifiedEvent[]>;
753
796
  /**
754
797
  * Call an implicit API method by its operationId (or auto-generated name).
755
798
  * Provides a typed entry point so unified methods can delegate to the implicit API
@@ -761,10 +804,6 @@ export declare abstract class PredictionMarketExchange {
761
804
  * Existing methods (unified API) are never overwritten.
762
805
  */
763
806
  protected defineImplicitApi(descriptor: ApiDescriptor): void;
764
- /**
765
- * Creates an async function for an implicit API endpoint.
766
- */
767
- private createImplicitMethod;
768
807
  /**
769
808
  * Returns auth headers for a private API call.
770
809
  * Exchanges should override this to provide authentication.
@@ -776,7 +815,7 @@ export declare abstract class PredictionMarketExchange {
776
815
  */
777
816
  protected mapImplicitApiError(error: any): any;
778
817
  /**
779
- * Introspection getter: returns info about all implicit API methods.
818
+ * Creates an async function for an implicit API endpoint.
780
819
  */
781
- get implicitApi(): ImplicitApiMethodInfo[];
820
+ private createImplicitMethod;
782
821
  }
@@ -4,41 +4,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.PredictionMarketExchange = void 0;
7
- const math_1 = require("./utils/math");
7
+ const axios_1 = __importDefault(require("axios"));
8
8
  const errors_1 = require("./errors");
9
+ const math_1 = require("./utils/math");
9
10
  const throttler_1 = require("./utils/throttler");
10
- const axios_1 = __importDefault(require("axios"));
11
11
  // ----------------------------------------------------------------------------
12
12
  // Base Exchange Class
13
13
  // ----------------------------------------------------------------------------
14
14
  class PredictionMarketExchange {
15
- credentials;
16
15
  verbose = false;
17
16
  http;
18
17
  enableRateLimit = true;
19
- _rateLimit = 1000;
20
- _throttler;
21
- // Snapshot state for cursor-based pagination
22
- _snapshotTTL;
23
- _snapshot;
24
- get rateLimit() {
25
- return this._rateLimit;
26
- }
27
- set rateLimit(value) {
28
- this._rateLimit = value;
29
- this._throttler = new throttler_1.Throttler({
30
- refillRate: 1 / value,
31
- capacity: 1,
32
- delay: 1,
33
- });
34
- }
35
18
  // Market Cache
36
19
  markets = {};
37
20
  marketsBySlug = {};
38
21
  loadedMarkets = false;
39
- // Implicit API (merged across multiple defineImplicitApi calls)
40
- apiDescriptor;
41
- apiDescriptors = [];
42
22
  has = {
43
23
  fetchMarkets: false,
44
24
  fetchEvents: false,
@@ -51,6 +31,8 @@ class PredictionMarketExchange {
51
31
  fetchOpenOrders: false,
52
32
  fetchPositions: false,
53
33
  fetchBalance: false,
34
+ watchAddress: false,
35
+ unwatchAddress: false,
54
36
  watchOrderBook: false,
55
37
  watchTrades: false,
56
38
  fetchMyTrades: false,
@@ -59,6 +41,14 @@ class PredictionMarketExchange {
59
41
  buildOrder: false,
60
42
  submitOrder: false,
61
43
  };
44
+ credentials;
45
+ // Implicit API (merged across multiple defineImplicitApi calls)
46
+ apiDescriptor;
47
+ _throttler;
48
+ // Snapshot state for cursor-based pagination
49
+ _snapshotTTL;
50
+ _snapshot;
51
+ apiDescriptors = [];
62
52
  constructor(credentials, options) {
63
53
  this.credentials = credentials;
64
54
  this._snapshotTTL = options?.snapshotTTL ?? 0;
@@ -94,7 +84,7 @@ class PredictionMarketExchange {
94
84
  this.http.interceptors.response.use((response) => {
95
85
  if (this.verbose) {
96
86
  console.log(`\n[pmxt] ← ${response.status} ${response.statusText} ${response.config.url}`);
97
- // console.log('[pmxt] response:', JSON.stringify(response.data, null, 2));
87
+ // console.log('[pmxt] response:', JSON.stringify(response.data, null, 2));
98
88
  // Commented out full body log to avoid spam, but headers might be useful
99
89
  }
100
90
  return response;
@@ -110,6 +100,31 @@ class PredictionMarketExchange {
110
100
  return Promise.reject(error);
111
101
  });
112
102
  }
103
+ _rateLimit = 1000;
104
+ get rateLimit() {
105
+ return this._rateLimit;
106
+ }
107
+ set rateLimit(value) {
108
+ this._rateLimit = value;
109
+ this._throttler = new throttler_1.Throttler({
110
+ refillRate: 1 / value,
111
+ capacity: 1,
112
+ delay: 1,
113
+ });
114
+ }
115
+ /**
116
+ * Introspection getter: returns info about all implicit API methods.
117
+ */
118
+ get implicitApi() {
119
+ if (!this.apiDescriptor)
120
+ return [];
121
+ return Object.entries(this.apiDescriptor.endpoints).map(([name, endpoint]) => ({
122
+ name,
123
+ method: endpoint.method,
124
+ path: endpoint.path,
125
+ isPrivate: !!endpoint.isPrivate,
126
+ }));
127
+ }
113
128
  /**
114
129
  * Load and cache all markets from the exchange into `this.markets` and `this.marketsBySlug`.
115
130
  * Subsequent calls return the cached result without hitting the API again.
@@ -303,6 +318,9 @@ class PredictionMarketExchange {
303
318
  }
304
319
  return markets[0];
305
320
  }
321
+ // ----------------------------------------------------------------------------
322
+ // Implementation methods (to be overridden by exchanges)
323
+ // ----------------------------------------------------------------------------
306
324
  /**
307
325
  * Fetch a single event by lookup parameters.
308
326
  * Convenience wrapper around fetchEvents() that returns a single result or throws EventNotFound.
@@ -325,24 +343,6 @@ class PredictionMarketExchange {
325
343
  }
326
344
  return events[0];
327
345
  }
328
- // ----------------------------------------------------------------------------
329
- // Implementation methods (to be overridden by exchanges)
330
- // ----------------------------------------------------------------------------
331
- /**
332
- * @internal
333
- * Implementation for fetching/searching markets.
334
- * Exchanges should handle query, slug, and plain fetch cases based on params.
335
- */
336
- async fetchMarketsImpl(params) {
337
- throw new Error("Method fetchMarketsImpl not implemented.");
338
- }
339
- /**
340
- * @internal
341
- * Implementation for searching events by keyword.
342
- */
343
- async fetchEventsImpl(params) {
344
- throw new Error("Method fetchEventsImpl not implemented.");
345
- }
346
346
  /**
347
347
  * Fetch historical OHLCV (candlestick) price data for a specific market outcome.
348
348
  *
@@ -422,9 +422,6 @@ class PredictionMarketExchange {
422
422
  }
423
423
  throw new Error("Method fetchTrades not implemented.");
424
424
  }
425
- // ----------------------------------------------------------------------------
426
- // Trading Methods
427
- // ----------------------------------------------------------------------------
428
425
  /**
429
426
  * Place a new order on the exchange.
430
427
  *
@@ -474,6 +471,9 @@ class PredictionMarketExchange {
474
471
  async createOrder(params) {
475
472
  throw new Error("Method createOrder not implemented.");
476
473
  }
474
+ // ----------------------------------------------------------------------------
475
+ // Trading Methods
476
+ // ----------------------------------------------------------------------------
477
477
  /**
478
478
  * Build an order payload without submitting it to the exchange.
479
479
  * Returns the exchange-native signed order or request body for inspection,
@@ -507,7 +507,7 @@ class PredictionMarketExchange {
507
507
  * order = exchange.submit_order(built)
508
508
  */
509
509
  async buildOrder(params) {
510
- throw new Error("Method buildOrder not implemented.");
510
+ throw new Error('Method buildOrder not implemented.');
511
511
  }
512
512
  /**
513
513
  * Submit a pre-built order returned by buildOrder().
@@ -526,7 +526,7 @@ class PredictionMarketExchange {
526
526
  * print(f"Order {order.id}: {order.status}")
527
527
  */
528
528
  async submitOrder(built) {
529
- throw new Error("Method submitOrder not implemented.");
529
+ throw new Error('Method submitOrder not implemented.');
530
530
  }
531
531
  /**
532
532
  * Cancel an existing open order.
@@ -600,6 +600,7 @@ class PredictionMarketExchange {
600
600
  /**
601
601
  * Fetch current user positions across all markets.
602
602
  *
603
+ * @param address - Optional public wallet address
603
604
  * @returns Array of user positions
604
605
  *
605
606
  * @example-ts Fetch positions
@@ -615,12 +616,13 @@ class PredictionMarketExchange {
615
616
  * print(f"{pos.outcome_label}: {pos.size} @ ${pos.entry_price}")
616
617
  * print(f"Unrealized P&L: ${pos.unrealized_pnl:.2f}")
617
618
  */
618
- async fetchPositions() {
619
+ async fetchPositions(address) {
619
620
  throw new Error("Method fetchPositions not implemented.");
620
621
  }
621
622
  /**
622
623
  * Fetch account balances.
623
624
  *
625
+ * @param address - Optional public wallet address
624
626
  * @returns Array of account balances
625
627
  *
626
628
  * @example-ts Fetch balance
@@ -631,7 +633,7 @@ class PredictionMarketExchange {
631
633
  * balances = exchange.fetch_balance()
632
634
  * print(f"Available: ${balances[0].available}")
633
635
  */
634
- async fetchBalance() {
636
+ async fetchBalance(address) {
635
637
  throw new Error("Method fetchBalance not implemented.");
636
638
  }
637
639
  /**
@@ -681,9 +683,6 @@ class PredictionMarketExchange {
681
683
  getExecutionPriceDetailed(orderBook, side, amount) {
682
684
  return (0, math_1.getExecutionPriceDetailed)(orderBook, side, amount);
683
685
  }
684
- // ----------------------------------------------------------------------------
685
- // Filtering Methods
686
- // ----------------------------------------------------------------------------
687
686
  /**
688
687
  * Filter a list of markets by criteria.
689
688
  * Can filter by string query, structured criteria object, or custom filter function.
@@ -847,6 +846,9 @@ class PredictionMarketExchange {
847
846
  return true;
848
847
  });
849
848
  }
849
+ // ----------------------------------------------------------------------------
850
+ // Filtering Methods
851
+ // ----------------------------------------------------------------------------
850
852
  /**
851
853
  * Filter a list of events by criteria.
852
854
  * Can filter by string query, structured criteria object, or custom filter function.
@@ -938,9 +940,6 @@ class PredictionMarketExchange {
938
940
  return true;
939
941
  });
940
942
  }
941
- // ----------------------------------------------------------------------------
942
- // WebSocket Streaming Methods
943
- // ----------------------------------------------------------------------------
944
943
  /**
945
944
  * Watch order book updates in real-time via WebSocket.
946
945
  * Returns a promise that resolves with the next order book update. Call repeatedly in a loop to stream updates (CCXT Pro pattern).
@@ -963,11 +962,15 @@ class PredictionMarketExchange {
963
962
  async watchOrderBook(id, limit) {
964
963
  throw new Error(`watchOrderBook() is not supported by ${this.name}`);
965
964
  }
965
+ // ----------------------------------------------------------------------------
966
+ // WebSocket Streaming Methods
967
+ // ----------------------------------------------------------------------------
966
968
  /**
967
969
  * Watch trade executions in real-time via WebSocket.
968
970
  * Returns a promise that resolves with the next trade(s). Call repeatedly in a loop to stream updates (CCXT Pro pattern).
969
971
  *
970
972
  * @param id - The Outcome ID to watch
973
+ * @param address - Public wallet address
971
974
  * @param since - Optional timestamp to filter trades from
972
975
  * @param limit - Optional limit for number of trades
973
976
  * @returns Promise that resolves with recent trades
@@ -986,9 +989,46 @@ class PredictionMarketExchange {
986
989
  * for trade in trades:
987
990
  * print(f"{trade.side} {trade.amount} @ {trade.price}")
988
991
  */
989
- async watchTrades(id, since, limit) {
992
+ async watchTrades(id, address, since, limit) {
990
993
  throw new Error(`watchTrades() is not supported by ${this.name}`);
991
994
  }
995
+ /**
996
+ * Stream activity for a public wallet address
997
+ * Returns a promise that resolves with the next activity snapshot whenever a change
998
+ * is detected. Call repeatedly in a loop to stream updates (CCXT Pro pattern).
999
+ *
1000
+ * @param address - Public wallet address to watch
1001
+ * @param types - Subset of activity to watch (default: all types)
1002
+ * @returns Promise that resolves with the latest SubscribedAddressSnapshot snapshot
1003
+ *
1004
+ * @example-ts Stream wallet activity
1005
+ * while (true) {
1006
+ * const activity = await exchange.watchAddress('0xabc...', ['trades', 'positions']);
1007
+ * console.log(activity.trades, activity.positions);
1008
+ * }
1009
+ *
1010
+ * @example-python Stream wallet activity
1011
+ * while True:
1012
+ * activity = exchange.watch_address('0xabc...', ['trades', 'positions'])
1013
+ * print(activity.trades, activity.positions)
1014
+ */
1015
+ async watchAddress(address, types) {
1016
+ throw new Error(`watchAddress() is not supported by ${this.name}`);
1017
+ }
1018
+ /**
1019
+ * Stop watching a previously registered wallet address and release its resource updates.
1020
+ *
1021
+ * @param address - Public wallet address to stop watching
1022
+ *
1023
+ * @example-ts Stop watching
1024
+ * await exchange.unwatchAddress('0xabc...');
1025
+ *
1026
+ * @example-python Stop watching
1027
+ * exchange.unwatch_address('0xabc...')
1028
+ */
1029
+ async unwatchAddress(address) {
1030
+ throw new Error(`unwatchAddress() is not supported by ${this.name}`);
1031
+ }
992
1032
  /**
993
1033
  * Close all WebSocket connections and clean up resources.
994
1034
  * Call this when you're done streaming to properly release connections.
@@ -1003,9 +1043,24 @@ class PredictionMarketExchange {
1003
1043
  // Default implementation: no-op
1004
1044
  // Exchanges with WebSocket support should override this
1005
1045
  }
1046
+ /**
1047
+ * @internal
1048
+ * Implementation for fetching/searching markets.
1049
+ * Exchanges should handle query, slug, and plain fetch cases based on params.
1050
+ */
1051
+ async fetchMarketsImpl(params) {
1052
+ throw new Error("Method fetchMarketsImpl not implemented.");
1053
+ }
1006
1054
  // ----------------------------------------------------------------------------
1007
1055
  // Implicit API (OpenAPI-driven method generation)
1008
1056
  // ----------------------------------------------------------------------------
1057
+ /**
1058
+ * @internal
1059
+ * Implementation for searching events by keyword.
1060
+ */
1061
+ async fetchEventsImpl(params) {
1062
+ throw new Error("Method fetchEventsImpl not implemented.");
1063
+ }
1009
1064
  /**
1010
1065
  * Call an implicit API method by its operationId (or auto-generated name).
1011
1066
  * Provides a typed entry point so unified methods can delegate to the implicit API
@@ -1039,6 +1094,20 @@ class PredictionMarketExchange {
1039
1094
  this[name] = this.createImplicitMethod(name, endpoint, descriptor.baseUrl);
1040
1095
  }
1041
1096
  }
1097
+ /**
1098
+ * Returns auth headers for a private API call.
1099
+ * Exchanges should override this to provide authentication.
1100
+ */
1101
+ sign(_method, _path, _params) {
1102
+ return {};
1103
+ }
1104
+ /**
1105
+ * Maps errors from implicit API calls through the exchange's error mapper.
1106
+ * Exchanges should override this to use their specific error mapper.
1107
+ */
1108
+ mapImplicitApiError(error) {
1109
+ throw error;
1110
+ }
1042
1111
  /**
1043
1112
  * Creates an async function for an implicit API endpoint.
1044
1113
  */
@@ -1089,32 +1158,5 @@ class PredictionMarketExchange {
1089
1158
  }
1090
1159
  };
1091
1160
  }
1092
- /**
1093
- * Returns auth headers for a private API call.
1094
- * Exchanges should override this to provide authentication.
1095
- */
1096
- sign(_method, _path, _params) {
1097
- return {};
1098
- }
1099
- /**
1100
- * Maps errors from implicit API calls through the exchange's error mapper.
1101
- * Exchanges should override this to use their specific error mapper.
1102
- */
1103
- mapImplicitApiError(error) {
1104
- throw error;
1105
- }
1106
- /**
1107
- * Introspection getter: returns info about all implicit API methods.
1108
- */
1109
- get implicitApi() {
1110
- if (!this.apiDescriptor)
1111
- return [];
1112
- return Object.entries(this.apiDescriptor.endpoints).map(([name, endpoint]) => ({
1113
- name,
1114
- method: endpoint.method,
1115
- path: endpoint.path,
1116
- isPrivate: !!endpoint.isPrivate,
1117
- }));
1118
- }
1119
1161
  }
1120
1162
  exports.PredictionMarketExchange = PredictionMarketExchange;
@@ -17,6 +17,8 @@ export declare class BaoziExchange extends PredictionMarketExchange {
17
17
  fetchOpenOrders: "emulated";
18
18
  fetchPositions: true;
19
19
  fetchBalance: true;
20
+ watchAddress: false;
21
+ unwatchAddress: false;
20
22
  watchOrderBook: true;
21
23
  watchTrades: false;
22
24
  fetchMyTrades: false;
@@ -26,6 +26,8 @@ class BaoziExchange extends BaseExchange_1.PredictionMarketExchange {
26
26
  fetchOpenOrders: 'emulated',
27
27
  fetchPositions: true,
28
28
  fetchBalance: true,
29
+ watchAddress: false,
30
+ unwatchAddress: false,
29
31
  watchOrderBook: true,
30
32
  watchTrades: false,
31
33
  fetchMyTrades: false,
@@ -0,0 +1,3 @@
1
+ import { MarketOutcome } from "../../types";
2
+ export declare function clampBaoziPrice(value: number): number;
3
+ export declare function normalizeBaoziOutcomes(outcomes: MarketOutcome[]): void;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.clampBaoziPrice = clampBaoziPrice;
4
+ exports.normalizeBaoziOutcomes = normalizeBaoziOutcomes;
5
+ function clampBaoziPrice(value) {
6
+ return Math.min(Math.max(value, 0), 1);
7
+ }
8
+ function normalizeBaoziOutcomes(outcomes) {
9
+ const sum = outcomes.reduce((acc, item) => acc + item.price, 0);
10
+ if (sum <= 0) {
11
+ return;
12
+ }
13
+ for (const outcome of outcomes) {
14
+ outcome.price = outcome.price / sum;
15
+ }
16
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const price_1 = require("./price");
4
+ describe("clampBaoziPrice", () => {
5
+ test("clamps values below 0 to 0", () => {
6
+ expect((0, price_1.clampBaoziPrice)(-0.1)).toBe(0);
7
+ });
8
+ test("clamps values above 1 to 1", () => {
9
+ expect((0, price_1.clampBaoziPrice)(1.2)).toBe(1);
10
+ });
11
+ test("leaves values in range unchanged", () => {
12
+ expect((0, price_1.clampBaoziPrice)(0.3)).toBe(0.3);
13
+ expect((0, price_1.clampBaoziPrice)(0)).toBe(0);
14
+ expect((0, price_1.clampBaoziPrice)(1)).toBe(1);
15
+ });
16
+ });
17
+ describe("normalizeBaoziOutcomes", () => {
18
+ function makeOutcome(price) {
19
+ return { outcomeId: "x", marketId: "m", label: "X", price };
20
+ }
21
+ test("normalizes prices to sum to 1", () => {
22
+ const outcomes = [makeOutcome(2), makeOutcome(3)];
23
+ (0, price_1.normalizeBaoziOutcomes)(outcomes);
24
+ expect(outcomes[0].price).toBeCloseTo(0.4);
25
+ expect(outcomes[1].price).toBeCloseTo(0.6);
26
+ });
27
+ test("does nothing when sum is zero", () => {
28
+ const outcomes = [makeOutcome(0), makeOutcome(0)];
29
+ (0, price_1.normalizeBaoziOutcomes)(outcomes);
30
+ expect(outcomes[0].price).toBe(0);
31
+ expect(outcomes[1].price).toBe(0);
32
+ });
33
+ });