@agg-build/hooks 1.2.11 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -79,11 +79,13 @@ __export(src_exports, {
79
79
  CONFIRMED_MATCH_STATUSES: () => CONFIRMED_MATCH_STATUSES,
80
80
  DEFAULT_AGG_ROOT_CLASS_NAME: () => DEFAULT_AGG_ROOT_CLASS_NAME,
81
81
  EventListStateProvider: () => EventListStateProvider,
82
+ MAX_PRICE_GAP_PCT: () => MAX_PRICE_GAP_PCT,
83
+ MIN_PRICE_GAP_PCT: () => MIN_PRICE_GAP_PCT,
82
84
  MarketStatus: () => MarketStatus,
83
85
  MatchStatus: () => MatchStatus,
84
86
  MatchType: () => MatchType,
85
- QueryClient: () => import_react_query37.QueryClient,
86
- QueryClientProvider: () => import_react_query37.QueryClientProvider,
87
+ QueryClient: () => import_react_query38.QueryClient,
88
+ QueryClientProvider: () => import_react_query38.QueryClientProvider,
87
89
  RedeemRejectedError: () => RedeemRejectedError,
88
90
  TradeSide: () => TradeSide,
89
91
  TurnstileChallengeError: () => import_sdk4.TurnstileChallengeError,
@@ -97,12 +99,18 @@ __export(src_exports, {
97
99
  getBuilder: () => getBuilder,
98
100
  getDepositAddress: () => getDepositAddress,
99
101
  getOrCreateBuilder: () => getOrCreateBuilder,
102
+ getVenueAvailabilityState: () => getVenueAvailabilityState,
103
+ getVisibleVenueIdsByConfig: () => getVisibleVenueIdsByConfig,
104
+ getVisibleVenuesByConfig: () => getVisibleVenuesByConfig,
100
105
  getWalletAddressFromUserProfile: () => getWalletAddressFromUserProfile,
101
106
  invalidateBalanceQueries: () => invalidateBalanceQueries,
102
107
  invalidatePositionQueries: () => invalidatePositionQueries,
103
108
  invalidateUserActivityQueries: () => invalidateUserActivityQueries,
109
+ invalidateUserClaimState: () => invalidateUserClaimState,
104
110
  invalidateUserMoneyState: () => invalidateUserMoneyState,
111
+ isVenueDisabledByConfig: () => isVenueDisabledByConfig,
105
112
  mergeBestPricesPreferringLive: () => mergeBestPricesPreferringLive,
113
+ normalizeVenueId: () => normalizeVenueId,
106
114
  optimizedImageUrl: () => optimizedImageUrl,
107
115
  parseEmail: () => parseEmail,
108
116
  parseEmailStrict: () => parseEmailStrict,
@@ -130,7 +138,10 @@ __export(src_exports, {
130
138
  useAggUiConfig: () => useAggUiConfig,
131
139
  useAggWebSocket: () => useAggWebSocket,
132
140
  useAppConfig: () => useAppConfig,
141
+ useArbFeed: () => useArbFeed,
142
+ useCachedAppConfig: () => useCachedAppConfig,
133
143
  useCategories: () => useCategories,
144
+ useCategoryChildren: () => useCategoryChildren,
134
145
  useDebouncedValue: () => useDebouncedValue,
135
146
  useDepositAddresses: () => useDepositAddresses,
136
147
  useEnrichedVenueEvent: () => useEnrichedVenueEvent,
@@ -153,19 +164,22 @@ __export(src_exports, {
153
164
  useLiveOutcomePrices: () => useLiveOutcomePrices,
154
165
  useLiveTrades: () => useLiveTrades,
155
166
  useManagedBalances: () => useManagedBalances,
167
+ useMarketArb: () => useMarketArb,
156
168
  useMarketChart: () => useMarketChart,
157
169
  useMarketOrderbook: () => useMarketOrderbook,
158
170
  useMarketSearch: () => useMarketSearch,
159
171
  useMidpoints: () => useMidpoints,
160
172
  useOnBalanceUpdate: () => useOnBalanceUpdate,
173
+ useOnOrderEvent: () => useOnOrderEvent,
161
174
  useOnOrderSubmitted: () => useOnOrderSubmitted,
162
175
  useOnRedeemEvent: () => useOnRedeemEvent2,
163
176
  useOnWithdrawalLifecycle: () => useOnWithdrawalLifecycle,
177
+ useOptionalAggClient: () => useOptionalAggClient,
164
178
  useOrderBook: () => useOrderBook,
165
179
  useOrderbookQuote: () => useOrderbookQuote,
166
180
  useOrders: () => useOrders,
167
181
  usePositions: () => usePositions,
168
- useQueryClient: () => import_react_query37.useQueryClient,
182
+ useQueryClient: () => import_react_query38.useQueryClient,
169
183
  useQuoteManaged: () => useQuoteManaged,
170
184
  useRampQuotes: () => useRampQuotes,
171
185
  useRampSession: () => useRampSession,
@@ -318,7 +332,7 @@ var getVenueOrder = (venue) => {
318
332
  var sortVenues = (venues) => [...venues].sort((a, b) => getVenueOrder(a) - getVenueOrder(b));
319
333
 
320
334
  // src/index.ts
321
- var import_react_query37 = require("@tanstack/react-query");
335
+ var import_react_query38 = require("@tanstack/react-query");
322
336
 
323
337
  // src/candle-store.ts
324
338
  var import_sdk = require("@agg-build/sdk");
@@ -355,11 +369,23 @@ function evict() {
355
369
  }
356
370
 
357
371
  // src/core/providers/agg-provider.tsx
358
- var import_react_query3 = require("@tanstack/react-query");
372
+ var import_react_query4 = require("@tanstack/react-query");
359
373
 
360
374
  // src/core/providers/auth-provider.tsx
375
+ var import_react_query = require("@tanstack/react-query");
361
376
  var import_react2 = require("react");
362
377
 
378
+ // src/current-user-query.ts
379
+ var CURRENT_USER_QUERY_KEY = ["current-user"];
380
+ var CURRENT_USER_STALE_TIME_MS = 6e4;
381
+ var fetchCurrentUserProfile = (queryClient, client, queryKey = CURRENT_USER_QUERY_KEY) => {
382
+ return queryClient.fetchQuery({
383
+ queryKey,
384
+ queryFn: () => client.getCurrentUser(),
385
+ staleTime: CURRENT_USER_STALE_TIME_MS
386
+ });
387
+ };
388
+
363
389
  // src/core/providers/auth-utils.ts
364
390
  var import_sdk2 = require("@agg-build/sdk");
365
391
  var createPlaceholderUserProfile = (input) => {
@@ -687,11 +713,8 @@ var enUsLabels = {
687
713
  loadingDescription: "This may take a few minutes. You can safely close this window and check the status later in your activity.",
688
714
  summary: {
689
715
  requestedWithdrawal: "Requested withdrawal",
690
- // The response is `pricingStatus: "unquoted"` we don't know net
691
- // output until on-chain settlement. Calling this "Amount received"
692
- // would imply receipt before the lifecycle has confirmed. Keep it
693
- // honest as the submitted amount until the multi-stable quote
694
- // layer (PR-E) populates `expected.outputRaw`.
716
+ // Calling this "Amount received" would imply receipt before the
717
+ // lifecycle has confirmed. Keep it honest as the submitted amount.
695
718
  amountReceived: "Amount",
696
719
  network: "Network",
697
720
  toWallet: "To wallet",
@@ -739,9 +762,8 @@ var enUsLabels = {
739
762
  }
740
763
  },
741
764
  summary: {
742
- // Lifecycle-honest: until quoting is live (PR-E) the response is
743
- // `pricingStatus: "unquoted"` so this is the submitted amount, not
744
- // a guaranteed net output.
765
+ // Lifecycle-honest: this is the submitted amount, not a guaranteed net
766
+ // output.
745
767
  amountReceived: "Amount",
746
768
  network: "Network"
747
769
  }
@@ -752,14 +774,21 @@ var enUsLabels = {
752
774
  },
753
775
  home: {
754
776
  trending: "Trending",
755
- topMarkets: "Top Markets",
777
+ topMarkets: "Trending",
756
778
  newMarkets: "New Markets",
757
779
  categoryTabsAria: "Home page category tabs"
758
780
  },
759
781
  userProfile: {
760
782
  activity: {
761
783
  depositType: "Deposit",
784
+ redeemType: "Claim",
762
785
  withdrawalType: "Withdrawal",
786
+ redeemStatusTitles: {
787
+ pending: "Processing claim",
788
+ completed: "Successful claim",
789
+ failed: "Failed claim",
790
+ canceled: "Canceled claim"
791
+ },
763
792
  depositTitles: {
764
793
  connectedWallet: "Deposit from connected wallet",
765
794
  externalWallet: "Deposit from external wallet",
@@ -830,6 +859,15 @@ var enUsLabels = {
830
859
  eventList: {
831
860
  matchedTab: "Matched",
832
861
  allTab: "All",
862
+ sortByLabel: "Sort by",
863
+ sortBy24hVolume: "24h volume",
864
+ sortByTopArbitrage: "Top arbitrage",
865
+ sortByTotalVolume: "Total volume",
866
+ sortByEndingSoon: "Ending soon",
867
+ subcategoriesLabel: "Subcategories",
868
+ subcategoriesAll: "All",
869
+ subcategoriesOpenAria: "Open subcategories",
870
+ subcategoriesCloseAria: "Close subcategories",
833
871
  loading: (title) => `Loading ${title}`,
834
872
  tabsAria: (title) => `${title} tabs`,
835
873
  emptyAria: "No events found",
@@ -858,12 +896,14 @@ var enUsLabels = {
858
896
  unavailableTitle: "Market unavailable",
859
897
  unavailableDescription: "We could not load this market right now.",
860
898
  arbitrage: "Arbitrage",
861
- priceGap: "Price Gap",
862
899
  volumeSuffix: "Vol.",
863
900
  marketSingular: "Market",
864
901
  marketPlural: "Markets",
865
902
  venueSingular: "Venue",
866
- venuePlural: "Venues"
903
+ venuePlural: "Venues",
904
+ matched: "Matched",
905
+ matchedCount: (count) => `${count} ${count === 1 ? "Match" : "Matches"}`,
906
+ priceGap: "Price Gap"
867
907
  },
868
908
  eventItemDetails: {
869
909
  loading: "Loading market details",
@@ -975,8 +1015,8 @@ var enUsLabels = {
975
1015
  })}\xA2 avg. price`,
976
1016
  balance: (value) => `Balance ${value}`,
977
1017
  shares: (value) => `${value.toLocaleString("en-US", {
978
- minimumFractionDigits: Number.isInteger(value) ? 0 : 2,
979
- maximumFractionDigits: 6
1018
+ minimumFractionDigits: Number.isInteger(value) ? 0 : 1,
1019
+ maximumFractionDigits: 2
980
1020
  })} shares`,
981
1021
  maxShares: "Max",
982
1022
  slippage: (value) => `Slippage: ${value}%`,
@@ -1017,6 +1057,18 @@ var enUsLabels = {
1017
1057
  noOrderbooks: "No live orderbooks are available for this market right now.",
1018
1058
  quoteUnavailable: "Quote temporarily unavailable. Please try again.",
1019
1059
  quoteBalanceMismatch: "Quote balance mismatch. Try a different amount.",
1060
+ serviceTemporarilyUnavailable: "Service temporarily unavailable. Please try again in a moment.",
1061
+ orderDeadlineExpiredBeforeSubmission: "Order deadline expired before submission. Please try again.",
1062
+ sellNoOnchainPosition: "You don't currently hold any on-chain shares of this outcome. If you just sold or redeemed elsewhere, your position display will refresh shortly \u2014 try again after that.",
1063
+ venueQuoteUnfillable: "The venue couldn't fill this order at the quoted price right now. Try a smaller size, a higher slippage tolerance, or wait a moment and re-quote.",
1064
+ venueMinOrderSize: "Order size is below the venue minimum. Try a larger amount.",
1065
+ sourceBalanceChanged: "Your balance changed since the quote. Refresh and try again, or pick a smaller amount.",
1066
+ venueMarketResolved: "This market just resolved. Pick a different market or wait for the next round.",
1067
+ dflowWalletUnverified: "Your Solana wallet needs to be verified with dFlow before you can trade Kalshi markets. Verify at https://dflow.net/proof, then try again.",
1068
+ venueNoQuotePath: "No active quote path for this market right now. Try a different size, or wait a moment and re-quote.",
1069
+ solanaBlockhashExpired: "Solana transaction expired before submission. Please re-quote and try again.",
1070
+ venueRateLimited: "The venue is rate-limiting requests right now. Please wait a moment and try again.",
1071
+ serviceBlockedOrder: "Something on our side blocked this order. Please contact support if it keeps happening \u2014 retrying with the same quote will hit the same issue.",
1020
1072
  selectedVenueUnavailable: "The venue you selected is no longer available on this route. Review the updated options and try again.",
1021
1073
  engineUnavailable: "The routing engine is temporarily unavailable. Please try again in a moment.",
1022
1074
  insufficientInputAmount: "Trade amount is too small to cover bridging and execution costs. Increase your spend or deposit funds on the destination chain.",
@@ -1030,6 +1082,7 @@ var enUsLabels = {
1030
1082
  deposit: "Deposit",
1031
1083
  kycRequired: "Verify to trade Kalshi",
1032
1084
  kycNotVerifiedTooltip: "You have not been verified yet",
1085
+ kycVerify: "Verify Identity",
1033
1086
  kycVerifyModalTitle: "Verify Your Identity",
1034
1087
  kycVerifyModalDescription: "To start trading on Kalshi, you'll need to complete identity verification through dFlow. It only takes a few minutes and helps us stay compliant with regulations.",
1035
1088
  kycStartVerification: "Start Verification",
@@ -1043,12 +1096,15 @@ var enUsLabels = {
1043
1096
  splitOrderDescription: "We split your order for the best price:",
1044
1097
  viewAllRoutes: (count) => `View all (${count})`,
1045
1098
  venueUnavailableInRegion: "Unavailable in your region",
1099
+ verified: "Verified",
1046
1100
  platformFee: "0% platform fees",
1047
1101
  estimatedFees: "Estimated fees",
1048
1102
  estimatedFeesTooltipAria: "Estimated fees breakdown",
1049
- feeBreakdownVenueFees: "Venue fees",
1050
- feeBreakdownBridgeFees: "Bridge fees",
1051
- feeBreakdownExecutionGas: "Execution gas",
1103
+ feeBreakdownVenueFees: "Venue",
1104
+ feeBreakdownBridgeFees: "Bridging",
1105
+ feeBreakdownExecutionGas: "Gas",
1106
+ feeBreakdownAggMarket: "agg.market",
1107
+ feeBreakdownPlatformFeeBadge: "0% fee",
1052
1108
  feeBreakdownTotalFees: "Total fees",
1053
1109
  toWin: (tab) => tab === "buy" ? "To win" : "Payout",
1054
1110
  buyingOutcome: (label) => `Buying ${label}`,
@@ -1234,6 +1290,70 @@ var enUsLabels = {
1234
1290
  header: {
1235
1291
  bannerAria: "Site header",
1236
1292
  logoAria: "Home"
1293
+ },
1294
+ notifications: {
1295
+ order: {
1296
+ filledTitle: "Order filled",
1297
+ filledMessage: ({ venueLabel, sideLabel, amountLabel, priceLabel }) => {
1298
+ const action = sideLabel ? `${sideLabel} filled` : "Filled";
1299
+ const amount = amountLabel ? ` ${amountLabel}` : "";
1300
+ const price = priceLabel ? ` at ${priceLabel}` : "";
1301
+ const venue = venueLabel ? ` on ${venueLabel}` : "";
1302
+ return `${action}${amount}${price}${venue}`.trim();
1303
+ },
1304
+ partialFilledTitle: "Order partially filled",
1305
+ partialFilledMessage: ({ venueLabel, sideLabel, amountLabel, priceLabel }) => {
1306
+ const action = sideLabel ? `${sideLabel} partially filled` : "Partially filled";
1307
+ const amount = amountLabel ? ` ${amountLabel}` : "";
1308
+ const price = priceLabel ? ` at ${priceLabel}` : "";
1309
+ const venue = venueLabel ? ` on ${venueLabel}` : "";
1310
+ return `${action}${amount}${price}${venue}`.trim();
1311
+ },
1312
+ failedTitle: "Order failed",
1313
+ failedMessage: (errorReason) => errorReason && errorReason.length > 0 ? errorReason : "Your order could not be completed. Please try again."
1314
+ },
1315
+ deposit: {
1316
+ completedTitle: "Deposit complete",
1317
+ completedMessage: ({ amountLabel, tokenLabel }) => {
1318
+ if (amountLabel && tokenLabel) return `${amountLabel} ${tokenLabel} added to your balance.`;
1319
+ if (tokenLabel) return `Your ${tokenLabel} has been added to your balance.`;
1320
+ return "Your funds have been added to your balance.";
1321
+ },
1322
+ failedTitle: "Deposit failed",
1323
+ failedMessage: ({ amountLabel, tokenLabel }) => {
1324
+ const what = amountLabel && tokenLabel ? `${amountLabel} ${tokenLabel}` : "deposit";
1325
+ return `We couldn't complete your ${what}.`;
1326
+ }
1327
+ },
1328
+ withdrawal: {
1329
+ completedTitle: "Withdrawal complete",
1330
+ completedMessage: ({ amountLabel, tokenLabel }) => {
1331
+ if (amountLabel && tokenLabel) return `${amountLabel} ${tokenLabel} sent to your wallet.`;
1332
+ if (tokenLabel) return `Your ${tokenLabel} has been sent to your wallet.`;
1333
+ return "Your withdrawal has been sent to your wallet.";
1334
+ },
1335
+ partialTitle: "Withdrawal partially completed",
1336
+ partialMessage: ({ amountLabel, tokenLabel }) => {
1337
+ if (amountLabel && tokenLabel)
1338
+ return `Part of your ${tokenLabel} was sent. The remainder was returned to your balance.`;
1339
+ return "Part of your withdrawal was sent. The remainder was returned to your balance.";
1340
+ },
1341
+ failedTitle: "Withdrawal failed",
1342
+ failedMessage: (errorReason) => errorReason && errorReason.length > 0 ? errorReason : "Your funds have been returned to your balance."
1343
+ },
1344
+ claim: {
1345
+ pendingTitle: "Claim started",
1346
+ pendingMessage: "Claiming your winnings.",
1347
+ submittedTitle: "Claim submitted",
1348
+ submittedMessage: "Your claim was submitted. It may take a little while to finish.",
1349
+ successTitle: "Claim complete",
1350
+ successMessage: "Your winnings have been claimed.",
1351
+ partialTitle: "Claim partially completed",
1352
+ partialMessage: (errorReason) => errorReason && errorReason.length > 0 ? errorReason : "Some winnings could not be claimed. Please try again.",
1353
+ failedTitle: "Claim failed",
1354
+ failedMessage: (errorReason) => errorReason && errorReason.length > 0 ? errorReason : "Your winnings could not be claimed. Please try again.",
1355
+ missingOutcomeMessage: "This position is missing claimable outcome data. Please refresh."
1356
+ }
1237
1357
  }
1238
1358
  };
1239
1359
  var defaultAggUiLabelsByLocale = {
@@ -1323,8 +1443,11 @@ var defaultAggUiConfig = {
1323
1443
  features: {
1324
1444
  enableAnimations: true,
1325
1445
  enableLiveUpdates: true,
1446
+ enablePriceGap: false,
1326
1447
  showFeesBreakdown: false,
1327
- enableGradients: false
1448
+ enableGradients: false,
1449
+ enableVenueEventDiscoveryFilters: false,
1450
+ enableNotifications: true
1328
1451
  },
1329
1452
  market: {
1330
1453
  arbitrageThreshold: 0
@@ -1351,7 +1474,7 @@ var mergeAggUiSearchConfig = (config) => {
1351
1474
  };
1352
1475
  };
1353
1476
  var mergeAggUiConfig = (persisted, config) => {
1354
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N;
1477
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T;
1355
1478
  const locale = (_d = (_c = (_a = config == null ? void 0 : config.general) == null ? void 0 : _a.locale) != null ? _c : (_b = persisted.general) == null ? void 0 : _b.locale) != null ? _d : DEFAULT_LOCALE;
1356
1479
  const theme = (_h = (_g = (_e = config == null ? void 0 : config.general) == null ? void 0 : _e.theme) != null ? _g : (_f = persisted.general) == null ? void 0 : _f.theme) != null ? _h : defaultAggUiConfig.general.theme;
1357
1480
  const formatters = createFormatters(locale);
@@ -1369,23 +1492,26 @@ var mergeAggUiConfig = (persisted, config) => {
1369
1492
  features: {
1370
1493
  enableAnimations: (_p = (_o = config == null ? void 0 : config.features) == null ? void 0 : _o.enableAnimations) != null ? _p : defaultAggUiConfig.features.enableAnimations,
1371
1494
  enableLiveUpdates: (_r = (_q = config == null ? void 0 : config.features) == null ? void 0 : _q.enableLiveUpdates) != null ? _r : defaultAggUiConfig.features.enableLiveUpdates,
1372
- showFeesBreakdown: (_t = (_s = config == null ? void 0 : config.features) == null ? void 0 : _s.showFeesBreakdown) != null ? _t : defaultAggUiConfig.features.showFeesBreakdown,
1373
- enableGradients: (_v = (_u = config == null ? void 0 : config.features) == null ? void 0 : _u.enableGradients) != null ? _v : defaultAggUiConfig.features.enableGradients
1495
+ enablePriceGap: (_t = (_s = config == null ? void 0 : config.features) == null ? void 0 : _s.enablePriceGap) != null ? _t : defaultAggUiConfig.features.enablePriceGap,
1496
+ showFeesBreakdown: (_v = (_u = config == null ? void 0 : config.features) == null ? void 0 : _u.showFeesBreakdown) != null ? _v : defaultAggUiConfig.features.showFeesBreakdown,
1497
+ enableGradients: (_x = (_w = config == null ? void 0 : config.features) == null ? void 0 : _w.enableGradients) != null ? _x : defaultAggUiConfig.features.enableGradients,
1498
+ enableVenueEventDiscoveryFilters: (_z = (_y = config == null ? void 0 : config.features) == null ? void 0 : _y.enableVenueEventDiscoveryFilters) != null ? _z : defaultAggUiConfig.features.enableVenueEventDiscoveryFilters,
1499
+ enableNotifications: (_B = (_A = config == null ? void 0 : config.features) == null ? void 0 : _A.enableNotifications) != null ? _B : defaultAggUiConfig.features.enableNotifications
1374
1500
  },
1375
1501
  market: {
1376
- arbitrageThreshold: (_x = (_w = config == null ? void 0 : config.market) == null ? void 0 : _w.arbitrageThreshold) != null ? _x : defaultAggUiConfig.market.arbitrageThreshold
1502
+ arbitrageThreshold: (_D = (_C = config == null ? void 0 : config.market) == null ? void 0 : _C.arbitrageThreshold) != null ? _D : defaultAggUiConfig.market.arbitrageThreshold
1377
1503
  },
1378
1504
  chart: {
1379
- defaultChartTimeRange: (_z = (_y = config == null ? void 0 : config.chart) == null ? void 0 : _y.defaultChartTimeRange) != null ? _z : defaultAggUiConfig.chart.defaultChartTimeRange,
1380
- selectedChartTimeRange: (_D = (_C = (_A = persisted.chart) == null ? void 0 : _A.selectedChartTimeRange) != null ? _C : (_B = config == null ? void 0 : config.chart) == null ? void 0 : _B.defaultChartTimeRange) != null ? _D : defaultAggUiConfig.chart.defaultChartTimeRange,
1505
+ defaultChartTimeRange: (_F = (_E = config == null ? void 0 : config.chart) == null ? void 0 : _E.defaultChartTimeRange) != null ? _F : defaultAggUiConfig.chart.defaultChartTimeRange,
1506
+ selectedChartTimeRange: (_J = (_I = (_G = persisted.chart) == null ? void 0 : _G.selectedChartTimeRange) != null ? _I : (_H = config == null ? void 0 : config.chart) == null ? void 0 : _H.defaultChartTimeRange) != null ? _J : defaultAggUiConfig.chart.defaultChartTimeRange,
1381
1507
  setSelectedChartTimeRange: defaultAggUiConfig.chart.setSelectedChartTimeRange
1382
1508
  },
1383
1509
  formatting: {
1384
- formatNumber: (_F = (_E = config == null ? void 0 : config.formatting) == null ? void 0 : _E.formatNumber) != null ? _F : formatters.formatNumber,
1385
- formatPercent: (_H = (_G = config == null ? void 0 : config.formatting) == null ? void 0 : _G.formatPercent) != null ? _H : formatters.formatPercent,
1386
- formatCurrency: (_J = (_I = config == null ? void 0 : config.formatting) == null ? void 0 : _I.formatCurrency) != null ? _J : formatters.formatCurrency,
1387
- formatCompactCurrency: (_L = (_K = config == null ? void 0 : config.formatting) == null ? void 0 : _K.formatCompactCurrency) != null ? _L : formatters.formatCompactCurrency,
1388
- formatDate: (_N = (_M = config == null ? void 0 : config.formatting) == null ? void 0 : _M.formatDate) != null ? _N : formatters.formatDate
1510
+ formatNumber: (_L = (_K = config == null ? void 0 : config.formatting) == null ? void 0 : _K.formatNumber) != null ? _L : formatters.formatNumber,
1511
+ formatPercent: (_N = (_M = config == null ? void 0 : config.formatting) == null ? void 0 : _M.formatPercent) != null ? _N : formatters.formatPercent,
1512
+ formatCurrency: (_P = (_O = config == null ? void 0 : config.formatting) == null ? void 0 : _O.formatCurrency) != null ? _P : formatters.formatCurrency,
1513
+ formatCompactCurrency: (_R = (_Q = config == null ? void 0 : config.formatting) == null ? void 0 : _Q.formatCompactCurrency) != null ? _R : formatters.formatCompactCurrency,
1514
+ formatDate: (_T = (_S = config == null ? void 0 : config.formatting) == null ? void 0 : _S.formatDate) != null ? _T : formatters.formatDate
1389
1515
  },
1390
1516
  search: mergeAggUiSearchConfig(config == null ? void 0 : config.search),
1391
1517
  walletActions: config == null ? void 0 : config.walletActions,
@@ -1418,6 +1544,9 @@ var replaceAuthCallbackUrl = (cleanupPath) => {
1418
1544
  };
1419
1545
  function AggAuthProvider({ children }) {
1420
1546
  const client = (0, import_react2.useContext)(AggClientContext);
1547
+ const queryClientFromContext = (0, import_react2.useContext)(import_react_query.QueryClientContext);
1548
+ const fallbackQueryClient = (0, import_react2.useMemo)(() => new import_react_query.QueryClient(), []);
1549
+ const queryClient = queryClientFromContext && "fetchQuery" in queryClientFromContext ? queryClientFromContext : fallbackQueryClient;
1421
1550
  const snapshot = getClientAuthSnapshot(client);
1422
1551
  const [isAuthenticated, setIsAuthenticated] = (0, import_react2.useState)(snapshot.isAuthenticated);
1423
1552
  const [user, setUser] = (0, import_react2.useState)(snapshot.user);
@@ -1432,12 +1561,15 @@ function AggAuthProvider({ children }) {
1432
1561
  return provider === "wallet" || provider === "solana_wallet";
1433
1562
  });
1434
1563
  }, [user]);
1435
- const refreshCurrentUser = (0, import_react2.useCallback)((targetClient) => __async(null, null, function* () {
1436
- const fullUser = yield targetClient.getCurrentUser();
1437
- setIsAuthenticated(true);
1438
- setUser(fullUser);
1439
- return fullUser;
1440
- }), []);
1564
+ const refreshCurrentUser = (0, import_react2.useCallback)(
1565
+ (targetClient) => __async(null, null, function* () {
1566
+ const fullUser = yield fetchCurrentUserProfile(queryClient, targetClient);
1567
+ setIsAuthenticated(true);
1568
+ setUser(fullUser);
1569
+ return fullUser;
1570
+ }),
1571
+ [queryClient]
1572
+ );
1441
1573
  (0, import_react2.useEffect)(() => {
1442
1574
  const state = getClientAuthSnapshot(client);
1443
1575
  setIsAuthenticated(state.isAuthenticated);
@@ -1629,15 +1761,22 @@ function AggAuthProvider({ children }) {
1629
1761
  }
1630
1762
 
1631
1763
  // src/core/providers/balance-provider.tsx
1632
- var import_react_query = require("@tanstack/react-query");
1764
+ var import_react_query2 = require("@tanstack/react-query");
1633
1765
  var import_react3 = require("react");
1634
1766
 
1635
1767
  // src/execution/query-keys.ts
1636
1768
  var executionKeys = {
1637
1769
  all: () => ["execution"],
1638
- balances: () => ["execution", "balances"],
1639
- positions: (cursor, limit, status) => ["execution", "positions", cursor != null ? cursor : null, limit != null ? limit : null, status != null ? status : null],
1770
+ balances: (mode) => mode ? ["execution", "balances", mode] : ["execution", "balances"],
1771
+ 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],
1640
1772
  positionsPrefix: () => ["execution", "positions"],
1773
+ claimablePositionsCount: () => ["execution", "positions", "claimable-count"],
1774
+ /**
1775
+ * @deprecated Misnomer — claimable (redeemStatus "eligible") groups live in
1776
+ * the ACTIVE bucket, not closed (won-but-unclaimed stays Active until a
1777
+ * redeem stamps redeemedAt). Same key value as `claimablePositionsCount`;
1778
+ * kept so existing invalidation call sites keep matching.
1779
+ */
1641
1780
  claimableClosedPositionsCount: () => ["execution", "positions", "claimable-count"],
1642
1781
  orders: (status, cursor, limit) => ["execution", "orders", status != null ? status : null, cursor != null ? cursor : null, limit != null ? limit : null],
1643
1782
  ordersPrefix: () => ["execution", "orders"],
@@ -1688,7 +1827,8 @@ var shouldInvalidateBalancesForOrderEvent = (event, currentUserId) => {
1688
1827
  return event.userId === currentUserId;
1689
1828
  };
1690
1829
  var userActivityQueryKeys = {
1691
- all: () => ["user-activity"]
1830
+ all: () => ["user-activity"],
1831
+ feed: (type, limit) => ["user-activity", type != null ? type : "all", limit != null ? limit : 50]
1692
1832
  };
1693
1833
  var invalidateUserActivityQueries = (queryClient, options) => {
1694
1834
  var _a;
@@ -1707,6 +1847,17 @@ var invalidateUserMoneyState = (queryClient, options) => {
1707
1847
  invalidatePositionQueries(queryClient, { refetchType: options == null ? void 0 : options.refetchType });
1708
1848
  invalidateUserActivityQueries(queryClient, { strategy: options == null ? void 0 : options.activityStrategy });
1709
1849
  };
1850
+ var invalidateUserClaimState = (queryClient, options) => {
1851
+ var _a;
1852
+ const refetchType = (_a = options == null ? void 0 : options.refetchType) != null ? _a : "active";
1853
+ invalidateBalanceQueries(queryClient, { refetchType });
1854
+ invalidatePositionQueries(queryClient, { refetchType });
1855
+ queryClient.invalidateQueries({
1856
+ queryKey: executionKeys.claimablePositionsCount(),
1857
+ refetchType
1858
+ });
1859
+ invalidateUserActivityQueries(queryClient, { strategy: options == null ? void 0 : options.activityStrategy });
1860
+ };
1710
1861
 
1711
1862
  // src/core/providers/balance-provider.tsx
1712
1863
  var import_jsx_runtime2 = require("react/jsx-runtime");
@@ -1746,7 +1897,7 @@ function AggBalanceProvider({ children }) {
1746
1897
  throw new Error("AggBalanceProvider must be used within an <AggAuthProvider>");
1747
1898
  }
1748
1899
  const { isAuthenticated } = authContext;
1749
- const balancesQuery = (0, import_react_query.useQuery)({
1900
+ const balancesQuery = (0, import_react_query2.useQuery)({
1750
1901
  queryKey: balanceQueryKeys.provider(),
1751
1902
  queryFn: () => __async(null, null, function* () {
1752
1903
  if (!client || !isAuthenticated) {
@@ -1914,7 +2065,7 @@ function useEventListState() {
1914
2065
 
1915
2066
  // src/core/providers/ws-provider.tsx
1916
2067
  var import_react6 = require("react");
1917
- var import_react_query2 = require("@tanstack/react-query");
2068
+ var import_react_query3 = require("@tanstack/react-query");
1918
2069
 
1919
2070
  // src/market-data/chart-cache.ts
1920
2071
  var MAX_CACHE_RETENTION_SECONDS = 7 * 30 * 24 * 60 * 60 + 14 * 24 * 60 * 60;
@@ -2372,6 +2523,9 @@ var useAggClient = () => {
2372
2523
  }
2373
2524
  return client;
2374
2525
  };
2526
+ var useOptionalAggClient = () => {
2527
+ return (0, import_react5.useContext)(AggClientContext);
2528
+ };
2375
2529
  var useAggUiConfig = () => {
2376
2530
  return (0, import_react5.useContext)(AggUiContext);
2377
2531
  };
@@ -2498,7 +2652,7 @@ function useOnWithdrawalLifecycle(callback) {
2498
2652
  function AggWebSocketProvider({ children }) {
2499
2653
  const client = useAggClient();
2500
2654
  const { enableWebsocketsLogs } = useAggUiConfig();
2501
- const queryClient = (0, import_react_query2.useQueryClient)();
2655
+ const queryClient = (0, import_react_query3.useQueryClient)();
2502
2656
  const [ws, setWs] = (0, import_react6.useState)(null);
2503
2657
  const [isConnected, setIsConnected] = (0, import_react6.useState)(false);
2504
2658
  const [isClientAuthenticated, setIsClientAuthenticated] = (0, import_react6.useState)(client.isAuthenticated);
@@ -3491,7 +3645,7 @@ var import_jsx_runtime8 = require("react/jsx-runtime");
3491
3645
  var hasWarnedMissingQueryClient = false;
3492
3646
  function useQueryClientCheck() {
3493
3647
  try {
3494
- (0, import_react_query3.useQueryClient)();
3648
+ (0, import_react_query4.useQueryClient)();
3495
3649
  } catch (e) {
3496
3650
  if (!hasWarnedMissingQueryClient) {
3497
3651
  hasWarnedMissingQueryClient = true;
@@ -3512,10 +3666,10 @@ var AggProvider = ({ client, config, children }) => {
3512
3666
  };
3513
3667
 
3514
3668
  // src/use-ramp-quotes.ts
3515
- var import_react_query4 = require("@tanstack/react-query");
3669
+ var import_react_query5 = require("@tanstack/react-query");
3516
3670
  function useRampQuotes() {
3517
3671
  const client = useAggClient();
3518
- return (0, import_react_query4.useMutation)({
3672
+ return (0, import_react_query5.useMutation)({
3519
3673
  mutationFn: (params) => __async(null, null, function* () {
3520
3674
  return client.getRampQuotes(params);
3521
3675
  })
@@ -3523,10 +3677,10 @@ function useRampQuotes() {
3523
3677
  }
3524
3678
 
3525
3679
  // src/use-ramp-session.ts
3526
- var import_react_query5 = require("@tanstack/react-query");
3680
+ var import_react_query6 = require("@tanstack/react-query");
3527
3681
  function useRampSession() {
3528
3682
  const client = useAggClient();
3529
- return (0, import_react_query5.useMutation)({
3683
+ return (0, import_react_query6.useMutation)({
3530
3684
  mutationFn: (params) => __async(null, null, function* () {
3531
3685
  return client.createRampSession(params);
3532
3686
  })
@@ -3537,10 +3691,10 @@ function useRampSession() {
3537
3691
  var import_react13 = require("react");
3538
3692
 
3539
3693
  // src/execution/use-quote-managed.ts
3540
- var import_react_query6 = require("@tanstack/react-query");
3694
+ var import_react_query7 = require("@tanstack/react-query");
3541
3695
  function useQuoteManaged(options) {
3542
3696
  const client = useAggClient();
3543
- return (0, import_react_query6.useMutation)({
3697
+ return (0, import_react_query7.useMutation)({
3544
3698
  mutationFn: (params) => client.quoteManaged(params),
3545
3699
  onSuccess: options == null ? void 0 : options.onSuccess,
3546
3700
  onError: options == null ? void 0 : options.onError
@@ -3548,11 +3702,11 @@ function useQuoteManaged(options) {
3548
3702
  }
3549
3703
 
3550
3704
  // src/execution/use-execute-managed.ts
3551
- var import_react_query7 = require("@tanstack/react-query");
3705
+ var import_react_query8 = require("@tanstack/react-query");
3552
3706
  function useExecuteManaged(options) {
3553
3707
  const client = useAggClient();
3554
- const queryClient = (0, import_react_query7.useQueryClient)();
3555
- return (0, import_react_query7.useMutation)({
3708
+ const queryClient = (0, import_react_query8.useQueryClient)();
3709
+ return (0, import_react_query8.useMutation)({
3556
3710
  mutationFn: (params) => client.executeManaged(params),
3557
3711
  onSuccess: (data) => {
3558
3712
  var _a;
@@ -3566,11 +3720,11 @@ function useExecuteManaged(options) {
3566
3720
  }
3567
3721
 
3568
3722
  // src/execution/use-withdraw-managed.ts
3569
- var import_react_query8 = require("@tanstack/react-query");
3723
+ var import_react_query9 = require("@tanstack/react-query");
3570
3724
  function useWithdrawManaged(options) {
3571
3725
  const client = useAggClient();
3572
- const queryClient = (0, import_react_query8.useQueryClient)();
3573
- return (0, import_react_query8.useMutation)({
3726
+ const queryClient = (0, import_react_query9.useQueryClient)();
3727
+ return (0, import_react_query9.useMutation)({
3574
3728
  mutationFn: (params) => client.withdrawManaged(params),
3575
3729
  onSuccess: (data) => {
3576
3730
  var _a;
@@ -3582,13 +3736,13 @@ function useWithdrawManaged(options) {
3582
3736
  }
3583
3737
 
3584
3738
  // src/execution/use-managed-balances.ts
3585
- var import_react_query9 = require("@tanstack/react-query");
3739
+ var import_react_query10 = require("@tanstack/react-query");
3586
3740
  function useManagedBalances(options) {
3587
3741
  const client = useAggClient();
3588
- const { enabled = true } = options != null ? options : {};
3589
- const query = (0, import_react_query9.useQuery)({
3590
- queryKey: executionKeys.balances(),
3591
- queryFn: () => client.getManagedBalances(),
3742
+ const { enabled = true, mode } = options != null ? options : {};
3743
+ const query = (0, import_react_query10.useQuery)({
3744
+ queryKey: executionKeys.balances(mode),
3745
+ queryFn: () => client.getManagedBalances(mode ? { mode } : void 0),
3592
3746
  enabled,
3593
3747
  staleTime: 1e4,
3594
3748
  gcTime: 5 * 6e4,
@@ -3600,14 +3754,14 @@ function useManagedBalances(options) {
3600
3754
  }
3601
3755
 
3602
3756
  // src/execution/use-positions.ts
3603
- var import_react_query10 = require("@tanstack/react-query");
3757
+ var import_react_query11 = require("@tanstack/react-query");
3604
3758
  function usePositions(options) {
3605
3759
  var _a, _b, _c, _d;
3606
3760
  const client = useAggClient();
3607
- const { enabled = true, cursor, limit, status } = options != null ? options : {};
3608
- const query = (0, import_react_query10.useQuery)({
3609
- queryKey: executionKeys.positions(cursor, limit, status),
3610
- queryFn: () => client.getPositions({ cursor, limit, status }),
3761
+ const { enabled = true, cursor, limit, status, mode } = options != null ? options : {};
3762
+ const query = (0, import_react_query11.useQuery)({
3763
+ queryKey: executionKeys.positions(cursor, limit, status, mode),
3764
+ queryFn: () => client.getPositions(__spreadValues({ cursor, limit, status }, mode ? { mode } : {})),
3611
3765
  enabled,
3612
3766
  staleTime: 1e4,
3613
3767
  gcTime: 5 * 6e4,
@@ -3622,7 +3776,7 @@ function usePositions(options) {
3622
3776
 
3623
3777
  // src/execution/use-deposit-addresses.ts
3624
3778
  var import_react9 = require("react");
3625
- var import_react_query11 = require("@tanstack/react-query");
3779
+ var import_react_query12 = require("@tanstack/react-query");
3626
3780
  var SVM_CHAIN_IDS = /* @__PURE__ */ new Set([792703809]);
3627
3781
  function getDepositAddress(chainId, data) {
3628
3782
  return chainId !== void 0 && SVM_CHAIN_IDS.has(chainId) ? data.svmAddress : data.evmAddress;
@@ -3646,7 +3800,7 @@ function useDepositAddresses(options) {
3646
3800
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
3647
3801
  };
3648
3802
  }, [enabled, poll, timeoutMs]);
3649
- const query = (0, import_react_query11.useQuery)({
3803
+ const query = (0, import_react_query12.useQuery)({
3650
3804
  queryKey: executionKeys.depositAddresses(),
3651
3805
  queryFn: () => client.getDepositAddresses(),
3652
3806
  enabled,
@@ -3678,11 +3832,11 @@ function useDepositAddresses(options) {
3678
3832
  }
3679
3833
 
3680
3834
  // src/execution/use-sync-balances.ts
3681
- var import_react_query12 = require("@tanstack/react-query");
3835
+ var import_react_query13 = require("@tanstack/react-query");
3682
3836
  function useSyncBalances(options) {
3683
3837
  const client = useAggClient();
3684
- const queryClient = (0, import_react_query12.useQueryClient)();
3685
- return (0, import_react_query12.useMutation)({
3838
+ const queryClient = (0, import_react_query13.useQueryClient)();
3839
+ return (0, import_react_query13.useMutation)({
3686
3840
  mutationFn: () => client.syncManagedBalances(),
3687
3841
  onSuccess: () => {
3688
3842
  var _a;
@@ -3695,17 +3849,24 @@ function useSyncBalances(options) {
3695
3849
 
3696
3850
  // src/execution/use-execution-progress.ts
3697
3851
  var import_react10 = require("react");
3698
- var TERMINAL_ORDER_STATUSES = /* @__PURE__ */ new Set(["filled", "partial_fill", "failed", "cancelled"]);
3852
+ var TERMINAL_ORDER_STATUSES = /* @__PURE__ */ new Set([
3853
+ "filled",
3854
+ "partial_fill",
3855
+ "failed",
3856
+ "cancelled",
3857
+ "expired"
3858
+ ]);
3699
3859
  var ORDER_POLL_INTERVAL_MS = 5e3;
3700
3860
  function mapOrderStatusToTerminalEvent(status) {
3701
3861
  if (status === "filled") return "filled";
3702
3862
  if (status === "partial_fill") return "partial_fill";
3703
- if (status === "failed" || status === "cancelled") return "failed";
3863
+ if (status === "failed" || status === "cancelled" || status === "expired") return "failed";
3704
3864
  return null;
3705
3865
  }
3706
3866
  function useExecutionProgress({
3707
3867
  orderIds,
3708
- enabled
3868
+ enabled,
3869
+ mode
3709
3870
  }) {
3710
3871
  const [phase, setPhase] = (0, import_react10.useState)("idle");
3711
3872
  const [submittedOrders, setSubmittedOrders] = (0, import_react10.useState)([]);
@@ -3756,12 +3917,13 @@ function useExecutionProgress({
3756
3917
  submittedOrderVenueByIdRef.current.set(msg.orderId, trimmedVenue);
3757
3918
  }
3758
3919
  const { event } = msg;
3759
- if (event === "filled" || event === "partial_fill" || event === "failed" || event === "bridge_ws_subscribe_failed") {
3760
- const mappedEvent = event === "bridge_ws_subscribe_failed" ? "failed" : event;
3920
+ if (event === "filled" || event === "partial_fill" || event === "failed" || event === "bridge_ws_subscribe_failed" || event === "expired" || event === "dag_cancelled") {
3921
+ const mappedEvent = event === "filled" || event === "partial_fill" ? event : "failed";
3761
3922
  const resolvedVenue = trimmedVenue || submittedOrderVenueByIdRef.current.get(msg.orderId) || "";
3762
3923
  if (resolvedVenue) {
3763
3924
  submittedOrderVenueByIdRef.current.set(msg.orderId, resolvedVenue);
3764
3925
  }
3926
+ const fallbackErrorReason = event === "bridge_ws_subscribe_failed" ? "Bridge event subscription failed." : event === "expired" ? "Order expired before it could be submitted." : event === "dag_cancelled" ? "Order was cancelled before submission." : void 0;
3765
3927
  const nextTerminalEvent = {
3766
3928
  orderId: msg.orderId,
3767
3929
  venue: resolvedVenue,
@@ -3774,7 +3936,7 @@ function useExecutionProgress({
3774
3936
  quotedToWinRaw: msg.quotedToWinRaw,
3775
3937
  executionPriceRaw: msg.executionPriceRaw,
3776
3938
  quotedPriceRaw: msg.quotedPriceRaw,
3777
- errorReason: event === "bridge_ws_subscribe_failed" ? (_a = msg.errorReason) != null ? _a : "Bridge event subscription failed." : msg.errorReason,
3939
+ errorReason: (_a = msg.errorReason) != null ? _a : fallbackErrorReason,
3778
3940
  timestamp: msg.timestamp
3779
3941
  };
3780
3942
  setTerminalOrderEvents((prev) => {
@@ -3912,7 +4074,10 @@ function useExecutionProgress({
3912
4074
  pending.map((orderId) => __async(null, null, function* () {
3913
4075
  var _a2, _b2;
3914
4076
  try {
3915
- const res = yield client.getExecutionOrders({ orderId, limit: 1 });
4077
+ const res = yield client.getExecutionOrders(__spreadValues({
4078
+ orderId,
4079
+ limit: 1
4080
+ }, mode ? { mode } : {}));
3916
4081
  return (_b2 = (_a2 = res.data) == null ? void 0 : _a2[0]) != null ? _b2 : null;
3917
4082
  } catch (e) {
3918
4083
  return null;
@@ -3973,7 +4138,7 @@ function useExecutionProgress({
3973
4138
  cancelled = true;
3974
4139
  stopPolling();
3975
4140
  };
3976
- }, [client, isListening, orderIds]);
4141
+ }, [client, isListening, mode, orderIds]);
3977
4142
  return { phase, submittedOrders, latestBalance, dagProgress, terminalOrderEvents };
3978
4143
  }
3979
4144
 
@@ -4016,7 +4181,7 @@ var computeClosedPositionTotals = (group) => {
4016
4181
  };
4017
4182
 
4018
4183
  // src/execution/use-redeem.ts
4019
- var import_react_query13 = require("@tanstack/react-query");
4184
+ var import_react_query14 = require("@tanstack/react-query");
4020
4185
  var RedeemRejectedError = class extends Error {
4021
4186
  constructor(message, response) {
4022
4187
  super(message);
@@ -4027,8 +4192,8 @@ var RedeemRejectedError = class extends Error {
4027
4192
  var isLegRejected = (status) => status === "ineligible" || status === "rejected";
4028
4193
  var useRedeem = () => {
4029
4194
  const client = useAggClient();
4030
- const queryClient = (0, import_react_query13.useQueryClient)();
4031
- return (0, import_react_query13.useMutation)({
4195
+ const queryClient = (0, import_react_query14.useQueryClient)();
4196
+ return (0, import_react_query14.useMutation)({
4032
4197
  mutationFn: (body) => __async(null, null, function* () {
4033
4198
  const response = yield client.redeem(body);
4034
4199
  if (response.results.length > 0 && response.results.every((r) => isLegRejected(r.status))) {
@@ -4038,10 +4203,8 @@ var useRedeem = () => {
4038
4203
  }
4039
4204
  return response;
4040
4205
  }),
4041
- onSuccess: () => {
4042
- queryClient.invalidateQueries({ queryKey: executionKeys.positionsPrefix() });
4043
- queryClient.invalidateQueries({ queryKey: executionKeys.balances() });
4044
- queryClient.invalidateQueries({ queryKey: executionKeys.claimableClosedPositionsCount() });
4206
+ onSettled: () => {
4207
+ invalidateUserClaimState(queryClient);
4045
4208
  }
4046
4209
  });
4047
4210
  };
@@ -4052,15 +4215,15 @@ var useOnRedeemEvent2 = (listener) => {
4052
4215
  };
4053
4216
 
4054
4217
  // src/execution/use-redeem-eligible-count.ts
4055
- var import_react_query14 = require("@tanstack/react-query");
4218
+ var import_react_query15 = require("@tanstack/react-query");
4056
4219
  var CLAIMABLE_COUNT_PAGE_LIMIT = 100;
4057
- var getClaimableClosedPositionsCount = (client) => __async(null, null, function* () {
4220
+ var getClaimablePositionsCount = (client) => __async(null, null, function* () {
4058
4221
  var _a;
4059
4222
  let total = 0;
4060
4223
  let cursor;
4061
4224
  do {
4062
4225
  const page = yield client.getExecutionPositions({
4063
- status: "closed",
4226
+ status: "active",
4064
4227
  limit: CLAIMABLE_COUNT_PAGE_LIMIT,
4065
4228
  cursor
4066
4229
  });
@@ -4077,9 +4240,9 @@ var useRedeemEligibleCount = () => {
4077
4240
  var _a;
4078
4241
  const client = useAggClient();
4079
4242
  const { isAuthenticated } = useAggAuthState();
4080
- const query = (0, import_react_query14.useQuery)({
4081
- queryKey: executionKeys.claimableClosedPositionsCount(),
4082
- queryFn: () => getClaimableClosedPositionsCount(client),
4243
+ const query = (0, import_react_query15.useQuery)({
4244
+ queryKey: executionKeys.claimablePositionsCount(),
4245
+ queryFn: () => getClaimablePositionsCount(client),
4083
4246
  enabled: isAuthenticated,
4084
4247
  staleTime: 3e4,
4085
4248
  refetchInterval: isAuthenticated ? 45e3 : false
@@ -4528,7 +4691,7 @@ function useWithdrawEstimate({
4528
4691
 
4529
4692
  // src/withdraw/use-withdrawal-lifecycle.ts
4530
4693
  var import_react15 = require("react");
4531
- var import_react_query15 = require("@tanstack/react-query");
4694
+ var import_react_query16 = require("@tanstack/react-query");
4532
4695
  var INITIAL_STATE2 = {
4533
4696
  pending: true,
4534
4697
  status: null,
@@ -4583,7 +4746,7 @@ var restToLifecycleState = (response) => {
4583
4746
  function useWithdrawalLifecycle(withdrawalId) {
4584
4747
  const client = useAggClient();
4585
4748
  const wsConnected = useAggWebSocketConnectionState();
4586
- const queryClient = (0, import_react_query15.useQueryClient)();
4749
+ const queryClient = (0, import_react_query16.useQueryClient)();
4587
4750
  const [state, setState] = (0, import_react15.useState)(INITIAL_STATE2);
4588
4751
  const stateRef = (0, import_react15.useRef)(state);
4589
4752
  stateRef.current = state;
@@ -4673,6 +4836,32 @@ function useGeoBlock() {
4673
4836
  };
4674
4837
  }
4675
4838
 
4839
+ // src/venue-availability.ts
4840
+ var normalizeVenueId = (venueId) => venueId.trim().toLowerCase();
4841
+ var getDisabledVenueSet = (disabledVenues) => {
4842
+ return new Set((disabledVenues != null ? disabledVenues : []).map(normalizeVenueId));
4843
+ };
4844
+ var isVenueDisabledByConfig = (venueId, disabledVenues) => {
4845
+ return getDisabledVenueSet(disabledVenues).has(normalizeVenueId(venueId));
4846
+ };
4847
+ var getVisibleVenuesByConfig = (venues, disabledVenues) => {
4848
+ const disabledVenueSet = getDisabledVenueSet(disabledVenues);
4849
+ return venues.filter((venue) => !disabledVenueSet.has(normalizeVenueId(venue.id)));
4850
+ };
4851
+ var getVisibleVenueIdsByConfig = (venueIds, disabledVenues) => {
4852
+ const disabledVenueSet = getDisabledVenueSet(disabledVenues);
4853
+ return venueIds.filter((venueId) => !disabledVenueSet.has(normalizeVenueId(venueId)));
4854
+ };
4855
+ var getVenueAvailabilityState = ({
4856
+ venueId,
4857
+ disabledVenues,
4858
+ isLocationBlocked
4859
+ }) => {
4860
+ if (isVenueDisabledByConfig(venueId, disabledVenues)) return "hidden";
4861
+ if (isLocationBlocked) return "geoblocked";
4862
+ return "available";
4863
+ };
4864
+
4676
4865
  // src/use-agg-auth.ts
4677
4866
  var import_react17 = require("react");
4678
4867
  function useAggAuth(options = {}) {
@@ -4741,19 +4930,21 @@ var requestAggAuthChooserOpen = () => {
4741
4930
  };
4742
4931
 
4743
4932
  // src/use-categories.ts
4744
- var import_react_query16 = require("@tanstack/react-query");
4933
+ var import_react_query17 = require("@tanstack/react-query");
4745
4934
  function useCategories(options) {
4746
- var _a, _b, _c, _d;
4935
+ var _a, _b, _c, _d, _e, _f;
4747
4936
  const client = useAggClient();
4748
- const enabled = (_a = options == null ? void 0 : options.enabled) != null ? _a : true;
4749
- const limit = (_b = options == null ? void 0 : options.limit) != null ? _b : 20;
4750
- const query = (0, import_react_query16.useInfiniteQuery)({
4751
- queryKey: ["categories", limit],
4937
+ const queryKeyScope = (_a = options == null ? void 0 : options.queryKeyScope) != null ? _a : "categories";
4938
+ const parentId = (_b = options == null ? void 0 : options.parentId) != null ? _b : null;
4939
+ const enabled = (_c = options == null ? void 0 : options.enabled) != null ? _c : true;
4940
+ const limit = (_d = options == null ? void 0 : options.limit) != null ? _d : 20;
4941
+ const query = (0, import_react_query17.useInfiniteQuery)({
4942
+ queryKey: [queryKeyScope, "parent", parentId != null ? parentId : "__root__", limit],
4752
4943
  queryFn: (_0) => __async(null, [_0], function* ({ pageParam }) {
4753
- const res = yield client.getCategories({
4944
+ const res = yield client.getCategories(__spreadValues({
4754
4945
  limit,
4755
4946
  cursor: pageParam
4756
- });
4947
+ }, parentId != null ? { parentId } : {}));
4757
4948
  return res;
4758
4949
  }),
4759
4950
  initialPageParam: void 0,
@@ -4763,13 +4954,48 @@ function useCategories(options) {
4763
4954
  },
4764
4955
  enabled
4765
4956
  });
4766
- const categories = (_d = (_c = query.data) == null ? void 0 : _c.pages.flatMap((p) => p.data)) != null ? _d : [];
4957
+ const categories = (_f = (_e = query.data) == null ? void 0 : _e.pages.flatMap((p) => p.data)) != null ? _f : [];
4767
4958
  const hasNextPage = !!query.hasNextPage;
4768
4959
  return __spreadProps(__spreadValues({}, query), {
4769
4960
  categories,
4770
4961
  hasNextPage
4771
4962
  });
4772
4963
  }
4964
+ function useCategoryChildren(options) {
4965
+ var _a, _b, _c, _d;
4966
+ const client = useAggClient();
4967
+ const queryKeyScope = (_a = options == null ? void 0 : options.queryKeyScope) != null ? _a : "category-children";
4968
+ const enabled = (_b = options == null ? void 0 : options.enabled) != null ? _b : true;
4969
+ const limit = (_c = options == null ? void 0 : options.limit) != null ? _c : 20;
4970
+ const parentIds = Array.from(
4971
+ new Set(((_d = options == null ? void 0 : options.parentIds) != null ? _d : []).filter((parentId) => Boolean(parentId)))
4972
+ );
4973
+ const queries = (0, import_react_query17.useQueries)({
4974
+ queries: parentIds.map((parentId) => ({
4975
+ queryKey: [queryKeyScope, "parent", parentId, limit],
4976
+ queryFn: () => __async(null, null, function* () {
4977
+ return client.getCategories({
4978
+ limit,
4979
+ cursor: void 0,
4980
+ parentId
4981
+ });
4982
+ }),
4983
+ enabled
4984
+ }))
4985
+ });
4986
+ const childrenByParentId = /* @__PURE__ */ new Map();
4987
+ queries.forEach((query, index) => {
4988
+ var _a2, _b2;
4989
+ const parentId = parentIds[index];
4990
+ if (!parentId) return;
4991
+ childrenByParentId.set(parentId, (_b2 = (_a2 = query.data) == null ? void 0 : _a2.data) != null ? _b2 : []);
4992
+ });
4993
+ return {
4994
+ queries,
4995
+ childrenByParentId,
4996
+ isLoading: queries.some((query) => query.isLoading)
4997
+ };
4998
+ }
4773
4999
 
4774
5000
  // src/use-debounced-value.ts
4775
5001
  var import_react19 = require("react");
@@ -4787,7 +5013,7 @@ function useDebouncedValue(value, delay) {
4787
5013
  }
4788
5014
 
4789
5015
  // src/use-execution-orders.ts
4790
- var import_react_query17 = require("@tanstack/react-query");
5016
+ var import_react_query18 = require("@tanstack/react-query");
4791
5017
  function useExecutionOrders(options = {}) {
4792
5018
  var _a, _b;
4793
5019
  const client = useAggClient();
@@ -4795,21 +5021,30 @@ function useExecutionOrders(options = {}) {
4795
5021
  status,
4796
5022
  orderId,
4797
5023
  quoteId,
5024
+ mode,
4798
5025
  limit = 50,
4799
5026
  enabled = true,
4800
5027
  refetchIntervalMs = false
4801
5028
  } = options;
4802
- const query = (0, import_react_query17.useInfiniteQuery)({
5029
+ const query = (0, import_react_query18.useInfiniteQuery)({
4803
5030
  // quoteId + orderId are part of the cache key — different filters
4804
5031
  // produce different result sets, so they have to vary the key.
4805
- queryKey: ["execution-orders", status != null ? status : "all", quoteId != null ? quoteId : null, orderId != null ? orderId : null, limit],
4806
- queryFn: ({ pageParam }) => client.getExecutionOrders({
5032
+ queryKey: [
5033
+ "execution-orders",
5034
+ status != null ? status : "all",
5035
+ quoteId != null ? quoteId : null,
5036
+ orderId != null ? orderId : null,
5037
+ ...mode ? [mode] : [],
5038
+ limit
5039
+ ],
5040
+ queryFn: ({ pageParam }) => client.getExecutionOrders(__spreadProps(__spreadValues({
4807
5041
  status,
4808
5042
  orderId,
4809
- quoteId,
5043
+ quoteId
5044
+ }, mode ? { mode } : {}), {
4810
5045
  limit,
4811
5046
  cursor: pageParam
4812
- }),
5047
+ })),
4813
5048
  initialPageParam: void 0,
4814
5049
  getNextPageParam: (lastPage) => {
4815
5050
  var _a2;
@@ -4827,7 +5062,7 @@ function useExecutionOrders(options = {}) {
4827
5062
  }
4828
5063
 
4829
5064
  // src/use-user-activity.ts
4830
- var import_react_query18 = require("@tanstack/react-query");
5065
+ var import_react_query19 = require("@tanstack/react-query");
4831
5066
  var DEFAULT_PENDING_REFETCH_INTERVAL_MS = 15e3;
4832
5067
  var PENDING_ACTIVITY_STATUSES = /* @__PURE__ */ new Set([
4833
5068
  "pending",
@@ -4844,6 +5079,9 @@ var hasPendingActivity = (pages) => {
4844
5079
  if (!pages) return false;
4845
5080
  for (const page of pages) {
4846
5081
  for (const item of page.data) {
5082
+ if (item.type === "redeem" && item.legs.length > 0 && item.legs.every((leg) => leg.status.toLowerCase() === "confirmed")) {
5083
+ continue;
5084
+ }
4847
5085
  if (PENDING_ACTIVITY_STATUSES.has(item.status.toLowerCase())) return true;
4848
5086
  }
4849
5087
  }
@@ -4858,8 +5096,8 @@ function useUserActivity(options = {}) {
4858
5096
  enabled = true,
4859
5097
  pendingRefetchIntervalMs = DEFAULT_PENDING_REFETCH_INTERVAL_MS
4860
5098
  } = options;
4861
- const query = (0, import_react_query18.useInfiniteQuery)({
4862
- queryKey: ["user-activity", type != null ? type : "all", limit],
5099
+ const query = (0, import_react_query19.useInfiniteQuery)({
5100
+ queryKey: userActivityQueryKeys.feed(type, limit),
4863
5101
  queryFn: ({ pageParam }) => client.getUserActivity({
4864
5102
  type,
4865
5103
  limit,
@@ -4875,7 +5113,7 @@ function useUserActivity(options = {}) {
4875
5113
  // flight (typically after a deposit / withdraw cache invalidation).
4876
5114
  // Without this the feed flashes to the skeleton mid-session, which
4877
5115
  // is worse UX than briefly showing slightly-stale rows.
4878
- placeholderData: import_react_query18.keepPreviousData,
5116
+ placeholderData: import_react_query19.keepPreviousData,
4879
5117
  refetchInterval: (q) => {
4880
5118
  if (pendingRefetchIntervalMs === false) return false;
4881
5119
  const data = q.state.data;
@@ -4920,18 +5158,19 @@ function useExternalId(options = {}) {
4920
5158
  }
4921
5159
 
4922
5160
  // src/use-execution-positions.ts
4923
- var import_react_query19 = require("@tanstack/react-query");
5161
+ var import_react_query20 = require("@tanstack/react-query");
4924
5162
  function useExecutionPositions(options = {}) {
4925
5163
  var _a, _b;
4926
5164
  const client = useAggClient();
4927
- const { limit = 50, status, enabled = true } = options;
4928
- const query = (0, import_react_query19.useInfiniteQuery)({
4929
- queryKey: executionKeys.positions(null, limit, status != null ? status : null),
4930
- queryFn: ({ pageParam }) => client.getExecutionPositions({
5165
+ const { limit = 50, status, mode, enabled = true } = options;
5166
+ const query = (0, import_react_query20.useInfiniteQuery)({
5167
+ queryKey: executionKeys.positions(null, limit, status != null ? status : null, mode != null ? mode : null),
5168
+ queryFn: ({ pageParam }) => client.getExecutionPositions(__spreadProps(__spreadValues({
4931
5169
  limit,
4932
- status,
5170
+ status
5171
+ }, mode ? { mode } : {}), {
4933
5172
  cursor: pageParam
4934
- }),
5173
+ })),
4935
5174
  initialPageParam: void 0,
4936
5175
  getNextPageParam: (lastPage) => {
4937
5176
  var _a2;
@@ -4955,7 +5194,7 @@ var import_react23 = require("react");
4955
5194
  var import_sdk3 = require("@agg-build/sdk");
4956
5195
 
4957
5196
  // src/use-market-chart.ts
4958
- var import_react_query20 = require("@tanstack/react-query");
5197
+ var import_react_query21 = require("@tanstack/react-query");
4959
5198
 
4960
5199
  // src/market-data/subscription.ts
4961
5200
  var import_react21 = require("react");
@@ -5040,7 +5279,7 @@ function useMarketChart(options) {
5040
5279
  orderbook: true,
5041
5280
  trades: true
5042
5281
  });
5043
- const queries = (0, import_react_query20.useQueries)({
5282
+ const queries = (0, import_react_query21.useQueries)({
5044
5283
  queries: outcomeIds.map((outcomeId) => ({
5045
5284
  // Cache key is intentionally time-free. The rolling window's
5046
5285
  // startTs/endTs advance on every bucket but the user expects the same
@@ -5075,7 +5314,7 @@ function useMarketChart(options) {
5075
5314
  gcTime: 60 * 6e4,
5076
5315
  refetchOnWindowFocus: false,
5077
5316
  retry: 1,
5078
- placeholderData: import_react_query20.keepPreviousData,
5317
+ placeholderData: import_react_query21.keepPreviousData,
5079
5318
  refetchInterval: refetchIntervalMs != null && refetchIntervalMs > 0 ? refetchIntervalMs : false,
5080
5319
  refetchIntervalInBackground: false
5081
5320
  }))
@@ -5318,7 +5557,7 @@ function useEventOrderbookData(venueMarkets, selectedMarketId) {
5318
5557
  }
5319
5558
 
5320
5559
  // src/use-live-market.ts
5321
- var import_react_query21 = require("@tanstack/react-query");
5560
+ var import_react_query22 = require("@tanstack/react-query");
5322
5561
  function outcomeOrderbookToState(response, marketId) {
5323
5562
  var _a, _b, _c, _d;
5324
5563
  const { venue, orderbook, midpoint, spread, seq, checksum, timestamp, venueMarketOutcomeId } = response;
@@ -5368,7 +5607,7 @@ function useLiveMarket(canonicalMarketId) {
5368
5607
  enabled: isLiveSubscriptionEnabled,
5369
5608
  orderbook: true
5370
5609
  });
5371
- const query = (0, import_react_query21.useQuery)({
5610
+ const query = (0, import_react_query22.useQuery)({
5372
5611
  queryKey: marketDataKeys.live(canonicalMarketId != null ? canonicalMarketId : "__disabled__"),
5373
5612
  queryFn: () => __async(null, null, function* () {
5374
5613
  return createMarketLiveState(canonicalMarketId != null ? canonicalMarketId : "__disabled__");
@@ -5380,7 +5619,7 @@ function useLiveMarket(canonicalMarketId) {
5380
5619
  isConnected: Boolean(isLiveSubscriptionEnabled && isConnected)
5381
5620
  })
5382
5621
  });
5383
- const seedQuery = (0, import_react_query21.useQuery)({
5622
+ const seedQuery = (0, import_react_query22.useQuery)({
5384
5623
  queryKey: ["live-market-seed", canonicalMarketId],
5385
5624
  queryFn: ({ signal }) => canonicalMarketId ? client.getOutcomeOrderbook(canonicalMarketId, { signal }) : Promise.resolve(null),
5386
5625
  enabled: Boolean(canonicalMarketId),
@@ -5401,7 +5640,7 @@ function useLiveMarket(canonicalMarketId) {
5401
5640
 
5402
5641
  // src/use-live-outcome-prices.ts
5403
5642
  var import_react26 = require("react");
5404
- var import_react_query22 = require("@tanstack/react-query");
5643
+ var import_react_query23 = require("@tanstack/react-query");
5405
5644
  var EMPTY_PRICES = /* @__PURE__ */ new Map();
5406
5645
  var buildMidpointFingerprint = (outcomeIds, queries) => {
5407
5646
  var _a, _b, _c;
@@ -5427,7 +5666,7 @@ function useLiveOutcomePrices(venueMarkets) {
5427
5666
  }
5428
5667
  return [...ids].sort();
5429
5668
  }, [venueMarkets]);
5430
- const queries = (0, import_react_query22.useQueries)({
5669
+ const queries = (0, import_react_query23.useQueries)({
5431
5670
  queries: outcomeIds.map((id) => ({
5432
5671
  queryKey: marketDataKeys.live(id),
5433
5672
  queryFn: () => createMarketLiveState(id),
@@ -5477,7 +5716,7 @@ function findLivePriceById(livePrices, id) {
5477
5716
 
5478
5717
  // src/use-live-best-prices.ts
5479
5718
  var import_react27 = require("react");
5480
- var import_react_query23 = require("@tanstack/react-query");
5719
+ var import_react_query24 = require("@tanstack/react-query");
5481
5720
  var EMPTY = /* @__PURE__ */ new Map();
5482
5721
  var extractOutcomeBestPrices = (state) => {
5483
5722
  var _a, _b;
@@ -5519,7 +5758,7 @@ function useLiveBestPrices(venueMarkets) {
5519
5758
  }
5520
5759
  return [...ids].sort();
5521
5760
  }, [venueMarkets]);
5522
- const queries = (0, import_react_query23.useQueries)({
5761
+ const queries = (0, import_react_query24.useQueries)({
5523
5762
  queries: outcomeIds.map((id) => ({
5524
5763
  queryKey: marketDataKeys.live(id),
5525
5764
  queryFn: () => createMarketLiveState(id),
@@ -5613,7 +5852,7 @@ function useLiveTrades(canonicalMarketId) {
5613
5852
  }
5614
5853
 
5615
5854
  // src/use-midpoints.ts
5616
- var import_react_query24 = require("@tanstack/react-query");
5855
+ var import_react_query25 = require("@tanstack/react-query");
5617
5856
  var import_react28 = require("react");
5618
5857
  var normalizeVenueMarketIds = (venueMarkets) => {
5619
5858
  var _a;
@@ -5750,7 +5989,7 @@ function useMidpoints(venueMarkets) {
5750
5989
  () => resolveBestMidpointCandidateOutcomeIds(venueMarkets),
5751
5990
  [venueMarkets]
5752
5991
  );
5753
- const { data, isLoading } = (0, import_react_query24.useQuery)({
5992
+ const { data, isLoading } = (0, import_react_query25.useQuery)({
5754
5993
  queryKey: ["midpoints", ids],
5755
5994
  queryFn: () => client.getMidpoints(ids, { bestPrice: true }),
5756
5995
  enabled: ids.length > 0,
@@ -5906,10 +6145,10 @@ var useRollingChartWindow = (options) => {
5906
6145
  };
5907
6146
 
5908
6147
  // src/use-market-orderbook.ts
5909
- var import_react_query25 = require("@tanstack/react-query");
6148
+ var import_react_query26 = require("@tanstack/react-query");
5910
6149
  function useMarketOrderbook(options) {
5911
6150
  var _a, _b, _c, _d, _e, _f, _g;
5912
- const queryClient = (0, import_react_query25.useQueryClient)();
6151
+ const queryClient = (0, import_react_query26.useQueryClient)();
5913
6152
  const ws = useAggWebSocket();
5914
6153
  const isConnected = useAggWebSocketConnectionState();
5915
6154
  const {
@@ -5926,7 +6165,7 @@ function useMarketOrderbook(options) {
5926
6165
  enabled: enabled && !!selectedOutcomeId,
5927
6166
  orderbook: true
5928
6167
  });
5929
- const liveQueries = (0, import_react_query25.useQueries)({
6168
+ const liveQueries = (0, import_react_query26.useQueries)({
5930
6169
  queries: subscriptionIds.map((subscriptionId) => ({
5931
6170
  queryKey: marketDataKeys.live(subscriptionId),
5932
6171
  queryFn: () => createMarketLiveState(subscriptionId),
@@ -5991,8 +6230,66 @@ function useMarketOrderbook(options) {
5991
6230
  };
5992
6231
  }
5993
6232
 
6233
+ // src/use-arb.ts
6234
+ var import_react31 = require("react");
6235
+ function useMarketArb(marketId) {
6236
+ const ws = useAggWebSocket();
6237
+ const [state, setState] = (0, import_react31.useState)({ arbReturn: null, isLive: false });
6238
+ (0, import_react31.useEffect)(() => {
6239
+ if (!ws || !marketId) return;
6240
+ const cached = ws.getArb(marketId);
6241
+ if (cached != null) {
6242
+ setState({ arbReturn: cached.arbReturn, isLive: true });
6243
+ }
6244
+ const off = ws.subscribeArb(marketId, (msg) => {
6245
+ setState({ arbReturn: msg.arbReturn, isLive: true });
6246
+ });
6247
+ return off;
6248
+ }, [ws, marketId]);
6249
+ return state;
6250
+ }
6251
+ var EMPTY_ARB_FEED = {
6252
+ byMarket: /* @__PURE__ */ new Map(),
6253
+ byEvent: /* @__PURE__ */ new Map()
6254
+ };
6255
+ function useArbFeed() {
6256
+ const ws = useAggWebSocket();
6257
+ const [state, setState] = (0, import_react31.useState)(EMPTY_ARB_FEED);
6258
+ const stateRef = (0, import_react31.useRef)(state);
6259
+ stateRef.current = state;
6260
+ (0, import_react31.useEffect)(() => {
6261
+ if (!ws) return;
6262
+ const off = ws.subscribeArbFeed((batch) => {
6263
+ setState((prev) => {
6264
+ const nextByMarket = new Map(prev.byMarket);
6265
+ for (const entry of batch.entries) {
6266
+ nextByMarket.set(entry.marketId, {
6267
+ arb: entry.arbReturn,
6268
+ eventId: entry.venueEventId
6269
+ });
6270
+ }
6271
+ const nextByEvent = /* @__PURE__ */ new Map();
6272
+ for (const { arb, eventId } of nextByMarket.values()) {
6273
+ if (eventId == null) continue;
6274
+ const current = nextByEvent.get(eventId);
6275
+ if (current == null || arb > current) {
6276
+ nextByEvent.set(eventId, arb);
6277
+ }
6278
+ }
6279
+ return { byMarket: nextByMarket, byEvent: nextByEvent };
6280
+ });
6281
+ });
6282
+ return off;
6283
+ }, [ws]);
6284
+ const publicByMarket = /* @__PURE__ */ new Map();
6285
+ for (const [marketId, { arb }] of state.byMarket) {
6286
+ publicByMarket.set(marketId, arb);
6287
+ }
6288
+ return { byMarket: publicByMarket, byEvent: state.byEvent };
6289
+ }
6290
+
5994
6291
  // src/use-order-book.ts
5995
- var import_react_query26 = require("@tanstack/react-query");
6292
+ var import_react_query27 = require("@tanstack/react-query");
5996
6293
  function useOrderBook(options) {
5997
6294
  const client = useAggClient();
5998
6295
  const { orderbooks, enabled = true, canonicalMarketId } = options;
@@ -6005,7 +6302,7 @@ function useOrderBook(options) {
6005
6302
  venueMarketOutcomeId: outcome.id
6006
6303
  })) : void 0
6007
6304
  });
6008
- const batchedResult = (0, import_react_query26.useQuery)({
6305
+ const batchedResult = (0, import_react_query27.useQuery)({
6009
6306
  queryKey: requestedVenueMarketIds.length ? ["orderbooks", requestedVenueMarketIds, null] : ["orderbooks", "__disabled__", null],
6010
6307
  queryFn: ({ signal }) => client.getOrderbooks(
6011
6308
  {
@@ -6018,7 +6315,7 @@ function useOrderBook(options) {
6018
6315
  gcTime: 5 * 6e4,
6019
6316
  refetchOnWindowFocus: false,
6020
6317
  retry: 1,
6021
- placeholderData: import_react_query26.keepPreviousData
6318
+ placeholderData: import_react_query27.keepPreviousData
6022
6319
  });
6023
6320
  const data = (() => {
6024
6321
  var _a, _b;
@@ -6073,7 +6370,7 @@ function useOrderBook(options) {
6073
6370
  }
6074
6371
 
6075
6372
  // src/use-orderbook-quote.ts
6076
- var import_react_query27 = require("@tanstack/react-query");
6373
+ var import_react_query28 = require("@tanstack/react-query");
6077
6374
  var QUOTE_DEBOUNCE_MS = 300;
6078
6375
  var createUnavailableOrderbookError = (message, code, retryable) => {
6079
6376
  const error = new Error(message);
@@ -6135,7 +6432,7 @@ function useOrderbookQuote(options) {
6135
6432
  const { marketId, side, size, enabled = true } = options;
6136
6433
  const debouncedSize = useDebouncedValue(size, QUOTE_DEBOUNCE_MS);
6137
6434
  const shouldFetch = enabled && !!marketId && debouncedSize > 0;
6138
- const query = (0, import_react_query27.useQuery)({
6435
+ const query = (0, import_react_query28.useQuery)({
6139
6436
  queryKey: marketId ? marketDataKeys.orderbookQuote(marketId, side, debouncedSize) : ["market-data", "orderbook-quote", "__disabled__"],
6140
6437
  queryFn: () => __async(null, null, function* () {
6141
6438
  var _a2, _b, _c, _d;
@@ -6166,7 +6463,7 @@ function useOrderbookQuote(options) {
6166
6463
  staleTime: 1e4,
6167
6464
  gcTime: 5 * 6e4,
6168
6465
  retry: 1,
6169
- placeholderData: import_react_query27.keepPreviousData
6466
+ placeholderData: import_react_query28.keepPreviousData
6170
6467
  });
6171
6468
  return {
6172
6469
  data: (_a = query.data) != null ? _a : null,
@@ -6177,12 +6474,12 @@ function useOrderbookQuote(options) {
6177
6474
  }
6178
6475
 
6179
6476
  // src/use-orders.ts
6180
- var import_react_query28 = require("@tanstack/react-query");
6477
+ var import_react_query29 = require("@tanstack/react-query");
6181
6478
  function useOrders(options = {}) {
6182
6479
  var _a, _b, _c, _d;
6183
6480
  const client = useAggClient();
6184
6481
  const { userId, status, limit = 50, offset = 0, enabled = true } = options;
6185
- const query = (0, import_react_query28.useQuery)({
6482
+ const query = (0, import_react_query29.useQuery)({
6186
6483
  queryKey: ["orders", userId != null ? userId : "me", status != null ? status : "all", limit, offset],
6187
6484
  queryFn: () => client.getOrders({
6188
6485
  userId,
@@ -6199,16 +6496,16 @@ function useOrders(options = {}) {
6199
6496
  }
6200
6497
 
6201
6498
  // src/use-search.ts
6202
- var import_react_query29 = require("@tanstack/react-query");
6203
- var import_react31 = require("react");
6499
+ var import_react_query30 = require("@tanstack/react-query");
6500
+ var import_react32 = require("react");
6204
6501
  function useSearch(options) {
6205
6502
  var _a, _b, _c;
6206
- const client = (0, import_react31.useContext)(AggClientContext);
6207
- const queryClient = (0, import_react31.useContext)(import_react_query29.QueryClientContext);
6208
- const [fallbackQueryClient] = (0, import_react31.useState)(() => new import_react_query29.QueryClient());
6503
+ const client = (0, import_react32.useContext)(AggClientContext);
6504
+ const queryClient = (0, import_react32.useContext)(import_react_query30.QueryClientContext);
6505
+ const [fallbackQueryClient] = (0, import_react32.useState)(() => new import_react_query30.QueryClient());
6209
6506
  const { q, type, categoryIds, limit = 20, enabled = true, deep = false } = options;
6210
6507
  const isEnabled = enabled && q.length > 0;
6211
- (0, import_react31.useEffect)(() => {
6508
+ (0, import_react32.useEffect)(() => {
6212
6509
  if (queryClient) return void 0;
6213
6510
  fallbackQueryClient.mount();
6214
6511
  return () => {
@@ -6218,7 +6515,7 @@ function useSearch(options) {
6218
6515
  if (isEnabled && !client) {
6219
6516
  throw new Error("useSearch must be used within an <AggProvider>");
6220
6517
  }
6221
- const query = (0, import_react_query29.useInfiniteQuery)(
6518
+ const query = (0, import_react_query30.useInfiniteQuery)(
6222
6519
  {
6223
6520
  // deep is part of the key — TanStack treats deep vs light as
6224
6521
  // independent queries so users can have both modes cached side-by-side.
@@ -6243,7 +6540,7 @@ function useSearch(options) {
6243
6540
  if (!lastPage.hasMore) return void 0;
6244
6541
  return (_a2 = lastPage.nextCursor) != null ? _a2 : void 0;
6245
6542
  },
6246
- placeholderData: import_react_query29.keepPreviousData,
6543
+ placeholderData: import_react_query30.keepPreviousData,
6247
6544
  enabled: isEnabled && !!client
6248
6545
  },
6249
6546
  queryClient != null ? queryClient : fallbackQueryClient
@@ -6262,7 +6559,7 @@ function useSearch(options) {
6262
6559
  }
6263
6560
 
6264
6561
  // src/use-market-search.ts
6265
- var import_react32 = require("react");
6562
+ var import_react33 = require("react");
6266
6563
  function useMarketSearch(options) {
6267
6564
  var _a;
6268
6565
  const {
@@ -6273,8 +6570,8 @@ function useMarketSearch(options) {
6273
6570
  enableSuggestions = true,
6274
6571
  minLength = 1
6275
6572
  } = options;
6276
- const [query, setQueryState] = (0, import_react32.useState)("");
6277
- const [submittedQuery, setSubmittedQuery] = (0, import_react32.useState)(null);
6573
+ const [query, setQueryState] = (0, import_react33.useState)("");
6574
+ const [submittedQuery, setSubmittedQuery] = (0, import_react33.useState)(null);
6278
6575
  const debouncedQuery = useDebouncedValue(query, debounceMs);
6279
6576
  const trimmedDebounced = debouncedQuery.trim();
6280
6577
  const suggestionsEnabled = enableSuggestions && trimmedDebounced.length >= minLength;
@@ -6295,10 +6592,10 @@ function useMarketSearch(options) {
6295
6592
  enabled: submittedQ.length > 0,
6296
6593
  deep: true
6297
6594
  });
6298
- const setQuery = (0, import_react32.useCallback)((value) => {
6595
+ const setQuery = (0, import_react33.useCallback)((value) => {
6299
6596
  setQueryState(value);
6300
6597
  }, []);
6301
- const submit = (0, import_react32.useCallback)(
6598
+ const submit = (0, import_react33.useCallback)(
6302
6599
  (q) => {
6303
6600
  const target = (q != null ? q : query).trim();
6304
6601
  if (target.length === 0) return;
@@ -6306,7 +6603,7 @@ function useMarketSearch(options) {
6306
6603
  },
6307
6604
  [query]
6308
6605
  );
6309
- const clear = (0, import_react32.useCallback)(() => {
6606
+ const clear = (0, import_react33.useCallback)(() => {
6310
6607
  setQueryState("");
6311
6608
  setSubmittedQuery(null);
6312
6609
  }, []);
@@ -6348,7 +6645,7 @@ function useMarketSearch(options) {
6348
6645
  }
6349
6646
 
6350
6647
  // src/use-smart-route.ts
6351
- var import_react_query30 = require("@tanstack/react-query");
6648
+ var import_react_query31 = require("@tanstack/react-query");
6352
6649
  var SMART_ROUTE_STALE_TIME_MS = 2e4;
6353
6650
  function useSmartRoute(options) {
6354
6651
  var _a, _b;
@@ -6359,6 +6656,7 @@ function useSmartRoute(options) {
6359
6656
  outcomeId,
6360
6657
  side,
6361
6658
  tradeSide,
6659
+ mode,
6362
6660
  maxSpend,
6363
6661
  sellShares,
6364
6662
  chainBalances,
@@ -6369,12 +6667,13 @@ function useSmartRoute(options) {
6369
6667
  staleTimeMs = SMART_ROUTE_STALE_TIME_MS
6370
6668
  } = options;
6371
6669
  const resolvedVenueMarketOutcomeId = (_a = venueMarketOutcomeId != null ? venueMarketOutcomeId : venueMarketId) != null ? _a : outcomeId;
6372
- const query = (0, import_react_query30.useQuery)({
6670
+ const query = (0, import_react_query31.useQuery)({
6373
6671
  queryKey: [
6374
6672
  "smart-route",
6375
6673
  resolvedVenueMarketOutcomeId,
6376
6674
  side != null ? side : null,
6377
6675
  tradeSide != null ? tradeSide : null,
6676
+ ...mode ? [mode] : [],
6378
6677
  maxSpend != null ? maxSpend : null,
6379
6678
  sellShares != null ? sellShares : null,
6380
6679
  chainBalances ? JSON.stringify(chainBalances) : null,
@@ -6384,17 +6683,18 @@ function useSmartRoute(options) {
6384
6683
  ],
6385
6684
  queryFn: (_0) => __async(null, [_0], function* ({ signal }) {
6386
6685
  return client.getSmartRoute(
6387
- {
6686
+ __spreadProps(__spreadValues({
6388
6687
  venueMarketOutcomeId: resolvedVenueMarketOutcomeId,
6389
6688
  side: side != null ? side : void 0,
6390
- tradeSide: tradeSide != null ? tradeSide : void 0,
6689
+ tradeSide: tradeSide != null ? tradeSide : void 0
6690
+ }, mode ? { mode } : {}), {
6391
6691
  maxSpend,
6392
6692
  sellShares,
6393
6693
  chainBalances,
6394
6694
  slipCapBps,
6395
6695
  compareVenues,
6396
6696
  deepEstimate
6397
- },
6697
+ }),
6398
6698
  { signal }
6399
6699
  );
6400
6700
  }),
@@ -6404,7 +6704,7 @@ function useSmartRoute(options) {
6404
6704
  gcTime: 6e4,
6405
6705
  refetchOnWindowFocus: false,
6406
6706
  retry: 1,
6407
- placeholderData: import_react_query30.keepPreviousData
6707
+ placeholderData: import_react_query31.keepPreviousData
6408
6708
  });
6409
6709
  const error = query.error;
6410
6710
  return {
@@ -6417,12 +6717,12 @@ function useSmartRoute(options) {
6417
6717
  }
6418
6718
 
6419
6719
  // src/use-user-holdings.ts
6420
- var import_react_query31 = require("@tanstack/react-query");
6720
+ var import_react_query32 = require("@tanstack/react-query");
6421
6721
  function useUserHoldings(options) {
6422
6722
  var _a, _b;
6423
6723
  const client = useAggClient();
6424
6724
  const { venue, venueMarketId, venueEventId, enabled = true } = options;
6425
- const query = (0, import_react_query31.useInfiniteQuery)({
6725
+ const query = (0, import_react_query32.useInfiniteQuery)({
6426
6726
  queryKey: ["user-holdings", venue, venueMarketId, venueEventId],
6427
6727
  queryFn: (_0) => __async(null, [_0], function* ({ pageParam }) {
6428
6728
  return client.getUserHoldings({
@@ -6448,15 +6748,15 @@ function useUserHoldings(options) {
6448
6748
  }
6449
6749
 
6450
6750
  // src/use-enriched-venue-event.ts
6451
- var import_react34 = require("react");
6751
+ var import_react35 = require("react");
6452
6752
 
6453
6753
  // src/use-venue-event.ts
6454
- var import_react_query32 = require("@tanstack/react-query");
6754
+ var import_react_query33 = require("@tanstack/react-query");
6455
6755
  function useVenueEvent(options) {
6456
6756
  var _a;
6457
6757
  const client = useAggClient();
6458
6758
  const { eventId, enabled = true } = options;
6459
- const query = (0, import_react_query32.useQuery)({
6759
+ const query = (0, import_react_query33.useQuery)({
6460
6760
  queryKey: ["venue-event", eventId],
6461
6761
  queryFn: (_0) => __async(null, [_0], function* ({ signal }) {
6462
6762
  return client.getVenueEventById(eventId, { signal });
@@ -6475,13 +6775,13 @@ function useVenueEvent(options) {
6475
6775
  }
6476
6776
 
6477
6777
  // src/use-venue-markets.ts
6478
- var import_react_query33 = require("@tanstack/react-query");
6479
- var import_react33 = require("react");
6778
+ var import_react_query34 = require("@tanstack/react-query");
6779
+ var import_react34 = require("react");
6480
6780
  function useVenueMarkets(options) {
6481
6781
  var _a, _b, _c, _d, _e;
6482
- const client = (0, import_react33.useContext)(AggClientContext);
6483
- const queryClient = (0, import_react33.useContext)(import_react_query33.QueryClientContext);
6484
- const [fallbackQueryClient] = (0, import_react33.useState)(() => new import_react_query33.QueryClient());
6782
+ const client = (0, import_react34.useContext)(AggClientContext);
6783
+ const queryClient = (0, import_react34.useContext)(import_react_query34.QueryClientContext);
6784
+ const [fallbackQueryClient] = (0, import_react34.useState)(() => new import_react_query34.QueryClient());
6485
6785
  const venue = options == null ? void 0 : options.venue;
6486
6786
  const venueEventId = options == null ? void 0 : options.venueEventId;
6487
6787
  const search = options == null ? void 0 : options.search;
@@ -6492,7 +6792,7 @@ function useVenueMarkets(options) {
6492
6792
  const limit = (_b = options == null ? void 0 : options.limit) != null ? _b : 20;
6493
6793
  const sortBy = options == null ? void 0 : options.sortBy;
6494
6794
  const sortDir = options == null ? void 0 : options.sortDir;
6495
- (0, import_react33.useEffect)(() => {
6795
+ (0, import_react34.useEffect)(() => {
6496
6796
  if (queryClient) return void 0;
6497
6797
  fallbackQueryClient.mount();
6498
6798
  return () => {
@@ -6502,7 +6802,7 @@ function useVenueMarkets(options) {
6502
6802
  if (enabled && !client) {
6503
6803
  throw new Error("useVenueMarkets must be used within an <AggProvider>");
6504
6804
  }
6505
- const query = (0, import_react_query33.useInfiniteQuery)(
6805
+ const query = (0, import_react_query34.useInfiniteQuery)(
6506
6806
  {
6507
6807
  queryKey: [
6508
6808
  "venue-markets",
@@ -6572,7 +6872,7 @@ function useEnrichedVenueEvent(options) {
6572
6872
  sortBy: "yesPrice",
6573
6873
  sortDir: "desc"
6574
6874
  });
6575
- const enrichedEvent = (0, import_react34.useMemo)(() => {
6875
+ const enrichedEvent = (0, import_react35.useMemo)(() => {
6576
6876
  if (!event) return void 0;
6577
6877
  if (markets.length === 0) return event;
6578
6878
  return mergeEventWithFullMarkets(event, markets);
@@ -6586,13 +6886,13 @@ function useEnrichedVenueEvent(options) {
6586
6886
  }
6587
6887
 
6588
6888
  // src/use-venue-events.ts
6589
- var import_react_query34 = require("@tanstack/react-query");
6590
- var import_react35 = require("react");
6889
+ var import_react_query35 = require("@tanstack/react-query");
6890
+ var import_react36 = require("react");
6591
6891
  function useVenueEvents(options) {
6592
6892
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
6593
- const client = (0, import_react35.useContext)(AggClientContext);
6594
- const queryClient = (0, import_react35.useContext)(import_react_query34.QueryClientContext);
6595
- const [fallbackQueryClient] = (0, import_react35.useState)(() => new import_react_query34.QueryClient());
6893
+ const client = (0, import_react36.useContext)(AggClientContext);
6894
+ const queryClient = (0, import_react36.useContext)(import_react_query35.QueryClientContext);
6895
+ const [fallbackQueryClient] = (0, import_react36.useState)(() => new import_react_query35.QueryClient());
6596
6896
  const venues = options == null ? void 0 : options.venues;
6597
6897
  const search = options == null ? void 0 : options.search;
6598
6898
  const categoryIds = options == null ? void 0 : options.categoryIds;
@@ -6602,12 +6902,13 @@ function useVenueEvents(options) {
6602
6902
  const status = options == null ? void 0 : options.status;
6603
6903
  const sortBy = options == null ? void 0 : options.sortBy;
6604
6904
  const sortDir = options == null ? void 0 : options.sortDir;
6905
+ const recurrence = options == null ? void 0 : options.recurrence;
6605
6906
  const queryKeyScope = (_d = options == null ? void 0 : options.queryKeyScope) != null ? _d : "events";
6606
6907
  const minYesPrice = options == null ? void 0 : options.minYesPrice;
6607
6908
  const maxYesPrice = options == null ? void 0 : options.maxYesPrice;
6608
6909
  const endDateFrom = options == null ? void 0 : options.endDateFrom;
6609
6910
  const initialPages = options == null ? void 0 : options.initialPages;
6610
- (0, import_react35.useEffect)(() => {
6911
+ (0, import_react36.useEffect)(() => {
6611
6912
  if (queryClient) return void 0;
6612
6913
  fallbackQueryClient.mount();
6613
6914
  return () => {
@@ -6617,7 +6918,7 @@ function useVenueEvents(options) {
6617
6918
  if (enabled && !client) {
6618
6919
  throw new Error("useVenueEvents must be used within an <AggProvider>");
6619
6920
  }
6620
- const query = (0, import_react_query34.useInfiniteQuery)(
6921
+ const query = (0, import_react_query35.useInfiniteQuery)(
6621
6922
  {
6622
6923
  queryKey: [
6623
6924
  queryKeyScope,
@@ -6628,6 +6929,7 @@ function useVenueEvents(options) {
6628
6929
  (_g = status == null ? void 0 : status.join(",")) != null ? _g : "",
6629
6930
  sortBy != null ? sortBy : "",
6630
6931
  sortDir != null ? sortDir : "",
6932
+ recurrence != null ? recurrence : "",
6631
6933
  minYesPrice != null ? minYesPrice : "",
6632
6934
  maxYesPrice != null ? maxYesPrice : "",
6633
6935
  endDateFrom != null ? endDateFrom : "",
@@ -6645,6 +6947,7 @@ function useVenueEvents(options) {
6645
6947
  status,
6646
6948
  sortBy,
6647
6949
  sortDir,
6950
+ recurrence,
6648
6951
  limit,
6649
6952
  minYesPrice,
6650
6953
  maxYesPrice,
@@ -6660,13 +6963,13 @@ function useVenueEvents(options) {
6660
6963
  return (_a2 = lastPage.nextCursor) != null ? _a2 : void 0;
6661
6964
  },
6662
6965
  // TODO: RMIK - Comment out to show skeletons on category switch
6663
- placeholderData: import_react_query34.keepPreviousData,
6966
+ placeholderData: import_react_query35.keepPreviousData,
6664
6967
  enabled: enabled && !!client
6665
6968
  },
6666
6969
  queryClient != null ? queryClient : fallbackQueryClient
6667
6970
  );
6668
- const prefetchedRef = (0, import_react35.useRef)(false);
6669
- (0, import_react35.useEffect)(() => {
6971
+ const prefetchedRef = (0, import_react36.useRef)(false);
6972
+ (0, import_react36.useEffect)(() => {
6670
6973
  var _a2, _b2;
6671
6974
  if (prefetchedRef.current) return;
6672
6975
  if (!initialPages || initialPages <= 1) return;
@@ -6684,7 +6987,7 @@ function useVenueEvents(options) {
6684
6987
  query.hasNextPage,
6685
6988
  query.fetchNextPage
6686
6989
  ]);
6687
- const events = (0, import_react35.useMemo)(
6990
+ const events = (0, import_react36.useMemo)(
6688
6991
  () => {
6689
6992
  var _a2, _b2;
6690
6993
  return (_b2 = (_a2 = query.data) == null ? void 0 : _a2.pages.flatMap((page) => page.data)) != null ? _b2 : [];
@@ -6702,7 +7005,7 @@ function useVenueEvents(options) {
6702
7005
  }
6703
7006
 
6704
7007
  // src/use-venue-market-midpoints.ts
6705
- var import_react_query35 = require("@tanstack/react-query");
7008
+ var import_react_query36 = require("@tanstack/react-query");
6706
7009
  var MAX_VENUE_MARKET_IDS_PER_REQUEST = 200;
6707
7010
  var normalizeVenueMarketIds2 = (venueMarketIds) => {
6708
7011
  return [
@@ -6738,7 +7041,7 @@ function useVenueMarketMidpoints(options) {
6738
7041
  const client = useAggClient();
6739
7042
  const enabled = (_a = options.enabled) != null ? _a : true;
6740
7043
  const requestedVenueMarketIds = normalizeVenueMarketIds2(options.venueMarketIds);
6741
- const query = (0, import_react_query35.useQuery)({
7044
+ const query = (0, import_react_query36.useQuery)({
6742
7045
  queryKey: requestedVenueMarketIds.length ? ["venue-market-midpoints", requestedVenueMarketIds] : ["venue-market-midpoints", "__disabled__"],
6743
7046
  queryFn: (_0) => __async(null, [_0], function* ({ signal }) {
6744
7047
  const venueMarketIdChunks = chunkVenueMarketIds(requestedVenueMarketIds);
@@ -6757,7 +7060,7 @@ function useVenueMarketMidpoints(options) {
6757
7060
  gcTime: 5 * 6e4,
6758
7061
  refetchOnWindowFocus: false,
6759
7062
  retry: 1,
6760
- placeholderData: import_react_query35.keepPreviousData
7063
+ placeholderData: import_react_query36.keepPreviousData
6761
7064
  });
6762
7065
  const midpointRows = (_c = (_b = query.data) == null ? void 0 : _b.data) != null ? _c : [];
6763
7066
  const midpointsByVenueMarketId = mapMidpointsByVenueMarketId(midpointRows);
@@ -6770,29 +7073,52 @@ function useVenueMarketMidpoints(options) {
6770
7073
 
6771
7074
  // src/utils/compute-price-gaps.ts
6772
7075
  var MIN_PRICE_GAP_PCT = 3;
6773
- function computePriceGaps(input) {
7076
+ var MAX_PRICE_GAP_PCT = 50;
7077
+ var normalizeMidpoint = (value) => {
7078
+ if (typeof value !== "number" || !Number.isFinite(value)) return void 0;
7079
+ if (value <= 0) return void 0;
7080
+ if (value > 1) return void 0;
7081
+ return value;
7082
+ };
7083
+ var collectMarketMidpoints = (market, midpointsByVenueMarketId) => {
6774
7084
  var _a;
6775
- const { markets, midpointsByVenueMarketId } = input;
6776
- const result = /* @__PURE__ */ new Map();
7085
+ const midpoints = [];
7086
+ const marketMidpoint = normalizeMidpoint(midpointsByVenueMarketId.get(market.id));
7087
+ if (marketMidpoint != null) {
7088
+ midpoints.push(marketMidpoint);
7089
+ }
7090
+ for (const matchedMarket of (_a = market.matchedVenueMarkets) != null ? _a : []) {
7091
+ const matchedMidpoint = normalizeMidpoint(midpointsByVenueMarketId.get(matchedMarket.id));
7092
+ if (matchedMidpoint == null) continue;
7093
+ midpoints.push(matchedMidpoint);
7094
+ }
7095
+ return midpoints;
7096
+ };
7097
+ var computePriceGapPct = (midpoints) => {
7098
+ if (midpoints.length < 2) return void 0;
7099
+ const minMidpoint = Math.min(...midpoints);
7100
+ const maxMidpoint = Math.max(...midpoints);
7101
+ if (minMidpoint <= 0 || maxMidpoint <= minMidpoint) return void 0;
7102
+ const gapPct = (maxMidpoint - minMidpoint) * 100;
7103
+ if (gapPct < MIN_PRICE_GAP_PCT) return void 0;
7104
+ if (gapPct > MAX_PRICE_GAP_PCT) return void 0;
7105
+ return gapPct;
7106
+ };
7107
+ var computePriceGaps = ({
7108
+ markets,
7109
+ midpointsByVenueMarketId
7110
+ }) => {
7111
+ const gapsByVenueMarketId = /* @__PURE__ */ new Map();
6777
7112
  for (const market of markets) {
6778
- const ownMidpoint = midpointsByVenueMarketId.get(market.id);
6779
- if (ownMidpoint == null || ownMidpoint <= 0) continue;
6780
- const siblings = (_a = market.matchedVenueMarkets) != null ? _a : [];
6781
- if (siblings.length === 0) continue;
6782
- let maxGap = 0;
6783
- for (const sibling of siblings) {
6784
- const siblingMidpoint = midpointsByVenueMarketId.get(sibling.id);
6785
- if (siblingMidpoint == null || siblingMidpoint <= 0) continue;
6786
- const gap = Math.abs(ownMidpoint - siblingMidpoint) / ownMidpoint * 100;
6787
- if (gap > maxGap) maxGap = gap;
6788
- }
6789
- if (maxGap >= MIN_PRICE_GAP_PCT) result.set(market.id, maxGap);
7113
+ const gapPct = computePriceGapPct(collectMarketMidpoints(market, midpointsByVenueMarketId));
7114
+ if (gapPct == null) continue;
7115
+ gapsByVenueMarketId.set(market.id, gapPct);
6790
7116
  }
6791
- return result;
6792
- }
7117
+ return gapsByVenueMarketId;
7118
+ };
6793
7119
 
6794
7120
  // src/use-viewport-midpoints.ts
6795
- var import_react36 = require("react");
7121
+ var import_react37 = require("react");
6796
7122
  var buildOutcomeMidpointMap = (outcomes) => {
6797
7123
  const m = /* @__PURE__ */ new Map();
6798
7124
  if (!outcomes) return m;
@@ -6840,15 +7166,15 @@ var buildCachedMidpointEntries = (requestedVenueMarketIds, rows) => {
6840
7166
  };
6841
7167
  function useViewportMidpoints(visibleMarkets) {
6842
7168
  const client = useAggClient();
6843
- const [cache, setCache] = (0, import_react36.useState)(() => /* @__PURE__ */ new Map());
6844
- const inFlightRef = (0, import_react36.useRef)(/* @__PURE__ */ new Set());
6845
- const visibleRef = (0, import_react36.useRef)(visibleMarkets);
7169
+ const [cache, setCache] = (0, import_react37.useState)(() => /* @__PURE__ */ new Map());
7170
+ const inFlightRef = (0, import_react37.useRef)(/* @__PURE__ */ new Set());
7171
+ const visibleRef = (0, import_react37.useRef)(visibleMarkets);
6846
7172
  visibleRef.current = visibleMarkets;
6847
- const visibleFp = (0, import_react36.useMemo)(
7173
+ const visibleFp = (0, import_react37.useMemo)(
6848
7174
  () => [...new Set(visibleMarkets.map((m) => m.id))].sort().join("|"),
6849
7175
  [visibleMarkets]
6850
7176
  );
6851
- (0, import_react36.useEffect)(() => {
7177
+ (0, import_react37.useEffect)(() => {
6852
7178
  const toFetch = resolveUncachedVisibleMarketIds(visibleRef.current, cache, inFlightRef.current);
6853
7179
  if (!toFetch.length) return;
6854
7180
  let cancelled = false;
@@ -6872,7 +7198,7 @@ function useViewportMidpoints(visibleMarkets) {
6872
7198
  cancelled = true;
6873
7199
  };
6874
7200
  }, [visibleFp, cache]);
6875
- const { prices, venueByOutcomeId } = (0, import_react36.useMemo)(() => {
7201
+ const { prices, venueByOutcomeId } = (0, import_react37.useMemo)(() => {
6876
7202
  var _a, _b, _c, _d;
6877
7203
  const map = /* @__PURE__ */ new Map();
6878
7204
  const venueMap = /* @__PURE__ */ new Map();
@@ -6905,15 +7231,15 @@ function useViewportMidpoints(visibleMarkets) {
6905
7231
  }
6906
7232
 
6907
7233
  // src/use-visible-ids.ts
6908
- var import_react37 = require("react");
7234
+ var import_react38 = require("react");
6909
7235
  function useVisibleIds(options = {}) {
6910
7236
  const { rootMargin = "0px", threshold = 0 } = options;
6911
- const [visibleIds, setVisibleIds] = (0, import_react37.useState)(() => /* @__PURE__ */ new Set());
6912
- const observerRef = (0, import_react37.useRef)(null);
6913
- const elementsRef = (0, import_react37.useRef)(/* @__PURE__ */ new Map());
6914
- const elementIdRef = (0, import_react37.useRef)(/* @__PURE__ */ new WeakMap());
6915
- const callbackRefsRef = (0, import_react37.useRef)(/* @__PURE__ */ new Map());
6916
- (0, import_react37.useEffect)(() => {
7237
+ const [visibleIds, setVisibleIds] = (0, import_react38.useState)(() => /* @__PURE__ */ new Set());
7238
+ const observerRef = (0, import_react38.useRef)(null);
7239
+ const elementsRef = (0, import_react38.useRef)(/* @__PURE__ */ new Map());
7240
+ const elementIdRef = (0, import_react38.useRef)(/* @__PURE__ */ new WeakMap());
7241
+ const callbackRefsRef = (0, import_react38.useRef)(/* @__PURE__ */ new Map());
7242
+ (0, import_react38.useEffect)(() => {
6917
7243
  if (typeof IntersectionObserver === "undefined") return;
6918
7244
  const observer = new IntersectionObserver(
6919
7245
  (entries) => {
@@ -6945,7 +7271,7 @@ function useVisibleIds(options = {}) {
6945
7271
  observerRef.current = null;
6946
7272
  };
6947
7273
  }, [rootMargin, threshold]);
6948
- const register = (0, import_react37.useCallback)((id) => {
7274
+ const register = (0, import_react38.useCallback)((id) => {
6949
7275
  const existing = callbackRefsRef.current.get(id);
6950
7276
  if (existing) return existing;
6951
7277
  const callback = (el) => {
@@ -6978,16 +7304,38 @@ function useVisibleIds(options = {}) {
6978
7304
  }
6979
7305
 
6980
7306
  // src/use-app-config.ts
6981
- var import_react_query36 = require("@tanstack/react-query");
7307
+ var import_react_query37 = require("@tanstack/react-query");
6982
7308
  var FIVE_MINUTES = 5 * 60 * 1e3;
7309
+ var APP_CONFIG_QUERY_KEY = ["agg", "app-config"];
6983
7310
  function useAppConfig() {
6984
- var _a, _b, _c, _d, _e, _f, _g, _h;
6985
7311
  const client = useAggClient();
6986
- const query = (0, import_react_query36.useQuery)({
6987
- queryKey: ["agg", "app-config"],
7312
+ const query = (0, import_react_query37.useQuery)({
7313
+ queryKey: APP_CONFIG_QUERY_KEY,
6988
7314
  queryFn: () => client.getAppConfig(),
6989
7315
  staleTime: FIVE_MINUTES
6990
7316
  });
7317
+ return toAppConfigResult({
7318
+ data: query.data,
7319
+ isLoading: query.isLoading,
7320
+ error: query.error
7321
+ });
7322
+ }
7323
+ function useCachedAppConfig() {
7324
+ const queryClient = (0, import_react_query37.useQueryClient)();
7325
+ const query = (0, import_react_query37.useQuery)({
7326
+ queryKey: APP_CONFIG_QUERY_KEY,
7327
+ enabled: false,
7328
+ initialData: () => queryClient.getQueryData(APP_CONFIG_QUERY_KEY),
7329
+ staleTime: FIVE_MINUTES
7330
+ });
7331
+ return toAppConfigResult({
7332
+ data: query.data,
7333
+ isLoading: query.isLoading,
7334
+ error: query.error
7335
+ });
7336
+ }
7337
+ var toAppConfigResult = (query) => {
7338
+ var _a, _b, _c, _d, _e, _f, _g, _h;
6991
7339
  return {
6992
7340
  disabledVenues: (_b = (_a = query.data) == null ? void 0 : _a.disabledVenues) != null ? _b : [],
6993
7341
  disabledCategoryPresets: (_d = (_c = query.data) == null ? void 0 : _c.disabledCategoryPresets) != null ? _d : [],
@@ -6996,7 +7344,7 @@ function useAppConfig() {
6996
7344
  isLoading: query.isLoading,
6997
7345
  error: query.error
6998
7346
  };
6999
- }
7347
+ };
7000
7348
  // Annotate the CommonJS export names for ESM import in node:
7001
7349
  0 && (module.exports = {
7002
7350
  AUTH_CHOOSER_OPEN_EVENT,
@@ -7008,6 +7356,8 @@ function useAppConfig() {
7008
7356
  CONFIRMED_MATCH_STATUSES,
7009
7357
  DEFAULT_AGG_ROOT_CLASS_NAME,
7010
7358
  EventListStateProvider,
7359
+ MAX_PRICE_GAP_PCT,
7360
+ MIN_PRICE_GAP_PCT,
7011
7361
  MarketStatus,
7012
7362
  MatchStatus,
7013
7363
  MatchType,
@@ -7026,12 +7376,18 @@ function useAppConfig() {
7026
7376
  getBuilder,
7027
7377
  getDepositAddress,
7028
7378
  getOrCreateBuilder,
7379
+ getVenueAvailabilityState,
7380
+ getVisibleVenueIdsByConfig,
7381
+ getVisibleVenuesByConfig,
7029
7382
  getWalletAddressFromUserProfile,
7030
7383
  invalidateBalanceQueries,
7031
7384
  invalidatePositionQueries,
7032
7385
  invalidateUserActivityQueries,
7386
+ invalidateUserClaimState,
7033
7387
  invalidateUserMoneyState,
7388
+ isVenueDisabledByConfig,
7034
7389
  mergeBestPricesPreferringLive,
7390
+ normalizeVenueId,
7035
7391
  optimizedImageUrl,
7036
7392
  parseEmail,
7037
7393
  parseEmailStrict,
@@ -7059,7 +7415,10 @@ function useAppConfig() {
7059
7415
  useAggUiConfig,
7060
7416
  useAggWebSocket,
7061
7417
  useAppConfig,
7418
+ useArbFeed,
7419
+ useCachedAppConfig,
7062
7420
  useCategories,
7421
+ useCategoryChildren,
7063
7422
  useDebouncedValue,
7064
7423
  useDepositAddresses,
7065
7424
  useEnrichedVenueEvent,
@@ -7082,14 +7441,17 @@ function useAppConfig() {
7082
7441
  useLiveOutcomePrices,
7083
7442
  useLiveTrades,
7084
7443
  useManagedBalances,
7444
+ useMarketArb,
7085
7445
  useMarketChart,
7086
7446
  useMarketOrderbook,
7087
7447
  useMarketSearch,
7088
7448
  useMidpoints,
7089
7449
  useOnBalanceUpdate,
7450
+ useOnOrderEvent,
7090
7451
  useOnOrderSubmitted,
7091
7452
  useOnRedeemEvent,
7092
7453
  useOnWithdrawalLifecycle,
7454
+ useOptionalAggClient,
7093
7455
  useOrderBook,
7094
7456
  useOrderbookQuote,
7095
7457
  useOrders,