@usherlabs/cex-broker 0.2.49 → 0.2.50

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.
@@ -20,6 +20,7 @@ export type CryptoHftDataCapabilityProfile = Readonly<{
20
20
  }>;
21
21
  export declare const CRYPTOHFTDATA_BINANCE_SPOT_BTCUSDT_PROFILE: CryptoHftDataCapabilityProfile;
22
22
  export declare const CRYPTOHFTDATA_OKX_SPOT_ARBUSDT_PROFILE: CryptoHftDataCapabilityProfile;
23
+ export declare const CRYPTOHFTDATA_OKX_SPOT_ARBUSDC_PROFILE: CryptoHftDataCapabilityProfile;
23
24
  export declare class CryptoHftDataError extends Error {
24
25
  readonly reason: string;
25
26
  constructor(reason: string);
@@ -1,6 +1,7 @@
1
1
  export declare const LEGACY_CAPABILITY_POLICY_ID: "market-data-vendor-backfill-capabilities/v1";
2
2
  export declare const CAPABILITY_POLICY_ID: "market-data-vendor-backfill-capabilities/v2";
3
- export declare const RESOURCE_POLICY_ID: "market-data-vendor-backfill-resources/v1";
3
+ export declare const LEGACY_RESOURCE_POLICY_ID: "market-data-vendor-backfill-resources/v1";
4
+ export declare const RESOURCE_POLICY_ID: "market-data-vendor-backfill-resources/v2";
4
5
  export declare const ADAPTER_POLICY_ID: "cryptohftdata-orderbook-adapter/v1";
5
6
  export declare const ACQUISITION_POLICY_ID: "cryptohftdata-hourly-acquisition/v1";
6
7
  export declare const LEGACY_CAPABILITY_POLICY: Readonly<{
@@ -32,7 +33,7 @@ export declare const LEGACY_CAPABILITY_POLICY: Readonly<{
32
33
  export declare const CAPABILITY_POLICY: Readonly<{
33
34
  policy_sha256: string;
34
35
  policy_id: "market-data-vendor-backfill-capabilities/v2";
35
- profiles: {
36
+ profiles: readonly [...{
36
37
  source_policies: readonly ["authoritative_window", "fill_gaps"];
37
38
  exchange: "okx";
38
39
  market_type: "spot";
@@ -42,7 +43,17 @@ export declare const CAPABILITY_POLICY: Readonly<{
42
43
  resolved_symbol: "ARB-USDT";
43
44
  construction_modes: readonly ["sampled_top_n_snapshot"];
44
45
  max_depth: 400;
45
- }[];
46
+ }[], {
47
+ readonly exchange: "okx";
48
+ readonly market_type: "spot";
49
+ readonly feed: "ORDERBOOK";
50
+ readonly canonical_trading_pair: "ARB-USDC";
51
+ readonly provider_exchange_id: "okx_spot";
52
+ readonly resolved_symbol: "ARB-USDC";
53
+ readonly construction_modes: readonly ["sampled_top_n_snapshot"];
54
+ readonly source_policies: readonly ["authoritative_window", "fill_gaps"];
55
+ readonly max_depth: 400;
56
+ }];
46
57
  provider: "cryptohftdata";
47
58
  adapter_policy: {
48
59
  readonly policy_id: "cryptohftdata-orderbook-adapter/v1";
@@ -55,7 +66,7 @@ export declare const CAPABILITY_POLICY: Readonly<{
55
66
  readonly initialization_lookback_ms: 0;
56
67
  };
57
68
  }>;
58
- export declare const RESOURCE_POLICY: Readonly<{
69
+ export declare const LEGACY_RESOURCE_POLICY: Readonly<{
59
70
  policy_sha256: string;
60
71
  policy_id: "market-data-vendor-backfill-resources/v1";
61
72
  limits: {
@@ -71,6 +82,22 @@ export declare const RESOURCE_POLICY: Readonly<{
71
82
  readonly max_required_events: 100000;
72
83
  };
73
84
  }>;
85
+ export declare const RESOURCE_POLICY: Readonly<{
86
+ policy_sha256: string;
87
+ policy_id: "market-data-vendor-backfill-resources/v2";
88
+ request_bounds: {
89
+ readonly max_window_ms: number;
90
+ readonly max_depth: 500;
91
+ readonly max_required_events: 100000;
92
+ };
93
+ limits: {
94
+ readonly max_files: 10000;
95
+ readonly max_bytes: number;
96
+ readonly max_rows: 1000000000;
97
+ readonly max_duration_ms: number;
98
+ readonly max_boundary_lookback_ms: number;
99
+ };
100
+ }>;
74
101
  export declare const EFFECTIVE_ADAPTER_POLICY_PIN: Readonly<{
75
102
  policy_id: "cryptohftdata-orderbook-adapter/v1";
76
103
  policy_sha256: string;
@@ -0,0 +1,8 @@
1
+ import type { Metadata } from "@grpc/grpc-js";
2
+ /** gRPC metadata key for lightweight operational correlation with callers. */
3
+ export declare const TRACE_METADATA_KEY = "x-trace-id";
4
+ /**
5
+ * Returns a validated caller correlation ID without mutating inbound metadata.
6
+ * Invalid values are deliberately discarded before they can reach telemetry.
7
+ */
8
+ export declare function extractTraceId(metadata: Metadata): string | undefined;
package/dist/index.js CHANGED
@@ -310668,6 +310668,24 @@ function selectBrokerAccountForCex(normalizedCex, brokers, metadata) {
310668
310668
  return selectBrokerAccount(brokers[normalizedCex], metadata) ?? undefined;
310669
310669
  }
310670
310670
 
310671
+ // src/helpers/trace-context.ts
310672
+ var TRACE_METADATA_KEY = "x-trace-id";
310673
+ var MAX_TRACE_METADATA_LENGTH = 128;
310674
+ var OTEL_TRACE_ID_PATTERN = /^[0-9a-f]{32}$/;
310675
+ var UUID_V4_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
310676
+ var ZERO_OTEL_TRACE_ID = "00000000000000000000000000000000";
310677
+ function extractTraceId(metadata) {
310678
+ const raw = metadata.get(TRACE_METADATA_KEY)[0];
310679
+ if (typeof raw !== "string" || raw.length > MAX_TRACE_METADATA_LENGTH) {
310680
+ return;
310681
+ }
310682
+ const traceId = raw.trim();
310683
+ if (OTEL_TRACE_ID_PATTERN.test(traceId) && traceId !== ZERO_OTEL_TRACE_ID || UUID_V4_PATTERN.test(traceId)) {
310684
+ return traceId;
310685
+ }
310686
+ return;
310687
+ }
310688
+
310671
310689
  // src/handlers/execute-action/order-book-call.ts
310672
310690
  import * as grpc4 from "@grpc/grpc-js";
310673
310691
  async function handleOrderBookCall(ctx) {
@@ -311971,6 +311989,15 @@ function isPublicMarketDataAction(action, payload) {
311971
311989
  return false;
311972
311990
  return isOrderBookCallMethod(payload?.method ?? payload?.functionName);
311973
311991
  }
311992
+ function grpcStatusName(error48) {
311993
+ if (!error48) {
311994
+ return "OK";
311995
+ }
311996
+ if (typeof error48.code !== "number") {
311997
+ return "UNKNOWN";
311998
+ }
311999
+ return grpc12.status[error48.code] ?? "UNKNOWN";
312000
+ }
311974
312001
  function createExecuteActionHandler(deps) {
311975
312002
  const {
311976
312003
  policy,
@@ -311987,12 +312014,28 @@ function createExecuteActionHandler(deps) {
311987
312014
  const startTime = Date.now();
311988
312015
  const { action: rawAction, cex: cex3, symbol: symbol2 } = call.request;
311989
312016
  const action = resolveAction(rawAction);
312017
+ const actionName = getActionName(action);
312018
+ const operationalCex = cex3?.trim().toLowerCase() || "unknown";
312019
+ const traceId = extractTraceId(call.metadata);
312020
+ const traceFields = traceId === undefined ? {} : { trace_id: traceId };
311990
312021
  let actionCompleted = false;
311991
312022
  const wrappedCallback = (error48, value) => {
311992
312023
  if (!actionCompleted) {
311993
312024
  actionCompleted = true;
311994
312025
  const latency = Date.now() - startTime;
311995
- const actionName = getActionName(action);
312026
+ const terminalFields = {
312027
+ action: actionName,
312028
+ cex: operationalCex,
312029
+ latency_ms: latency,
312030
+ outcome: error48 ? "error" : "success",
312031
+ grpc_status: grpcStatusName(error48),
312032
+ ...traceFields
312033
+ };
312034
+ if (error48) {
312035
+ log.withMetadata(terminalFields).error("ExecuteAction failed");
312036
+ } else {
312037
+ log.withMetadata(terminalFields).info("ExecuteAction completed");
312038
+ }
311996
312039
  otelMetrics?.recordHistogram("execute_action_duration_ms", latency, {
311997
312040
  action: actionName,
311998
312041
  cex: cex3 || "unknown"
@@ -312013,9 +312056,13 @@ function createExecuteActionHandler(deps) {
312013
312056
  callback(error48, value);
312014
312057
  };
312015
312058
  try {
312016
- log.info(`Request - ExecuteAction:`, { action, cex: cex3, symbol: symbol2 });
312059
+ log.withMetadata({
312060
+ action: actionName,
312061
+ cex: operationalCex,
312062
+ ...traceFields
312063
+ }).info("ExecuteAction started");
312017
312064
  otelMetrics?.recordCounter("execute_action_requests_total", 1, {
312018
- action: getActionName(action),
312065
+ action: actionName,
312019
312066
  cex: cex3 || "unknown"
312020
312067
  });
312021
312068
  if (!authenticateRequest(call, whitelistIps)) {
@@ -312253,6 +312300,9 @@ async function writeSubscribeError(call, isClosed, frame) {
312253
312300
  call.end();
312254
312301
  }
312255
312302
  }
312303
+ function grpcStatusName2(status14) {
312304
+ return typeof status14 === "number" ? grpc13.status[status14] ?? "UNKNOWN" : "UNKNOWN";
312305
+ }
312256
312306
  function getBinanceEventMarketId(event) {
312257
312307
  const value = event.s;
312258
312308
  return typeof value === "string" ? value : null;
@@ -312385,6 +312435,24 @@ function createSubscribeHandler(deps) {
312385
312435
  });
312386
312436
  return async (call) => {
312387
312437
  const subscribeStartTime = Date.now();
312438
+ const request = call.request;
312439
+ const { cex: cex3, symbol: symbol2, type: type2 } = request;
312440
+ const metadata = call.metadata;
312441
+ const traceId = extractTraceId(metadata);
312442
+ const traceFields = traceId === undefined ? {} : { trace_id: traceId };
312443
+ const operationalCex = cex3?.trim().toLowerCase() || "unknown";
312444
+ const operationalSymbol = symbol2?.trim() || "unknown";
312445
+ const subscriptionType2 = resolveSubscriptionType(type2);
312446
+ const subscriptionTypeName = getSubscriptionTypeName(subscriptionType2);
312447
+ const operationalFields = {
312448
+ cex: operationalCex,
312449
+ symbol: operationalSymbol,
312450
+ subscription_type: subscriptionTypeName,
312451
+ ...traceFields
312452
+ };
312453
+ let terminalLogged = false;
312454
+ let terminalOutcome = "completed";
312455
+ let terminalGrpcStatus = "OK";
312388
312456
  let streamClosed = false;
312389
312457
  let ownedBroker = null;
312390
312458
  let ownedBrokerClosePromise;
@@ -312407,12 +312475,41 @@ function createSubscribeHandler(deps) {
312407
312475
  const closeOwnedBrokerOnCallEnd = () => {
312408
312476
  closeOwnedBroker();
312409
312477
  };
312410
- call.once("cancelled", markStreamClosed);
312478
+ const logTerminalOutcome = (outcome) => {
312479
+ if (terminalLogged) {
312480
+ return;
312481
+ }
312482
+ terminalLogged = true;
312483
+ const fields = {
312484
+ ...operationalFields,
312485
+ duration_ms: Date.now() - subscribeStartTime,
312486
+ outcome,
312487
+ grpc_status: outcome === "cancelled" ? "CANCELLED" : terminalGrpcStatus
312488
+ };
312489
+ if (outcome === "error") {
312490
+ log.withMetadata(fields).error("Subscribe failed");
312491
+ } else if (outcome === "cancelled") {
312492
+ log.withMetadata(fields).info("Subscribe cancelled");
312493
+ } else {
312494
+ log.withMetadata(fields).info("Subscribe ended");
312495
+ }
312496
+ };
312497
+ const writeTerminalError = async (frame, status14 = grpc13.status.UNKNOWN) => {
312498
+ terminalOutcome = "error";
312499
+ terminalGrpcStatus = grpcStatusName2(status14);
312500
+ await writeSubscribeError(call, isStreamClosed, frame);
312501
+ };
312502
+ log.withMetadata(operationalFields).info("Subscribe started");
312503
+ call.once("cancelled", () => {
312504
+ terminalGrpcStatus = "CANCELLED";
312505
+ markStreamClosed();
312506
+ logTerminalOutcome("cancelled");
312507
+ });
312411
312508
  call.once("cancelled", closeOwnedBrokerOnCallEnd);
312412
312509
  call.once("error", closeOwnedBrokerOnCallEnd);
312413
312510
  call.once("end", () => {
312414
312511
  markStreamClosed();
312415
- log.info("Subscribe stream ended");
312512
+ logTerminalOutcome(terminalOutcome);
312416
312513
  const duration3 = Date.now() - subscribeStartTime;
312417
312514
  otelMetrics?.recordHistogram("subscribe_duration_ms", duration3, {
312418
312515
  cex: call.request?.cex || "unknown",
@@ -312421,12 +312518,16 @@ function createSubscribeHandler(deps) {
312421
312518
  });
312422
312519
  call.once("error", (error48) => {
312423
312520
  markStreamClosed();
312424
- log.error("Subscribe stream error:", error48);
312521
+ terminalOutcome = "error";
312522
+ terminalGrpcStatus = grpcStatusName2(typeof error48 === "object" && error48 !== null && "code" in error48 ? error48.code : undefined);
312523
+ logTerminalOutcome(call.cancelled ? "cancelled" : "error");
312425
312524
  otelMetrics?.recordCounter("subscribe_errors_total", 1, {
312426
312525
  error_type: error48 instanceof Error ? error48.message : "unknown"
312427
312526
  });
312428
312527
  });
312429
312528
  if (!authenticateRequest(call, whitelistIps)) {
312529
+ terminalOutcome = "error";
312530
+ terminalGrpcStatus = "PERMISSION_DENIED";
312430
312531
  otelMetrics?.recordCounter("subscribe_errors_total", 1, {
312431
312532
  error_type: "permission_denied"
312432
312533
  });
@@ -312437,32 +312538,22 @@ function createSubscribeHandler(deps) {
312437
312538
  call.destroy(new Error("Access denied: Unauthorized IP"));
312438
312539
  return;
312439
312540
  }
312440
- const metadata = call.metadata;
312441
- let subscriptionType2 = SubscriptionType.ORDERBOOK;
312442
312541
  try {
312443
- const request = call.request;
312444
- const { cex: cex3, symbol: symbol2, type: type2, options } = request;
312445
- subscriptionType2 = resolveSubscriptionType(type2);
312446
- log.info(`Request - Subscribe:`, {
312447
- cex: request.cex,
312448
- symbol: request.symbol,
312449
- type: subscriptionType2
312450
- });
312451
- const subscriptionTypeName = getSubscriptionTypeName(subscriptionType2);
312542
+ const { options } = request;
312452
312543
  otelMetrics?.recordCounter("subscribe_requests_total", 1, {
312453
312544
  cex: cex3 || "unknown",
312454
312545
  symbol: symbol2 || "unknown",
312455
312546
  type: subscriptionTypeName
312456
312547
  });
312457
312548
  if (!cex3 || !symbol2) {
312458
- await writeSubscribeError(call, isStreamClosed, {
312549
+ await writeTerminalError({
312459
312550
  data: JSON.stringify({
312460
312551
  error: "cex, symbol, and type are required"
312461
312552
  }),
312462
312553
  timestamp: Date.now(),
312463
312554
  symbol: symbol2 || "",
312464
312555
  type: subscriptionType2
312465
- });
312556
+ }, grpc13.status.INVALID_ARGUMENT);
312466
312557
  return;
312467
312558
  }
312468
312559
  if (isPublicMarketDataSubscription(subscriptionType2)) {
@@ -312491,7 +312582,7 @@ function createSubscribeHandler(deps) {
312491
312582
  } catch (error48) {
312492
312583
  const message = getErrorMessage(error48);
312493
312584
  if (!isStreamClosed()) {
312494
- await writeSubscribeError(call, isStreamClosed, {
312585
+ await writeTerminalError({
312495
312586
  data: JSON.stringify({ error: message }),
312496
312587
  timestamp: Date.now(),
312497
312588
  symbol: symbol2,
@@ -312512,14 +312603,14 @@ function createSubscribeHandler(deps) {
312512
312603
  const selectedBroker = selectedBrokerAccount?.exchange ?? createBroker(normalizedCex, metadata);
312513
312604
  const broker = selectedBroker ?? createPublicBroker(normalizedCex);
312514
312605
  if (!broker) {
312515
- await writeSubscribeError(call, isStreamClosed, {
312606
+ await writeTerminalError({
312516
312607
  data: JSON.stringify({
312517
312608
  error: "Exchange not registered and no API metadata found"
312518
312609
  }),
312519
312610
  timestamp: Date.now(),
312520
312611
  symbol: symbol2,
312521
312612
  type: subscriptionType2
312522
- });
312613
+ }, grpc13.status.NOT_FOUND);
312523
312614
  return;
312524
312615
  }
312525
312616
  if (!selectedBrokerAccount) {
@@ -312547,28 +312638,28 @@ function createSubscribeHandler(deps) {
312547
312638
  if (isBinanceSpotAccountSubscription(normalizedCex, subscriptionType2, options?.marketType)) {
312548
312639
  const accountBroker = selectedBrokerAccount?.exchange ?? selectedBroker;
312549
312640
  if (!accountBroker) {
312550
- await writeSubscribeError(call, isStreamClosed, {
312641
+ await writeTerminalError({
312551
312642
  data: JSON.stringify({
312552
312643
  error: "Binance account subscriptions require API credentials"
312553
312644
  }),
312554
312645
  timestamp: Date.now(),
312555
312646
  symbol: resolvedSymbol,
312556
312647
  type: subscriptionType2
312557
- });
312648
+ }, grpc13.status.FAILED_PRECONDITION);
312558
312649
  return;
312559
312650
  }
312560
312651
  const marketId = subscriptionType2 === SubscriptionType.ORDERS ? await getBinanceMarketId(accountBroker, resolvedSymbol) : undefined;
312561
312652
  let userDataSource;
312562
312653
  if (selectedBrokerAccount) {
312563
312654
  if (!userDataStreamSupervisor) {
312564
- await writeSubscribeError(call, isStreamClosed, {
312655
+ await writeTerminalError({
312565
312656
  data: JSON.stringify({
312566
312657
  error: "Configured account user-data supervisor is unavailable"
312567
312658
  }),
312568
312659
  timestamp: Date.now(),
312569
312660
  symbol: resolvedSymbol,
312570
312661
  type: subscriptionType2
312571
- });
312662
+ }, grpc13.status.FAILED_PRECONDITION);
312572
312663
  return;
312573
312664
  }
312574
312665
  userDataSource = userDataStreamSupervisor.subscribe({
@@ -312591,7 +312682,7 @@ function createSubscribeHandler(deps) {
312591
312682
  } catch (error48) {
312592
312683
  const message = getErrorMessage(error48);
312593
312684
  log.error(`Error fetching balance for ${cex3}:`, error48);
312594
- await writeSubscribeError(call, isStreamClosed, {
312685
+ await writeTerminalError({
312595
312686
  data: JSON.stringify({
312596
312687
  error: `Failed to fetch balance: ${message}`
312597
312688
  }),
@@ -312610,7 +312701,7 @@ function createSubscribeHandler(deps) {
312610
312701
  } catch (error48) {
312611
312702
  log.error(`Error fetching orders for ${resolvedSymbol} on ${cex3}:`, error48);
312612
312703
  const message = getErrorMessage(error48);
312613
- await writeSubscribeError(call, isStreamClosed, {
312704
+ await writeTerminalError({
312614
312705
  data: JSON.stringify({
312615
312706
  error: `Failed to fetch orders: ${message}`
312616
312707
  }),
@@ -312621,26 +312712,27 @@ function createSubscribeHandler(deps) {
312621
312712
  }
312622
312713
  break;
312623
312714
  default:
312624
- await writeSubscribeError(call, isStreamClosed, {
312715
+ await writeTerminalError({
312625
312716
  data: JSON.stringify({ error: "Invalid subscription type" }),
312626
312717
  timestamp: Date.now(),
312627
312718
  symbol: symbol2,
312628
312719
  type: subscriptionType2
312629
- });
312720
+ }, grpc13.status.INVALID_ARGUMENT);
312630
312721
  }
312631
312722
  } catch (error48) {
312632
312723
  log.error("Error in Subscribe stream:", error48);
312633
312724
  const message = getErrorMessage(error48);
312634
- await writeSubscribeError(call, isStreamClosed, {
312725
+ await writeTerminalError({
312635
312726
  data: JSON.stringify({ error: `Internal server error: ${message}` }),
312636
312727
  timestamp: Date.now(),
312637
312728
  symbol: "",
312638
312729
  type: subscriptionType2
312639
- });
312730
+ }, grpc13.status.INTERNAL);
312640
312731
  } finally {
312641
312732
  call.off("cancelled", closeOwnedBrokerOnCallEnd);
312642
312733
  call.off("error", closeOwnedBrokerOnCallEnd);
312643
312734
  await closeOwnedBroker();
312735
+ logTerminalOutcome(call.cancelled ? "cancelled" : terminalOutcome);
312644
312736
  }
312645
312737
  };
312646
312738
  }
@@ -313252,4 +313344,4 @@ export {
313252
313344
  CEXBroker as default
313253
313345
  };
313254
313346
 
313255
- //# debugId=D97F25782E1185C764756E2164756E21
313347
+ //# debugId=B0B080620F355A6764756E2164756E21