@0xarchive/sdk 0.1.0 → 0.2.0

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/dist/index.d.ts CHANGED
@@ -9,14 +9,24 @@ interface ClientOptions {
9
9
  /** Request timeout in milliseconds (defaults to 30000) */
10
10
  timeout?: number;
11
11
  }
12
+ /**
13
+ * Response metadata
14
+ */
15
+ interface ApiMeta {
16
+ /** Number of records returned */
17
+ count: number;
18
+ /** Cursor for next page (if available) */
19
+ next_cursor?: string;
20
+ /** Unique request ID for debugging */
21
+ request_id: string;
22
+ }
12
23
  /**
13
24
  * Standard API response wrapper
14
25
  */
15
26
  interface ApiResponse<T> {
16
27
  success: boolean;
17
28
  data: T;
18
- count: number;
19
- request_id: string;
29
+ meta: ApiMeta;
20
30
  }
21
31
  /**
22
32
  * Pagination parameters for list endpoints
@@ -36,19 +46,35 @@ interface TimeRangeParams extends PaginationParams {
36
46
  /** End timestamp (Unix ms or ISO string) */
37
47
  end?: number | string;
38
48
  }
39
- /** A price level in the order book [price, size] */
40
- type PriceLevel = [string, string];
49
+ /**
50
+ * A price level in the order book
51
+ */
52
+ interface PriceLevel {
53
+ /** Price at this level */
54
+ px: string;
55
+ /** Total size at this price level */
56
+ sz: string;
57
+ /** Number of orders at this level */
58
+ n: number;
59
+ }
41
60
  /**
42
61
  * Order book snapshot
43
62
  */
44
63
  interface OrderBook {
64
+ /** Trading pair symbol (e.g., BTC, ETH) */
45
65
  coin: string;
46
- timestamp: number;
66
+ /** Snapshot timestamp (UTC) */
67
+ timestamp: string;
68
+ /** Bid price levels (best bid first) */
47
69
  bids: PriceLevel[];
70
+ /** Ask price levels (best ask first) */
48
71
  asks: PriceLevel[];
49
- mid_price: string;
50
- spread: string;
51
- spread_bps: string;
72
+ /** Mid price (best bid + best ask) / 2 */
73
+ mid_price?: string;
74
+ /** Spread in absolute terms (best ask - best bid) */
75
+ spread?: string;
76
+ /** Spread in basis points */
77
+ spread_bps?: string;
52
78
  }
53
79
  interface GetOrderBookParams {
54
80
  /** Timestamp to get order book at (Unix ms or ISO string) */
@@ -60,72 +86,112 @@ interface OrderBookHistoryParams extends TimeRangeParams {
60
86
  /** Number of price levels to return per side */
61
87
  depth?: number;
62
88
  }
89
+ /** Trade side: 'A' (ask/sell) or 'B' (bid/buy) */
90
+ type TradeSide = 'A' | 'B';
91
+ /** Position direction */
92
+ type TradeDirection = 'Open Long' | 'Open Short' | 'Close Long' | 'Close Short';
93
+ /** Data source */
94
+ type DataSource = 's3' | 'ws' | 'api';
63
95
  /**
64
- * Trade/fill record
96
+ * Trade/fill record with full execution details
65
97
  */
66
98
  interface Trade {
67
- id: string;
99
+ /** Trading pair symbol */
68
100
  coin: string;
69
- side: 'buy' | 'sell';
101
+ /** Trade side: 'A' (ask/sell) or 'B' (bid/buy) */
102
+ side: TradeSide;
103
+ /** Execution price */
70
104
  price: string;
105
+ /** Trade size */
71
106
  size: string;
72
- value: string;
73
- timestamp: number;
74
- trade_type: string;
107
+ /** Execution timestamp (UTC) */
108
+ timestamp: string;
109
+ /** Blockchain transaction hash */
110
+ tx_hash?: string;
111
+ /** Unique trade ID */
112
+ trade_id?: number;
113
+ /** Associated order ID */
114
+ order_id?: number;
115
+ /** True if taker (crossed the spread), false if maker */
116
+ crossed?: boolean;
117
+ /** Trading fee amount */
118
+ fee?: string;
119
+ /** Fee denomination (e.g., USDC) */
120
+ fee_token?: string;
121
+ /** Realized PnL if closing a position */
122
+ closed_pnl?: string;
123
+ /** Position direction */
124
+ direction?: TradeDirection;
125
+ /** Position size before this trade */
126
+ start_position?: string;
127
+ /** Data source */
128
+ source?: DataSource;
129
+ /** User's wallet address */
130
+ user_address?: string;
75
131
  }
76
132
  interface GetTradesParams extends TimeRangeParams {
77
133
  /** Filter by side */
78
- side?: 'buy' | 'sell';
79
- }
80
- /**
81
- * OHLCV candle
82
- */
83
- interface Candle {
84
- coin: string;
85
- interval: string;
86
- timestamp: number;
87
- open: string;
88
- high: string;
89
- low: string;
90
- close: string;
91
- volume: string;
92
- trades: number;
93
- }
94
- type CandleInterval = '1m' | '5m' | '15m' | '1h' | '4h' | '1d';
95
- interface GetCandlesParams extends TimeRangeParams {
96
- /** Candle interval */
97
- interval?: CandleInterval;
134
+ side?: TradeSide;
98
135
  }
136
+ /** Instrument type */
137
+ type InstrumentType = 'perp' | 'spot';
99
138
  /**
100
139
  * Trading instrument metadata
101
140
  */
102
141
  interface Instrument {
103
- coin: string;
142
+ /** Instrument symbol (e.g., BTC) */
104
143
  name: string;
144
+ /** Size decimal precision */
105
145
  sz_decimals: number;
106
- max_leverage: number;
107
- only_isolated: boolean;
146
+ /** Maximum leverage allowed */
147
+ max_leverage?: number;
148
+ /** If true, only isolated margin mode is allowed */
149
+ only_isolated?: boolean;
150
+ /** Type of instrument */
151
+ instrument_type?: InstrumentType;
152
+ /** Whether the instrument is currently tradeable */
108
153
  is_active: boolean;
109
154
  }
110
155
  /**
111
156
  * Funding rate record
112
157
  */
113
158
  interface FundingRate {
159
+ /** Trading pair symbol */
114
160
  coin: string;
161
+ /** Funding timestamp (UTC) */
162
+ timestamp: string;
163
+ /** Funding rate as decimal (e.g., 0.0001 = 0.01%) */
115
164
  funding_rate: string;
116
- premium: string;
117
- timestamp: number;
165
+ /** Premium component of funding rate */
166
+ premium?: string;
118
167
  }
119
168
  /**
120
- * Open interest record
169
+ * Open interest snapshot with market context
121
170
  */
122
171
  interface OpenInterest {
172
+ /** Trading pair symbol */
123
173
  coin: string;
174
+ /** Snapshot timestamp (UTC) */
175
+ timestamp: string;
176
+ /** Total open interest in contracts */
124
177
  open_interest: string;
125
- timestamp: number;
126
- }
127
- /** WebSocket channel types */
128
- type WsChannel = 'orderbook' | 'trades' | 'ticker' | 'all_tickers' | 'candles' | 'funding' | 'openinterest';
178
+ /** Mark price used for liquidations */
179
+ mark_price?: string;
180
+ /** Oracle price from external feed */
181
+ oracle_price?: string;
182
+ /** 24-hour notional volume */
183
+ day_ntl_volume?: string;
184
+ /** Price 24 hours ago */
185
+ prev_day_price?: string;
186
+ /** Current mid price */
187
+ mid_price?: string;
188
+ /** Impact bid price for liquidations */
189
+ impact_bid_price?: string;
190
+ /** Impact ask price for liquidations */
191
+ impact_ask_price?: string;
192
+ }
193
+ /** WebSocket channel types. Note: ticker/all_tickers are real-time only. */
194
+ type WsChannel = 'orderbook' | 'trades' | 'ticker' | 'all_tickers';
129
195
  /** Subscribe message from client */
130
196
  interface WsSubscribe {
131
197
  op: 'subscribe';
@@ -207,7 +273,7 @@ interface WsError {
207
273
  type: 'error';
208
274
  message: string;
209
275
  }
210
- /** Data message from server */
276
+ /** Data message from server (real-time) */
211
277
  interface WsData<T = unknown> {
212
278
  type: 'data';
213
279
  channel: WsChannel;
@@ -219,10 +285,12 @@ interface WsReplayStarted {
219
285
  type: 'replay_started';
220
286
  channel: WsChannel;
221
287
  coin: string;
288
+ /** Start timestamp in milliseconds */
222
289
  start: number;
290
+ /** End timestamp in milliseconds */
223
291
  end: number;
292
+ /** Playback speed multiplier */
224
293
  speed: number;
225
- total_records: number;
226
294
  }
227
295
  /** Replay paused response */
228
296
  interface WsReplayPaused {
@@ -239,7 +307,7 @@ interface WsReplayCompleted {
239
307
  type: 'replay_completed';
240
308
  channel: WsChannel;
241
309
  coin: string;
242
- records_sent: number;
310
+ snapshots_sent: number;
243
311
  }
244
312
  /** Replay stopped response */
245
313
  interface WsReplayStopped {
@@ -258,47 +326,53 @@ interface WsStreamStarted {
258
326
  type: 'stream_started';
259
327
  channel: WsChannel;
260
328
  coin: string;
329
+ /** Start timestamp in milliseconds */
261
330
  start: number;
331
+ /** End timestamp in milliseconds */
262
332
  end: number;
263
- batch_size: number;
264
- total_records: number;
265
333
  }
266
- /** Stream progress response */
334
+ /** Stream progress response (sent periodically during streaming) */
267
335
  interface WsStreamProgress {
268
336
  type: 'stream_progress';
269
- records_sent: number;
270
- total_records: number;
271
- progress_pct: number;
337
+ snapshots_sent: number;
338
+ }
339
+ /** A record with timestamp for batched data */
340
+ interface TimestampedRecord<T = unknown> {
341
+ timestamp: number;
342
+ data: T;
272
343
  }
273
- /** Stream batch (bulk data) */
344
+ /** Batch of historical data (bulk streaming) */
274
345
  interface WsHistoricalBatch<T = unknown> {
275
346
  type: 'historical_batch';
276
347
  channel: WsChannel;
277
348
  coin: string;
278
- batch_index: number;
279
- records: Array<{
280
- timestamp: number;
281
- data: T;
282
- }>;
349
+ data: TimestampedRecord<T>[];
283
350
  }
284
351
  /** Stream completed response */
285
352
  interface WsStreamCompleted {
286
353
  type: 'stream_completed';
287
354
  channel: WsChannel;
288
355
  coin: string;
289
- records_sent: number;
356
+ snapshots_sent: number;
290
357
  }
291
358
  /** Stream stopped response */
292
359
  interface WsStreamStopped {
293
360
  type: 'stream_stopped';
361
+ snapshots_sent: number;
294
362
  }
295
363
  /** Server message union type */
296
364
  type WsServerMessage = WsSubscribed | WsUnsubscribed | WsPong | WsError | WsData | WsReplayStarted | WsReplayPaused | WsReplayResumed | WsReplayCompleted | WsReplayStopped | WsHistoricalData | WsStreamStarted | WsStreamProgress | WsHistoricalBatch | WsStreamCompleted | WsStreamStopped;
297
- /** WebSocket connection options */
365
+ /**
366
+ * WebSocket connection options.
367
+ *
368
+ * The server sends WebSocket ping frames every 30 seconds and will disconnect
369
+ * idle connections after 60 seconds. The SDK automatically handles keep-alive
370
+ * by sending application-level pings at the configured interval.
371
+ */
298
372
  interface WsOptions {
299
373
  /** API key for authentication */
300
374
  apiKey: string;
301
- /** WebSocket URL (defaults to wss://ws.0xarchive.io) */
375
+ /** WebSocket URL (defaults to wss://api.0xarchive.io/ws) */
302
376
  wsUrl?: string;
303
377
  /** Auto-reconnect on disconnect (defaults to true) */
304
378
  autoReconnect?: boolean;
@@ -306,7 +380,7 @@ interface WsOptions {
306
380
  reconnectDelay?: number;
307
381
  /** Maximum reconnect attempts (defaults to 10) */
308
382
  maxReconnectAttempts?: number;
309
- /** Ping interval in ms (defaults to 30000) */
383
+ /** Ping interval in ms to keep connection alive (defaults to 30000). Server disconnects after 60s idle. */
310
384
  pingInterval?: number;
311
385
  }
312
386
  /** WebSocket connection state */
@@ -334,6 +408,8 @@ declare class OxArchiveError extends Error {
334
408
  requestId?: string;
335
409
  constructor(message: string, code: number, requestId?: string);
336
410
  }
411
+ /** Timestamp can be Unix ms (number), ISO string, or Date object */
412
+ type Timestamp = number | string | Date;
337
413
 
338
414
  interface HttpClientOptions {
339
415
  baseUrl: string;
@@ -434,38 +510,6 @@ declare class TradesResource {
434
510
  recent(coin: string, limit?: number): Promise<Trade[]>;
435
511
  }
436
512
 
437
- /**
438
- * Candles (OHLCV) API resource
439
- *
440
- * @example
441
- * ```typescript
442
- * // Get hourly candles
443
- * const candles = await client.candles.list('BTC', {
444
- * interval: '1h',
445
- * start: Date.now() - 86400000,
446
- * end: Date.now()
447
- * });
448
- *
449
- * // Get daily candles
450
- * const daily = await client.candles.list('ETH', {
451
- * interval: '1d',
452
- * limit: 30
453
- * });
454
- * ```
455
- */
456
- declare class CandlesResource {
457
- private http;
458
- constructor(http: HttpClient);
459
- /**
460
- * Get OHLCV candles for a coin
461
- *
462
- * @param coin - The coin symbol (e.g., 'BTC', 'ETH')
463
- * @param params - Interval, time range, and pagination parameters
464
- * @returns Array of candles
465
- */
466
- list(coin: string, params?: GetCandlesParams): Promise<Candle[]>;
467
- }
468
-
469
513
  /**
470
514
  * Instruments API resource
471
515
  *
@@ -601,10 +645,6 @@ declare class OxArchive {
601
645
  * Trade/fill history
602
646
  */
603
647
  readonly trades: TradesResource;
604
- /**
605
- * OHLCV candles
606
- */
607
- readonly candles: CandlesResource;
608
648
  /**
609
649
  * Trading instruments metadata
610
650
  */
@@ -670,7 +710,13 @@ declare class OxArchive {
670
710
  */
671
711
 
672
712
  /**
673
- * WebSocket client for real-time data streaming
713
+ * WebSocket client for real-time data streaming.
714
+ *
715
+ * **Keep-Alive:** The server sends WebSocket ping frames every 30 seconds
716
+ * and will disconnect idle connections after 60 seconds. This SDK automatically
717
+ * handles keep-alive by sending application-level pings at the configured interval
718
+ * (default: 30 seconds). The browser WebSocket API automatically responds to
719
+ * server ping frames.
674
720
  */
675
721
  declare class OxArchiveWs {
676
722
  private ws;
@@ -806,23 +852,23 @@ declare class OxArchiveWs {
806
852
  /**
807
853
  * Handle replay started event
808
854
  */
809
- onReplayStart(handler: (channel: WsChannel, coin: string, totalRecords: number, speed: number) => void): void;
855
+ onReplayStart(handler: (channel: WsChannel, coin: string, start: number, end: number, speed: number) => void): void;
810
856
  /**
811
857
  * Handle replay completed event
812
858
  */
813
- onReplayComplete(handler: (channel: WsChannel, coin: string, recordsSent: number) => void): void;
859
+ onReplayComplete(handler: (channel: WsChannel, coin: string, snapshotsSent: number) => void): void;
814
860
  /**
815
861
  * Handle stream started event
816
862
  */
817
- onStreamStart(handler: (channel: WsChannel, coin: string, totalRecords: number) => void): void;
863
+ onStreamStart(handler: (channel: WsChannel, coin: string, start: number, end: number) => void): void;
818
864
  /**
819
865
  * Handle stream progress event
820
866
  */
821
- onStreamProgress(handler: (recordsSent: number, totalRecords: number, progressPct: number) => void): void;
867
+ onStreamProgress(handler: (snapshotsSent: number) => void): void;
822
868
  /**
823
869
  * Handle stream completed event
824
870
  */
825
- onStreamComplete(handler: (channel: WsChannel, coin: string, recordsSent: number) => void): void;
871
+ onStreamComplete(handler: (channel: WsChannel, coin: string, snapshotsSent: number) => void): void;
826
872
  /**
827
873
  * Get current connection state
828
874
  */
@@ -853,4 +899,4 @@ declare class OxArchiveWs {
853
899
  private clearReconnectTimer;
854
900
  }
855
901
 
856
- export { type ApiError, type ApiResponse, type Candle, type CandleInterval, type ClientOptions, type FundingRate, type GetCandlesParams, type GetOrderBookParams, type GetTradesParams, type Instrument, type OpenInterest, type OrderBook, type OrderBookHistoryParams, OxArchive, OxArchiveError, OxArchiveWs, type PaginationParams, type PriceLevel, type TimeRangeParams, type Trade, type WsChannel, type WsClientMessage, type WsConnectionState, type WsData, type WsError, type WsEventHandlers, type WsHistoricalBatch, type WsHistoricalData, type WsOptions, type WsPing, type WsPong, type WsReplay, type WsReplayCompleted, type WsReplayPause, type WsReplayPaused, type WsReplayResume, type WsReplayResumed, type WsReplaySeek, type WsReplayStarted, type WsReplayStop, type WsReplayStopped, type WsServerMessage, type WsStream, type WsStreamCompleted, type WsStreamProgress, type WsStreamStarted, type WsStreamStop, type WsStreamStopped, type WsSubscribe, type WsSubscribed, type WsUnsubscribe, type WsUnsubscribed, OxArchive as default };
902
+ export { type ApiError, type ApiMeta, type ApiResponse, type ClientOptions, type DataSource, type FundingRate, type GetOrderBookParams, type GetTradesParams, type Instrument, type InstrumentType, type OpenInterest, type OrderBook, type OrderBookHistoryParams, OxArchive, OxArchiveError, OxArchiveWs, type PaginationParams, type PriceLevel, type TimeRangeParams, type Timestamp, type TimestampedRecord, type Trade, type TradeDirection, type TradeSide, type WsChannel, type WsClientMessage, type WsConnectionState, type WsData, type WsError, type WsEventHandlers, type WsHistoricalBatch, type WsHistoricalData, type WsOptions, type WsPing, type WsPong, type WsReplay, type WsReplayCompleted, type WsReplayPause, type WsReplayPaused, type WsReplayResume, type WsReplayResumed, type WsReplaySeek, type WsReplayStarted, type WsReplayStop, type WsReplayStopped, type WsServerMessage, type WsStream, type WsStreamCompleted, type WsStreamProgress, type WsStreamStarted, type WsStreamStop, type WsStreamStopped, type WsSubscribe, type WsSubscribed, type WsUnsubscribe, type WsUnsubscribed, OxArchive as default };
package/dist/index.js CHANGED
@@ -79,7 +79,7 @@ var HttpClient = class {
79
79
  throw new OxArchiveError(
80
80
  error.error || `Request failed with status ${response.status}`,
81
81
  response.status,
82
- data.request_id
82
+ data.meta?.request_id
83
83
  );
84
84
  }
85
85
  return data;
@@ -169,27 +169,6 @@ var TradesResource = class {
169
169
  }
170
170
  };
171
171
 
172
- // src/resources/candles.ts
173
- var CandlesResource = class {
174
- constructor(http) {
175
- this.http = http;
176
- }
177
- /**
178
- * Get OHLCV candles for a coin
179
- *
180
- * @param coin - The coin symbol (e.g., 'BTC', 'ETH')
181
- * @param params - Interval, time range, and pagination parameters
182
- * @returns Array of candles
183
- */
184
- async list(coin, params) {
185
- const response = await this.http.get(
186
- `/v1/candles/${coin.toUpperCase()}`,
187
- params
188
- );
189
- return response.data;
190
- }
191
- };
192
-
193
172
  // src/resources/instruments.ts
194
173
  var InstrumentsResource = class {
195
174
  constructor(http) {
@@ -299,10 +278,6 @@ var OxArchive = class {
299
278
  * Trade/fill history
300
279
  */
301
280
  trades;
302
- /**
303
- * OHLCV candles
304
- */
305
- candles;
306
281
  /**
307
282
  * Trading instruments metadata
308
283
  */
@@ -331,7 +306,6 @@ var OxArchive = class {
331
306
  });
332
307
  this.orderbook = new OrderBookResource(this.http);
333
308
  this.trades = new TradesResource(this.http);
334
- this.candles = new CandlesResource(this.http);
335
309
  this.instruments = new InstrumentsResource(this.http);
336
310
  this.funding = new FundingResource(this.http);
337
311
  this.openInterest = new OpenInterestResource(this.http);
@@ -339,7 +313,7 @@ var OxArchive = class {
339
313
  };
340
314
 
341
315
  // src/websocket.ts
342
- var DEFAULT_WS_URL = "wss://ws.0xarchive.io";
316
+ var DEFAULT_WS_URL = "wss://api.0xarchive.io/ws";
343
317
  var DEFAULT_PING_INTERVAL = 3e4;
344
318
  var DEFAULT_RECONNECT_DELAY = 1e3;
345
319
  var DEFAULT_MAX_RECONNECT_ATTEMPTS = 10;
@@ -592,7 +566,7 @@ var OxArchiveWs = class {
592
566
  this.handlers.onMessage = (message) => {
593
567
  if (message.type === "historical_batch") {
594
568
  const msg = message;
595
- handler(msg.coin, msg.records);
569
+ handler(msg.coin, msg.data);
596
570
  }
597
571
  originalHandler?.(message);
598
572
  };
@@ -605,7 +579,7 @@ var OxArchiveWs = class {
605
579
  this.handlers.onMessage = (message) => {
606
580
  if (message.type === "replay_started") {
607
581
  const msg = message;
608
- handler(msg.channel, msg.coin, msg.total_records, msg.speed);
582
+ handler(msg.channel, msg.coin, msg.start, msg.end, msg.speed);
609
583
  }
610
584
  originalHandler?.(message);
611
585
  };
@@ -618,7 +592,7 @@ var OxArchiveWs = class {
618
592
  this.handlers.onMessage = (message) => {
619
593
  if (message.type === "replay_completed") {
620
594
  const msg = message;
621
- handler(msg.channel, msg.coin, msg.records_sent);
595
+ handler(msg.channel, msg.coin, msg.snapshots_sent);
622
596
  }
623
597
  originalHandler?.(message);
624
598
  };
@@ -631,7 +605,7 @@ var OxArchiveWs = class {
631
605
  this.handlers.onMessage = (message) => {
632
606
  if (message.type === "stream_started") {
633
607
  const msg = message;
634
- handler(msg.channel, msg.coin, msg.total_records);
608
+ handler(msg.channel, msg.coin, msg.start, msg.end);
635
609
  }
636
610
  originalHandler?.(message);
637
611
  };
@@ -644,7 +618,7 @@ var OxArchiveWs = class {
644
618
  this.handlers.onMessage = (message) => {
645
619
  if (message.type === "stream_progress") {
646
620
  const msg = message;
647
- handler(msg.records_sent, msg.total_records, msg.progress_pct);
621
+ handler(msg.snapshots_sent);
648
622
  }
649
623
  originalHandler?.(message);
650
624
  };
@@ -657,7 +631,7 @@ var OxArchiveWs = class {
657
631
  this.handlers.onMessage = (message) => {
658
632
  if (message.type === "stream_completed") {
659
633
  const msg = message;
660
- handler(msg.channel, msg.coin, msg.records_sent);
634
+ handler(msg.channel, msg.coin, msg.snapshots_sent);
661
635
  }
662
636
  originalHandler?.(message);
663
637
  };