@pear-protocol/utils 0.5.1 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,67 +1,88 @@
1
- import BigNumber9 from 'bignumber.js';
2
- import { sha256 } from '@noble/hashes/sha256';
3
- import { bytesToHex } from '@noble/hashes/utils';
1
+ import BigNumber7 from 'bignumber.js';
2
+ import { sha256 } from '@noble/hashes/sha2';
3
+ import { bytesToHex, randomBytes, utf8ToBytes } from '@noble/hashes/utils';
4
4
  import { WATERMARK_FUTURE_SKEW_MS } from '@pear-protocol/types';
5
+ import { base64urlnopad } from '@scure/base';
5
6
 
6
- // src/asset/compute.ts
7
+ var __defProp = Object.defineProperty;
8
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
7
9
  function parse(value) {
8
- return value instanceof BigNumber9 ? value : new BigNumber9(value);
10
+ return value instanceof BigNumber7 ? value : new BigNumber7(value);
9
11
  }
12
+ __name(parse, "parse");
10
13
  function toDecimalString(value) {
11
14
  return parse(value).toFixed();
12
15
  }
16
+ __name(toDecimalString, "toDecimalString");
13
17
  function signed(value) {
14
18
  const bn = parse(value);
15
19
  return bn.isNegative() && !bn.isZero() ? bn.toFixed() : `+${bn.toFixed()}`;
16
20
  }
21
+ __name(signed, "signed");
17
22
  function add(a, b) {
18
23
  return parse(a).plus(parse(b));
19
24
  }
25
+ __name(add, "add");
20
26
  function subtract(a, b) {
21
27
  return parse(a).minus(parse(b));
22
28
  }
29
+ __name(subtract, "subtract");
23
30
  function multiply(a, b) {
24
31
  return parse(a).times(parse(b));
25
32
  }
33
+ __name(multiply, "multiply");
26
34
  function divide(a, b) {
27
35
  return parse(a).div(parse(b));
28
36
  }
37
+ __name(divide, "divide");
29
38
  function negate(value) {
30
39
  return parse(value).negated();
31
40
  }
41
+ __name(negate, "negate");
32
42
  function abs(value) {
33
43
  return parse(value).abs();
34
44
  }
45
+ __name(abs, "abs");
35
46
  function min(a, b) {
36
- return BigNumber9.min(parse(a), parse(b));
47
+ return BigNumber7.min(parse(a), parse(b));
37
48
  }
49
+ __name(min, "min");
38
50
  function isZero(value) {
39
51
  return parse(value).isZero();
40
52
  }
53
+ __name(isZero, "isZero");
41
54
  function isPositive(value) {
42
55
  return parse(value).isPositive();
43
56
  }
57
+ __name(isPositive, "isPositive");
44
58
  function isNegative(value) {
45
59
  return parse(value).isNegative();
46
60
  }
61
+ __name(isNegative, "isNegative");
47
62
  function isFiniteDecimal(value) {
48
63
  return parse(value).isFinite();
49
64
  }
65
+ __name(isFiniteDecimal, "isFiniteDecimal");
50
66
  function isEqualTo(a, b) {
51
67
  return parse(a).isEqualTo(parse(b));
52
68
  }
69
+ __name(isEqualTo, "isEqualTo");
53
70
  function isGreaterThan(a, b) {
54
71
  return parse(a).isGreaterThan(parse(b));
55
72
  }
73
+ __name(isGreaterThan, "isGreaterThan");
56
74
  function isGreaterThanOrEqual(a, b) {
57
75
  return parse(a).isGreaterThanOrEqualTo(parse(b));
58
76
  }
77
+ __name(isGreaterThanOrEqual, "isGreaterThanOrEqual");
59
78
  function isLessThan(a, b) {
60
79
  return parse(a).isLessThan(parse(b));
61
80
  }
81
+ __name(isLessThan, "isLessThan");
62
82
  function isLessThanOrEqual(a, b) {
63
83
  return parse(a).isLessThanOrEqualTo(parse(b));
64
84
  }
85
+ __name(isLessThanOrEqual, "isLessThanOrEqual");
65
86
  function sideSign(side) {
66
87
  switch (side) {
67
88
  case "BUY":
@@ -70,36 +91,42 @@ function sideSign(side) {
70
91
  return -1;
71
92
  }
72
93
  }
94
+ __name(sideSign, "sideSign");
73
95
  function signedBySide(value, side) {
74
96
  return parse(value).times(sideSign(side));
75
97
  }
98
+ __name(signedBySide, "signedBySide");
76
99
 
77
100
  // src/math/index.ts
78
- var ZERO = new BigNumber9(0);
79
- var BIPS = new BigNumber9(1e4);
101
+ var ZERO = new BigNumber7(0);
102
+ var BIPS = new BigNumber7(1e4);
80
103
  function exponentiate(value) {
81
104
  const result = Math.exp(value);
82
- return new BigNumber9(result);
105
+ return new BigNumber7(result);
83
106
  }
107
+ __name(exponentiate, "exponentiate");
84
108
  function sign(value) {
85
109
  if (value.isZero()) return 0;
86
110
  return value.isPositive() ? 1 : -1;
87
111
  }
112
+ __name(sign, "sign");
88
113
  function countDecimals(value) {
89
114
  const parts = value.split(".");
90
115
  return parts[1]?.length ?? 0;
91
116
  }
117
+ __name(countDecimals, "countDecimals");
92
118
  function compareValue(track, value, threshold) {
93
119
  return track === "PEAK" ? value.isGreaterThanOrEqualTo(threshold) : value.isLessThan(threshold);
94
120
  }
121
+ __name(compareValue, "compareValue");
95
122
 
96
123
  // src/fills/compute.ts
97
124
  function computeEntryPriceForAsset(fills) {
98
125
  let entryPrice = ZERO;
99
126
  let positionSize = ZERO;
100
127
  for (const fill of fills) {
101
- const price = new BigNumber9(fill.price);
102
- const quantity = new BigNumber9(fill.quantity);
128
+ const price = new BigNumber7(fill.price);
129
+ const quantity = new BigNumber7(fill.quantity);
103
130
  const signed2 = fill.side === "BUY" ? quantity : quantity.negated();
104
131
  const newPositionSize = positionSize.plus(signed2);
105
132
  const isSameDirection = !positionSize.isZero() && positionSize.isPositive() === signed2.isPositive();
@@ -113,6 +140,7 @@ function computeEntryPriceForAsset(fills) {
113
140
  }
114
141
  return entryPrice;
115
142
  }
143
+ __name(computeEntryPriceForAsset, "computeEntryPriceForAsset");
116
144
 
117
145
  // src/asset/compute.ts
118
146
  function computeAssetEntryNotional(signedQuantity, fills) {
@@ -126,6 +154,7 @@ function computeAssetEntryNotional(signedQuantity, fills) {
126
154
  const unsignedQuantity = signedQuantity.abs();
127
155
  return unsignedQuantity.multipliedBy(entryPrice);
128
156
  }
157
+ __name(computeAssetEntryNotional, "computeAssetEntryNotional");
129
158
  function computeAssetUnrealizedPnL(signedQuantity, currentPrice, fills) {
130
159
  if (signedQuantity.isZero()) {
131
160
  return ZERO;
@@ -137,9 +166,11 @@ function computeAssetUnrealizedPnL(signedQuantity, currentPrice, fills) {
137
166
  const deltaPrice = currentPrice.minus(entryPrice);
138
167
  return signedQuantity.multipliedBy(deltaPrice);
139
168
  }
169
+ __name(computeAssetUnrealizedPnL, "computeAssetUnrealizedPnL");
140
170
  function computeAssetGrossRealizedPnL(fills) {
141
171
  return walkAssetFills(fills).gross;
142
172
  }
173
+ __name(computeAssetGrossRealizedPnL, "computeAssetGrossRealizedPnL");
143
174
  function computeAssetUndeterminedSizes(fills) {
144
175
  const result = {};
145
176
  for (const asset of computeAssetRealizedPnLs(fills)) {
@@ -149,6 +180,7 @@ function computeAssetUndeterminedSizes(fills) {
149
180
  }
150
181
  return result;
151
182
  }
183
+ __name(computeAssetUndeterminedSizes, "computeAssetUndeterminedSizes");
152
184
  function computeAssetUnrealizedPnLs(exposureMap, priceMap, fills) {
153
185
  const result = [];
154
186
  for (const [id, signedQtyString] of Object.entries(exposureMap)) {
@@ -156,11 +188,11 @@ function computeAssetUnrealizedPnLs(exposureMap, priceMap, fills) {
156
188
  if (!priceString) {
157
189
  continue;
158
190
  }
159
- const signedQuantity = new BigNumber9(signedQtyString);
191
+ const signedQuantity = new BigNumber7(signedQtyString);
160
192
  if (signedQuantity.isZero()) {
161
193
  continue;
162
194
  }
163
- const currentPrice = new BigNumber9(priceString);
195
+ const currentPrice = new BigNumber7(priceString);
164
196
  const assetFills = fills.filter((fill) => fill.symbol === id);
165
197
  const entryPrice = computeEntryPriceForAsset(assetFills);
166
198
  const upnl = signedQuantity.multipliedBy(currentPrice.minus(entryPrice));
@@ -174,6 +206,7 @@ function computeAssetUnrealizedPnLs(exposureMap, priceMap, fills) {
174
206
  }
175
207
  return result;
176
208
  }
209
+ __name(computeAssetUnrealizedPnLs, "computeAssetUnrealizedPnLs");
177
210
  function computeAssetRealizedPnLs(fills) {
178
211
  const bySymbol = /* @__PURE__ */ new Map();
179
212
  for (const fill of fills) {
@@ -183,8 +216,8 @@ function computeAssetRealizedPnLs(fills) {
183
216
  }
184
217
  const result = [];
185
218
  for (const [id, assetFills] of bySymbol) {
186
- const tradeFees = assetFills.reduce((acc, fill) => acc.plus(new BigNumber9(fill.tradeFee ?? "0")), ZERO);
187
- const pearFees = assetFills.reduce((acc, fill) => acc.plus(new BigNumber9(fill.pearFee ?? "0")), ZERO);
219
+ const tradeFees = assetFills.reduce((acc, fill) => acc.plus(new BigNumber7(fill.tradeFee ?? "0")), ZERO);
220
+ const pearFees = assetFills.reduce((acc, fill) => acc.plus(new BigNumber7(fill.pearFee ?? "0")), ZERO);
188
221
  const totalFees = tradeFees.plus(pearFees);
189
222
  const { gross: grossPnl, undeterminedSize, closures, exitQuantity, exitNotional } = walkAssetFills(assetFills);
190
223
  const netPnl = grossPnl.minus(totalFees);
@@ -205,6 +238,7 @@ function computeAssetRealizedPnLs(fills) {
205
238
  }
206
239
  return result;
207
240
  }
241
+ __name(computeAssetRealizedPnLs, "computeAssetRealizedPnLs");
208
242
  function walkAssetFills(fills) {
209
243
  let entryPrice = ZERO;
210
244
  let positionSize = ZERO;
@@ -262,6 +296,9 @@ function walkAssetFills(fills) {
262
296
  exitNotional
263
297
  };
264
298
  }
299
+ __name(walkAssetFills, "walkAssetFills");
300
+
301
+ // src/basket/compute.ts
265
302
  function computeBasketWeightedRatioV1(basket, priceMap) {
266
303
  let logSum = 0;
267
304
  for (const leg of basket) {
@@ -278,28 +315,39 @@ function computeBasketWeightedRatioV1(basket, priceMap) {
278
315
  }
279
316
  return exponentiate(logSum);
280
317
  }
318
+ __name(computeBasketWeightedRatioV1, "computeBasketWeightedRatioV1");
281
319
  function deriveBasketKey(longInstrumentIds, shortInstrumentIds) {
282
320
  const payload = JSON.stringify({
283
- long: [...longInstrumentIds].sort((a, b) => a.localeCompare(b)),
284
- short: [...shortInstrumentIds].sort((a, b) => a.localeCompare(b))
321
+ long: [
322
+ ...longInstrumentIds
323
+ ].sort((a, b) => a.localeCompare(b)),
324
+ short: [
325
+ ...shortInstrumentIds
326
+ ].sort((a, b) => a.localeCompare(b))
285
327
  });
286
328
  return bytesToHex(sha256(new TextEncoder().encode(payload)));
287
329
  }
330
+ __name(deriveBasketKey, "deriveBasketKey");
288
331
  function contractsToBase(contracts, contractSize) {
289
- return new BigNumber9(contracts).times(contractSize);
332
+ return new BigNumber7(contracts).times(contractSize);
290
333
  }
334
+ __name(contractsToBase, "contractsToBase");
291
335
  function baseToContracts(base, contractSize) {
292
- return new BigNumber9(base).div(contractSize);
336
+ return new BigNumber7(base).div(contractSize);
293
337
  }
338
+ __name(baseToContracts, "baseToContracts");
294
339
  function computeRealizedPnlBySymbol(fills) {
295
340
  const bySymbol = groupFillsBySymbol(fills);
296
341
  const result = /* @__PURE__ */ new Map();
297
342
  for (const [symbol, symbolFills] of bySymbol) {
298
- const sorted = [...symbolFills].sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
343
+ const sorted = [
344
+ ...symbolFills
345
+ ].sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
299
346
  result.set(symbol, computeRealizedForSymbol(sorted));
300
347
  }
301
348
  return result;
302
349
  }
350
+ __name(computeRealizedPnlBySymbol, "computeRealizedPnlBySymbol");
303
351
  function computeRealizedPnlFromFills(fills) {
304
352
  const byPnl = computeRealizedPnlBySymbol(fills);
305
353
  let total = ZERO;
@@ -308,6 +356,7 @@ function computeRealizedPnlFromFills(fills) {
308
356
  }
309
357
  return total;
310
358
  }
359
+ __name(computeRealizedPnlFromFills, "computeRealizedPnlFromFills");
311
360
  function groupFillsBySymbol(fills) {
312
361
  const bySymbol = /* @__PURE__ */ new Map();
313
362
  for (const fill of fills) {
@@ -317,17 +366,18 @@ function groupFillsBySymbol(fills) {
317
366
  }
318
367
  return bySymbol;
319
368
  }
369
+ __name(groupFillsBySymbol, "groupFillsBySymbol");
320
370
  function computeRealizedForSymbol(fills) {
321
371
  let entryPrice = ZERO;
322
372
  let positionSize = ZERO;
323
373
  let realized = ZERO;
324
374
  for (const fill of fills) {
325
- const price = new BigNumber9(fill.price);
326
- const quantity = new BigNumber9(fill.quantity);
375
+ const price = new BigNumber7(fill.price);
376
+ const quantity = new BigNumber7(fill.quantity);
327
377
  const signed2 = fill.side === "BUY" ? quantity : quantity.negated();
328
378
  const newPositionSize = positionSize.plus(signed2);
329
379
  if (!positionSize.isZero() && positionSize.isPositive() !== signed2.isPositive()) {
330
- const closedQty = BigNumber9.min(positionSize.abs(), signed2.abs());
380
+ const closedQty = BigNumber7.min(positionSize.abs(), signed2.abs());
331
381
  if (positionSize.isPositive()) {
332
382
  realized = realized.plus(closedQty.multipliedBy(price.minus(entryPrice)));
333
383
  } else {
@@ -345,6 +395,9 @@ function computeRealizedForSymbol(fills) {
345
395
  }
346
396
  return realized;
347
397
  }
398
+ __name(computeRealizedForSymbol, "computeRealizedForSymbol");
399
+
400
+ // src/position/compute.ts
348
401
  function computeUnrealizedPositionState(exposureMap, priceMap, fills) {
349
402
  const assetUPnLs = computeAssetUnrealizedPnLs(exposureMap, priceMap, fills);
350
403
  const entryPrice = computePositionEntryPrice(assetUPnLs);
@@ -363,9 +416,11 @@ function computeUnrealizedPositionState(exposureMap, priceMap, fills) {
363
416
  upnlBips
364
417
  };
365
418
  }
419
+ __name(computeUnrealizedPositionState, "computeUnrealizedPositionState");
366
420
  function computeRealizedPositionState(fills) {
367
421
  return aggregateRealizedPositionState(computeAssetRealizedPnLs(fills));
368
422
  }
423
+ __name(computeRealizedPositionState, "computeRealizedPositionState");
369
424
  function aggregateRealizedPositionState(assetPnLs) {
370
425
  const grossPnl = computePositionGrossRealizedPnL(assetPnLs);
371
426
  const netPnl = computePositionNetRealizedPnL(assetPnLs);
@@ -380,25 +435,24 @@ function aggregateRealizedPositionState(assetPnLs) {
380
435
  pearFees
381
436
  };
382
437
  }
438
+ __name(aggregateRealizedPositionState, "aggregateRealizedPositionState");
383
439
  function computePositionEntryPrice(assetUPnLs) {
384
- const { totalWeightedPrice, totalWeight } = assetUPnLs.reduce(
385
- (acc, { signedQuantity, entryPrice }) => {
386
- const absQuantity = signedQuantity.abs();
387
- return {
388
- totalWeightedPrice: acc.totalWeightedPrice.plus(absQuantity.multipliedBy(entryPrice)),
389
- totalWeight: acc.totalWeight.plus(absQuantity)
390
- };
391
- },
392
- {
393
- totalWeightedPrice: ZERO,
394
- totalWeight: ZERO
395
- }
396
- );
440
+ const { totalWeightedPrice, totalWeight } = assetUPnLs.reduce((acc, { signedQuantity, entryPrice }) => {
441
+ const absQuantity = signedQuantity.abs();
442
+ return {
443
+ totalWeightedPrice: acc.totalWeightedPrice.plus(absQuantity.multipliedBy(entryPrice)),
444
+ totalWeight: acc.totalWeight.plus(absQuantity)
445
+ };
446
+ }, {
447
+ totalWeightedPrice: ZERO,
448
+ totalWeight: ZERO
449
+ });
397
450
  if (totalWeight.isZero()) {
398
451
  return null;
399
452
  }
400
453
  return totalWeightedPrice.dividedBy(totalWeight);
401
454
  }
455
+ __name(computePositionEntryPrice, "computePositionEntryPrice");
402
456
  function computePositionEntryNotional(assetUPnLs) {
403
457
  return assetUPnLs.reduce((acc, asset) => {
404
458
  if (asset.signedQuantity.isZero()) {
@@ -407,25 +461,24 @@ function computePositionEntryNotional(assetUPnLs) {
407
461
  return acc.plus(asset.signedQuantity.abs().multipliedBy(asset.entryPrice));
408
462
  }, ZERO);
409
463
  }
464
+ __name(computePositionEntryNotional, "computePositionEntryNotional");
410
465
  function computePositionCurrentPrice(assetUPnLs) {
411
- const { totalWeightedPrice, totalWeight } = assetUPnLs.reduce(
412
- (acc, { signedQuantity, currentPrice }) => {
413
- const absQuantity = signedQuantity.abs();
414
- return {
415
- totalWeightedPrice: acc.totalWeightedPrice.plus(absQuantity.multipliedBy(currentPrice)),
416
- totalWeight: acc.totalWeight.plus(absQuantity)
417
- };
418
- },
419
- {
420
- totalWeightedPrice: ZERO,
421
- totalWeight: ZERO
422
- }
423
- );
466
+ const { totalWeightedPrice, totalWeight } = assetUPnLs.reduce((acc, { signedQuantity, currentPrice }) => {
467
+ const absQuantity = signedQuantity.abs();
468
+ return {
469
+ totalWeightedPrice: acc.totalWeightedPrice.plus(absQuantity.multipliedBy(currentPrice)),
470
+ totalWeight: acc.totalWeight.plus(absQuantity)
471
+ };
472
+ }, {
473
+ totalWeightedPrice: ZERO,
474
+ totalWeight: ZERO
475
+ });
424
476
  if (totalWeight.isZero()) {
425
477
  return null;
426
478
  }
427
479
  return totalWeightedPrice.dividedBy(totalWeight);
428
480
  }
481
+ __name(computePositionCurrentPrice, "computePositionCurrentPrice");
429
482
  function computePositionMarkNotional(assetUPnLs) {
430
483
  return assetUPnLs.reduce((acc, asset) => {
431
484
  if (asset.signedQuantity.isZero()) {
@@ -434,21 +487,26 @@ function computePositionMarkNotional(assetUPnLs) {
434
487
  return acc.plus(asset.signedQuantity.abs().multipliedBy(asset.currentPrice));
435
488
  }, ZERO);
436
489
  }
490
+ __name(computePositionMarkNotional, "computePositionMarkNotional");
437
491
  function computePositionUnrealizedPnL(assetUPnLs) {
438
492
  return assetUPnLs.reduce((acc, asset) => acc.plus(asset.upnl), ZERO);
439
493
  }
494
+ __name(computePositionUnrealizedPnL, "computePositionUnrealizedPnL");
440
495
  function computePositionUnrealizedPnLBips(upnl, entryNotional) {
441
496
  if (upnl.isZero() || entryNotional.isZero()) {
442
497
  return ZERO;
443
498
  }
444
499
  return upnl.div(entryNotional).multipliedBy(BIPS);
445
500
  }
501
+ __name(computePositionUnrealizedPnLBips, "computePositionUnrealizedPnLBips");
446
502
  function computePositionGrossRealizedPnL(assetPnLs) {
447
503
  return assetPnLs.reduce((acc, asset) => acc.plus(asset.grossPnl), ZERO);
448
504
  }
505
+ __name(computePositionGrossRealizedPnL, "computePositionGrossRealizedPnL");
449
506
  function computePositionNetRealizedPnL(assetPnLs) {
450
507
  return assetPnLs.reduce((acc, asset) => acc.plus(asset.netPnl), ZERO);
451
508
  }
509
+ __name(computePositionNetRealizedPnL, "computePositionNetRealizedPnL");
452
510
  function computePositionEntryPrices(exposureMap, fills) {
453
511
  const entryPrices = {};
454
512
  for (const instrumentId of Object.keys(exposureMap)) {
@@ -459,6 +517,7 @@ function computePositionEntryPrices(exposureMap, fills) {
459
517
  }
460
518
  return entryPrices;
461
519
  }
520
+ __name(computePositionEntryPrices, "computePositionEntryPrices");
462
521
  function computeUnrealizedPositionStateFromEntryPrices(exposureMap, entryPrices, priceMap) {
463
522
  const assetUPnLs = [];
464
523
  for (const [id, signedQuantityString] of Object.entries(exposureMap)) {
@@ -470,7 +529,13 @@ function computeUnrealizedPositionStateFromEntryPrices(exposureMap, entryPrices,
470
529
  const currentPrice = parse(currentPriceString);
471
530
  const entryPrice2 = parse(entryPriceString);
472
531
  const upnl2 = multiply(signedQuantity, subtract(currentPrice, entryPrice2));
473
- assetUPnLs.push({ id, signedQuantity, entryPrice: entryPrice2, currentPrice, upnl: upnl2 });
532
+ assetUPnLs.push({
533
+ id,
534
+ signedQuantity,
535
+ entryPrice: entryPrice2,
536
+ currentPrice,
537
+ upnl: upnl2
538
+ });
474
539
  }
475
540
  const entryPrice = computePositionEntryPrice(assetUPnLs);
476
541
  const entryNotional = computePositionEntryNotional(assetUPnLs);
@@ -478,19 +543,31 @@ function computeUnrealizedPositionStateFromEntryPrices(exposureMap, entryPrices,
478
543
  const markNotional = computePositionMarkNotional(assetUPnLs);
479
544
  const upnl = computePositionUnrealizedPnL(assetUPnLs);
480
545
  const upnlBips = computePositionUnrealizedPnLBips(upnl, entryNotional);
481
- return { assetUPnLs, entryPrice, entryNotional, markPrice, markNotional, upnl, upnlBips };
546
+ return {
547
+ assetUPnLs,
548
+ entryPrice,
549
+ entryNotional,
550
+ markPrice,
551
+ markNotional,
552
+ upnl,
553
+ upnlBips
554
+ };
482
555
  }
556
+ __name(computeUnrealizedPositionStateFromEntryPrices, "computeUnrealizedPositionStateFromEntryPrices");
483
557
  function generateDeterministicPositionKey(input) {
484
- const symbols = [...input.symbols].sort((a, b) => a.localeCompare(b));
558
+ const symbols = [
559
+ ...input.symbols
560
+ ].sort((a, b) => a.localeCompare(b));
485
561
  const payload = JSON.stringify({
486
562
  tradeAccountId: input.tradeAccountId.toLowerCase(),
487
563
  symbols
488
564
  });
489
565
  return bytesToHex(sha256(new TextEncoder().encode(payload)));
490
566
  }
491
- BigNumber9.config({
567
+ __name(generateDeterministicPositionKey, "generateDeterministicPositionKey");
568
+ BigNumber7.config({
492
569
  DECIMAL_PLACES: 30,
493
- ROUNDING_MODE: BigNumber9.ROUND_DOWN
570
+ ROUNDING_MODE: BigNumber7.ROUND_DOWN
494
571
  });
495
572
  function precisePrice(connector, raw, precision, side = "BUY", slippageToleranceBps = 0) {
496
573
  const normalized = normalizePrice(raw);
@@ -505,34 +582,38 @@ function precisePrice(connector, raw, precision, side = "BUY", slippageTolerance
505
582
  return preciseTickGridPrice(effectiveRaw, precision, side);
506
583
  }
507
584
  }
585
+ __name(precisePrice, "precisePrice");
508
586
  function withSlippageTolerance(normalized, slippageToleranceBps, side) {
509
587
  if (slippageToleranceBps === 0) {
510
588
  return normalized;
511
589
  }
512
- const bps = new BigNumber9(slippageToleranceBps);
590
+ const bps = new BigNumber7(slippageToleranceBps);
513
591
  const factor = bps.div(1e4);
514
- return side === "BUY" ? normalized.times(new BigNumber9(1).plus(factor)) : normalized.times(new BigNumber9(1).minus(factor));
592
+ return side === "BUY" ? normalized.times(new BigNumber7(1).plus(factor)) : normalized.times(new BigNumber7(1).minus(factor));
515
593
  }
594
+ __name(withSlippageTolerance, "withSlippageTolerance");
516
595
  function preciseHyperliquidPrice(price, precision, side) {
517
596
  const maxDecimals = precision.price.decimals;
518
597
  const maxSigFigs = precision.price.sigFigs ?? 5;
519
- const rounding = side === "BUY" ? BigNumber9.ROUND_FLOOR : BigNumber9.ROUND_CEIL;
598
+ const rounding = side === "BUY" ? BigNumber7.ROUND_FLOOR : BigNumber7.ROUND_CEIL;
520
599
  price = price.decimalPlaces(maxDecimals, rounding);
521
600
  price = clampSigFigs(price, maxSigFigs, maxDecimals, rounding);
522
601
  return price.toFixed();
523
602
  }
603
+ __name(preciseHyperliquidPrice, "preciseHyperliquidPrice");
524
604
  function preciseTickGridPrice(price, precision, side) {
525
605
  const tick = precision.price.tick ?? 1e-4;
526
- const rounding = side === "BUY" ? BigNumber9.ROUND_FLOOR : BigNumber9.ROUND_CEIL;
527
- const tickBN = new BigNumber9(tick);
606
+ const rounding = side === "BUY" ? BigNumber7.ROUND_FLOOR : BigNumber7.ROUND_CEIL;
607
+ const tickBN = new BigNumber7(tick);
528
608
  const scaled = price.div(tickBN);
529
609
  const snapped = scaled.integerValue(rounding).times(tickBN);
530
610
  const maxDecimals = precision.price.decimals;
531
611
  const final = snapped.decimalPlaces(maxDecimals, rounding);
532
612
  return final.toFixed();
533
613
  }
614
+ __name(preciseTickGridPrice, "preciseTickGridPrice");
534
615
  function clampSigFigs(price, maxSigFigs, maxDecimals, rounding) {
535
- const countSigFigs = (value) => value.toFixed().replace(".", "").replace(/^0+/, "").length;
616
+ const countSigFigs = /* @__PURE__ */ __name((value) => value.toFixed().replace(".", "").replace(/^0+/, "").length, "countSigFigs");
536
617
  if (countSigFigs(price) <= maxSigFigs) {
537
618
  return price;
538
619
  }
@@ -544,13 +625,15 @@ function clampSigFigs(price, maxSigFigs, maxDecimals, rounding) {
544
625
  }
545
626
  return price;
546
627
  }
628
+ __name(clampSigFigs, "clampSigFigs");
547
629
  function normalizePrice(value) {
548
- const parsed = new BigNumber9(value);
549
- return new BigNumber9(parsed.toFixed());
630
+ const parsed = new BigNumber7(value);
631
+ return new BigNumber7(parsed.toFixed());
550
632
  }
551
- BigNumber9.config({
633
+ __name(normalizePrice, "normalizePrice");
634
+ BigNumber7.config({
552
635
  DECIMAL_PLACES: 30,
553
- ROUNDING_MODE: BigNumber9.ROUND_DOWN
636
+ ROUNDING_MODE: BigNumber7.ROUND_DOWN
554
637
  });
555
638
  function preciseQuantity(connector, raw, precision, side) {
556
639
  switch (connector) {
@@ -563,23 +646,26 @@ function preciseQuantity(connector, raw, precision, side) {
563
646
  return preciseStepGridQuantity(raw, precision, side);
564
647
  }
565
648
  }
649
+ __name(preciseQuantity, "preciseQuantity");
566
650
  function preciseHyperliquidQuantity(raw, precision, side) {
567
651
  const decimals = precision.quantity.decimals;
568
- const quantity = new BigNumber9(raw);
569
- const rounded = quantity.decimalPlaces(decimals, side === "BUY" ? BigNumber9.ROUND_FLOOR : BigNumber9.ROUND_CEIL);
652
+ const quantity = new BigNumber7(raw);
653
+ const rounded = quantity.decimalPlaces(decimals, side === "BUY" ? BigNumber7.ROUND_FLOOR : BigNumber7.ROUND_CEIL);
570
654
  return rounded.toFixed();
571
655
  }
656
+ __name(preciseHyperliquidQuantity, "preciseHyperliquidQuantity");
572
657
  function preciseStepGridQuantity(raw, precision, side) {
573
658
  const step = precision.quantity.step;
574
659
  const contractQuantity = baseToContracts(raw, precision.quantity.contractSize);
575
- const stepBN = new BigNumber9(step);
660
+ const stepBN = new BigNumber7(step);
576
661
  const scaled = contractQuantity.div(stepBN);
577
- const rounded = side === "BUY" ? scaled.integerValue(BigNumber9.ROUND_FLOOR) : scaled.integerValue(BigNumber9.ROUND_CEIL);
662
+ const rounded = side === "BUY" ? scaled.integerValue(BigNumber7.ROUND_FLOOR) : scaled.integerValue(BigNumber7.ROUND_CEIL);
578
663
  const result = rounded.times(stepBN);
579
664
  const maxDecimals = precision.quantity.decimals;
580
- const final = result.decimalPlaces(maxDecimals, side === "BUY" ? BigNumber9.ROUND_FLOOR : BigNumber9.ROUND_CEIL);
665
+ const final = result.decimalPlaces(maxDecimals, side === "BUY" ? BigNumber7.ROUND_FLOOR : BigNumber7.ROUND_CEIL);
581
666
  return final.toFixed();
582
667
  }
668
+ __name(preciseStepGridQuantity, "preciseStepGridQuantity");
583
669
 
584
670
  // src/proxy.ts
585
671
  var activeOrigin = null;
@@ -594,12 +680,14 @@ function configureProxy(config) {
594
680
  activeOrigin = null;
595
681
  }
596
682
  }
683
+ __name(configureProxy, "configureProxy");
597
684
  function toProxyUrl(target, origin) {
598
685
  const proxied = new URL(origin);
599
686
  proxied.pathname = target.pathname;
600
687
  proxied.search = target.search;
601
688
  return proxied.toString();
602
689
  }
690
+ __name(toProxyUrl, "toProxyUrl");
603
691
  async function withProxyFallback(proxied, direct) {
604
692
  try {
605
693
  const response = await proxied();
@@ -608,17 +696,19 @@ async function withProxyFallback(proxied, direct) {
608
696
  }
609
697
  return direct();
610
698
  }
699
+ __name(withProxyFallback, "withProxyFallback");
611
700
  function proxyFetch(input, init) {
612
701
  const origin = activeOrigin;
613
702
  if (!origin) return fetch(input, init);
614
703
  const target = new URL(input);
615
704
  const headers = new Headers(init?.headers);
616
705
  headers.set("X-Proxy-Target", target.host);
617
- return withProxyFallback(
618
- () => fetch(toProxyUrl(target, origin), { ...init, headers }),
619
- () => fetch(input, init)
620
- );
706
+ return withProxyFallback(() => fetch(toProxyUrl(target, origin), {
707
+ ...init,
708
+ headers
709
+ }), () => fetch(input, init));
621
710
  }
711
+ __name(proxyFetch, "proxyFetch");
622
712
 
623
713
  // src/sync/applicables/constants.ts
624
714
  var DUST = parse("0.00000001");
@@ -626,8 +716,8 @@ var MISSED_HISTORY_FILL_PREFIX = "opening-synthetic-";
626
716
  var BASKET_RULES = [
627
717
  // V2 Basket Hyperliquid — legs of one Pear basket order share the order's cloid.
628
718
  {
629
- matches: (fill) => fill.connector === "hyperliquid" && isPearCloid(fill.connector, fill.cloid),
630
- key: (fill) => `v2-basket-hl ${fill.cloid}`
719
+ matches: /* @__PURE__ */ __name((fill) => fill.connector === "hyperliquid" && isPearCloid(fill.connector, fill.cloid), "matches"),
720
+ key: /* @__PURE__ */ __name((fill) => `v2-basket-hl ${fill.cloid}`, "key")
631
721
  }
632
722
  ];
633
723
  function isPearCloid(connector, cloid) {
@@ -636,17 +726,21 @@ function isPearCloid(connector, cloid) {
636
726
  }
637
727
  return PEAR_CLOID_CHECK[connector]?.(cloid) ?? false;
638
728
  }
729
+ __name(isPearCloid, "isPearCloid");
639
730
  var PEAR_CLOID_CHECK = {
640
- hyperliquid: (cloid) => cloid.startsWith("0x50454152"),
641
- lighter: (cloid) => cloid.length === 15 && cloid.startsWith("10")
731
+ hyperliquid: /* @__PURE__ */ __name((cloid) => cloid.startsWith("0x50454152"), "hyperliquid"),
732
+ lighter: /* @__PURE__ */ __name((cloid) => cloid.length === 15 && cloid.startsWith("10"), "lighter")
642
733
  };
643
734
 
644
735
  // src/sync/applicables/basket.ts
645
736
  var Basket = class _Basket {
737
+ static {
738
+ __name(this, "Basket");
739
+ }
740
+ legs;
646
741
  constructor(legs) {
647
742
  this.legs = legs;
648
743
  }
649
- legs;
650
744
  /** Detect baskets from a fill stream, returned in ascending time order. */
651
745
  static detect(fills) {
652
746
  return groupFillsIntoBaskets(fills).map((group) => new _Basket(combineFillsBySymbolAndSide(group)));
@@ -661,26 +755,32 @@ var Basket = class _Basket {
661
755
  }
662
756
  };
663
757
  var CombinedLeg = class {
664
- constructor(symbol, side) {
665
- this.symbol = symbol;
666
- this.side = side;
758
+ static {
759
+ __name(this, "CombinedLeg");
667
760
  }
668
761
  symbol;
669
762
  side;
670
763
  _totalSize = ZERO;
671
764
  queue = [];
765
+ constructor(symbol, side) {
766
+ this.symbol = symbol;
767
+ this.side = side;
768
+ }
672
769
  get totalSize() {
673
770
  return this._totalSize;
674
771
  }
675
772
  /** Append a fill to this leg's queue and grow the total size. */
676
773
  addFill(fill) {
677
774
  this._totalSize = this._totalSize.plus(fill.quantity);
678
- this.queue.push({ fill, remaining: parse(fill.quantity) });
775
+ this.queue.push({
776
+ fill,
777
+ remaining: parse(fill.quantity)
778
+ });
679
779
  }
680
780
  /**
681
- * Take `qty` of fill slices from this leg (FIFO across source fills, consumes the queue).
682
- * Returns the parts taken, which are consumed from the queue.
683
- */
781
+ * Take `qty` of fill slices from this leg (FIFO across source fills, consumes the queue).
782
+ * Returns the parts taken, which are consumed from the queue.
783
+ */
684
784
  take(qty) {
685
785
  const parts = [];
686
786
  let need = qty;
@@ -692,7 +792,10 @@ var CombinedLeg = class {
692
792
  continue;
693
793
  }
694
794
  const taken = min(entry.remaining, need);
695
- parts.push({ source: entry.fill, quantity: taken.toFixed() });
795
+ parts.push({
796
+ source: entry.fill,
797
+ quantity: taken.toFixed()
798
+ });
696
799
  entry.remaining = entry.remaining.minus(taken);
697
800
  need = need.minus(taken);
698
801
  }
@@ -704,14 +807,20 @@ function groupFillsIntoBaskets(fills) {
704
807
  for (const fill of fills) {
705
808
  const rule = BASKET_RULES.find((r) => r.matches(fill));
706
809
  const key = rule ? rule.key(fill) : `id ${fill.exchangeFillId}`;
707
- const bucket = buckets.get(key) ?? { timestamp: fill.timestamp, fills: [] };
810
+ const bucket = buckets.get(key) ?? {
811
+ timestamp: fill.timestamp,
812
+ fills: []
813
+ };
708
814
  bucket.timestamp = Math.min(bucket.timestamp, fill.timestamp);
709
815
  bucket.fills.push(fill);
710
816
  buckets.set(key, bucket);
711
817
  }
712
- const sorted = [...buckets.values()].sort((a, b) => a.timestamp - b.timestamp);
818
+ const sorted = [
819
+ ...buckets.values()
820
+ ].sort((a, b) => a.timestamp - b.timestamp);
713
821
  return sorted.map((bucket) => bucket.fills);
714
822
  }
823
+ __name(groupFillsIntoBaskets, "groupFillsIntoBaskets");
715
824
  function combineFillsBySymbolAndSide(group) {
716
825
  const map = /* @__PURE__ */ new Map();
717
826
  for (const fill of group) {
@@ -723,15 +832,21 @@ function combineFillsBySymbolAndSide(group) {
723
832
  }
724
833
  combined.addFill(fill);
725
834
  }
726
- return [...map.values()];
835
+ return [
836
+ ...map.values()
837
+ ];
727
838
  }
839
+ __name(combineFillsBySymbolAndSide, "combineFillsBySymbolAndSide");
728
840
 
729
841
  // src/sync/applicables/exposure.ts
730
842
  var Exposure = class _Exposure {
843
+ static {
844
+ __name(this, "Exposure");
845
+ }
846
+ legs;
731
847
  constructor(legs) {
732
848
  this.legs = legs;
733
849
  }
734
- legs;
735
850
  /** Create an exposure with no legs — the starting state for a new position. */
736
851
  static empty() {
737
852
  return new _Exposure(/* @__PURE__ */ new Map());
@@ -784,7 +899,10 @@ var Exposure = class _Exposure {
784
899
  break;
785
900
  }
786
901
  }
787
- return { longs, shorts };
902
+ return {
903
+ longs,
904
+ shorts
905
+ };
788
906
  }
789
907
  /** True once every leg sits within DUST of zero (effectively closed). */
790
908
  isFlat() {
@@ -805,10 +923,10 @@ var Exposure = class _Exposure {
805
923
  return true;
806
924
  }
807
925
  /**
808
- * Snap every non-zero leg to exactly zero. Called once a position is flat so it
809
- * reads CLOSED (all-zero exposure) and never lingers in the open list with stray
810
- * dust that a later reopen of the same pair could merge into.
811
- */
926
+ * Snap every non-zero leg to exactly zero. Called once a position is flat so it
927
+ * reads CLOSED (all-zero exposure) and never lingers in the open list with stray
928
+ * dust that a later reopen of the same pair could merge into.
929
+ */
812
930
  snapToZero() {
813
931
  for (const [symbol, qty] of this.legs) {
814
932
  if (!qty.isZero()) {
@@ -818,7 +936,9 @@ var Exposure = class _Exposure {
818
936
  }
819
937
  /** All symbols with a leg, including zeroed ones (a closed leg still carries cost basis). */
820
938
  symbols() {
821
- return [...this.legs.keys()];
939
+ return [
940
+ ...this.legs.keys()
941
+ ];
822
942
  }
823
943
  /** Canonical signed-string view for the wire (`+0` for zero). */
824
944
  toSigned() {
@@ -833,29 +953,43 @@ var Exposure = class _Exposure {
833
953
  // src/sync/applicables/matching.ts
834
954
  function matchPositions(args) {
835
955
  const { tradeAccountId, orphanFills, pear } = args;
836
- const book = WorkingBook.load({ tradeAccountId, openPositions: pear.positions() });
956
+ const book = WorkingBook.load({
957
+ tradeAccountId,
958
+ openPositions: pear.positions()
959
+ });
837
960
  for (const basket of Basket.detect(orphanFills)) {
838
961
  const exactCloseTarget = findExactCloseTarget(book.open(), basket.longs, basket.shorts);
839
- const leftover = applyCloses({ legs: basket.legs, book, exactCloseTarget });
962
+ const leftover = applyCloses({
963
+ legs: basket.legs,
964
+ book,
965
+ exactCloseTarget
966
+ });
840
967
  if (leftover.length === 0) {
841
968
  continue;
842
969
  }
843
- const target = resolveLeftoverTarget({ book, leftover });
970
+ const target = resolveLeftoverTarget({
971
+ book,
972
+ leftover
973
+ });
844
974
  applyLeftover(target, leftover);
845
975
  }
846
976
  return book.toMatched();
847
977
  }
848
- var WorkingBook = class _WorkingBook {
849
- constructor(tradeAccountId) {
850
- this.tradeAccountId = tradeAccountId;
978
+ __name(matchPositions, "matchPositions");
979
+ var WorkingBook = class WorkingBook2 {
980
+ static {
981
+ __name(this, "WorkingBook");
851
982
  }
852
983
  tradeAccountId;
853
984
  all = [];
854
985
  openByKey = /* @__PURE__ */ new Map();
986
+ constructor(tradeAccountId) {
987
+ this.tradeAccountId = tradeAccountId;
988
+ }
855
989
  /** Seed the book from existing open DB positions (they arrive pre-filtered by connector). */
856
990
  static load(args) {
857
991
  const { tradeAccountId, openPositions } = args;
858
- const book = new _WorkingBook(tradeAccountId);
992
+ const book = new WorkingBook2(tradeAccountId);
859
993
  for (const p of openPositions) {
860
994
  const position = {
861
995
  // Trust the position's own stored key — never recompute it from exposure.
@@ -874,7 +1008,10 @@ var WorkingBook = class _WorkingBook {
874
1008
  }
875
1009
  /** Deterministic position key for a symbol set under this book's trade account. */
876
1010
  keyFor(symbols) {
877
- return generateDeterministicPositionKey({ tradeAccountId: this.tradeAccountId, symbols });
1011
+ return generateDeterministicPositionKey({
1012
+ tradeAccountId: this.tradeAccountId,
1013
+ symbols
1014
+ });
878
1015
  }
879
1016
  /** Currently open working positions, in insertion order. */
880
1017
  open() {
@@ -922,7 +1059,10 @@ function findExactCloseTarget(openList, basketLongs, basketShorts) {
922
1059
  return setEq(longs, basketShorts) && setEq(shorts, basketLongs);
923
1060
  });
924
1061
  }
925
- var setEq = (a, b) => a.size === b.size && [...a].every((x) => b.has(x));
1062
+ __name(findExactCloseTarget, "findExactCloseTarget");
1063
+ var setEq = /* @__PURE__ */ __name((a, b) => a.size === b.size && [
1064
+ ...a
1065
+ ].every((x) => b.has(x)), "setEq");
926
1066
  function applyCloses(args) {
927
1067
  const { legs, book, exactCloseTarget } = args;
928
1068
  const openList = book.open();
@@ -952,48 +1092,75 @@ function applyCloses(args) {
952
1092
  book.markClosedIfFlat(position);
953
1093
  }
954
1094
  if (isGreaterThanOrEqual(remaining, DUST)) {
955
- leftover.push({ side: leg.side, qty: remaining, leg });
1095
+ leftover.push({
1096
+ side: leg.side,
1097
+ qty: remaining,
1098
+ leg
1099
+ });
956
1100
  }
957
1101
  }
958
1102
  return leftover;
959
1103
  }
1104
+ __name(applyCloses, "applyCloses");
960
1105
  function resolveLeftoverTarget(args) {
961
1106
  const { book, leftover } = args;
962
1107
  const leftoverLongs = new Set(leftover.filter((entry) => entry.side === "BUY").map((entry) => entry.leg.symbol));
963
1108
  const leftoverShorts = new Set(leftover.filter((entry) => entry.side === "SELL").map((entry) => entry.leg.symbol));
964
1109
  const target = book.open().find((position) => {
965
1110
  const { longs, shorts } = position.exposure.activeLegs();
966
- const longOk = [...leftoverLongs].every((a) => longs.has(a));
967
- const shortOk = [...leftoverShorts].every((a) => shorts.has(a));
968
- return longOk && shortOk;
1111
+ const sameActiveShape = setEq(leftoverLongs, longs) && setEq(leftoverShorts, shorts);
1112
+ const noDormantLegs = position.exposure.symbols().length === longs.size + shorts.size;
1113
+ return sameActiveShape && noDormantLegs;
969
1114
  });
970
1115
  if (target) {
971
1116
  return target;
972
1117
  }
973
- const symbols = [.../* @__PURE__ */ new Set([...leftoverLongs, ...leftoverShorts])];
1118
+ const symbols = [
1119
+ .../* @__PURE__ */ new Set([
1120
+ ...leftoverLongs,
1121
+ ...leftoverShorts
1122
+ ])
1123
+ ];
974
1124
  const positionKey = book.keyFor(symbols);
975
1125
  return book.findOpenByKey(positionKey) ?? book.create(positionKey);
976
1126
  }
1127
+ __name(resolveLeftoverTarget, "resolveLeftoverTarget");
977
1128
  function applyLeftover(target, leftover) {
978
1129
  for (const entry of leftover) {
979
1130
  target.parts.push(...entry.leg.take(entry.qty));
980
1131
  target.exposure.addSigned(entry.leg.symbol, entry.qty.toFixed(), entry.side);
981
1132
  }
982
1133
  }
1134
+ __name(applyLeftover, "applyLeftover");
983
1135
 
984
1136
  // src/sync/applicables/synthetics.ts
985
1137
  function isMissedHistoryFill(fill) {
986
1138
  return fill.exchangeFillId.startsWith(MISSED_HISTORY_FILL_PREFIX);
987
1139
  }
1140
+ __name(isMissedHistoryFill, "isMissedHistoryFill");
988
1141
  function addFillsForMissedHistory(args) {
989
1142
  const missedHistoryFills = buildMissedHistoryFills(args);
990
- return [...missedHistoryFills, ...args.orphanFills].sort((a, b) => a.timestamp - b.timestamp);
1143
+ return [
1144
+ ...missedHistoryFills,
1145
+ ...args.orphanFills
1146
+ ].sort((a, b) => a.timestamp - b.timestamp);
991
1147
  }
1148
+ __name(addFillsForMissedHistory, "addFillsForMissedHistory");
992
1149
  function alignPositionsWithExchange(args) {
993
1150
  const { positions, pear, snapshot, tradeAccountId } = args;
994
- const neededSynthetics = findNeededSynthetics({ positions, pear, snapshot });
995
- return assignSyntheticsToPositions({ neededSynthetics, positions, pear, tradeAccountId });
1151
+ const neededSynthetics = findNeededSynthetics({
1152
+ positions,
1153
+ pear,
1154
+ snapshot
1155
+ });
1156
+ return assignSyntheticsToPositions({
1157
+ neededSynthetics,
1158
+ positions,
1159
+ pear,
1160
+ tradeAccountId
1161
+ });
996
1162
  }
1163
+ __name(alignPositionsWithExchange, "alignPositionsWithExchange");
997
1164
  function buildSyntheticFill(args) {
998
1165
  return {
999
1166
  // Content-addressed id — no wall-clock, no positionId, so re-syncs collide
@@ -1020,6 +1187,7 @@ function buildSyntheticFill(args) {
1020
1187
  liquidation: null
1021
1188
  };
1022
1189
  }
1190
+ __name(buildSyntheticFill, "buildSyntheticFill");
1023
1191
  function buildMissedHistoryFills(args) {
1024
1192
  const { orphanFills, pear, connector, entryBySymbol, snapshot } = args;
1025
1193
  const fillTotals = /* @__PURE__ */ new Map();
@@ -1030,13 +1198,16 @@ function buildMissedHistoryFills(args) {
1030
1198
  orphanNotional.set(fill.symbol, add(orphanNotional.get(fill.symbol) ?? ZERO, notional));
1031
1199
  }
1032
1200
  const pearTotals = pear.totalBySymbol();
1033
- const assets = /* @__PURE__ */ new Set([...orphanFills.map((fill) => fill.symbol), ...snapshot.symbols()]);
1201
+ const assets = /* @__PURE__ */ new Set([
1202
+ ...orphanFills.map((fill) => fill.symbol),
1203
+ ...snapshot.symbols()
1204
+ ]);
1034
1205
  const earliestTs = orphanFills.reduce((min2, fill) => Math.min(min2, fill.timestamp), Infinity);
1035
1206
  if (!Number.isFinite(earliestTs)) {
1036
1207
  return [];
1037
1208
  }
1038
1209
  const watermark = Math.max(1, earliestTs - 1);
1039
- const haveBySymbol = (symbol) => add(pearTotals.get(symbol) ?? ZERO, fillTotals.get(symbol) ?? ZERO);
1210
+ const haveBySymbol = /* @__PURE__ */ __name((symbol) => add(pearTotals.get(symbol) ?? ZERO, fillTotals.get(symbol) ?? ZERO), "haveBySymbol");
1040
1211
  const result = [];
1041
1212
  for (const gap of gapsToTarget({
1042
1213
  assets,
@@ -1068,6 +1239,7 @@ function buildMissedHistoryFills(args) {
1068
1239
  }
1069
1240
  return result;
1070
1241
  }
1242
+ __name(buildMissedHistoryFills, "buildMissedHistoryFills");
1071
1243
  function priceForMissedHistoryFill(args) {
1072
1244
  const { exchangePosition, syntheticQty, pearQty, pearEntry, orphanNotional } = args;
1073
1245
  const fallback = exchangePosition?.entryPrice ?? "0";
@@ -1089,6 +1261,7 @@ function priceForMissedHistoryFill(args) {
1089
1261
  const derived = divide(subtract(targetNotional, realNotional), synthQty);
1090
1262
  return derived.isFinite() && derived.isPositive() ? derived.toFixed() : fallback;
1091
1263
  }
1264
+ __name(priceForMissedHistoryFill, "priceForMissedHistoryFill");
1092
1265
  function findNeededSynthetics(args) {
1093
1266
  const { positions, pear, snapshot } = args;
1094
1267
  const pearTotals = pear.totalBySymbol();
@@ -1104,13 +1277,13 @@ function findNeededSynthetics(args) {
1104
1277
  for (const symbol of pearTotals.keys()) {
1105
1278
  assets.add(symbol);
1106
1279
  }
1107
- const haveBySymbol = (symbol) => {
1280
+ const haveBySymbol = /* @__PURE__ */ __name((symbol) => {
1108
1281
  let totalFills = ZERO;
1109
1282
  for (const pos of positions) {
1110
1283
  totalFills = add(totalFills, Exposure.netFromParts(pos.parts, symbol));
1111
1284
  }
1112
1285
  return add(pearTotals.get(symbol) ?? ZERO, totalFills);
1113
- };
1286
+ }, "haveBySymbol");
1114
1287
  const result = /* @__PURE__ */ new Map();
1115
1288
  for (const gap of gapsToTarget({
1116
1289
  assets,
@@ -1137,9 +1310,13 @@ function findNeededSynthetics(args) {
1137
1310
  }
1138
1311
  return result;
1139
1312
  }
1313
+ __name(findNeededSynthetics, "findNeededSynthetics");
1140
1314
  function assignSyntheticsToPositions(args) {
1141
1315
  const { neededSynthetics, positions, pear, tradeAccountId } = args;
1142
- const keyOf = (symbols) => generateDeterministicPositionKey({ tradeAccountId, symbols });
1316
+ const keyOf = /* @__PURE__ */ __name((symbols) => generateDeterministicPositionKey({
1317
+ tradeAccountId,
1318
+ symbols
1319
+ }), "keyOf");
1143
1320
  const existingBySymbol = pear.positionBySymbol();
1144
1321
  const created = [];
1145
1322
  const byPosition = /* @__PURE__ */ new Map();
@@ -1147,11 +1324,12 @@ function assignSyntheticsToPositions(args) {
1147
1324
  let target = positions.find((pos) => !pos.closed && pos.parts.some((part) => part.source.symbol === symbol));
1148
1325
  if (!target) {
1149
1326
  const existing = existingBySymbol.get(symbol);
1150
- const positionKey = existing ? existing.positionKey : keyOf([symbol]);
1327
+ const positionKey = existing ? existing.positionKey : keyOf([
1328
+ symbol
1329
+ ]);
1151
1330
  target = positions.find((pos) => pos.positionKey === positionKey) ?? created.find((pos) => pos.positionKey === positionKey);
1152
1331
  if (!target) {
1153
1332
  target = existing ? (
1154
- // Stand-in for an existing DB position untouched by this batch's fills:
1155
1333
  // seed its exposure and origin so folding the synthetic yields the true
1156
1334
  // final state (a gone-close nets to zero -> CLOSED/NETTED, a gap writes
1157
1335
  // the full total, not just the delta).
@@ -1175,8 +1353,15 @@ function assignSyntheticsToPositions(args) {
1175
1353
  list.push(spec);
1176
1354
  byPosition.set(target, list);
1177
1355
  }
1178
- return { positions: [...positions, ...created], synthByPosition: byPosition };
1356
+ return {
1357
+ positions: [
1358
+ ...positions,
1359
+ ...created
1360
+ ],
1361
+ synthByPosition: byPosition
1362
+ };
1179
1363
  }
1364
+ __name(assignSyntheticsToPositions, "assignSyntheticsToPositions");
1180
1365
  function gapsToTarget(args) {
1181
1366
  const { assets, haveBySymbol, snapshot } = args;
1182
1367
  const gaps = [];
@@ -1192,6 +1377,7 @@ function gapsToTarget(args) {
1192
1377
  }
1193
1378
  return gaps;
1194
1379
  }
1380
+ __name(gapsToTarget, "gapsToTarget");
1195
1381
  function findGapToTarget(args) {
1196
1382
  const { symbol, have, target } = args;
1197
1383
  if (isZero(target)) {
@@ -1216,6 +1402,7 @@ function findGapToTarget(args) {
1216
1402
  }
1217
1403
  return null;
1218
1404
  }
1405
+ __name(findGapToTarget, "findGapToTarget");
1219
1406
 
1220
1407
  // src/sync/applicables/fills.ts
1221
1408
  function assignPartIds(positions) {
@@ -1231,13 +1418,18 @@ function assignPartIds(positions) {
1231
1418
  for (const [sourceId, parts] of bySource) {
1232
1419
  const single = parts.length === 1 ? parts[0] : void 0;
1233
1420
  if (single && isEqualTo(single.quantity, single.source.quantity)) {
1234
- resolution.set(single, { exchangeFillId: sourceId });
1421
+ resolution.set(single, {
1422
+ exchangeFillId: sourceId
1423
+ });
1235
1424
  continue;
1236
1425
  }
1237
1426
  parts.forEach((part, i) => {
1238
1427
  resolution.set(part, {
1239
1428
  exchangeFillId: `${sourceId}-p${i}`,
1240
- original: { exchangeFillId: sourceId, quantity: part.source.quantity }
1429
+ original: {
1430
+ exchangeFillId: sourceId,
1431
+ quantity: part.source.quantity
1432
+ }
1241
1433
  });
1242
1434
  });
1243
1435
  }
@@ -1249,6 +1441,7 @@ function assignPartIds(positions) {
1249
1441
  return id;
1250
1442
  };
1251
1443
  }
1444
+ __name(assignPartIds, "assignPartIds");
1252
1445
  function partToApplicableFill(part, id, connector) {
1253
1446
  const fill = part.source;
1254
1447
  const base = {
@@ -1283,9 +1476,12 @@ function partToApplicableFill(part, id, connector) {
1283
1476
  tradeFee: feeShareForPart(fill.tradeFee, part.quantity, fill.quantity),
1284
1477
  builderFee: feeShareForPart(fill.builderFee, part.quantity, fill.quantity),
1285
1478
  liquidation: fill.liquidation,
1286
- ...id.original ? { original: id.original } : {}
1479
+ ...id.original ? {
1480
+ original: id.original
1481
+ } : {}
1287
1482
  };
1288
1483
  }
1484
+ __name(partToApplicableFill, "partToApplicableFill");
1289
1485
  function feeShareForPart(totalFee, partQty, sourceQty) {
1290
1486
  if (isEqualTo(partQty, sourceQty)) {
1291
1487
  return totalFee;
@@ -1296,6 +1492,7 @@ function feeShareForPart(totalFee, partQty, sourceQty) {
1296
1492
  const feeShare = divide(multiply(totalFee, partQty), sourceQty);
1297
1493
  return feeShare.toFixed();
1298
1494
  }
1495
+ __name(feeShareForPart, "feeShareForPart");
1299
1496
 
1300
1497
  // src/sync/applicables/position.ts
1301
1498
  function assembleApplicables(args) {
@@ -1310,17 +1507,19 @@ function assembleApplicables(args) {
1310
1507
  }
1311
1508
  return applicables;
1312
1509
  }
1510
+ __name(assembleApplicables, "assembleApplicables");
1313
1511
  function assembleOneApplicable(pos, connector, partIdFor, assignedSynthetics, now) {
1314
1512
  const realFills = pos.parts.map((part) => partToApplicableFill(part, partIdFor(part), connector)).sort((a, b) => a.timestamp - b.timestamp);
1315
- const syntheticFills = assignedSynthetics.map(
1316
- (synthetic) => buildSyntheticFill({
1317
- positionKey: pos.positionKey,
1318
- connector,
1319
- timestamp: anchorSyntheticTimestamp(realFills, synthetic.symbol, now),
1320
- ...synthetic
1321
- })
1322
- );
1323
- const fills = [...realFills, ...syntheticFills].sort((a, b) => a.timestamp - b.timestamp);
1513
+ const syntheticFills = assignedSynthetics.map((synthetic) => buildSyntheticFill({
1514
+ positionKey: pos.positionKey,
1515
+ connector,
1516
+ timestamp: anchorSyntheticTimestamp(realFills, synthetic.symbol, now),
1517
+ ...synthetic
1518
+ }));
1519
+ const fills = [
1520
+ ...realFills,
1521
+ ...syntheticFills
1522
+ ].sort((a, b) => a.timestamp - b.timestamp);
1324
1523
  if (fills.length === 0) {
1325
1524
  return null;
1326
1525
  }
@@ -1333,11 +1532,14 @@ function assembleOneApplicable(pos, connector, partIdFor, assignedSynthetics, no
1333
1532
  exposure: exposure.toSigned(),
1334
1533
  origin,
1335
1534
  status,
1336
- ...closed ? { closedReason: "NETTED" } : {},
1535
+ ...closed ? {
1536
+ closedReason: "NETTED"
1537
+ } : {},
1337
1538
  fills,
1338
1539
  metadata: buildMetadata(new Set(exposure.symbols()), realFills)
1339
1540
  };
1340
1541
  }
1542
+ __name(assembleOneApplicable, "assembleOneApplicable");
1341
1543
  function finalExposure(pos, synthetics) {
1342
1544
  const exposure = pos.exposure.clone();
1343
1545
  for (const synthetic of synthetics) {
@@ -1345,6 +1547,7 @@ function finalExposure(pos, synthetics) {
1345
1547
  }
1346
1548
  return exposure;
1347
1549
  }
1550
+ __name(finalExposure, "finalExposure");
1348
1551
  function anchorSyntheticTimestamp(realFills, symbol, now) {
1349
1552
  const oldestForSymbol = realFills.find((fill) => fill.symbol === symbol)?.timestamp;
1350
1553
  if (oldestForSymbol !== void 0) {
@@ -1353,12 +1556,16 @@ function anchorSyntheticTimestamp(realFills, symbol, now) {
1353
1556
  const oldestRealTs = realFills[0]?.timestamp;
1354
1557
  return oldestRealTs !== void 0 ? Math.max(1, oldestRealTs - 1) : now;
1355
1558
  }
1559
+ __name(anchorSyntheticTimestamp, "anchorSyntheticTimestamp");
1356
1560
  function buildMetadata(symbols, realFills) {
1357
1561
  const initialExposureUSD = {};
1358
1562
  for (const symbol of symbols) {
1359
- const legFills = realFills.flatMap(
1360
- (fill) => fill.symbol === symbol && fill.usd != null ? [{ side: fill.side, usd: fill.usd }] : []
1361
- );
1563
+ const legFills = realFills.flatMap((fill) => fill.symbol === symbol && fill.usd != null ? [
1564
+ {
1565
+ side: fill.side,
1566
+ usd: fill.usd
1567
+ }
1568
+ ] : []);
1362
1569
  const opener = legFills[0];
1363
1570
  if (!opener) {
1364
1571
  continue;
@@ -1367,8 +1574,11 @@ function buildMetadata(symbols, realFills) {
1367
1574
  const signedNotional = signed(opener.side === "BUY" ? notional : notional.negated());
1368
1575
  initialExposureUSD[symbol] = signedNotional;
1369
1576
  }
1370
- return { initialExposureUSD };
1577
+ return {
1578
+ initialExposureUSD
1579
+ };
1371
1580
  }
1581
+ __name(buildMetadata, "buildMetadata");
1372
1582
  function mergeOrigin(existing, fills) {
1373
1583
  let anyExternal = false;
1374
1584
  let anyPear = false;
@@ -1396,16 +1606,23 @@ function mergeOrigin(existing, fills) {
1396
1606
  }
1397
1607
  return anyPear ? "PEAR" : "EXTERNAL";
1398
1608
  }
1609
+ __name(mergeOrigin, "mergeOrigin");
1399
1610
 
1400
1611
  // src/sync/applicables/snapshot.ts
1401
1612
  var ExchangeSnapshot = class _ExchangeSnapshot {
1613
+ static {
1614
+ __name(this, "ExchangeSnapshot");
1615
+ }
1616
+ bySymbol;
1402
1617
  constructor(bySymbol) {
1403
1618
  this.bySymbol = bySymbol;
1404
1619
  }
1405
- bySymbol;
1406
1620
  /** Index `positions` by symbol for O(1) lookup. */
1407
1621
  static from(positions) {
1408
- return new _ExchangeSnapshot(new Map(positions.map((position) => [position.symbol, position])));
1622
+ return new _ExchangeSnapshot(new Map(positions.map((position) => [
1623
+ position.symbol,
1624
+ position
1625
+ ])));
1409
1626
  }
1410
1627
  /** Raw exchange position for `symbol`, or `undefined` when the exchange holds nothing. */
1411
1628
  get(symbol) {
@@ -1427,14 +1644,19 @@ var ExchangeSnapshot = class _ExchangeSnapshot {
1427
1644
  }
1428
1645
  /** All symbols the exchange currently reports a position for. */
1429
1646
  symbols() {
1430
- return [...this.bySymbol.keys()];
1647
+ return [
1648
+ ...this.bySymbol.keys()
1649
+ ];
1431
1650
  }
1432
1651
  };
1433
1652
  var PearHoldings = class _PearHoldings {
1653
+ static {
1654
+ __name(this, "PearHoldings");
1655
+ }
1656
+ filtered;
1434
1657
  constructor(filtered) {
1435
1658
  this.filtered = filtered;
1436
1659
  }
1437
- filtered;
1438
1660
  /** Filter `openPositions` to the given connector and wrap. */
1439
1661
  static from(args) {
1440
1662
  const { openPositions, connector } = args;
@@ -1458,10 +1680,10 @@ var PearHoldings = class _PearHoldings {
1458
1680
  return totals;
1459
1681
  }
1460
1682
  /**
1461
- * Which open DB position holds each active asset — the fallback target for a
1462
- * synthetic when no matched position already carries that asset. First open
1463
- * position with a non-zero leg wins per symbol.
1464
- */
1683
+ * Which open DB position holds each active asset — the fallback target for a
1684
+ * synthetic when no matched position already carries that asset. First open
1685
+ * position with a non-zero leg wins per symbol.
1686
+ */
1465
1687
  positionBySymbol() {
1466
1688
  const existingBySymbol = /* @__PURE__ */ new Map();
1467
1689
  for (const position of this.filtered) {
@@ -1481,18 +1703,37 @@ var PearHoldings = class _PearHoldings {
1481
1703
  function buildApplicables(args) {
1482
1704
  const { tradeAccountId, connector, orphanFills, openPositions, entryBySymbol, exchangePositions } = args;
1483
1705
  const snapshot = ExchangeSnapshot.from(exchangePositions);
1484
- const pear = PearHoldings.from({ openPositions, connector });
1706
+ const pear = PearHoldings.from({
1707
+ openPositions,
1708
+ connector
1709
+ });
1485
1710
  const now = Date.now();
1486
- const fills = addFillsForMissedHistory({ orphanFills, pear, connector, entryBySymbol, snapshot });
1487
- const matched = matchPositions({ tradeAccountId, orphanFills: fills, pear });
1711
+ const fills = addFillsForMissedHistory({
1712
+ orphanFills,
1713
+ pear,
1714
+ connector,
1715
+ entryBySymbol,
1716
+ snapshot
1717
+ });
1718
+ const matched = matchPositions({
1719
+ tradeAccountId,
1720
+ orphanFills: fills,
1721
+ pear
1722
+ });
1488
1723
  const { positions, synthByPosition } = alignPositionsWithExchange({
1489
1724
  positions: matched,
1490
1725
  pear,
1491
1726
  snapshot,
1492
1727
  tradeAccountId
1493
1728
  });
1494
- return assembleApplicables({ positions, connector, synthByPosition, now });
1729
+ return assembleApplicables({
1730
+ positions,
1731
+ connector,
1732
+ synthByPosition,
1733
+ now
1734
+ });
1495
1735
  }
1736
+ __name(buildApplicables, "buildApplicables");
1496
1737
 
1497
1738
  // src/sync/cutoff.ts
1498
1739
  function selectFirstSyncCutoff(args) {
@@ -1515,7 +1756,9 @@ function selectFirstSyncCutoff(args) {
1515
1756
  for (let boundary = fills.length; boundary >= 0; boundary--) {
1516
1757
  const withinAnchor = pearIndex === null || boundary <= pearIndex;
1517
1758
  if (withinAnchor && book.isAllZero() && isStrictTimestampBoundary(fills, boundary)) {
1518
- return boundary === 0 ? null : { keepFromIndex: boundary };
1759
+ return boundary === 0 ? null : {
1760
+ keepFromIndex: boundary
1761
+ };
1519
1762
  }
1520
1763
  const preceding = fills[boundary - 1];
1521
1764
  if (preceding) {
@@ -1524,6 +1767,7 @@ function selectFirstSyncCutoff(args) {
1524
1767
  }
1525
1768
  return null;
1526
1769
  }
1770
+ __name(selectFirstSyncCutoff, "selectFirstSyncCutoff");
1527
1771
  function findFirstPearFillIndex(connector, fills) {
1528
1772
  const index = fills.findIndex((fill) => isPearCloid(connector, fill.cloid));
1529
1773
  if (index === -1) {
@@ -1531,6 +1775,7 @@ function findFirstPearFillIndex(connector, fills) {
1531
1775
  }
1532
1776
  return index;
1533
1777
  }
1778
+ __name(findFirstPearFillIndex, "findFirstPearFillIndex");
1534
1779
  function isStrictTimestampBoundary(fills, boundary) {
1535
1780
  const before = fills[boundary - 1];
1536
1781
  const after = fills[boundary];
@@ -1539,26 +1784,13 @@ function isStrictTimestampBoundary(fills, boundary) {
1539
1784
  }
1540
1785
  return before.timestamp < after.timestamp;
1541
1786
  }
1787
+ __name(isStrictTimestampBoundary, "isStrictTimestampBoundary");
1542
1788
 
1543
1789
  // src/sync/compute.ts
1544
1790
  async function computeSyncPayload(args) {
1545
- const {
1546
- tradeAccountId,
1547
- connector,
1548
- openPositions,
1549
- entryBySymbol,
1550
- provisionalFills,
1551
- confirmedExchangeFillIds,
1552
- externalFills,
1553
- exchangePositions,
1554
- neverSynced
1555
- } = args;
1791
+ const { tradeAccountId, connector, openPositions, entryBySymbol, provisionalFills, confirmedExchangeFillIds, externalFills, exchangePositions, neverSynced } = args;
1556
1792
  const fillsToProcess = _prepareExternalFills(externalFills, confirmedExchangeFillIds);
1557
- const {
1558
- reconcilables,
1559
- confirmables: confirmableFills,
1560
- orphans
1561
- } = _segregateExternalFills(provisionalFills, fillsToProcess);
1793
+ const { reconcilables, confirmables: confirmableFills, orphans } = _segregateExternalFills(provisionalFills, fillsToProcess);
1562
1794
  const confirmablesByPosition = groupConfirmablesByPosition(confirmableFills);
1563
1795
  const { keptOrphans, firstSyncTrim } = applyFirstSyncCutoff({
1564
1796
  neverSynced,
@@ -1591,11 +1823,10 @@ async function computeSyncPayload(args) {
1591
1823
  firstSyncTrim
1592
1824
  };
1593
1825
  }
1826
+ __name(computeSyncPayload, "computeSyncPayload");
1594
1827
  function _prepareExternalFills(externalFills, confirmedExchangeFillIdsInput) {
1595
1828
  const dedupedByExchangeFillId = /* @__PURE__ */ new Map();
1596
- const confirmedExchangeFillIds = new Set(
1597
- Array.from(confirmedExchangeFillIdsInput).map((exchangeFillId) => _normalizeExchangeFillId(exchangeFillId)).filter((exchangeFillId) => exchangeFillId !== void 0)
1598
- );
1829
+ const confirmedExchangeFillIds = new Set(Array.from(confirmedExchangeFillIdsInput).map((exchangeFillId) => _normalizeExchangeFillId(exchangeFillId)).filter((exchangeFillId) => exchangeFillId !== void 0));
1599
1830
  const candidates = externalFills.reduce((acc, fill) => {
1600
1831
  const normalizedExchangeFillId = _normalizeExchangeFillId(fill.exchangeFillId);
1601
1832
  if (!normalizedExchangeFillId) {
@@ -1610,7 +1841,10 @@ function _prepareExternalFills(externalFills, confirmedExchangeFillIdsInput) {
1610
1841
  if (confirmedExchangeFillIds.has(normalizedExchangeFillId)) {
1611
1842
  return acc;
1612
1843
  }
1613
- acc.push({ ...fill, exchangeFillId: normalizedExchangeFillId });
1844
+ acc.push({
1845
+ ...fill,
1846
+ exchangeFillId: normalizedExchangeFillId
1847
+ });
1614
1848
  return acc;
1615
1849
  }, []);
1616
1850
  for (const fill of candidates) {
@@ -1621,6 +1855,7 @@ function _prepareExternalFills(externalFills, confirmedExchangeFillIdsInput) {
1621
1855
  }
1622
1856
  return Array.from(dedupedByExchangeFillId.values()).sort((a, b) => a.timestamp - b.timestamp);
1623
1857
  }
1858
+ __name(_prepareExternalFills, "_prepareExternalFills");
1624
1859
  function _segregateExternalFills(provisionalFills, externalFills) {
1625
1860
  const provisionalFillsMap = /* @__PURE__ */ new Map();
1626
1861
  for (const fill of provisionalFills) {
@@ -1637,7 +1872,10 @@ function _segregateExternalFills(provisionalFills, externalFills) {
1637
1872
  if (!cloid) {
1638
1873
  orphans.push(fill);
1639
1874
  } else {
1640
- fillsByCloid.set(cloid, [...fillsByCloid.get(cloid) || [], fill]);
1875
+ fillsByCloid.set(cloid, [
1876
+ ...fillsByCloid.get(cloid) || [],
1877
+ fill
1878
+ ]);
1641
1879
  }
1642
1880
  }
1643
1881
  const reconcilables = {};
@@ -1651,9 +1889,18 @@ function _segregateExternalFills(provisionalFills, externalFills) {
1651
1889
  throw new Error("Corrupted state: sibling group must contain at least 2 fills for reconcile");
1652
1890
  }
1653
1891
  reconcilables[cloid] = [
1654
- { ...first, cloid },
1655
- { ...second, cloid },
1656
- ...rest.map((fill) => ({ ...fill, cloid }))
1892
+ {
1893
+ ...first,
1894
+ cloid
1895
+ },
1896
+ {
1897
+ ...second,
1898
+ cloid
1899
+ },
1900
+ ...rest.map((fill) => ({
1901
+ ...fill,
1902
+ cloid
1903
+ }))
1657
1904
  ];
1658
1905
  } else {
1659
1906
  orphans.push(...fills);
@@ -1673,8 +1920,13 @@ function _segregateExternalFills(provisionalFills, externalFills) {
1673
1920
  }
1674
1921
  }
1675
1922
  }
1676
- return { reconcilables, confirmables: confirmableFills, orphans };
1923
+ return {
1924
+ reconcilables,
1925
+ confirmables: confirmableFills,
1926
+ orphans
1927
+ };
1677
1928
  }
1929
+ __name(_segregateExternalFills, "_segregateExternalFills");
1678
1930
  function _normalizeCloid(cloid) {
1679
1931
  const value = cloid?.trim();
1680
1932
  if (!value) {
@@ -1682,6 +1934,7 @@ function _normalizeCloid(cloid) {
1682
1934
  }
1683
1935
  return value;
1684
1936
  }
1937
+ __name(_normalizeCloid, "_normalizeCloid");
1685
1938
  function _normalizeExchangeFillId(exchangeFillId) {
1686
1939
  const value = exchangeFillId?.trim().toLowerCase();
1687
1940
  if (!value) {
@@ -1689,6 +1942,7 @@ function _normalizeExchangeFillId(exchangeFillId) {
1689
1942
  }
1690
1943
  return value;
1691
1944
  }
1945
+ __name(_normalizeExchangeFillId, "_normalizeExchangeFillId");
1692
1946
  function _isValidExternalQuantity(quantity) {
1693
1947
  if (/e/i.test(quantity)) {
1694
1948
  return false;
@@ -1698,18 +1952,24 @@ function _isValidExternalQuantity(quantity) {
1698
1952
  }
1699
1953
  return isGreaterThan(quantity, ZERO);
1700
1954
  }
1955
+ __name(_isValidExternalQuantity, "_isValidExternalQuantity");
1701
1956
  function _isValidExternalTimestamp(timestamp) {
1702
1957
  if (!Number.isFinite(timestamp) || timestamp < 0) {
1703
1958
  return false;
1704
1959
  }
1705
1960
  return timestamp <= Date.now() + WATERMARK_FUTURE_SKEW_MS;
1706
1961
  }
1962
+ __name(_isValidExternalTimestamp, "_isValidExternalTimestamp");
1707
1963
  function groupConfirmablesByPosition(confirmableFills) {
1708
1964
  return confirmableFills.reduce((acc, fill) => {
1709
- acc[fill.positionId] = [...acc[fill.positionId] || [], fill];
1965
+ acc[fill.positionId] = [
1966
+ ...acc[fill.positionId] || [],
1967
+ fill
1968
+ ];
1710
1969
  return acc;
1711
1970
  }, {});
1712
1971
  }
1972
+ __name(groupConfirmablesByPosition, "groupConfirmablesByPosition");
1713
1973
  function latestFillTimestamp(fills) {
1714
1974
  const last = fills[fills.length - 1];
1715
1975
  if (!last) {
@@ -1717,10 +1977,14 @@ function latestFillTimestamp(fills) {
1717
1977
  }
1718
1978
  return last.timestamp;
1719
1979
  }
1980
+ __name(latestFillTimestamp, "latestFillTimestamp");
1720
1981
  function applyFirstSyncCutoff(args) {
1721
1982
  const { neverSynced, fillsToProcess, orphans, exchangePositions, connector } = args;
1722
1983
  if (!neverSynced || fillsToProcess.length === 0) {
1723
- return { keptOrphans: orphans, firstSyncTrim: null };
1984
+ return {
1985
+ keptOrphans: orphans,
1986
+ firstSyncTrim: null
1987
+ };
1724
1988
  }
1725
1989
  const cutoff = selectFirstSyncCutoff({
1726
1990
  fills: fillsToProcess,
@@ -1728,7 +1992,10 @@ function applyFirstSyncCutoff(args) {
1728
1992
  connector
1729
1993
  });
1730
1994
  if (!cutoff) {
1731
- return { keptOrphans: orphans, firstSyncTrim: null };
1995
+ return {
1996
+ keptOrphans: orphans,
1997
+ firstSyncTrim: null
1998
+ };
1732
1999
  }
1733
2000
  const keptIds = new Set(fillsToProcess.slice(cutoff.keepFromIndex).map((fill) => fill.exchangeFillId));
1734
2001
  const keptOrphans = [];
@@ -1737,7 +2004,10 @@ function applyFirstSyncCutoff(args) {
1737
2004
  (keptIds.has(orphan.exchangeFillId) ? keptOrphans : droppedOrphans).push(orphan);
1738
2005
  }
1739
2006
  if (droppedOrphans.length === 0) {
1740
- return { keptOrphans, firstSyncTrim: null };
2007
+ return {
2008
+ keptOrphans,
2009
+ firstSyncTrim: null
2010
+ };
1741
2011
  }
1742
2012
  const firstKeptFill = fillsToProcess[cutoff.keepFromIndex];
1743
2013
  return {
@@ -1749,9 +2019,11 @@ function applyFirstSyncCutoff(args) {
1749
2019
  }
1750
2020
  };
1751
2021
  }
2022
+ __name(applyFirstSyncCutoff, "applyFirstSyncCutoff");
1752
2023
  function isEmptyCycle(reconcilables, confirmablesByPosition, applicables) {
1753
2024
  return Object.keys(reconcilables).length === 0 && Object.keys(confirmablesByPosition).length === 0 && applicables.length === 0;
1754
2025
  }
2026
+ __name(isEmptyCycle, "isEmptyCycle");
1755
2027
 
1756
2028
  // src/validate-leverage.ts
1757
2029
  function validateLeverage(leverage, instrument) {
@@ -1763,32 +2035,104 @@ function validateLeverage(leverage, instrument) {
1763
2035
  }
1764
2036
  return true;
1765
2037
  }
2038
+ __name(validateLeverage, "validateLeverage");
1766
2039
  function validateQuantity(quantity, price, precision) {
1767
- const parsedQuantity = new BigNumber9(quantity);
2040
+ const parsedQuantity = new BigNumber7(quantity);
1768
2041
  if (!parsedQuantity.isFinite() || parsedQuantity.lte(0)) {
1769
2042
  return false;
1770
2043
  }
1771
- const parsedPrice = new BigNumber9(price);
2044
+ const parsedPrice = new BigNumber7(price);
1772
2045
  if (!parsedPrice.isFinite() || parsedPrice.lte(0)) {
1773
2046
  return false;
1774
2047
  }
1775
- const step = new BigNumber9(precision.quantity.step);
2048
+ const step = new BigNumber7(precision.quantity.step);
1776
2049
  const scaled = parsedQuantity.div(step);
1777
2050
  if (!scaled.isInteger()) {
1778
2051
  return false;
1779
2052
  }
1780
2053
  const notional = contractsToBase(parsedQuantity, precision.quantity.contractSize).times(parsedPrice);
1781
2054
  if (precision.notional?.min !== void 0 && precision.notional.min !== null && precision.notional.min > 0) {
1782
- if (notional.lt(new BigNumber9(precision.notional.min))) {
2055
+ if (notional.lt(new BigNumber7(precision.notional.min))) {
1783
2056
  return false;
1784
2057
  }
1785
2058
  }
1786
2059
  if (precision.notional?.max !== void 0 && precision.notional.max !== null && precision.notional.max > 0) {
1787
- if (notional.gt(new BigNumber9(precision.notional.max))) {
2060
+ if (notional.gt(new BigNumber7(precision.notional.max))) {
1788
2061
  return false;
1789
2062
  }
1790
2063
  }
1791
2064
  return true;
1792
2065
  }
2066
+ __name(validateQuantity, "validateQuantity");
2067
+ var STORAGE_PREFIX = "pear.x-handoff.";
2068
+ function startXHandoff(storage) {
2069
+ const handoffId = base64urlnopad.encode(randomBytes(16));
2070
+ const verifier = base64urlnopad.encode(randomBytes(32));
2071
+ storage.setItem(`${STORAGE_PREFIX}${handoffId}`, verifier);
2072
+ return {
2073
+ handoffId,
2074
+ challenge: base64urlnopad.encode(sha256(utf8ToBytes(verifier)))
2075
+ };
2076
+ }
2077
+ __name(startXHandoff, "startXHandoff");
2078
+ function finishXHandoff(href, storage) {
2079
+ const url = new URL(href);
2080
+ const linkStatus = url.searchParams.get("x_link");
2081
+ const loginStatus = url.searchParams.get("x_login");
2082
+ const reason = url.searchParams.get("x_reason") ?? void 0;
2083
+ if (linkStatus === "connected" || linkStatus === "reconnected") {
2084
+ return {
2085
+ kind: "link-succeeded",
2086
+ status: linkStatus
2087
+ };
2088
+ }
2089
+ if (linkStatus) {
2090
+ return {
2091
+ kind: "link-failed",
2092
+ reason
2093
+ };
2094
+ }
2095
+ if (!loginStatus) {
2096
+ return void 0;
2097
+ }
2098
+ const verifier = takeVerifier(url.searchParams.get("x_handoff"), storage);
2099
+ const ticket = new URLSearchParams(url.hash.replace(/^#/, "")).get("x_ticket");
2100
+ if (loginStatus !== "signed_in" || !ticket || !verifier) {
2101
+ return {
2102
+ kind: "login-failed",
2103
+ reason: loginStatus === "signed_in" ? "wrong_browser" : reason
2104
+ };
2105
+ }
2106
+ return {
2107
+ kind: "login-settled",
2108
+ ticket,
2109
+ verifier
2110
+ };
2111
+ }
2112
+ __name(finishXHandoff, "finishXHandoff");
2113
+ function stripXReturn(href) {
2114
+ const url = new URL(href);
2115
+ for (const key of [
2116
+ "x_link",
2117
+ "x_login",
2118
+ "x_reason",
2119
+ "x_handoff"
2120
+ ]) {
2121
+ url.searchParams.delete(key);
2122
+ }
2123
+ url.hash = "";
2124
+ return `${url.pathname}${url.search}`;
2125
+ }
2126
+ __name(stripXReturn, "stripXReturn");
2127
+ function takeVerifier(handoffId, storage) {
2128
+ if (!handoffId) {
2129
+ return void 0;
2130
+ }
2131
+ const key = `${STORAGE_PREFIX}${handoffId}`;
2132
+ const verifier = storage.getItem(key) ?? void 0;
2133
+ storage.removeItem(key);
2134
+ return verifier;
2135
+ }
2136
+ __name(takeVerifier, "takeVerifier");
1793
2137
 
1794
- export { BIPS, ZERO, abs, add, aggregateRealizedPositionState, baseToContracts, buildApplicables, compareValue, computeAssetEntryNotional, computeAssetGrossRealizedPnL, computeAssetRealizedPnLs, computeAssetUndeterminedSizes, computeAssetUnrealizedPnL, computeAssetUnrealizedPnLs, computeBasketWeightedRatioV1, computeEntryPriceForAsset, computePositionEntryPrices, computeRealizedPnlBySymbol, computeRealizedPnlFromFills, computeRealizedPositionState, computeSyncPayload, computeUnrealizedPositionState, computeUnrealizedPositionStateFromEntryPrices, configureProxy, contractsToBase, countDecimals, deriveBasketKey, divide, exponentiate, generateDeterministicPositionKey, isEqualTo, isFiniteDecimal, isGreaterThan, isGreaterThanOrEqual, isLessThan, isLessThanOrEqual, isNegative, isPositive, isZero, min, multiply, negate, parse, precisePrice, preciseQuantity, proxyFetch, sideSign, sign, signed, signedBySide, subtract, toDecimalString, validateLeverage, validateQuantity };
2138
+ export { BIPS, ZERO, abs, add, aggregateRealizedPositionState, baseToContracts, buildApplicables, compareValue, computeAssetEntryNotional, computeAssetGrossRealizedPnL, computeAssetRealizedPnLs, computeAssetUndeterminedSizes, computeAssetUnrealizedPnL, computeAssetUnrealizedPnLs, computeBasketWeightedRatioV1, computeEntryPriceForAsset, computePositionEntryPrices, computeRealizedPnlBySymbol, computeRealizedPnlFromFills, computeRealizedPositionState, computeSyncPayload, computeUnrealizedPositionState, computeUnrealizedPositionStateFromEntryPrices, configureProxy, contractsToBase, countDecimals, deriveBasketKey, divide, exponentiate, finishXHandoff, generateDeterministicPositionKey, isEqualTo, isFiniteDecimal, isGreaterThan, isGreaterThanOrEqual, isLessThan, isLessThanOrEqual, isNegative, isPositive, isZero, min, multiply, negate, parse, precisePrice, preciseQuantity, proxyFetch, sideSign, sign, signed, signedBySide, startXHandoff, stripXReturn, subtract, toDecimalString, validateLeverage, validateQuantity };