@alango/dr-manhattan 0.1.4 → 0.1.6

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.
package/README.md CHANGED
@@ -16,6 +16,7 @@ CCXT-style unified API for prediction markets in TypeScript.
16
16
  | [Limitless](https://limitless.exchange) | ✅ | ✅ | Base |
17
17
  | [Opinion](https://opinion.trade) | ✅ | ❌ | BNB |
18
18
  | [Kalshi](https://kalshi.com) | ✅ | ❌ | - |
19
+ | [Predict.fun](https://predict.fun) | ✅ | ❌ | BNB |
19
20
 
20
21
  ## Installation
21
22
 
@@ -33,7 +34,7 @@ yarn add @alango/dr-manhattan
33
34
  import { createExchange, listExchanges, MarketUtils } from '@alango/dr-manhattan';
34
35
 
35
36
  // List available exchanges
36
- console.log(listExchanges()); // ['polymarket', 'limitless', 'opinion', 'kalshi']
37
+ console.log(listExchanges()); // ['polymarket', 'limitless', 'opinion', 'kalshi', 'predictfun']
37
38
 
38
39
  // Create exchange instance (no auth required for public data)
39
40
  const polymarket = createExchange('polymarket');
@@ -139,6 +140,47 @@ const order = await kalshi.createOrder({
139
140
  });
140
141
  ```
141
142
 
143
+ ### Predict.fun
144
+
145
+ ```typescript
146
+ import { PredictFun } from '@alango/dr-manhattan';
147
+
148
+ // Mainnet
149
+ const predictfun = new PredictFun({
150
+ apiKey: process.env.PREDICTFUN_API_KEY,
151
+ privateKey: process.env.PRIVATE_KEY,
152
+ });
153
+
154
+ // Testnet
155
+ const predictfunTestnet = new PredictFun({
156
+ apiKey: process.env.PREDICTFUN_API_KEY,
157
+ privateKey: process.env.PRIVATE_KEY,
158
+ testnet: true,
159
+ });
160
+
161
+ // Fetch markets (no auth required for public data)
162
+ const markets = await predictfun.fetchMarkets({ limit: 10 });
163
+
164
+ // Get orderbook
165
+ const orderbook = await predictfun.getOrderbook(marketId);
166
+
167
+ // Create order (auth required)
168
+ const order = await predictfun.createOrder({
169
+ marketId: '123',
170
+ outcome: 'Yes',
171
+ side: OrderSide.BUY,
172
+ price: 0.55,
173
+ size: 100,
174
+ });
175
+
176
+ // Fetch positions
177
+ const positions = await predictfun.fetchPositions();
178
+
179
+ // Fetch balance
180
+ const balance = await predictfun.fetchBalance();
181
+ console.log(`USDT: ${balance.USDT}`);
182
+ ```
183
+
142
184
  ## API Reference
143
185
 
144
186
  ### Exchange Methods
@@ -381,15 +423,53 @@ interface ExchangeConfig {
381
423
 
382
424
  See the [examples/](examples/) directory:
383
425
 
384
- - **list-markets.ts** - Fetch and display markets
385
- - **websocket-orderbook.ts** - Real-time orderbook streaming
386
- - **spread-strategy.ts** - Market making strategy with inventory management
426
+ | Example | Description | Exchanges |
427
+ |---------|-------------|-----------|
428
+ | **list-markets.ts** | Fetch and display markets from all exchanges | All |
429
+ | **websocket-orderbook.ts** | Real-time orderbook streaming via WebSocket | Polymarket |
430
+ | **spread-strategy.ts** | Market making strategy with inventory management | All |
431
+ | **spike-strategy.ts** | Mean reversion strategy - buys price spikes | All |
432
+ | **weather-bot-strategy.ts** | London temperature bucket mispricing strategy | Polymarket |
433
+
434
+ ### Running Examples
387
435
 
388
436
  ```bash
389
- # Run examples
437
+ # List markets from all exchanges
390
438
  npx tsx examples/list-markets.ts
439
+
440
+ # WebSocket orderbook streaming (Polymarket)
391
441
  npx tsx examples/websocket-orderbook.ts
392
- npx tsx examples/spread-strategy.ts # Requires PRIVATE_KEY env var for real trades
442
+
443
+ # Spread strategy - works with any exchange
444
+ # Polymarket (WebSocket)
445
+ EXCHANGE=polymarket PRIVATE_KEY=0x... npx tsx examples/spread-strategy.ts
446
+
447
+ # Limitless (WebSocket)
448
+ EXCHANGE=limitless PRIVATE_KEY=0x... npx tsx examples/spread-strategy.ts
449
+
450
+ # Kalshi (REST polling)
451
+ EXCHANGE=kalshi KALSHI_API_KEY_ID=... KALSHI_PRIVATE_KEY_PATH=./key.pem npx tsx examples/spread-strategy.ts
452
+
453
+ # Predict.fun (REST polling)
454
+ EXCHANGE=predictfun PREDICTFUN_API_KEY=... PRIVATE_KEY=0x... npx tsx examples/spread-strategy.ts
455
+
456
+ # Opinion (REST polling)
457
+ EXCHANGE=opinion OPINION_API_KEY=... PRIVATE_KEY=0x... npx tsx examples/spread-strategy.ts
458
+
459
+ # Simulation mode (no credentials = no real trades)
460
+ EXCHANGE=polymarket npx tsx examples/spread-strategy.ts
461
+
462
+ # Spike strategy - mean reversion (buys dips)
463
+ EXCHANGE=polymarket PRIVATE_KEY=0x... npx tsx examples/spike-strategy.ts
464
+
465
+ # Spike strategy with custom parameters
466
+ npx tsx examples/spike-strategy.ts --spike-threshold 0.02 --profit-target 0.03 --stop-loss 0.02
467
+
468
+ # Weather bot strategy - London temperature bucket mispricing
469
+ npx tsx examples/weather-bot-strategy.ts --dry-run
470
+
471
+ # Weather bot with live trading
472
+ PRIVATE_KEY=0x... npx tsx examples/weather-bot-strategy.ts --order-size 5
393
473
  ```
394
474
 
395
475
  ## Requirements
package/dist/index.d.ts CHANGED
@@ -694,6 +694,8 @@ declare class Polymarket extends Exchange {
694
694
  private clobClient;
695
695
  private wallet;
696
696
  private address;
697
+ private clobClientAuthenticated;
698
+ private authConfig;
697
699
  constructor(config?: PolymarketConfig);
698
700
  describe(): {
699
701
  has: {
@@ -711,6 +713,7 @@ declare class Polymarket extends Exchange {
711
713
  name: string;
712
714
  };
713
715
  private initializeClobClient;
716
+ private ensureAuthenticated;
714
717
  fetchMarkets(params?: FetchMarketsParams): Promise<Market[]>;
715
718
  fetchMarket(marketId: string): Promise<Market>;
716
719
  fetchMarketsBySlug(slugOrUrl: string): Promise<Market[]>;
@@ -732,6 +735,7 @@ declare class Polymarket extends Exchange {
732
735
  }>;
733
736
  private parseMarketIdentifier;
734
737
  private parseSamplingMarket;
738
+ private parseClobMarket;
735
739
  private parseGammaMarket;
736
740
  private parseOrder;
737
741
  private parseOrderStatus;
@@ -780,17 +784,96 @@ interface PolymarketWsConfig extends WebSocketConfig {
780
784
  }
781
785
  declare class PolymarketWebSocket extends OrderBookWebSocket {
782
786
  readonly wsUrl = "wss://ws-subscriptions-clob.polymarket.com/ws/market";
783
- private apiKey?;
784
787
  private assetSubscriptions;
788
+ private initialSubscriptionSent;
785
789
  constructor(config?: PolymarketWsConfig);
786
790
  protected authenticate(): Promise<void>;
787
791
  protected subscribeOrderbook(marketId: string): Promise<void>;
788
792
  protected unsubscribeOrderbook(marketId: string): Promise<void>;
793
+ protected startPingTimer(): void;
794
+ protected handleMessage(data: WebSocket.RawData): void;
789
795
  protected parseOrderbookMessage(message: Record<string, unknown>): OrderbookUpdate | null;
790
796
  watchOrderbookWithAsset(marketId: string, assetId: string, callback: (marketId: string, orderbook: OrderbookUpdate) => void | Promise<void>): Promise<void>;
791
797
  private findMarketIdByAsset;
792
798
  }
793
799
 
800
+ /**
801
+ * Predict.fun Exchange implementation for dr-manhattan.
802
+ *
803
+ * Predict.fun is a prediction market on BNB Chain with CLOB-style orderbook.
804
+ * Uses REST API for communication and EIP-712 for order signing.
805
+ *
806
+ * API Documentation: https://dev.predict.fun/
807
+ */
808
+
809
+ interface PredictFunConfig extends ExchangeConfig {
810
+ /** Use testnet API */
811
+ testnet?: boolean;
812
+ /** Custom API host */
813
+ host?: string;
814
+ }
815
+ declare class PredictFun extends Exchange {
816
+ readonly id = "predictfun";
817
+ readonly name = "Predict.fun";
818
+ private readonly host;
819
+ private readonly chainId;
820
+ private readonly testnet;
821
+ private wallet;
822
+ private address;
823
+ private jwtToken;
824
+ private authenticated;
825
+ private readonly yieldBearingCtfExchange;
826
+ private readonly yieldBearingNegRiskCtfExchange;
827
+ private readonly ctfExchange;
828
+ private readonly negRiskCtfExchange;
829
+ constructor(config?: PredictFunConfig);
830
+ private getHeaders;
831
+ private authenticate;
832
+ private ensureAuth;
833
+ private request;
834
+ private parseMarket;
835
+ private parseOrder;
836
+ private parseOrderStatus;
837
+ private parsePosition;
838
+ fetchMarkets(params?: FetchMarketsParams): Promise<Market[]>;
839
+ fetchMarket(marketId: string): Promise<Market>;
840
+ getOrderbook(marketId: string): Promise<{
841
+ bids: Array<{
842
+ price: string;
843
+ size: string;
844
+ }>;
845
+ asks: Array<{
846
+ price: string;
847
+ size: string;
848
+ }>;
849
+ }>;
850
+ fetchTokenIds(marketId: string): Promise<string[]>;
851
+ createOrder(params: CreateOrderParams): Promise<Order>;
852
+ private buildSignedOrder;
853
+ private signOrderEip712;
854
+ cancelOrder(orderId: string, marketId?: string): Promise<Order>;
855
+ fetchOrder(orderId: string, _marketId?: string): Promise<Order>;
856
+ fetchOpenOrders(marketId?: string): Promise<Order[]>;
857
+ fetchPositions(marketId?: string): Promise<Position[]>;
858
+ fetchBalance(): Promise<Record<string, number>>;
859
+ get walletAddress(): string | null;
860
+ describe(): {
861
+ id: string;
862
+ name: string;
863
+ has: {
864
+ fetchMarkets: boolean;
865
+ fetchMarket: boolean;
866
+ createOrder: boolean;
867
+ cancelOrder: boolean;
868
+ fetchOrder: boolean;
869
+ fetchOpenOrders: boolean;
870
+ fetchPositions: boolean;
871
+ fetchBalance: boolean;
872
+ websocket: boolean;
873
+ };
874
+ };
875
+ }
876
+
794
877
  declare function listExchanges(): string[];
795
878
  declare function createExchange(exchangeId: string, config?: ExchangeConfig): Exchange;
796
879
 
@@ -812,4 +895,4 @@ declare function clampPrice(price: number, min?: number, max?: number): number;
812
895
  declare function formatPrice(price: number, decimals?: number): string;
813
896
  declare function formatUsd(amount: number): string;
814
897
 
815
- export { AuthenticationError, Colors, type CreateOrderParams, type DeltaInfo, DrManhattanError, Exchange, type ExchangeCapabilities, type ExchangeConfig, ExchangeError, type FetchMarketsParams, InsufficientFunds, InvalidOrder, Kalshi, Limitless, LimitlessWebSocket, type Market, MarketNotFound, MarketUtils, NetworkError, Opinion, type Order, OrderBookWebSocket, OrderSide, OrderStatus, OrderUtils, type Orderbook, type OrderbookCallback, OrderbookManager, type OrderbookUpdate, OrderbookUtils, type OutcomeToken, Polymarket, PolymarketWebSocket, type Position, PositionUtils, type PriceLevel, RateLimitError, Strategy, type StrategyConfig, StrategyState, type WebSocketConfig, WebSocketState, calculateDelta, clampPrice, createExchange, createLogger, formatPrice, formatUsd, listExchanges, logger, roundToTickSize };
898
+ export { AuthenticationError, Colors, type CreateOrderParams, type DeltaInfo, DrManhattanError, Exchange, type ExchangeCapabilities, type ExchangeConfig, ExchangeError, type FetchMarketsParams, InsufficientFunds, InvalidOrder, Kalshi, Limitless, LimitlessWebSocket, type Market, MarketNotFound, MarketUtils, NetworkError, Opinion, type Order, OrderBookWebSocket, OrderSide, OrderStatus, OrderUtils, type Orderbook, type OrderbookCallback, OrderbookManager, type OrderbookUpdate, OrderbookUtils, type OutcomeToken, Polymarket, PolymarketWebSocket, type Position, PositionUtils, PredictFun, type PriceLevel, RateLimitError, Strategy, type StrategyConfig, StrategyState, type WebSocketConfig, WebSocketState, calculateDelta, clampPrice, createExchange, createLogger, formatPrice, formatUsd, listExchanges, logger, roundToTickSize };