@imbingox/acex 0.3.0-beta.1 → 0.3.0-beta.2

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.
@@ -3,7 +3,7 @@ import type {
3
3
  StreamHandle,
4
4
  } from "../adapters/types.ts";
5
5
  import { AcexError } from "../errors.ts";
6
- import type { AccountRuntimeOptions, Exchange } from "../types/index.ts";
6
+ import type { AccountRuntimeOptions, Venue } from "../types/index.ts";
7
7
  import type {
8
8
  ClientContext,
9
9
  PrivateAccountDataConsumer,
@@ -13,7 +13,7 @@ import type {
13
13
 
14
14
  interface PrivateSubscriptionRecord {
15
15
  accountId: string;
16
- exchange: Exchange;
16
+ venue: Venue;
17
17
  accountSubscribed: boolean;
18
18
  ordersSubscribed: boolean;
19
19
  accountReady: boolean;
@@ -30,24 +30,27 @@ const DEFAULT_LISTEN_KEY_KEEPALIVE_MS = 30 * 60 * 1_000;
30
30
 
31
31
  export class PrivateSubscriptionCoordinator {
32
32
  private readonly context: ClientContext;
33
- private readonly adapter: PrivateUserDataAdapter;
33
+ private readonly adapters: Map<Venue, PrivateUserDataAdapter>;
34
34
  private readonly accountConsumer: PrivateAccountDataConsumer;
35
35
  private readonly orderConsumer: PrivateOrderDataConsumer;
36
36
  private readonly streamOpenTimeoutMs: number;
37
37
  private readonly streamReconnectDelayMs: number;
38
38
  private readonly streamReconnectMaxDelayMs: number;
39
39
  private readonly listenKeyKeepAliveMs: number;
40
+ private readonly juplendPollIntervalMs?: number;
40
41
  private readonly records = new Map<string, PrivateSubscriptionRecord>();
41
42
 
42
43
  constructor(
43
44
  context: ClientContext,
44
- adapter: PrivateUserDataAdapter,
45
+ adapters: PrivateUserDataAdapter[],
45
46
  accountConsumer: PrivateAccountDataConsumer,
46
47
  orderConsumer: PrivateOrderDataConsumer,
47
48
  options: AccountRuntimeOptions = {},
48
49
  ) {
49
50
  this.context = context;
50
- this.adapter = adapter;
51
+ this.adapters = new Map(
52
+ adapters.map((adapter) => [adapter.venue, adapter]),
53
+ );
51
54
  this.accountConsumer = accountConsumer;
52
55
  this.orderConsumer = orderConsumer;
53
56
  this.streamOpenTimeoutMs =
@@ -59,6 +62,7 @@ export class PrivateSubscriptionCoordinator {
59
62
  DEFAULT_STREAM_RECONNECT_MAX_DELAY_MS;
60
63
  this.listenKeyKeepAliveMs =
61
64
  options.listenKeyKeepAliveMs ?? DEFAULT_LISTEN_KEY_KEEPALIVE_MS;
65
+ this.juplendPollIntervalMs = options.juplend?.pollIntervalMs;
62
66
  }
63
67
 
64
68
  async subscribeAccountFeed(accountId: string): Promise<void> {
@@ -67,12 +71,17 @@ export class PrivateSubscriptionCoordinator {
67
71
  const needsPending = !record.stream && !record.startPromise;
68
72
  record.accountSubscribed = true;
69
73
  if (needsPending) {
70
- this.accountConsumer.onPrivateAccountPending(accountId, record.exchange);
74
+ this.accountConsumer.onPrivateAccountPending(accountId, record.venue);
71
75
  }
72
76
 
73
77
  try {
74
- await this.ensureStream(record, account);
75
- await this.bootstrapAccount(record, account);
78
+ if (record.venue === "juplend") {
79
+ await this.bootstrapAccount(record, account);
80
+ await this.ensureStream(record, account);
81
+ } else {
82
+ await this.ensureStream(record, account);
83
+ await this.bootstrapAccount(record, account);
84
+ }
76
85
  } catch (error) {
77
86
  record.accountSubscribed = false;
78
87
  this.closeIfUnused(record);
@@ -96,7 +105,7 @@ export class PrivateSubscriptionCoordinator {
96
105
  const needsPending = !record.stream && !record.startPromise;
97
106
  record.ordersSubscribed = true;
98
107
  if (needsPending) {
99
- this.orderConsumer.onPrivateOrderPending(accountId, record.exchange);
108
+ this.orderConsumer.onPrivateOrderPending(accountId, record.venue);
100
109
  }
101
110
 
102
111
  try {
@@ -128,13 +137,13 @@ export class PrivateSubscriptionCoordinator {
128
137
  if (record.accountSubscribed) {
129
138
  this.accountConsumer.onPrivateAccountPending(
130
139
  record.accountId,
131
- record.exchange,
140
+ record.venue,
132
141
  );
133
142
  }
134
143
  if (record.ordersSubscribed) {
135
144
  this.orderConsumer.onPrivateOrderPending(
136
145
  record.accountId,
137
- record.exchange,
146
+ record.venue,
138
147
  );
139
148
  }
140
149
 
@@ -165,10 +174,10 @@ export class PrivateSubscriptionCoordinator {
165
174
  }
166
175
 
167
176
  if (record.accountSubscribed) {
168
- this.accountConsumer.onPrivateAccountPending(accountId, record.exchange);
177
+ this.accountConsumer.onPrivateAccountPending(accountId, record.venue);
169
178
  }
170
179
  if (record.ordersSubscribed) {
171
- this.orderConsumer.onPrivateOrderPending(accountId, record.exchange);
180
+ this.orderConsumer.onPrivateOrderPending(accountId, record.venue);
172
181
  }
173
182
 
174
183
  void this.resumeRecord(record);
@@ -179,9 +188,14 @@ export class PrivateSubscriptionCoordinator {
179
188
  this.closeStream(record);
180
189
 
181
190
  try {
182
- await this.ensureStream(record, account);
183
- if (record.accountSubscribed) {
191
+ if (record.venue === "juplend" && record.accountSubscribed) {
184
192
  await this.bootstrapAccount(record, account);
193
+ await this.ensureStream(record, account);
194
+ } else {
195
+ await this.ensureStream(record, account);
196
+ if (record.accountSubscribed) {
197
+ await this.bootstrapAccount(record, account);
198
+ }
185
199
  }
186
200
  if (record.ordersSubscribed) {
187
201
  await this.bootstrapOrders(record, account);
@@ -193,16 +207,28 @@ export class PrivateSubscriptionCoordinator {
193
207
 
194
208
  private getAccount(accountId: string): RegisteredAccountRecord {
195
209
  const account = this.context.getRegisteredAccount(accountId);
196
- if (account.exchange !== this.adapter.exchange) {
210
+ if (!this.adapters.has(account.venue)) {
197
211
  throw new AcexError(
198
- "EXCHANGE_NOT_SUPPORTED",
199
- `Exchange is not supported yet: ${account.exchange}`,
212
+ "VENUE_NOT_SUPPORTED",
213
+ `Venue is not supported yet: ${account.venue}`,
200
214
  );
201
215
  }
202
216
 
203
217
  return account;
204
218
  }
205
219
 
220
+ private getAdapter(venue: Venue): PrivateUserDataAdapter {
221
+ const adapter = this.adapters.get(venue);
222
+ if (!adapter) {
223
+ throw new AcexError(
224
+ "VENUE_NOT_SUPPORTED",
225
+ `Venue is not supported yet: ${venue}`,
226
+ );
227
+ }
228
+
229
+ return adapter;
230
+ }
231
+
206
232
  private getOrCreateRecord(
207
233
  account: RegisteredAccountRecord,
208
234
  ): PrivateSubscriptionRecord {
@@ -213,7 +239,7 @@ export class PrivateSubscriptionCoordinator {
213
239
 
214
240
  const record: PrivateSubscriptionRecord = {
215
241
  accountId: account.accountId,
216
- exchange: account.exchange,
242
+ venue: account.venue,
217
243
  accountSubscribed: false,
218
244
  ordersSubscribed: false,
219
245
  accountReady: false,
@@ -275,9 +301,22 @@ export class PrivateSubscriptionCoordinator {
275
301
  );
276
302
  }
277
303
 
278
- const stream = this.adapter.createPrivateStream(
304
+ const adapter = this.getAdapter(record.venue);
305
+ const stream = adapter.createPrivateStream(
279
306
  credentials,
280
307
  {
308
+ onAccountSnapshot: (snapshot) => {
309
+ if (!record.accountSubscribed) {
310
+ return;
311
+ }
312
+
313
+ record.accountReady = true;
314
+ this.accountConsumer.onPrivateAccountBootstrap(
315
+ record.accountId,
316
+ record.venue,
317
+ snapshot,
318
+ );
319
+ },
281
320
  onAccountUpdate: (update) => {
282
321
  if (!record.accountSubscribed) {
283
322
  return;
@@ -286,7 +325,7 @@ export class PrivateSubscriptionCoordinator {
286
325
  record.accountReady = true;
287
326
  this.accountConsumer.onPrivateAccountUpdate(
288
327
  record.accountId,
289
- record.exchange,
328
+ record.venue,
290
329
  update,
291
330
  );
292
331
  },
@@ -298,7 +337,7 @@ export class PrivateSubscriptionCoordinator {
298
337
  record.orderReady = true;
299
338
  this.orderConsumer.onPrivateOrderUpdate(
300
339
  record.accountId,
301
- record.exchange,
340
+ record.venue,
302
341
  update,
303
342
  );
304
343
  },
@@ -306,7 +345,7 @@ export class PrivateSubscriptionCoordinator {
306
345
  if (record.accountSubscribed) {
307
346
  this.accountConsumer.onPrivateAccountStreamState(
308
347
  record.accountId,
309
- record.exchange,
348
+ record.venue,
310
349
  {
311
350
  runtimeStatus: "reconnecting",
312
351
  ready: record.accountReady,
@@ -317,7 +356,7 @@ export class PrivateSubscriptionCoordinator {
317
356
  if (record.ordersSubscribed) {
318
357
  this.orderConsumer.onPrivateOrderStreamState(
319
358
  record.accountId,
320
- record.exchange,
359
+ record.venue,
321
360
  {
322
361
  runtimeStatus: "reconnecting",
323
362
  ready: record.orderReady,
@@ -338,8 +377,19 @@ export class PrivateSubscriptionCoordinator {
338
377
  onError: (error) => {
339
378
  this.context.publishRuntimeError("adapter", error, {
340
379
  accountId: record.accountId,
341
- exchange: record.exchange,
380
+ venue: record.venue,
342
381
  });
382
+ if (record.accountSubscribed) {
383
+ this.accountConsumer.onPrivateAccountStreamState(
384
+ record.accountId,
385
+ record.venue,
386
+ {
387
+ runtimeStatus: "degraded",
388
+ ready: record.accountReady,
389
+ reason: "http_failed",
390
+ },
391
+ );
392
+ }
343
393
  },
344
394
  },
345
395
  {
@@ -347,6 +397,7 @@ export class PrivateSubscriptionCoordinator {
347
397
  reconnectDelayMs: this.streamReconnectDelayMs,
348
398
  reconnectMaxDelayMs: this.streamReconnectMaxDelayMs,
349
399
  listenKeyKeepAliveMs: this.listenKeyKeepAliveMs,
400
+ juplendPollIntervalMs: this.juplendPollIntervalMs,
350
401
  now: () => this.context.now(),
351
402
  },
352
403
  account.options,
@@ -361,16 +412,16 @@ export class PrivateSubscriptionCoordinator {
361
412
  const runtimeError =
362
413
  error instanceof Error
363
414
  ? error
364
- : new Error("Failed to open Binance private stream");
415
+ : new Error(`Failed to open ${record.venue} private stream`);
365
416
  this.context.publishRuntimeError("adapter", runtimeError, {
366
417
  accountId: record.accountId,
367
- exchange: record.exchange,
418
+ venue: record.venue,
368
419
  });
369
420
 
370
421
  if (record.accountSubscribed) {
371
422
  this.accountConsumer.onPrivateAccountStreamState(
372
423
  record.accountId,
373
- record.exchange,
424
+ record.venue,
374
425
  {
375
426
  runtimeStatus: "degraded",
376
427
  ready: record.accountReady,
@@ -381,7 +432,7 @@ export class PrivateSubscriptionCoordinator {
381
432
  if (record.ordersSubscribed) {
382
433
  this.orderConsumer.onPrivateOrderStreamState(
383
434
  record.accountId,
384
- record.exchange,
435
+ record.venue,
385
436
  {
386
437
  runtimeStatus: "degraded",
387
438
  ready: record.orderReady,
@@ -402,16 +453,13 @@ export class PrivateSubscriptionCoordinator {
402
453
  if (record.accountSubscribed) {
403
454
  this.accountConsumer.onPrivateAccountPending(
404
455
  record.accountId,
405
- record.exchange,
456
+ record.venue,
406
457
  );
407
458
  await this.bootstrapAccount(record, account);
408
459
  }
409
460
 
410
461
  if (record.ordersSubscribed) {
411
- this.orderConsumer.onPrivateOrderPending(
412
- record.accountId,
413
- record.exchange,
414
- );
462
+ this.orderConsumer.onPrivateOrderPending(record.accountId, record.venue);
415
463
  await this.bootstrapOrders(record, account);
416
464
  }
417
465
  }
@@ -421,9 +469,9 @@ export class PrivateSubscriptionCoordinator {
421
469
  account: RegisteredAccountRecord,
422
470
  ): Promise<void> {
423
471
  try {
424
- const bootstrap = await this.adapter.bootstrapAccount(
472
+ const bootstrap = await this.getAdapter(record.venue).bootstrapAccount(
425
473
  account.credentials ?? {},
426
- account.options,
474
+ { ...account.options, accountId: account.accountId },
427
475
  );
428
476
  if (!record.accountSubscribed) {
429
477
  return;
@@ -432,7 +480,7 @@ export class PrivateSubscriptionCoordinator {
432
480
  record.accountReady = true;
433
481
  this.accountConsumer.onPrivateAccountBootstrap(
434
482
  record.accountId,
435
- record.exchange,
483
+ record.venue,
436
484
  bootstrap,
437
485
  );
438
486
  } catch (error) {
@@ -441,24 +489,28 @@ export class PrivateSubscriptionCoordinator {
441
489
  "adapter",
442
490
  error instanceof Error
443
491
  ? error
444
- : new Error("Failed to bootstrap Binance private account state"),
492
+ : new Error(
493
+ `Failed to bootstrap ${record.venue} private account state`,
494
+ ),
445
495
  {
446
496
  accountId: record.accountId,
447
- exchange: record.exchange,
497
+ venue: record.venue,
448
498
  },
449
499
  );
450
500
  this.accountConsumer.onPrivateAccountStreamState(
451
501
  record.accountId,
452
- record.exchange,
502
+ record.venue,
453
503
  {
454
504
  runtimeStatus: "degraded",
455
505
  ready: false,
456
- reason: "auth_failed",
506
+ reason: record.venue === "juplend" ? "http_failed" : "auth_failed",
457
507
  },
458
508
  );
509
+ const reason =
510
+ error instanceof Error && error.message ? ` (${error.message})` : "";
459
511
  throw new AcexError(
460
512
  "ACCOUNT_BOOTSTRAP_FAILED",
461
- `Failed to bootstrap account data: ${record.accountId}`,
513
+ `Failed to bootstrap account data: ${record.accountId}${reason}`,
462
514
  );
463
515
  }
464
516
  }
@@ -468,7 +520,7 @@ export class PrivateSubscriptionCoordinator {
468
520
  account: RegisteredAccountRecord,
469
521
  ): Promise<void> {
470
522
  try {
471
- const snapshots = await this.adapter.bootstrapOpenOrders(
523
+ const snapshots = await this.getAdapter(record.venue).bootstrapOpenOrders(
472
524
  account.credentials ?? {},
473
525
  account.options,
474
526
  );
@@ -479,7 +531,7 @@ export class PrivateSubscriptionCoordinator {
479
531
  record.orderReady = true;
480
532
  this.orderConsumer.onPrivateOrderBootstrap(
481
533
  record.accountId,
482
- record.exchange,
534
+ record.venue,
483
535
  snapshots,
484
536
  );
485
537
  } catch (error) {
@@ -488,15 +540,17 @@ export class PrivateSubscriptionCoordinator {
488
540
  "adapter",
489
541
  error instanceof Error
490
542
  ? error
491
- : new Error("Failed to bootstrap Binance private order state"),
543
+ : new Error(
544
+ `Failed to bootstrap ${record.venue} private order state`,
545
+ ),
492
546
  {
493
547
  accountId: record.accountId,
494
- exchange: record.exchange,
548
+ venue: record.venue,
495
549
  },
496
550
  );
497
551
  this.orderConsumer.onPrivateOrderStreamState(
498
552
  record.accountId,
499
- record.exchange,
553
+ record.venue,
500
554
  {
501
555
  runtimeStatus: "degraded",
502
556
  ready: false,
@@ -1,5 +1,6 @@
1
1
  import { BinanceMarketAdapter } from "../adapters/binance/adapter.ts";
2
2
  import { BinancePrivateAdapter } from "../adapters/binance/private-adapter.ts";
3
+ import { JuplendPrivateAdapter } from "../adapters/juplend/private-adapter.ts";
3
4
  import type {
4
5
  CancelAllOrdersRequest,
5
6
  CancelOrderRequest,
@@ -33,6 +34,7 @@ import type {
33
34
  RegisterAccountInput,
34
35
  RegisterAccountResult,
35
36
  StopOptions,
37
+ Venue,
36
38
  } from "../types/index.ts";
37
39
  import {
38
40
  type ClientContext,
@@ -87,14 +89,20 @@ export class AcexClientImpl implements AcexClient, ClientContext {
87
89
  private readonly marketManager: MarketManagerImpl;
88
90
  private readonly accountManager: AccountManagerImpl;
89
91
  private readonly orderManager: OrderManagerImpl;
90
- private readonly privateAdapter: PrivateUserDataAdapter;
92
+ private readonly privateAdapters: Map<string, PrivateUserDataAdapter>;
91
93
  private readonly privateCoordinator: PrivateSubscriptionCoordinator;
92
94
 
93
95
  constructor(options: CreateClientOptions = {}) {
94
96
  activeClients.add(this);
95
97
 
96
98
  const marketAdapter = new BinanceMarketAdapter();
97
- this.privateAdapter = new BinancePrivateAdapter();
99
+ const privateAdapters = [
100
+ new BinancePrivateAdapter(),
101
+ new JuplendPrivateAdapter(),
102
+ ];
103
+ this.privateAdapters = new Map(
104
+ privateAdapters.map((adapter) => [adapter.venue, adapter]),
105
+ );
98
106
 
99
107
  this.marketManager = new MarketManagerImpl(this, marketAdapter, {
100
108
  initialL1TimeoutMs: options.market?.l1InitialMessageTimeoutMs,
@@ -106,7 +114,7 @@ export class AcexClientImpl implements AcexClient, ClientContext {
106
114
  this.orderManager = new OrderManagerImpl(this);
107
115
  this.privateCoordinator = new PrivateSubscriptionCoordinator(
108
116
  this,
109
- this.privateAdapter,
117
+ privateAdapters,
110
118
  this.accountManager as PrivateAccountDataConsumer,
111
119
  this.orderManager as PrivateOrderDataConsumer,
112
120
  options.account,
@@ -141,20 +149,20 @@ export class AcexClientImpl implements AcexClient, ClientContext {
141
149
  throw this.createError(
142
150
  "ACCOUNT_ALREADY_EXISTS",
143
151
  `Account already exists: ${input.accountId}`,
144
- { accountId: input.accountId, exchange: input.exchange },
152
+ { accountId: input.accountId, venue: input.venue },
145
153
  );
146
154
  }
147
155
 
148
156
  this.registeredAccounts.set(input.accountId, {
149
157
  accountId: input.accountId,
150
- exchange: input.exchange,
158
+ venue: input.venue,
151
159
  credentials: input.credentials,
152
- options: input.options,
160
+ options: input.options as Record<string, unknown> | undefined,
153
161
  });
154
162
 
155
163
  return {
156
164
  accountId: input.accountId,
157
- exchange: input.exchange,
165
+ venue: input.venue,
158
166
  };
159
167
  }
160
168
 
@@ -177,8 +185,8 @@ export class AcexClientImpl implements AcexClient, ClientContext {
177
185
  return;
178
186
  }
179
187
 
180
- this.accountManager.onCredentialsUpdated(accountId, account.exchange);
181
- this.orderManager.onCredentialsUpdated(accountId, account.exchange);
188
+ this.accountManager.onCredentialsUpdated(accountId, account.venue);
189
+ this.orderManager.onCredentialsUpdated(accountId, account.venue);
182
190
  this.privateCoordinator.onCredentialsUpdated(accountId);
183
191
  }
184
192
 
@@ -262,14 +270,14 @@ export class AcexClientImpl implements AcexClient, ClientContext {
262
270
 
263
271
  ensurePrivateCredentials(accountId: string): void {
264
272
  const account = this.getRegisteredAccount(accountId);
265
- if (hasPrivateCredentials(account.credentials)) {
273
+ if (hasPrivateCredentials(account.credentials, account.venue)) {
266
274
  return;
267
275
  }
268
276
 
269
277
  throw this.createError(
270
278
  "CREDENTIALS_MISSING",
271
279
  `Account credentials are required for private subscriptions: ${accountId}`,
272
- { accountId, exchange: account.exchange },
280
+ { accountId, venue: account.venue },
273
281
  );
274
282
  }
275
283
 
@@ -303,7 +311,7 @@ export class AcexClientImpl implements AcexClient, ClientContext {
303
311
  positionSide: input.positionSide,
304
312
  };
305
313
 
306
- return this.privateAdapter.createOrder(
314
+ return this.getPrivateAdapter(account.venue).createOrder(
307
315
  account.credentials ?? {},
308
316
  request,
309
317
  account.options,
@@ -318,7 +326,7 @@ export class AcexClientImpl implements AcexClient, ClientContext {
318
326
  clientOrderId: input.clientOrderId,
319
327
  };
320
328
 
321
- return this.privateAdapter.cancelOrder(
329
+ return this.getPrivateAdapter(account.venue).cancelOrder(
322
330
  account.credentials ?? {},
323
331
  request,
324
332
  account.options,
@@ -331,7 +339,7 @@ export class AcexClientImpl implements AcexClient, ClientContext {
331
339
  symbol: input.symbol,
332
340
  };
333
341
 
334
- return this.privateAdapter.cancelAllOrders(
342
+ return this.getPrivateAdapter(account.venue).cancelAllOrders(
335
343
  account.credentials ?? {},
336
344
  request,
337
345
  account.options,
@@ -390,22 +398,36 @@ export class AcexClientImpl implements AcexClient, ClientContext {
390
398
 
391
399
  private getPrivateCommandAccount(accountId: string): RegisteredAccountRecord {
392
400
  const account = this.getRegisteredAccount(accountId);
393
- if (account.exchange !== this.privateAdapter.exchange) {
401
+ const adapter = this.getPrivateAdapter(account.venue);
402
+ if (adapter.venue === "juplend") {
394
403
  throw this.createError(
395
- "EXCHANGE_NOT_SUPPORTED",
396
- `Exchange is not supported yet: ${account.exchange}`,
397
- { accountId, exchange: account.exchange },
404
+ "VENUE_NOT_SUPPORTED",
405
+ `Venue does not support private order commands: ${account.venue}`,
406
+ { accountId, venue: account.venue },
398
407
  );
399
408
  }
400
409
 
401
- if (!hasPrivateCredentials(account.credentials)) {
410
+ if (!hasPrivateCredentials(account.credentials, account.venue)) {
402
411
  throw this.createError(
403
412
  "CREDENTIALS_MISSING",
404
413
  `Account credentials are required for private order commands: ${accountId}`,
405
- { accountId, exchange: account.exchange },
414
+ { accountId, venue: account.venue },
406
415
  );
407
416
  }
408
417
 
409
418
  return account;
410
419
  }
420
+
421
+ private getPrivateAdapter(venue: Venue): PrivateUserDataAdapter {
422
+ const adapter = this.privateAdapters.get(venue);
423
+ if (!adapter) {
424
+ throw this.createError(
425
+ "VENUE_NOT_SUPPORTED",
426
+ `Venue is not supported yet: ${venue}`,
427
+ { venue },
428
+ );
429
+ }
430
+
431
+ return adapter;
432
+ }
411
433
  }
package/src/errors.ts CHANGED
@@ -4,7 +4,7 @@ export type AcexErrorCode =
4
4
  | "ACCOUNT_NOT_FOUND"
5
5
  | "CLIENT_NOT_STARTED"
6
6
  | "CREDENTIALS_MISSING"
7
- | "EXCHANGE_NOT_SUPPORTED"
7
+ | "VENUE_NOT_SUPPORTED"
8
8
  | "MARKET_CATALOG_LOAD_FAILED"
9
9
  | "MARKET_INACTIVE"
10
10
  | "MARKET_FUNDING_RATE_UNSUPPORTED"
@@ -1,21 +1,21 @@
1
1
  import type {
2
2
  AccountEventFilter,
3
- Exchange,
4
3
  HealthEvent,
5
4
  HealthEventFilter,
6
5
  MarketEventFilter,
7
6
  OrderEventFilter,
7
+ Venue,
8
8
  } from "../types/index.ts";
9
9
 
10
10
  export function matchesMarketFilter(
11
- event: { exchange: Exchange; symbol: string },
11
+ event: { venue: Venue; symbol: string },
12
12
  filter?: MarketEventFilter,
13
13
  ): boolean {
14
14
  if (!filter) {
15
15
  return true;
16
16
  }
17
17
 
18
- if (filter.exchange && event.exchange !== filter.exchange) {
18
+ if (filter.venue && event.venue !== filter.venue) {
19
19
  return false;
20
20
  }
21
21
 
@@ -27,7 +27,7 @@ export function matchesMarketFilter(
27
27
  }
28
28
 
29
29
  export function matchesAccountFilter(
30
- event: { accountId: string; exchange: Exchange; symbol?: string },
30
+ event: { accountId: string; venue: Venue; symbol?: string },
31
31
  filter?: AccountEventFilter,
32
32
  ): boolean {
33
33
  if (!filter) {
@@ -38,7 +38,7 @@ export function matchesAccountFilter(
38
38
  return false;
39
39
  }
40
40
 
41
- if (filter.exchange && event.exchange !== filter.exchange) {
41
+ if (filter.venue && event.venue !== filter.venue) {
42
42
  return false;
43
43
  }
44
44
 
@@ -50,7 +50,7 @@ export function matchesAccountFilter(
50
50
  }
51
51
 
52
52
  export function matchesOrderFilter(
53
- event: { accountId: string; exchange: Exchange; symbol?: string },
53
+ event: { accountId: string; venue: Venue; symbol?: string },
54
54
  filter?: OrderEventFilter,
55
55
  ): boolean {
56
56
  if (!filter) {
@@ -61,7 +61,7 @@ export function matchesOrderFilter(
61
61
  return false;
62
62
  }
63
63
 
64
- if (filter.exchange && event.exchange !== filter.exchange) {
64
+ if (filter.venue && event.venue !== filter.venue) {
65
65
  return false;
66
66
  }
67
67
 
@@ -95,8 +95,8 @@ export function matchesHealthFilter(
95
95
  }
96
96
  }
97
97
 
98
- if (filter.exchange) {
99
- if (!("exchange" in event) || event.exchange !== filter.exchange) {
98
+ if (filter.venue) {
99
+ if (!("venue" in event) || event.venue !== filter.venue) {
100
100
  return false;
101
101
  }
102
102
  }