@polyester/sdk 0.9.1 → 0.10.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/CHANGELOG.md +26 -0
- package/dist/catalogs/readers.d.ts.map +1 -1
- package/dist/catalogs/readers.js +22 -0
- package/dist/catalogs/readers.js.map +1 -1
- package/dist/core-client.d.ts.map +1 -1
- package/dist/core-client.js +49 -15
- package/dist/core-client.js.map +1 -1
- package/dist/environment.d.ts.map +1 -1
- package/dist/environment.js +3 -2
- package/dist/environment.js.map +1 -1
- package/dist/realtime/client.d.ts.map +1 -1
- package/dist/realtime/client.js +13 -5
- package/dist/realtime/client.js.map +1 -1
- package/dist/realtime/ready-gated-subscription.js +68 -0
- package/dist/realtime/ready-gated-subscription.js.map +1 -0
- package/dist/realtime/snapshot-then-stream.js +19 -10
- package/dist/realtime/snapshot-then-stream.js.map +1 -1
- package/dist/server-client.d.ts +3 -1
- package/dist/server-client.d.ts.map +1 -1
- package/dist/server-client.js +9 -4
- package/dist/server-client.js.map +1 -1
- package/dist/services/auth/session.d.ts.map +1 -1
- package/dist/services/auth/session.js +4 -1
- package/dist/services/auth/session.js.map +1 -1
- package/dist/services/auth/token-storage.js +2 -2
- package/dist/services/auth/token-storage.js.map +1 -1
- package/dist/services/balances/balances.js +5 -8
- package/dist/services/balances/balances.js.map +1 -1
- package/dist/services/candles/candles.js +9 -12
- package/dist/services/candles/candles.js.map +1 -1
- package/dist/services/heatmap/heatmap.js +5 -8
- package/dist/services/heatmap/heatmap.js.map +1 -1
- package/dist/services/lifecycle/lifecycle.schemas.d.ts +42 -42
- package/dist/services/lifecycle/lifecycle.schemas.js +1 -1
- package/dist/services/market-data/market-data.d.ts.map +1 -1
- package/dist/services/market-data/market-data.js +5 -8
- package/dist/services/market-data/market-data.js.map +1 -1
- package/dist/services/market-data/market-data.schemas.d.ts.map +1 -1
- package/dist/services/market-data/market-data.schemas.js +3 -2
- package/dist/services/market-data/market-data.schemas.js.map +1 -1
- package/dist/services/market-overview/market-overview.d.ts.map +1 -1
- package/dist/services/market-overview/market-overview.js +7 -13
- package/dist/services/market-overview/market-overview.js.map +1 -1
- package/dist/services/orderbook/orderbook.d.ts.map +1 -1
- package/dist/services/orderbook/orderbook.js +18 -11
- package/dist/services/orderbook/orderbook.js.map +1 -1
- package/dist/services/orders/orders-batch.schemas.d.ts +6 -22
- package/dist/services/orders/orders-batch.schemas.d.ts.map +1 -1
- package/dist/services/orders/orders-batch.schemas.js +23 -20
- package/dist/services/orders/orders-batch.schemas.js.map +1 -1
- package/dist/services/orders/orders-identifiers.schemas.js +6 -1
- package/dist/services/orders/orders-identifiers.schemas.js.map +1 -1
- package/dist/services/orders/orders-input.schemas.d.ts +11 -43
- package/dist/services/orders/orders-input.schemas.d.ts.map +1 -1
- package/dist/services/orders/orders-input.schemas.js +10 -11
- package/dist/services/orders/orders-input.schemas.js.map +1 -1
- package/dist/services/orders/orders-modify.schemas.d.ts +1 -25
- package/dist/services/orders/orders-modify.schemas.d.ts.map +1 -1
- package/dist/services/orders/orders-modify.schemas.js +2 -4
- package/dist/services/orders/orders-modify.schemas.js.map +1 -1
- package/dist/services/orders/orders-output.schemas.d.ts +165 -27
- package/dist/services/orders/orders-output.schemas.d.ts.map +1 -1
- package/dist/services/orders/orders-output.schemas.js +1 -1
- package/dist/services/orders/orders-output.schemas.js.map +1 -1
- package/dist/services/orders/orders-risk.schemas.d.ts +1 -20
- package/dist/services/orders/orders-risk.schemas.d.ts.map +1 -1
- package/dist/services/orders/orders-risk.schemas.js +52 -15
- package/dist/services/orders/orders-risk.schemas.js.map +1 -1
- package/dist/services/orders/orders.codecs.js +12 -1
- package/dist/services/orders/orders.codecs.js.map +1 -1
- package/dist/services/orders/orders.d.ts.map +1 -1
- package/dist/services/orders/orders.js +6 -9
- package/dist/services/orders/orders.js.map +1 -1
- package/dist/services/subaccounts/subaccounts.schemas.d.ts +3 -3
- package/dist/services/trades/trades.js +5 -8
- package/dist/services/trades/trades.js.map +1 -1
- package/dist/services/trailing-oneof-inputs.js +3 -3
- package/dist/services/trailing-oneof-inputs.js.map +1 -1
- package/dist/services/transfers/index.d.ts +2 -2
- package/dist/services/transfers/transfers.d.ts +1 -2
- package/dist/services/transfers/transfers.d.ts.map +1 -1
- package/dist/services/transfers/transfers.js +8 -13
- package/dist/services/transfers/transfers.js.map +1 -1
- package/dist/services/transfers/transfers.schemas.d.ts +5 -5
- package/dist/services/transfers/transfers.schemas.d.ts.map +1 -1
- package/dist/services/transfers/transfers.schemas.js +31 -33
- package/dist/services/transfers/transfers.schemas.js.map +1 -1
- package/dist/services/triggers/trigger-input.schemas.d.ts +21 -8
- package/dist/services/triggers/trigger-input.schemas.d.ts.map +1 -1
- package/dist/services/triggers/trigger-input.schemas.js +20 -43
- package/dist/services/triggers/trigger-input.schemas.js.map +1 -1
- package/dist/services/triggers/triggers-output.schemas.d.ts +13 -13
- package/dist/services/triggers/triggers-output.schemas.js +5 -5
- package/dist/services/triggers/triggers-output.schemas.js.map +1 -1
- package/dist/services/triggers/triggers.d.ts.map +1 -1
- package/dist/services/triggers/triggers.js +10 -23
- package/dist/services/triggers/triggers.js.map +1 -1
- package/dist/services/zipper/zipper.d.ts.map +1 -1
- package/dist/services/zipper/zipper.js +15 -18
- package/dist/services/zipper/zipper.js.map +1 -1
- package/dist/shared/connect-error-mapping.d.ts.map +1 -1
- package/dist/shared/connect-error-mapping.js +9 -2
- package/dist/shared/connect-error-mapping.js.map +1 -1
- package/dist/shared/decimal-surface.d.ts.map +1 -1
- package/dist/shared/decimal-surface.js +40 -17
- package/dist/shared/decimal-surface.js.map +1 -1
- package/dist/shared/transports.d.ts.map +1 -1
- package/dist/shared/transports.js +33 -11
- package/dist/shared/transports.js.map +1 -1
- package/dist/utils/base58-id.js +1 -2
- package/dist/utils/base58-id.js.map +1 -1
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +4 -3
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/event-emitter.d.ts.map +1 -1
- package/dist/utils/event-emitter.js +6 -3
- package/dist/utils/event-emitter.js.map +1 -1
- package/dist/utils/jwt.d.ts.map +1 -1
- package/dist/utils/jwt.js +2 -2
- package/dist/utils/jwt.js.map +1 -1
- package/dist/utils/numbers.js +20 -3
- package/dist/utils/numbers.js.map +1 -1
- package/dist/utils/timestamp.js +27 -16
- package/dist/utils/timestamp.js.map +1 -1
- package/dist/utils/u128.js +6 -18
- package/dist/utils/u128.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { parse } from "../../shared/validation.js";
|
|
2
2
|
import { toConnectCallOptions } from "../../shared/request-options.js";
|
|
3
|
-
import { publicationHandlerErrorContext } from "../../shared/subscription-errors.js";
|
|
4
|
-
import { createReadyGate } from "../../shared/decimal-surface.js";
|
|
5
3
|
import { MarketOverviewBatchSchema, MarketOverviewService as MarketOverviewService$1 } from "../../gen/marketoverview/v1/marketoverview_pb.js";
|
|
6
4
|
import { snapshotThenStream } from "../../realtime/snapshot-then-stream.js";
|
|
7
5
|
import { ListMarketOverviewInputSchema, createMarketOverviewSchema } from "./market-overview.schemas.js";
|
|
@@ -44,7 +42,6 @@ var MarketOverviewService = class {
|
|
|
44
42
|
const sparklineIntervals = input.sparklineIntervals ?? ["24h"];
|
|
45
43
|
const listMarketOverview = this.list.bind(this);
|
|
46
44
|
const schema = this.#marketOverviewSchema;
|
|
47
|
-
const gate = createReadyGate(() => this.#scales.ready(), (error) => input.onError?.(publicationHandlerErrorContext(channel, error)));
|
|
48
45
|
function emit() {
|
|
49
46
|
input.onEvent(Array.from(bySymbolId.values()));
|
|
50
47
|
}
|
|
@@ -71,19 +68,16 @@ var MarketOverviewService = class {
|
|
|
71
68
|
snapshotErrorLog: "Failed to fetch market overview",
|
|
72
69
|
fetchSnapshot,
|
|
73
70
|
readPublication: (batch) => batch.markets ?? [],
|
|
71
|
+
bufferPublicationKey: (market) => market.symbolId,
|
|
74
72
|
applySnapshot: (markets, bufferedMarkets) => {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
emit();
|
|
80
|
-
});
|
|
73
|
+
bySymbolId.clear();
|
|
74
|
+
applyMarkets(markets);
|
|
75
|
+
applyMarkets(parseMarkets(bufferedMarkets));
|
|
76
|
+
emit();
|
|
81
77
|
},
|
|
82
78
|
applyLivePublications: (markets) => {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
emit();
|
|
86
|
-
});
|
|
79
|
+
applyMarkets(parseMarkets(markets));
|
|
80
|
+
emit();
|
|
87
81
|
},
|
|
88
82
|
onOpen: input.onOpen,
|
|
89
83
|
onClose: input.onClose,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"market-overview.js","names":["#client","Proto.MarketOverviewService","#realtime","#scales","#marketOverviewSchema","Proto.MarketOverviewBatchSchema"],"sources":["../../../src/services/market-overview/market-overview.ts"],"sourcesContent":["import * as Proto from \"../../gen/marketoverview/v1/marketoverview_pb.js\";\nimport { createClient, type Client, type Transport } from \"@connectrpc/connect\";\nimport
|
|
1
|
+
{"version":3,"file":"market-overview.js","names":["#client","Proto.MarketOverviewService","#realtime","#scales","#marketOverviewSchema","Proto.MarketOverviewBatchSchema"],"sources":["../../../src/services/market-overview/market-overview.ts"],"sourcesContent":["import * as Proto from \"../../gen/marketoverview/v1/marketoverview_pb.js\";\nimport { createClient, type Client, type Transport } from \"@connectrpc/connect\";\nimport * as v from \"valibot\";\nimport { parse } from \"../../shared/validation.js\";\nimport type { PolyesterRealtime } from \"../../realtime/types.js\";\nimport { snapshotThenStream } from \"../../realtime/snapshot-then-stream.js\";\nimport type { BaseSubscribeInput } from \"../../shared/types.js\";\nimport {\n toConnectCallOptions,\n type PolyesterRequestOptions,\n} from \"../../shared/request-options.js\";\nimport type { SdkScales } from \"../../shared/decimal-surface.js\";\nimport {\n ListMarketOverviewInputSchema,\n createMarketOverviewSchema,\n type SparklineIntervalName,\n type ListMarketOverviewInput,\n type MarketOverview,\n} from \"./market-overview.schemas.js\";\n\ninterface SubscribeMarketOverviewInput extends BaseSubscribeInput<MarketOverview[]> {\n includeSparklines?: boolean;\n sparklineIntervals?: SparklineIntervalName[];\n}\n\n/**\n * Provides ticker-style per-market stats and a live merged overview stream.\n */\nexport class MarketOverviewService {\n #client: Client<typeof Proto.MarketOverviewService>;\n #realtime: PolyesterRealtime;\n #scales: SdkScales;\n #marketOverviewSchema: ReturnType<typeof createMarketOverviewSchema>;\n\n constructor(transport: Transport, realtime: PolyesterRealtime, scales: SdkScales) {\n this.#client = createClient(Proto.MarketOverviewService, transport);\n this.#realtime = realtime;\n this.#scales = scales;\n this.#marketOverviewSchema = createMarketOverviewSchema(scales);\n }\n\n /**\n * Returns market overview rows with last and index prices, 24h stats, top-of-book values, listing timestamp, and optional sparklines. Supports symbol ID filtering, sorting, pagination, and sparkline interval selection.\n */\n async list(\n input: ListMarketOverviewInput = {},\n options?: PolyesterRequestOptions,\n ): Promise<{ markets: MarketOverview[]; nextPageToken: string }> {\n const validatedInput = parse(ListMarketOverviewInputSchema, input);\n await this.#scales.ready();\n const res = await this.#client.listMarketOverview(\n validatedInput,\n toConnectCallOptions(options),\n );\n return {\n markets: parse(v.array(this.#marketOverviewSchema), res.markets),\n nextPageToken: res.nextPageToken,\n };\n }\n\n /**\n * Subscribes to public:spot:market_overview:updates:proto, fetches an initial snapshot, buffers updates until ready, and emits the merged set of latest market rows. On reconnect it refetches the snapshot before resuming updates.\n */\n subscribe(input: SubscribeMarketOverviewInput): () => void {\n const channel = \"public:spot:market_overview:updates:proto\";\n const bySymbolId = new Map<number, MarketOverview>();\n const includeSparklines = input.includeSparklines ?? true;\n const sparklineIntervals = input.sparklineIntervals ?? [\"24h\"];\n const listMarketOverview = this.list.bind(this);\n const schema = this.#marketOverviewSchema;\n function emit(): void {\n input.onEvent(Array.from(bySymbolId.values()));\n }\n\n function handleMarketUpdate(m: MarketOverview): void {\n bySymbolId.set(m.symbolId, m);\n }\n\n function applyMarkets(markets: readonly MarketOverview[]): void {\n for (const market of markets) {\n handleMarketUpdate(market);\n }\n }\n\n function parseMarkets(markets: readonly Proto.MarketOverview[]): MarketOverview[] {\n return markets.map((m) => parse(schema, m));\n }\n\n async function fetchSnapshot(): Promise<MarketOverview[]> {\n const result = await listMarketOverview({\n includeSparklines,\n sparklineIntervals,\n });\n return result.markets;\n }\n\n const stream = snapshotThenStream({\n realtime: this.#realtime,\n channel,\n schema: Proto.MarketOverviewBatchSchema,\n maxBufferedPublications: 2000,\n snapshotErrorLog: \"Failed to fetch market overview\",\n fetchSnapshot,\n readPublication: (batch) => batch.markets ?? [],\n bufferPublicationKey: (market) => market.symbolId,\n applySnapshot: (markets, bufferedMarkets) => {\n bySymbolId.clear();\n applyMarkets(markets);\n applyMarkets(parseMarkets(bufferedMarkets));\n emit();\n },\n applyLivePublications: (markets) => {\n applyMarkets(parseMarkets(markets));\n emit();\n },\n onOpen: input.onOpen,\n onClose: input.onClose,\n onError: input.onError,\n });\n\n function dispose(): void {\n stream.unsubscribe();\n }\n\n return dispose;\n }\n}\n"],"mappings":";;;;;;;;;;;AA4BA,IAAa,wBAAb,MAAmC;CAC/B;CACA;CACA;CACA;CAEA,YAAY,WAAsB,UAA6B,QAAmB;EAC9E,KAAKA,UAAU,aAAaC,yBAA6B,SAAS;EAClE,KAAKC,YAAY;EACjB,KAAKC,UAAU;EACf,KAAKC,wBAAwB,2BAA2B,MAAM;CAClE;;;;CAKA,MAAM,KACF,QAAiC,CAAC,GAClC,SAC6D;EAC7D,MAAM,iBAAiB,MAAM,+BAA+B,KAAK;EACjE,MAAM,KAAKD,QAAQ,MAAM;EACzB,MAAM,MAAM,MAAM,KAAKH,QAAQ,mBAC3B,gBACA,qBAAqB,OAAO,CAChC;EACA,OAAO;GACH,SAAS,MAAM,EAAE,MAAM,KAAKI,qBAAqB,GAAG,IAAI,OAAO;GAC/D,eAAe,IAAI;EACvB;CACJ;;;;CAKA,UAAU,OAAiD;EACvD,MAAM,UAAU;EAChB,MAAM,6BAAa,IAAI,IAA4B;EACnD,MAAM,oBAAoB,MAAM,qBAAqB;EACrD,MAAM,qBAAqB,MAAM,sBAAsB,CAAC,KAAK;EAC7D,MAAM,qBAAqB,KAAK,KAAK,KAAK,IAAI;EAC9C,MAAM,SAAS,KAAKA;EACpB,SAAS,OAAa;GAClB,MAAM,QAAQ,MAAM,KAAK,WAAW,OAAO,CAAC,CAAC;EACjD;EAEA,SAAS,mBAAmB,GAAyB;GACjD,WAAW,IAAI,EAAE,UAAU,CAAC;EAChC;EAEA,SAAS,aAAa,SAA0C;GAC5D,KAAK,MAAM,UAAU,SACjB,mBAAmB,MAAM;EAEjC;EAEA,SAAS,aAAa,SAA4D;GAC9E,OAAO,QAAQ,KAAK,MAAM,MAAM,QAAQ,CAAC,CAAC;EAC9C;EAEA,eAAe,gBAA2C;GAKtD,QAAO,MAJc,mBAAmB;IACpC;IACA;GACJ,CAAC,EAAA,CACa;EAClB;EAEA,MAAM,SAAS,mBAAmB;GAC9B,UAAU,KAAKF;GACf;GACA,QAAQG;GACR,yBAAyB;GACzB,kBAAkB;GAClB;GACA,kBAAkB,UAAU,MAAM,WAAW,CAAC;GAC9C,uBAAuB,WAAW,OAAO;GACzC,gBAAgB,SAAS,oBAAoB;IACzC,WAAW,MAAM;IACjB,aAAa,OAAO;IACpB,aAAa,aAAa,eAAe,CAAC;IAC1C,KAAK;GACT;GACA,wBAAwB,YAAY;IAChC,aAAa,aAAa,OAAO,CAAC;IAClC,KAAK;GACT;GACA,QAAQ,MAAM;GACd,SAAS,MAAM;GACf,SAAS,MAAM;EACnB,CAAC;EAED,SAAS,UAAgB;GACrB,OAAO,YAAY;EACvB;EAEA,OAAO;CACX;AACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orderbook.d.ts","names":[],"sources":["../../../src/services/orderbook/orderbook.ts"],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"orderbook.d.ts","names":[],"sources":["../../../src/services/orderbook/orderbook.ts"],"mappings":";;;;;;;;UA2BU,gCAAgC,mBAAmB;EACzD;EACA;EACA;;UAGa,gCAAgC,mBAAmB;UAEnD;EACb;EACA,YAAY;;UAGC,yCAET,yBACA,KAAK;;;;cAOA;;EAKG,YAAA,WAAW,WAAW,UAAU,mBAAmB,QAAQ;;;;EASjE,IACF,OAAO,EAAE,kBAAkB,0BAC3B,UAAU,0BACX,QAAQ;;;;EAmBX,UAAU,OAAO;;;;;;;;EAWjB,mBAAmB,OAAO,mCAAmC"}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { parse } from "../../shared/validation.js";
|
|
2
2
|
import { toConnectCallOptions } from "../../shared/request-options.js";
|
|
3
|
+
import { decimalInputToScaled } from "../../shared/decimal-surface.js";
|
|
3
4
|
import { publicationHandlerErrorContext } from "../../shared/subscription-errors.js";
|
|
4
|
-
import { createReadyGate, decimalInputToScaled } from "../../shared/decimal-surface.js";
|
|
5
5
|
import { isResourceNotFoundError } from "../../utils/errors.js";
|
|
6
6
|
import { snapshotThenStream } from "../../realtime/snapshot-then-stream.js";
|
|
7
7
|
import { GetOrderBookResponseSchema, OrderBookDeltaSchema, OrderbookService as OrderbookService$1 } from "../../gen/orderbook/v1/orderbook_pb.js";
|
|
8
8
|
import { orderbookWsChannelDepth } from "./orderbook.codecs.js";
|
|
9
9
|
import { GetOrderbookInputSchema, createOrderbookDataSchema, formatOrderbookLevel } from "./orderbook.schemas.js";
|
|
10
|
-
import { toBig } from "../../utils/u128.js";
|
|
11
10
|
import { create } from "@bufbuild/protobuf";
|
|
12
11
|
import { createClient } from "@connectrpc/connect";
|
|
13
12
|
//#region src/services/orderbook/orderbook.ts
|
|
@@ -64,7 +63,6 @@ var OrderbookService = class {
|
|
|
64
63
|
const channel = `public:spot:orderbook:deltas:depth:${channelDepth}:${symbolId}:proto`;
|
|
65
64
|
const client = this.#client;
|
|
66
65
|
const scales = this.#scales;
|
|
67
|
-
const gate = createReadyGate(() => scales.ready(), (error) => input.onError?.(publicationHandlerErrorContext(channel, error)));
|
|
68
66
|
let bidsMap = /* @__PURE__ */ new Map();
|
|
69
67
|
let asksMap = /* @__PURE__ */ new Map();
|
|
70
68
|
let currentBookSeq = 0n;
|
|
@@ -98,13 +96,14 @@ var OrderbookService = class {
|
|
|
98
96
|
const agg = /* @__PURE__ */ new Map();
|
|
99
97
|
for (const [priceTicks, qtyScaled] of map.entries()) {
|
|
100
98
|
if (qtyScaled <= 0n) continue;
|
|
101
|
-
const
|
|
99
|
+
const bucketFloor = priceTicks / bucket * bucket;
|
|
100
|
+
const bucketPrice = side === "asks" && bucketFloor !== priceTicks ? bucketFloor + bucket : bucketFloor;
|
|
102
101
|
agg.set(bucketPrice, (agg.get(bucketPrice) ?? 0n) + qtyScaled);
|
|
103
102
|
}
|
|
104
103
|
return sideToUI(agg, side, limit);
|
|
105
104
|
}
|
|
106
105
|
function emit() {
|
|
107
|
-
|
|
106
|
+
try {
|
|
108
107
|
input.onEvent({
|
|
109
108
|
symbolId,
|
|
110
109
|
depth: requestedDepth,
|
|
@@ -112,7 +111,9 @@ var OrderbookService = class {
|
|
|
112
111
|
bids: sideToUIBucketed(bidsMap, "bids", requestedDepth, bucketTicks),
|
|
113
112
|
asks: sideToUIBucketed(asksMap, "asks", requestedDepth, bucketTicks)
|
|
114
113
|
});
|
|
115
|
-
})
|
|
114
|
+
} catch (error) {
|
|
115
|
+
input.onError?.(publicationHandlerErrorContext(channel, error));
|
|
116
|
+
}
|
|
116
117
|
}
|
|
117
118
|
function setBucket(bucket) {
|
|
118
119
|
if (!bucket) bucketTicks = null;
|
|
@@ -124,6 +125,7 @@ var OrderbookService = class {
|
|
|
124
125
|
if (stream?.isReady()) emit();
|
|
125
126
|
}
|
|
126
127
|
async function inputServiceFetch() {
|
|
128
|
+
await scales.ready();
|
|
127
129
|
const validated = parse(GetOrderbookInputSchema, {
|
|
128
130
|
symbolId,
|
|
129
131
|
depth: channelDepth
|
|
@@ -144,6 +146,7 @@ var OrderbookService = class {
|
|
|
144
146
|
}
|
|
145
147
|
}
|
|
146
148
|
function handleDelta(delta) {
|
|
149
|
+
if (delta.bookSeqEnd <= currentBookSeq) return true;
|
|
147
150
|
if (delta.reset) {
|
|
148
151
|
bidsMap.clear();
|
|
149
152
|
asksMap.clear();
|
|
@@ -151,13 +154,13 @@ var OrderbookService = class {
|
|
|
151
154
|
}
|
|
152
155
|
if (currentBookSeq !== 0n && delta.bookSeqStart > currentBookSeq + 1n) {
|
|
153
156
|
stream?.refreshSnapshot();
|
|
154
|
-
return;
|
|
157
|
+
return false;
|
|
155
158
|
}
|
|
156
|
-
if (delta.bookSeqEnd <= currentBookSeq) return;
|
|
157
159
|
applySideDelta(bidsMap, delta.bids);
|
|
158
160
|
applySideDelta(asksMap, delta.asks);
|
|
159
161
|
currentBookSeq = delta.bookSeqEnd > currentBookSeq ? delta.bookSeqEnd : currentBookSeq;
|
|
160
162
|
emit();
|
|
163
|
+
return true;
|
|
161
164
|
}
|
|
162
165
|
setBucket(input.bucket);
|
|
163
166
|
stream = snapshotThenStream({
|
|
@@ -166,22 +169,26 @@ var OrderbookService = class {
|
|
|
166
169
|
schema: OrderBookDeltaSchema,
|
|
167
170
|
maxBufferedPublications: 200,
|
|
168
171
|
snapshotErrorLog: "Failed to fetch orderbook",
|
|
172
|
+
snapshotRetry: {
|
|
173
|
+
maxAttempts: 3,
|
|
174
|
+
delayMs: 1e3
|
|
175
|
+
},
|
|
169
176
|
fetchSnapshot: inputServiceFetch,
|
|
170
177
|
readPublication: (delta) => [delta],
|
|
171
178
|
applySnapshot: (snapshot, bufferedDeltas) => {
|
|
172
179
|
bidsMap = levelsToMap(snapshot.bids);
|
|
173
180
|
asksMap = levelsToMap(snapshot.asks);
|
|
174
|
-
currentBookSeq =
|
|
181
|
+
currentBookSeq = snapshot.bookSeq;
|
|
175
182
|
emit();
|
|
176
183
|
for (const delta of bufferedDeltas) {
|
|
177
184
|
if (stream?.isDisposed()) return;
|
|
178
|
-
handleDelta(delta);
|
|
185
|
+
if (!handleDelta(delta)) return;
|
|
179
186
|
}
|
|
180
187
|
},
|
|
181
188
|
applyLivePublications: (deltas) => {
|
|
182
189
|
for (const delta of deltas) {
|
|
183
190
|
if (stream?.isDisposed()) return;
|
|
184
|
-
handleDelta(delta);
|
|
191
|
+
if (!handleDelta(delta)) return;
|
|
185
192
|
}
|
|
186
193
|
},
|
|
187
194
|
onOpen: input.onOpen,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orderbook.js","names":["#client","Proto.OrderbookService","#realtime","#scales","Proto.GetOrderBookResponseSchema","Proto.OrderBookDeltaSchema"],"sources":["../../../src/services/orderbook/orderbook.ts"],"sourcesContent":["import { create } from \"@bufbuild/protobuf\";\nimport * as Proto from \"../../gen/orderbook/v1/orderbook_pb.js\";\nimport { createClient, type Client, type Transport } from \"@connectrpc/connect\";\nimport { publicationHandlerErrorContext } from \"../../shared/subscription-errors.js\";\nimport type { PolyesterRealtime } from \"../../realtime/types.js\";\nimport {\n snapshotThenStream,\n type SnapshotThenStreamSubscription,\n} from \"../../realtime/snapshot-then-stream.js\";\nimport type { BaseSubscribeInput } from \"../../shared/types.js\";\nimport {\n toConnectCallOptions,\n type PolyesterRequestOptions,\n} from \"../../shared/request-options.js\";\nimport {\n createReadyGate,\n decimalInputToScaled,\n type SdkScales,\n} from \"../../shared/decimal-surface.js\";\nimport {\n formatOrderbookLevel,\n GetOrderbookInputSchema,\n createOrderbookDataSchema,\n type OrderbookLevel,\n type OrderbookData,\n} from \"./orderbook.schemas.js\";\nimport { orderbookWsChannelDepth } from \"./orderbook.codecs.js\";\nimport { toBig } from \"../../utils/u128.js\";\nimport { isResourceNotFoundError } from \"../../utils/errors.js\";\nimport type * as v from \"valibot\";\nimport { parse } from \"../../shared/validation.js\";\n\ninterface SubscribeOrderbookInput extends BaseSubscribeInput<OrderbookData> {\n symbolId: number;\n depth?: number;\n bucket?: string | null;\n}\n\nexport interface OrderbookStreamHandlers extends BaseSubscribeInput<OrderbookData> {}\n\nexport interface OrderbookSubscription {\n unsubscribe: () => void;\n setBucket: (bucket: string | null | undefined) => void;\n}\n\nexport interface CreateOrderbookSubscriptionInput\n extends\n OrderbookStreamHandlers,\n Pick<SubscribeOrderbookInput, \"symbolId\" | \"depth\" | \"bucket\"> {}\n\ntype BookSide = Map<bigint, bigint>;\n\n/**\n * Reads spot order book snapshots and maintains realtime local order book state from public delta channels.\n */\nexport class OrderbookService {\n #client: Client<typeof Proto.OrderbookService>;\n #realtime: PolyesterRealtime;\n #scales: SdkScales;\n\n constructor(transport: Transport, realtime: PolyesterRealtime, scales: SdkScales) {\n this.#client = createClient(Proto.OrderbookService, transport);\n this.#realtime = realtime;\n this.#scales = scales;\n }\n\n /**\n * Fetches a spot order book depth snapshot for a symbol ID and requested depth, returning best bids and asks with the backend book sequence.\n */\n async get(\n input: v.InferInput<typeof GetOrderbookInputSchema>,\n options?: PolyesterRequestOptions,\n ): Promise<OrderbookData> {\n const validated = parse(GetOrderbookInputSchema, input);\n await this.#scales.ready();\n const res = await this.#client.getOrderBook(\n { symbolId: validated.symbolId, depth: validated.protoDepth },\n toConnectCallOptions(options),\n );\n return parse(createOrderbookDataSchema(this.#scales, validated.symbolId), {\n symbolId: res.symbolId,\n depth: validated.depth,\n bookSeq: res.bookSeq,\n bids: res.bids,\n asks: res.asks,\n });\n }\n\n /**\n * Subscribes to the managed order book stream for a symbol ID and forwards reconstructed snapshots to onEvent. This is a convenience wrapper around createSubscription().unsubscribe.\n */\n subscribe(input: SubscribeOrderbookInput): () => void {\n return this.createSubscription(input).unsubscribe;\n }\n\n /**\n * Creates a stateful order book subscription that first fetches a snapshot, buffers proto deltas from public:spot:orderbook:deltas:depth:{depth}:{symbolId}:proto, applies sequence-checked updates, and refetches on observed sequence gaps or reconnects. The returned handle can unsubscribe or change local price bucket aggregation without reconnecting.\n *\n * `depth` is clamped to [1, 500] and rides the smallest published channel depth that covers it (see ORDERBOOK_WS_DEPTHS); levels are sliced back to the requested depth locally.\n *\n * Refetching is driven by observed sequence gaps and reconnect events only. A feed that stays subscribed but stops publishing is indistinguishable from a quiet market, so it does not trigger onError or a refetch. Callers that must detect a stalled book need their own idle watchdog plus a REST refetch.\n */\n createSubscription(input: CreateOrderbookSubscriptionInput): OrderbookSubscription {\n const { symbolId } = parse(GetOrderbookInputSchema, {\n symbolId: input.symbolId,\n depth: input.depth,\n });\n const requestedDepth = Math.min(500, Math.max(1, Math.trunc(input.depth ?? 50)));\n const channelDepth = orderbookWsChannelDepth(requestedDepth);\n const channel = `public:spot:orderbook:deltas:depth:${channelDepth}:${symbolId}:proto`;\n\n const client = this.#client;\n const scales = this.#scales;\n const gate = createReadyGate(\n () => scales.ready(),\n (error) => input.onError?.(publicationHandlerErrorContext(channel, error)),\n );\n\n let bidsMap: BookSide = new Map();\n let asksMap: BookSide = new Map();\n let currentBookSeq = 0n;\n let bucketTicks: bigint | null = null;\n let stream: SnapshotThenStreamSubscription | undefined;\n\n function levelsToMap(levels: Proto.PriceLevel[] | undefined): BookSide {\n const map: BookSide = new Map();\n for (const l of levels ?? []) {\n if (l.qtyScaled === 0n) continue;\n map.set(l.priceTicks, l.qtyScaled);\n }\n return map;\n }\n\n function applySideDelta(map: BookSide, levels: Proto.PriceLevel[] | undefined): void {\n for (const l of levels ?? []) {\n if (l.qtyScaled === 0n) map.delete(l.priceTicks);\n else map.set(l.priceTicks, l.qtyScaled);\n }\n }\n\n function sideToUI(map: BookSide, side: \"bids\" | \"asks\", limit: number): OrderbookLevel[] {\n const entries = Array.from(map.entries());\n entries.sort(([pa], [pb]) => {\n if (pa === pb) return 0;\n return side === \"bids\" ? (pa > pb ? -1 : 1) : pa < pb ? -1 : 1;\n });\n return entries\n .slice(0, limit)\n .map(([priceTicks, qtyScaled]) =>\n formatOrderbookLevel({ priceTicks, qtyScaled }, scales, symbolId),\n );\n }\n\n function sideToUIBucketed(\n map: BookSide,\n side: \"bids\" | \"asks\",\n limit: number,\n bucket: bigint | null,\n ): OrderbookLevel[] {\n if (!bucket || bucket <= 0n) return sideToUI(map, side, limit);\n\n const agg: BookSide = new Map();\n for (const [priceTicks, qtyScaled] of map.entries()) {\n if (qtyScaled <= 0n) continue;\n const bucketPrice = (priceTicks / bucket) * bucket;\n agg.set(bucketPrice, (agg.get(bucketPrice) ?? 0n) + qtyScaled);\n }\n return sideToUI(agg, side, limit);\n }\n\n function emit(): void {\n gate.run(() => {\n input.onEvent({\n symbolId,\n depth: requestedDepth,\n bookSeq: currentBookSeq.toString(),\n bids: sideToUIBucketed(bidsMap, \"bids\", requestedDepth, bucketTicks),\n asks: sideToUIBucketed(asksMap, \"asks\", requestedDepth, bucketTicks),\n });\n });\n }\n\n function setBucket(bucket: string | null | undefined): void {\n if (!bucket) {\n bucketTicks = null;\n } else {\n try {\n bucketTicks = decimalInputToScaled(\"bucket\", bucket, scales.price());\n } catch {\n bucketTicks = null;\n }\n }\n if (stream?.isReady()) emit();\n }\n\n async function inputServiceFetch(): Promise<Proto.GetOrderBookResponse> {\n const validated = parse(GetOrderbookInputSchema, {\n symbolId,\n depth: channelDepth,\n });\n try {\n return await client.getOrderBook({\n symbolId: validated.symbolId,\n depth: validated.protoDepth,\n });\n } catch (error: unknown) {\n if (!isResourceNotFoundError(error)) throw error;\n\n return create(Proto.GetOrderBookResponseSchema, {\n symbolId,\n bookSeq: 0n,\n bids: [],\n asks: [],\n });\n }\n }\n\n function handleDelta(delta: Proto.OrderBookDelta): void {\n if (delta.reset) {\n bidsMap.clear();\n asksMap.clear();\n currentBookSeq = 0n;\n }\n\n if (currentBookSeq !== 0n && delta.bookSeqStart > currentBookSeq + 1n) {\n stream?.refreshSnapshot();\n return;\n }\n\n if (delta.bookSeqEnd <= currentBookSeq) return;\n\n applySideDelta(bidsMap, delta.bids);\n applySideDelta(asksMap, delta.asks);\n\n currentBookSeq = delta.bookSeqEnd > currentBookSeq ? delta.bookSeqEnd : currentBookSeq;\n emit();\n }\n\n setBucket(input.bucket);\n stream = snapshotThenStream({\n realtime: this.#realtime,\n channel,\n schema: Proto.OrderBookDeltaSchema,\n maxBufferedPublications: 200,\n snapshotErrorLog: \"Failed to fetch orderbook\",\n fetchSnapshot: inputServiceFetch,\n readPublication: (delta) => [delta],\n applySnapshot: (snapshot, bufferedDeltas) => {\n bidsMap = levelsToMap(snapshot.bids);\n asksMap = levelsToMap(snapshot.asks);\n currentBookSeq = toBig(snapshot.bookSeq);\n emit();\n for (const delta of bufferedDeltas) {\n if (stream?.isDisposed()) return;\n handleDelta(delta);\n }\n },\n applyLivePublications: (deltas) => {\n for (const delta of deltas) {\n if (stream?.isDisposed()) return;\n handleDelta(delta);\n }\n },\n onOpen: input.onOpen,\n onClose: input.onClose,\n onError: input.onError,\n });\n\n function dispose(): void {\n stream?.unsubscribe();\n }\n\n return { unsubscribe: dispose, setBucket };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"orderbook.js","names":["#client","Proto.OrderbookService","#realtime","#scales","Proto.GetOrderBookResponseSchema","Proto.OrderBookDeltaSchema"],"sources":["../../../src/services/orderbook/orderbook.ts"],"sourcesContent":["import { create } from \"@bufbuild/protobuf\";\nimport * as Proto from \"../../gen/orderbook/v1/orderbook_pb.js\";\nimport { createClient, type Client, type Transport } from \"@connectrpc/connect\";\nimport { publicationHandlerErrorContext } from \"../../shared/subscription-errors.js\";\nimport type { PolyesterRealtime } from \"../../realtime/types.js\";\nimport {\n snapshotThenStream,\n type SnapshotThenStreamSubscription,\n} from \"../../realtime/snapshot-then-stream.js\";\nimport type { BaseSubscribeInput } from \"../../shared/types.js\";\nimport {\n toConnectCallOptions,\n type PolyesterRequestOptions,\n} from \"../../shared/request-options.js\";\nimport { decimalInputToScaled, type SdkScales } from \"../../shared/decimal-surface.js\";\nimport {\n formatOrderbookLevel,\n GetOrderbookInputSchema,\n createOrderbookDataSchema,\n type OrderbookLevel,\n type OrderbookData,\n} from \"./orderbook.schemas.js\";\nimport { orderbookWsChannelDepth } from \"./orderbook.codecs.js\";\nimport { isResourceNotFoundError } from \"../../utils/errors.js\";\nimport type * as v from \"valibot\";\nimport { parse } from \"../../shared/validation.js\";\n\ninterface SubscribeOrderbookInput extends BaseSubscribeInput<OrderbookData> {\n symbolId: number;\n depth?: number;\n bucket?: string | null;\n}\n\nexport interface OrderbookStreamHandlers extends BaseSubscribeInput<OrderbookData> {}\n\nexport interface OrderbookSubscription {\n unsubscribe: () => void;\n setBucket: (bucket: string | null | undefined) => void;\n}\n\nexport interface CreateOrderbookSubscriptionInput\n extends\n OrderbookStreamHandlers,\n Pick<SubscribeOrderbookInput, \"symbolId\" | \"depth\" | \"bucket\"> {}\n\ntype BookSide = Map<bigint, bigint>;\n\n/**\n * Reads spot order book snapshots and maintains realtime local order book state from public delta channels.\n */\nexport class OrderbookService {\n #client: Client<typeof Proto.OrderbookService>;\n #realtime: PolyesterRealtime;\n #scales: SdkScales;\n\n constructor(transport: Transport, realtime: PolyesterRealtime, scales: SdkScales) {\n this.#client = createClient(Proto.OrderbookService, transport);\n this.#realtime = realtime;\n this.#scales = scales;\n }\n\n /**\n * Fetches a spot order book depth snapshot for a symbol ID and requested depth, returning best bids and asks with the backend book sequence.\n */\n async get(\n input: v.InferInput<typeof GetOrderbookInputSchema>,\n options?: PolyesterRequestOptions,\n ): Promise<OrderbookData> {\n const validated = parse(GetOrderbookInputSchema, input);\n await this.#scales.ready();\n const res = await this.#client.getOrderBook(\n { symbolId: validated.symbolId, depth: validated.protoDepth },\n toConnectCallOptions(options),\n );\n return parse(createOrderbookDataSchema(this.#scales, validated.symbolId), {\n symbolId: res.symbolId,\n depth: validated.depth,\n bookSeq: res.bookSeq,\n bids: res.bids,\n asks: res.asks,\n });\n }\n\n /**\n * Subscribes to the managed order book stream for a symbol ID and forwards reconstructed snapshots to onEvent. This is a convenience wrapper around createSubscription().unsubscribe.\n */\n subscribe(input: SubscribeOrderbookInput): () => void {\n return this.createSubscription(input).unsubscribe;\n }\n\n /**\n * Creates a stateful order book subscription that first fetches a snapshot, buffers proto deltas from public:spot:orderbook:deltas:depth:{depth}:{symbolId}:proto, applies sequence-checked updates, and refetches on observed sequence gaps or reconnects. The returned handle can unsubscribe or change local price bucket aggregation without reconnecting.\n *\n * `depth` is clamped to [1, 500] and rides the smallest published channel depth that covers it (see ORDERBOOK_WS_DEPTHS); levels are sliced back to the requested depth locally.\n *\n * Refetching is driven by observed sequence gaps and reconnect events only. A feed that stays subscribed but stops publishing is indistinguishable from a quiet market, so it does not trigger onError or a refetch. Callers that must detect a stalled book need their own idle watchdog plus a REST refetch.\n */\n createSubscription(input: CreateOrderbookSubscriptionInput): OrderbookSubscription {\n const { symbolId } = parse(GetOrderbookInputSchema, {\n symbolId: input.symbolId,\n depth: input.depth,\n });\n const requestedDepth = Math.min(500, Math.max(1, Math.trunc(input.depth ?? 50)));\n const channelDepth = orderbookWsChannelDepth(requestedDepth);\n const channel = `public:spot:orderbook:deltas:depth:${channelDepth}:${symbolId}:proto`;\n\n const client = this.#client;\n const scales = this.#scales;\n let bidsMap: BookSide = new Map();\n let asksMap: BookSide = new Map();\n let currentBookSeq = 0n;\n let bucketTicks: bigint | null = null;\n let stream: SnapshotThenStreamSubscription | undefined;\n\n function levelsToMap(levels: Proto.PriceLevel[] | undefined): BookSide {\n const map: BookSide = new Map();\n for (const l of levels ?? []) {\n if (l.qtyScaled === 0n) continue;\n map.set(l.priceTicks, l.qtyScaled);\n }\n return map;\n }\n\n function applySideDelta(map: BookSide, levels: Proto.PriceLevel[] | undefined): void {\n for (const l of levels ?? []) {\n if (l.qtyScaled === 0n) map.delete(l.priceTicks);\n else map.set(l.priceTicks, l.qtyScaled);\n }\n }\n\n function sideToUI(map: BookSide, side: \"bids\" | \"asks\", limit: number): OrderbookLevel[] {\n const entries = Array.from(map.entries());\n entries.sort(([pa], [pb]) => {\n if (pa === pb) return 0;\n return side === \"bids\" ? (pa > pb ? -1 : 1) : pa < pb ? -1 : 1;\n });\n return entries\n .slice(0, limit)\n .map(([priceTicks, qtyScaled]) =>\n formatOrderbookLevel({ priceTicks, qtyScaled }, scales, symbolId),\n );\n }\n\n function sideToUIBucketed(\n map: BookSide,\n side: \"bids\" | \"asks\",\n limit: number,\n bucket: bigint | null,\n ): OrderbookLevel[] {\n if (!bucket || bucket <= 0n) return sideToUI(map, side, limit);\n\n const agg: BookSide = new Map();\n for (const [priceTicks, qtyScaled] of map.entries()) {\n if (qtyScaled <= 0n) continue;\n const bucketFloor = (priceTicks / bucket) * bucket;\n const bucketPrice =\n side === \"asks\" && bucketFloor !== priceTicks\n ? bucketFloor + bucket\n : bucketFloor;\n agg.set(bucketPrice, (agg.get(bucketPrice) ?? 0n) + qtyScaled);\n }\n return sideToUI(agg, side, limit);\n }\n\n function emit(): void {\n try {\n input.onEvent({\n symbolId,\n depth: requestedDepth,\n bookSeq: currentBookSeq.toString(),\n bids: sideToUIBucketed(bidsMap, \"bids\", requestedDepth, bucketTicks),\n asks: sideToUIBucketed(asksMap, \"asks\", requestedDepth, bucketTicks),\n });\n } catch (error) {\n input.onError?.(publicationHandlerErrorContext(channel, error));\n }\n }\n\n function setBucket(bucket: string | null | undefined): void {\n if (!bucket) {\n bucketTicks = null;\n } else {\n try {\n bucketTicks = decimalInputToScaled(\"bucket\", bucket, scales.price());\n } catch {\n bucketTicks = null;\n }\n }\n if (stream?.isReady()) emit();\n }\n\n async function inputServiceFetch(): Promise<Proto.GetOrderBookResponse> {\n await scales.ready();\n const validated = parse(GetOrderbookInputSchema, {\n symbolId,\n depth: channelDepth,\n });\n try {\n return await client.getOrderBook({\n symbolId: validated.symbolId,\n depth: validated.protoDepth,\n });\n } catch (error: unknown) {\n if (!isResourceNotFoundError(error)) throw error;\n\n return create(Proto.GetOrderBookResponseSchema, {\n symbolId,\n bookSeq: 0n,\n bids: [],\n asks: [],\n });\n }\n }\n\n function handleDelta(delta: Proto.OrderBookDelta): boolean {\n if (delta.bookSeqEnd <= currentBookSeq) return true;\n\n if (delta.reset) {\n bidsMap.clear();\n asksMap.clear();\n currentBookSeq = 0n;\n }\n\n if (currentBookSeq !== 0n && delta.bookSeqStart > currentBookSeq + 1n) {\n stream?.refreshSnapshot();\n return false;\n }\n\n applySideDelta(bidsMap, delta.bids);\n applySideDelta(asksMap, delta.asks);\n\n currentBookSeq = delta.bookSeqEnd > currentBookSeq ? delta.bookSeqEnd : currentBookSeq;\n emit();\n return true;\n }\n\n setBucket(input.bucket);\n stream = snapshotThenStream({\n realtime: this.#realtime,\n channel,\n schema: Proto.OrderBookDeltaSchema,\n maxBufferedPublications: 200,\n snapshotErrorLog: \"Failed to fetch orderbook\",\n snapshotRetry: { maxAttempts: 3, delayMs: 1_000 },\n fetchSnapshot: inputServiceFetch,\n readPublication: (delta) => [delta],\n applySnapshot: (snapshot, bufferedDeltas) => {\n bidsMap = levelsToMap(snapshot.bids);\n asksMap = levelsToMap(snapshot.asks);\n currentBookSeq = snapshot.bookSeq;\n emit();\n for (const delta of bufferedDeltas) {\n if (stream?.isDisposed()) return;\n if (!handleDelta(delta)) return;\n }\n },\n applyLivePublications: (deltas) => {\n for (const delta of deltas) {\n if (stream?.isDisposed()) return;\n if (!handleDelta(delta)) return;\n }\n },\n onOpen: input.onOpen,\n onClose: input.onClose,\n onError: input.onError,\n });\n\n function dispose(): void {\n stream?.unsubscribe();\n }\n\n return { unsubscribe: dispose, setBucket };\n }\n}\n"],"mappings":"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"}
|
|
@@ -212,8 +212,6 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
212
212
|
}, undefined>, v.StrictObjectSchema<{
|
|
213
213
|
readonly kind: v.LiteralSchema<"bps", undefined>;
|
|
214
214
|
readonly bps: v.UnionSchema<[v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>]>, v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.GtValueAction<number, 0, undefined>]>], undefined>;
|
|
215
|
-
}, undefined>, v.StrictObjectSchema<{
|
|
216
|
-
readonly kind: v.LiteralSchema<"none", undefined>;
|
|
217
215
|
}, undefined>], undefined>;
|
|
218
216
|
readonly maxSlippage: v.OptionalSchema<v.UnionSchema<[v.StrictObjectSchema<{
|
|
219
217
|
readonly kind: v.LiteralSchema<"slippage", undefined>;
|
|
@@ -229,8 +227,6 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
229
227
|
trailingDistance: {
|
|
230
228
|
kind: "bps";
|
|
231
229
|
bps: string | number;
|
|
232
|
-
} | {
|
|
233
|
-
kind: "none";
|
|
234
230
|
} | {
|
|
235
231
|
kind: "distance";
|
|
236
232
|
distance: string;
|
|
@@ -343,8 +339,6 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
343
339
|
}, undefined>, v.StrictObjectSchema<{
|
|
344
340
|
readonly kind: v.LiteralSchema<"bps", undefined>;
|
|
345
341
|
readonly bps: v.UnionSchema<[v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>]>, v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.GtValueAction<number, 0, undefined>]>], undefined>;
|
|
346
|
-
}, undefined>, v.StrictObjectSchema<{
|
|
347
|
-
readonly kind: v.LiteralSchema<"none", undefined>;
|
|
348
342
|
}, undefined>], undefined>;
|
|
349
343
|
readonly maxSlippage: v.OptionalSchema<v.UnionSchema<[v.StrictObjectSchema<{
|
|
350
344
|
readonly kind: v.LiteralSchema<"slippage", undefined>;
|
|
@@ -360,8 +354,6 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
360
354
|
trailingDistance: {
|
|
361
355
|
kind: "bps";
|
|
362
356
|
bps: string | number;
|
|
363
|
-
} | {
|
|
364
|
-
kind: "none";
|
|
365
357
|
} | {
|
|
366
358
|
kind: "distance";
|
|
367
359
|
distance: string;
|
|
@@ -743,8 +735,6 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
743
735
|
}, undefined>, v.StrictObjectSchema<{
|
|
744
736
|
readonly kind: v.LiteralSchema<"bps", undefined>;
|
|
745
737
|
readonly bps: v.UnionSchema<[v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>]>, v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.GtValueAction<number, 0, undefined>]>], undefined>;
|
|
746
|
-
}, undefined>, v.StrictObjectSchema<{
|
|
747
|
-
readonly kind: v.LiteralSchema<"none", undefined>;
|
|
748
738
|
}, undefined>], undefined>;
|
|
749
739
|
readonly maxSlippage: v.OptionalSchema<v.UnionSchema<[v.StrictObjectSchema<{
|
|
750
740
|
readonly kind: v.LiteralSchema<"slippage", undefined>;
|
|
@@ -760,8 +750,6 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
760
750
|
trailingDistance: {
|
|
761
751
|
kind: "bps";
|
|
762
752
|
bps: string | number;
|
|
763
|
-
} | {
|
|
764
|
-
kind: "none";
|
|
765
753
|
} | {
|
|
766
754
|
kind: "distance";
|
|
767
755
|
distance: string;
|
|
@@ -874,8 +862,6 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
874
862
|
}, undefined>, v.StrictObjectSchema<{
|
|
875
863
|
readonly kind: v.LiteralSchema<"bps", undefined>;
|
|
876
864
|
readonly bps: v.UnionSchema<[v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>]>, v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.GtValueAction<number, 0, undefined>]>], undefined>;
|
|
877
|
-
}, undefined>, v.StrictObjectSchema<{
|
|
878
|
-
readonly kind: v.LiteralSchema<"none", undefined>;
|
|
879
865
|
}, undefined>], undefined>;
|
|
880
866
|
readonly maxSlippage: v.OptionalSchema<v.UnionSchema<[v.StrictObjectSchema<{
|
|
881
867
|
readonly kind: v.LiteralSchema<"slippage", undefined>;
|
|
@@ -891,8 +877,6 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
891
877
|
trailingDistance: {
|
|
892
878
|
kind: "bps";
|
|
893
879
|
bps: string | number;
|
|
894
|
-
} | {
|
|
895
|
-
kind: "none";
|
|
896
880
|
} | {
|
|
897
881
|
kind: "distance";
|
|
898
882
|
distance: string;
|
|
@@ -3257,9 +3241,9 @@ declare const GetBatchReplaceStatusResultSchema: v.SchemaWithPipe<readonly [v.Ob
|
|
|
3257
3241
|
}>]>;
|
|
3258
3242
|
type GetBatchReplaceStatusResult = v.InferOutput<typeof GetBatchReplaceStatusResultSchema>;
|
|
3259
3243
|
declare const BatchCancelOrderInputSchema: v.UnionSchema<[v.SchemaWithPipe<readonly [v.StrictObjectSchema<{
|
|
3260
|
-
readonly orderId: v.SchemaWithPipe<readonly [v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.TransformAction<string, bigint>]>, v.CheckAction<bigint,
|
|
3244
|
+
readonly orderId: v.SchemaWithPipe<readonly [v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.TransformAction<string, bigint>]>, v.CheckAction<bigint, `${string} must be greater than zero`>]>;
|
|
3261
3245
|
readonly clientOrderId: v.OptionalSchema<v.NeverSchema<undefined>, undefined>;
|
|
3262
|
-
readonly symbolId: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.
|
|
3246
|
+
readonly symbolId: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.GtValueAction<number, 0, undefined>, v.MaxValueAction<number, 4294967295, undefined>]>, undefined>;
|
|
3263
3247
|
}, undefined>, v.TransformAction<{
|
|
3264
3248
|
orderId: bigint;
|
|
3265
3249
|
clientOrderId?: undefined;
|
|
@@ -3270,7 +3254,7 @@ declare const BatchCancelOrderInputSchema: v.UnionSchema<[v.SchemaWithPipe<reado
|
|
|
3270
3254
|
}>]>, v.SchemaWithPipe<readonly [v.StrictObjectSchema<{
|
|
3271
3255
|
readonly orderId: v.OptionalSchema<v.NeverSchema<undefined>, undefined>;
|
|
3272
3256
|
readonly clientOrderId: v.SchemaWithPipe<readonly [v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MaxLengthAction<string, 36, undefined>, v.RegexAction<string, "clientOrderId has an invalid format">]>, v.MinLengthAction<string, 1, undefined>]>;
|
|
3273
|
-
readonly symbolId: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.
|
|
3257
|
+
readonly symbolId: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.GtValueAction<number, 0, undefined>, v.MaxValueAction<number, 4294967295, undefined>]>, undefined>;
|
|
3274
3258
|
}, undefined>, v.TransformAction<{
|
|
3275
3259
|
orderId?: undefined;
|
|
3276
3260
|
clientOrderId: string;
|
|
@@ -3283,9 +3267,9 @@ type BatchCancelOrderInput = v.InferInput<typeof BatchCancelOrderInputSchema>;
|
|
|
3283
3267
|
declare const BatchCancelOrdersInputSchema: v.SchemaWithPipe<readonly [v.StrictObjectSchema<{
|
|
3284
3268
|
readonly requestId: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 64, undefined>, v.RegexAction<string, "requestId has an invalid format">]>, undefined>;
|
|
3285
3269
|
readonly items: v.SchemaWithPipe<readonly [v.ArraySchema<v.UnionSchema<[v.SchemaWithPipe<readonly [v.StrictObjectSchema<{
|
|
3286
|
-
readonly orderId: v.SchemaWithPipe<readonly [v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.TransformAction<string, bigint>]>, v.CheckAction<bigint,
|
|
3270
|
+
readonly orderId: v.SchemaWithPipe<readonly [v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.TransformAction<string, bigint>]>, v.CheckAction<bigint, `${string} must be greater than zero`>]>;
|
|
3287
3271
|
readonly clientOrderId: v.OptionalSchema<v.NeverSchema<undefined>, undefined>;
|
|
3288
|
-
readonly symbolId: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.
|
|
3272
|
+
readonly symbolId: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.GtValueAction<number, 0, undefined>, v.MaxValueAction<number, 4294967295, undefined>]>, undefined>;
|
|
3289
3273
|
}, undefined>, v.TransformAction<{
|
|
3290
3274
|
orderId: bigint;
|
|
3291
3275
|
clientOrderId?: undefined;
|
|
@@ -3296,7 +3280,7 @@ declare const BatchCancelOrdersInputSchema: v.SchemaWithPipe<readonly [v.StrictO
|
|
|
3296
3280
|
}>]>, v.SchemaWithPipe<readonly [v.StrictObjectSchema<{
|
|
3297
3281
|
readonly orderId: v.OptionalSchema<v.NeverSchema<undefined>, undefined>;
|
|
3298
3282
|
readonly clientOrderId: v.SchemaWithPipe<readonly [v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MaxLengthAction<string, 36, undefined>, v.RegexAction<string, "clientOrderId has an invalid format">]>, v.MinLengthAction<string, 1, undefined>]>;
|
|
3299
|
-
readonly symbolId: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.
|
|
3283
|
+
readonly symbolId: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.GtValueAction<number, 0, undefined>, v.MaxValueAction<number, 4294967295, undefined>]>, undefined>;
|
|
3300
3284
|
}, undefined>, v.TransformAction<{
|
|
3301
3285
|
orderId?: undefined;
|
|
3302
3286
|
clientOrderId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orders-batch.schemas.d.ts","names":[],"sources":["../../../src/services/orders/orders-batch.schemas.ts"],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"orders-batch.schemas.d.ts","names":[],"sources":["../../../src/services/orders/orders-batch.schemas.ts"],"mappings":";;;;;;;;cAuDa,2BAAyB,EAAA,yBAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;KAc1B,sBAAsB,EAAE,kBAAkB;cAEzC,4BAA0B,EAAA,yBAAA,EAAA;;;;;;;;;;;;;;;;;;KAgB3B,uBAAuB,EAAE,mBAAmB;iBAExC,mCAAmC,QAAQ,YAAS,EAAA,yBAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAwBxD,yBAAyB,EAAE,WACnC,kBAAkB;iBA4BN,oCAAoC,QAAQ,WAAW,sBAAmB,EAAA,yBAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAsD9E,0BAA0B,EAAE,YACpC,kBAAkB;KAEV,yBAAyB;KAkIzB;EACR,UAAU,EAAE,kBAAkB,yBAAyB;EACvD;EACA;EACA,OAAO;IACH;IACA;IACA;IACA;IACA,OAAO,EAAE,WAAW,kBAAkB;IACtC;IACA;;;cAIF,iCAA+B,EAAA,yBAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA0BzB,4BAA4B,EAAE,mBAAmB;cAEhD,gCAA8B,EAAA,yBAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAkC/B,2BAA2B,EAAE,mBAAmB;cAE/C,kCAAgC,EAAA,yBAAA,EAAA;;;;;;;;;;;;;;KAcjC,6BAA6B,EAAE,kBAAkB;cAwChD,mCAAiC,EAAA,yBAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAqClC,8BAA8B,EAAE,mBAAmB;cAEzD,6BAA2B,EAAA,aAAA,EAAA,yBAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;KAmBrB,wBAAwB,EAAE,kBAAkB;cAE3C,8BAA4B,EAAA,yBAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAgB7B,yBAAyB,EAAE,kBAAkB;cAEnD,8BAA4B,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;KAQtB,yBAAyB,EAAE,mBAAmB;cAE7C,+BAA6B,EAAA,yBAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAkB9B,0BAA0B,EAAE,mBAAmB"}
|
|
@@ -11,7 +11,7 @@ import { OrderSideCodec } from "./order-enums.codecs.js";
|
|
|
11
11
|
import { BatchReplaceAdmissionStatusCodec, BatchReplaceItemAdmissionStatusCodec, BatchReplacePhaseCodec, OrderStatusCodec } from "./orders.codecs.js";
|
|
12
12
|
import { OrderErrorDetailSchema } from "./order-errors.schemas.js";
|
|
13
13
|
import { createRequiredRiskPolicyInputSchema } from "./orders-risk.schemas.js";
|
|
14
|
-
import { ClientOrderIdInputSchema, OrderRequestIdInputSchema } from "./orders-identifiers.schemas.js";
|
|
14
|
+
import { ClientOrderIdInputSchema, OrderRequestIdInputSchema, positiveOrderIdInputSchema } from "./orders-identifiers.schemas.js";
|
|
15
15
|
import { createOrderIntentInputSchema } from "./orders-input.schemas.js";
|
|
16
16
|
import { create } from "@bufbuild/protobuf";
|
|
17
17
|
import * as v from "valibot";
|
|
@@ -127,7 +127,7 @@ const BatchReplaceTargetInputSchema = v.union([v.pipe(v.object({
|
|
|
127
127
|
case: "clientOrderId",
|
|
128
128
|
value: clientOrderId
|
|
129
129
|
} })))]);
|
|
130
|
-
function createBatchReplaceOrderItemInputSchema(scales
|
|
130
|
+
function createBatchReplaceOrderItemInputSchema(scales) {
|
|
131
131
|
const patchSchema = v.union([
|
|
132
132
|
v.object({
|
|
133
133
|
newPrice: DecimalInputStringSchema,
|
|
@@ -154,31 +154,34 @@ function createBatchReplaceOrderItemInputSchema(scales, symbolId) {
|
|
|
154
154
|
clearRisk: v.literal(true)
|
|
155
155
|
})
|
|
156
156
|
]);
|
|
157
|
-
return v.
|
|
157
|
+
return v.intersect([
|
|
158
158
|
BatchReplaceTargetInputSchema,
|
|
159
159
|
patchSchema,
|
|
160
160
|
v.object({ newClientOrderId: v.optional(ClientOrderIdInputSchema) })
|
|
161
|
-
])
|
|
162
|
-
key: input.key,
|
|
163
|
-
newPriceTicks: input.newPrice === void 0 ? void 0 : positiveDecimalInputToScaled("items.newPrice", input.newPrice, scales.price()),
|
|
164
|
-
newQtyScaled: input.newQty === void 0 ? void 0 : positiveDecimalInputToScaled("items.newQty", input.newQty, scales.baseQty(symbolId)),
|
|
165
|
-
newAttachedRisk: input.clearRisk === true ? create(RiskPolicySchema) : input.risk,
|
|
166
|
-
newClientOrderId: input.newClientOrderId ?? ""
|
|
167
|
-
})));
|
|
161
|
+
]);
|
|
168
162
|
}
|
|
169
|
-
function createBatchReplaceOrdersInputSchema(scales
|
|
163
|
+
function createBatchReplaceOrdersInputSchema(scales) {
|
|
170
164
|
return v.pipe(v.strictObject({
|
|
171
165
|
...AccountScopeInputEntries,
|
|
172
|
-
symbolId:
|
|
166
|
+
symbolId: SymbolIdInputSchema,
|
|
173
167
|
requestId: v.optional(OrderRequestIdInputSchema),
|
|
174
|
-
items: v.pipe(v.array(createBatchReplaceOrderItemInputSchema(scales
|
|
168
|
+
items: v.pipe(v.array(createBatchReplaceOrderItemInputSchema(scales)), v.minLength(1, "At least one replacement is required."), v.maxLength(50, "Batch replace accepts at most 50 replacements."))
|
|
175
169
|
}), v.check((input) => {
|
|
176
170
|
const targets = input.items.map((item) => `${item.key.case}:${item.key.value.toString()}`);
|
|
177
171
|
return new Set(targets).size === targets.length;
|
|
178
|
-
}, "Each batch replace target must be unique."), v.transform(({ account, ...input }) =>
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
172
|
+
}, "Each batch replace target must be unique."), v.transform(({ account, items, ...input }) => {
|
|
173
|
+
return {
|
|
174
|
+
...input,
|
|
175
|
+
items: items.map((item) => ({
|
|
176
|
+
key: item.key,
|
|
177
|
+
newPriceTicks: item.newPrice === void 0 ? void 0 : positiveDecimalInputToScaled("items.newPrice", item.newPrice, scales.price()),
|
|
178
|
+
newQtyScaled: item.newQty === void 0 ? void 0 : positiveDecimalInputToScaled("items.newQty", item.newQty, scales.baseQty(input.symbolId)),
|
|
179
|
+
newAttachedRisk: item.clearRisk === true ? create(RiskPolicySchema) : item.risk,
|
|
180
|
+
newClientOrderId: item.newClientOrderId ?? ""
|
|
181
|
+
})),
|
|
182
|
+
subaccountId: accountScopeToSubaccountId(account)
|
|
183
|
+
};
|
|
184
|
+
}));
|
|
182
185
|
}
|
|
183
186
|
const BatchReplaceAdmissionItemSchema = v.pipe(v.object({
|
|
184
187
|
itemIndex: BatchItemIndexSchema,
|
|
@@ -241,16 +244,16 @@ const GetBatchReplaceStatusResultSchema = v.pipe(v.object({
|
|
|
241
244
|
updatedTsNs: updatedTsNs.toString()
|
|
242
245
|
})));
|
|
243
246
|
const BatchCancelOrderInputSchema = v.union([v.pipe(v.strictObject({
|
|
244
|
-
orderId:
|
|
247
|
+
orderId: positiveOrderIdInputSchema("items.orderId"),
|
|
245
248
|
clientOrderId: v.optional(v.never()),
|
|
246
|
-
symbolId: v.optional(
|
|
249
|
+
symbolId: v.optional(SymbolIdInputSchema)
|
|
247
250
|
}), v.transform(({ orderId, symbolId }) => ({
|
|
248
251
|
orderId,
|
|
249
252
|
symbolId
|
|
250
253
|
}))), v.pipe(v.strictObject({
|
|
251
254
|
orderId: v.optional(v.never()),
|
|
252
255
|
clientOrderId: ClientOrderIdInputSchema,
|
|
253
|
-
symbolId: v.optional(
|
|
256
|
+
symbolId: v.optional(SymbolIdInputSchema)
|
|
254
257
|
}), v.transform(({ clientOrderId, symbolId }) => ({
|
|
255
258
|
clientOrderId,
|
|
256
259
|
symbolId
|