@pear-protocol/types 1.5.0 → 1.7.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.
@@ -1,15 +1,33 @@
1
1
  import { z } from 'zod';
2
+ import { CursorResponse } from '../common';
3
+ import { AutoRebalanceConfig, RebalanceEvent } from './entities';
2
4
 
3
- const RebalanceManuallyResponse = z.object({
4
- plan: z.union([
5
+ const RebalanceManualResponse = z.object({
6
+ plan: z.discriminatedUnion("outcome", [
5
7
  z.object({
6
8
  outcome: z.literal("full_rebalance")
7
9
  }),
8
10
  z.object({
9
- outcome: z.union([z.literal("partial_rebalance"), z.literal("no_rebalance")]),
11
+ outcome: z.literal("partial_rebalance"),
12
+ messages: z.tuple([z.string()]).rest(z.string())
13
+ }),
14
+ z.object({
15
+ outcome: z.literal("no_rebalance"),
16
+ messages: z.tuple([z.string()]).rest(z.string())
17
+ }),
18
+ // `failed` only occurs on background runs (dispatch/cron); MANUAL execution errors throw and surface as HTTP errors instead.
19
+ z.object({
20
+ outcome: z.literal("failed"),
10
21
  messages: z.tuple([z.string()]).rest(z.string())
11
22
  })
12
23
  ])
13
24
  });
25
+ const AutoRebalanceListResponse = CursorResponse.extend({
26
+ items: z.array(AutoRebalanceConfig)
27
+ });
28
+ const CreateAutoRebalanceResponse = z.object({ config: AutoRebalanceConfig });
29
+ const RebalanceEventListResponse = CursorResponse.extend({
30
+ items: z.array(RebalanceEvent)
31
+ });
14
32
 
15
- export { RebalanceManuallyResponse };
33
+ export { AutoRebalanceListResponse, CreateAutoRebalanceResponse, RebalanceEventListResponse, RebalanceManualResponse };
@@ -114,6 +114,7 @@ declare const BaseSchedule: z.ZodObject<{
114
114
  }>;
115
115
  reduceOnly: z.ZodBoolean;
116
116
  isExternal: z.ZodBoolean;
117
+ synthetic: z.ZodBoolean;
117
118
  quantity: z.ZodString;
118
119
  price: z.ZodString;
119
120
  usd: z.ZodString;
@@ -183,6 +184,7 @@ export declare const TWAPOpen: z.ZodObject<{
183
184
  }>;
184
185
  reduceOnly: z.ZodBoolean;
185
186
  isExternal: z.ZodBoolean;
187
+ synthetic: z.ZodBoolean;
186
188
  quantity: z.ZodString;
187
189
  price: z.ZodString;
188
190
  usd: z.ZodString;
@@ -269,6 +271,7 @@ export declare const TWAPClose: z.ZodObject<{
269
271
  }>;
270
272
  reduceOnly: z.ZodBoolean;
271
273
  isExternal: z.ZodBoolean;
274
+ synthetic: z.ZodBoolean;
272
275
  quantity: z.ZodString;
273
276
  price: z.ZodString;
274
277
  usd: z.ZodString;
@@ -347,6 +350,7 @@ export declare const Schedule: z.ZodDiscriminatedUnion<[z.ZodObject<{
347
350
  }>;
348
351
  reduceOnly: z.ZodBoolean;
349
352
  isExternal: z.ZodBoolean;
353
+ synthetic: z.ZodBoolean;
350
354
  quantity: z.ZodString;
351
355
  price: z.ZodString;
352
356
  usd: z.ZodString;
@@ -432,6 +436,7 @@ export declare const Schedule: z.ZodDiscriminatedUnion<[z.ZodObject<{
432
436
  }>;
433
437
  reduceOnly: z.ZodBoolean;
434
438
  isExternal: z.ZodBoolean;
439
+ synthetic: z.ZodBoolean;
435
440
  quantity: z.ZodString;
436
441
  price: z.ZodString;
437
442
  usd: z.ZodString;
@@ -59,6 +59,7 @@ export declare const ScheduleListResponse: z.ZodObject<{
59
59
  }>;
60
60
  reduceOnly: z.ZodBoolean;
61
61
  isExternal: z.ZodBoolean;
62
+ synthetic: z.ZodBoolean;
62
63
  quantity: z.ZodString;
63
64
  price: z.ZodString;
64
65
  usd: z.ZodString;
@@ -144,6 +145,7 @@ export declare const ScheduleListResponse: z.ZodObject<{
144
145
  }>;
145
146
  reduceOnly: z.ZodBoolean;
146
147
  isExternal: z.ZodBoolean;
148
+ synthetic: z.ZodBoolean;
147
149
  quantity: z.ZodString;
148
150
  price: z.ZodString;
149
151
  usd: z.ZodString;
@@ -225,6 +227,7 @@ export declare const CreateScheduleResponse: z.ZodObject<{
225
227
  }>;
226
228
  reduceOnly: z.ZodBoolean;
227
229
  isExternal: z.ZodBoolean;
230
+ synthetic: z.ZodBoolean;
228
231
  quantity: z.ZodString;
229
232
  price: z.ZodString;
230
233
  usd: z.ZodString;
@@ -310,6 +313,7 @@ export declare const CreateScheduleResponse: z.ZodObject<{
310
313
  }>;
311
314
  reduceOnly: z.ZodBoolean;
312
315
  isExternal: z.ZodBoolean;
316
+ synthetic: z.ZodBoolean;
313
317
  quantity: z.ZodString;
314
318
  price: z.ZodString;
315
319
  usd: z.ZodString;
@@ -67,36 +67,6 @@ export declare const ReconcileReplacementExternalFill: z.ZodObject<{
67
67
  mark: z.ZodString;
68
68
  }, z.core.$strip>>;
69
69
  }, z.core.$strip>;
70
- export declare const CreatableExternalFill: z.ZodObject<{
71
- type: z.ZodLiteral<"create">;
72
- exchangeFillId: z.ZodString;
73
- cloid: z.ZodNullable<z.ZodString>;
74
- positionId: z.ZodUUID;
75
- connector: z.ZodEnum<{
76
- hyperliquid: "hyperliquid";
77
- binance: "binance";
78
- bybit: "bybit";
79
- okx: "okx";
80
- lighter: "lighter";
81
- }>;
82
- symbol: z.ZodString;
83
- price: z.ZodString;
84
- quantity: z.ZodString;
85
- side: z.ZodEnum<{
86
- BUY: "BUY";
87
- SELL: "SELL";
88
- }>;
89
- reduceOnly: z.ZodBoolean;
90
- timestamp: z.ZodNumber;
91
- tradeFee: z.ZodString;
92
- liquidation: z.ZodNullable<z.ZodObject<{
93
- mark: z.ZodString;
94
- }, z.core.$strip>>;
95
- original: z.ZodOptional<z.ZodObject<{
96
- exchangeFillId: z.ZodString;
97
- quantity: z.ZodString;
98
- }, z.core.$strip>>;
99
- }, z.core.$strip>;
100
70
  export declare const ConfirmFillsRequest: z.ZodRecord<z.ZodUUID, z.ZodTuple<[z.ZodObject<{
101
71
  type: z.ZodLiteral<"confirm">;
102
72
  exchangeFillId: z.ZodString;
@@ -205,11 +175,43 @@ export declare const ReconcileFillsRequest: z.ZodRecord<z.ZodString, z.ZodTuple<
205
175
  mark: z.ZodString;
206
176
  }, z.core.$strip>>;
207
177
  }, z.core.$strip>>>;
208
- export declare const CreateFillsRequest: z.ZodRecord<z.ZodUUID, z.ZodTuple<[z.ZodObject<{
209
- type: z.ZodLiteral<"create">;
178
+ export declare const SyncFillsSinceRequest: z.ZodObject<{
179
+ overlapMs: z.ZodNumber;
180
+ }, z.core.$strip>;
181
+ export declare const SyncFundingSinceRequest: z.ZodObject<{
182
+ overlapMs: z.ZodNumber;
183
+ }, z.core.$strip>;
184
+ export type ConfirmFillsRequest = z.output<typeof ConfirmFillsRequest>;
185
+ export type ReconcileFillsRequest = z.output<typeof ReconcileFillsRequest>;
186
+ export type SyncFillsSinceRequest = z.output<typeof SyncFillsSinceRequest>;
187
+ export type SyncFundingSinceRequest = z.output<typeof SyncFundingSinceRequest>;
188
+ export type UnknownExternalFill = z.output<typeof UnknownExternalFill>;
189
+ export type ReconcileReplacementExternalFill = z.output<typeof ReconcileReplacementExternalFill>;
190
+ export type ConfirmableExternalFill = z.output<typeof ConfirmableExternalFill>;
191
+ /**
192
+ * An exchange-reported open position snapshot. The exchange position API is the
193
+ * source of truth for current exposure; sizes are normalized to BASE units
194
+ * (contractSize applied) so gap arithmetic against fills is unit-consistent.
195
+ */
196
+ export declare const ExternalPosition: z.ZodObject<{
197
+ symbol: z.ZodString;
198
+ size: z.ZodString;
199
+ side: z.ZodEnum<{
200
+ BUY: "BUY";
201
+ SELL: "SELL";
202
+ }>;
203
+ entryPrice: z.ZodString;
204
+ markPrice: z.ZodString;
205
+ }, z.core.$strip>;
206
+ export type ExternalPosition = z.output<typeof ExternalPosition>;
207
+ /**
208
+ * A single fill bound to a positionKey basket. Every fill carries a price/usd:
209
+ * real and gap/opening synthetics a genuine value, unpriceable gone-close
210
+ * synthetics "0" (consumers treat 0-price as unpriceable).
211
+ */
212
+ export declare const ApplicableFill: z.ZodObject<{
210
213
  exchangeFillId: z.ZodString;
211
214
  cloid: z.ZodNullable<z.ZodString>;
212
- positionId: z.ZodUUID;
213
215
  connector: z.ZodEnum<{
214
216
  hyperliquid: "hyperliquid";
215
217
  binance: "binance";
@@ -218,27 +220,205 @@ export declare const CreateFillsRequest: z.ZodRecord<z.ZodUUID, z.ZodTuple<[z.Zo
218
220
  lighter: "lighter";
219
221
  }>;
220
222
  symbol: z.ZodString;
221
- price: z.ZodString;
222
- quantity: z.ZodString;
223
223
  side: z.ZodEnum<{
224
224
  BUY: "BUY";
225
225
  SELL: "SELL";
226
226
  }>;
227
- reduceOnly: z.ZodBoolean;
227
+ quantity: z.ZodString;
228
+ price: z.ZodString;
229
+ usd: z.ZodString;
228
230
  timestamp: z.ZodNumber;
231
+ reduceOnly: z.ZodBoolean;
232
+ synthetic: z.ZodBoolean;
233
+ isExternal: z.ZodBoolean;
229
234
  tradeFee: z.ZodString;
230
- liquidation: z.ZodNullable<z.ZodObject<{
235
+ builderFee: z.ZodString;
236
+ closedReason: z.ZodOptional<z.ZodEnum<{
237
+ NETTED: "NETTED";
238
+ USER: "USER";
239
+ LIQUIDATED: "LIQUIDATED";
240
+ }>>;
241
+ liquidation: z.ZodOptional<z.ZodNullable<z.ZodObject<{
231
242
  mark: z.ZodString;
232
- }, z.core.$strip>>;
243
+ }, z.core.$strip>>>;
233
244
  original: z.ZodOptional<z.ZodObject<{
234
245
  exchangeFillId: z.ZodString;
235
246
  quantity: z.ZodString;
236
247
  }, z.core.$strip>>;
237
- }, z.core.$strip>], z.ZodObject<{
238
- type: z.ZodLiteral<"create">;
239
- exchangeFillId: z.ZodString;
240
- cloid: z.ZodNullable<z.ZodString>;
241
- positionId: z.ZodUUID;
248
+ }, z.core.$strip>;
249
+ export type ApplicableFill = z.output<typeof ApplicableFill>;
250
+ /**
251
+ * Position metadata for an applicable. Consumed ONLY when the apply step CREATES a
252
+ * new position for the positionKey. On merge into an existing position it is
253
+ * ignored. Origin/status/exposure are carried top-level on ApplicablePosition
254
+ * (client-authoritative lifecycle), so this holds only creation metadata.
255
+ */
256
+ export declare const ApplicableMetadata: z.ZodObject<{
257
+ initialExposureUSD: z.ZodRecord<z.ZodString, z.ZodPipe<z.ZodString, z.ZodTransform<`-${string}` | `+${string}`, string>>>;
258
+ }, z.core.$strip>;
259
+ export type ApplicableMetadata = z.output<typeof ApplicableMetadata>;
260
+ /**
261
+ * A basket of fills bound for find-or-create of one target position, keyed by a
262
+ * deterministic positionKey computed client-side from (tradeAccountId, symbols).
263
+ *
264
+ * The client matcher is the lifecycle authority: it computes the final position
265
+ * `exposure`, `origin`, and `status` and the server blind-writes them (no
266
+ * server-side recompute). A flip is two ordered applicables sharing one
267
+ * positionKey: `{status:CLOSED}` then `{status:OPEN}`.
268
+ */
269
+ export declare const ApplicablePosition: z.ZodObject<{
270
+ positionKey: z.ZodString;
271
+ exposure: z.ZodRecord<z.ZodString, z.ZodPipe<z.ZodString, z.ZodTransform<`-${string}` | `+${string}`, string>>>;
272
+ origin: z.ZodEnum<{
273
+ PARTIAL: "PARTIAL";
274
+ PEAR: "PEAR";
275
+ EXTERNAL: "EXTERNAL";
276
+ }>;
277
+ status: z.ZodEnum<{
278
+ OPEN: "OPEN";
279
+ CLOSED: "CLOSED";
280
+ }>;
281
+ closedReason: z.ZodOptional<z.ZodEnum<{
282
+ NETTED: "NETTED";
283
+ USER: "USER";
284
+ LIQUIDATED: "LIQUIDATED";
285
+ }>>;
286
+ fills: z.ZodArray<z.ZodObject<{
287
+ exchangeFillId: z.ZodString;
288
+ cloid: z.ZodNullable<z.ZodString>;
289
+ connector: z.ZodEnum<{
290
+ hyperliquid: "hyperliquid";
291
+ binance: "binance";
292
+ bybit: "bybit";
293
+ okx: "okx";
294
+ lighter: "lighter";
295
+ }>;
296
+ symbol: z.ZodString;
297
+ side: z.ZodEnum<{
298
+ BUY: "BUY";
299
+ SELL: "SELL";
300
+ }>;
301
+ quantity: z.ZodString;
302
+ price: z.ZodString;
303
+ usd: z.ZodString;
304
+ timestamp: z.ZodNumber;
305
+ reduceOnly: z.ZodBoolean;
306
+ synthetic: z.ZodBoolean;
307
+ isExternal: z.ZodBoolean;
308
+ tradeFee: z.ZodString;
309
+ builderFee: z.ZodString;
310
+ closedReason: z.ZodOptional<z.ZodEnum<{
311
+ NETTED: "NETTED";
312
+ USER: "USER";
313
+ LIQUIDATED: "LIQUIDATED";
314
+ }>>;
315
+ liquidation: z.ZodOptional<z.ZodNullable<z.ZodObject<{
316
+ mark: z.ZodString;
317
+ }, z.core.$strip>>>;
318
+ original: z.ZodOptional<z.ZodObject<{
319
+ exchangeFillId: z.ZodString;
320
+ quantity: z.ZodString;
321
+ }, z.core.$strip>>;
322
+ }, z.core.$strip>>;
323
+ metadata: z.ZodObject<{
324
+ initialExposureUSD: z.ZodRecord<z.ZodString, z.ZodPipe<z.ZodString, z.ZodTransform<`-${string}` | `+${string}`, string>>>;
325
+ }, z.core.$strip>;
326
+ }, z.core.$strip>;
327
+ export type ApplicablePosition = z.output<typeof ApplicablePosition>;
328
+ /**
329
+ * Cycle-level metadata for the unified sync request.
330
+ */
331
+ export declare const SyncMeta: z.ZodObject<{
332
+ externalMaxTs: z.ZodNullable<z.ZodNumber>;
333
+ }, z.core.$strip>;
334
+ export type SyncMeta = z.output<typeof SyncMeta>;
335
+ /**
336
+ * POST /sync/create request — the discover+apply phase of the cycle.
337
+ * - applicables: baskets keyed by positionKey, find-or-created during apply.
338
+ * - exchangePositions: the exchange snapshot, enforced source of truth at verify.
339
+ * - meta: cycle metadata (watermark).
340
+ *
341
+ */
342
+ export declare const CreateApplicablesRequest: z.ZodObject<{
343
+ applicables: z.ZodArray<z.ZodObject<{
344
+ positionKey: z.ZodString;
345
+ exposure: z.ZodRecord<z.ZodString, z.ZodPipe<z.ZodString, z.ZodTransform<`-${string}` | `+${string}`, string>>>;
346
+ origin: z.ZodEnum<{
347
+ PARTIAL: "PARTIAL";
348
+ PEAR: "PEAR";
349
+ EXTERNAL: "EXTERNAL";
350
+ }>;
351
+ status: z.ZodEnum<{
352
+ OPEN: "OPEN";
353
+ CLOSED: "CLOSED";
354
+ }>;
355
+ closedReason: z.ZodOptional<z.ZodEnum<{
356
+ NETTED: "NETTED";
357
+ USER: "USER";
358
+ LIQUIDATED: "LIQUIDATED";
359
+ }>>;
360
+ fills: z.ZodArray<z.ZodObject<{
361
+ exchangeFillId: z.ZodString;
362
+ cloid: z.ZodNullable<z.ZodString>;
363
+ connector: z.ZodEnum<{
364
+ hyperliquid: "hyperliquid";
365
+ binance: "binance";
366
+ bybit: "bybit";
367
+ okx: "okx";
368
+ lighter: "lighter";
369
+ }>;
370
+ symbol: z.ZodString;
371
+ side: z.ZodEnum<{
372
+ BUY: "BUY";
373
+ SELL: "SELL";
374
+ }>;
375
+ quantity: z.ZodString;
376
+ price: z.ZodString;
377
+ usd: z.ZodString;
378
+ timestamp: z.ZodNumber;
379
+ reduceOnly: z.ZodBoolean;
380
+ synthetic: z.ZodBoolean;
381
+ isExternal: z.ZodBoolean;
382
+ tradeFee: z.ZodString;
383
+ builderFee: z.ZodString;
384
+ closedReason: z.ZodOptional<z.ZodEnum<{
385
+ NETTED: "NETTED";
386
+ USER: "USER";
387
+ LIQUIDATED: "LIQUIDATED";
388
+ }>>;
389
+ liquidation: z.ZodOptional<z.ZodNullable<z.ZodObject<{
390
+ mark: z.ZodString;
391
+ }, z.core.$strip>>>;
392
+ original: z.ZodOptional<z.ZodObject<{
393
+ exchangeFillId: z.ZodString;
394
+ quantity: z.ZodString;
395
+ }, z.core.$strip>>;
396
+ }, z.core.$strip>>;
397
+ metadata: z.ZodObject<{
398
+ initialExposureUSD: z.ZodRecord<z.ZodString, z.ZodPipe<z.ZodString, z.ZodTransform<`-${string}` | `+${string}`, string>>>;
399
+ }, z.core.$strip>;
400
+ }, z.core.$strip>>;
401
+ exchangePositions: z.ZodArray<z.ZodObject<{
402
+ symbol: z.ZodString;
403
+ size: z.ZodString;
404
+ side: z.ZodEnum<{
405
+ BUY: "BUY";
406
+ SELL: "SELL";
407
+ }>;
408
+ entryPrice: z.ZodString;
409
+ markPrice: z.ZodString;
410
+ }, z.core.$strip>>;
411
+ meta: z.ZodObject<{
412
+ externalMaxTs: z.ZodNullable<z.ZodNumber>;
413
+ }, z.core.$strip>;
414
+ }, z.core.$strip>;
415
+ export type CreateApplicablesRequest = z.output<typeof CreateApplicablesRequest>;
416
+ /**
417
+ * A single historical funding event for an instrument: the applied funding rate,
418
+ * the funding amount in USD notional, and the SIGNED funding per 1 unit of size
419
+ * (notional / szi). All signed (negative when the user paid).
420
+ */
421
+ export declare const FundingPaymentEntry: z.ZodObject<{
242
422
  connector: z.ZodEnum<{
243
423
  hyperliquid: "hyperliquid";
244
424
  binance: "binance";
@@ -246,34 +426,34 @@ export declare const CreateFillsRequest: z.ZodRecord<z.ZodUUID, z.ZodTuple<[z.Zo
246
426
  okx: "okx";
247
427
  lighter: "lighter";
248
428
  }>;
249
- symbol: z.ZodString;
250
- price: z.ZodString;
251
- quantity: z.ZodString;
252
- side: z.ZodEnum<{
253
- BUY: "BUY";
254
- SELL: "SELL";
255
- }>;
256
- reduceOnly: z.ZodBoolean;
429
+ instrumentId: z.ZodString;
430
+ fundingRate: z.ZodString;
431
+ notional: z.ZodString;
432
+ fundingPerUnit: z.ZodString;
257
433
  timestamp: z.ZodNumber;
258
- tradeFee: z.ZodString;
259
- liquidation: z.ZodNullable<z.ZodObject<{
260
- mark: z.ZodString;
261
- }, z.core.$strip>>;
262
- original: z.ZodOptional<z.ZodObject<{
263
- exchangeFillId: z.ZodString;
264
- quantity: z.ZodString;
434
+ }, z.core.$strip>;
435
+ export type FundingPaymentEntry = z.output<typeof FundingPaymentEntry>;
436
+ /**
437
+ * POST /sync/funding/create request — funding events since the watermark plus the
438
+ * cycle watermark. Rows upsert idempotently on (account, connector, instrument, ts).
439
+ */
440
+ export declare const CreateFundingPaymentsRequest: z.ZodObject<{
441
+ payments: z.ZodArray<z.ZodObject<{
442
+ connector: z.ZodEnum<{
443
+ hyperliquid: "hyperliquid";
444
+ binance: "binance";
445
+ bybit: "bybit";
446
+ okx: "okx";
447
+ lighter: "lighter";
448
+ }>;
449
+ instrumentId: z.ZodString;
450
+ fundingRate: z.ZodString;
451
+ notional: z.ZodString;
452
+ fundingPerUnit: z.ZodString;
453
+ timestamp: z.ZodNumber;
265
454
  }, z.core.$strip>>;
266
- }, z.core.$strip>>>;
267
- export declare const SyncSinceRequest: z.ZodObject<{
268
- overlapMs: z.ZodNumber;
269
- nowMs: z.ZodOptional<z.ZodNumber>;
270
- bootstrapLookbackMs: z.ZodOptional<z.ZodNumber>;
455
+ meta: z.ZodObject<{
456
+ externalMaxTs: z.ZodNullable<z.ZodNumber>;
457
+ }, z.core.$strip>;
271
458
  }, z.core.$strip>;
272
- export type ConfirmFillsRequest = z.output<typeof ConfirmFillsRequest>;
273
- export type ReconcileFillsRequest = z.output<typeof ReconcileFillsRequest>;
274
- export type CreateFillsRequest = z.output<typeof CreateFillsRequest>;
275
- export type SyncSinceRequest = z.output<typeof SyncSinceRequest>;
276
- export type UnknownExternalFill = z.output<typeof UnknownExternalFill>;
277
- export type ReconcileReplacementExternalFill = z.output<typeof ReconcileReplacementExternalFill>;
278
- export type ConfirmableExternalFill = z.output<typeof ConfirmableExternalFill>;
279
- export type CreatableExternalFill = z.output<typeof CreatableExternalFill>;
459
+ export type CreateFundingPaymentsRequest = z.output<typeof CreateFundingPaymentsRequest>;
@@ -1,11 +1,19 @@
1
1
  import { z } from 'zod';
2
2
  import { RefineMinimumOneKeyValuePair } from '../common/refinement';
3
- import { UnsignedDecimalString, Side } from '../common/schema';
3
+ import { UnsignedDecimalString, Side, SignedDecimalString } from '../common/schema';
4
4
  import { Connector } from '../connector';
5
5
  import { InstrumentId } from '../instrument';
6
+ import { PositionClosedReason, PositionStatus, PositionOrigin } from '../position/entities';
6
7
 
8
+ const ExchangeFillId = z.string().trim().min(1, "Exchange fill ID must be non-empty");
9
+ const MsTimestamp = z.number().int().positive().describe("Unix timestamp in milliseconds");
10
+ const LiquidationMark = z.object({ mark: UnsignedDecimalString }).nullable();
11
+ const OriginalFillRef = z.object({
12
+ exchangeFillId: ExchangeFillId,
13
+ quantity: UnsignedDecimalString
14
+ });
7
15
  const UnknownExternalFill = z.object({
8
- exchangeFillId: z.string().trim().min(1, "Exchange fill ID must be non-empty"),
16
+ exchangeFillId: ExchangeFillId,
9
17
  cloid: z.string().nullable(),
10
18
  connector: Connector,
11
19
  symbol: InstrumentId,
@@ -13,25 +21,25 @@ const UnknownExternalFill = z.object({
13
21
  quantity: UnsignedDecimalString,
14
22
  side: Side,
15
23
  reduceOnly: z.boolean(),
16
- timestamp: z.number().int().positive().describe("Unix timestamp in milliseconds"),
24
+ timestamp: MsTimestamp,
17
25
  tradeFee: UnsignedDecimalString,
18
26
  builderFee: UnsignedDecimalString,
19
- liquidation: z.object({ mark: UnsignedDecimalString }).nullable()
27
+ liquidation: LiquidationMark
20
28
  });
21
29
  const ConfirmableExternalFill = z.object({
22
30
  type: z.literal("confirm"),
23
- exchangeFillId: z.string().trim().min(1, "Exchange fill ID must be non-empty"),
31
+ exchangeFillId: ExchangeFillId,
24
32
  cloid: z.string(),
25
33
  positionId: z.uuid().describe("Position ID"),
26
34
  connector: Connector,
27
35
  symbol: InstrumentId,
28
36
  quantity: UnsignedDecimalString,
29
- timestamp: z.number().int().positive().describe("Unix timestamp in milliseconds"),
37
+ timestamp: MsTimestamp,
30
38
  tradeFee: UnsignedDecimalString,
31
39
  builderFee: UnsignedDecimalString
32
40
  });
33
41
  const ReconcileReplacementExternalFill = z.object({
34
- exchangeFillId: z.string().trim().min(1, "Exchange fill ID must be non-empty"),
42
+ exchangeFillId: ExchangeFillId,
35
43
  cloid: z.string(),
36
44
  connector: Connector,
37
45
  symbol: InstrumentId,
@@ -39,40 +47,84 @@ const ReconcileReplacementExternalFill = z.object({
39
47
  quantity: UnsignedDecimalString,
40
48
  side: Side,
41
49
  reduceOnly: z.boolean(),
42
- timestamp: z.number().int().positive().describe("Unix timestamp in milliseconds"),
50
+ timestamp: MsTimestamp,
43
51
  tradeFee: UnsignedDecimalString,
44
52
  builderFee: UnsignedDecimalString,
45
- liquidation: z.object({ mark: UnsignedDecimalString }).nullable()
53
+ liquidation: LiquidationMark
54
+ });
55
+ const ConfirmFillsRequest = z.record(z.uuid().describe("Position ID"), z.tuple([ConfirmableExternalFill]).rest(ConfirmableExternalFill)).superRefine(RefineMinimumOneKeyValuePair);
56
+ const ReconcileFillsRequest = z.record(
57
+ z.string().trim().min(1, "CLOID must be non-empty"),
58
+ z.tuple([ReconcileReplacementExternalFill, ReconcileReplacementExternalFill]).rest(ReconcileReplacementExternalFill)
59
+ ).superRefine(RefineMinimumOneKeyValuePair);
60
+ const SyncFillsSinceRequest = z.object({
61
+ overlapMs: z.number().int().positive()
46
62
  });
47
- const CreatableExternalFill = z.object({
48
- type: z.literal("create"),
49
- exchangeFillId: z.string().trim().min(1, "Exchange fill ID must be non-empty"),
63
+ const SyncFundingSinceRequest = z.object({
64
+ overlapMs: z.number().int().positive()
65
+ });
66
+ const ExternalPosition = z.object({
67
+ symbol: InstrumentId,
68
+ size: UnsignedDecimalString.describe("BASE units, contractSize applied; always >= 0"),
69
+ side: Side.describe("sign of the net position"),
70
+ entryPrice: UnsignedDecimalString.describe("exchange-reported average entry"),
71
+ markPrice: UnsignedDecimalString
72
+ });
73
+ const ApplicableFill = z.object({
74
+ // Deterministic synthetic id (`synthetic-{positionKey}-{symbol}-{side}`) for synthetic fills,
75
+ // exchange-native id for real fills.
76
+ exchangeFillId: ExchangeFillId,
50
77
  cloid: z.string().nullable(),
51
- positionId: z.uuid().describe("Position ID"),
52
78
  connector: Connector,
53
79
  symbol: InstrumentId,
54
- price: UnsignedDecimalString,
55
- quantity: UnsignedDecimalString,
56
80
  side: Side,
81
+ quantity: UnsignedDecimalString.describe("BASE units"),
82
+ price: UnsignedDecimalString.describe('"0" only on an unpriceable gone-close synthetic'),
83
+ usd: UnsignedDecimalString.describe('"0" only on an unpriceable gone-close synthetic'),
84
+ timestamp: MsTimestamp.describe("ms \u2014 apply replays in this order"),
57
85
  reduceOnly: z.boolean(),
58
- timestamp: z.number().int().positive().describe("Unix timestamp in milliseconds"),
86
+ synthetic: z.boolean(),
87
+ isExternal: z.boolean(),
59
88
  tradeFee: UnsignedDecimalString,
60
- liquidation: z.object({ mark: UnsignedDecimalString }).nullable(),
61
- original: z.object({
62
- exchangeFillId: z.string().trim().min(1, "Exchange fill ID must be non-empty"),
63
- quantity: UnsignedDecimalString
64
- }).optional()
89
+ builderFee: UnsignedDecimalString,
90
+ closedReason: PositionClosedReason.optional().describe("e.g. NETTED for a synthetic close fill"),
91
+ liquidation: LiquidationMark.optional(),
92
+ original: OriginalFillRef.optional()
65
93
  });
66
- const ConfirmFillsRequest = z.record(z.uuid().describe("Position ID"), z.tuple([ConfirmableExternalFill]).rest(ConfirmableExternalFill)).superRefine(RefineMinimumOneKeyValuePair);
67
- const ReconcileFillsRequest = z.record(
68
- z.string().trim().min(1, "CLOID must be non-empty"),
69
- z.tuple([ReconcileReplacementExternalFill, ReconcileReplacementExternalFill]).rest(ReconcileReplacementExternalFill)
70
- ).superRefine(RefineMinimumOneKeyValuePair);
71
- const CreateFillsRequest = z.record(z.uuid().describe("Position ID"), z.tuple([CreatableExternalFill]).rest(CreatableExternalFill)).superRefine(RefineMinimumOneKeyValuePair);
72
- const SyncSinceRequest = z.object({
73
- overlapMs: z.number().int().positive(),
74
- nowMs: z.number().int().nonnegative().optional(),
75
- bootstrapLookbackMs: z.number().int().positive().optional()
94
+ const ApplicableMetadata = z.object({
95
+ initialExposureUSD: z.record(InstrumentId, SignedDecimalString).describe("opening cost basis from this position\u2019s own real fills; partial map allowed")
96
+ });
97
+ const ApplicablePosition = z.object({
98
+ positionKey: z.string().trim().min(1, "positionKey must be non-empty"),
99
+ exposure: z.record(InstrumentId, SignedDecimalString).describe("final position exposure (signed, BASE units)"),
100
+ origin: PositionOrigin,
101
+ status: PositionStatus,
102
+ closedReason: PositionClosedReason.optional().describe("set when status is CLOSED, e.g. NETTED"),
103
+ fills: z.array(ApplicableFill).min(1, "Applicable must carry at least one fill"),
104
+ metadata: ApplicableMetadata
105
+ });
106
+ const SyncMeta = z.object({
107
+ externalMaxTs: z.number().int().nonnegative().nullable().describe("watermark advance source")
108
+ });
109
+ const CreateApplicablesRequest = z.object({
110
+ applicables: z.array(ApplicablePosition),
111
+ exchangePositions: z.array(ExternalPosition),
112
+ meta: SyncMeta
113
+ });
114
+ const OptionallySignedDecimalString = z.string().regex(/^[+-]?\d+(\.\d+)?$/, "Must be a valid signed decimal string");
115
+ const FundingPaymentEntry = z.object({
116
+ connector: Connector,
117
+ instrumentId: InstrumentId,
118
+ fundingRate: OptionallySignedDecimalString.describe("applied funding rate, optionally signed"),
119
+ notional: OptionallySignedDecimalString.describe("funding amount in USD notional, optionally signed"),
120
+ fundingPerUnit: OptionallySignedDecimalString.describe(
121
+ "signed funding per 1 unit of size (notional / szi); attribution coefficient"
122
+ ),
123
+ timestamp: MsTimestamp
124
+ });
125
+ const CreateFundingPaymentsRequest = z.object({
126
+ payments: z.array(FundingPaymentEntry),
127
+ meta: SyncMeta
76
128
  });
77
129
 
78
- export { ConfirmFillsRequest, ConfirmableExternalFill, CreatableExternalFill, CreateFillsRequest, ReconcileFillsRequest, ReconcileReplacementExternalFill, SyncSinceRequest, UnknownExternalFill };
130
+ export { ApplicableFill, ApplicableMetadata, ApplicablePosition, ConfirmFillsRequest, ConfirmableExternalFill, CreateApplicablesRequest, CreateFundingPaymentsRequest, ExternalPosition, FundingPaymentEntry, ReconcileFillsRequest, ReconcileReplacementExternalFill, SyncFillsSinceRequest, SyncFundingSinceRequest, SyncMeta, UnknownExternalFill };
@@ -1,10 +1,13 @@
1
1
  import { z } from 'zod';
2
2
  export declare const SyncFillsResponse: z.ZodObject<{}, z.core.$strip>;
3
- export declare const SyncSinceResponse: z.ZodObject<{
4
- since: z.ZodISODateTime;
3
+ export declare const SyncFillsSinceResponse: z.ZodObject<{
5
4
  sinceMs: z.ZodNumber;
6
- safeTs: z.ZodOptional<z.ZodNumber>;
5
+ neverSynced: z.ZodBoolean;
7
6
  confirmedExchangeFillIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
8
7
  }, z.core.$strip>;
8
+ export declare const SyncFundingSinceResponse: z.ZodObject<{
9
+ sinceMs: z.ZodNumber;
10
+ }, z.core.$strip>;
9
11
  export type SyncFillsResponse = z.output<typeof SyncFillsResponse>;
10
- export type SyncSinceResponse = z.output<typeof SyncSinceResponse>;
12
+ export type SyncFillsSinceResponse = z.output<typeof SyncFillsSinceResponse>;
13
+ export type SyncFundingSinceResponse = z.output<typeof SyncFundingSinceResponse>;
@@ -1,11 +1,16 @@
1
1
  import { z } from 'zod';
2
2
 
3
3
  const SyncFillsResponse = z.object({});
4
- const SyncSinceResponse = z.object({
5
- since: z.iso.datetime(),
4
+ const SyncFillsSinceResponse = z.object({
6
5
  sinceMs: z.number().int().nonnegative(),
7
- safeTs: z.number().int().nonnegative().optional(),
6
+ // True only when the account has no checkpoint and nothing to anchor on, so sync starts from
7
+ // genesis. Clients use this to detect an account that has never imported its trade history —
8
+ // `sinceMs === 0` alone is ambiguous (a clamped watermark also yields 0).
9
+ neverSynced: z.boolean(),
8
10
  confirmedExchangeFillIds: z.array(z.string()).optional()
9
11
  });
12
+ const SyncFundingSinceResponse = z.object({
13
+ sinceMs: z.number().int().nonnegative()
14
+ });
10
15
 
11
- export { SyncFillsResponse, SyncSinceResponse };
16
+ export { SyncFillsResponse, SyncFillsSinceResponse, SyncFundingSinceResponse };