@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.
- package/dist/commands/cex-canonical-orderbook-export.js +50 -16
- package/dist/commands/cex-canonical-orderbook-export.js.map +4 -4
- package/dist/commands/cli.js +124 -32
- package/dist/commands/market-data-vendor-backfill.js +74 -18
- package/dist/commands/market-data-vendor-backfill.js.map +7 -7
- package/dist/helpers/market-data-vendor-backfill/cryptohftdata.d.ts +1 -0
- package/dist/helpers/market-data-vendor-backfill/manifests.d.ts +31 -4
- package/dist/helpers/trace-context.d.ts +8 -0
- package/dist/index.js +125 -33
- package/dist/index.js.map +6 -5
- package/dist/market-data-preparation/fixtures/conformance-v2.json +7 -7
- package/dist/market-data-preparation/policies/capability-policy.json +12 -1
- package/dist/market-data-preparation/policies/resource-policy-v1.json +16 -0
- package/dist/market-data-preparation/policies/resource-policy.json +3 -3
- package/dist/market-data-preparation.js +45 -13
- package/dist/market-data-preparation.js.map +6 -6
- package/dist/market-data-vendor-backfill/policies/capability-policy-v2.json +12 -1
- package/dist/market-data-vendor-backfill/policies/resource-policy-v2.json +16 -0
- package/dist/market-data-vendor-backfill.d.ts +2 -2
- package/dist/market-data-vendor-backfill.js +74 -18
- package/dist/market-data-vendor-backfill.js.map +7 -7
- package/package.json +1 -1
|
@@ -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
|
|
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
|
|
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
|
|
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.
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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=
|
|
313347
|
+
//# debugId=B0B080620F355A6764756E2164756E21
|