@usherlabs/cex-broker 0.2.19 → 0.2.21
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/cli.js +467 -32
- package/dist/handlers/execute-action/context.d.ts +2 -0
- package/dist/handlers/execute-action/handler.d.ts +2 -0
- package/dist/helpers/broker-execution-archive/capture.d.ts +8 -0
- package/dist/helpers/broker-execution-archive/index.d.ts +3 -3
- package/dist/helpers/broker-execution-archive/rows.d.ts +55 -1
- package/dist/helpers/broker-execution-archive/types.d.ts +5 -1
- package/dist/helpers/broker-execution-archive/writer.d.ts +2 -0
- package/dist/helpers/fill-archive-poller.d.ts +42 -0
- package/dist/helpers/order-activity-tracker.d.ts +22 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +474 -37
- package/dist/index.js.map +17 -15
- package/dist/server.d.ts +2 -1
- package/package.json +1 -1
|
@@ -5,6 +5,7 @@ import type { z } from "zod";
|
|
|
5
5
|
import type { BrokerAccount, BrokerPoolEntry } from "../../helpers";
|
|
6
6
|
import type { BrokerExecutionArchiver } from "../../helpers/broker-execution-archive";
|
|
7
7
|
import type { Action as ActionType } from "../../helpers/constants";
|
|
8
|
+
import type { OrderActivityTracker } from "../../helpers/order-activity-tracker";
|
|
8
9
|
import type { OtelMetrics } from "../../helpers/otel";
|
|
9
10
|
import type { PolicyConfig } from "../../types";
|
|
10
11
|
import type { ActionRequest, ActionResponse } from "../types";
|
|
@@ -29,6 +30,7 @@ export type ExecuteActionContext = {
|
|
|
29
30
|
verityProverUrl: string;
|
|
30
31
|
otelMetrics?: OtelMetrics;
|
|
31
32
|
brokerArchiver?: BrokerExecutionArchiver;
|
|
33
|
+
orderActivityTracker?: OrderActivityTracker;
|
|
32
34
|
};
|
|
33
35
|
export declare function requireSymbol(ctx: ExecuteActionContext, message?: string): ctx is ExecuteActionContext & {
|
|
34
36
|
symbol: string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as grpc from "@grpc/grpc-js";
|
|
2
2
|
import { type BrokerPoolEntry } from "../../helpers/broker";
|
|
3
3
|
import type { BrokerExecutionArchiver } from "../../helpers/broker-execution-archive";
|
|
4
|
+
import type { OrderActivityTracker } from "../../helpers/order-activity-tracker";
|
|
4
5
|
import type { OtelMetrics } from "../../helpers/otel";
|
|
5
6
|
import type { PolicyConfig } from "../../types";
|
|
6
7
|
import type { ActionRequest, ActionResponse } from "../types";
|
|
@@ -12,5 +13,6 @@ export type ExecuteActionDeps = {
|
|
|
12
13
|
verityProverUrl: string;
|
|
13
14
|
otelMetrics?: OtelMetrics;
|
|
14
15
|
brokerArchiver?: BrokerExecutionArchiver;
|
|
16
|
+
orderActivityTracker?: OrderActivityTracker;
|
|
15
17
|
};
|
|
16
18
|
export declare function createExecuteActionHandler(deps: ExecuteActionDeps): (call: grpc.ServerUnaryCall<ActionRequest, ActionResponse>, callback: grpc.sendUnaryData<ActionResponse>) => Promise<void>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Exchange } from "@usherlabs/ccxt";
|
|
2
2
|
import { type OrderTelemetryAction, type OrderTelemetryContext } from "../order-telemetry";
|
|
3
|
+
import { type TransferArchiveFields } from "./rows";
|
|
3
4
|
import type { SubscribeArchiveType } from "./types";
|
|
4
5
|
import type { BrokerExecutionArchiver } from "./writer";
|
|
5
6
|
export declare function archiveOrderExecutionInBackground(archiver: BrokerExecutionArchiver | undefined, context: OrderTelemetryContext, order: unknown, error?: unknown, options?: {
|
|
@@ -13,6 +14,13 @@ export declare function archiveSubscribeStreamInBackground(archiver: BrokerExecu
|
|
|
13
14
|
streamPayload: unknown;
|
|
14
15
|
secretLiterals?: readonly string[];
|
|
15
16
|
}): void;
|
|
17
|
+
export declare function archiveTransferEventInBackground(archiver: BrokerExecutionArchiver | undefined, input: {
|
|
18
|
+
exchange: string;
|
|
19
|
+
accountSelector?: string;
|
|
20
|
+
assetSymbol?: string;
|
|
21
|
+
brokerObservedTimestamp?: string;
|
|
22
|
+
transfer: TransferArchiveFields;
|
|
23
|
+
}): void;
|
|
16
24
|
export declare function captureMarketMetadataSnapshot(archiver: BrokerExecutionArchiver | undefined, broker: Exchange, input: {
|
|
17
25
|
exchange: string;
|
|
18
26
|
accountSelector?: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { archiveOrderExecutionInBackground, archiveSubscribeStreamInBackground, captureMarketMetadataSnapshot, captureMarketMetadataSnapshotInBackground, } from "./capture";
|
|
1
|
+
export { archiveOrderExecutionInBackground, archiveSubscribeStreamInBackground, archiveTransferEventInBackground, captureMarketMetadataSnapshot, captureMarketMetadataSnapshotInBackground, } from "./capture";
|
|
2
2
|
export { hashMarketMetadata, redactErrorForArchive, redactSecretLiterals, redactStreamPayload, } from "./redact";
|
|
3
|
-
export { buildCommonArchiveTags, buildMarketMetadataSnapshotRow, buildOrderEventArchiveRow, buildSubscribeStreamArchiveRow, } from "./rows";
|
|
4
|
-
export { BROKER_WRITE_SOURCE, type BrokerArchiveCommonTags, type BrokerArchiveRow, type BrokerArchiveTable, type OrderArchiveAction, type SubscribeArchiveType, } from "./types";
|
|
3
|
+
export { buildCommonArchiveTags, buildFillEventArchiveRow, buildMarketMetadataSnapshotRow, buildOrderEventArchiveRow, buildSubscribeStreamArchiveRow, buildTransferEventArchiveRow, type FillArchiveFields, normalizeCcxtTradeForArchive, normalizeCcxtTransactionForArchive, type NormalizedCcxtTransfer, type TransferArchiveFields, } from "./rows";
|
|
4
|
+
export { ARCHIVE_SCHEMA_VERSION, BROKER_WRITE_SOURCE, type BrokerArchiveCommonTags, type BrokerArchiveRow, type BrokerArchiveTable, type OrderArchiveAction, type SubscribeArchiveType, type TransferEventKind, type TransferLifecycleAction, } from "./types";
|
|
5
5
|
export { BrokerExecutionArchiver, type BrokerExecutionArchiverOptions, createBrokerExecutionArchiverFromEnv, isArchiveOtelLogsEnabled, resolveArchiveForwarderUrlFromEnv, } from "./writer";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { OrderExecutionTelemetry } from "../order-telemetry";
|
|
2
|
-
import { type BrokerArchiveCommonTags, type BrokerArchiveRow, type OrderArchiveAction, type SubscribeArchiveType } from "./types";
|
|
2
|
+
import { type BrokerArchiveCommonTags, type BrokerArchiveRow, type OrderArchiveAction, type SubscribeArchiveType, type TransferEventKind, type TransferLifecycleAction } from "./types";
|
|
3
3
|
export declare function buildCommonArchiveTags(input: {
|
|
4
4
|
deploymentId: string;
|
|
5
5
|
accountSelector?: string;
|
|
@@ -21,6 +21,60 @@ export declare function buildSubscribeStreamArchiveRow(input: {
|
|
|
21
21
|
streamPayload: unknown;
|
|
22
22
|
secretLiterals?: readonly string[];
|
|
23
23
|
}): BrokerArchiveRow;
|
|
24
|
+
export type TransferArchiveFields = {
|
|
25
|
+
eventKind: TransferEventKind;
|
|
26
|
+
lifecycleAction: TransferLifecycleAction;
|
|
27
|
+
status?: string;
|
|
28
|
+
amount?: string;
|
|
29
|
+
address?: string;
|
|
30
|
+
network?: string;
|
|
31
|
+
externalId?: string;
|
|
32
|
+
txid?: string;
|
|
33
|
+
resultIndex?: number;
|
|
34
|
+
feeAmount?: string;
|
|
35
|
+
feeCurrency?: string;
|
|
36
|
+
exchangeTimestamp?: string;
|
|
37
|
+
errorSummary?: string;
|
|
38
|
+
payload: unknown;
|
|
39
|
+
};
|
|
40
|
+
export declare function buildTransferEventArchiveRow(input: {
|
|
41
|
+
tags: BrokerArchiveCommonTags;
|
|
42
|
+
transfer: TransferArchiveFields;
|
|
43
|
+
}): BrokerArchiveRow;
|
|
44
|
+
export type NormalizedCcxtTransfer = {
|
|
45
|
+
externalId?: string;
|
|
46
|
+
txid?: string;
|
|
47
|
+
address?: string;
|
|
48
|
+
network?: string;
|
|
49
|
+
amount?: string;
|
|
50
|
+
assetSymbol?: string;
|
|
51
|
+
status?: string;
|
|
52
|
+
feeAmount?: string;
|
|
53
|
+
feeCurrency?: string;
|
|
54
|
+
exchangeTimestamp?: string;
|
|
55
|
+
};
|
|
56
|
+
export declare function normalizeCcxtTransactionForArchive(transaction: unknown): NormalizedCcxtTransfer;
|
|
57
|
+
export type FillArchiveFields = {
|
|
58
|
+
orderId?: string;
|
|
59
|
+
clientOrderId?: string;
|
|
60
|
+
fillId?: string;
|
|
61
|
+
fillIndex?: number;
|
|
62
|
+
side?: string;
|
|
63
|
+
orderType?: string;
|
|
64
|
+
price?: string;
|
|
65
|
+
baseQuantity?: string;
|
|
66
|
+
quoteQuantity?: string;
|
|
67
|
+
feeAmount?: string;
|
|
68
|
+
feeCurrency?: string;
|
|
69
|
+
feeRate?: string;
|
|
70
|
+
exchangeTimestamp?: string;
|
|
71
|
+
payload: unknown;
|
|
72
|
+
};
|
|
73
|
+
export declare function buildFillEventArchiveRow(input: {
|
|
74
|
+
tags: BrokerArchiveCommonTags;
|
|
75
|
+
fill: FillArchiveFields;
|
|
76
|
+
}): BrokerArchiveRow;
|
|
77
|
+
export declare function normalizeCcxtTradeForArchive(trade: unknown): FillArchiveFields;
|
|
24
78
|
export declare function buildMarketMetadataSnapshotRow(input: {
|
|
25
79
|
tags: BrokerArchiveCommonTags;
|
|
26
80
|
clientOrderId?: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export declare const BROKER_WRITE_SOURCE: "broker_write";
|
|
2
|
-
export
|
|
2
|
+
export declare const ARCHIVE_SCHEMA_VERSION: "1";
|
|
3
|
+
export type BrokerArchiveTable = "broker_execution.order_events" | "broker_execution.market_metadata_snapshots" | "broker_execution.transfer_events" | "broker_execution.fill_events" | "market_data.orderbook_snapshots" | "market_data.candles" | "market_data.cex_stream_events" | "market_data.cex_ticker_events" | "market_data.cex_trades";
|
|
3
4
|
export type BrokerArchiveRow = {
|
|
4
5
|
table: BrokerArchiveTable;
|
|
5
6
|
row: Record<string, unknown>;
|
|
@@ -14,3 +15,6 @@ export type BrokerArchiveCommonTags = {
|
|
|
14
15
|
};
|
|
15
16
|
export type OrderArchiveAction = "CreateOrder" | "CancelOrder" | "GetOrderDetails";
|
|
16
17
|
export type SubscribeArchiveType = "ORDERS" | "BALANCE";
|
|
18
|
+
export type TransferEventKind = "withdrawal" | "deposit" | "internal_transfer";
|
|
19
|
+
export type TransferLifecycleAction = "submit_withdrawal" | "observe_deposit" | "submit_internal_transfer";
|
|
20
|
+
export declare const FILL_EVENT_KIND: "trade_history_fill";
|
|
@@ -49,7 +49,9 @@ export declare class BrokerExecutionArchiver {
|
|
|
49
49
|
getQueueDepth(): number;
|
|
50
50
|
private enforceQueueBound;
|
|
51
51
|
private flushBatch;
|
|
52
|
+
private recordFlushHealth;
|
|
52
53
|
private recordArchiveMetric;
|
|
54
|
+
private recordArchiveGauge;
|
|
53
55
|
private emitOtelLog;
|
|
54
56
|
private postToForwarder;
|
|
55
57
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { BrokerPoolEntry } from "./broker";
|
|
2
|
+
import { type BrokerExecutionArchiver } from "./broker-execution-archive";
|
|
3
|
+
import type { OrderActivityTracker } from "./order-activity-tracker";
|
|
4
|
+
import type { OtelMetrics } from "./otel";
|
|
5
|
+
export type FillArchivePollerConfig = {
|
|
6
|
+
pollIntervalMs: number;
|
|
7
|
+
lookbackMs: number;
|
|
8
|
+
tradesLimit: number;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Advances a since-cursor past the newest trade in a batch. The next poll asks for
|
|
12
|
+
* trades strictly after the last one seen (+1ms) so the same trade is not refetched
|
|
13
|
+
* every tick, while still tolerating out-of-order timestamps within a batch.
|
|
14
|
+
*/
|
|
15
|
+
export declare function nextFillCursor(trades: unknown[], currentSince: number): number;
|
|
16
|
+
/**
|
|
17
|
+
* Broker-internal periodic capture of per-fill facts. For each (account, symbol)
|
|
18
|
+
* that saw recent order activity it calls the venue trade-history endpoint
|
|
19
|
+
* (fetchMyTrades) with a since-cursor and archives each trade to
|
|
20
|
+
* broker_execution.fill_events. Started at bootstrap only when archiving is
|
|
21
|
+
* enabled; symbols are staggered by sequential awaits so one tick never bursts the
|
|
22
|
+
* venue rate limit. Mirrors the TravelRuleDepositReconciler lifecycle.
|
|
23
|
+
*/
|
|
24
|
+
export declare class FillArchivePoller {
|
|
25
|
+
#private;
|
|
26
|
+
private readonly params;
|
|
27
|
+
constructor(params: {
|
|
28
|
+
brokers: Record<string, BrokerPoolEntry>;
|
|
29
|
+
archiver: BrokerExecutionArchiver;
|
|
30
|
+
tracker: OrderActivityTracker;
|
|
31
|
+
metrics?: OtelMetrics;
|
|
32
|
+
config?: Partial<FillArchivePollerConfig>;
|
|
33
|
+
});
|
|
34
|
+
start(): void;
|
|
35
|
+
stop(): void;
|
|
36
|
+
/**
|
|
37
|
+
* Runs one poll pass over every tracked (account, symbol), sequentially so the
|
|
38
|
+
* per-symbol awaits stagger venue calls. Exposed for tests (the timer loop calls
|
|
39
|
+
* it every tick).
|
|
40
|
+
*/
|
|
41
|
+
pollTrackedOnce(): Promise<void>;
|
|
42
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type OrderActivityEntry = {
|
|
2
|
+
exchangeId: string;
|
|
3
|
+
accountLabel: string;
|
|
4
|
+
symbol: string;
|
|
5
|
+
lastActivityAt: number;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Records the (exchange, account, symbol) tuples that saw order activity through
|
|
9
|
+
* the execute-action path, so the fill poller scans only those markets instead of
|
|
10
|
+
* the whole exchange. Process-lifetime, in-memory only (no persistence needed: on
|
|
11
|
+
* restart the poller re-derives the set from fresh order activity and read-time
|
|
12
|
+
* dedup absorbs the lookback re-scan).
|
|
13
|
+
*/
|
|
14
|
+
export declare class OrderActivityTracker {
|
|
15
|
+
#private;
|
|
16
|
+
constructor(options?: {
|
|
17
|
+
maxAgeMs?: number;
|
|
18
|
+
});
|
|
19
|
+
record(exchangeId: string, accountLabel: string, symbol: string, now?: number): void;
|
|
20
|
+
/** Active entries (seen within maxAge). Prunes stale entries as a side effect. */
|
|
21
|
+
list(now?: number): OrderActivityEntry[];
|
|
22
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ export default class CEXBroker {
|
|
|
13
13
|
private otelLogs?;
|
|
14
14
|
private brokerArchiver?;
|
|
15
15
|
private depositReconciler?;
|
|
16
|
+
private readonly orderActivityTracker;
|
|
17
|
+
private fillArchivePoller?;
|
|
16
18
|
/**
|
|
17
19
|
* Loads environment variables prefixed with CEX_BROKER_
|
|
18
20
|
* Expected format:
|