@agg-build/hooks 4.17.2 → 4.18.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.
@@ -59,11 +59,13 @@ var Venue = /* @__PURE__ */ ((Venue2) => {
59
59
  Venue2["opinion"] = "opinion";
60
60
  Venue2["predict"] = "predict";
61
61
  Venue2["pred"] = "pred";
62
+ Venue2["tiprun"] = "tiprun";
62
63
  Venue2["probable"] = "probable";
63
64
  Venue2["myriad"] = "myriad";
64
65
  Venue2["hyperliquid"] = "hyperliquid";
65
66
  Venue2["novig"] = "novig";
66
67
  Venue2["prophetx"] = "prophetx";
68
+ Venue2["betdex"] = "betdex";
67
69
  return Venue2;
68
70
  })(Venue || {});
69
71
  var ACTIVE_VENUES = [
@@ -73,11 +75,13 @@ var ACTIVE_VENUES = [
73
75
  "opinion" /* opinion */,
74
76
  "predict" /* predict */,
75
77
  "pred" /* pred */,
78
+ "tiprun" /* tiprun */,
76
79
  "probable" /* probable */,
77
80
  "myriad" /* myriad */,
78
81
  "hyperliquid" /* hyperliquid */,
79
82
  "novig" /* novig */,
80
- "prophetx" /* prophetx */
83
+ "prophetx" /* prophetx */,
84
+ "betdex" /* betdex */
81
85
  ];
82
86
  var INACTIVE_VENUES = [];
83
87
  var ACTIVE_VENUE_SET = new Set(ACTIVE_VENUES);
@@ -158,6 +162,9 @@ function parseEmailStrict(raw) {
158
162
  return result.data;
159
163
  }
160
164
 
165
+ // ../common/src/enums/image-size.ts
166
+ var RETINA_IMAGE_SIZES = [80 /* xl */, 96 /* xxl */, 120 /* xxxl */];
167
+
161
168
  // ../common/src/utils/image-url.ts
162
169
  function pickVariant(px) {
163
170
  if (px <= 44 /* sm */) return 44 /* sm */;
@@ -173,6 +180,13 @@ function optimizedImageUrl(url, maxPx) {
173
180
  const filename = variant === 0 /* original */ ? "original.webp" : `${variant}.webp`;
174
181
  return url.replace(VARIANT_RE, `/${filename}`);
175
182
  }
183
+ function retinaImageUrl(url, maxPx) {
184
+ if (!url) return void 0;
185
+ if (!VARIANT_RE.test(url)) return void 0;
186
+ const variant = RETINA_IMAGE_SIZES.find((size) => size >= maxPx * 2);
187
+ if (variant == null) return void 0;
188
+ return url.replace(VARIANT_RE, `/${variant}.webp`);
189
+ }
176
190
 
177
191
  // ../common/src/utils/sort-venues.ts
178
192
  var VENUE_SORT_ORDER = [
@@ -180,10 +194,12 @@ var VENUE_SORT_ORDER = [
180
194
  "hyperliquid" /* hyperliquid */,
181
195
  "predict" /* predict */,
182
196
  "prophetx" /* prophetx */,
197
+ "betdex" /* betdex */,
183
198
  "kalshi" /* kalshi */,
184
199
  "limitless" /* limitless */,
185
200
  "myriad" /* myriad */,
186
201
  "pred" /* pred */,
202
+ "tiprun" /* tiprun */,
187
203
  "probable" /* probable */,
188
204
  "novig" /* novig */,
189
205
  "opinion" /* opinion */
@@ -228,6 +244,19 @@ function evict() {
228
244
  builders.delete(oldest);
229
245
  }
230
246
  }
247
+ function getCandleStoreDiagnostics() {
248
+ return {
249
+ builders: builders.size,
250
+ retainedCandles: [...builders.values()].reduce(
251
+ (total, builder) => total + ["1m", "5m", "1h", "1d"].reduce(
252
+ (count, interval) => count + builder.getClosed(interval).length + (builder.getForming(interval) ? 1 : 0),
253
+ 0
254
+ ),
255
+ 0
256
+ ),
257
+ maxBuilders: MAX_BUILDERS
258
+ };
259
+ }
231
260
 
232
261
  // src/core/ui-config/labels.ts
233
262
  var enUsLabels = {
@@ -244,6 +273,10 @@ var enUsLabels = {
244
273
  lineChartAria: "Line chart",
245
274
  candlestickChartAria: "Candlestick chart",
246
275
  lineChartSeriesSwitchAria: "Chart series switch",
276
+ chartSources: (historyVenue, liquidityVenue) => `History: ${historyVenue} \xB7 Resting liquidity: ${liquidityVenue != null ? liquidityVenue : "all venues"}`,
277
+ chartBidLiquidity: (amount) => `Bid ${amount}`,
278
+ chartAskLiquidity: (amount) => `Ask ${amount}`,
279
+ chartEmpty: "No price history in this range",
247
280
  lineChartSeriesOptionAria: (seriesLabel) => `Show ${seriesLabel} series`,
248
281
  chartTypeSwitchAria: "Chart type switch",
249
282
  lineChartType: "Line",
@@ -255,12 +288,14 @@ var enUsLabels = {
255
288
  opinion: "Opinion",
256
289
  predict: "Predict",
257
290
  pred: "PRED",
291
+ tiprun: "Tip Run",
258
292
  limitless: "Limitless",
259
293
  probable: "Probable",
260
294
  myriad: "Myriad",
261
295
  hyperliquid: "Hyperliquid",
262
296
  novig: "Novig",
263
- prophetx: "ProphetX"
297
+ prophetx: "ProphetX",
298
+ betdex: "BETDEX"
264
299
  },
265
300
  auth: {
266
301
  connect: (connectorName) => connectorName ? `Sign in with ${connectorName}` : "Sign in",
@@ -551,10 +586,74 @@ var enUsLabels = {
551
586
  positionsValue: "Positions Value",
552
587
  kalshiBalance: "Kalshi Balance",
553
588
  balanceByNetwork: "Balance by network",
589
+ venueAccount: "Venue account",
590
+ balanceUnavailable: "Balance unavailable",
554
591
  paperModeNetwork: "Paper",
555
592
  paperModeWarning: "Paper mode is enabled. These are simulated funds for paper trading.",
556
593
  networkTooltipDescription: "Funds are stored across networks. We handle routing automatically, but keeping funds on the right network enables faster trades and lower fees. When depositing, you can choose your preferred network."
557
594
  },
595
+ hostedBetdex: {
596
+ deposit: "Deposit USDC",
597
+ depositInstructions: {
598
+ production: "Send USDC on Solana to this BETDEX account address.",
599
+ sandbox: "This is a sandbox account. Use sandbox test funds only."
600
+ },
601
+ depositAddress: "BETDEX Solana deposit address",
602
+ transferUnavailable: "This transfer is temporarily unavailable. Check its status before trying again.",
603
+ withdraw: "Withdraw USDC",
604
+ withdrawalAmount: "Amount (USDC)",
605
+ withdrawalDestination: "Your Solana wallet address",
606
+ withdrawalSubmit: "Withdraw from BETDEX",
607
+ withdrawalCheck: "Check withdrawal",
608
+ withdrawalRetry: "Retry the same withdrawal",
609
+ withdrawalNew: "New withdrawal",
610
+ withdrawalUnknown: "The response was not confirmed. Your request is saved; retrying checks the same withdrawal.",
611
+ withdrawalStatuses: {
612
+ processing: "Withdrawal is processing.",
613
+ confirmed: "Withdrawal confirmed.",
614
+ failed: "Withdrawal failed. Funds are available again.",
615
+ flagged: "Withdrawal needs review. Funds remain reserved.",
616
+ review_required: "Withdrawal needs review. Funds remain reserved."
617
+ },
618
+ title: "BETDEX account",
619
+ description: "USDC held with BETDEX, separate from your connected wallets.",
620
+ sandbox: "Sandbox \xB7 simulated funds",
621
+ createAccount: "Set up BETDEX account",
622
+ checkSetup: "Check account setup",
623
+ provisioning: "Account setup is processing. Check again for confirmation.",
624
+ suspended: "This BETDEX account is suspended.",
625
+ unavailable: "BETDEX balance is temporarily unavailable.",
626
+ provisioningUnavailable: "BETDEX account setup is currently unavailable.",
627
+ total: "Total balance",
628
+ available: "Available to trade",
629
+ reserved: "Reserved for open orders",
630
+ refresh: "Refresh account",
631
+ creationFailed: "We could not confirm account setup. Refresh to check its status before trying again.",
632
+ showActivity: "Show account activity",
633
+ hideActivity: "Hide account activity",
634
+ activityTitle: "BETDEX account activity",
635
+ activityDescription: "Observed ledger entries, not spendable balances or per-order fees. A ledger entry alone does not confirm a withdrawal's completion.",
636
+ activityEmpty: "No account activity on this page.",
637
+ activityUnavailable: "BETDEX account activity is temporarily unavailable.",
638
+ activityPrevious: "Previous activity page",
639
+ activityNext: "Next activity page",
640
+ activityRefresh: "Refresh activity",
641
+ activityCodes: {
642
+ Deposit: "Deposit",
643
+ Withdrawal: "Withdrawal",
644
+ TradeCreation: "Trade created",
645
+ TradeVoid: "Trade voided",
646
+ TradeWin: "Trade payout",
647
+ WalletToWallet: "Wallet transfer",
648
+ Commission: "Commission",
649
+ MarketPositionVoid: "Position voided",
650
+ MarketPositionPayout: "Position payout",
651
+ MarketPositionRefund: "Position refund",
652
+ ManualDebit: "Manual debit",
653
+ ManualCredit: "Manual credit",
654
+ SettlementResidual: "Settlement adjustment"
655
+ }
656
+ },
558
657
  activity: {
559
658
  depositType: "Deposit",
560
659
  redeemType: "Claim",
@@ -708,6 +807,17 @@ var enUsLabels = {
708
807
  priceGap: "Price Gap"
709
808
  },
710
809
  eventItemDetails: {
810
+ chartLegend: "Markets on chart",
811
+ selectChartMarkets: "Select a line above to show its history",
812
+ marketHistoryUnavailable: "History unavailable",
813
+ comparisonSource: (venue) => `${venue} \xB7 Outcome probabilities \xB7 Click a line to show or hide it`,
814
+ comparisonSeriesCount: (shown, total) => `Showing ${shown} of ${total} series`,
815
+ comparisonSeriesPage: (page, total) => `Page ${page} of ${total}`,
816
+ comparisonSeriesBudget: (limit) => `Up to ${limit} series are live at once. Change pages to compare others; your selected outcome stays visible.`,
817
+ comparisonPreviousSeries: "Previous series",
818
+ comparisonNextSeries: "Next series",
819
+ comparisonSelectedSeries: "Selected",
820
+ comparisonHiddenSeries: "Hidden",
711
821
  loading: "Loading market details",
712
822
  unavailableAria: "Market details unavailable",
713
823
  unavailableTitle: "Market details unavailable",
@@ -813,6 +923,7 @@ var enUsLabels = {
813
923
  settlementCriticalDifferenceLabel: "Critical",
814
924
  settlementValueUnavailable: "Not provided",
815
925
  settlementLoading: "Loading settlement",
926
+ settlementDetailsLoadError: "Settlement details could not be loaded.",
816
927
  settlementDetailsAria: (venueLabel) => `${venueLabel} settlement details`,
817
928
  settlementShowMoreAria: (ctaLabel, venueLabel) => `${ctaLabel} for ${venueLabel}`,
818
929
  settlementDescriptionLabel: "Description",
@@ -834,6 +945,9 @@ var enUsLabels = {
834
945
  maximumFractionDigits: 2
835
946
  })}\xA2 avg. price`,
836
947
  balance: (value) => `Balance ${value}`,
948
+ betdexBalance: (value) => `BETDEX balance ${value}`,
949
+ betdexBalanceUnavailable: "BETDEX balance unavailable",
950
+ manageBetdexAccount: "Manage BETDEX account",
837
951
  shares: (value) => `${value.toLocaleString("en-US", {
838
952
  minimumFractionDigits: Number.isInteger(value) ? 0 : 1,
839
953
  maximumFractionDigits: 2
@@ -951,6 +1065,10 @@ var enUsLabels = {
951
1065
  }
952
1066
  },
953
1067
  connectKalshi: "Connect Kalshi to trade",
1068
+ connectProphetx: "Connect ProphetX to trade",
1069
+ manageProphetx: "Manage ProphetX connection",
1070
+ prophetxFundingNotice: "Manage funds on ProphetX",
1071
+ prophetxSettlementNotice: "This position settles on ProphetX",
954
1072
  requiresKalshiAccount: "Requires Kalshi account",
955
1073
  tradingAccessVenues: "Venues",
956
1074
  tradingAccessAvailable: "Available",
@@ -999,6 +1117,7 @@ var enUsLabels = {
999
1117
  verified: "Verified",
1000
1118
  platformFee: "0% platform fees",
1001
1119
  estimatedFees: "Estimated fees",
1120
+ betdexSettlementFeeNotice: "BETDEX charges 1% of net profit per market at settlement, not per fill. The final fee depends on all positions in that market.",
1002
1121
  executionReserve: "Execution reserve",
1003
1122
  executionReserveTooltipAria: "Why funds are reserved",
1004
1123
  executionReserveDescription: "Held for price movement or possible venue charges, not a confirmed fee. Unused funds are returned after execution.",
@@ -1062,6 +1181,11 @@ var enUsLabels = {
1062
1181
  orderFullyFilled: "Order fully filled",
1063
1182
  orderPartiallyFilled: "Order partially filled",
1064
1183
  orderAveragePrice: (priceLabel) => `avg. ${priceLabel}`,
1184
+ orderAmount: "Order amount",
1185
+ orderLimitPrice: (priceLabel) => `limit ${priceLabel}`,
1186
+ limitVenueOrder: (venueLabel) => `${venueLabel} limit order`,
1187
+ limitOrderSubmitting: "Submitting limit order...",
1188
+ limitOrderSubmitted: "Limit order submitted",
1065
1189
  orderComplete: "Order complete",
1066
1190
  orderFilledAtPrice: (venueLabel, priceLabel) => `${venueLabel} order filled at ${priceLabel}`,
1067
1191
  orderFilledAtPriceWithAmount: (venueLabel, priceLabel, amountLabel) => `${venueLabel} order filled at ${priceLabel} (${amountLabel})`,
@@ -1144,6 +1268,22 @@ var enUsLabels = {
1144
1268
  cancel: "Cancel",
1145
1269
  fallbackError: "Signature declined. Please try again."
1146
1270
  },
1271
+ connectProphetxModal: {
1272
+ disconnect: "Disconnect ProphetX",
1273
+ disconnecting: "Disconnecting\u2026",
1274
+ disconnectError: "Could not disconnect ProphetX. Finish any open orders and try again.",
1275
+ title: "Connect ProphetX Account",
1276
+ description: "Add your ProphetX access key and secret key to trade with your existing account.",
1277
+ fundingNotice: "Trades use your ProphetX balance. Deposits, withdrawals, and transfers are managed on ProphetX, outside AGG.",
1278
+ instructions: "Create an API key in your ProphetX account settings",
1279
+ accessKey: "Access key",
1280
+ secretKey: "Secret key",
1281
+ verify: "Verify connection",
1282
+ verifying: "Verifying\u2026",
1283
+ error: "Could not connect to ProphetX. Check your credentials and try again.",
1284
+ connected: "Your ProphetX account is connected.",
1285
+ done: "Done"
1286
+ },
1147
1287
  connectKalshiModal: {
1148
1288
  ariaLabel: "Connect Kalshi Account",
1149
1289
  title: "Connect Kalshi Account",
@@ -1190,6 +1330,20 @@ var enUsLabels = {
1190
1330
  }
1191
1331
  },
1192
1332
  eventMarketPage: {
1333
+ loadMoreMarkets: "Load more markets",
1334
+ loadingMoreMarkets: "Loading markets\u2026",
1335
+ openOrders: {
1336
+ title: "Open orders",
1337
+ limitPriceHeader: "Limit price",
1338
+ filledHeader: "Filled",
1339
+ totalHeader: "Total",
1340
+ expirationHeader: "Expiration",
1341
+ // Abbreviated forms for the stacked mobile card.
1342
+ limitShort: "Limit",
1343
+ filledShort: "Filled",
1344
+ totalShort: "Tot.",
1345
+ expirationShort: "Exp."
1346
+ },
1193
1347
  unavailableAria: "Event market page unavailable",
1194
1348
  unavailableTitle: "Something went wrong",
1195
1349
  unavailableDescription: "We're having trouble loading this event right now.\nTry refreshing or check back later.",
@@ -1556,7 +1710,7 @@ var mergeAggUiConfig = (persisted, config) => {
1556
1710
  // src/execution/query-keys.ts
1557
1711
  var executionKeys = {
1558
1712
  all: () => ["execution"],
1559
- balances: (mode) => mode ? ["execution", "balances", mode] : ["execution", "balances"],
1713
+ balances: (mode, custody) => custody && custody !== "managed" ? ["execution", "balances", mode != null ? mode : "live", custody] : mode ? ["execution", "balances", mode] : ["execution", "balances"],
1560
1714
  positions: (cursor, limit, status, mode) => mode ? ["execution", "positions", cursor != null ? cursor : null, limit != null ? limit : null, status != null ? status : null, mode] : ["execution", "positions", cursor != null ? cursor : null, limit != null ? limit : null, status != null ? status : null],
1561
1715
  positionsPrefix: () => ["execution", "positions"],
1562
1716
  claimablePositionsCount: () => ["execution", "positions", "claimable-count"],
@@ -1582,7 +1736,11 @@ var balanceQueryKeys = {
1582
1736
  venue: (venuesKey) => ["venue-balances", venuesKey],
1583
1737
  venuePrefix: () => ["venue-balances"]
1584
1738
  };
1585
- var BALANCE_REFRESHING_ORDER_EVENTS = /* @__PURE__ */ new Set(["filled", "partial_fill"]);
1739
+ var BALANCE_REFRESHING_ORDER_EVENTS = /* @__PURE__ */ new Set([
1740
+ "filled",
1741
+ "partial_fill",
1742
+ "cancelled"
1743
+ ]);
1586
1744
  var invalidateBalanceQueries = (queryClient, options) => {
1587
1745
  var _a;
1588
1746
  const refetchType = (_a = options == null ? void 0 : options.refetchType) != null ? _a : "active";
@@ -1603,6 +1761,7 @@ var invalidateBalanceQueries = (queryClient, options) => {
1603
1761
  queryKey: balanceQueryKeys.venuePrefix(),
1604
1762
  refetchType
1605
1763
  });
1764
+ queryClient.invalidateQueries({ queryKey: ["agg", "hosted-venue-account"], refetchType });
1606
1765
  };
1607
1766
  var invalidatePositionQueries = (queryClient, options) => {
1608
1767
  var _a;
@@ -1653,7 +1812,7 @@ var invalidateUserClaimState = (queryClient, options) => {
1653
1812
  import { useContext as useContext7 } from "react";
1654
1813
 
1655
1814
  // src/core/providers/agg-provider.tsx
1656
- import { useQueryClient as useQueryClient3 } from "@tanstack/react-query";
1815
+ import { useQueryClient as useQueryClient4 } from "@tanstack/react-query";
1657
1816
 
1658
1817
  // src/core/providers/auth-provider.tsx
1659
1818
  import { QueryClient, QueryClientContext } from "@tanstack/react-query";
@@ -2105,7 +2264,7 @@ var EMPTY_MANAGED_BALANCES = {
2105
2264
  positions: []
2106
2265
  };
2107
2266
  function AggBalanceProvider({ children }) {
2108
- var _a;
2267
+ var _a, _b;
2109
2268
  const client = useContext2(AggClientContext);
2110
2269
  const authContext = useContext2(AggAuthContext);
2111
2270
  const { executionMode } = useResolvedExecutionMode();
@@ -2168,8 +2327,8 @@ function AggBalanceProvider({ children }) {
2168
2327
  }
2169
2328
  return sum + token.chains.reduce(
2170
2329
  (chainSum, chain) => {
2171
- var _a2, _b;
2172
- return chainSum + toTokenUnits((_a2 = chain.availableRaw) != null ? _a2 : chain.balanceRaw, (_b = chain.decimals) != null ? _b : token.decimals);
2330
+ var _a2, _b2;
2331
+ return chainSum + toTokenUnits((_a2 = chain.availableRaw) != null ? _a2 : chain.balanceRaw, (_b2 = chain.decimals) != null ? _b2 : token.decimals);
2173
2332
  },
2174
2333
  0
2175
2334
  );
@@ -2183,8 +2342,8 @@ function AggBalanceProvider({ children }) {
2183
2342
  }
2184
2343
  return sum + token.chains.reduce(
2185
2344
  (chainSum, chain) => {
2186
- var _a2, _b;
2187
- return chainSum + toTokenUnits((_a2 = chain.heldRaw) != null ? _a2 : "0", (_b = chain.decimals) != null ? _b : token.decimals);
2345
+ var _a2, _b2;
2346
+ return chainSum + toTokenUnits((_a2 = chain.heldRaw) != null ? _a2 : "0", (_b2 = chain.decimals) != null ? _b2 : token.decimals);
2188
2347
  },
2189
2348
  0
2190
2349
  );
@@ -2192,29 +2351,40 @@ function AggBalanceProvider({ children }) {
2192
2351
  }, [managedBalances]);
2193
2352
  const buildBalanceBreakdown = useCallback2(
2194
2353
  (rawForChain) => {
2195
- var _a2, _b;
2196
- const byChain = /* @__PURE__ */ new Map();
2354
+ var _a2, _b2;
2355
+ const bySource = /* @__PURE__ */ new Map();
2197
2356
  const cash = managedBalances.cash;
2357
+ const chainVenues = connectedVenues.filter((venue) => venue !== "betdex");
2198
2358
  for (const token of cash) {
2199
2359
  if (!isUsdBasedToken(token.tokenSymbol)) continue;
2200
2360
  for (const chain of token.chains) {
2201
- const current = (_a2 = byChain.get(chain.chainId)) != null ? _a2 : {
2202
- label: chainLabelFromId(chain.chainId),
2361
+ const native = chain.custodyKind === "VENUE_ACCOUNT";
2362
+ const key = native ? JSON.stringify([
2363
+ "venue-account",
2364
+ chain.venue,
2365
+ chain.venueAccountId,
2366
+ chain.externalAccountId,
2367
+ chain.chainId
2368
+ ]) : String(chain.chainId);
2369
+ const current = (_a2 = bySource.get(key)) != null ? _a2 : __spreadValues({
2370
+ key,
2371
+ label: native ? chain.venue ? resolveAggUiLabels("en").venues[chain.venue] : resolveAggUiLabels("en").userProfile.balance.venueAccount : chainLabelFromId(chain.chainId),
2203
2372
  balance: 0,
2204
- accountCount: 0
2205
- };
2206
- current.balance += toTokenUnits(rawForChain(chain), (_b = chain.decimals) != null ? _b : token.decimals);
2373
+ accountCount: 0,
2374
+ venues: native && chain.venue ? [chain.venue] : chainVenues.length > 0 ? chainVenues : void 0
2375
+ }, native ? {
2376
+ venue: chain.venue,
2377
+ venueAccountId: chain.venueAccountId,
2378
+ externalAccountId: chain.externalAccountId,
2379
+ isFresh: chain.isFresh === true
2380
+ } : {});
2381
+ current.balance += toTokenUnits(rawForChain(chain), (_b2 = chain.decimals) != null ? _b2 : token.decimals);
2207
2382
  current.accountCount += 1;
2208
- byChain.set(chain.chainId, current);
2383
+ if (native) current.isFresh = current.isFresh === true && chain.isFresh === true;
2384
+ bySource.set(key, current);
2209
2385
  }
2210
2386
  }
2211
- return Array.from(byChain.entries()).sort((a, b) => a[1].label.localeCompare(b[1].label)).map(([chainId, value2]) => ({
2212
- key: String(chainId),
2213
- label: value2.label,
2214
- balance: value2.balance,
2215
- accountCount: value2.accountCount,
2216
- venues: connectedVenues.length > 0 ? connectedVenues : void 0
2217
- }));
2387
+ return Array.from(bySource.values()).sort((a, b) => a.label.localeCompare(b.label));
2218
2388
  },
2219
2389
  [connectedVenues, managedBalances.cash]
2220
2390
  );
@@ -2236,8 +2406,27 @@ function AggBalanceProvider({ children }) {
2236
2406
  return actualPositionsBalance + reservedBalance;
2237
2407
  }, [managedBalances.positions, reservedBalance]);
2238
2408
  const kalshiVenueCash = (_a = managedBalances.venueCash) == null ? void 0 : _a.find((item) => item.venue === "kalshi");
2409
+ const venueCashBalances = useMemo2(
2410
+ () => {
2411
+ var _a2;
2412
+ return Object.fromEntries(
2413
+ ((_a2 = managedBalances.venueCash) != null ? _a2 : []).map((item) => [item.venue, item.balanceCents / 100])
2414
+ );
2415
+ },
2416
+ [managedBalances.venueCash]
2417
+ );
2239
2418
  const kalshiBalance = kalshiVenueCash ? kalshiVenueCash.balanceCents / 100 : null;
2240
2419
  const kalshiPortfolioValue = (kalshiVenueCash == null ? void 0 : kalshiVenueCash.portfolioValueCents) == null ? null : kalshiVenueCash.portfolioValueCents / 100;
2420
+ const betdexCash = (_b = managedBalances.venueCash) == null ? void 0 : _b.find(
2421
+ (item) => item.venue === "betdex" && item.accountModel === "platform-hosted"
2422
+ );
2423
+ const hostedUsd = (raw) => {
2424
+ if (raw === void 0 || !/^-?\d+$/.test(raw)) return null;
2425
+ const value2 = Number(raw) / 1e6;
2426
+ return Number.isFinite(value2) ? value2 : null;
2427
+ };
2428
+ const betdexBalance = (betdexCash == null ? void 0 : betdexCash.decimals) === 6 ? hostedUsd(betdexCash.balanceRaw) : null;
2429
+ const betdexAvailableBalance = (betdexCash == null ? void 0 : betdexCash.decimals) === 6 ? hostedUsd(betdexCash.availableRaw) : null;
2241
2430
  const refetch = useCallback2(() => {
2242
2431
  if (!isAuthenticated) return;
2243
2432
  void refetchBalances();
@@ -2257,6 +2446,8 @@ function AggBalanceProvider({ children }) {
2257
2446
  positionsBalanceTotal: 0,
2258
2447
  kalshiBalance: null,
2259
2448
  kalshiPortfolioValue: null,
2449
+ betdexBalance: null,
2450
+ betdexAvailableBalance: null,
2260
2451
  balanceBreakdown: [],
2261
2452
  availableBalanceBreakdown: [],
2262
2453
  connectedVenues: [],
@@ -2275,7 +2466,10 @@ function AggBalanceProvider({ children }) {
2275
2466
  reservedBalance,
2276
2467
  positionsBalanceTotal,
2277
2468
  kalshiBalance,
2469
+ venueCashBalances,
2278
2470
  kalshiPortfolioValue,
2471
+ betdexBalance,
2472
+ betdexAvailableBalance,
2279
2473
  balanceBreakdown,
2280
2474
  availableBalanceBreakdown,
2281
2475
  connectedVenues,
@@ -2293,7 +2487,10 @@ function AggBalanceProvider({ children }) {
2293
2487
  isBalancesLoading,
2294
2488
  isAuthenticated,
2295
2489
  kalshiBalance,
2490
+ venueCashBalances,
2296
2491
  kalshiPortfolioValue,
2492
+ betdexBalance,
2493
+ betdexAvailableBalance,
2297
2494
  managedBalances,
2298
2495
  balancesQuery.dataUpdatedAt,
2299
2496
  positionsBalanceTotal,
@@ -2353,14 +2550,15 @@ function useCachedAppConfig() {
2353
2550
  });
2354
2551
  }
2355
2552
  var toAppConfigResult = (query) => {
2356
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
2553
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
2357
2554
  return {
2358
- disabledVenues: (_b = (_a = query.data) == null ? void 0 : _a.disabledVenues) != null ? _b : [],
2359
- disabledCategoryPresets: (_d = (_c = query.data) == null ? void 0 : _c.disabledCategoryPresets) != null ? _d : [],
2360
- earlyAccessEnabled: (_f = (_e = query.data) == null ? void 0 : _e.earlyAccessEnabled) != null ? _f : false,
2361
- authOptions: (_h = (_g = query.data) == null ? void 0 : _g.authOptions) != null ? _h : [],
2362
- tradingMode: (_i = query.data) == null ? void 0 : _i.tradingMode,
2363
- paperStartingBalance: (_j = query.data) == null ? void 0 : _j.paperStartingBalance,
2555
+ prophetxExecutionMode: query.data ? (_a = query.data.prophetxExecutionMode) != null ? _a : "clearinghouse" : void 0,
2556
+ disabledVenues: (_c = (_b = query.data) == null ? void 0 : _b.disabledVenues) != null ? _c : [],
2557
+ disabledCategoryPresets: (_e = (_d = query.data) == null ? void 0 : _d.disabledCategoryPresets) != null ? _e : [],
2558
+ earlyAccessEnabled: (_g = (_f = query.data) == null ? void 0 : _f.earlyAccessEnabled) != null ? _g : false,
2559
+ authOptions: (_i = (_h = query.data) == null ? void 0 : _h.authOptions) != null ? _i : [],
2560
+ tradingMode: (_j = query.data) == null ? void 0 : _j.tradingMode,
2561
+ paperStartingBalance: (_k = query.data) == null ? void 0 : _k.paperStartingBalance,
2364
2562
  isLoading: query.isLoading,
2365
2563
  error: query.error
2366
2564
  };
@@ -2422,254 +2620,11 @@ import {
2422
2620
  useCallback as useCallback4,
2423
2621
  useContext as useContext5,
2424
2622
  useEffect as useEffect2,
2425
- useMemo as useMemo4,
2623
+ useMemo as useMemo5,
2426
2624
  useRef as useRef2,
2427
2625
  useState as useState2
2428
2626
  } from "react";
2429
- import { useQueryClient as useQueryClient2 } from "@tanstack/react-query";
2430
-
2431
- // src/market-data/chart-cache.ts
2432
- var MAX_CACHE_RETENTION_SECONDS = 7 * 30 * 24 * 60 * 60 + 14 * 24 * 60 * 60;
2433
- var getIntervalSeconds = (interval) => {
2434
- switch (interval) {
2435
- case "1m":
2436
- return 60;
2437
- case "5m":
2438
- return 5 * 60;
2439
- case "1h":
2440
- return 60 * 60;
2441
- case "1d":
2442
- return 24 * 60 * 60;
2443
- }
2444
- };
2445
- var createVenueData = (venue, outcomeIds = []) => ({
2446
- venue,
2447
- outcomeIds,
2448
- candles: [],
2449
- liveCandle: null,
2450
- lineValue: void 0,
2451
- lastTrade: null,
2452
- lastUpdateTs: null
2453
- });
2454
- var pruneCandlesBefore = (candles, cutoffTs) => {
2455
- if (cutoffTs <= 0) return candles;
2456
- let firstKeptIndex = 0;
2457
- while (firstKeptIndex < candles.length && candles[firstKeptIndex].time < cutoffTs) {
2458
- firstKeptIndex += 1;
2459
- }
2460
- if (firstKeptIndex === 0) return candles;
2461
- return candles.slice(firstKeptIndex);
2462
- };
2463
- var promoteClosedLiveCandle = (candles, liveCandle, expectedCandleTime) => {
2464
- if (!liveCandle || liveCandle.time >= expectedCandleTime) {
2465
- return { candles, promoted: false };
2466
- }
2467
- if (candles.some((candle) => candle.time === liveCandle.time)) {
2468
- return { candles, promoted: false };
2469
- }
2470
- return { candles: sortCandles([...candles, liveCandle]), promoted: true };
2471
- };
2472
- var resolveMaxLastUpdateTs = (venues) => {
2473
- let max = null;
2474
- for (const venueData of Object.values(venues)) {
2475
- if (venueData.lastUpdateTs != null && (max == null || venueData.lastUpdateTs > max)) {
2476
- max = venueData.lastUpdateTs;
2477
- }
2478
- }
2479
- return max;
2480
- };
2481
- var sortCandles = (candles) => {
2482
- return [...candles].sort((left, right) => left.time - right.time);
2483
- };
2484
- var createMarketChartData = (params) => {
2485
- var _a;
2486
- const candles = sortCandles(
2487
- params.response.data.map((candle) => ({
2488
- time: Math.floor(candle.t / 1e3),
2489
- open: candle.o,
2490
- high: candle.h,
2491
- low: candle.l,
2492
- close: candle.c,
2493
- volume: candle.v,
2494
- source: "rest"
2495
- }))
2496
- );
2497
- const lastCandle = candles[candles.length - 1];
2498
- const lastUpdateTs = (_a = lastCandle == null ? void 0 : lastCandle.time) != null ? _a : null;
2499
- const venues = {
2500
- [params.response.venue]: {
2501
- venue: params.response.venue,
2502
- outcomeIds: [params.response.venueMarketOutcomeId],
2503
- candles,
2504
- liveCandle: null,
2505
- lineValue: lastCandle == null ? void 0 : lastCandle.close,
2506
- lastTrade: null,
2507
- lastUpdateTs
2508
- }
2509
- };
2510
- return {
2511
- marketId: params.marketId,
2512
- outcomeIds: [params.response.venueMarketOutcomeId],
2513
- primaryVenue: params.response.venue,
2514
- interval: params.interval,
2515
- startTs: params.startTs,
2516
- endTs: params.endTs,
2517
- venues,
2518
- lastUpdateTs
2519
- };
2520
- };
2521
- var mergeMarketChartData = (params) => {
2522
- var _a, _b;
2523
- if (params.datasets.length === 0) {
2524
- return null;
2525
- }
2526
- const primaryVenue = (_b = (_a = params.datasets[0]) == null ? void 0 : _a.primaryVenue) != null ? _b : "aggregate";
2527
- const outcomeIds = Array.from(
2528
- new Set(
2529
- params.datasets.flatMap((dataset) => {
2530
- return dataset.outcomeIds.length > 0 ? dataset.outcomeIds : [dataset.marketId];
2531
- })
2532
- )
2533
- );
2534
- const venues = params.datasets.reduce((acc, dataset) => {
2535
- for (const [venue, venueData] of Object.entries(dataset.venues)) {
2536
- const existingVenueData = acc[venue];
2537
- acc[venue] = existingVenueData ? __spreadProps(__spreadValues({}, venueData), {
2538
- outcomeIds: Array.from(
2539
- /* @__PURE__ */ new Set([...existingVenueData.outcomeIds, ...venueData.outcomeIds])
2540
- )
2541
- }) : venueData;
2542
- }
2543
- return acc;
2544
- }, {});
2545
- return {
2546
- marketId: params.marketId,
2547
- outcomeIds,
2548
- primaryVenue,
2549
- interval: params.interval,
2550
- startTs: params.startTs,
2551
- endTs: params.endTs,
2552
- venues,
2553
- lastUpdateTs: resolveMaxLastUpdateTs(venues)
2554
- };
2555
- };
2556
- var applyMidpointToMarketChart = (data, update) => {
2557
- var _a;
2558
- if (!data || !Number.isFinite(update.midpoint)) {
2559
- return data;
2560
- }
2561
- const targetVenueEntry = Object.entries(data.venues).find(
2562
- ([, venueData]) => venueData.outcomeIds.includes(update.outcomeId)
2563
- );
2564
- if (!targetVenueEntry && data.marketId !== update.outcomeId) {
2565
- return data;
2566
- }
2567
- const [targetVenueName, currentVenue] = targetVenueEntry != null ? targetVenueEntry : [
2568
- data.primaryVenue,
2569
- (_a = data.venues[data.primaryVenue]) != null ? _a : createVenueData(data.primaryVenue, [update.outcomeId])
2570
- ];
2571
- const intervalSeconds = getIntervalSeconds(data.interval);
2572
- const expectedCandleTime = update.timestamp - update.timestamp % intervalSeconds;
2573
- let liveCandle = currentVenue.liveCandle;
2574
- const { candles: promotedCandles } = promoteClosedLiveCandle(
2575
- currentVenue.candles,
2576
- liveCandle,
2577
- expectedCandleTime
2578
- );
2579
- const nextCandles = pruneCandlesBefore(
2580
- promotedCandles,
2581
- update.timestamp - MAX_CACHE_RETENTION_SECONDS
2582
- );
2583
- if (liveCandle && liveCandle.time === expectedCandleTime) {
2584
- if (liveCandle.source === "trade") {
2585
- liveCandle = __spreadProps(__spreadValues({}, liveCandle), {
2586
- close: update.midpoint
2587
- });
2588
- } else {
2589
- liveCandle = __spreadProps(__spreadValues({}, liveCandle), {
2590
- close: update.midpoint,
2591
- high: Math.max(liveCandle.high, update.midpoint),
2592
- low: Math.min(liveCandle.low, update.midpoint),
2593
- source: "midpoint"
2594
- });
2595
- }
2596
- } else {
2597
- liveCandle = {
2598
- time: expectedCandleTime,
2599
- open: update.midpoint,
2600
- high: update.midpoint,
2601
- low: update.midpoint,
2602
- close: update.midpoint,
2603
- volume: 0,
2604
- source: "midpoint"
2605
- };
2606
- }
2607
- const nextVenues = __spreadProps(__spreadValues({}, data.venues), {
2608
- [targetVenueName]: __spreadProps(__spreadValues({}, currentVenue), {
2609
- outcomeIds: currentVenue.outcomeIds.includes(update.outcomeId) ? currentVenue.outcomeIds : [...currentVenue.outcomeIds, update.outcomeId],
2610
- candles: nextCandles,
2611
- liveCandle,
2612
- lineValue: update.midpoint,
2613
- lastUpdateTs: update.timestamp
2614
- })
2615
- });
2616
- return __spreadProps(__spreadValues({}, data), {
2617
- venues: nextVenues,
2618
- lastUpdateTs: resolveMaxLastUpdateTs(nextVenues)
2619
- });
2620
- };
2621
- var applyTradeToMarketChart = (data, trade) => {
2622
- var _a, _b, _c;
2623
- if (!data || data.marketId !== trade.outcomeId) {
2624
- return data;
2625
- }
2626
- const currentVenue = (_a = data.venues[trade.venue]) != null ? _a : createVenueData(trade.venue);
2627
- const intervalSeconds = getIntervalSeconds(data.interval);
2628
- const expectedCandleTime = trade.timestamp - trade.timestamp % intervalSeconds;
2629
- let liveCandle = currentVenue.liveCandle;
2630
- const { candles: promotedCandles } = promoteClosedLiveCandle(
2631
- currentVenue.candles,
2632
- liveCandle,
2633
- expectedCandleTime
2634
- );
2635
- const nextCandles = pruneCandlesBefore(
2636
- promotedCandles,
2637
- trade.timestamp - MAX_CACHE_RETENTION_SECONDS
2638
- );
2639
- if (liveCandle && liveCandle.time === expectedCandleTime) {
2640
- liveCandle = __spreadProps(__spreadValues({}, liveCandle), {
2641
- close: trade.price,
2642
- high: Math.max(liveCandle.high, trade.price),
2643
- low: Math.min(liveCandle.low, trade.price),
2644
- volume: ((_b = liveCandle.volume) != null ? _b : 0) + trade.size,
2645
- source: "trade"
2646
- });
2647
- } else if (!liveCandle || liveCandle.time !== expectedCandleTime) {
2648
- liveCandle = {
2649
- time: expectedCandleTime,
2650
- open: trade.price,
2651
- high: trade.price,
2652
- low: trade.price,
2653
- close: trade.price,
2654
- volume: trade.size,
2655
- source: "trade"
2656
- };
2657
- }
2658
- const nextVenues = __spreadProps(__spreadValues({}, data.venues), {
2659
- [trade.venue]: __spreadProps(__spreadValues({}, currentVenue), {
2660
- outcomeIds: currentVenue.outcomeIds.includes(trade.outcomeId) ? currentVenue.outcomeIds : [...currentVenue.outcomeIds, trade.outcomeId],
2661
- candles: nextCandles,
2662
- liveCandle,
2663
- lineValue: (_c = liveCandle == null ? void 0 : liveCandle.close) != null ? _c : trade.price,
2664
- lastTrade: trade,
2665
- lastUpdateTs: trade.timestamp
2666
- })
2667
- });
2668
- return __spreadProps(__spreadValues({}, data), {
2669
- venues: nextVenues,
2670
- lastUpdateTs: resolveMaxLastUpdateTs(nextVenues)
2671
- });
2672
- };
2627
+ import { useQueryClient as useQueryClient3 } from "@tanstack/react-query";
2673
2628
 
2674
2629
  // src/market-data/live-cache.ts
2675
2630
  var MAX_TRADES = 50;
@@ -2682,13 +2637,6 @@ var createMarketLiveState = (marketId, overrides) => __spreadValues({
2682
2637
  isConnected: false,
2683
2638
  integrity: "ok"
2684
2639
  }, overrides);
2685
- var withLiveConnectionState = (data, isConnected) => {
2686
- if (!data) return data;
2687
- if (data.isConnected === isConnected) return data;
2688
- return __spreadProps(__spreadValues({}, data), {
2689
- isConnected
2690
- });
2691
- };
2692
2640
  var withLiveOrderbook = (data, orderbook, source) => {
2693
2641
  const current = data != null ? data : createMarketLiveState(orderbook.marketId);
2694
2642
  return __spreadProps(__spreadValues({}, current), {
@@ -2723,133 +2671,254 @@ var withLiveTrade = (data, trade) => {
2723
2671
  });
2724
2672
  };
2725
2673
 
2726
- // src/market-data/orderbook-cache.ts
2727
- var truncateLevels = (levels, depth) => {
2728
- if (depth == null) return levels;
2729
- return levels.slice(0, Math.max(0, depth));
2674
+ // src/market-data/live-store.ts
2675
+ import { useMemo as useMemo4, useSyncExternalStore } from "react";
2676
+ import { useQueryClient as useQueryClient2 } from "@tanstack/react-query";
2677
+
2678
+ // src/market-data/query-keys.ts
2679
+ var marketDataKeys = {
2680
+ all: () => ["market-data"],
2681
+ live: (marketId) => ["market-data", "live", marketId],
2682
+ livePrefix: () => ["market-data", "live"],
2683
+ orderbook: (marketId, selectionKey, depth) => ["market-data", "orderbook", marketId, selectionKey != null ? selectionKey : null, depth != null ? depth : null],
2684
+ orderbookPrefix: (marketId) => marketId == null ? ["market-data", "orderbook"] : ["market-data", "orderbook", marketId],
2685
+ orderbookQuote: (marketId, side, size) => ["market-data", "orderbook-quote", marketId, side, size],
2686
+ /**
2687
+ * Stable per `{marketId, interval, rangeKey}`. Deliberately excludes the
2688
+ * concrete `startTs`/`endTs` of the rolling window — those advance every
2689
+ * candle bucket, and including them would mint a fresh key on every
2690
+ * rollover, defeating React Query's cache on tab/page revisits. The
2691
+ * current window is passed to `queryFn` via closure instead, and
2692
+ * `refetchInterval` advances the data under the stable key.
2693
+ */
2694
+ chart: (marketId, interval, rangeKey, countBack) => ["market-data", "chart", marketId, interval, rangeKey, countBack != null ? countBack : null],
2695
+ chartPrefix: (marketId, interval) => {
2696
+ if (!marketId) return ["market-data", "chart"];
2697
+ if (!interval) return ["market-data", "chart", marketId];
2698
+ return ["market-data", "chart", marketId, interval];
2699
+ }
2730
2700
  };
2731
- var truncateVenueOrderbooks = (venueOrderbooks, depth) => {
2732
- if (depth == null) return venueOrderbooks;
2733
- return Object.fromEntries(
2734
- Object.entries(venueOrderbooks).map(([venue, book]) => [
2735
- venue,
2736
- {
2737
- bids: truncateLevels(book.bids, depth),
2738
- asks: truncateLevels(book.asks, depth)
2739
- }
2740
- ])
2741
- );
2701
+
2702
+ // src/market-data/live-store.ts
2703
+ var LIVE_RETENTION = {
2704
+ maxInactiveSnapshots: 32,
2705
+ maxInactiveLevels: 16384,
2706
+ inactiveTtlMs: 5e3,
2707
+ maxEntries: 300
2742
2708
  };
2743
- var aggregateVenueLevels = (venueOrderbooks, side) => {
2744
- var _a;
2745
- const levelsByPrice = /* @__PURE__ */ new Map();
2746
- for (const [venue, orderbook] of Object.entries(venueOrderbooks)) {
2747
- for (const level of orderbook[side]) {
2748
- const currentLevel = levelsByPrice.get(level.price);
2749
- if (currentLevel) {
2750
- currentLevel.size += level.size;
2751
- currentLevel.venues[venue] = ((_a = currentLevel.venues[venue]) != null ? _a : 0) + level.size;
2752
- continue;
2753
- }
2754
- levelsByPrice.set(level.price, {
2755
- price: level.price,
2756
- size: level.size,
2757
- venues: {
2758
- [venue]: level.size
2759
- }
2709
+ var levelEntries = (state) => {
2710
+ var _a, _b, _c, _d, _e;
2711
+ const book = state.orderbook;
2712
+ return book ? ((_b = (_a = book.bids) == null ? void 0 : _a.length) != null ? _b : 0) + ((_d = (_c = book.asks) == null ? void 0 : _c.length) != null ? _d : 0) + Object.values((_e = book.venueOrderbooks) != null ? _e : {}).reduce(
2713
+ (n, venue) => n + venue.bids.length + venue.asks.length,
2714
+ 0
2715
+ ) : 0;
2716
+ };
2717
+ var hasSnapshot = (state) => !!state.orderbook || !!state.candles || state.trades.length > 0;
2718
+ var MarketLiveStore = class {
2719
+ constructor(seed) {
2720
+ this.seed = seed;
2721
+ this.connectionState = false;
2722
+ this.connectionGeneration = 0;
2723
+ this.states = /* @__PURE__ */ new Map();
2724
+ this.listeners = /* @__PURE__ */ new Map();
2725
+ this.touched = /* @__PURE__ */ new Map();
2726
+ this.needsPrune = false;
2727
+ }
2728
+ ensure(id) {
2729
+ var _a, _b;
2730
+ let state = this.states.get(id);
2731
+ if (state && !this.listeners.has(id) && Date.now() - ((_a = this.touched.get(id)) != null ? _a : 0) >= LIVE_RETENTION.inactiveTtlMs) {
2732
+ this.drop(id);
2733
+ state = void 0;
2734
+ }
2735
+ if (!state) {
2736
+ const seed = (_b = this.seed) == null ? void 0 : _b.call(this, id);
2737
+ state = __spreadProps(__spreadValues({}, createMarketLiveState(id, __spreadValues({ isConnected: this.connectionState }, seed))), {
2738
+ connectionGeneration: this.connectionGeneration,
2739
+ orderbookGeneration: (seed == null ? void 0 : seed.orderbook) ? -1 : this.connectionGeneration
2760
2740
  });
2741
+ this.states.set(id, state);
2742
+ this.touched.set(id, Date.now());
2743
+ this.needsPrune = true;
2761
2744
  }
2745
+ return state;
2746
+ }
2747
+ get(id) {
2748
+ const state = this.ensure(id);
2749
+ this.touched.set(id, Date.now());
2750
+ if (this.needsPrune) this.prune(/* @__PURE__ */ new Set([id]));
2751
+ return state;
2752
+ }
2753
+ /** Read retained data without creating a state, keeping it alive, or observing updates. */
2754
+ peek(id) {
2755
+ var _a;
2756
+ if (!this.listeners.has(id) && Date.now() - ((_a = this.touched.get(id)) != null ? _a : 0) >= LIVE_RETENTION.inactiveTtlMs)
2757
+ return void 0;
2758
+ return this.states.get(id);
2759
+ }
2760
+ /** Protect a render's whole selection before useSyncExternalStore subscribes. */
2761
+ getMany(ids) {
2762
+ const result = ids.map((id) => {
2763
+ const state = this.ensure(id);
2764
+ this.touched.set(id, Date.now());
2765
+ return state;
2766
+ });
2767
+ if (this.needsPrune) this.prune(new Set(ids));
2768
+ return result;
2769
+ }
2770
+ update(id, updater) {
2771
+ var _a;
2772
+ const previous = this.ensure(id);
2773
+ const next = updater(previous);
2774
+ if (!next || next === previous) return;
2775
+ const bookChanged = next.orderbook && (!previous.orderbook || next.orderbook.seq !== previous.orderbook.seq || next.orderbook.checksum !== previous.orderbook.checksum || next.orderbook.timestamp !== previous.orderbook.timestamp || next.orderbookSnapshotVersion !== previous.orderbookSnapshotVersion);
2776
+ this.states.set(
2777
+ id,
2778
+ bookChanged ? __spreadProps(__spreadValues({}, next), { orderbookGeneration: this.connectionGeneration }) : next
2779
+ );
2780
+ if (bookChanged || next.candles !== previous.candles || next.trades !== previous.trades)
2781
+ this.touched.set(id, Date.now());
2782
+ for (const listener of (_a = this.listeners.get(id)) != null ? _a : []) listener();
2783
+ if (!this.listeners.has(id) || this.needsPrune) this.prune(/* @__PURE__ */ new Set([id]));
2784
+ }
2785
+ connected(connected) {
2786
+ if (connected && !this.connectionState) this.connectionGeneration++;
2787
+ this.connectionState = connected;
2788
+ for (const id of [...this.states.keys()])
2789
+ this.update(
2790
+ id,
2791
+ (state) => state.isConnected === connected && state.connectionGeneration === this.connectionGeneration ? state : __spreadValues(__spreadProps(__spreadValues({}, state), {
2792
+ isConnected: connected,
2793
+ connectionGeneration: this.connectionGeneration
2794
+ }), connected ? {} : { candles: void 0 })
2795
+ );
2796
+ }
2797
+ subscribe(ids, listener) {
2798
+ var _a;
2799
+ for (const id of ids) {
2800
+ const set = (_a = this.listeners.get(id)) != null ? _a : /* @__PURE__ */ new Set();
2801
+ set.add(listener);
2802
+ this.listeners.set(id, set);
2803
+ this.touched.set(id, Date.now());
2804
+ }
2805
+ return () => {
2806
+ for (const id of ids) {
2807
+ const set = this.listeners.get(id);
2808
+ set == null ? void 0 : set.delete(listener);
2809
+ if (!(set == null ? void 0 : set.size)) {
2810
+ this.listeners.delete(id);
2811
+ this.touched.set(id, Date.now());
2812
+ }
2813
+ }
2814
+ this.prune();
2815
+ };
2816
+ }
2817
+ getDiagnostics() {
2818
+ const inactive = [...this.states].filter(([id]) => !this.listeners.has(id));
2819
+ return {
2820
+ entries: this.states.size,
2821
+ activeEntries: this.listeners.size,
2822
+ cachedBooks: [...this.states.values()].filter((state) => state.orderbook).length,
2823
+ cachedLevelEntries: [...this.states.values()].reduce(
2824
+ (n, state) => n + levelEntries(state),
2825
+ 0
2826
+ ),
2827
+ inactiveSnapshots: inactive.filter(([, state]) => hasSnapshot(state)).length,
2828
+ inactiveLevelEntries: inactive.reduce((n, [, state]) => n + levelEntries(state), 0),
2829
+ limits: LIVE_RETENTION
2830
+ };
2831
+ }
2832
+ drop(id) {
2833
+ this.states.delete(id);
2834
+ this.touched.delete(id);
2835
+ }
2836
+ prune(protectedIds = /* @__PURE__ */ new Set()) {
2837
+ var _a, _b;
2838
+ this.needsPrune = false;
2839
+ if (this.timer) clearTimeout(this.timer);
2840
+ this.timer = void 0;
2841
+ const now = Date.now();
2842
+ const inactive = [...this.states].filter(([id]) => !this.listeners.has(id) && !protectedIds.has(id)).sort(([a], [b]) => {
2843
+ var _a2, _b2;
2844
+ return ((_a2 = this.touched.get(a)) != null ? _a2 : 0) - ((_b2 = this.touched.get(b)) != null ? _b2 : 0);
2845
+ });
2846
+ let count = inactive.filter(([, state]) => hasSnapshot(state)).length;
2847
+ let levels = inactive.reduce((n, [, state]) => n + levelEntries(state), 0);
2848
+ for (const [id, state] of inactive) {
2849
+ if (now - ((_a = this.touched.get(id)) != null ? _a : 0) >= LIVE_RETENTION.inactiveTtlMs || this.states.size > LIVE_RETENTION.maxEntries || count > LIVE_RETENTION.maxInactiveSnapshots || levels > LIVE_RETENTION.maxInactiveLevels) {
2850
+ if (hasSnapshot(state)) count--;
2851
+ levels -= levelEntries(state);
2852
+ this.drop(id);
2853
+ }
2854
+ }
2855
+ let nextExpiry = Infinity;
2856
+ for (const id of this.states.keys())
2857
+ if (!this.listeners.has(id))
2858
+ nextExpiry = Math.min(
2859
+ nextExpiry,
2860
+ ((_b = this.touched.get(id)) != null ? _b : now) + LIVE_RETENTION.inactiveTtlMs
2861
+ );
2862
+ if (Number.isFinite(nextExpiry))
2863
+ this.timer = setTimeout(
2864
+ () => {
2865
+ this.timer = void 0;
2866
+ this.prune();
2867
+ },
2868
+ Math.max(1, nextExpiry - now)
2869
+ );
2762
2870
  }
2763
- return [...levelsByPrice.values()].sort(
2764
- (left, right) => side === "bids" ? right.price - left.price : left.price - right.price
2765
- );
2766
- };
2767
- var createMarketOrderbookDataFromVenueOrderbooks = ({
2768
- marketId,
2769
- venueOrderbooks,
2770
- timestamp = Math.floor(Date.now() / 1e3)
2771
- }) => {
2772
- var _a, _b, _c, _d;
2773
- const bids = aggregateVenueLevels(venueOrderbooks, "bids");
2774
- const asks = aggregateVenueLevels(venueOrderbooks, "asks");
2775
- const bestBid = (_b = (_a = bids[0]) == null ? void 0 : _a.price) != null ? _b : null;
2776
- const bestAsk = (_d = (_c = asks[0]) == null ? void 0 : _c.price) != null ? _d : null;
2777
- return {
2778
- marketId,
2779
- orderbook: {
2780
- bids,
2781
- asks
2782
- },
2783
- venueOrderbooks,
2784
- venues: Object.fromEntries(
2785
- Object.entries(venueOrderbooks).map(([venue, orderbook]) => {
2786
- var _a2, _b2, _c2, _d2;
2787
- return [
2788
- venue,
2789
- {
2790
- bestBid: (_b2 = (_a2 = orderbook.bids[0]) == null ? void 0 : _a2.price) != null ? _b2 : null,
2791
- bestAsk: (_d2 = (_c2 = orderbook.asks[0]) == null ? void 0 : _c2.price) != null ? _d2 : null
2792
- }
2793
- ];
2794
- })
2795
- ),
2796
- midpoint: bestBid != null && bestAsk != null ? (bestBid + bestAsk) / 2 : null,
2797
- spread: bestBid != null && bestAsk != null ? bestAsk - bestBid : null,
2798
- timestamp,
2799
- snapshotVersion: 0,
2800
- integrity: "ok"
2801
- };
2802
- };
2803
- var createMarketOrderbookDataFromState = (state, options) => {
2804
- var _a;
2805
- return {
2806
- marketId: state.marketId,
2807
- orderbook: {
2808
- bids: state.bids,
2809
- asks: state.asks
2810
- },
2811
- venueOrderbooks: state.venueOrderbooks,
2812
- venues: state.venues,
2813
- midpoint: state.midpoint,
2814
- spread: state.spread,
2815
- timestamp: state.timestamp,
2816
- snapshotVersion: (_a = options == null ? void 0 : options.snapshotVersion) != null ? _a : 0,
2817
- seq: state.seq,
2818
- checksum: state.checksum,
2819
- integrity: "ok"
2820
- };
2821
- };
2822
- var marketOrderbookDataToResponse = (data) => {
2823
- return {
2824
- venueMarketId: data.marketId,
2825
- orderbook: data.orderbook,
2826
- venueOrderbooks: data.venueOrderbooks,
2827
- venues: data.venues,
2828
- midpoint: data.midpoint,
2829
- spread: data.spread,
2830
- timestamp: data.timestamp,
2831
- seq: data.seq,
2832
- checksum: data.checksum,
2833
- matchedMarkets: data.matchedMarkets
2834
- };
2835
- };
2836
- var withOrderbookIntegrity = (data, integrity) => {
2837
- if (!data) return data;
2838
- if (data.integrity === integrity) return data;
2839
- return __spreadProps(__spreadValues({}, data), {
2840
- integrity
2841
- });
2842
- };
2843
- var applyOrderbookDepth = (data, depth) => {
2844
- if (depth == null) return data;
2845
- return __spreadProps(__spreadValues({}, data), {
2846
- orderbook: {
2847
- bids: truncateLevels(data.orderbook.bids, depth),
2848
- asks: truncateLevels(data.orderbook.asks, depth)
2849
- },
2850
- venueOrderbooks: truncateVenueOrderbooks(data.venueOrderbooks, depth)
2851
- });
2852
2871
  };
2872
+ var stores = /* @__PURE__ */ new WeakMap();
2873
+ function getMarketLiveStore(client) {
2874
+ let store = stores.get(client);
2875
+ if (!store) {
2876
+ store = new MarketLiveStore((id) => {
2877
+ var _a;
2878
+ return (_a = client.getQueryData) == null ? void 0 : _a.call(client, marketDataKeys.live(id));
2879
+ });
2880
+ stores.set(client, store);
2881
+ }
2882
+ return store;
2883
+ }
2884
+ function useLiveStates(ids) {
2885
+ const client = useQueryClient2();
2886
+ const store = getMarketLiveStore(client);
2887
+ const key = JSON.stringify(ids);
2888
+ const selector = useMemo4(() => {
2889
+ const selectedIds = JSON.parse(key);
2890
+ let previous = [];
2891
+ return {
2892
+ subscribe: (listener) => store.subscribe(selectedIds, listener),
2893
+ get: () => {
2894
+ const next = store.getMany(selectedIds).map((data) => ({ data }));
2895
+ if (next.length === previous.length && next.every((entry, index) => {
2896
+ var _a;
2897
+ return entry.data === ((_a = previous[index]) == null ? void 0 : _a.data);
2898
+ }))
2899
+ return previous;
2900
+ previous = next;
2901
+ return next;
2902
+ }
2903
+ };
2904
+ }, [key, store]);
2905
+ return useSyncExternalStore(selector.subscribe, selector.get, selector.get);
2906
+ }
2907
+ function mergeCandleTails(previous, next) {
2908
+ return Object.fromEntries(
2909
+ ["1m", "5m", "1h", "1d"].map((interval) => {
2910
+ var _a;
2911
+ const oldClosed = (_a = previous == null ? void 0 : previous[interval].closed) != null ? _a : [];
2912
+ const incoming = next[interval].closed;
2913
+ const closed = incoming.length ? [
2914
+ ...new Map(
2915
+ [...oldClosed, ...incoming].map((candle) => [candle.openTime, candle])
2916
+ ).values()
2917
+ ].sort((a, b) => a.openTime - b.openTime).slice(-500) : oldClosed;
2918
+ return [interval, { forming: next[interval].forming, closed }];
2919
+ })
2920
+ );
2921
+ }
2853
2922
 
2854
2923
  // src/market-data/market-resolution-cache.ts
2855
2924
  var isRecord = (value) => {
@@ -2943,29 +3012,116 @@ var applyResolutionToCachedData = (data, resolution) => {
2943
3012
  return changed ? next : data;
2944
3013
  };
2945
3014
 
2946
- // src/market-data/query-keys.ts
2947
- var marketDataKeys = {
2948
- all: () => ["market-data"],
2949
- live: (marketId) => ["market-data", "live", marketId],
2950
- livePrefix: () => ["market-data", "live"],
2951
- orderbook: (marketId, selectionKey, depth) => ["market-data", "orderbook", marketId, selectionKey != null ? selectionKey : null, depth != null ? depth : null],
2952
- orderbookPrefix: (marketId) => marketId == null ? ["market-data", "orderbook"] : ["market-data", "orderbook", marketId],
2953
- orderbookQuote: (marketId, side, size) => ["market-data", "orderbook-quote", marketId, side, size],
2954
- /**
2955
- * Stable per `{marketId, interval, rangeKey}`. Deliberately excludes the
2956
- * concrete `startTs`/`endTs` of the rolling window — those advance every
2957
- * candle bucket, and including them would mint a fresh key on every
2958
- * rollover, defeating React Query's cache on tab/page revisits. The
2959
- * current window is passed to `queryFn` via closure instead, and
2960
- * `refetchInterval` advances the data under the stable key.
2961
- */
2962
- chart: (marketId, interval, rangeKey, countBack) => ["market-data", "chart", marketId, interval, rangeKey, countBack != null ? countBack : null],
2963
- chartPrefix: (marketId, interval) => {
2964
- if (!marketId) return ["market-data", "chart"];
2965
- if (!interval) return ["market-data", "chart", marketId];
2966
- return ["market-data", "chart", marketId, interval];
2967
- }
3015
+ // src/market-data/history-retention.ts
3016
+ var DEFAULT_HISTORY_RETENTION = {
3017
+ maxInactiveQueries: 16,
3018
+ maxInactivePoints: 2e4
3019
+ };
3020
+ var owners = /* @__PURE__ */ new WeakMap();
3021
+ var isHistory = (key) => key[0] === "market-data" && key[1] === "chart";
3022
+ var points = (data) => {
3023
+ const chart = data;
3024
+ return (chart == null ? void 0 : chart.venues) ? Object.values(chart.venues).reduce(
3025
+ (total, venue) => total + venue.candles.length + (venue.liveCandle ? 1 : 0),
3026
+ 0
3027
+ ) : 0;
2968
3028
  };
3029
+ function getChartHistoryRetentionStats(client) {
3030
+ var _a, _b, _c;
3031
+ const queries = client.getQueryCache().findAll({ queryKey: marketDataKeys.chartPrefix() });
3032
+ const active = queries.filter((query) => query.getObserversCount() > 0);
3033
+ const inactive = queries.filter((query) => query.getObserversCount() === 0);
3034
+ const owner = owners.get(client);
3035
+ return {
3036
+ activeQueries: active.length,
3037
+ inactiveQueries: inactive.length,
3038
+ activePoints: active.reduce((sum, query) => sum + points(query.state.data), 0),
3039
+ inactivePoints: inactive.reduce((sum, query) => sum + points(query.state.data), 0),
3040
+ inFlightQueries: queries.filter((query) => query.state.fetchStatus === "fetching").length,
3041
+ trackedQueries: (_a = owner == null ? void 0 : owner.touched.size) != null ? _a : 0,
3042
+ evictedQueries: (_b = owner == null ? void 0 : owner.evicted) != null ? _b : 0,
3043
+ limits: (_c = owner == null ? void 0 : owner.limits) != null ? _c : DEFAULT_HISTORY_RETENTION
3044
+ };
3045
+ }
3046
+ function installChartHistoryRetention(client, limits = DEFAULT_HISTORY_RETENTION) {
3047
+ let owner = owners.get(client);
3048
+ if (!owner) {
3049
+ owner = {
3050
+ refs: 0,
3051
+ clock: Date.now(),
3052
+ touched: /* @__PURE__ */ new Map(),
3053
+ evicted: 0,
3054
+ queued: false,
3055
+ pruning: false,
3056
+ limits,
3057
+ unsubscribe: () => {
3058
+ },
3059
+ prune: () => {
3060
+ }
3061
+ };
3062
+ owners.set(client, owner);
3063
+ const current2 = owner;
3064
+ const prune = () => {
3065
+ if (current2.pruning) return;
3066
+ current2.pruning = true;
3067
+ try {
3068
+ const inactive = client.getQueryCache().findAll({ queryKey: marketDataKeys.chartPrefix() }).filter((query) => query.getObserversCount() === 0).sort(
3069
+ (a, b) => {
3070
+ var _a, _b;
3071
+ return ((_a = current2.touched.get(a.queryHash)) != null ? _a : a.state.dataUpdatedAt) - ((_b = current2.touched.get(b.queryHash)) != null ? _b : b.state.dataUpdatedAt);
3072
+ }
3073
+ );
3074
+ let count = inactive.length;
3075
+ let totalPoints = inactive.reduce((sum, query) => sum + points(query.state.data), 0);
3076
+ for (const query of inactive) {
3077
+ if (count <= current2.limits.maxInactiveQueries && totalPoints <= current2.limits.maxInactivePoints)
3078
+ break;
3079
+ if (query.getObserversCount() > 0) continue;
3080
+ count--;
3081
+ totalPoints -= points(query.state.data);
3082
+ current2.evicted++;
3083
+ current2.touched.delete(query.queryHash);
3084
+ client.removeQueries({ queryKey: query.queryKey, exact: true });
3085
+ }
3086
+ } finally {
3087
+ current2.pruning = false;
3088
+ }
3089
+ };
3090
+ current2.prune = prune;
3091
+ const schedule = () => {
3092
+ if (current2.queued) return;
3093
+ current2.queued = true;
3094
+ queueMicrotask(() => {
3095
+ current2.queued = false;
3096
+ prune();
3097
+ });
3098
+ };
3099
+ current2.unsubscribe = client.getQueryCache().subscribe((event) => {
3100
+ if (!isHistory(event.query.queryKey)) return;
3101
+ if (event.type === "removed") current2.touched.delete(event.query.queryHash);
3102
+ else if (event.type === "observerAdded" || event.type === "updated" || event.type === "added") {
3103
+ current2.clock = Math.max(current2.clock + 1, Date.now());
3104
+ current2.touched.set(event.query.queryHash, current2.clock);
3105
+ }
3106
+ if (!current2.pruning) schedule();
3107
+ });
3108
+ schedule();
3109
+ }
3110
+ owner.refs++;
3111
+ const current = owner;
3112
+ let released = false;
3113
+ return () => {
3114
+ if (released) return;
3115
+ released = true;
3116
+ if (--current.refs > 0) return;
3117
+ queueMicrotask(() => {
3118
+ if (current.refs > 0) return;
3119
+ current.prune();
3120
+ current.unsubscribe();
3121
+ owners.delete(client);
3122
+ });
3123
+ };
3124
+ }
2969
3125
 
2970
3126
  // src/core/providers/hooks.ts
2971
3127
  import { useContext as useContext4 } from "react";
@@ -3012,20 +3168,12 @@ var AggWebSocketContext = createContext3(null);
3012
3168
  var AggWebSocketConnectionContext = createContext3(false);
3013
3169
  var AggWsUserEventContext = createContext3(null);
3014
3170
  var snapshotUnavailableOutcomeIdPattern = /snapshot unavailable for\s+([^\s]+)/i;
3015
- var ORDERBOOK_DEBUG_TOP_LEVELS = 5;
3016
3171
  var resolveSnapshotUnavailableOutcomeId = (errorMessage) => {
3017
3172
  var _a;
3018
3173
  const matchedOutcomeId = (_a = snapshotUnavailableOutcomeIdPattern.exec(errorMessage)) == null ? void 0 : _a[1];
3019
3174
  if (!matchedOutcomeId) return null;
3020
3175
  return matchedOutcomeId.replace(/[.,;:!?]+$/, "");
3021
3176
  };
3022
- var summarizeTopLevels = (levels) => {
3023
- return levels.slice(0, ORDERBOOK_DEBUG_TOP_LEVELS).map((level) => ({ price: level.price, size: level.size }));
3024
- };
3025
- var debugOrderbook = (enabled, event, payload) => {
3026
- if (!enabled) return;
3027
- console.debug(`[AggHooks][ws-provider] ${event}`, payload);
3028
- };
3029
3177
  function useAggWebSocket() {
3030
3178
  return useContext5(AggWebSocketContext);
3031
3179
  }
@@ -3105,7 +3253,9 @@ function useOnWithdrawalLifecycle(callback) {
3105
3253
  function AggWebSocketProvider({ children }) {
3106
3254
  const client = useAggClient();
3107
3255
  const { enableWebsocketsLogs } = useAggUiConfig();
3108
- const queryClient = useQueryClient2();
3256
+ const queryClient = useQueryClient3();
3257
+ const liveStore = getMarketLiveStore(queryClient);
3258
+ useEffect2(() => installChartHistoryRetention(queryClient), [queryClient]);
3109
3259
  const [ws, setWs] = useState2(null);
3110
3260
  const [isConnected, setIsConnected] = useState2(false);
3111
3261
  const [isClientAuthenticated, setIsClientAuthenticated] = useState2(client.isAuthenticated);
@@ -3125,7 +3275,7 @@ function AggWebSocketProvider({ children }) {
3125
3275
  const withdrawalLifecycleListenersRef = useRef2(
3126
3276
  /* @__PURE__ */ new Set()
3127
3277
  );
3128
- const userEventListeners = useMemo4(
3278
+ const userEventListeners = useMemo5(
3129
3279
  () => ({
3130
3280
  addOrderSubmittedListener: (cb) => {
3131
3281
  orderSubmittedListenersRef.current.add(cb);
@@ -3160,43 +3310,11 @@ function AggWebSocketProvider({ children }) {
3160
3310
  }),
3161
3311
  []
3162
3312
  );
3163
- const syncOrderbookQueries = useCallback4(
3164
- (marketId, updater) => {
3165
- var _a;
3166
- const queries = queryClient.getQueryCache().findAll({
3167
- queryKey: marketDataKeys.orderbookPrefix(marketId)
3168
- });
3169
- for (const query of queries) {
3170
- const depth = (_a = query.queryKey[4]) != null ? _a : null;
3171
- queryClient.setQueryData(
3172
- query.queryKey,
3173
- (previous) => updater(query.queryKey, depth, previous)
3174
- );
3175
- }
3176
- },
3177
- [queryClient]
3178
- );
3179
- const syncChartQueries = useCallback4(
3180
- (marketId, updater) => {
3181
- const queries = queryClient.getQueryCache().findAll({
3182
- queryKey: marketDataKeys.chartPrefix(marketId)
3183
- });
3184
- for (const query of queries) {
3185
- queryClient.setQueryData(
3186
- query.queryKey,
3187
- (previous) => updater(query.queryKey, previous)
3188
- );
3189
- }
3190
- },
3191
- [queryClient]
3192
- );
3193
3313
  const syncLiveQuery = useCallback4(
3194
3314
  (marketId, updater) => {
3195
- queryClient.setQueryData(marketDataKeys.live(marketId), (previous) => {
3196
- return updater(previous);
3197
- });
3315
+ liveStore.update(marketId, (previous) => updater(previous));
3198
3316
  },
3199
- [queryClient]
3317
+ [liveStore]
3200
3318
  );
3201
3319
  const invalidateBalanceCaches = useCallback4(() => {
3202
3320
  const now = Date.now();
@@ -3215,9 +3333,9 @@ function AggWebSocketProvider({ children }) {
3215
3333
  const { outcomeId } = resolution;
3216
3334
  syncLiveQuery(outcomeId, (previous) => {
3217
3335
  if (!previous) return previous;
3218
- if (previous.orderbook == null && previous.orderbookError == null) return previous;
3219
3336
  return __spreadProps(__spreadValues({}, previous), {
3220
3337
  orderbook: null,
3338
+ orderbookSnapshotVersion: previous.orderbookSnapshotVersion + 1,
3221
3339
  orderbookError: null,
3222
3340
  integrity: "ok"
3223
3341
  });
@@ -3266,93 +3384,63 @@ function AggWebSocketProvider({ children }) {
3266
3384
  },
3267
3385
  [queryClient, syncLiveQuery]
3268
3386
  );
3269
- const callbacks = useMemo4(
3387
+ const publishLocalCandles = useCallback4(
3388
+ (id) => {
3389
+ const builder = getOrCreateBuilder(id);
3390
+ const candles = Object.fromEntries(
3391
+ ["1m", "5m", "1h", "1d"].map((interval) => [
3392
+ interval,
3393
+ {
3394
+ forming: builder.getForming(interval) ? __spreadValues({}, builder.getForming(interval)) : null,
3395
+ closed: builder.getClosed(interval).slice(-2)
3396
+ }
3397
+ ])
3398
+ );
3399
+ liveStore.update(id, (previous) => __spreadProps(__spreadValues({}, previous), { candles }));
3400
+ },
3401
+ [liveStore]
3402
+ );
3403
+ const callbacks = useMemo5(
3270
3404
  () => ({
3405
+ onMarketView: (view) => {
3406
+ if (view.book && view.integrity === "ok")
3407
+ resyncDeadlineByMarketRef.current.delete(view.outcomeId);
3408
+ liveStore.update(view.outcomeId, (previous) => __spreadProps(__spreadValues({}, view.book ? withLiveOrderbook(previous, view.book, view.snapshot ? "snapshot" : "delta") : previous), {
3409
+ integrity: view.integrity,
3410
+ candles: mergeCandleTails(previous.candles, view.candles),
3411
+ receivedAtMs: view.receivedAtMs,
3412
+ trades: [...view.trades, ...previous.trades].slice(0, 50)
3413
+ }));
3414
+ getOrCreateBuilder(view.outcomeId).replaceTail(view.candles);
3415
+ },
3271
3416
  onSnapshot: (marketId, book) => {
3272
- const orderbook = createMarketOrderbookDataFromState(book);
3417
+ var _a, _b;
3418
+ if ((_a = wsRef.current) == null ? void 0 : _a.processesCandles) return;
3273
3419
  resyncDeadlineByMarketRef.current.delete(marketId);
3274
- syncOrderbookQueries(marketId, (_queryKey, depth, previous) => {
3275
- var _a;
3276
- const previousSnapshotVersion = (_a = previous == null ? void 0 : previous.snapshotVersion) != null ? _a : 0;
3277
- return applyOrderbookDepth(
3278
- __spreadProps(__spreadValues({}, orderbook), {
3279
- snapshotVersion: previousSnapshotVersion + 1
3280
- }),
3281
- depth
3282
- );
3283
- });
3284
3420
  syncLiveQuery(marketId, (previous) => withLiveOrderbook(previous, book, "snapshot"));
3285
- if (book.midpoint != null) {
3421
+ if (!((_b = wsRef.current) == null ? void 0 : _b.processesCandles) && book.midpoint != null) {
3286
3422
  getOrCreateBuilder(marketId).addMidpoint(book.midpoint, book.timestamp);
3287
- syncChartQueries(
3288
- marketId,
3289
- (_queryKey, previous) => applyMidpointToMarketChart(previous, {
3290
- outcomeId: marketId,
3291
- midpoint: book.midpoint,
3292
- timestamp: book.timestamp
3293
- })
3294
- );
3423
+ publishLocalCandles(marketId);
3295
3424
  }
3296
3425
  },
3297
3426
  onDelta: (marketId, book) => {
3298
3427
  var _a, _b;
3299
- const previousLiveState = queryClient.getQueryData(marketDataKeys.live(marketId));
3300
- debugOrderbook(enableWebsocketsLogs, "delta_received", {
3301
- outcomeId: marketId,
3302
- seq: book.seq,
3303
- checksum: book.checksum,
3304
- hasTargetOrderbook: Boolean(previousLiveState == null ? void 0 : previousLiveState.orderbook),
3305
- beforeTop: (previousLiveState == null ? void 0 : previousLiveState.orderbook) ? {
3306
- bids: summarizeTopLevels(previousLiveState.orderbook.bids),
3307
- asks: summarizeTopLevels(previousLiveState.orderbook.asks)
3308
- } : null,
3309
- afterTop: {
3310
- bids: summarizeTopLevels(book.bids),
3311
- asks: summarizeTopLevels(book.asks)
3312
- }
3313
- });
3314
- const orderbook = createMarketOrderbookDataFromState(book);
3428
+ if ((_a = wsRef.current) == null ? void 0 : _a.processesCandles) return;
3315
3429
  resyncDeadlineByMarketRef.current.delete(marketId);
3316
- syncOrderbookQueries(marketId, (_queryKey, depth, previous) => {
3317
- var _a2;
3318
- const previousSnapshotVersion = (_a2 = previous == null ? void 0 : previous.snapshotVersion) != null ? _a2 : 0;
3319
- return applyOrderbookDepth(
3320
- __spreadProps(__spreadValues({}, orderbook), {
3321
- snapshotVersion: previousSnapshotVersion
3322
- }),
3323
- depth
3324
- );
3325
- });
3326
3430
  syncLiveQuery(marketId, (previous) => withLiveOrderbook(previous, book, "delta"));
3327
- const nextLiveState = queryClient.getQueryData(
3328
- marketDataKeys.live(marketId)
3329
- );
3330
- debugOrderbook(enableWebsocketsLogs, "delta_cached", {
3331
- outcomeId: marketId,
3332
- seq: (_b = (_a = nextLiveState == null ? void 0 : nextLiveState.orderbook) == null ? void 0 : _a.seq) != null ? _b : null,
3333
- selectorTop: (nextLiveState == null ? void 0 : nextLiveState.orderbook) ? {
3334
- bids: summarizeTopLevels(nextLiveState.orderbook.bids),
3335
- asks: summarizeTopLevels(nextLiveState.orderbook.asks)
3336
- } : null
3337
- });
3338
- if (book.midpoint != null) {
3431
+ if (!((_b = wsRef.current) == null ? void 0 : _b.processesCandles) && book.midpoint != null) {
3339
3432
  getOrCreateBuilder(marketId).addMidpoint(book.midpoint, book.timestamp);
3340
- syncChartQueries(
3341
- marketId,
3342
- (_queryKey, previous) => applyMidpointToMarketChart(previous, {
3343
- outcomeId: marketId,
3344
- midpoint: book.midpoint,
3345
- timestamp: book.timestamp
3346
- })
3347
- );
3433
+ publishLocalCandles(marketId);
3348
3434
  }
3349
3435
  },
3350
3436
  onTrade: (trade) => {
3351
- syncChartQueries(trade.outcomeId, (_queryKey, previous) => {
3352
- return applyTradeToMarketChart(previous, trade);
3353
- });
3437
+ var _a, _b;
3438
+ if ((_a = wsRef.current) == null ? void 0 : _a.processesCandles) return;
3354
3439
  syncLiveQuery(trade.outcomeId, (previous) => withLiveTrade(previous, trade));
3355
- getOrCreateBuilder(trade.outcomeId).addTrade(trade.price, trade.size, trade.timestamp);
3440
+ if (!((_b = wsRef.current) == null ? void 0 : _b.processesCandles)) {
3441
+ getOrCreateBuilder(trade.outcomeId).addTrade(trade.price, trade.size, trade.timestamp);
3442
+ publishLocalCandles(trade.outcomeId);
3443
+ }
3356
3444
  },
3357
3445
  onHeartbeat: () => {
3358
3446
  const now = Date.now();
@@ -3368,10 +3456,6 @@ function AggWebSocketProvider({ children }) {
3368
3456
  if (event.type !== "seq_gap" && event.type !== "checksum_mismatch") return;
3369
3457
  const id = (_a = event.outcomeId) != null ? _a : event.marketId;
3370
3458
  resyncDeadlineByMarketRef.current.set(id, Date.now() + 35e3);
3371
- syncOrderbookQueries(
3372
- id,
3373
- (_queryKey, _depth, previous) => withOrderbookIntegrity(previous, "resyncing")
3374
- );
3375
3459
  syncLiveQuery(id, (previous) => withLiveIntegrity(previous, "resyncing"));
3376
3460
  },
3377
3461
  onOrderSubmitted: (msg) => {
@@ -3440,38 +3524,34 @@ function AggWebSocketProvider({ children }) {
3440
3524
  } else {
3441
3525
  resetAllBuilders();
3442
3526
  }
3443
- const liveQueries = queryClient.getQueryCache().findAll({
3444
- queryKey: marketDataKeys.livePrefix()
3445
- });
3446
- for (const query of liveQueries) {
3447
- queryClient.setQueryData(query.queryKey, (previous) => {
3448
- return withLiveConnectionState(
3449
- previous,
3450
- connected
3451
- );
3452
- });
3453
- }
3527
+ liveStore.connected(connected);
3454
3528
  }
3455
3529
  }),
3456
3530
  [
3457
3531
  client,
3458
- enableWebsocketsLogs,
3459
3532
  invalidateActivityCaches,
3460
3533
  invalidateBalanceCaches,
3461
3534
  invalidatePositionCaches,
3462
3535
  invalidateResolutionCaches,
3463
3536
  isClientAuthenticated,
3464
3537
  queryClient,
3465
- syncChartQueries,
3466
3538
  syncLiveQuery,
3467
- syncOrderbookQueries
3539
+ liveStore,
3540
+ publishLocalCandles
3468
3541
  ]
3469
3542
  );
3543
+ const callbacksRef = useRef2(callbacks);
3544
+ callbacksRef.current = callbacks;
3545
+ useEffect2(() => {
3546
+ var _a;
3547
+ (_a = wsRef.current) == null ? void 0 : _a.setCallbacks(callbacks);
3548
+ }, [callbacks]);
3470
3549
  useEffect2(() => {
3550
+ var _a;
3471
3551
  let instance = null;
3472
3552
  const resyncDeadlineByMarket = resyncDeadlineByMarketRef.current;
3473
3553
  try {
3474
- instance = client.createWebSocket(callbacks, { enableLogs: enableWebsocketsLogs });
3554
+ instance = client.createWebSocket(callbacksRef.current, { enableLogs: enableWebsocketsLogs });
3475
3555
  } catch (e) {
3476
3556
  console.warn(
3477
3557
  "[AggUI] WebSocket connection could not be established. Ensure wsUrl is configured in createAggClient(). Real-time features (live prices, order updates) are disabled."
@@ -3481,6 +3561,11 @@ function AggWebSocketProvider({ children }) {
3481
3561
  setIsConnected(false);
3482
3562
  return;
3483
3563
  }
3564
+ (_a = instance.setHostDiagnostics) == null ? void 0 : _a.call(instance, () => ({
3565
+ live: liveStore.getDiagnostics(),
3566
+ history: getChartHistoryRetentionStats(queryClient),
3567
+ candles: getCandleStoreDiagnostics()
3568
+ }));
3484
3569
  setWs(instance);
3485
3570
  wsRef.current = instance;
3486
3571
  return () => {
@@ -3492,12 +3577,12 @@ function AggWebSocketProvider({ children }) {
3492
3577
  setWs(null);
3493
3578
  setIsConnected(false);
3494
3579
  };
3495
- }, [callbacks, client, enableWebsocketsLogs, isClientAuthenticated]);
3580
+ }, [client, enableWebsocketsLogs, isClientAuthenticated, liveStore, queryClient]);
3496
3581
  return /* @__PURE__ */ jsx6(AggWebSocketConnectionContext.Provider, { value: isConnected, children: /* @__PURE__ */ jsx6(AggWsUserEventContext.Provider, { value: userEventListeners, children: /* @__PURE__ */ jsx6(AggWebSocketContext.Provider, { value: ws, children }) }) });
3497
3582
  }
3498
3583
 
3499
3584
  // src/core/providers/ui-provider.tsx
3500
- import { useCallback as useCallback6, useEffect as useEffect3, useMemo as useMemo6, useState as useState3 } from "react";
3585
+ import { useCallback as useCallback6, useEffect as useEffect3, useMemo as useMemo7, useState as useState3 } from "react";
3501
3586
 
3502
3587
  // src/core/ui-config/constants.ts
3503
3588
  var DEFAULT_AGG_ROOT_CLASS_NAME = "agg-root";
@@ -3574,7 +3659,7 @@ var applyThemeToDocument = (theme) => {
3574
3659
  };
3575
3660
 
3576
3661
  // src/core/providers/event-trading-context.tsx
3577
- import { createContext as createContext4, useCallback as useCallback5, useContext as useContext6, useMemo as useMemo5, useReducer, useRef as useRef3 } from "react";
3662
+ import { createContext as createContext4, useCallback as useCallback5, useContext as useContext6, useMemo as useMemo6, useReducer, useRef as useRef3 } from "react";
3578
3663
  import { jsx as jsx7 } from "react/jsx-runtime";
3579
3664
  var OPEN_TRADING_STATE = {
3580
3665
  kind: "open",
@@ -3975,7 +4060,7 @@ var EventTradingProvider = ({
3975
4060
  (tradeSide) => dispatch({ type: "SET_TRADE_SIDE", tradeSide }),
3976
4061
  [dispatch]
3977
4062
  );
3978
- const value = useMemo5(
4063
+ const value = useMemo6(
3979
4064
  () => {
3980
4065
  var _a2, _b2, _c, _d, _e, _f, _g, _h, _i;
3981
4066
  return {
@@ -4042,8 +4127,8 @@ var getSearchStateAfterSelect = (selectedEvent) => {
4042
4127
  };
4043
4128
  };
4044
4129
  var AggUiProvider = ({ config, children }) => {
4045
- const persisted = useMemo6(() => loadPersistedConfig(), []);
4046
- const mergedConfig = useMemo6(() => mergeAggUiConfig(persisted, config), [persisted, config]);
4130
+ const persisted = useMemo7(() => loadPersistedConfig(), []);
4131
+ const mergedConfig = useMemo7(() => mergeAggUiConfig(persisted, config), [persisted, config]);
4047
4132
  const [selectedChartTimeRange, setSelectedChartTimeRange] = useState3(
4048
4133
  mergedConfig.chart.selectedChartTimeRange
4049
4134
  );
@@ -4095,7 +4180,7 @@ var AggUiProvider = ({ config, children }) => {
4095
4180
  setIsShowingAllResults(false);
4096
4181
  (_b = (_a = mergedConfig.search).closeResults) == null ? void 0 : _b.call(_a);
4097
4182
  }, [mergedConfig.search]);
4098
- const resolvedConfig = useMemo6(() => {
4183
+ const resolvedConfig = useMemo7(() => {
4099
4184
  return __spreadProps(__spreadValues({}, mergedConfig), {
4100
4185
  chart: __spreadProps(__spreadValues({}, mergedConfig.chart), {
4101
4186
  selectedChartTimeRange,
@@ -4163,7 +4248,7 @@ import { jsx as jsx9 } from "react/jsx-runtime";
4163
4248
  var hasWarnedMissingQueryClient = false;
4164
4249
  function useQueryClientCheck() {
4165
4250
  try {
4166
- useQueryClient3();
4251
+ useQueryClient4();
4167
4252
  } catch (e) {
4168
4253
  if (!hasWarnedMissingQueryClient) {
4169
4254
  hasWarnedMissingQueryClient = true;
@@ -4202,10 +4287,10 @@ function useResolvedExecutionMode(override) {
4202
4287
  }
4203
4288
 
4204
4289
  // src/execution/use-execute-managed.ts
4205
- import { useMutation, useQueryClient as useQueryClient4 } from "@tanstack/react-query";
4290
+ import { useMutation, useQueryClient as useQueryClient5 } from "@tanstack/react-query";
4206
4291
  function useExecuteManaged(options) {
4207
4292
  const client = useAggClient();
4208
- const queryClient = useQueryClient4();
4293
+ const queryClient = useQueryClient5();
4209
4294
  return useMutation({
4210
4295
  mutationFn: (params) => client.executeManaged(params),
4211
4296
  onSuccess: (data) => {
@@ -4234,10 +4319,10 @@ function useExecuteManaged(options) {
4234
4319
  }
4235
4320
 
4236
4321
  // src/execution/use-place-limit-order.ts
4237
- import { useMutation as useMutation2, useQueryClient as useQueryClient5 } from "@tanstack/react-query";
4322
+ import { useMutation as useMutation2, useQueryClient as useQueryClient6 } from "@tanstack/react-query";
4238
4323
  function usePlaceLimitOrder(options) {
4239
4324
  const client = useAggClient();
4240
- const queryClient = useQueryClient5();
4325
+ const queryClient = useQueryClient6();
4241
4326
  return useMutation2({
4242
4327
  mutationFn: (params) => client.placeLimitOrder(params),
4243
4328
  onSuccess: (data) => {
@@ -4253,10 +4338,10 @@ function usePlaceLimitOrder(options) {
4253
4338
  }
4254
4339
 
4255
4340
  // src/execution/use-cancel-managed-order.ts
4256
- import { useMutation as useMutation3, useQueryClient as useQueryClient6 } from "@tanstack/react-query";
4341
+ import { useMutation as useMutation3, useQueryClient as useQueryClient7 } from "@tanstack/react-query";
4257
4342
  function useCancelManagedOrder(options) {
4258
4343
  const client = useAggClient();
4259
- const queryClient = useQueryClient6();
4344
+ const queryClient = useQueryClient7();
4260
4345
  return useMutation3({
4261
4346
  mutationFn: (orderId) => client.cancelManagedOrder(orderId),
4262
4347
  onSuccess: (data, orderId) => {
@@ -4276,10 +4361,10 @@ function useCancelManagedOrder(options) {
4276
4361
  }
4277
4362
 
4278
4363
  // src/execution/use-withdraw-managed.ts
4279
- import { useMutation as useMutation4, useQueryClient as useQueryClient7 } from "@tanstack/react-query";
4364
+ import { useMutation as useMutation4, useQueryClient as useQueryClient8 } from "@tanstack/react-query";
4280
4365
  function useWithdrawManaged(options) {
4281
4366
  const client = useAggClient();
4282
- const queryClient = useQueryClient7();
4367
+ const queryClient = useQueryClient8();
4283
4368
  return useMutation4({
4284
4369
  mutationFn: (params) => client.withdrawManaged(params),
4285
4370
  onSuccess: (data) => {
@@ -4295,10 +4380,11 @@ function useWithdrawManaged(options) {
4295
4380
  import { useQuery as useQuery3 } from "@tanstack/react-query";
4296
4381
  function useManagedBalances(options) {
4297
4382
  const client = useAggClient();
4298
- const { enabled = true, mode } = options != null ? options : {};
4383
+ const { enabled = true, mode, custody } = options != null ? options : {};
4384
+ const params = __spreadValues(__spreadValues({}, mode ? { mode } : {}), custody ? { custody } : {});
4299
4385
  const query = useQuery3({
4300
- queryKey: executionKeys.balances(mode),
4301
- queryFn: () => client.getManagedBalances(mode ? { mode } : void 0),
4386
+ queryKey: executionKeys.balances(mode, custody),
4387
+ queryFn: () => client.getManagedBalances(Object.keys(params).length ? params : void 0),
4302
4388
  enabled,
4303
4389
  staleTime: 1e4,
4304
4390
  // A matched fill can precede settlement and the API's next balance snapshot.
@@ -4335,7 +4421,7 @@ function usePositions(options) {
4335
4421
  }
4336
4422
 
4337
4423
  // src/execution/use-deposit-addresses.ts
4338
- import { useEffect as useEffect4, useMemo as useMemo7, useRef as useRef4, useState as useState4 } from "react";
4424
+ import { useEffect as useEffect4, useMemo as useMemo8, useRef as useRef4, useState as useState4 } from "react";
4339
4425
  import { useQuery as useQuery5 } from "@tanstack/react-query";
4340
4426
  var SVM_CHAIN_IDS = /* @__PURE__ */ new Set([792703809]);
4341
4427
  function getDepositAddress(chainId, data) {
@@ -4376,9 +4462,9 @@ function useDepositAddresses(options) {
4376
4462
  });
4377
4463
  const isReady = ((_a = query.data) == null ? void 0 : _a.ready) === true;
4378
4464
  const readyData = isReady ? query.data : void 0;
4379
- const evmAddress = useMemo7(() => readyData == null ? void 0 : readyData.evmAddress, [readyData]);
4380
- const svmAddress = useMemo7(() => readyData == null ? void 0 : readyData.svmAddress, [readyData]);
4381
- const supportedChains = useMemo7(() => readyData == null ? void 0 : readyData.supportedChains, [readyData]);
4465
+ const evmAddress = useMemo8(() => readyData == null ? void 0 : readyData.evmAddress, [readyData]);
4466
+ const svmAddress = useMemo8(() => readyData == null ? void 0 : readyData.svmAddress, [readyData]);
4467
+ const supportedChains = useMemo8(() => readyData == null ? void 0 : readyData.supportedChains, [readyData]);
4382
4468
  return __spreadProps(__spreadValues({}, query), {
4383
4469
  isReady,
4384
4470
  isTimedOut,
@@ -4392,10 +4478,10 @@ function useDepositAddresses(options) {
4392
4478
  }
4393
4479
 
4394
4480
  // src/execution/use-sync-balances.ts
4395
- import { useMutation as useMutation5, useQueryClient as useQueryClient8 } from "@tanstack/react-query";
4481
+ import { useMutation as useMutation5, useQueryClient as useQueryClient9 } from "@tanstack/react-query";
4396
4482
  function useSyncBalances(options) {
4397
4483
  const client = useAggClient();
4398
- const queryClient = useQueryClient8();
4484
+ const queryClient = useQueryClient9();
4399
4485
  return useMutation5({
4400
4486
  mutationFn: () => client.syncManagedBalances(),
4401
4487
  onSuccess: () => {
@@ -4605,7 +4691,7 @@ function useExecutionProgress({
4605
4691
  submittedOrderVenueByIdRef.current.set(msg.orderId, trimmedVenue);
4606
4692
  }
4607
4693
  const { event } = msg;
4608
- if (event === "filled" || event === "partial_fill" || event === "failed" || event === "bridge_ws_subscribe_failed" || event === "expired" || event === "dag_cancelled") {
4694
+ if (event === "filled" || event === "partial_fill" || event === "failed" || event === "bridge_ws_subscribe_failed" || event === "expired" || event === "dag_cancelled" || event === "cancelled") {
4609
4695
  const mappedEvent = event === "filled" || event === "partial_fill" ? event : "failed";
4610
4696
  const resolvedVenue = trimmedVenue || submittedOrderVenueByIdRef.current.get(msg.orderId) || "";
4611
4697
  if (resolvedVenue) {
@@ -5124,11 +5210,11 @@ function useExecutionProgress({
5124
5210
  }
5125
5211
 
5126
5212
  // src/execution/use-balance-refill-policies.ts
5127
- import { useMutation as useMutation6, useQuery as useQuery6, useQueryClient as useQueryClient9 } from "@tanstack/react-query";
5213
+ import { useMutation as useMutation6, useQuery as useQuery6, useQueryClient as useQueryClient10 } from "@tanstack/react-query";
5128
5214
  function useBalanceRefillPolicies(options) {
5129
5215
  var _a, _b;
5130
5216
  const client = useAggClient();
5131
- const queryClient = useQueryClient9();
5217
+ const queryClient = useQueryClient10();
5132
5218
  const queryKey = executionKeys.balanceRefillPolicies();
5133
5219
  const query = useQuery6({
5134
5220
  queryKey,
@@ -5209,7 +5295,7 @@ var computeClosedPositionTotals = (group) => {
5209
5295
  };
5210
5296
 
5211
5297
  // src/execution/use-redeem.ts
5212
- import { useMutation as useMutation7, useQueryClient as useQueryClient10 } from "@tanstack/react-query";
5298
+ import { useMutation as useMutation7, useQueryClient as useQueryClient11 } from "@tanstack/react-query";
5213
5299
  var RedeemRejectedError = class extends Error {
5214
5300
  constructor(message, response) {
5215
5301
  super(message);
@@ -5220,7 +5306,7 @@ var RedeemRejectedError = class extends Error {
5220
5306
  var isLegRejected = (status) => status === "ineligible" || status === "rejected";
5221
5307
  var useRedeem = () => {
5222
5308
  const client = useAggClient();
5223
- const queryClient = useQueryClient10();
5309
+ const queryClient = useQueryClient11();
5224
5310
  const { executionMode } = useResolvedExecutionMode();
5225
5311
  return useMutation7({
5226
5312
  mutationFn: (body) => __async(null, null, function* () {
@@ -5281,7 +5367,7 @@ var useRedeemEligibleCount = () => {
5281
5367
  };
5282
5368
 
5283
5369
  // src/execution/use-redeem-lifecycles.ts
5284
- import { useEffect as useEffect6, useMemo as useMemo8, useState as useState6 } from "react";
5370
+ import { useEffect as useEffect6, useMemo as useMemo9, useState as useState6 } from "react";
5285
5371
  var computeDerivedState = (legs, expectedCount) => {
5286
5372
  const legCount = Object.keys(legs).length;
5287
5373
  let allTerminal = legCount === expectedCount;
@@ -5332,7 +5418,7 @@ var seedState = (input) => {
5332
5418
  };
5333
5419
  };
5334
5420
  function useRedeemLifecycles(inputs) {
5335
- const inputsByRedeemId = useMemo8(() => {
5421
+ const inputsByRedeemId = useMemo9(() => {
5336
5422
  const map = {};
5337
5423
  for (const input of inputs) {
5338
5424
  map[input.redeemId] = input;
@@ -5364,7 +5450,7 @@ function useRedeemLifecycles(inputs) {
5364
5450
  });
5365
5451
  }, [inputsByRedeemId]);
5366
5452
  useOnRedeemEvent(
5367
- useMemo8(() => {
5453
+ useMemo9(() => {
5368
5454
  if (Object.keys(inputsByRedeemId).length === 0) return null;
5369
5455
  return (event) => {
5370
5456
  const input = inputsByRedeemId[event.redeemId];
@@ -5399,7 +5485,7 @@ function useRedeemLifecycles(inputs) {
5399
5485
  }
5400
5486
 
5401
5487
  // src/execution/use-redeem-lifecycle.ts
5402
- import { useMemo as useMemo9 } from "react";
5488
+ import { useMemo as useMemo10 } from "react";
5403
5489
  var INITIAL_STATE = {
5404
5490
  pending: true,
5405
5491
  terminal: false,
@@ -5410,13 +5496,14 @@ var INITIAL_STATE = {
5410
5496
  };
5411
5497
  function useRedeemLifecycle(input) {
5412
5498
  var _a;
5413
- const inputs = useMemo9(() => input ? [input] : [], [input]);
5499
+ const inputs = useMemo10(() => input ? [input] : [], [input]);
5414
5500
  const map = useRedeemLifecycles(inputs);
5415
5501
  if (!input) return INITIAL_STATE;
5416
5502
  return (_a = map[input.redeemId]) != null ? _a : INITIAL_STATE;
5417
5503
  }
5418
5504
 
5419
5505
  export {
5506
+ __pow,
5420
5507
  __spreadValues,
5421
5508
  __spreadProps,
5422
5509
  __objRest,
@@ -5430,6 +5517,7 @@ export {
5430
5517
  parseEmail,
5431
5518
  parseEmailStrict,
5432
5519
  optimizedImageUrl,
5520
+ retinaImageUrl,
5433
5521
  sortVenues,
5434
5522
  getOrCreateBuilder,
5435
5523
  getBuilder,
@@ -5451,15 +5539,10 @@ export {
5451
5539
  useCachedAppConfig,
5452
5540
  EventListStateProvider,
5453
5541
  useEventListState,
5454
- getIntervalSeconds,
5455
- createMarketChartData,
5456
- mergeMarketChartData,
5457
5542
  createMarketLiveState,
5458
- createMarketOrderbookDataFromVenueOrderbooks,
5459
- createMarketOrderbookDataFromState,
5460
- marketOrderbookDataToResponse,
5461
- applyOrderbookDepth,
5462
5543
  marketDataKeys,
5544
+ getMarketLiveStore,
5545
+ useLiveStates,
5463
5546
  useAggClient,
5464
5547
  useOptionalAggClient,
5465
5548
  useAggUiConfig,