@pear-protocol/utils 0.5.0 → 0.5.2

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,79 @@ 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));
1111
+ const longOk = [
1112
+ ...leftoverLongs
1113
+ ].every((a) => longs.has(a));
1114
+ const shortOk = [
1115
+ ...leftoverShorts
1116
+ ].every((a) => shorts.has(a));
968
1117
  return longOk && shortOk;
969
1118
  });
970
1119
  if (target) {
971
1120
  return target;
972
1121
  }
973
- const symbols = [.../* @__PURE__ */ new Set([...leftoverLongs, ...leftoverShorts])];
1122
+ const symbols = [
1123
+ .../* @__PURE__ */ new Set([
1124
+ ...leftoverLongs,
1125
+ ...leftoverShorts
1126
+ ])
1127
+ ];
974
1128
  const positionKey = book.keyFor(symbols);
975
1129
  return book.findOpenByKey(positionKey) ?? book.create(positionKey);
976
1130
  }
1131
+ __name(resolveLeftoverTarget, "resolveLeftoverTarget");
977
1132
  function applyLeftover(target, leftover) {
978
1133
  for (const entry of leftover) {
979
1134
  target.parts.push(...entry.leg.take(entry.qty));
980
1135
  target.exposure.addSigned(entry.leg.symbol, entry.qty.toFixed(), entry.side);
981
1136
  }
982
1137
  }
1138
+ __name(applyLeftover, "applyLeftover");
983
1139
 
984
1140
  // src/sync/applicables/synthetics.ts
985
1141
  function isMissedHistoryFill(fill) {
986
1142
  return fill.exchangeFillId.startsWith(MISSED_HISTORY_FILL_PREFIX);
987
1143
  }
1144
+ __name(isMissedHistoryFill, "isMissedHistoryFill");
988
1145
  function addFillsForMissedHistory(args) {
989
1146
  const missedHistoryFills = buildMissedHistoryFills(args);
990
- return [...missedHistoryFills, ...args.orphanFills].sort((a, b) => a.timestamp - b.timestamp);
1147
+ return [
1148
+ ...missedHistoryFills,
1149
+ ...args.orphanFills
1150
+ ].sort((a, b) => a.timestamp - b.timestamp);
991
1151
  }
1152
+ __name(addFillsForMissedHistory, "addFillsForMissedHistory");
992
1153
  function alignPositionsWithExchange(args) {
993
1154
  const { positions, pear, snapshot, tradeAccountId } = args;
994
- const neededSynthetics = findNeededSynthetics({ positions, pear, snapshot });
995
- return assignSyntheticsToPositions({ neededSynthetics, positions, pear, tradeAccountId });
1155
+ const neededSynthetics = findNeededSynthetics({
1156
+ positions,
1157
+ pear,
1158
+ snapshot
1159
+ });
1160
+ return assignSyntheticsToPositions({
1161
+ neededSynthetics,
1162
+ positions,
1163
+ pear,
1164
+ tradeAccountId
1165
+ });
996
1166
  }
1167
+ __name(alignPositionsWithExchange, "alignPositionsWithExchange");
997
1168
  function buildSyntheticFill(args) {
998
1169
  return {
999
1170
  // Content-addressed id — no wall-clock, no positionId, so re-syncs collide
@@ -1020,6 +1191,7 @@ function buildSyntheticFill(args) {
1020
1191
  liquidation: null
1021
1192
  };
1022
1193
  }
1194
+ __name(buildSyntheticFill, "buildSyntheticFill");
1023
1195
  function buildMissedHistoryFills(args) {
1024
1196
  const { orphanFills, pear, connector, entryBySymbol, snapshot } = args;
1025
1197
  const fillTotals = /* @__PURE__ */ new Map();
@@ -1030,13 +1202,16 @@ function buildMissedHistoryFills(args) {
1030
1202
  orphanNotional.set(fill.symbol, add(orphanNotional.get(fill.symbol) ?? ZERO, notional));
1031
1203
  }
1032
1204
  const pearTotals = pear.totalBySymbol();
1033
- const assets = /* @__PURE__ */ new Set([...orphanFills.map((fill) => fill.symbol), ...snapshot.symbols()]);
1205
+ const assets = /* @__PURE__ */ new Set([
1206
+ ...orphanFills.map((fill) => fill.symbol),
1207
+ ...snapshot.symbols()
1208
+ ]);
1034
1209
  const earliestTs = orphanFills.reduce((min2, fill) => Math.min(min2, fill.timestamp), Infinity);
1035
1210
  if (!Number.isFinite(earliestTs)) {
1036
1211
  return [];
1037
1212
  }
1038
1213
  const watermark = Math.max(1, earliestTs - 1);
1039
- const haveBySymbol = (symbol) => add(pearTotals.get(symbol) ?? ZERO, fillTotals.get(symbol) ?? ZERO);
1214
+ const haveBySymbol = /* @__PURE__ */ __name((symbol) => add(pearTotals.get(symbol) ?? ZERO, fillTotals.get(symbol) ?? ZERO), "haveBySymbol");
1040
1215
  const result = [];
1041
1216
  for (const gap of gapsToTarget({
1042
1217
  assets,
@@ -1068,6 +1243,7 @@ function buildMissedHistoryFills(args) {
1068
1243
  }
1069
1244
  return result;
1070
1245
  }
1246
+ __name(buildMissedHistoryFills, "buildMissedHistoryFills");
1071
1247
  function priceForMissedHistoryFill(args) {
1072
1248
  const { exchangePosition, syntheticQty, pearQty, pearEntry, orphanNotional } = args;
1073
1249
  const fallback = exchangePosition?.entryPrice ?? "0";
@@ -1089,6 +1265,7 @@ function priceForMissedHistoryFill(args) {
1089
1265
  const derived = divide(subtract(targetNotional, realNotional), synthQty);
1090
1266
  return derived.isFinite() && derived.isPositive() ? derived.toFixed() : fallback;
1091
1267
  }
1268
+ __name(priceForMissedHistoryFill, "priceForMissedHistoryFill");
1092
1269
  function findNeededSynthetics(args) {
1093
1270
  const { positions, pear, snapshot } = args;
1094
1271
  const pearTotals = pear.totalBySymbol();
@@ -1104,13 +1281,13 @@ function findNeededSynthetics(args) {
1104
1281
  for (const symbol of pearTotals.keys()) {
1105
1282
  assets.add(symbol);
1106
1283
  }
1107
- const haveBySymbol = (symbol) => {
1284
+ const haveBySymbol = /* @__PURE__ */ __name((symbol) => {
1108
1285
  let totalFills = ZERO;
1109
1286
  for (const pos of positions) {
1110
1287
  totalFills = add(totalFills, Exposure.netFromParts(pos.parts, symbol));
1111
1288
  }
1112
1289
  return add(pearTotals.get(symbol) ?? ZERO, totalFills);
1113
- };
1290
+ }, "haveBySymbol");
1114
1291
  const result = /* @__PURE__ */ new Map();
1115
1292
  for (const gap of gapsToTarget({
1116
1293
  assets,
@@ -1137,9 +1314,13 @@ function findNeededSynthetics(args) {
1137
1314
  }
1138
1315
  return result;
1139
1316
  }
1317
+ __name(findNeededSynthetics, "findNeededSynthetics");
1140
1318
  function assignSyntheticsToPositions(args) {
1141
1319
  const { neededSynthetics, positions, pear, tradeAccountId } = args;
1142
- const keyOf = (symbols) => generateDeterministicPositionKey({ tradeAccountId, symbols });
1320
+ const keyOf = /* @__PURE__ */ __name((symbols) => generateDeterministicPositionKey({
1321
+ tradeAccountId,
1322
+ symbols
1323
+ }), "keyOf");
1143
1324
  const existingBySymbol = pear.positionBySymbol();
1144
1325
  const created = [];
1145
1326
  const byPosition = /* @__PURE__ */ new Map();
@@ -1147,11 +1328,12 @@ function assignSyntheticsToPositions(args) {
1147
1328
  let target = positions.find((pos) => !pos.closed && pos.parts.some((part) => part.source.symbol === symbol));
1148
1329
  if (!target) {
1149
1330
  const existing = existingBySymbol.get(symbol);
1150
- const positionKey = existing ? existing.positionKey : keyOf([symbol]);
1331
+ const positionKey = existing ? existing.positionKey : keyOf([
1332
+ symbol
1333
+ ]);
1151
1334
  target = positions.find((pos) => pos.positionKey === positionKey) ?? created.find((pos) => pos.positionKey === positionKey);
1152
1335
  if (!target) {
1153
1336
  target = existing ? (
1154
- // Stand-in for an existing DB position untouched by this batch's fills:
1155
1337
  // seed its exposure and origin so folding the synthetic yields the true
1156
1338
  // final state (a gone-close nets to zero -> CLOSED/NETTED, a gap writes
1157
1339
  // the full total, not just the delta).
@@ -1175,8 +1357,15 @@ function assignSyntheticsToPositions(args) {
1175
1357
  list.push(spec);
1176
1358
  byPosition.set(target, list);
1177
1359
  }
1178
- return { positions: [...positions, ...created], synthByPosition: byPosition };
1360
+ return {
1361
+ positions: [
1362
+ ...positions,
1363
+ ...created
1364
+ ],
1365
+ synthByPosition: byPosition
1366
+ };
1179
1367
  }
1368
+ __name(assignSyntheticsToPositions, "assignSyntheticsToPositions");
1180
1369
  function gapsToTarget(args) {
1181
1370
  const { assets, haveBySymbol, snapshot } = args;
1182
1371
  const gaps = [];
@@ -1192,6 +1381,7 @@ function gapsToTarget(args) {
1192
1381
  }
1193
1382
  return gaps;
1194
1383
  }
1384
+ __name(gapsToTarget, "gapsToTarget");
1195
1385
  function findGapToTarget(args) {
1196
1386
  const { symbol, have, target } = args;
1197
1387
  if (isZero(target)) {
@@ -1216,6 +1406,7 @@ function findGapToTarget(args) {
1216
1406
  }
1217
1407
  return null;
1218
1408
  }
1409
+ __name(findGapToTarget, "findGapToTarget");
1219
1410
 
1220
1411
  // src/sync/applicables/fills.ts
1221
1412
  function assignPartIds(positions) {
@@ -1231,13 +1422,18 @@ function assignPartIds(positions) {
1231
1422
  for (const [sourceId, parts] of bySource) {
1232
1423
  const single = parts.length === 1 ? parts[0] : void 0;
1233
1424
  if (single && isEqualTo(single.quantity, single.source.quantity)) {
1234
- resolution.set(single, { exchangeFillId: sourceId });
1425
+ resolution.set(single, {
1426
+ exchangeFillId: sourceId
1427
+ });
1235
1428
  continue;
1236
1429
  }
1237
1430
  parts.forEach((part, i) => {
1238
1431
  resolution.set(part, {
1239
1432
  exchangeFillId: `${sourceId}-p${i}`,
1240
- original: { exchangeFillId: sourceId, quantity: part.source.quantity }
1433
+ original: {
1434
+ exchangeFillId: sourceId,
1435
+ quantity: part.source.quantity
1436
+ }
1241
1437
  });
1242
1438
  });
1243
1439
  }
@@ -1249,6 +1445,7 @@ function assignPartIds(positions) {
1249
1445
  return id;
1250
1446
  };
1251
1447
  }
1448
+ __name(assignPartIds, "assignPartIds");
1252
1449
  function partToApplicableFill(part, id, connector) {
1253
1450
  const fill = part.source;
1254
1451
  const base = {
@@ -1283,9 +1480,12 @@ function partToApplicableFill(part, id, connector) {
1283
1480
  tradeFee: feeShareForPart(fill.tradeFee, part.quantity, fill.quantity),
1284
1481
  builderFee: feeShareForPart(fill.builderFee, part.quantity, fill.quantity),
1285
1482
  liquidation: fill.liquidation,
1286
- ...id.original ? { original: id.original } : {}
1483
+ ...id.original ? {
1484
+ original: id.original
1485
+ } : {}
1287
1486
  };
1288
1487
  }
1488
+ __name(partToApplicableFill, "partToApplicableFill");
1289
1489
  function feeShareForPart(totalFee, partQty, sourceQty) {
1290
1490
  if (isEqualTo(partQty, sourceQty)) {
1291
1491
  return totalFee;
@@ -1296,6 +1496,7 @@ function feeShareForPart(totalFee, partQty, sourceQty) {
1296
1496
  const feeShare = divide(multiply(totalFee, partQty), sourceQty);
1297
1497
  return feeShare.toFixed();
1298
1498
  }
1499
+ __name(feeShareForPart, "feeShareForPart");
1299
1500
 
1300
1501
  // src/sync/applicables/position.ts
1301
1502
  function assembleApplicables(args) {
@@ -1310,17 +1511,19 @@ function assembleApplicables(args) {
1310
1511
  }
1311
1512
  return applicables;
1312
1513
  }
1514
+ __name(assembleApplicables, "assembleApplicables");
1313
1515
  function assembleOneApplicable(pos, connector, partIdFor, assignedSynthetics, now) {
1314
1516
  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);
1517
+ const syntheticFills = assignedSynthetics.map((synthetic) => buildSyntheticFill({
1518
+ positionKey: pos.positionKey,
1519
+ connector,
1520
+ timestamp: anchorSyntheticTimestamp(realFills, synthetic.symbol, now),
1521
+ ...synthetic
1522
+ }));
1523
+ const fills = [
1524
+ ...realFills,
1525
+ ...syntheticFills
1526
+ ].sort((a, b) => a.timestamp - b.timestamp);
1324
1527
  if (fills.length === 0) {
1325
1528
  return null;
1326
1529
  }
@@ -1333,11 +1536,14 @@ function assembleOneApplicable(pos, connector, partIdFor, assignedSynthetics, no
1333
1536
  exposure: exposure.toSigned(),
1334
1537
  origin,
1335
1538
  status,
1336
- ...closed ? { closedReason: "NETTED" } : {},
1539
+ ...closed ? {
1540
+ closedReason: "NETTED"
1541
+ } : {},
1337
1542
  fills,
1338
1543
  metadata: buildMetadata(new Set(exposure.symbols()), realFills)
1339
1544
  };
1340
1545
  }
1546
+ __name(assembleOneApplicable, "assembleOneApplicable");
1341
1547
  function finalExposure(pos, synthetics) {
1342
1548
  const exposure = pos.exposure.clone();
1343
1549
  for (const synthetic of synthetics) {
@@ -1345,6 +1551,7 @@ function finalExposure(pos, synthetics) {
1345
1551
  }
1346
1552
  return exposure;
1347
1553
  }
1554
+ __name(finalExposure, "finalExposure");
1348
1555
  function anchorSyntheticTimestamp(realFills, symbol, now) {
1349
1556
  const oldestForSymbol = realFills.find((fill) => fill.symbol === symbol)?.timestamp;
1350
1557
  if (oldestForSymbol !== void 0) {
@@ -1353,12 +1560,16 @@ function anchorSyntheticTimestamp(realFills, symbol, now) {
1353
1560
  const oldestRealTs = realFills[0]?.timestamp;
1354
1561
  return oldestRealTs !== void 0 ? Math.max(1, oldestRealTs - 1) : now;
1355
1562
  }
1563
+ __name(anchorSyntheticTimestamp, "anchorSyntheticTimestamp");
1356
1564
  function buildMetadata(symbols, realFills) {
1357
1565
  const initialExposureUSD = {};
1358
1566
  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
- );
1567
+ const legFills = realFills.flatMap((fill) => fill.symbol === symbol && fill.usd != null ? [
1568
+ {
1569
+ side: fill.side,
1570
+ usd: fill.usd
1571
+ }
1572
+ ] : []);
1362
1573
  const opener = legFills[0];
1363
1574
  if (!opener) {
1364
1575
  continue;
@@ -1367,8 +1578,11 @@ function buildMetadata(symbols, realFills) {
1367
1578
  const signedNotional = signed(opener.side === "BUY" ? notional : notional.negated());
1368
1579
  initialExposureUSD[symbol] = signedNotional;
1369
1580
  }
1370
- return { initialExposureUSD };
1581
+ return {
1582
+ initialExposureUSD
1583
+ };
1371
1584
  }
1585
+ __name(buildMetadata, "buildMetadata");
1372
1586
  function mergeOrigin(existing, fills) {
1373
1587
  let anyExternal = false;
1374
1588
  let anyPear = false;
@@ -1396,16 +1610,23 @@ function mergeOrigin(existing, fills) {
1396
1610
  }
1397
1611
  return anyPear ? "PEAR" : "EXTERNAL";
1398
1612
  }
1613
+ __name(mergeOrigin, "mergeOrigin");
1399
1614
 
1400
1615
  // src/sync/applicables/snapshot.ts
1401
1616
  var ExchangeSnapshot = class _ExchangeSnapshot {
1617
+ static {
1618
+ __name(this, "ExchangeSnapshot");
1619
+ }
1620
+ bySymbol;
1402
1621
  constructor(bySymbol) {
1403
1622
  this.bySymbol = bySymbol;
1404
1623
  }
1405
- bySymbol;
1406
1624
  /** Index `positions` by symbol for O(1) lookup. */
1407
1625
  static from(positions) {
1408
- return new _ExchangeSnapshot(new Map(positions.map((position) => [position.symbol, position])));
1626
+ return new _ExchangeSnapshot(new Map(positions.map((position) => [
1627
+ position.symbol,
1628
+ position
1629
+ ])));
1409
1630
  }
1410
1631
  /** Raw exchange position for `symbol`, or `undefined` when the exchange holds nothing. */
1411
1632
  get(symbol) {
@@ -1427,14 +1648,19 @@ var ExchangeSnapshot = class _ExchangeSnapshot {
1427
1648
  }
1428
1649
  /** All symbols the exchange currently reports a position for. */
1429
1650
  symbols() {
1430
- return [...this.bySymbol.keys()];
1651
+ return [
1652
+ ...this.bySymbol.keys()
1653
+ ];
1431
1654
  }
1432
1655
  };
1433
1656
  var PearHoldings = class _PearHoldings {
1657
+ static {
1658
+ __name(this, "PearHoldings");
1659
+ }
1660
+ filtered;
1434
1661
  constructor(filtered) {
1435
1662
  this.filtered = filtered;
1436
1663
  }
1437
- filtered;
1438
1664
  /** Filter `openPositions` to the given connector and wrap. */
1439
1665
  static from(args) {
1440
1666
  const { openPositions, connector } = args;
@@ -1458,10 +1684,10 @@ var PearHoldings = class _PearHoldings {
1458
1684
  return totals;
1459
1685
  }
1460
1686
  /**
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
- */
1687
+ * Which open DB position holds each active asset — the fallback target for a
1688
+ * synthetic when no matched position already carries that asset. First open
1689
+ * position with a non-zero leg wins per symbol.
1690
+ */
1465
1691
  positionBySymbol() {
1466
1692
  const existingBySymbol = /* @__PURE__ */ new Map();
1467
1693
  for (const position of this.filtered) {
@@ -1481,18 +1707,37 @@ var PearHoldings = class _PearHoldings {
1481
1707
  function buildApplicables(args) {
1482
1708
  const { tradeAccountId, connector, orphanFills, openPositions, entryBySymbol, exchangePositions } = args;
1483
1709
  const snapshot = ExchangeSnapshot.from(exchangePositions);
1484
- const pear = PearHoldings.from({ openPositions, connector });
1710
+ const pear = PearHoldings.from({
1711
+ openPositions,
1712
+ connector
1713
+ });
1485
1714
  const now = Date.now();
1486
- const fills = addFillsForMissedHistory({ orphanFills, pear, connector, entryBySymbol, snapshot });
1487
- const matched = matchPositions({ tradeAccountId, orphanFills: fills, pear });
1715
+ const fills = addFillsForMissedHistory({
1716
+ orphanFills,
1717
+ pear,
1718
+ connector,
1719
+ entryBySymbol,
1720
+ snapshot
1721
+ });
1722
+ const matched = matchPositions({
1723
+ tradeAccountId,
1724
+ orphanFills: fills,
1725
+ pear
1726
+ });
1488
1727
  const { positions, synthByPosition } = alignPositionsWithExchange({
1489
1728
  positions: matched,
1490
1729
  pear,
1491
1730
  snapshot,
1492
1731
  tradeAccountId
1493
1732
  });
1494
- return assembleApplicables({ positions, connector, synthByPosition, now });
1733
+ return assembleApplicables({
1734
+ positions,
1735
+ connector,
1736
+ synthByPosition,
1737
+ now
1738
+ });
1495
1739
  }
1740
+ __name(buildApplicables, "buildApplicables");
1496
1741
 
1497
1742
  // src/sync/cutoff.ts
1498
1743
  function selectFirstSyncCutoff(args) {
@@ -1515,7 +1760,9 @@ function selectFirstSyncCutoff(args) {
1515
1760
  for (let boundary = fills.length; boundary >= 0; boundary--) {
1516
1761
  const withinAnchor = pearIndex === null || boundary <= pearIndex;
1517
1762
  if (withinAnchor && book.isAllZero() && isStrictTimestampBoundary(fills, boundary)) {
1518
- return boundary === 0 ? null : { keepFromIndex: boundary };
1763
+ return boundary === 0 ? null : {
1764
+ keepFromIndex: boundary
1765
+ };
1519
1766
  }
1520
1767
  const preceding = fills[boundary - 1];
1521
1768
  if (preceding) {
@@ -1524,6 +1771,7 @@ function selectFirstSyncCutoff(args) {
1524
1771
  }
1525
1772
  return null;
1526
1773
  }
1774
+ __name(selectFirstSyncCutoff, "selectFirstSyncCutoff");
1527
1775
  function findFirstPearFillIndex(connector, fills) {
1528
1776
  const index = fills.findIndex((fill) => isPearCloid(connector, fill.cloid));
1529
1777
  if (index === -1) {
@@ -1531,6 +1779,7 @@ function findFirstPearFillIndex(connector, fills) {
1531
1779
  }
1532
1780
  return index;
1533
1781
  }
1782
+ __name(findFirstPearFillIndex, "findFirstPearFillIndex");
1534
1783
  function isStrictTimestampBoundary(fills, boundary) {
1535
1784
  const before = fills[boundary - 1];
1536
1785
  const after = fills[boundary];
@@ -1539,26 +1788,13 @@ function isStrictTimestampBoundary(fills, boundary) {
1539
1788
  }
1540
1789
  return before.timestamp < after.timestamp;
1541
1790
  }
1791
+ __name(isStrictTimestampBoundary, "isStrictTimestampBoundary");
1542
1792
 
1543
1793
  // src/sync/compute.ts
1544
1794
  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;
1795
+ const { tradeAccountId, connector, openPositions, entryBySymbol, provisionalFills, confirmedExchangeFillIds, externalFills, exchangePositions, neverSynced } = args;
1556
1796
  const fillsToProcess = _prepareExternalFills(externalFills, confirmedExchangeFillIds);
1557
- const {
1558
- reconcilables,
1559
- confirmables: confirmableFills,
1560
- orphans
1561
- } = _segregateExternalFills(provisionalFills, fillsToProcess);
1797
+ const { reconcilables, confirmables: confirmableFills, orphans } = _segregateExternalFills(provisionalFills, fillsToProcess);
1562
1798
  const confirmablesByPosition = groupConfirmablesByPosition(confirmableFills);
1563
1799
  const { keptOrphans, firstSyncTrim } = applyFirstSyncCutoff({
1564
1800
  neverSynced,
@@ -1591,11 +1827,10 @@ async function computeSyncPayload(args) {
1591
1827
  firstSyncTrim
1592
1828
  };
1593
1829
  }
1830
+ __name(computeSyncPayload, "computeSyncPayload");
1594
1831
  function _prepareExternalFills(externalFills, confirmedExchangeFillIdsInput) {
1595
1832
  const dedupedByExchangeFillId = /* @__PURE__ */ new Map();
1596
- const confirmedExchangeFillIds = new Set(
1597
- Array.from(confirmedExchangeFillIdsInput).map((exchangeFillId) => _normalizeExchangeFillId(exchangeFillId)).filter((exchangeFillId) => exchangeFillId !== void 0)
1598
- );
1833
+ const confirmedExchangeFillIds = new Set(Array.from(confirmedExchangeFillIdsInput).map((exchangeFillId) => _normalizeExchangeFillId(exchangeFillId)).filter((exchangeFillId) => exchangeFillId !== void 0));
1599
1834
  const candidates = externalFills.reduce((acc, fill) => {
1600
1835
  const normalizedExchangeFillId = _normalizeExchangeFillId(fill.exchangeFillId);
1601
1836
  if (!normalizedExchangeFillId) {
@@ -1610,7 +1845,10 @@ function _prepareExternalFills(externalFills, confirmedExchangeFillIdsInput) {
1610
1845
  if (confirmedExchangeFillIds.has(normalizedExchangeFillId)) {
1611
1846
  return acc;
1612
1847
  }
1613
- acc.push({ ...fill, exchangeFillId: normalizedExchangeFillId });
1848
+ acc.push({
1849
+ ...fill,
1850
+ exchangeFillId: normalizedExchangeFillId
1851
+ });
1614
1852
  return acc;
1615
1853
  }, []);
1616
1854
  for (const fill of candidates) {
@@ -1621,6 +1859,7 @@ function _prepareExternalFills(externalFills, confirmedExchangeFillIdsInput) {
1621
1859
  }
1622
1860
  return Array.from(dedupedByExchangeFillId.values()).sort((a, b) => a.timestamp - b.timestamp);
1623
1861
  }
1862
+ __name(_prepareExternalFills, "_prepareExternalFills");
1624
1863
  function _segregateExternalFills(provisionalFills, externalFills) {
1625
1864
  const provisionalFillsMap = /* @__PURE__ */ new Map();
1626
1865
  for (const fill of provisionalFills) {
@@ -1637,7 +1876,10 @@ function _segregateExternalFills(provisionalFills, externalFills) {
1637
1876
  if (!cloid) {
1638
1877
  orphans.push(fill);
1639
1878
  } else {
1640
- fillsByCloid.set(cloid, [...fillsByCloid.get(cloid) || [], fill]);
1879
+ fillsByCloid.set(cloid, [
1880
+ ...fillsByCloid.get(cloid) || [],
1881
+ fill
1882
+ ]);
1641
1883
  }
1642
1884
  }
1643
1885
  const reconcilables = {};
@@ -1651,9 +1893,18 @@ function _segregateExternalFills(provisionalFills, externalFills) {
1651
1893
  throw new Error("Corrupted state: sibling group must contain at least 2 fills for reconcile");
1652
1894
  }
1653
1895
  reconcilables[cloid] = [
1654
- { ...first, cloid },
1655
- { ...second, cloid },
1656
- ...rest.map((fill) => ({ ...fill, cloid }))
1896
+ {
1897
+ ...first,
1898
+ cloid
1899
+ },
1900
+ {
1901
+ ...second,
1902
+ cloid
1903
+ },
1904
+ ...rest.map((fill) => ({
1905
+ ...fill,
1906
+ cloid
1907
+ }))
1657
1908
  ];
1658
1909
  } else {
1659
1910
  orphans.push(...fills);
@@ -1673,8 +1924,13 @@ function _segregateExternalFills(provisionalFills, externalFills) {
1673
1924
  }
1674
1925
  }
1675
1926
  }
1676
- return { reconcilables, confirmables: confirmableFills, orphans };
1927
+ return {
1928
+ reconcilables,
1929
+ confirmables: confirmableFills,
1930
+ orphans
1931
+ };
1677
1932
  }
1933
+ __name(_segregateExternalFills, "_segregateExternalFills");
1678
1934
  function _normalizeCloid(cloid) {
1679
1935
  const value = cloid?.trim();
1680
1936
  if (!value) {
@@ -1682,6 +1938,7 @@ function _normalizeCloid(cloid) {
1682
1938
  }
1683
1939
  return value;
1684
1940
  }
1941
+ __name(_normalizeCloid, "_normalizeCloid");
1685
1942
  function _normalizeExchangeFillId(exchangeFillId) {
1686
1943
  const value = exchangeFillId?.trim().toLowerCase();
1687
1944
  if (!value) {
@@ -1689,6 +1946,7 @@ function _normalizeExchangeFillId(exchangeFillId) {
1689
1946
  }
1690
1947
  return value;
1691
1948
  }
1949
+ __name(_normalizeExchangeFillId, "_normalizeExchangeFillId");
1692
1950
  function _isValidExternalQuantity(quantity) {
1693
1951
  if (/e/i.test(quantity)) {
1694
1952
  return false;
@@ -1698,18 +1956,24 @@ function _isValidExternalQuantity(quantity) {
1698
1956
  }
1699
1957
  return isGreaterThan(quantity, ZERO);
1700
1958
  }
1959
+ __name(_isValidExternalQuantity, "_isValidExternalQuantity");
1701
1960
  function _isValidExternalTimestamp(timestamp) {
1702
1961
  if (!Number.isFinite(timestamp) || timestamp < 0) {
1703
1962
  return false;
1704
1963
  }
1705
1964
  return timestamp <= Date.now() + WATERMARK_FUTURE_SKEW_MS;
1706
1965
  }
1966
+ __name(_isValidExternalTimestamp, "_isValidExternalTimestamp");
1707
1967
  function groupConfirmablesByPosition(confirmableFills) {
1708
1968
  return confirmableFills.reduce((acc, fill) => {
1709
- acc[fill.positionId] = [...acc[fill.positionId] || [], fill];
1969
+ acc[fill.positionId] = [
1970
+ ...acc[fill.positionId] || [],
1971
+ fill
1972
+ ];
1710
1973
  return acc;
1711
1974
  }, {});
1712
1975
  }
1976
+ __name(groupConfirmablesByPosition, "groupConfirmablesByPosition");
1713
1977
  function latestFillTimestamp(fills) {
1714
1978
  const last = fills[fills.length - 1];
1715
1979
  if (!last) {
@@ -1717,10 +1981,14 @@ function latestFillTimestamp(fills) {
1717
1981
  }
1718
1982
  return last.timestamp;
1719
1983
  }
1984
+ __name(latestFillTimestamp, "latestFillTimestamp");
1720
1985
  function applyFirstSyncCutoff(args) {
1721
1986
  const { neverSynced, fillsToProcess, orphans, exchangePositions, connector } = args;
1722
1987
  if (!neverSynced || fillsToProcess.length === 0) {
1723
- return { keptOrphans: orphans, firstSyncTrim: null };
1988
+ return {
1989
+ keptOrphans: orphans,
1990
+ firstSyncTrim: null
1991
+ };
1724
1992
  }
1725
1993
  const cutoff = selectFirstSyncCutoff({
1726
1994
  fills: fillsToProcess,
@@ -1728,7 +1996,10 @@ function applyFirstSyncCutoff(args) {
1728
1996
  connector
1729
1997
  });
1730
1998
  if (!cutoff) {
1731
- return { keptOrphans: orphans, firstSyncTrim: null };
1999
+ return {
2000
+ keptOrphans: orphans,
2001
+ firstSyncTrim: null
2002
+ };
1732
2003
  }
1733
2004
  const keptIds = new Set(fillsToProcess.slice(cutoff.keepFromIndex).map((fill) => fill.exchangeFillId));
1734
2005
  const keptOrphans = [];
@@ -1737,7 +2008,10 @@ function applyFirstSyncCutoff(args) {
1737
2008
  (keptIds.has(orphan.exchangeFillId) ? keptOrphans : droppedOrphans).push(orphan);
1738
2009
  }
1739
2010
  if (droppedOrphans.length === 0) {
1740
- return { keptOrphans, firstSyncTrim: null };
2011
+ return {
2012
+ keptOrphans,
2013
+ firstSyncTrim: null
2014
+ };
1741
2015
  }
1742
2016
  const firstKeptFill = fillsToProcess[cutoff.keepFromIndex];
1743
2017
  return {
@@ -1749,9 +2023,11 @@ function applyFirstSyncCutoff(args) {
1749
2023
  }
1750
2024
  };
1751
2025
  }
2026
+ __name(applyFirstSyncCutoff, "applyFirstSyncCutoff");
1752
2027
  function isEmptyCycle(reconcilables, confirmablesByPosition, applicables) {
1753
2028
  return Object.keys(reconcilables).length === 0 && Object.keys(confirmablesByPosition).length === 0 && applicables.length === 0;
1754
2029
  }
2030
+ __name(isEmptyCycle, "isEmptyCycle");
1755
2031
 
1756
2032
  // src/validate-leverage.ts
1757
2033
  function validateLeverage(leverage, instrument) {
@@ -1763,32 +2039,104 @@ function validateLeverage(leverage, instrument) {
1763
2039
  }
1764
2040
  return true;
1765
2041
  }
2042
+ __name(validateLeverage, "validateLeverage");
1766
2043
  function validateQuantity(quantity, price, precision) {
1767
- const parsedQuantity = new BigNumber9(quantity);
2044
+ const parsedQuantity = new BigNumber7(quantity);
1768
2045
  if (!parsedQuantity.isFinite() || parsedQuantity.lte(0)) {
1769
2046
  return false;
1770
2047
  }
1771
- const parsedPrice = new BigNumber9(price);
2048
+ const parsedPrice = new BigNumber7(price);
1772
2049
  if (!parsedPrice.isFinite() || parsedPrice.lte(0)) {
1773
2050
  return false;
1774
2051
  }
1775
- const step = new BigNumber9(precision.quantity.step);
2052
+ const step = new BigNumber7(precision.quantity.step);
1776
2053
  const scaled = parsedQuantity.div(step);
1777
2054
  if (!scaled.isInteger()) {
1778
2055
  return false;
1779
2056
  }
1780
2057
  const notional = contractsToBase(parsedQuantity, precision.quantity.contractSize).times(parsedPrice);
1781
2058
  if (precision.notional?.min !== void 0 && precision.notional.min !== null && precision.notional.min > 0) {
1782
- if (notional.lt(new BigNumber9(precision.notional.min))) {
2059
+ if (notional.lt(new BigNumber7(precision.notional.min))) {
1783
2060
  return false;
1784
2061
  }
1785
2062
  }
1786
2063
  if (precision.notional?.max !== void 0 && precision.notional.max !== null && precision.notional.max > 0) {
1787
- if (notional.gt(new BigNumber9(precision.notional.max))) {
2064
+ if (notional.gt(new BigNumber7(precision.notional.max))) {
1788
2065
  return false;
1789
2066
  }
1790
2067
  }
1791
2068
  return true;
1792
2069
  }
2070
+ __name(validateQuantity, "validateQuantity");
2071
+ var STORAGE_PREFIX = "pear.x-handoff.";
2072
+ function startXHandoff(storage) {
2073
+ const handoffId = base64urlnopad.encode(randomBytes(16));
2074
+ const verifier = base64urlnopad.encode(randomBytes(32));
2075
+ storage.setItem(`${STORAGE_PREFIX}${handoffId}`, verifier);
2076
+ return {
2077
+ handoffId,
2078
+ challenge: base64urlnopad.encode(sha256(utf8ToBytes(verifier)))
2079
+ };
2080
+ }
2081
+ __name(startXHandoff, "startXHandoff");
2082
+ function finishXHandoff(href, storage) {
2083
+ const url = new URL(href);
2084
+ const linkStatus = url.searchParams.get("x_link");
2085
+ const loginStatus = url.searchParams.get("x_login");
2086
+ const reason = url.searchParams.get("x_reason") ?? void 0;
2087
+ if (linkStatus === "connected" || linkStatus === "reconnected") {
2088
+ return {
2089
+ kind: "link-succeeded",
2090
+ status: linkStatus
2091
+ };
2092
+ }
2093
+ if (linkStatus) {
2094
+ return {
2095
+ kind: "link-failed",
2096
+ reason
2097
+ };
2098
+ }
2099
+ if (!loginStatus) {
2100
+ return void 0;
2101
+ }
2102
+ const verifier = takeVerifier(url.searchParams.get("x_handoff"), storage);
2103
+ const ticket = new URLSearchParams(url.hash.replace(/^#/, "")).get("x_ticket");
2104
+ if (loginStatus !== "signed_in" || !ticket || !verifier) {
2105
+ return {
2106
+ kind: "login-failed",
2107
+ reason: loginStatus === "signed_in" ? "wrong_browser" : reason
2108
+ };
2109
+ }
2110
+ return {
2111
+ kind: "login-settled",
2112
+ ticket,
2113
+ verifier
2114
+ };
2115
+ }
2116
+ __name(finishXHandoff, "finishXHandoff");
2117
+ function stripXReturn(href) {
2118
+ const url = new URL(href);
2119
+ for (const key of [
2120
+ "x_link",
2121
+ "x_login",
2122
+ "x_reason",
2123
+ "x_handoff"
2124
+ ]) {
2125
+ url.searchParams.delete(key);
2126
+ }
2127
+ url.hash = "";
2128
+ return `${url.pathname}${url.search}`;
2129
+ }
2130
+ __name(stripXReturn, "stripXReturn");
2131
+ function takeVerifier(handoffId, storage) {
2132
+ if (!handoffId) {
2133
+ return void 0;
2134
+ }
2135
+ const key = `${STORAGE_PREFIX}${handoffId}`;
2136
+ const verifier = storage.getItem(key) ?? void 0;
2137
+ storage.removeItem(key);
2138
+ return verifier;
2139
+ }
2140
+ __name(takeVerifier, "takeVerifier");
1793
2141
 
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 };
2142
+ 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 };