@alpha-arcade/sdk 0.3.1 → 0.4.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.
- package/README.md +144 -0
- package/dist/index.cjs +267 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +159 -1
- package/dist/index.d.ts +159 -1
- package/dist/index.js +266 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -362,6 +362,76 @@ type EscrowGlobalState = {
|
|
|
362
362
|
asset_listed?: number;
|
|
363
363
|
fee_timer_start?: number;
|
|
364
364
|
};
|
|
365
|
+
/** Configuration for AlphaWebSocket */
|
|
366
|
+
type AlphaWebSocketConfig = {
|
|
367
|
+
/** WebSocket URL override (default: wss://wss.platform.alphaarcade.com) */
|
|
368
|
+
url?: string;
|
|
369
|
+
/** Enable auto-reconnect on unexpected disconnect (default: true) */
|
|
370
|
+
reconnect?: boolean;
|
|
371
|
+
/** Maximum reconnect attempts before giving up (default: Infinity) */
|
|
372
|
+
maxReconnectAttempts?: number;
|
|
373
|
+
/** Heartbeat interval in ms (default: 60000) */
|
|
374
|
+
heartbeatIntervalMs?: number;
|
|
375
|
+
/**
|
|
376
|
+
* WebSocket constructor to use. Defaults to the global `WebSocket`.
|
|
377
|
+
* On Node.js < 22, pass the `ws` package: `import WebSocket from 'ws'; new AlphaWebSocket({ WebSocket })`
|
|
378
|
+
*/
|
|
379
|
+
WebSocket?: unknown;
|
|
380
|
+
};
|
|
381
|
+
/** Orderbook bid/ask entry at the top level (decimal cents) */
|
|
382
|
+
type WsOrderbookAggregatedEntry = {
|
|
383
|
+
price: number;
|
|
384
|
+
quantity: number;
|
|
385
|
+
total: number;
|
|
386
|
+
};
|
|
387
|
+
/** Orderbook bid/ask entry with escrow details (raw microunit prices) */
|
|
388
|
+
type WsOrderbookDetailEntry = {
|
|
389
|
+
price: number;
|
|
390
|
+
quantity: number;
|
|
391
|
+
total: number;
|
|
392
|
+
escrowAppId: number;
|
|
393
|
+
owner: string;
|
|
394
|
+
};
|
|
395
|
+
/** Per-side orderbook detail (yes or no) */
|
|
396
|
+
type WsOrderbookDetailSide = {
|
|
397
|
+
bids: WsOrderbookDetailEntry[];
|
|
398
|
+
asks: WsOrderbookDetailEntry[];
|
|
399
|
+
};
|
|
400
|
+
/** Orderbook data for a single app within the orderbook payload */
|
|
401
|
+
type WsOrderbookApp = {
|
|
402
|
+
bids: WsOrderbookAggregatedEntry[];
|
|
403
|
+
asks: WsOrderbookAggregatedEntry[];
|
|
404
|
+
spread: number;
|
|
405
|
+
yes: WsOrderbookDetailSide;
|
|
406
|
+
no: WsOrderbookDetailSide;
|
|
407
|
+
};
|
|
408
|
+
/** Payload for orderbook_changed events */
|
|
409
|
+
type OrderbookChangedEvent = {
|
|
410
|
+
type: 'orderbook_changed';
|
|
411
|
+
ts: number;
|
|
412
|
+
marketId: string;
|
|
413
|
+
orderbook: Record<string, WsOrderbookApp>;
|
|
414
|
+
};
|
|
415
|
+
/** Payload for markets_changed events (incremental diffs) */
|
|
416
|
+
type MarketsChangedEvent = {
|
|
417
|
+
type: 'markets_changed';
|
|
418
|
+
ts: number;
|
|
419
|
+
[key: string]: unknown;
|
|
420
|
+
};
|
|
421
|
+
/** Payload for market_changed events (single market) */
|
|
422
|
+
type MarketChangedEvent = {
|
|
423
|
+
type: 'market_changed';
|
|
424
|
+
ts: number;
|
|
425
|
+
[key: string]: unknown;
|
|
426
|
+
};
|
|
427
|
+
/** Payload for wallet_orders_changed events */
|
|
428
|
+
type WalletOrdersChangedEvent = {
|
|
429
|
+
type: 'wallet_orders_changed';
|
|
430
|
+
ts: number;
|
|
431
|
+
[key: string]: unknown;
|
|
432
|
+
};
|
|
433
|
+
/** Discriminated union of all WebSocket stream events */
|
|
434
|
+
type WebSocketStreamEvent = MarketsChangedEvent | MarketChangedEvent | OrderbookChangedEvent | WalletOrdersChangedEvent;
|
|
365
435
|
|
|
366
436
|
/**
|
|
367
437
|
* The main client for interacting with Alpha Market prediction markets on Algorand.
|
|
@@ -597,6 +667,93 @@ declare class AlphaClient {
|
|
|
597
667
|
getMarketFromApi(marketId: string): Promise<Market | null>;
|
|
598
668
|
}
|
|
599
669
|
|
|
670
|
+
/**
|
|
671
|
+
* Real-time WebSocket client for Alpha Market platform streams.
|
|
672
|
+
*
|
|
673
|
+
* Connects to `wss://wss.platform.alphaarcade.com` and provides typed,
|
|
674
|
+
* callback-based subscriptions for live market data. No auth required.
|
|
675
|
+
*
|
|
676
|
+
* @example
|
|
677
|
+
* ```typescript
|
|
678
|
+
* // Node.js 22+ or browser (native WebSocket)
|
|
679
|
+
* const ws = new AlphaWebSocket();
|
|
680
|
+
*
|
|
681
|
+
* // Node.js < 22 — pass the `ws` package
|
|
682
|
+
* import WebSocket from 'ws';
|
|
683
|
+
* const ws = new AlphaWebSocket({ WebSocket });
|
|
684
|
+
*
|
|
685
|
+
* const unsub = ws.subscribeOrderbook('will-btc-hit-100k', (event) => {
|
|
686
|
+
* console.log('Orderbook:', event.orderbook);
|
|
687
|
+
* });
|
|
688
|
+
*
|
|
689
|
+
* // Later
|
|
690
|
+
* unsub();
|
|
691
|
+
* ws.close();
|
|
692
|
+
* ```
|
|
693
|
+
*/
|
|
694
|
+
declare class AlphaWebSocket {
|
|
695
|
+
private url;
|
|
696
|
+
private reconnectEnabled;
|
|
697
|
+
private maxReconnectAttempts;
|
|
698
|
+
private heartbeatIntervalMs;
|
|
699
|
+
private WebSocketImpl;
|
|
700
|
+
private ws;
|
|
701
|
+
private subscriptions;
|
|
702
|
+
private pendingRequests;
|
|
703
|
+
private heartbeatTimer;
|
|
704
|
+
private reconnectTimer;
|
|
705
|
+
private reconnectAttempts;
|
|
706
|
+
private intentionallyClosed;
|
|
707
|
+
private connectPromise;
|
|
708
|
+
constructor(config?: AlphaWebSocketConfig);
|
|
709
|
+
/** Whether the WebSocket is currently open and connected */
|
|
710
|
+
get connected(): boolean;
|
|
711
|
+
/**
|
|
712
|
+
* Subscribe to live market probability updates (incremental diffs).
|
|
713
|
+
* @returns An unsubscribe function
|
|
714
|
+
*/
|
|
715
|
+
subscribeLiveMarkets(callback: (event: MarketsChangedEvent) => void): () => void;
|
|
716
|
+
/**
|
|
717
|
+
* Subscribe to change events for a single market.
|
|
718
|
+
* @param slug - The market slug
|
|
719
|
+
* @returns An unsubscribe function
|
|
720
|
+
*/
|
|
721
|
+
subscribeMarket(slug: string, callback: (event: MarketChangedEvent) => void): () => void;
|
|
722
|
+
/**
|
|
723
|
+
* Subscribe to full orderbook snapshots (~5s interval on changes).
|
|
724
|
+
* @param slug - The market slug
|
|
725
|
+
* @returns An unsubscribe function
|
|
726
|
+
*/
|
|
727
|
+
subscribeOrderbook(slug: string, callback: (event: OrderbookChangedEvent) => void): () => void;
|
|
728
|
+
/**
|
|
729
|
+
* Subscribe to wallet order updates.
|
|
730
|
+
* @param wallet - The wallet address
|
|
731
|
+
* @returns An unsubscribe function
|
|
732
|
+
*/
|
|
733
|
+
subscribeWalletOrders(wallet: string, callback: (event: WalletOrdersChangedEvent) => void): () => void;
|
|
734
|
+
/** Query the server for the list of active subscriptions on this connection */
|
|
735
|
+
listSubscriptions(): Promise<unknown>;
|
|
736
|
+
/** Query a server property (e.g. "heartbeat", "limits") */
|
|
737
|
+
getProperty(property: string): Promise<unknown>;
|
|
738
|
+
/** Open the WebSocket connection. Called automatically on first subscribe. */
|
|
739
|
+
connect(): Promise<void>;
|
|
740
|
+
/** Close the connection and clean up all resources */
|
|
741
|
+
close(): void;
|
|
742
|
+
private buildStreamKey;
|
|
743
|
+
private buildQueryString;
|
|
744
|
+
private subscribe;
|
|
745
|
+
private doConnect;
|
|
746
|
+
private handleMessage;
|
|
747
|
+
private sendSubscribe;
|
|
748
|
+
private sendUnsubscribe;
|
|
749
|
+
private sendRequest;
|
|
750
|
+
private send;
|
|
751
|
+
private startHeartbeat;
|
|
752
|
+
private stopHeartbeat;
|
|
753
|
+
private scheduleReconnect;
|
|
754
|
+
private clearTimers;
|
|
755
|
+
}
|
|
756
|
+
|
|
600
757
|
/**
|
|
601
758
|
* Fetches all live, tradeable markets directly from the Algorand blockchain.
|
|
602
759
|
*
|
|
@@ -639,6 +796,7 @@ declare const getLiveMarketsFromApi: (config: AlphaClientConfig) => Promise<Mark
|
|
|
639
796
|
declare const getMarketFromApi: (config: AlphaClientConfig, marketId: string) => Promise<Market | null>;
|
|
640
797
|
|
|
641
798
|
declare const DEFAULT_API_BASE_URL = "https://platform.alphaarcade.com/api";
|
|
799
|
+
declare const DEFAULT_WSS_BASE_URL = "wss://wss.platform.alphaarcade.com";
|
|
642
800
|
declare const DEFAULT_MARKET_CREATOR_ADDRESS = "5P5Y6HTWUNG2E3VXBQDZN3ENZD3JPAIR5PKT3LOYJAPAUKOLFD6KANYTRY";
|
|
643
801
|
|
|
644
802
|
/**
|
|
@@ -720,4 +878,4 @@ declare const getEscrowGlobalState: (indexerClient: algosdk.Indexer, escrowAppId
|
|
|
720
878
|
*/
|
|
721
879
|
declare const checkAssetOptIn: (algodClient: algosdk.Algodv2, address: string, assetId: number) => Promise<boolean>;
|
|
722
880
|
|
|
723
|
-
export { type AggregatedOrderbook, type AggregatedOrderbookEntry, type AggregatedOrderbookSide, AlphaClient, type AlphaClientConfig, type AmendOrderParams, type AmendOrderResult, type CancelOrderParams, type CancelOrderResult, type ClaimParams, type ClaimResult, type CounterpartyMatch, type CreateLimitOrderParams, type CreateMarketOrderParams, type CreateOrderResult, DEFAULT_API_BASE_URL, DEFAULT_MARKET_CREATOR_ADDRESS, type EscrowGlobalState, type Market, type MarketGlobalState, type MarketOption, type MergeSharesParams, type OpenOrder, type OrderSide, type Orderbook, type OrderbookEntry, type OrderbookSide, type Position, type ProcessMatchParams, type ProcessMatchResult, type ProposeMatchParams, type ProposeMatchResult, type SplitMergeResult, type SplitSharesParams, type WalletPosition, calculateFee, calculateFeeFromTotal, calculateMatchingOrders, checkAssetOptIn, decodeGlobalState, getEscrowGlobalState, getLiveMarketsFromApi, getMarketFromApi, getMarketGlobalState, getMarketOnChain, getMarketsOnChain };
|
|
881
|
+
export { type AggregatedOrderbook, type AggregatedOrderbookEntry, type AggregatedOrderbookSide, AlphaClient, type AlphaClientConfig, AlphaWebSocket, type AlphaWebSocketConfig, type AmendOrderParams, type AmendOrderResult, type CancelOrderParams, type CancelOrderResult, type ClaimParams, type ClaimResult, type CounterpartyMatch, type CreateLimitOrderParams, type CreateMarketOrderParams, type CreateOrderResult, DEFAULT_API_BASE_URL, DEFAULT_MARKET_CREATOR_ADDRESS, DEFAULT_WSS_BASE_URL, type EscrowGlobalState, type Market, type MarketChangedEvent, type MarketGlobalState, type MarketOption, type MarketsChangedEvent, type MergeSharesParams, type OpenOrder, type OrderSide, type Orderbook, type OrderbookChangedEvent, type OrderbookEntry, type OrderbookSide, type Position, type ProcessMatchParams, type ProcessMatchResult, type ProposeMatchParams, type ProposeMatchResult, type SplitMergeResult, type SplitSharesParams, type WalletOrdersChangedEvent, type WalletPosition, type WebSocketStreamEvent, type WsOrderbookAggregatedEntry, type WsOrderbookApp, type WsOrderbookDetailEntry, type WsOrderbookDetailSide, calculateFee, calculateFeeFromTotal, calculateMatchingOrders, checkAssetOptIn, decodeGlobalState, getEscrowGlobalState, getLiveMarketsFromApi, getMarketFromApi, getMarketGlobalState, getMarketOnChain, getMarketsOnChain };
|
package/dist/index.d.ts
CHANGED
|
@@ -362,6 +362,76 @@ type EscrowGlobalState = {
|
|
|
362
362
|
asset_listed?: number;
|
|
363
363
|
fee_timer_start?: number;
|
|
364
364
|
};
|
|
365
|
+
/** Configuration for AlphaWebSocket */
|
|
366
|
+
type AlphaWebSocketConfig = {
|
|
367
|
+
/** WebSocket URL override (default: wss://wss.platform.alphaarcade.com) */
|
|
368
|
+
url?: string;
|
|
369
|
+
/** Enable auto-reconnect on unexpected disconnect (default: true) */
|
|
370
|
+
reconnect?: boolean;
|
|
371
|
+
/** Maximum reconnect attempts before giving up (default: Infinity) */
|
|
372
|
+
maxReconnectAttempts?: number;
|
|
373
|
+
/** Heartbeat interval in ms (default: 60000) */
|
|
374
|
+
heartbeatIntervalMs?: number;
|
|
375
|
+
/**
|
|
376
|
+
* WebSocket constructor to use. Defaults to the global `WebSocket`.
|
|
377
|
+
* On Node.js < 22, pass the `ws` package: `import WebSocket from 'ws'; new AlphaWebSocket({ WebSocket })`
|
|
378
|
+
*/
|
|
379
|
+
WebSocket?: unknown;
|
|
380
|
+
};
|
|
381
|
+
/** Orderbook bid/ask entry at the top level (decimal cents) */
|
|
382
|
+
type WsOrderbookAggregatedEntry = {
|
|
383
|
+
price: number;
|
|
384
|
+
quantity: number;
|
|
385
|
+
total: number;
|
|
386
|
+
};
|
|
387
|
+
/** Orderbook bid/ask entry with escrow details (raw microunit prices) */
|
|
388
|
+
type WsOrderbookDetailEntry = {
|
|
389
|
+
price: number;
|
|
390
|
+
quantity: number;
|
|
391
|
+
total: number;
|
|
392
|
+
escrowAppId: number;
|
|
393
|
+
owner: string;
|
|
394
|
+
};
|
|
395
|
+
/** Per-side orderbook detail (yes or no) */
|
|
396
|
+
type WsOrderbookDetailSide = {
|
|
397
|
+
bids: WsOrderbookDetailEntry[];
|
|
398
|
+
asks: WsOrderbookDetailEntry[];
|
|
399
|
+
};
|
|
400
|
+
/** Orderbook data for a single app within the orderbook payload */
|
|
401
|
+
type WsOrderbookApp = {
|
|
402
|
+
bids: WsOrderbookAggregatedEntry[];
|
|
403
|
+
asks: WsOrderbookAggregatedEntry[];
|
|
404
|
+
spread: number;
|
|
405
|
+
yes: WsOrderbookDetailSide;
|
|
406
|
+
no: WsOrderbookDetailSide;
|
|
407
|
+
};
|
|
408
|
+
/** Payload for orderbook_changed events */
|
|
409
|
+
type OrderbookChangedEvent = {
|
|
410
|
+
type: 'orderbook_changed';
|
|
411
|
+
ts: number;
|
|
412
|
+
marketId: string;
|
|
413
|
+
orderbook: Record<string, WsOrderbookApp>;
|
|
414
|
+
};
|
|
415
|
+
/** Payload for markets_changed events (incremental diffs) */
|
|
416
|
+
type MarketsChangedEvent = {
|
|
417
|
+
type: 'markets_changed';
|
|
418
|
+
ts: number;
|
|
419
|
+
[key: string]: unknown;
|
|
420
|
+
};
|
|
421
|
+
/** Payload for market_changed events (single market) */
|
|
422
|
+
type MarketChangedEvent = {
|
|
423
|
+
type: 'market_changed';
|
|
424
|
+
ts: number;
|
|
425
|
+
[key: string]: unknown;
|
|
426
|
+
};
|
|
427
|
+
/** Payload for wallet_orders_changed events */
|
|
428
|
+
type WalletOrdersChangedEvent = {
|
|
429
|
+
type: 'wallet_orders_changed';
|
|
430
|
+
ts: number;
|
|
431
|
+
[key: string]: unknown;
|
|
432
|
+
};
|
|
433
|
+
/** Discriminated union of all WebSocket stream events */
|
|
434
|
+
type WebSocketStreamEvent = MarketsChangedEvent | MarketChangedEvent | OrderbookChangedEvent | WalletOrdersChangedEvent;
|
|
365
435
|
|
|
366
436
|
/**
|
|
367
437
|
* The main client for interacting with Alpha Market prediction markets on Algorand.
|
|
@@ -597,6 +667,93 @@ declare class AlphaClient {
|
|
|
597
667
|
getMarketFromApi(marketId: string): Promise<Market | null>;
|
|
598
668
|
}
|
|
599
669
|
|
|
670
|
+
/**
|
|
671
|
+
* Real-time WebSocket client for Alpha Market platform streams.
|
|
672
|
+
*
|
|
673
|
+
* Connects to `wss://wss.platform.alphaarcade.com` and provides typed,
|
|
674
|
+
* callback-based subscriptions for live market data. No auth required.
|
|
675
|
+
*
|
|
676
|
+
* @example
|
|
677
|
+
* ```typescript
|
|
678
|
+
* // Node.js 22+ or browser (native WebSocket)
|
|
679
|
+
* const ws = new AlphaWebSocket();
|
|
680
|
+
*
|
|
681
|
+
* // Node.js < 22 — pass the `ws` package
|
|
682
|
+
* import WebSocket from 'ws';
|
|
683
|
+
* const ws = new AlphaWebSocket({ WebSocket });
|
|
684
|
+
*
|
|
685
|
+
* const unsub = ws.subscribeOrderbook('will-btc-hit-100k', (event) => {
|
|
686
|
+
* console.log('Orderbook:', event.orderbook);
|
|
687
|
+
* });
|
|
688
|
+
*
|
|
689
|
+
* // Later
|
|
690
|
+
* unsub();
|
|
691
|
+
* ws.close();
|
|
692
|
+
* ```
|
|
693
|
+
*/
|
|
694
|
+
declare class AlphaWebSocket {
|
|
695
|
+
private url;
|
|
696
|
+
private reconnectEnabled;
|
|
697
|
+
private maxReconnectAttempts;
|
|
698
|
+
private heartbeatIntervalMs;
|
|
699
|
+
private WebSocketImpl;
|
|
700
|
+
private ws;
|
|
701
|
+
private subscriptions;
|
|
702
|
+
private pendingRequests;
|
|
703
|
+
private heartbeatTimer;
|
|
704
|
+
private reconnectTimer;
|
|
705
|
+
private reconnectAttempts;
|
|
706
|
+
private intentionallyClosed;
|
|
707
|
+
private connectPromise;
|
|
708
|
+
constructor(config?: AlphaWebSocketConfig);
|
|
709
|
+
/** Whether the WebSocket is currently open and connected */
|
|
710
|
+
get connected(): boolean;
|
|
711
|
+
/**
|
|
712
|
+
* Subscribe to live market probability updates (incremental diffs).
|
|
713
|
+
* @returns An unsubscribe function
|
|
714
|
+
*/
|
|
715
|
+
subscribeLiveMarkets(callback: (event: MarketsChangedEvent) => void): () => void;
|
|
716
|
+
/**
|
|
717
|
+
* Subscribe to change events for a single market.
|
|
718
|
+
* @param slug - The market slug
|
|
719
|
+
* @returns An unsubscribe function
|
|
720
|
+
*/
|
|
721
|
+
subscribeMarket(slug: string, callback: (event: MarketChangedEvent) => void): () => void;
|
|
722
|
+
/**
|
|
723
|
+
* Subscribe to full orderbook snapshots (~5s interval on changes).
|
|
724
|
+
* @param slug - The market slug
|
|
725
|
+
* @returns An unsubscribe function
|
|
726
|
+
*/
|
|
727
|
+
subscribeOrderbook(slug: string, callback: (event: OrderbookChangedEvent) => void): () => void;
|
|
728
|
+
/**
|
|
729
|
+
* Subscribe to wallet order updates.
|
|
730
|
+
* @param wallet - The wallet address
|
|
731
|
+
* @returns An unsubscribe function
|
|
732
|
+
*/
|
|
733
|
+
subscribeWalletOrders(wallet: string, callback: (event: WalletOrdersChangedEvent) => void): () => void;
|
|
734
|
+
/** Query the server for the list of active subscriptions on this connection */
|
|
735
|
+
listSubscriptions(): Promise<unknown>;
|
|
736
|
+
/** Query a server property (e.g. "heartbeat", "limits") */
|
|
737
|
+
getProperty(property: string): Promise<unknown>;
|
|
738
|
+
/** Open the WebSocket connection. Called automatically on first subscribe. */
|
|
739
|
+
connect(): Promise<void>;
|
|
740
|
+
/** Close the connection and clean up all resources */
|
|
741
|
+
close(): void;
|
|
742
|
+
private buildStreamKey;
|
|
743
|
+
private buildQueryString;
|
|
744
|
+
private subscribe;
|
|
745
|
+
private doConnect;
|
|
746
|
+
private handleMessage;
|
|
747
|
+
private sendSubscribe;
|
|
748
|
+
private sendUnsubscribe;
|
|
749
|
+
private sendRequest;
|
|
750
|
+
private send;
|
|
751
|
+
private startHeartbeat;
|
|
752
|
+
private stopHeartbeat;
|
|
753
|
+
private scheduleReconnect;
|
|
754
|
+
private clearTimers;
|
|
755
|
+
}
|
|
756
|
+
|
|
600
757
|
/**
|
|
601
758
|
* Fetches all live, tradeable markets directly from the Algorand blockchain.
|
|
602
759
|
*
|
|
@@ -639,6 +796,7 @@ declare const getLiveMarketsFromApi: (config: AlphaClientConfig) => Promise<Mark
|
|
|
639
796
|
declare const getMarketFromApi: (config: AlphaClientConfig, marketId: string) => Promise<Market | null>;
|
|
640
797
|
|
|
641
798
|
declare const DEFAULT_API_BASE_URL = "https://platform.alphaarcade.com/api";
|
|
799
|
+
declare const DEFAULT_WSS_BASE_URL = "wss://wss.platform.alphaarcade.com";
|
|
642
800
|
declare const DEFAULT_MARKET_CREATOR_ADDRESS = "5P5Y6HTWUNG2E3VXBQDZN3ENZD3JPAIR5PKT3LOYJAPAUKOLFD6KANYTRY";
|
|
643
801
|
|
|
644
802
|
/**
|
|
@@ -720,4 +878,4 @@ declare const getEscrowGlobalState: (indexerClient: algosdk.Indexer, escrowAppId
|
|
|
720
878
|
*/
|
|
721
879
|
declare const checkAssetOptIn: (algodClient: algosdk.Algodv2, address: string, assetId: number) => Promise<boolean>;
|
|
722
880
|
|
|
723
|
-
export { type AggregatedOrderbook, type AggregatedOrderbookEntry, type AggregatedOrderbookSide, AlphaClient, type AlphaClientConfig, type AmendOrderParams, type AmendOrderResult, type CancelOrderParams, type CancelOrderResult, type ClaimParams, type ClaimResult, type CounterpartyMatch, type CreateLimitOrderParams, type CreateMarketOrderParams, type CreateOrderResult, DEFAULT_API_BASE_URL, DEFAULT_MARKET_CREATOR_ADDRESS, type EscrowGlobalState, type Market, type MarketGlobalState, type MarketOption, type MergeSharesParams, type OpenOrder, type OrderSide, type Orderbook, type OrderbookEntry, type OrderbookSide, type Position, type ProcessMatchParams, type ProcessMatchResult, type ProposeMatchParams, type ProposeMatchResult, type SplitMergeResult, type SplitSharesParams, type WalletPosition, calculateFee, calculateFeeFromTotal, calculateMatchingOrders, checkAssetOptIn, decodeGlobalState, getEscrowGlobalState, getLiveMarketsFromApi, getMarketFromApi, getMarketGlobalState, getMarketOnChain, getMarketsOnChain };
|
|
881
|
+
export { type AggregatedOrderbook, type AggregatedOrderbookEntry, type AggregatedOrderbookSide, AlphaClient, type AlphaClientConfig, AlphaWebSocket, type AlphaWebSocketConfig, type AmendOrderParams, type AmendOrderResult, type CancelOrderParams, type CancelOrderResult, type ClaimParams, type ClaimResult, type CounterpartyMatch, type CreateLimitOrderParams, type CreateMarketOrderParams, type CreateOrderResult, DEFAULT_API_BASE_URL, DEFAULT_MARKET_CREATOR_ADDRESS, DEFAULT_WSS_BASE_URL, type EscrowGlobalState, type Market, type MarketChangedEvent, type MarketGlobalState, type MarketOption, type MarketsChangedEvent, type MergeSharesParams, type OpenOrder, type OrderSide, type Orderbook, type OrderbookChangedEvent, type OrderbookEntry, type OrderbookSide, type Position, type ProcessMatchParams, type ProcessMatchResult, type ProposeMatchParams, type ProposeMatchResult, type SplitMergeResult, type SplitSharesParams, type WalletOrdersChangedEvent, type WalletPosition, type WebSocketStreamEvent, type WsOrderbookAggregatedEntry, type WsOrderbookApp, type WsOrderbookDetailEntry, type WsOrderbookDetailSide, calculateFee, calculateFeeFromTotal, calculateMatchingOrders, checkAssetOptIn, decodeGlobalState, getEscrowGlobalState, getLiveMarketsFromApi, getMarketFromApi, getMarketGlobalState, getMarketOnChain, getMarketsOnChain };
|
package/dist/index.js
CHANGED
|
@@ -2103,6 +2103,7 @@ var calculateMatchingOrders = (orderbook, isBuying, isYes, quantity, price, slip
|
|
|
2103
2103
|
|
|
2104
2104
|
// src/constants.ts
|
|
2105
2105
|
var DEFAULT_API_BASE_URL = "https://platform.alphaarcade.com/api";
|
|
2106
|
+
var DEFAULT_WSS_BASE_URL = "wss://wss.platform.alphaarcade.com";
|
|
2106
2107
|
var DEFAULT_MARKET_CREATOR_ADDRESS = "5P5Y6HTWUNG2E3VXBQDZN3ENZD3JPAIR5PKT3LOYJAPAUKOLFD6KANYTRY";
|
|
2107
2108
|
|
|
2108
2109
|
// src/modules/orderbook.ts
|
|
@@ -3344,6 +3345,270 @@ var AlphaClient = class {
|
|
|
3344
3345
|
}
|
|
3345
3346
|
};
|
|
3346
3347
|
|
|
3347
|
-
|
|
3348
|
+
// src/websocket.ts
|
|
3349
|
+
var WS_OPEN = 1;
|
|
3350
|
+
var resolveWebSocket = (provided) => {
|
|
3351
|
+
if (provided) return provided;
|
|
3352
|
+
if (typeof globalThis !== "undefined" && globalThis.WebSocket) {
|
|
3353
|
+
return globalThis.WebSocket;
|
|
3354
|
+
}
|
|
3355
|
+
throw new Error(
|
|
3356
|
+
'No WebSocket implementation found. On Node.js < 22, install the "ws" package and pass it: new AlphaWebSocket({ WebSocket: require("ws") })'
|
|
3357
|
+
);
|
|
3358
|
+
};
|
|
3359
|
+
var AlphaWebSocket = class {
|
|
3360
|
+
url;
|
|
3361
|
+
reconnectEnabled;
|
|
3362
|
+
maxReconnectAttempts;
|
|
3363
|
+
heartbeatIntervalMs;
|
|
3364
|
+
WebSocketImpl;
|
|
3365
|
+
ws = null;
|
|
3366
|
+
subscriptions = /* @__PURE__ */ new Map();
|
|
3367
|
+
pendingRequests = /* @__PURE__ */ new Map();
|
|
3368
|
+
heartbeatTimer = null;
|
|
3369
|
+
reconnectTimer = null;
|
|
3370
|
+
reconnectAttempts = 0;
|
|
3371
|
+
intentionallyClosed = false;
|
|
3372
|
+
connectPromise = null;
|
|
3373
|
+
constructor(config) {
|
|
3374
|
+
this.url = config?.url ?? DEFAULT_WSS_BASE_URL;
|
|
3375
|
+
this.reconnectEnabled = config?.reconnect ?? true;
|
|
3376
|
+
this.maxReconnectAttempts = config?.maxReconnectAttempts ?? Infinity;
|
|
3377
|
+
this.heartbeatIntervalMs = config?.heartbeatIntervalMs ?? 6e4;
|
|
3378
|
+
this.WebSocketImpl = resolveWebSocket(config?.WebSocket);
|
|
3379
|
+
}
|
|
3380
|
+
/** Whether the WebSocket is currently open and connected */
|
|
3381
|
+
get connected() {
|
|
3382
|
+
return this.ws?.readyState === WS_OPEN;
|
|
3383
|
+
}
|
|
3384
|
+
// ============================================
|
|
3385
|
+
// Subscribe Methods
|
|
3386
|
+
// ============================================
|
|
3387
|
+
/**
|
|
3388
|
+
* Subscribe to live market probability updates (incremental diffs).
|
|
3389
|
+
* @returns An unsubscribe function
|
|
3390
|
+
*/
|
|
3391
|
+
subscribeLiveMarkets(callback) {
|
|
3392
|
+
return this.subscribe("get-live-markets", {}, "markets_changed", callback);
|
|
3393
|
+
}
|
|
3394
|
+
/**
|
|
3395
|
+
* Subscribe to change events for a single market.
|
|
3396
|
+
* @param slug - The market slug
|
|
3397
|
+
* @returns An unsubscribe function
|
|
3398
|
+
*/
|
|
3399
|
+
subscribeMarket(slug, callback) {
|
|
3400
|
+
return this.subscribe("get-market", { slug }, "market_changed", callback);
|
|
3401
|
+
}
|
|
3402
|
+
/**
|
|
3403
|
+
* Subscribe to full orderbook snapshots (~5s interval on changes).
|
|
3404
|
+
* @param slug - The market slug
|
|
3405
|
+
* @returns An unsubscribe function
|
|
3406
|
+
*/
|
|
3407
|
+
subscribeOrderbook(slug, callback) {
|
|
3408
|
+
return this.subscribe("get-orderbook", { slug }, "orderbook_changed", callback);
|
|
3409
|
+
}
|
|
3410
|
+
/**
|
|
3411
|
+
* Subscribe to wallet order updates.
|
|
3412
|
+
* @param wallet - The wallet address
|
|
3413
|
+
* @returns An unsubscribe function
|
|
3414
|
+
*/
|
|
3415
|
+
subscribeWalletOrders(wallet, callback) {
|
|
3416
|
+
return this.subscribe("get-wallet-orders", { wallet }, "wallet_orders_changed", callback);
|
|
3417
|
+
}
|
|
3418
|
+
// ============================================
|
|
3419
|
+
// Control Methods
|
|
3420
|
+
// ============================================
|
|
3421
|
+
/** Query the server for the list of active subscriptions on this connection */
|
|
3422
|
+
listSubscriptions() {
|
|
3423
|
+
return this.sendRequest({ method: "LIST_SUBSCRIPTIONS" });
|
|
3424
|
+
}
|
|
3425
|
+
/** Query a server property (e.g. "heartbeat", "limits") */
|
|
3426
|
+
getProperty(property) {
|
|
3427
|
+
return this.sendRequest({ method: "GET_PROPERTY", params: [property] });
|
|
3428
|
+
}
|
|
3429
|
+
// ============================================
|
|
3430
|
+
// Lifecycle
|
|
3431
|
+
// ============================================
|
|
3432
|
+
/** Open the WebSocket connection. Called automatically on first subscribe. */
|
|
3433
|
+
connect() {
|
|
3434
|
+
if (this.connectPromise) return this.connectPromise;
|
|
3435
|
+
this.connectPromise = this.doConnect();
|
|
3436
|
+
return this.connectPromise;
|
|
3437
|
+
}
|
|
3438
|
+
/** Close the connection and clean up all resources */
|
|
3439
|
+
close() {
|
|
3440
|
+
this.intentionallyClosed = true;
|
|
3441
|
+
this.clearTimers();
|
|
3442
|
+
this.subscriptions.clear();
|
|
3443
|
+
for (const [, req] of this.pendingRequests) {
|
|
3444
|
+
clearTimeout(req.timer);
|
|
3445
|
+
req.reject(new Error("WebSocket closed"));
|
|
3446
|
+
}
|
|
3447
|
+
this.pendingRequests.clear();
|
|
3448
|
+
if (this.ws) {
|
|
3449
|
+
this.ws.close();
|
|
3450
|
+
this.ws = null;
|
|
3451
|
+
}
|
|
3452
|
+
this.connectPromise = null;
|
|
3453
|
+
}
|
|
3454
|
+
// ============================================
|
|
3455
|
+
// Internal
|
|
3456
|
+
// ============================================
|
|
3457
|
+
buildStreamKey(stream, params) {
|
|
3458
|
+
const parts = [stream, ...Object.entries(params).sort().map(([k, v]) => `${k}=${v}`)];
|
|
3459
|
+
return parts.join("&");
|
|
3460
|
+
}
|
|
3461
|
+
buildQueryString() {
|
|
3462
|
+
const subs = [...this.subscriptions.values()];
|
|
3463
|
+
if (subs.length === 0) return "";
|
|
3464
|
+
const first = subs[0];
|
|
3465
|
+
const params = new URLSearchParams({ stream: first.stream, ...first.params });
|
|
3466
|
+
return "?" + params.toString();
|
|
3467
|
+
}
|
|
3468
|
+
subscribe(stream, params, eventType, callback) {
|
|
3469
|
+
const key = this.buildStreamKey(stream, params);
|
|
3470
|
+
this.subscriptions.set(key, { stream, params, callback, eventType });
|
|
3471
|
+
if (this.connected) {
|
|
3472
|
+
this.sendSubscribe(stream, params);
|
|
3473
|
+
} else {
|
|
3474
|
+
this.connect();
|
|
3475
|
+
}
|
|
3476
|
+
return () => {
|
|
3477
|
+
this.subscriptions.delete(key);
|
|
3478
|
+
if (this.connected) {
|
|
3479
|
+
this.sendUnsubscribe(stream, params);
|
|
3480
|
+
}
|
|
3481
|
+
};
|
|
3482
|
+
}
|
|
3483
|
+
async doConnect() {
|
|
3484
|
+
this.intentionallyClosed = false;
|
|
3485
|
+
return new Promise((resolve, reject) => {
|
|
3486
|
+
const qs = this.buildQueryString();
|
|
3487
|
+
const ws = new this.WebSocketImpl(this.url + qs);
|
|
3488
|
+
ws.onopen = () => {
|
|
3489
|
+
this.ws = ws;
|
|
3490
|
+
this.reconnectAttempts = 0;
|
|
3491
|
+
this.startHeartbeat();
|
|
3492
|
+
const subs = [...this.subscriptions.values()];
|
|
3493
|
+
for (const sub of subs.slice(1)) {
|
|
3494
|
+
this.sendSubscribe(sub.stream, sub.params);
|
|
3495
|
+
}
|
|
3496
|
+
resolve();
|
|
3497
|
+
};
|
|
3498
|
+
ws.onmessage = (event) => {
|
|
3499
|
+
this.handleMessage(event.data);
|
|
3500
|
+
};
|
|
3501
|
+
ws.onclose = () => {
|
|
3502
|
+
this.ws = null;
|
|
3503
|
+
this.connectPromise = null;
|
|
3504
|
+
this.stopHeartbeat();
|
|
3505
|
+
if (!this.intentionallyClosed) {
|
|
3506
|
+
this.scheduleReconnect();
|
|
3507
|
+
}
|
|
3508
|
+
};
|
|
3509
|
+
ws.onerror = (err) => {
|
|
3510
|
+
if (!this.ws) {
|
|
3511
|
+
reject(new Error("WebSocket connection failed"));
|
|
3512
|
+
}
|
|
3513
|
+
};
|
|
3514
|
+
});
|
|
3515
|
+
}
|
|
3516
|
+
handleMessage(raw) {
|
|
3517
|
+
let msg;
|
|
3518
|
+
try {
|
|
3519
|
+
msg = JSON.parse(raw);
|
|
3520
|
+
} catch {
|
|
3521
|
+
return;
|
|
3522
|
+
}
|
|
3523
|
+
if (msg.type === "ping") {
|
|
3524
|
+
this.send({ method: "PONG" });
|
|
3525
|
+
return;
|
|
3526
|
+
}
|
|
3527
|
+
const responseId = typeof msg.id === "string" ? msg.id : typeof msg.requestId === "string" ? msg.requestId : null;
|
|
3528
|
+
if (responseId && this.pendingRequests.has(responseId)) {
|
|
3529
|
+
const req = this.pendingRequests.get(responseId);
|
|
3530
|
+
this.pendingRequests.delete(responseId);
|
|
3531
|
+
clearTimeout(req.timer);
|
|
3532
|
+
req.resolve(msg);
|
|
3533
|
+
return;
|
|
3534
|
+
}
|
|
3535
|
+
const eventType = msg.type;
|
|
3536
|
+
if (!eventType) return;
|
|
3537
|
+
for (const sub of this.subscriptions.values()) {
|
|
3538
|
+
if (sub.eventType === eventType) {
|
|
3539
|
+
try {
|
|
3540
|
+
sub.callback(msg);
|
|
3541
|
+
} catch {
|
|
3542
|
+
}
|
|
3543
|
+
}
|
|
3544
|
+
}
|
|
3545
|
+
}
|
|
3546
|
+
sendSubscribe(stream, params) {
|
|
3547
|
+
this.send({ method: "SUBSCRIBE", params: [{ stream, ...params }] });
|
|
3548
|
+
}
|
|
3549
|
+
sendUnsubscribe(stream, params) {
|
|
3550
|
+
this.send({ method: "UNSUBSCRIBE", params: [{ stream, ...params }] });
|
|
3551
|
+
}
|
|
3552
|
+
sendRequest(payload, timeoutMs = 1e4) {
|
|
3553
|
+
const requestId = crypto.randomUUID();
|
|
3554
|
+
return new Promise((resolve, reject) => {
|
|
3555
|
+
const timer = setTimeout(() => {
|
|
3556
|
+
this.pendingRequests.delete(requestId);
|
|
3557
|
+
reject(new Error("Request timed out"));
|
|
3558
|
+
}, timeoutMs);
|
|
3559
|
+
this.pendingRequests.set(requestId, { resolve, reject, timer });
|
|
3560
|
+
if (!this.connected) {
|
|
3561
|
+
this.connect().then(() => {
|
|
3562
|
+
this.send({ ...payload, id: requestId });
|
|
3563
|
+
}).catch(reject);
|
|
3564
|
+
} else {
|
|
3565
|
+
this.send({ ...payload, id: requestId });
|
|
3566
|
+
}
|
|
3567
|
+
});
|
|
3568
|
+
}
|
|
3569
|
+
send(data) {
|
|
3570
|
+
if (this.ws?.readyState === WS_OPEN) {
|
|
3571
|
+
this.ws.send(JSON.stringify(data));
|
|
3572
|
+
}
|
|
3573
|
+
}
|
|
3574
|
+
// ============================================
|
|
3575
|
+
// Heartbeat
|
|
3576
|
+
// ============================================
|
|
3577
|
+
startHeartbeat() {
|
|
3578
|
+
this.stopHeartbeat();
|
|
3579
|
+
this.heartbeatTimer = setInterval(() => {
|
|
3580
|
+
this.send({ method: "PING" });
|
|
3581
|
+
}, this.heartbeatIntervalMs);
|
|
3582
|
+
}
|
|
3583
|
+
stopHeartbeat() {
|
|
3584
|
+
if (this.heartbeatTimer) {
|
|
3585
|
+
clearInterval(this.heartbeatTimer);
|
|
3586
|
+
this.heartbeatTimer = null;
|
|
3587
|
+
}
|
|
3588
|
+
}
|
|
3589
|
+
// ============================================
|
|
3590
|
+
// Reconnect
|
|
3591
|
+
// ============================================
|
|
3592
|
+
scheduleReconnect() {
|
|
3593
|
+
if (!this.reconnectEnabled) return;
|
|
3594
|
+
if (this.reconnectAttempts >= this.maxReconnectAttempts) return;
|
|
3595
|
+
const delay = Math.min(1e3 * 2 ** this.reconnectAttempts, 3e4);
|
|
3596
|
+
this.reconnectAttempts++;
|
|
3597
|
+
this.reconnectTimer = setTimeout(() => {
|
|
3598
|
+
this.reconnectTimer = null;
|
|
3599
|
+
this.connect().catch(() => {
|
|
3600
|
+
});
|
|
3601
|
+
}, delay);
|
|
3602
|
+
}
|
|
3603
|
+
clearTimers() {
|
|
3604
|
+
this.stopHeartbeat();
|
|
3605
|
+
if (this.reconnectTimer) {
|
|
3606
|
+
clearTimeout(this.reconnectTimer);
|
|
3607
|
+
this.reconnectTimer = null;
|
|
3608
|
+
}
|
|
3609
|
+
}
|
|
3610
|
+
};
|
|
3611
|
+
|
|
3612
|
+
export { AlphaClient, AlphaWebSocket, DEFAULT_API_BASE_URL, DEFAULT_MARKET_CREATOR_ADDRESS, DEFAULT_WSS_BASE_URL, calculateFee, calculateFeeFromTotal, calculateMatchingOrders, checkAssetOptIn, decodeGlobalState, getEscrowGlobalState, getLiveMarketsFromApi, getMarketFromApi, getMarketGlobalState, getMarketOnChain, getMarketsOnChain };
|
|
3348
3613
|
//# sourceMappingURL=index.js.map
|
|
3349
3614
|
//# sourceMappingURL=index.js.map
|