@polyester/sdk 0.8.0 → 0.9.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 +8 -0
- package/dist/catalogs/readers.js +1 -1
- package/dist/gen/auth/v1/policies_pb.d.ts +28 -10
- package/dist/gen/auth/v1/policies_pb.d.ts.map +1 -1
- package/dist/gen/auth/v1/policies_pb.js +37 -31
- package/dist/gen/auth/v1/policies_pb.js.map +1 -1
- package/dist/gen/fees/v1/fees_pb.d.ts +0 -6
- package/dist/gen/fees/v1/fees_pb.d.ts.map +1 -1
- package/dist/gen/fees/v1/fees_pb.js +1 -1
- package/dist/gen/fees/v1/fees_pb.js.map +1 -1
- package/dist/gen/marketoverview/v1/marketoverview_pb.d.ts +6 -11
- package/dist/gen/marketoverview/v1/marketoverview_pb.d.ts.map +1 -1
- package/dist/gen/marketoverview/v1/marketoverview_pb.js +1 -1
- package/dist/gen/marketoverview/v1/marketoverview_pb.js.map +1 -1
- package/dist/gen/orderbook/v1/orderbook_pb.d.ts +3 -3
- package/dist/gen/orderbook/v1/orderbook_pb.js +1 -1
- package/dist/gen/orderbook/v1/orderbook_pb.js.map +1 -1
- package/dist/gen/orders/v1/orders_pb.d.ts +11 -11
- package/dist/gen/orders/v1/orders_pb.js +1 -1
- package/dist/gen/orders/v1/orders_pb.js.map +1 -1
- package/dist/gen/triggers/v1/triggers_pb.d.ts +6 -12
- package/dist/gen/triggers/v1/triggers_pb.d.ts.map +1 -1
- package/dist/gen/triggers/v1/triggers_pb.js +1 -1
- package/dist/gen/triggers/v1/triggers_pb.js.map +1 -1
- package/dist/services/fees/fees.schemas.d.ts +2 -3
- package/dist/services/fees/fees.schemas.d.ts.map +1 -1
- package/dist/services/fees/fees.schemas.js +3 -4
- package/dist/services/fees/fees.schemas.js.map +1 -1
- package/dist/services/lifecycle/lifecycle.schemas.d.ts +42 -42
- package/dist/services/market-data/market-data.schemas.js +1 -1
- package/dist/services/market-overview/market-overview.d.ts +1 -1
- package/dist/services/market-overview/market-overview.js +1 -1
- package/dist/services/market-overview/market-overview.js.map +1 -1
- package/dist/services/market-overview/market-overview.schemas.d.ts +20 -7
- package/dist/services/market-overview/market-overview.schemas.d.ts.map +1 -1
- package/dist/services/market-overview/market-overview.schemas.js +8 -6
- package/dist/services/market-overview/market-overview.schemas.js.map +1 -1
- package/dist/services/orderbook/orderbook.d.ts +3 -4
- package/dist/services/orderbook/orderbook.d.ts.map +1 -1
- package/dist/services/orderbook/orderbook.js +13 -10
- package/dist/services/orderbook/orderbook.js.map +1 -1
- package/dist/services/orderbook/orderbook.schemas.d.ts +8 -9
- package/dist/services/orderbook/orderbook.schemas.d.ts.map +1 -1
- package/dist/services/orderbook/orderbook.schemas.js +9 -8
- package/dist/services/orderbook/orderbook.schemas.js.map +1 -1
- package/dist/services/orders/orders-batch.schemas.d.ts +22 -22
- package/dist/services/orders/orders-batch.schemas.d.ts.map +1 -1
- package/dist/services/orders/orders-batch.schemas.js +7 -8
- package/dist/services/orders/orders-batch.schemas.js.map +1 -1
- package/dist/services/orders/orders-input.schemas.d.ts +25 -25
- package/dist/services/orders/orders-input.schemas.d.ts.map +1 -1
- package/dist/services/orders/orders-input.schemas.js +10 -10
- package/dist/services/orders/orders-input.schemas.js.map +1 -1
- package/dist/services/orders/orders-modify.schemas.js +1 -1
- package/dist/services/orders/orders-output.schemas.d.ts +6 -6
- package/dist/services/orders/orders-risk.schemas.js +1 -1
- package/dist/services/orders/orders.d.ts +4 -4
- package/dist/services/orders/orders.d.ts.map +1 -1
- package/dist/services/orders/orders.js +7 -7
- package/dist/services/orders/orders.js.map +1 -1
- package/dist/services/policies/api-key-policies/api-key-policies.schemas.d.ts +15 -15
- package/dist/services/policies/shared.d.ts.map +1 -1
- package/dist/services/policies/shared.js +2 -1
- package/dist/services/policies/shared.js.map +1 -1
- package/dist/services/policies/subaccount-policies/subaccount-policies.schemas.d.ts +9 -9
- package/dist/services/shared.js +4 -1
- package/dist/services/shared.js.map +1 -1
- package/dist/services/subaccounts/subaccounts.schemas.d.ts +5 -5
- package/dist/services/trades/trades.schemas.js +1 -1
- package/dist/services/trailing-oneof-inputs.js +1 -1
- package/dist/services/triggers/trigger-child-order.schemas.js +5 -3
- package/dist/services/triggers/trigger-child-order.schemas.js.map +1 -1
- package/dist/services/triggers/trigger-input.schemas.d.ts +37 -33
- package/dist/services/triggers/trigger-input.schemas.d.ts.map +1 -1
- package/dist/services/triggers/trigger-input.schemas.js +8 -8
- package/dist/services/triggers/trigger-input.schemas.js.map +1 -1
- package/dist/services/triggers/triggers-output.schemas.d.ts +18 -19
- package/dist/services/triggers/triggers-output.schemas.d.ts.map +1 -1
- package/dist/services/triggers/triggers-output.schemas.js +3 -3
- package/dist/services/triggers/triggers-output.schemas.js.map +1 -1
- package/dist/services/triggers/triggers.d.ts +2 -2
- package/dist/services/triggers/triggers.js +2 -2
- package/dist/services/triggers/triggers.js.map +1 -1
- package/dist/shared/decimal-surface.js +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"market-overview.schemas.js","names":["Proto.SparklineInterval"],"sources":["../../../src/services/market-overview/market-overview.schemas.ts"],"sourcesContent":["import * as Proto from \"../../gen/marketoverview/v1/marketoverview_pb.js\";\nimport * as v from \"valibot\";\nimport { tsNsToMs } from \"../../utils/time.js\";\nimport type { DecodedEnum } from \"../../utils/types.js\";\nimport { requiredEnumLabel } from \"../../shared/proto-enum-codec.js\";\nimport { scaledToDecimalOutput, type SdkScales } from \"../../shared/decimal-surface.js\";\nimport {\n SPARKLINE_INTERVAL_VALUES,\n MARKET_OVERVIEW_ORDER_BY_VALUES,\n MARKET_OVERVIEW_SORT_VALUES,\n SparklineIntervalCodec,\n MarketOverviewOrderByCodec,\n MarketOverviewSortCodec,\n} from \"./market-overview.codecs.js\";\n\nexport {\n SPARKLINE_INTERVAL_VALUES,\n MARKET_OVERVIEW_ORDER_BY_VALUES,\n MARKET_OVERVIEW_SORT_VALUES,\n} from \"./market-overview.codecs.js\";\n\nexport {\n MarketOrderBy,\n SortDirection,\n SparklineInterval,\n} from \"../../gen/marketoverview/v1/marketoverview_pb.js\";\n\nexport const SparklineIntervalSchema = v.picklist(SPARKLINE_INTERVAL_VALUES);\n\nexport type SparklineIntervalName = v.InferOutput<typeof SparklineIntervalSchema>;\n\nconst MarketOverviewSparklineRawSchema = v.object({\n interval: v.pipe(\n v.enum(Proto.SparklineInterval),\n v.transform((value) =>\n requiredEnumLabel(\n SparklineIntervalCodec.protoToOutput,\n value,\n \"MarketOverviewSparklineSchema\",\n \"interval\",\n ),\n ),\n ),\n closeTicks: v.array(v.bigint()),\n});\n\nexport type MarketOverviewSparkline = {\n interval: DecodedEnum<SparklineIntervalName>;\n close: string[];\n};\n\nexport const MarketOverviewOrderBySchema = v.picklist(MARKET_OVERVIEW_ORDER_BY_VALUES);\n\nexport type MarketOverviewOrderBy = v.InferOutput<typeof MarketOverviewOrderBySchema>;\n\nexport const MarketOverviewSortSchema = v.picklist(MARKET_OVERVIEW_SORT_VALUES);\n\nexport type MarketOverviewSort = v.InferOutput<typeof MarketOverviewSortSchema>;\n\nconst MarketOverviewRawSchema = v.object({\n symbolId:
|
|
1
|
+
{"version":3,"file":"market-overview.schemas.js","names":["Proto.SparklineInterval"],"sources":["../../../src/services/market-overview/market-overview.schemas.ts"],"sourcesContent":["import * as Proto from \"../../gen/marketoverview/v1/marketoverview_pb.js\";\nimport * as v from \"valibot\";\nimport { tsNsToMs } from \"../../utils/time.js\";\nimport type { DecodedEnum } from \"../../utils/types.js\";\nimport { requiredEnumLabel } from \"../../shared/proto-enum-codec.js\";\nimport { scaledToDecimalOutput, type SdkScales } from \"../../shared/decimal-surface.js\";\nimport { SymbolIdInputSchema } from \"../shared.js\";\nimport {\n SPARKLINE_INTERVAL_VALUES,\n MARKET_OVERVIEW_ORDER_BY_VALUES,\n MARKET_OVERVIEW_SORT_VALUES,\n SparklineIntervalCodec,\n MarketOverviewOrderByCodec,\n MarketOverviewSortCodec,\n} from \"./market-overview.codecs.js\";\n\nexport {\n SPARKLINE_INTERVAL_VALUES,\n MARKET_OVERVIEW_ORDER_BY_VALUES,\n MARKET_OVERVIEW_SORT_VALUES,\n} from \"./market-overview.codecs.js\";\n\nexport {\n MarketOrderBy,\n SortDirection,\n SparklineInterval,\n} from \"../../gen/marketoverview/v1/marketoverview_pb.js\";\n\nexport const SparklineIntervalSchema = v.picklist(SPARKLINE_INTERVAL_VALUES);\n\nexport type SparklineIntervalName = v.InferOutput<typeof SparklineIntervalSchema>;\n\nconst MarketOverviewSparklineRawSchema = v.object({\n interval: v.pipe(\n v.enum(Proto.SparklineInterval),\n v.transform((value) =>\n requiredEnumLabel(\n SparklineIntervalCodec.protoToOutput,\n value,\n \"MarketOverviewSparklineSchema\",\n \"interval\",\n ),\n ),\n ),\n closeTicks: v.array(v.bigint()),\n});\n\nexport type MarketOverviewSparkline = {\n interval: DecodedEnum<SparklineIntervalName>;\n close: string[];\n};\n\nexport const MarketOverviewOrderBySchema = v.picklist(MARKET_OVERVIEW_ORDER_BY_VALUES);\n\nexport type MarketOverviewOrderBy = v.InferOutput<typeof MarketOverviewOrderBySchema>;\n\nexport const MarketOverviewSortSchema = v.picklist(MARKET_OVERVIEW_SORT_VALUES);\n\nexport type MarketOverviewSort = v.InferOutput<typeof MarketOverviewSortSchema>;\n\nconst MarketOverviewRawSchema = v.object({\n symbolId: SymbolIdInputSchema,\n lastPriceTicks: v.bigint(),\n lastTradeTsNs: v.optional(v.bigint(), 0n),\n change24hBps: v.number(),\n high24hTicks: v.bigint(),\n low24hTicks: v.bigint(),\n volume24hBaseScaled: v.bigint(),\n volume24hQuoteScaled: v.bigint(),\n listedTsNs: v.optional(v.bigint(), 0n),\n bestBidTicks: v.bigint(),\n bestBidQtyScaled: v.bigint(),\n bestAskTicks: v.bigint(),\n bestAskQtyScaled: v.bigint(),\n sparklines: v.optional(v.array(MarketOverviewSparklineRawSchema), []),\n indexPriceTicks: v.bigint(),\n});\n\nexport function createMarketOverviewSchema(scales: SdkScales) {\n return v.pipe(\n MarketOverviewRawSchema,\n v.transform((m) => {\n const priceScale = scales.price();\n const baseQtyScale = scales.baseQty(m.symbolId);\n const quoteAmountScale = scales.quoteAmount(m.symbolId);\n return {\n symbolId: m.symbolId,\n lastPrice: scaledToDecimalOutput(m.lastPriceTicks, priceScale),\n lastTradeTsMs: tsNsToMs(m.lastTradeTsNs),\n change24hBps: m.change24hBps,\n high24h: scaledToDecimalOutput(m.high24hTicks, priceScale),\n low24h: scaledToDecimalOutput(m.low24hTicks, priceScale),\n volume24hBase: scaledToDecimalOutput(m.volume24hBaseScaled, baseQtyScale),\n volume24hQuote: scaledToDecimalOutput(m.volume24hQuoteScaled, quoteAmountScale),\n listedTsMs: tsNsToMs(m.listedTsNs),\n bestBid: scaledToDecimalOutput(m.bestBidTicks, priceScale),\n bestBidQty: scaledToDecimalOutput(m.bestBidQtyScaled, baseQtyScale),\n bestAsk: scaledToDecimalOutput(m.bestAskTicks, priceScale),\n bestAskQty: scaledToDecimalOutput(m.bestAskQtyScaled, baseQtyScale),\n indexPrice:\n m.indexPriceTicks > 0n\n ? scaledToDecimalOutput(m.indexPriceTicks, priceScale)\n : undefined,\n sparklines: (m.sparklines ?? []).map(\n (s): MarketOverviewSparkline => ({\n interval: s.interval,\n close: s.closeTicks\n .map((tick) => scaledToDecimalOutput(tick, priceScale))\n .reverse(),\n }),\n ),\n };\n }),\n );\n}\n\nexport type MarketOverview = v.InferOutput<ReturnType<typeof createMarketOverviewSchema>>;\n\nconst MS_PER_24H = 86_400_000;\n\nfunction change24hBpsFromSparklineFirstLast(sparklines: MarketOverview[\"sparklines\"]): number {\n const s = sparklines.find((e) => e.interval === \"24h\") ?? sparklines[0];\n if (!s || s.close.length < 2) return 0;\n const first = Number(s.close[0] ?? 0);\n const last = Number(s.close.at(-1) ?? 0);\n if (!Number.isFinite(first) || !Number.isFinite(last)) return 0;\n if (first === 0) return 0;\n return Math.round(((last - first) / first) * 10_000);\n}\n\n/**\n * Formats the 24-hour market change percentage for display.\n */\nexport function getMarketOverview24hChangeDisplay(\n market: Pick<MarketOverview, \"change24hBps\" | \"listedTsMs\" | \"sparklines\">,\n nowMs: number = Date.now(),\n): { change24hBps: number; showNewListingSparklineInfo: boolean } {\n const api = market.change24hBps;\n const newish = api === 0 && market.listedTsMs > 0 && nowMs - market.listedTsMs < MS_PER_24H;\n if (!newish) {\n return { change24hBps: api, showNewListingSparklineInfo: false };\n }\n return {\n change24hBps: change24hBpsFromSparklineFirstLast(market.sparklines),\n showNewListingSparklineInfo: true,\n };\n}\n\nexport type MarketOverviewBatch = {\n markets: MarketOverview[];\n tsNs: bigint;\n};\n\nexport const ListMarketOverviewInputSchema = v.pipe(\n v.strictObject({\n symbolIds: v.optional(v.array(SymbolIdInputSchema), []),\n limit: v.optional(v.pipe(v.number(), v.integer(), v.gtValue(0)), 500),\n pageToken: v.optional(v.pipe(v.string(), v.trim()), \"\"),\n orderBy: v.pipe(\n v.optional(MarketOverviewOrderBySchema, \"volume_24h_quote\"),\n v.transform((v) => MarketOverviewOrderByCodec.inputToProto[v ?? \"volume_24h_quote\"]),\n ),\n sort: v.pipe(\n v.optional(MarketOverviewSortSchema, \"desc\"),\n v.transform((v) => MarketOverviewSortCodec.inputToProto[v ?? \"desc\"]),\n ),\n includeSparklines: v.optional(v.boolean(), true),\n sparklineIntervals: v.pipe(\n v.optional(v.array(SparklineIntervalSchema), [\"24h\"]),\n v.transform((intervals) =>\n (intervals ?? [\"24h\"]).map((v) => SparklineIntervalCodec.inputToProto[v]),\n ),\n ),\n }),\n v.transform(({ symbolIds, ...input }) => ({ symbolId: symbolIds, ...input })),\n);\n\nexport type ListMarketOverviewInput = v.InferInput<typeof ListMarketOverviewInputSchema>;\n"],"mappings":"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"}
|
|
@@ -7,7 +7,6 @@ import { Transport } from "@connectrpc/connect";
|
|
|
7
7
|
import * as v from "valibot";
|
|
8
8
|
//#region src/services/orderbook/orderbook.d.ts
|
|
9
9
|
interface SubscribeOrderbookInput extends BaseSubscribeInput<OrderbookData> {
|
|
10
|
-
symbol: string;
|
|
11
10
|
symbolId: number;
|
|
12
11
|
depth?: number;
|
|
13
12
|
bucket?: string | null;
|
|
@@ -17,7 +16,7 @@ interface OrderbookSubscription {
|
|
|
17
16
|
unsubscribe: () => void;
|
|
18
17
|
setBucket: (bucket: string | null | undefined) => void;
|
|
19
18
|
}
|
|
20
|
-
interface CreateOrderbookSubscriptionInput extends OrderbookStreamHandlers, Pick<SubscribeOrderbookInput, "
|
|
19
|
+
interface CreateOrderbookSubscriptionInput extends OrderbookStreamHandlers, Pick<SubscribeOrderbookInput, "symbolId" | "depth" | "bucket"> {}
|
|
21
20
|
/**
|
|
22
21
|
* Reads spot order book snapshots and maintains realtime local order book state from public delta channels.
|
|
23
22
|
*/
|
|
@@ -25,11 +24,11 @@ declare class OrderbookService {
|
|
|
25
24
|
#private;
|
|
26
25
|
constructor(transport: Transport, realtime: PolyesterRealtime, scales: SdkScales);
|
|
27
26
|
/**
|
|
28
|
-
* Fetches a spot order book depth snapshot for a symbol and requested depth, returning best bids and asks with the backend book sequence.
|
|
27
|
+
* Fetches a spot order book depth snapshot for a symbol ID and requested depth, returning best bids and asks with the backend book sequence.
|
|
29
28
|
*/
|
|
30
29
|
get(input: v.InferInput<typeof GetOrderbookInputSchema>, options?: PolyesterRequestOptions): Promise<OrderbookData>;
|
|
31
30
|
/**
|
|
32
|
-
* Subscribes to the managed order book stream for a symbol and forwards reconstructed snapshots to onEvent. This is a convenience wrapper around createSubscription().unsubscribe.
|
|
31
|
+
* 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.
|
|
33
32
|
*/
|
|
34
33
|
subscribe(input: SubscribeOrderbookInput): () => void;
|
|
35
34
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orderbook.d.ts","names":[],"sources":["../../../src/services/orderbook/orderbook.ts"],"mappings":";;;;;;;;UAgCU,gCAAgC,mBAAmB;EACzD;EACA;EACA
|
|
1
|
+
{"version":3,"file":"orderbook.d.ts","names":[],"sources":["../../../src/services/orderbook/orderbook.ts"],"mappings":";;;;;;;;UAgCU,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"}
|
|
@@ -10,7 +10,6 @@ import { GetOrderbookInputSchema, createOrderbookDataSchema, formatOrderbookLeve
|
|
|
10
10
|
import { toBig } from "../../utils/u128.js";
|
|
11
11
|
import { create } from "@bufbuild/protobuf";
|
|
12
12
|
import { createClient } from "@connectrpc/connect";
|
|
13
|
-
import * as v from "valibot";
|
|
14
13
|
//#region src/services/orderbook/orderbook.ts
|
|
15
14
|
/**
|
|
16
15
|
* Reads spot order book snapshots and maintains realtime local order book state from public delta channels.
|
|
@@ -25,17 +24,17 @@ var OrderbookService = class {
|
|
|
25
24
|
this.#scales = scales;
|
|
26
25
|
}
|
|
27
26
|
/**
|
|
28
|
-
* Fetches a spot order book depth snapshot for a symbol and requested depth, returning best bids and asks with the backend book sequence.
|
|
27
|
+
* Fetches a spot order book depth snapshot for a symbol ID and requested depth, returning best bids and asks with the backend book sequence.
|
|
29
28
|
*/
|
|
30
29
|
async get(input, options) {
|
|
31
30
|
const validated = parse(GetOrderbookInputSchema, input);
|
|
32
31
|
await this.#scales.ready();
|
|
33
32
|
const res = await this.#client.getOrderBook({
|
|
34
|
-
|
|
33
|
+
symbolId: validated.symbolId,
|
|
35
34
|
depth: validated.protoDepth
|
|
36
35
|
}, toConnectCallOptions(options));
|
|
37
|
-
return parse(createOrderbookDataSchema(this.#scales, validated.
|
|
38
|
-
|
|
36
|
+
return parse(createOrderbookDataSchema(this.#scales, validated.symbolId), {
|
|
37
|
+
symbolId: res.symbolId,
|
|
39
38
|
depth: validated.depth,
|
|
40
39
|
bookSeq: res.bookSeq,
|
|
41
40
|
bids: res.bids,
|
|
@@ -43,7 +42,7 @@ var OrderbookService = class {
|
|
|
43
42
|
});
|
|
44
43
|
}
|
|
45
44
|
/**
|
|
46
|
-
* Subscribes to the managed order book stream for a symbol and forwards reconstructed snapshots to onEvent. This is a convenience wrapper around createSubscription().unsubscribe.
|
|
45
|
+
* 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.
|
|
47
46
|
*/
|
|
48
47
|
subscribe(input) {
|
|
49
48
|
return this.createSubscription(input).unsubscribe;
|
|
@@ -56,7 +55,10 @@ var OrderbookService = class {
|
|
|
56
55
|
* 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.
|
|
57
56
|
*/
|
|
58
57
|
createSubscription(input) {
|
|
59
|
-
const symbolId = parse(
|
|
58
|
+
const { symbolId } = parse(GetOrderbookInputSchema, {
|
|
59
|
+
symbolId: input.symbolId,
|
|
60
|
+
depth: input.depth
|
|
61
|
+
});
|
|
60
62
|
const requestedDepth = Math.min(500, Math.max(1, Math.trunc(input.depth ?? 50)));
|
|
61
63
|
const channelDepth = orderbookWsChannelDepth(requestedDepth);
|
|
62
64
|
const channel = `public:spot:orderbook:deltas:depth:${channelDepth}:${symbolId}:proto`;
|
|
@@ -104,7 +106,7 @@ var OrderbookService = class {
|
|
|
104
106
|
function emit() {
|
|
105
107
|
gate.run(() => {
|
|
106
108
|
input.onEvent({
|
|
107
|
-
|
|
109
|
+
symbolId,
|
|
108
110
|
depth: requestedDepth,
|
|
109
111
|
bookSeq: currentBookSeq.toString(),
|
|
110
112
|
bids: sideToUIBucketed(bidsMap, "bids", requestedDepth, bucketTicks),
|
|
@@ -123,17 +125,18 @@ var OrderbookService = class {
|
|
|
123
125
|
}
|
|
124
126
|
async function inputServiceFetch() {
|
|
125
127
|
const validated = parse(GetOrderbookInputSchema, {
|
|
126
|
-
|
|
128
|
+
symbolId,
|
|
127
129
|
depth: channelDepth
|
|
128
130
|
});
|
|
129
131
|
try {
|
|
130
132
|
return await client.getOrderBook({
|
|
131
|
-
|
|
133
|
+
symbolId: validated.symbolId,
|
|
132
134
|
depth: validated.protoDepth
|
|
133
135
|
});
|
|
134
136
|
} catch (error) {
|
|
135
137
|
if (!isResourceNotFoundError(error)) throw error;
|
|
136
138
|
return create(GetOrderBookResponseSchema, {
|
|
139
|
+
symbolId,
|
|
137
140
|
bookSeq: 0n,
|
|
138
141
|
bids: [],
|
|
139
142
|
asks: []
|
|
@@ -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 * as v from \"valibot\";\nimport { parse } from \"../../shared/validation.js\";\n\ninterface SubscribeOrderbookInput extends BaseSubscribeInput<OrderbookData> {\n symbol: string;\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, \"symbol\" | \"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 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 { symbol: validated.symbol, depth: validated.protoDepth },\n toConnectCallOptions(options),\n );\n return parse(createOrderbookDataSchema(this.#scales, validated.symbol), {\n symbol: validated.symbol,\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 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(v.pipe(v.number(), v.integer(), v.gtValue(0)), input.symbolId);\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 symbol: input.symbol,\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 symbol: input.symbol,\n depth: channelDepth,\n });\n try {\n return await client.getOrderBook({\n symbol: validated.symbol,\n depth: validated.protoDepth,\n });\n } catch (error: unknown) {\n if (!isResourceNotFoundError(error)) throw error;\n\n return create(Proto.GetOrderBookResponseSchema, {\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 {\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,16 +1,15 @@
|
|
|
1
|
-
import { PairCatalogKey } from "../../catalogs/types.js";
|
|
2
1
|
import { Depth } from "../../gen/orderbook/v1/orderbook_pb.js";
|
|
3
2
|
import { SdkScales } from "../../shared/decimal-surface.js";
|
|
4
3
|
import * as v from "valibot";
|
|
5
4
|
//#region src/services/orderbook/orderbook.schemas.d.ts
|
|
6
5
|
declare const GetOrderbookInputSchema: v.SchemaWithPipe<readonly [v.ObjectSchema<{
|
|
7
|
-
readonly
|
|
6
|
+
readonly symbolId: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.GtValueAction<number, 0, undefined>, v.MaxValueAction<number, 4294967295, undefined>]>;
|
|
8
7
|
readonly depth: v.OptionalSchema<v.NumberSchema<undefined>, 50>;
|
|
9
8
|
}, undefined>, v.TransformAction<{
|
|
10
|
-
|
|
9
|
+
symbolId: number;
|
|
11
10
|
depth: number;
|
|
12
11
|
}, {
|
|
13
|
-
|
|
12
|
+
symbolId: number;
|
|
14
13
|
depth: 5 | 10 | 20 | 1 | 200 | 1000 | 500 | 100 | 50;
|
|
15
14
|
protoDepth: Depth;
|
|
16
15
|
}>]>;
|
|
@@ -20,13 +19,13 @@ declare const OrderbookLevelInputSchema: v.ObjectSchema<{
|
|
|
20
19
|
readonly qtyScaled: v.BigintSchema<undefined>;
|
|
21
20
|
}, undefined>;
|
|
22
21
|
type OrderbookLevelInput = v.InferOutput<typeof OrderbookLevelInputSchema>;
|
|
23
|
-
declare function formatOrderbookLevel(level: OrderbookLevelInput, scales: SdkScales,
|
|
22
|
+
declare function formatOrderbookLevel(level: OrderbookLevelInput, scales: SdkScales, symbolId: number): {
|
|
24
23
|
price: string;
|
|
25
24
|
qty: string;
|
|
26
25
|
};
|
|
27
26
|
type OrderbookLevel = ReturnType<typeof formatOrderbookLevel>;
|
|
28
|
-
declare function createOrderbookDataSchema(scales: SdkScales,
|
|
29
|
-
readonly
|
|
27
|
+
declare function createOrderbookDataSchema(scales: SdkScales, symbolId: number): v.SchemaWithPipe<readonly [v.ObjectSchema<{
|
|
28
|
+
readonly symbolId: v.LiteralSchema<number, undefined>;
|
|
30
29
|
readonly depth: v.NumberSchema<undefined>;
|
|
31
30
|
readonly bookSeq: v.BigintSchema<undefined>;
|
|
32
31
|
readonly bids: v.ArraySchema<v.ObjectSchema<{
|
|
@@ -38,7 +37,7 @@ declare function createOrderbookDataSchema(scales: SdkScales, pair: PairCatalogK
|
|
|
38
37
|
readonly qtyScaled: v.BigintSchema<undefined>;
|
|
39
38
|
}, undefined>, undefined>;
|
|
40
39
|
}, undefined>, v.TransformAction<{
|
|
41
|
-
|
|
40
|
+
symbolId: number;
|
|
42
41
|
depth: number;
|
|
43
42
|
bookSeq: bigint;
|
|
44
43
|
bids: {
|
|
@@ -59,7 +58,7 @@ declare function createOrderbookDataSchema(scales: SdkScales, pair: PairCatalogK
|
|
|
59
58
|
price: string;
|
|
60
59
|
qty: string;
|
|
61
60
|
}[];
|
|
62
|
-
|
|
61
|
+
symbolId: number;
|
|
63
62
|
depth: number;
|
|
64
63
|
}>]>;
|
|
65
64
|
type OrderbookData = v.InferOutput<ReturnType<typeof createOrderbookDataSchema>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orderbook.schemas.d.ts","names":[],"sources":["../../../src/services/orderbook/orderbook.schemas.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"orderbook.schemas.d.ts","names":[],"sources":["../../../src/services/orderbook/orderbook.schemas.ts"],"mappings":";;;;cAKa,yBAAuB,EAAA,yBAAA,EAAA;;;;;;;;;cAAA;;KAexB,oBAAoB,EAAE,kBAAkB;cAE9C,2BAAyB,EAAA;;;;KAKnB,sBAAsB,EAAE,mBAAmB;iBAEvC,qBACZ,OAAO,qBACP,QAAQ,WACR;;;;KAQQ,iBAAiB,kBAAkB;iBAE/B,0BAA0B,QAAQ,WAAW,mBAAgB,EAAA,yBAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAkBjE,gBAAgB,EAAE,YAAY,kBAAkB"}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
+
import { SymbolIdInputSchema } from "../shared.js";
|
|
1
2
|
import { scaledToDecimalOutput } from "../../shared/decimal-surface.js";
|
|
2
3
|
import { normalizeOrderbookDepth } from "./orderbook.codecs.js";
|
|
3
4
|
import * as v from "valibot";
|
|
4
5
|
//#region src/services/orderbook/orderbook.schemas.ts
|
|
5
6
|
const GetOrderbookInputSchema = v.pipe(v.object({
|
|
6
|
-
|
|
7
|
+
symbolId: SymbolIdInputSchema,
|
|
7
8
|
depth: v.optional(v.number(), 50)
|
|
8
9
|
}), v.transform((input) => {
|
|
9
10
|
const depth = normalizeOrderbookDepth(input.depth);
|
|
10
11
|
return {
|
|
11
|
-
|
|
12
|
+
symbolId: input.symbolId,
|
|
12
13
|
depth: depth.levels,
|
|
13
14
|
protoDepth: depth.protoDepth
|
|
14
15
|
};
|
|
@@ -17,15 +18,15 @@ const OrderbookLevelInputSchema = v.object({
|
|
|
17
18
|
priceTicks: v.bigint(),
|
|
18
19
|
qtyScaled: v.bigint()
|
|
19
20
|
});
|
|
20
|
-
function formatOrderbookLevel(level, scales,
|
|
21
|
+
function formatOrderbookLevel(level, scales, symbolId) {
|
|
21
22
|
return {
|
|
22
23
|
price: scaledToDecimalOutput(level.priceTicks, scales.price()),
|
|
23
|
-
qty: scaledToDecimalOutput(level.qtyScaled, scales.baseQty(
|
|
24
|
+
qty: scaledToDecimalOutput(level.qtyScaled, scales.baseQty(symbolId))
|
|
24
25
|
};
|
|
25
26
|
}
|
|
26
|
-
function createOrderbookDataSchema(scales,
|
|
27
|
+
function createOrderbookDataSchema(scales, symbolId) {
|
|
27
28
|
return v.pipe(v.object({
|
|
28
|
-
|
|
29
|
+
symbolId: v.literal(symbolId),
|
|
29
30
|
depth: v.number(),
|
|
30
31
|
bookSeq: v.bigint(),
|
|
31
32
|
bids: v.array(OrderbookLevelInputSchema),
|
|
@@ -33,8 +34,8 @@ function createOrderbookDataSchema(scales, pair) {
|
|
|
33
34
|
}), v.transform((d) => ({
|
|
34
35
|
...d,
|
|
35
36
|
bookSeq: d.bookSeq.toString(),
|
|
36
|
-
bids: d.bids.map((level) => formatOrderbookLevel(level, scales,
|
|
37
|
-
asks: d.asks.map((level) => formatOrderbookLevel(level, scales,
|
|
37
|
+
bids: d.bids.map((level) => formatOrderbookLevel(level, scales, symbolId)),
|
|
38
|
+
asks: d.asks.map((level) => formatOrderbookLevel(level, scales, symbolId))
|
|
38
39
|
})));
|
|
39
40
|
}
|
|
40
41
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orderbook.schemas.js","names":[],"sources":["../../../src/services/orderbook/orderbook.schemas.ts"],"sourcesContent":["import * as v from \"valibot\";\nimport type
|
|
1
|
+
{"version":3,"file":"orderbook.schemas.js","names":[],"sources":["../../../src/services/orderbook/orderbook.schemas.ts"],"sourcesContent":["import * as v from \"valibot\";\nimport { scaledToDecimalOutput, type SdkScales } from \"../../shared/decimal-surface.js\";\nimport { SymbolIdInputSchema } from \"../shared.js\";\nimport { normalizeOrderbookDepth } from \"./orderbook.codecs.js\";\n\nexport const GetOrderbookInputSchema = v.pipe(\n v.object({\n symbolId: SymbolIdInputSchema,\n depth: v.optional(v.number(), 50),\n }),\n v.transform((input) => {\n const depth = normalizeOrderbookDepth(input.depth);\n return {\n symbolId: input.symbolId,\n depth: depth.levels,\n protoDepth: depth.protoDepth,\n };\n }),\n);\n\nexport type GetOrderbookInput = v.InferInput<typeof GetOrderbookInputSchema>;\n\nconst OrderbookLevelInputSchema = v.object({\n priceTicks: v.bigint(),\n qtyScaled: v.bigint(),\n});\n\nexport type OrderbookLevelInput = v.InferOutput<typeof OrderbookLevelInputSchema>;\n\nexport function formatOrderbookLevel(\n level: OrderbookLevelInput,\n scales: SdkScales,\n symbolId: number,\n) {\n return {\n price: scaledToDecimalOutput(level.priceTicks, scales.price()),\n qty: scaledToDecimalOutput(level.qtyScaled, scales.baseQty(symbolId)),\n };\n}\n\nexport type OrderbookLevel = ReturnType<typeof formatOrderbookLevel>;\n\nexport function createOrderbookDataSchema(scales: SdkScales, symbolId: number) {\n return v.pipe(\n v.object({\n symbolId: v.literal(symbolId),\n depth: v.number(),\n bookSeq: v.bigint(),\n bids: v.array(OrderbookLevelInputSchema),\n asks: v.array(OrderbookLevelInputSchema),\n }),\n v.transform((d) => ({\n ...d,\n bookSeq: d.bookSeq.toString(),\n bids: d.bids.map((level) => formatOrderbookLevel(level, scales, symbolId)),\n asks: d.asks.map((level) => formatOrderbookLevel(level, scales, symbolId)),\n })),\n );\n}\n\nexport type OrderbookData = v.InferOutput<ReturnType<typeof createOrderbookDataSchema>>;\n"],"mappings":";;;;;AAKA,MAAa,0BAA0B,EAAE,KACrC,EAAE,OAAO;CACL,UAAU;CACV,OAAO,EAAE,SAAS,EAAE,OAAO,GAAG,EAAE;AACpC,CAAC,GACD,EAAE,WAAW,UAAU;CACnB,MAAM,QAAQ,wBAAwB,MAAM,KAAK;CACjD,OAAO;EACH,UAAU,MAAM;EAChB,OAAO,MAAM;EACb,YAAY,MAAM;CACtB;AACJ,CAAC,CACL;AAIA,MAAM,4BAA4B,EAAE,OAAO;CACvC,YAAY,EAAE,OAAO;CACrB,WAAW,EAAE,OAAO;AACxB,CAAC;AAID,SAAgB,qBACZ,OACA,QACA,UACF;CACE,OAAO;EACH,OAAO,sBAAsB,MAAM,YAAY,OAAO,MAAM,CAAC;EAC7D,KAAK,sBAAsB,MAAM,WAAW,OAAO,QAAQ,QAAQ,CAAC;CACxE;AACJ;AAIA,SAAgB,0BAA0B,QAAmB,UAAkB;CAC3E,OAAO,EAAE,KACL,EAAE,OAAO;EACL,UAAU,EAAE,QAAQ,QAAQ;EAC5B,OAAO,EAAE,OAAO;EAChB,SAAS,EAAE,OAAO;EAClB,MAAM,EAAE,MAAM,yBAAyB;EACvC,MAAM,EAAE,MAAM,yBAAyB;CAC3C,CAAC,GACD,EAAE,WAAW,OAAO;EAChB,GAAG;EACH,SAAS,EAAE,QAAQ,SAAS;EAC5B,MAAM,EAAE,KAAK,KAAK,UAAU,qBAAqB,OAAO,QAAQ,QAAQ,CAAC;EACzE,MAAM,EAAE,KAAK,KAAK,UAAU,qBAAqB,OAAO,QAAQ,QAAQ,CAAC;CAC7E,EAAE,CACN;AACJ"}
|
|
@@ -8,7 +8,7 @@ import * as v from "valibot";
|
|
|
8
8
|
//#region src/services/orders/orders-batch.schemas.d.ts
|
|
9
9
|
declare const CancelAllAfterInputSchema: v.SchemaWithPipe<readonly [v.StrictObjectSchema<{
|
|
10
10
|
readonly timeoutSec: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.CheckAction<number, "timeoutSec must be 0 to disable or between 10 and 120 seconds to arm">]>;
|
|
11
|
-
readonly
|
|
11
|
+
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>;
|
|
12
12
|
readonly side: v.SchemaWithPipe<readonly [v.OptionalSchema<v.PicklistSchema<["buy", "sell"], undefined>, undefined>, v.TransformAction<"buy" | "sell" | undefined, Side.BUY | Side.SELL | undefined>]>;
|
|
13
13
|
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>;
|
|
14
14
|
readonly account: v.OptionalSchema<v.UnionSchema<[v.PicklistSchema<["active", "main"], undefined>, v.StrictObjectSchema<{
|
|
@@ -16,7 +16,7 @@ declare const CancelAllAfterInputSchema: v.SchemaWithPipe<readonly [v.StrictObje
|
|
|
16
16
|
}, undefined>], undefined>, undefined>;
|
|
17
17
|
}, undefined>, v.TransformAction<{
|
|
18
18
|
timeoutSec: number;
|
|
19
|
-
|
|
19
|
+
symbolId?: number | undefined;
|
|
20
20
|
side?: Side.BUY | Side.SELL | undefined;
|
|
21
21
|
requestId?: string | undefined;
|
|
22
22
|
account?: "active" | "main" | {
|
|
@@ -25,7 +25,7 @@ declare const CancelAllAfterInputSchema: v.SchemaWithPipe<readonly [v.StrictObje
|
|
|
25
25
|
}, {
|
|
26
26
|
subaccountId: bigint | undefined;
|
|
27
27
|
timeoutSec: number;
|
|
28
|
-
|
|
28
|
+
symbolId?: number | undefined;
|
|
29
29
|
side?: Side.BUY | Side.SELL | undefined;
|
|
30
30
|
requestId?: string | undefined;
|
|
31
31
|
}>]>;
|
|
@@ -54,7 +54,7 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
54
54
|
readonly items: v.SchemaWithPipe<readonly [v.ArraySchema<v.SchemaWithPipe<readonly [v.SchemaWithPipe<readonly [v.UnionSchema<[v.StrictObjectSchema<{
|
|
55
55
|
readonly qty: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>]>;
|
|
56
56
|
readonly maxQuoteDebit: v.OptionalSchema<v.NeverSchema<undefined>, undefined>;
|
|
57
|
-
readonly
|
|
57
|
+
readonly symbolId: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.GtValueAction<number, 0, undefined>, v.MaxValueAction<number, 4294967295, undefined>]>;
|
|
58
58
|
readonly side: v.SchemaWithPipe<readonly [v.PicklistSchema<["buy", "sell"], undefined>, v.TransformAction<"buy" | "sell", Side.BUY | Side.SELL>]>;
|
|
59
59
|
readonly execution: v.VariantSchema<"type", [v.SchemaWithPipe<readonly [v.StrictObjectSchema<{
|
|
60
60
|
readonly type: v.LiteralSchema<"market_ioc", undefined>;
|
|
@@ -585,7 +585,7 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
585
585
|
}, undefined>, v.StrictObjectSchema<{
|
|
586
586
|
readonly qty: v.OptionalSchema<v.NeverSchema<undefined>, undefined>;
|
|
587
587
|
readonly maxQuoteDebit: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>]>;
|
|
588
|
-
readonly
|
|
588
|
+
readonly symbolId: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.GtValueAction<number, 0, undefined>, v.MaxValueAction<number, 4294967295, undefined>]>;
|
|
589
589
|
readonly side: v.SchemaWithPipe<readonly [v.PicklistSchema<["buy", "sell"], undefined>, v.TransformAction<"buy" | "sell", Side.BUY | Side.SELL>]>;
|
|
590
590
|
readonly execution: v.VariantSchema<"type", [v.SchemaWithPipe<readonly [v.StrictObjectSchema<{
|
|
591
591
|
readonly type: v.LiteralSchema<"market_ioc", undefined>;
|
|
@@ -1116,7 +1116,7 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
1116
1116
|
}, undefined>], undefined>, v.CheckAction<{
|
|
1117
1117
|
qty: string;
|
|
1118
1118
|
maxQuoteDebit?: undefined;
|
|
1119
|
-
|
|
1119
|
+
symbolId: number;
|
|
1120
1120
|
side: Side.BUY | Side.SELL;
|
|
1121
1121
|
execution: {
|
|
1122
1122
|
case: "marketIoc";
|
|
@@ -1195,7 +1195,7 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
1195
1195
|
} | {
|
|
1196
1196
|
qty?: undefined;
|
|
1197
1197
|
maxQuoteDebit: string;
|
|
1198
|
-
|
|
1198
|
+
symbolId: number;
|
|
1199
1199
|
side: Side.BUY | Side.SELL;
|
|
1200
1200
|
execution: {
|
|
1201
1201
|
case: "marketIoc";
|
|
@@ -1274,7 +1274,7 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
1274
1274
|
}, "maxQuoteDebit is supported only for BUY market IOC and BUY limit IOC orders">, v.CheckAction<{
|
|
1275
1275
|
qty: string;
|
|
1276
1276
|
maxQuoteDebit?: undefined;
|
|
1277
|
-
|
|
1277
|
+
symbolId: number;
|
|
1278
1278
|
side: Side.BUY | Side.SELL;
|
|
1279
1279
|
execution: {
|
|
1280
1280
|
case: "marketIoc";
|
|
@@ -1353,7 +1353,7 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
1353
1353
|
} | {
|
|
1354
1354
|
qty?: undefined;
|
|
1355
1355
|
maxQuoteDebit: string;
|
|
1356
|
-
|
|
1356
|
+
symbolId: number;
|
|
1357
1357
|
side: Side.BUY | Side.SELL;
|
|
1358
1358
|
execution: {
|
|
1359
1359
|
case: "marketIoc";
|
|
@@ -1432,7 +1432,7 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
1432
1432
|
}, "SELL orders must use the quote fee asset">]>, v.TransformAction<{
|
|
1433
1433
|
qty: string;
|
|
1434
1434
|
maxQuoteDebit?: undefined;
|
|
1435
|
-
|
|
1435
|
+
symbolId: number;
|
|
1436
1436
|
side: Side.BUY | Side.SELL;
|
|
1437
1437
|
execution: {
|
|
1438
1438
|
case: "marketIoc";
|
|
@@ -1511,7 +1511,7 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
1511
1511
|
} | {
|
|
1512
1512
|
qty?: undefined;
|
|
1513
1513
|
maxQuoteDebit: string;
|
|
1514
|
-
|
|
1514
|
+
symbolId: number;
|
|
1515
1515
|
side: Side.BUY | Side.SELL;
|
|
1516
1516
|
execution: {
|
|
1517
1517
|
case: "marketIoc";
|
|
@@ -1654,7 +1654,7 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
1654
1654
|
};
|
|
1655
1655
|
oco: boolean;
|
|
1656
1656
|
} | undefined;
|
|
1657
|
-
|
|
1657
|
+
symbolId: number;
|
|
1658
1658
|
side: Side.BUY | Side.SELL;
|
|
1659
1659
|
execution: {
|
|
1660
1660
|
case: "marketIoc";
|
|
@@ -1738,7 +1738,7 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
1738
1738
|
};
|
|
1739
1739
|
oco: boolean;
|
|
1740
1740
|
} | undefined;
|
|
1741
|
-
|
|
1741
|
+
symbolId: number;
|
|
1742
1742
|
side: Side.BUY | Side.SELL;
|
|
1743
1743
|
execution: {
|
|
1744
1744
|
case: "marketIoc";
|
|
@@ -1822,7 +1822,7 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
1822
1822
|
};
|
|
1823
1823
|
oco: boolean;
|
|
1824
1824
|
} | undefined;
|
|
1825
|
-
|
|
1825
|
+
symbolId: number;
|
|
1826
1826
|
side: Side.BUY | Side.SELL;
|
|
1827
1827
|
execution: {
|
|
1828
1828
|
case: "marketIoc";
|
|
@@ -1906,7 +1906,7 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
1906
1906
|
};
|
|
1907
1907
|
oco: boolean;
|
|
1908
1908
|
} | undefined;
|
|
1909
|
-
|
|
1909
|
+
symbolId: number;
|
|
1910
1910
|
side: Side.BUY | Side.SELL;
|
|
1911
1911
|
execution: {
|
|
1912
1912
|
case: "marketIoc";
|
|
@@ -1990,7 +1990,7 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
1990
1990
|
};
|
|
1991
1991
|
oco: boolean;
|
|
1992
1992
|
} | undefined;
|
|
1993
|
-
|
|
1993
|
+
symbolId: number;
|
|
1994
1994
|
side: Side.BUY | Side.SELL;
|
|
1995
1995
|
execution: {
|
|
1996
1996
|
case: "marketIoc";
|
|
@@ -2074,7 +2074,7 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
2074
2074
|
};
|
|
2075
2075
|
oco: boolean;
|
|
2076
2076
|
} | undefined;
|
|
2077
|
-
|
|
2077
|
+
symbolId: number;
|
|
2078
2078
|
side: Side.BUY | Side.SELL;
|
|
2079
2079
|
execution: {
|
|
2080
2080
|
case: "marketIoc";
|
|
@@ -2164,7 +2164,7 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
2164
2164
|
};
|
|
2165
2165
|
oco: boolean;
|
|
2166
2166
|
} | undefined;
|
|
2167
|
-
|
|
2167
|
+
symbolId: number;
|
|
2168
2168
|
side: Side.BUY | Side.SELL;
|
|
2169
2169
|
execution: {
|
|
2170
2170
|
case: "marketIoc";
|
|
@@ -2248,7 +2248,7 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
2248
2248
|
};
|
|
2249
2249
|
oco: boolean;
|
|
2250
2250
|
} | undefined;
|
|
2251
|
-
|
|
2251
|
+
symbolId: number;
|
|
2252
2252
|
side: Side.BUY | Side.SELL;
|
|
2253
2253
|
execution: {
|
|
2254
2254
|
case: "marketIoc";
|
|
@@ -2339,7 +2339,7 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
2339
2339
|
};
|
|
2340
2340
|
oco: boolean;
|
|
2341
2341
|
} | undefined;
|
|
2342
|
-
|
|
2342
|
+
symbolId: number;
|
|
2343
2343
|
side: Side.BUY | Side.SELL;
|
|
2344
2344
|
execution: {
|
|
2345
2345
|
case: "marketIoc";
|
|
@@ -2423,7 +2423,7 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
2423
2423
|
};
|
|
2424
2424
|
oco: boolean;
|
|
2425
2425
|
} | undefined;
|
|
2426
|
-
|
|
2426
|
+
symbolId: number;
|
|
2427
2427
|
side: Side.BUY | Side.SELL;
|
|
2428
2428
|
execution: {
|
|
2429
2429
|
case: "marketIoc";
|
|
@@ -2443,7 +2443,7 @@ declare function createBatchCreateOrdersInputSchema(scales: SdkScales): v.Schema
|
|
|
2443
2443
|
})[];
|
|
2444
2444
|
}>]>;
|
|
2445
2445
|
type BatchCreateOrdersInput = v.InferInput<ReturnType<typeof createBatchCreateOrdersInputSchema>>;
|
|
2446
|
-
declare function createBatchCreateOrdersResultSchema(scales: SdkScales,
|
|
2446
|
+
declare function createBatchCreateOrdersResultSchema(scales: SdkScales, symbolIds: number[]): v.SchemaWithPipe<readonly [v.ObjectSchema<{
|
|
2447
2447
|
readonly results: v.ArraySchema<v.ObjectSchema<{
|
|
2448
2448
|
readonly clientOrderId: v.StringSchema<undefined>;
|
|
2449
2449
|
readonly outcome: v.VariantSchema<"case", [v.ObjectSchema<{
|
|
@@ -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":";;;;;;;;cAsDa,2BAAyB,EAAA,yBAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;KAc1B,sBAAsB,EAAE,kBAAkB;cAEzC,4BAA0B,EAAA,yBAAA,EAAA;;;;;;;;;;;;;;;;;;KAgB3B,uBAAuB,EAAE,mBAAmB;iBAExC,mCAAmC,QAAQ,YAAS,EAAA,yBAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAkBxD,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;;;;;;;;;;;;;;;;;;;;;;;KAsBrB,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"}
|