@agg-build/hooks 1.2.0 → 1.2.12

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
@@ -82,8 +82,10 @@ __export(src_exports, {
82
82
  MarketStatus: () => MarketStatus,
83
83
  MatchStatus: () => MatchStatus,
84
84
  MatchType: () => MatchType,
85
- QueryClient: () => import_react_query36.QueryClient,
86
- QueryClientProvider: () => import_react_query36.QueryClientProvider,
85
+ QueryClient: () => import_react_query37.QueryClient,
86
+ QueryClientProvider: () => import_react_query37.QueryClientProvider,
87
+ RedeemRejectedError: () => RedeemRejectedError,
88
+ TradeSide: () => TradeSide,
87
89
  TurnstileChallengeError: () => import_sdk4.TurnstileChallengeError,
88
90
  Venue: () => Venue,
89
91
  computeClosedPositionTotals: () => computeClosedPositionTotals,
@@ -98,9 +100,13 @@ __export(src_exports, {
98
100
  getWalletAddressFromUserProfile: () => getWalletAddressFromUserProfile,
99
101
  invalidateBalanceQueries: () => invalidateBalanceQueries,
100
102
  invalidatePositionQueries: () => invalidatePositionQueries,
103
+ invalidateUserActivityQueries: () => invalidateUserActivityQueries,
104
+ invalidateUserMoneyState: () => invalidateUserMoneyState,
105
+ mergeBestPricesPreferringLive: () => mergeBestPricesPreferringLive,
101
106
  optimizedImageUrl: () => optimizedImageUrl,
102
107
  parseEmail: () => parseEmail,
103
108
  parseEmailStrict: () => parseEmailStrict,
109
+ rangeToSeconds: () => rangeToSeconds,
104
110
  requestAggAuthChooserOpen: () => requestAggAuthChooserOpen,
105
111
  resolveAggUiLabels: () => resolveAggUiLabels,
106
112
  resolveDefaultTradingMarket: () => resolveDefaultMarket,
@@ -108,6 +114,7 @@ __export(src_exports, {
108
114
  resolveMarketTradingState: () => resolveMarketTradingState,
109
115
  resolveMarketWinningOutcome: () => resolveMarketWinningOutcome,
110
116
  resolveOrderEligibility: () => resolveOrderEligibility,
117
+ resolveRollingWindow: () => resolveRollingWindow,
111
118
  resolveTradingStateKind: () => resolveTradingStateKind,
112
119
  sortVenues: () => sortVenues,
113
120
  timeRangeToInterval: () => timeRangeToInterval,
@@ -138,6 +145,7 @@ __export(src_exports, {
138
145
  useGeoBlock: () => useGeoBlock,
139
146
  useLabels: () => useLabels,
140
147
  useLinkAccount: () => useLinkAccount,
148
+ useLiveBestPrices: () => useLiveBestPrices,
141
149
  useLiveCandleOverlay: () => useLiveCandleOverlay,
142
150
  useLiveCandles: () => useLiveCandles,
143
151
  useLiveMarket: () => useLiveMarket,
@@ -147,26 +155,33 @@ __export(src_exports, {
147
155
  useManagedBalances: () => useManagedBalances,
148
156
  useMarketChart: () => useMarketChart,
149
157
  useMarketOrderbook: () => useMarketOrderbook,
158
+ useMarketSearch: () => useMarketSearch,
150
159
  useMidpoints: () => useMidpoints,
151
160
  useOnBalanceUpdate: () => useOnBalanceUpdate,
161
+ useOnOrderEvent: () => useOnOrderEvent,
152
162
  useOnOrderSubmitted: () => useOnOrderSubmitted,
153
163
  useOnRedeemEvent: () => useOnRedeemEvent2,
154
164
  useOnWithdrawalLifecycle: () => useOnWithdrawalLifecycle,
165
+ useOptionalAggClient: () => useOptionalAggClient,
155
166
  useOrderBook: () => useOrderBook,
156
167
  useOrderbookQuote: () => useOrderbookQuote,
157
168
  useOrders: () => useOrders,
158
169
  usePositions: () => usePositions,
159
- useQueryClient: () => import_react_query36.useQueryClient,
170
+ useQueryClient: () => import_react_query37.useQueryClient,
160
171
  useQuoteManaged: () => useQuoteManaged,
161
172
  useRampQuotes: () => useRampQuotes,
162
173
  useRampSession: () => useRampSession,
163
174
  useRedeem: () => useRedeem,
164
175
  useRedeemEligibleCount: () => useRedeemEligibleCount,
176
+ useRedeemLifecycle: () => useRedeemLifecycle,
177
+ useRedeemLifecycles: () => useRedeemLifecycles,
178
+ useRollingChartWindow: () => useRollingChartWindow,
165
179
  useSdkLabels: () => useSdkLabels,
166
180
  useSdkUiConfig: () => useSdkUiConfig,
167
181
  useSearch: () => useSearch,
168
182
  useSmartRoute: () => useSmartRoute,
169
183
  useSyncBalances: () => useSyncBalances,
184
+ useTradableVenues: () => useTradableVenues,
170
185
  useUserActivity: () => useUserActivity,
171
186
  useUserHoldings: () => useUserHoldings,
172
187
  useVenueEvent: () => useVenueEvent,
@@ -175,9 +190,11 @@ __export(src_exports, {
175
190
  useVenueMarkets: () => useVenueMarkets,
176
191
  useViewportMidpoints: () => useViewportMidpoints,
177
192
  useVisibleIds: () => useVisibleIds,
193
+ useWithdrawEstimate: () => useWithdrawEstimate,
178
194
  useWithdrawFlow: () => useWithdrawFlow,
179
195
  useWithdrawManaged: () => useWithdrawManaged,
180
- useWithdrawalLifecycle: () => useWithdrawalLifecycle
196
+ useWithdrawalLifecycle: () => useWithdrawalLifecycle,
197
+ userActivityQueryKeys: () => userActivityQueryKeys
181
198
  });
182
199
  module.exports = __toCommonJS(src_exports);
183
200
 
@@ -303,7 +320,7 @@ var getVenueOrder = (venue) => {
303
320
  var sortVenues = (venues) => [...venues].sort((a, b) => getVenueOrder(a) - getVenueOrder(b));
304
321
 
305
322
  // src/index.ts
306
- var import_react_query36 = require("@tanstack/react-query");
323
+ var import_react_query37 = require("@tanstack/react-query");
307
324
 
308
325
  // src/candle-store.ts
309
326
  var import_sdk = require("@agg-build/sdk");
@@ -437,7 +454,7 @@ var createAuthCallbackSession = (tokens) => {
437
454
  };
438
455
  };
439
456
  var executeWalletAuthFlow = (input) => __async(null, null, function* () {
440
- var _a, _b;
457
+ var _a, _b, _c, _d;
441
458
  const address = input.options.address.trim();
442
459
  const chain = (_a = input.options.chain) != null ? _a : "ethereum";
443
460
  const provider = chain === "solana" ? "siws" : "siwe";
@@ -460,14 +477,14 @@ var executeWalletAuthFlow = (input) => __async(null, null, function* () {
460
477
  uri: location.uri,
461
478
  nonce: startResult.nonce,
462
479
  chainId: typeof input.options.chainId === "string" ? input.options.chainId : "mainnet",
463
- statement: input.options.statement
480
+ statement: (_c = startResult.statement) != null ? _c : input.options.statement
464
481
  }) : input.client.buildSiweMessage({
465
482
  domain: location.domain,
466
483
  address,
467
484
  uri: location.uri,
468
485
  nonce: startResult.nonce,
469
486
  chainId: typeof input.options.chainId === "number" ? input.options.chainId : void 0,
470
- statement: input.options.statement
487
+ statement: (_d = startResult.statement) != null ? _d : input.options.statement
471
488
  });
472
489
  const signature = yield input.options.signMessage(message);
473
490
  const result = yield input.client.verify({ message, signature });
@@ -648,6 +665,12 @@ var enUsLabels = {
648
665
  max: "Max",
649
666
  tokenLabel: "Receive token",
650
667
  networkLabel: "Receive network",
668
+ estimatedFees: "Est. fees",
669
+ networkReserve: "Network reserve",
670
+ networkReserveTooltipAria: "Network reserve details",
671
+ networkReserveTooltipLineOne: "This reserve helps cover network and bridge costs.",
672
+ networkReserveTooltipLineTwo: "Any unused amount stays in your balance.",
673
+ youReceive: "You'll receive",
651
674
  confirm: "Confirm withdrawal",
652
675
  successTitle: "Withdrawal submitted",
653
676
  successDescription: (tokenSymbol) => `Your ${tokenSymbol} withdrawal is being processed and will arrive shortly.`,
@@ -656,12 +679,16 @@ var enUsLabels = {
656
679
  // terminal status — otherwise a finished withdrawal would keep showing
657
680
  // "submitted / processing" forever and force the user to hard-refresh.
658
681
  successTitleCompleted: "Withdrawal complete",
659
- successDescriptionCompleted: (tokenSymbol) => `Your ${tokenSymbol} withdrawal has been delivered.`,
682
+ successDescriptionCompleted: (tokenSymbol) => `Your ${tokenSymbol} has been successfully sent to your wallet.`,
660
683
  successTitlePartial: "Withdrawal partially completed",
661
- successDescriptionPartial: (tokenSymbol) => `Some legs of your ${tokenSymbol} withdrawal completed; see details below.`,
684
+ successDescriptionPartial: () => "Part of your withdrawal was completed successfully, but the remaining funds failed to transfer and were returned to your balance.",
662
685
  successTitleFailed: "Withdrawal failed",
663
- successDescriptionFailed: (tokenSymbol) => `Your ${tokenSymbol} withdrawal could not be completed.`,
686
+ successDescriptionFailed: () => "We couldn't complete your withdrawal. Your funds were returned to your balance.",
687
+ retry: "Try Again",
688
+ close: "Close",
689
+ loadingDescription: "This may take a few minutes. You can safely close this window and check the status later in your activity.",
664
690
  summary: {
691
+ requestedWithdrawal: "Requested withdrawal",
665
692
  // The response is `pricingStatus: "unquoted"` — we don't know net
666
693
  // output until on-chain settlement. Calling this "Amount received"
667
694
  // would imply receipt before the lifecycle has confirmed. Keep it
@@ -679,6 +706,12 @@ var enUsLabels = {
679
706
  completed: "Withdrawal complete.",
680
707
  partial: "Withdrawal partially completed \u2014 see details below.",
681
708
  failed: "Withdrawal failed.",
709
+ loadingSteps: {
710
+ preparing: "Preparing funds",
711
+ bridging: "Bridging between networks",
712
+ sending: "Sending to your wallet",
713
+ confirming: "Waiting for network confirmation"
714
+ },
682
715
  steps: {
683
716
  bridge: (sourceChainName, destChainName) => `Bridging from ${sourceChainName} to ${destChainName}`,
684
717
  transfer: (destChainName) => `Transferring on ${destChainName}`
@@ -734,10 +767,37 @@ var enUsLabels = {
734
767
  externalWallet: "Deposit from external wallet",
735
768
  card: "Deposit with card"
736
769
  },
770
+ depositStatusTitles: {
771
+ connectedWallet: {
772
+ pending: "Processing deposit from connected wallet",
773
+ completed: "Successful deposit from connected wallet",
774
+ failed: "Failed deposit from connected wallet",
775
+ canceled: "Canceled deposit from connected wallet"
776
+ },
777
+ externalWallet: {
778
+ pending: "Processing deposit from external wallet",
779
+ completed: "Successful deposit from external wallet",
780
+ failed: "Failed deposit from external wallet",
781
+ canceled: "Canceled deposit from external wallet"
782
+ },
783
+ card: {
784
+ pending: "Processing deposit with card",
785
+ completed: "Successful deposit with card",
786
+ failed: "Failed deposit with card",
787
+ canceled: "Canceled deposit with card"
788
+ }
789
+ },
790
+ withdrawalStatusTitles: {
791
+ pending: "Processing withdrawal",
792
+ completed: "Successful withdrawal",
793
+ failed: "Failed withdrawal",
794
+ canceled: "Canceled withdrawal"
795
+ },
737
796
  // Activity-row title for any withdrawal regardless of lifecycle
738
- // state (pending / completed / failed) — render the asset rather
739
- // than implying success. The ActivityRow renders a separate status
740
- // chip when the row is failed.
797
+ // state — render the asset rather than implying success. The
798
+ // ActivityRow renders a separate status chip when the row is
799
+ // failed. Retained for partner overrides that still want a
800
+ // status-agnostic title.
741
801
  withdrawalTitle: (tokenSymbol) => `Withdraw ${tokenSymbol}`
742
802
  },
743
803
  positions: {
@@ -772,6 +832,15 @@ var enUsLabels = {
772
832
  eventList: {
773
833
  matchedTab: "Matched",
774
834
  allTab: "All",
835
+ sortByLabel: "Sort by",
836
+ sortBy24hVolume: "24h volume",
837
+ sortByTopArbitrage: "Top arbitrage",
838
+ sortByTotalVolume: "Total volume",
839
+ sortByEndingSoon: "Ending soon",
840
+ subcategoriesLabel: "Subcategories",
841
+ subcategoriesAll: "All",
842
+ subcategoriesOpenAria: "Open subcategories",
843
+ subcategoriesCloseAria: "Close subcategories",
775
844
  loading: (title) => `Loading ${title}`,
776
845
  tabsAria: (title) => `${title} tabs`,
777
846
  emptyAria: "No events found",
@@ -958,6 +1027,19 @@ var enUsLabels = {
958
1027
  noMarketSelected: "Select a market to place an order.",
959
1028
  noOrderbooks: "No live orderbooks are available for this market right now.",
960
1029
  quoteUnavailable: "Quote temporarily unavailable. Please try again.",
1030
+ quoteBalanceMismatch: "Quote balance mismatch. Try a different amount.",
1031
+ serviceTemporarilyUnavailable: "Service temporarily unavailable. Please try again in a moment.",
1032
+ orderDeadlineExpiredBeforeSubmission: "Order deadline expired before submission. Please try again.",
1033
+ 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.",
1034
+ 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.",
1035
+ venueMinOrderSize: "Order size is below the venue minimum. Try a larger amount.",
1036
+ sourceBalanceChanged: "Your balance changed since the quote. Refresh and try again, or pick a smaller amount.",
1037
+ venueMarketResolved: "This market just resolved. Pick a different market or wait for the next round.",
1038
+ 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.",
1039
+ venueNoQuotePath: "No active quote path for this market right now. Try a different size, or wait a moment and re-quote.",
1040
+ solanaBlockhashExpired: "Solana transaction expired before submission. Please re-quote and try again.",
1041
+ venueRateLimited: "The venue is rate-limiting requests right now. Please wait a moment and try again.",
1042
+ 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.",
961
1043
  selectedVenueUnavailable: "The venue you selected is no longer available on this route. Review the updated options and try again.",
962
1044
  engineUnavailable: "The routing engine is temporarily unavailable. Please try again in a moment.",
963
1045
  insufficientInputAmount: "Trade amount is too small to cover bridging and execution costs. Increase your spend or deposit funds on the destination chain.",
@@ -971,6 +1053,7 @@ var enUsLabels = {
971
1053
  deposit: "Deposit",
972
1054
  kycRequired: "Verify to trade Kalshi",
973
1055
  kycNotVerifiedTooltip: "You have not been verified yet",
1056
+ kycVerify: "Verify Identity",
974
1057
  kycVerifyModalTitle: "Verify Your Identity",
975
1058
  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.",
976
1059
  kycStartVerification: "Start Verification",
@@ -984,6 +1067,7 @@ var enUsLabels = {
984
1067
  splitOrderDescription: "We split your order for the best price:",
985
1068
  viewAllRoutes: (count) => `View all (${count})`,
986
1069
  venueUnavailableInRegion: "Unavailable in your region",
1070
+ verified: "Verified",
987
1071
  platformFee: "0% platform fees",
988
1072
  estimatedFees: "Estimated fees",
989
1073
  estimatedFeesTooltipAria: "Estimated fees breakdown",
@@ -995,6 +1079,7 @@ var enUsLabels = {
995
1079
  buyingOutcome: (label) => `Buying ${label}`,
996
1080
  sellingOutcome: (label) => `Selling ${label}`,
997
1081
  findingBestRoute: "Finding the best route...",
1082
+ checkingBalance: "Checking balance",
998
1083
  submittingOrderProgress: "Submitting order...",
999
1084
  orderSubmittedProgress: (orderId) => `Order #${orderId.replace(/^#/, "")} submitted`,
1000
1085
  executingOnVenue: (venueLabel) => `Executing on ${venueLabel}...`,
@@ -1174,6 +1259,57 @@ var enUsLabels = {
1174
1259
  header: {
1175
1260
  bannerAria: "Site header",
1176
1261
  logoAria: "Home"
1262
+ },
1263
+ notifications: {
1264
+ order: {
1265
+ filledTitle: "Order filled",
1266
+ filledMessage: ({ venueLabel, sideLabel, amountLabel, priceLabel }) => {
1267
+ const action = sideLabel ? `${sideLabel} filled` : "Filled";
1268
+ const amount = amountLabel ? ` ${amountLabel}` : "";
1269
+ const price = priceLabel ? ` at ${priceLabel}` : "";
1270
+ const venue = venueLabel ? ` on ${venueLabel}` : "";
1271
+ return `${action}${amount}${price}${venue}`.trim();
1272
+ },
1273
+ partialFilledTitle: "Order partially filled",
1274
+ partialFilledMessage: ({ venueLabel, sideLabel, amountLabel, priceLabel }) => {
1275
+ const action = sideLabel ? `${sideLabel} partially filled` : "Partially filled";
1276
+ const amount = amountLabel ? ` ${amountLabel}` : "";
1277
+ const price = priceLabel ? ` at ${priceLabel}` : "";
1278
+ const venue = venueLabel ? ` on ${venueLabel}` : "";
1279
+ return `${action}${amount}${price}${venue}`.trim();
1280
+ },
1281
+ failedTitle: "Order failed",
1282
+ failedMessage: (errorReason) => errorReason && errorReason.length > 0 ? errorReason : "Your order could not be completed. Please try again."
1283
+ },
1284
+ deposit: {
1285
+ completedTitle: "Deposit complete",
1286
+ completedMessage: ({ amountLabel, tokenLabel }) => {
1287
+ if (amountLabel && tokenLabel) return `${amountLabel} ${tokenLabel} added to your balance.`;
1288
+ if (tokenLabel) return `Your ${tokenLabel} has been added to your balance.`;
1289
+ return "Your funds have been added to your balance.";
1290
+ },
1291
+ failedTitle: "Deposit failed",
1292
+ failedMessage: ({ amountLabel, tokenLabel }) => {
1293
+ const what = amountLabel && tokenLabel ? `${amountLabel} ${tokenLabel}` : "deposit";
1294
+ return `We couldn't complete your ${what}.`;
1295
+ }
1296
+ },
1297
+ withdrawal: {
1298
+ completedTitle: "Withdrawal complete",
1299
+ completedMessage: ({ amountLabel, tokenLabel }) => {
1300
+ if (amountLabel && tokenLabel) return `${amountLabel} ${tokenLabel} sent to your wallet.`;
1301
+ if (tokenLabel) return `Your ${tokenLabel} has been sent to your wallet.`;
1302
+ return "Your withdrawal has been sent to your wallet.";
1303
+ },
1304
+ partialTitle: "Withdrawal partially completed",
1305
+ partialMessage: ({ amountLabel, tokenLabel }) => {
1306
+ if (amountLabel && tokenLabel)
1307
+ return `Part of your ${tokenLabel} was sent. The remainder was returned to your balance.`;
1308
+ return "Part of your withdrawal was sent. The remainder was returned to your balance.";
1309
+ },
1310
+ failedTitle: "Withdrawal failed",
1311
+ failedMessage: (errorReason) => errorReason && errorReason.length > 0 ? errorReason : "Your funds have been returned to your balance."
1312
+ }
1177
1313
  }
1178
1314
  };
1179
1315
  var defaultAggUiLabelsByLocale = {
@@ -1253,6 +1389,7 @@ var defaultAggUiSearchConfig = {
1253
1389
  var defaultAggUiConfig = {
1254
1390
  enableLogs: false,
1255
1391
  enableWebsocketsLogs: false,
1392
+ enableDebug: false,
1256
1393
  general: {
1257
1394
  locale: DEFAULT_LOCALE,
1258
1395
  theme: "light",
@@ -1263,7 +1400,9 @@ var defaultAggUiConfig = {
1263
1400
  enableAnimations: true,
1264
1401
  enableLiveUpdates: true,
1265
1402
  showFeesBreakdown: false,
1266
- enableGradients: false
1403
+ enableGradients: false,
1404
+ enableVenueEventDiscoveryFilters: false,
1405
+ enableNotifications: true
1267
1406
  },
1268
1407
  market: {
1269
1408
  arbitrageThreshold: 0
@@ -1290,7 +1429,7 @@ var mergeAggUiSearchConfig = (config) => {
1290
1429
  };
1291
1430
  };
1292
1431
  var mergeAggUiConfig = (persisted, config) => {
1293
- 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;
1432
+ 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;
1294
1433
  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;
1295
1434
  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;
1296
1435
  const formatters = createFormatters(locale);
@@ -1298,32 +1437,35 @@ var mergeAggUiConfig = (persisted, config) => {
1298
1437
  return {
1299
1438
  enableLogs: (_i = config == null ? void 0 : config.enableLogs) != null ? _i : defaultAggUiConfig.enableLogs,
1300
1439
  enableWebsocketsLogs: (_j = config == null ? void 0 : config.enableWebsocketsLogs) != null ? _j : defaultAggUiConfig.enableWebsocketsLogs,
1440
+ enableDebug: (_k = config == null ? void 0 : config.enableDebug) != null ? _k : defaultAggUiConfig.enableDebug,
1301
1441
  general: {
1302
1442
  locale,
1303
1443
  theme,
1304
- rootClassName: (_l = (_k = config == null ? void 0 : config.general) == null ? void 0 : _k.rootClassName) != null ? _l : defaultAggUiConfig.general.rootClassName,
1305
- labels: mergeAggUiLabels(defaultLabels, (_m = config == null ? void 0 : config.general) == null ? void 0 : _m.labels)
1444
+ rootClassName: (_m = (_l = config == null ? void 0 : config.general) == null ? void 0 : _l.rootClassName) != null ? _m : defaultAggUiConfig.general.rootClassName,
1445
+ labels: mergeAggUiLabels(defaultLabels, (_n = config == null ? void 0 : config.general) == null ? void 0 : _n.labels)
1306
1446
  },
1307
1447
  features: {
1308
- enableAnimations: (_o = (_n = config == null ? void 0 : config.features) == null ? void 0 : _n.enableAnimations) != null ? _o : defaultAggUiConfig.features.enableAnimations,
1309
- enableLiveUpdates: (_q = (_p = config == null ? void 0 : config.features) == null ? void 0 : _p.enableLiveUpdates) != null ? _q : defaultAggUiConfig.features.enableLiveUpdates,
1310
- showFeesBreakdown: (_s = (_r = config == null ? void 0 : config.features) == null ? void 0 : _r.showFeesBreakdown) != null ? _s : defaultAggUiConfig.features.showFeesBreakdown,
1311
- enableGradients: (_u = (_t = config == null ? void 0 : config.features) == null ? void 0 : _t.enableGradients) != null ? _u : defaultAggUiConfig.features.enableGradients
1448
+ enableAnimations: (_p = (_o = config == null ? void 0 : config.features) == null ? void 0 : _o.enableAnimations) != null ? _p : defaultAggUiConfig.features.enableAnimations,
1449
+ enableLiveUpdates: (_r = (_q = config == null ? void 0 : config.features) == null ? void 0 : _q.enableLiveUpdates) != null ? _r : defaultAggUiConfig.features.enableLiveUpdates,
1450
+ showFeesBreakdown: (_t = (_s = config == null ? void 0 : config.features) == null ? void 0 : _s.showFeesBreakdown) != null ? _t : defaultAggUiConfig.features.showFeesBreakdown,
1451
+ enableGradients: (_v = (_u = config == null ? void 0 : config.features) == null ? void 0 : _u.enableGradients) != null ? _v : defaultAggUiConfig.features.enableGradients,
1452
+ enableVenueEventDiscoveryFilters: (_x = (_w = config == null ? void 0 : config.features) == null ? void 0 : _w.enableVenueEventDiscoveryFilters) != null ? _x : defaultAggUiConfig.features.enableVenueEventDiscoveryFilters,
1453
+ enableNotifications: (_z = (_y = config == null ? void 0 : config.features) == null ? void 0 : _y.enableNotifications) != null ? _z : defaultAggUiConfig.features.enableNotifications
1312
1454
  },
1313
1455
  market: {
1314
- arbitrageThreshold: (_w = (_v = config == null ? void 0 : config.market) == null ? void 0 : _v.arbitrageThreshold) != null ? _w : defaultAggUiConfig.market.arbitrageThreshold
1456
+ arbitrageThreshold: (_B = (_A = config == null ? void 0 : config.market) == null ? void 0 : _A.arbitrageThreshold) != null ? _B : defaultAggUiConfig.market.arbitrageThreshold
1315
1457
  },
1316
1458
  chart: {
1317
- defaultChartTimeRange: (_y = (_x = config == null ? void 0 : config.chart) == null ? void 0 : _x.defaultChartTimeRange) != null ? _y : defaultAggUiConfig.chart.defaultChartTimeRange,
1318
- selectedChartTimeRange: (_C = (_B = (_z = persisted.chart) == null ? void 0 : _z.selectedChartTimeRange) != null ? _B : (_A = config == null ? void 0 : config.chart) == null ? void 0 : _A.defaultChartTimeRange) != null ? _C : defaultAggUiConfig.chart.defaultChartTimeRange,
1459
+ defaultChartTimeRange: (_D = (_C = config == null ? void 0 : config.chart) == null ? void 0 : _C.defaultChartTimeRange) != null ? _D : defaultAggUiConfig.chart.defaultChartTimeRange,
1460
+ selectedChartTimeRange: (_H = (_G = (_E = persisted.chart) == null ? void 0 : _E.selectedChartTimeRange) != null ? _G : (_F = config == null ? void 0 : config.chart) == null ? void 0 : _F.defaultChartTimeRange) != null ? _H : defaultAggUiConfig.chart.defaultChartTimeRange,
1319
1461
  setSelectedChartTimeRange: defaultAggUiConfig.chart.setSelectedChartTimeRange
1320
1462
  },
1321
1463
  formatting: {
1322
- formatNumber: (_E = (_D = config == null ? void 0 : config.formatting) == null ? void 0 : _D.formatNumber) != null ? _E : formatters.formatNumber,
1323
- formatPercent: (_G = (_F = config == null ? void 0 : config.formatting) == null ? void 0 : _F.formatPercent) != null ? _G : formatters.formatPercent,
1324
- formatCurrency: (_I = (_H = config == null ? void 0 : config.formatting) == null ? void 0 : _H.formatCurrency) != null ? _I : formatters.formatCurrency,
1325
- formatCompactCurrency: (_K = (_J = config == null ? void 0 : config.formatting) == null ? void 0 : _J.formatCompactCurrency) != null ? _K : formatters.formatCompactCurrency,
1326
- formatDate: (_M = (_L = config == null ? void 0 : config.formatting) == null ? void 0 : _L.formatDate) != null ? _M : formatters.formatDate
1464
+ formatNumber: (_J = (_I = config == null ? void 0 : config.formatting) == null ? void 0 : _I.formatNumber) != null ? _J : formatters.formatNumber,
1465
+ formatPercent: (_L = (_K = config == null ? void 0 : config.formatting) == null ? void 0 : _K.formatPercent) != null ? _L : formatters.formatPercent,
1466
+ formatCurrency: (_N = (_M = config == null ? void 0 : config.formatting) == null ? void 0 : _M.formatCurrency) != null ? _N : formatters.formatCurrency,
1467
+ formatCompactCurrency: (_P = (_O = config == null ? void 0 : config.formatting) == null ? void 0 : _O.formatCompactCurrency) != null ? _P : formatters.formatCompactCurrency,
1468
+ formatDate: (_R = (_Q = config == null ? void 0 : config.formatting) == null ? void 0 : _Q.formatDate) != null ? _R : formatters.formatDate
1327
1469
  },
1328
1470
  search: mergeAggUiSearchConfig(config == null ? void 0 : config.search),
1329
1471
  walletActions: config == null ? void 0 : config.walletActions,
@@ -1625,6 +1767,26 @@ var shouldInvalidateBalancesForOrderEvent = (event, currentUserId) => {
1625
1767
  if (!currentUserId) return true;
1626
1768
  return event.userId === currentUserId;
1627
1769
  };
1770
+ var userActivityQueryKeys = {
1771
+ all: () => ["user-activity"]
1772
+ };
1773
+ var invalidateUserActivityQueries = (queryClient, options) => {
1774
+ var _a;
1775
+ const strategy = (_a = options == null ? void 0 : options.strategy) != null ? _a : "remove";
1776
+ if (strategy === "remove") {
1777
+ queryClient.removeQueries({ queryKey: userActivityQueryKeys.all() });
1778
+ return;
1779
+ }
1780
+ queryClient.invalidateQueries({
1781
+ queryKey: userActivityQueryKeys.all(),
1782
+ refetchType: "all"
1783
+ });
1784
+ };
1785
+ var invalidateUserMoneyState = (queryClient, options) => {
1786
+ invalidateBalanceQueries(queryClient, { refetchType: options == null ? void 0 : options.refetchType });
1787
+ invalidatePositionQueries(queryClient, { refetchType: options == null ? void 0 : options.refetchType });
1788
+ invalidateUserActivityQueries(queryClient, { strategy: options == null ? void 0 : options.activityStrategy });
1789
+ };
1628
1790
 
1629
1791
  // src/core/providers/balance-provider.tsx
1630
1792
  var import_jsx_runtime2 = require("react/jsx-runtime");
@@ -1633,6 +1795,7 @@ var CHAIN_LABELS = {
1633
1795
  10: "Optimism",
1634
1796
  56: "BNB",
1635
1797
  137: "Polygon",
1798
+ 1337: "Hyperliquid",
1636
1799
  8453: "Base",
1637
1800
  42161: "Arbitrum",
1638
1801
  43114: "Avalanche",
@@ -1672,7 +1835,9 @@ function AggBalanceProvider({ children }) {
1672
1835
  return client.getManagedBalances();
1673
1836
  }),
1674
1837
  enabled: Boolean(client && isAuthenticated),
1675
- staleTime: 1e4
1838
+ staleTime: 60 * 1e3,
1839
+ refetchOnWindowFocus: "always",
1840
+ refetchOnReconnect: "always"
1676
1841
  });
1677
1842
  const managedBalancesData = balancesQuery.data;
1678
1843
  const managedBalances = (0, import_react3.useMemo)(
@@ -1832,6 +1997,7 @@ var import_react6 = require("react");
1832
1997
  var import_react_query2 = require("@tanstack/react-query");
1833
1998
 
1834
1999
  // src/market-data/chart-cache.ts
2000
+ var MAX_CACHE_RETENTION_SECONDS = 7 * 30 * 24 * 60 * 60 + 14 * 24 * 60 * 60;
1835
2001
  var getIntervalSeconds = (interval) => {
1836
2002
  switch (interval) {
1837
2003
  case "1m":
@@ -1850,12 +2016,41 @@ var createVenueData = (venue, outcomeIds = []) => ({
1850
2016
  candles: [],
1851
2017
  liveCandle: null,
1852
2018
  lineValue: void 0,
1853
- lastTrade: null
2019
+ lastTrade: null,
2020
+ lastUpdateTs: null
1854
2021
  });
2022
+ var pruneCandlesBefore = (candles, cutoffTs) => {
2023
+ if (cutoffTs <= 0) return candles;
2024
+ let firstKeptIndex = 0;
2025
+ while (firstKeptIndex < candles.length && candles[firstKeptIndex].time < cutoffTs) {
2026
+ firstKeptIndex += 1;
2027
+ }
2028
+ if (firstKeptIndex === 0) return candles;
2029
+ return candles.slice(firstKeptIndex);
2030
+ };
2031
+ var promoteClosedLiveCandle = (candles, liveCandle, expectedCandleTime) => {
2032
+ if (!liveCandle || liveCandle.time >= expectedCandleTime) {
2033
+ return { candles, promoted: false };
2034
+ }
2035
+ if (candles.some((candle) => candle.time === liveCandle.time)) {
2036
+ return { candles, promoted: false };
2037
+ }
2038
+ return { candles: sortCandles([...candles, liveCandle]), promoted: true };
2039
+ };
2040
+ var resolveMaxLastUpdateTs = (venues) => {
2041
+ let max = null;
2042
+ for (const venueData of Object.values(venues)) {
2043
+ if (venueData.lastUpdateTs != null && (max == null || venueData.lastUpdateTs > max)) {
2044
+ max = venueData.lastUpdateTs;
2045
+ }
2046
+ }
2047
+ return max;
2048
+ };
1855
2049
  var sortCandles = (candles) => {
1856
2050
  return [...candles].sort((left, right) => left.time - right.time);
1857
2051
  };
1858
2052
  var createMarketChartData = (params) => {
2053
+ var _a;
1859
2054
  const candles = sortCandles(
1860
2055
  params.response.data.map((candle) => ({
1861
2056
  time: Math.floor(candle.t / 1e3),
@@ -1868,6 +2063,7 @@ var createMarketChartData = (params) => {
1868
2063
  }))
1869
2064
  );
1870
2065
  const lastCandle = candles[candles.length - 1];
2066
+ const lastUpdateTs = (_a = lastCandle == null ? void 0 : lastCandle.time) != null ? _a : null;
1871
2067
  const venues = {
1872
2068
  [params.response.venue]: {
1873
2069
  venue: params.response.venue,
@@ -1875,7 +2071,8 @@ var createMarketChartData = (params) => {
1875
2071
  candles,
1876
2072
  liveCandle: null,
1877
2073
  lineValue: lastCandle == null ? void 0 : lastCandle.close,
1878
- lastTrade: null
2074
+ lastTrade: null,
2075
+ lastUpdateTs
1879
2076
  }
1880
2077
  };
1881
2078
  return {
@@ -1885,7 +2082,8 @@ var createMarketChartData = (params) => {
1885
2082
  interval: params.interval,
1886
2083
  startTs: params.startTs,
1887
2084
  endTs: params.endTs,
1888
- venues
2085
+ venues,
2086
+ lastUpdateTs
1889
2087
  };
1890
2088
  };
1891
2089
  var mergeMarketChartData = (params) => {
@@ -1919,9 +2117,75 @@ var mergeMarketChartData = (params) => {
1919
2117
  interval: params.interval,
1920
2118
  startTs: params.startTs,
1921
2119
  endTs: params.endTs,
1922
- venues
2120
+ venues,
2121
+ lastUpdateTs: resolveMaxLastUpdateTs(venues)
1923
2122
  };
1924
2123
  };
2124
+ var applyMidpointToMarketChart = (data, update) => {
2125
+ var _a;
2126
+ if (!data || !Number.isFinite(update.midpoint)) {
2127
+ return data;
2128
+ }
2129
+ const targetVenueEntry = Object.entries(data.venues).find(
2130
+ ([, venueData]) => venueData.outcomeIds.includes(update.outcomeId)
2131
+ );
2132
+ if (!targetVenueEntry && data.marketId !== update.outcomeId) {
2133
+ return data;
2134
+ }
2135
+ const [targetVenueName, currentVenue] = targetVenueEntry != null ? targetVenueEntry : [
2136
+ data.primaryVenue,
2137
+ (_a = data.venues[data.primaryVenue]) != null ? _a : createVenueData(data.primaryVenue, [update.outcomeId])
2138
+ ];
2139
+ const intervalSeconds = getIntervalSeconds(data.interval);
2140
+ const expectedCandleTime = update.timestamp - update.timestamp % intervalSeconds;
2141
+ let liveCandle = currentVenue.liveCandle;
2142
+ const { candles: promotedCandles } = promoteClosedLiveCandle(
2143
+ currentVenue.candles,
2144
+ liveCandle,
2145
+ expectedCandleTime
2146
+ );
2147
+ const nextCandles = pruneCandlesBefore(
2148
+ promotedCandles,
2149
+ update.timestamp - MAX_CACHE_RETENTION_SECONDS
2150
+ );
2151
+ if (liveCandle && liveCandle.time === expectedCandleTime) {
2152
+ if (liveCandle.source === "trade") {
2153
+ liveCandle = __spreadProps(__spreadValues({}, liveCandle), {
2154
+ close: update.midpoint
2155
+ });
2156
+ } else {
2157
+ liveCandle = __spreadProps(__spreadValues({}, liveCandle), {
2158
+ close: update.midpoint,
2159
+ high: Math.max(liveCandle.high, update.midpoint),
2160
+ low: Math.min(liveCandle.low, update.midpoint),
2161
+ source: "midpoint"
2162
+ });
2163
+ }
2164
+ } else {
2165
+ liveCandle = {
2166
+ time: expectedCandleTime,
2167
+ open: update.midpoint,
2168
+ high: update.midpoint,
2169
+ low: update.midpoint,
2170
+ close: update.midpoint,
2171
+ volume: 0,
2172
+ source: "midpoint"
2173
+ };
2174
+ }
2175
+ const nextVenues = __spreadProps(__spreadValues({}, data.venues), {
2176
+ [targetVenueName]: __spreadProps(__spreadValues({}, currentVenue), {
2177
+ outcomeIds: currentVenue.outcomeIds.includes(update.outcomeId) ? currentVenue.outcomeIds : [...currentVenue.outcomeIds, update.outcomeId],
2178
+ candles: nextCandles,
2179
+ liveCandle,
2180
+ lineValue: update.midpoint,
2181
+ lastUpdateTs: update.timestamp
2182
+ })
2183
+ });
2184
+ return __spreadProps(__spreadValues({}, data), {
2185
+ venues: nextVenues,
2186
+ lastUpdateTs: resolveMaxLastUpdateTs(nextVenues)
2187
+ });
2188
+ };
1925
2189
  var applyTradeToMarketChart = (data, trade) => {
1926
2190
  var _a, _b, _c;
1927
2191
  if (!data || data.marketId !== trade.outcomeId) {
@@ -1931,6 +2195,15 @@ var applyTradeToMarketChart = (data, trade) => {
1931
2195
  const intervalSeconds = getIntervalSeconds(data.interval);
1932
2196
  const expectedCandleTime = trade.timestamp - trade.timestamp % intervalSeconds;
1933
2197
  let liveCandle = currentVenue.liveCandle;
2198
+ const { candles: promotedCandles } = promoteClosedLiveCandle(
2199
+ currentVenue.candles,
2200
+ liveCandle,
2201
+ expectedCandleTime
2202
+ );
2203
+ const nextCandles = pruneCandlesBefore(
2204
+ promotedCandles,
2205
+ trade.timestamp - MAX_CACHE_RETENTION_SECONDS
2206
+ );
1934
2207
  if (liveCandle && liveCandle.time === expectedCandleTime) {
1935
2208
  liveCandle = __spreadProps(__spreadValues({}, liveCandle), {
1936
2209
  close: trade.price,
@@ -1950,16 +2223,20 @@ var applyTradeToMarketChart = (data, trade) => {
1950
2223
  source: "trade"
1951
2224
  };
1952
2225
  }
1953
- return __spreadProps(__spreadValues({}, data), {
1954
- venues: __spreadProps(__spreadValues({}, data.venues), {
1955
- [trade.venue]: __spreadProps(__spreadValues({}, currentVenue), {
1956
- outcomeIds: currentVenue.outcomeIds.includes(trade.outcomeId) ? currentVenue.outcomeIds : [...currentVenue.outcomeIds, trade.outcomeId],
1957
- liveCandle,
1958
- lineValue: (_c = liveCandle == null ? void 0 : liveCandle.close) != null ? _c : trade.price,
1959
- lastTrade: trade
1960
- })
2226
+ const nextVenues = __spreadProps(__spreadValues({}, data.venues), {
2227
+ [trade.venue]: __spreadProps(__spreadValues({}, currentVenue), {
2228
+ outcomeIds: currentVenue.outcomeIds.includes(trade.outcomeId) ? currentVenue.outcomeIds : [...currentVenue.outcomeIds, trade.outcomeId],
2229
+ candles: nextCandles,
2230
+ liveCandle,
2231
+ lineValue: (_c = liveCandle == null ? void 0 : liveCandle.close) != null ? _c : trade.price,
2232
+ lastTrade: trade,
2233
+ lastUpdateTs: trade.timestamp
1961
2234
  })
1962
2235
  });
2236
+ return __spreadProps(__spreadValues({}, data), {
2237
+ venues: nextVenues,
2238
+ lastUpdateTs: resolveMaxLastUpdateTs(nextVenues)
2239
+ });
1963
2240
  };
1964
2241
 
1965
2242
  // src/market-data/live-cache.ts
@@ -2150,7 +2427,15 @@ var marketDataKeys = {
2150
2427
  orderbook: (marketId, selectionKey, depth) => ["market-data", "orderbook", marketId, selectionKey != null ? selectionKey : null, depth != null ? depth : null],
2151
2428
  orderbookPrefix: (marketId) => marketId == null ? ["market-data", "orderbook"] : ["market-data", "orderbook", marketId],
2152
2429
  orderbookQuote: (marketId, side, size) => ["market-data", "orderbook-quote", marketId, side, size],
2153
- chart: (marketId, interval, startTs, endTs, countBack) => ["market-data", "chart", marketId, interval, startTs, endTs, countBack != null ? countBack : null],
2430
+ /**
2431
+ * Stable per `{marketId, interval, rangeKey}`. Deliberately excludes the
2432
+ * concrete `startTs`/`endTs` of the rolling window — those advance every
2433
+ * candle bucket, and including them would mint a fresh key on every
2434
+ * rollover, defeating React Query's cache on tab/page revisits. The
2435
+ * current window is passed to `queryFn` via closure instead, and
2436
+ * `refetchInterval` advances the data under the stable key.
2437
+ */
2438
+ chart: (marketId, interval, rangeKey, countBack) => ["market-data", "chart", marketId, interval, rangeKey, countBack != null ? countBack : null],
2154
2439
  chartPrefix: (marketId, interval) => {
2155
2440
  if (!marketId) return ["market-data", "chart"];
2156
2441
  if (!interval) return ["market-data", "chart", marketId];
@@ -2167,6 +2452,9 @@ var useAggClient = () => {
2167
2452
  }
2168
2453
  return client;
2169
2454
  };
2455
+ var useOptionalAggClient = () => {
2456
+ return (0, import_react5.useContext)(AggClientContext);
2457
+ };
2170
2458
  var useAggUiConfig = () => {
2171
2459
  return (0, import_react5.useContext)(AggUiContext);
2172
2460
  };
@@ -2395,6 +2683,9 @@ function AggWebSocketProvider({ children }) {
2395
2683
  const invalidatePositionCaches = (0, import_react6.useCallback)(() => {
2396
2684
  invalidatePositionQueries(queryClient);
2397
2685
  }, [queryClient]);
2686
+ const invalidateActivityCaches = (0, import_react6.useCallback)(() => {
2687
+ invalidateUserActivityQueries(queryClient);
2688
+ }, [queryClient]);
2398
2689
  const callbacks = (0, import_react6.useMemo)(
2399
2690
  () => ({
2400
2691
  onSnapshot: (marketId, book) => {
@@ -2413,6 +2704,14 @@ function AggWebSocketProvider({ children }) {
2413
2704
  syncLiveQuery(marketId, (previous) => withLiveOrderbook(previous, book, "snapshot"));
2414
2705
  if (book.midpoint != null) {
2415
2706
  getOrCreateBuilder(marketId).addMidpoint(book.midpoint, book.timestamp);
2707
+ syncChartQueries(
2708
+ marketId,
2709
+ (_queryKey, previous) => applyMidpointToMarketChart(previous, {
2710
+ outcomeId: marketId,
2711
+ midpoint: book.midpoint,
2712
+ timestamp: book.timestamp
2713
+ })
2714
+ );
2416
2715
  }
2417
2716
  },
2418
2717
  onDelta: (marketId, book) => {
@@ -2458,6 +2757,14 @@ function AggWebSocketProvider({ children }) {
2458
2757
  });
2459
2758
  if (book.midpoint != null) {
2460
2759
  getOrCreateBuilder(marketId).addMidpoint(book.midpoint, book.timestamp);
2760
+ syncChartQueries(
2761
+ marketId,
2762
+ (_queryKey, previous) => applyMidpointToMarketChart(previous, {
2763
+ outcomeId: marketId,
2764
+ midpoint: book.midpoint,
2765
+ timestamp: book.timestamp
2766
+ })
2767
+ );
2461
2768
  }
2462
2769
  },
2463
2770
  onTrade: (trade) => {
@@ -2495,6 +2802,7 @@ function AggWebSocketProvider({ children }) {
2495
2802
  onBalanceUpdate: (msg) => {
2496
2803
  if (isClientAuthenticated) {
2497
2804
  invalidateBalanceCaches();
2805
+ invalidateActivityCaches();
2498
2806
  }
2499
2807
  for (const listener of balanceUpdateListenersRef.current) {
2500
2808
  listener(msg);
@@ -2560,6 +2868,7 @@ function AggWebSocketProvider({ children }) {
2560
2868
  [
2561
2869
  client,
2562
2870
  enableWebsocketsLogs,
2871
+ invalidateActivityCaches,
2563
2872
  invalidateBalanceCaches,
2564
2873
  invalidatePositionCaches,
2565
2874
  isClientAuthenticated,
@@ -2696,9 +3005,26 @@ var resolveTradingStateKind = (status) => {
2696
3005
  return "closed";
2697
3006
  };
2698
3007
  var resolveMarketWinningOutcome = (market) => {
2699
- var _a;
3008
+ var _a, _b, _c, _d;
2700
3009
  if (!market) return null;
2701
- return (_a = market.venueMarketOutcomes.find((outcome) => outcome.winner === true)) != null ? _a : null;
3010
+ const localWinningOutcome = (_a = market.venueMarketOutcomes.find((outcome) => outcome.winner === true)) != null ? _a : null;
3011
+ if (localWinningOutcome) return localWinningOutcome;
3012
+ const matchedVenueMarkets = (_b = market.matchedVenueMarkets) != null ? _b : [];
3013
+ if (!matchedVenueMarkets.length) return null;
3014
+ for (const outcome of market.venueMarketOutcomes) {
3015
+ const matchedRefs = (_c = outcome.matchedVenueMarketOutcomes) != null ? _c : [];
3016
+ for (const ref of matchedRefs) {
3017
+ const matchedMarket = matchedVenueMarkets.find((item) => item.id === ref.venueMarketId);
3018
+ if (!matchedMarket) continue;
3019
+ const matchedOutcome = (_d = matchedMarket.venueMarketOutcomes) == null ? void 0 : _d.find(
3020
+ (item) => item.id === ref.venueMarketOutcomeId
3021
+ );
3022
+ if ((matchedOutcome == null ? void 0 : matchedOutcome.winner) === true) {
3023
+ return outcome;
3024
+ }
3025
+ }
3026
+ }
3027
+ return null;
2702
3028
  };
2703
3029
  var AFFIRMATIVE_WINNER_LABELS = /* @__PURE__ */ new Set(["yes", "up", "buy", "long", "true"]);
2704
3030
  var isAffirmativeWinnerLabel = (label) => {
@@ -2886,51 +3212,50 @@ function findOutcomeAcrossMarkets(event, outcomeId) {
2886
3212
  }
2887
3213
  return null;
2888
3214
  }
3215
+ var TradeSide = {
3216
+ Buy: "buy",
3217
+ Sell: "sell"
3218
+ };
2889
3219
  function tradingReducer(state, action) {
2890
- var _a, _b;
3220
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
2891
3221
  switch (action.type) {
2892
3222
  case "INITIALIZE_EVENT": {
2893
3223
  if (!action.event) {
2894
- return { event: null, market: null, outcome: null };
3224
+ return { event: null, market: null, outcome: null, tradeSide: TradeSide.Buy };
2895
3225
  }
2896
- const market = resolveDefaultMarket(action.event);
2897
3226
  return {
2898
3227
  event: action.event,
2899
- market,
2900
- outcome: resolveDefaultOutcome(market)
3228
+ market: null,
3229
+ outcome: null,
3230
+ tradeSide: TradeSide.Buy
2901
3231
  };
2902
3232
  }
2903
3233
  case "SYNC_EVENT": {
2904
- const nextEvent = action.event;
2905
- const preservedMarket = state.market ? findMarketById(nextEvent, state.market.id) : null;
2906
- if (preservedMarket) {
2907
- const preservedMarketState = resolveMarketTradingState(preservedMarket);
2908
- if (preservedMarketState.isTradingDisabled) {
2909
- const tradableAlternative = resolveDefaultMarket(nextEvent);
2910
- if (tradableAlternative && resolveMarketTradingState(tradableAlternative).isOpen) {
2911
- return {
2912
- event: nextEvent,
2913
- market: tradableAlternative,
2914
- outcome: resolveDefaultOutcome(tradableAlternative)
2915
- };
2916
- }
2917
- }
2918
- const preservedOutcome = state.outcome ? findOutcomeById(preservedMarket, state.outcome.id) : null;
3234
+ const previousMarketId = (_b = (_a = state.market) == null ? void 0 : _a.id) != null ? _b : null;
3235
+ const previousOutcomeId = (_d = (_c = state.outcome) == null ? void 0 : _c.id) != null ? _d : null;
3236
+ const syncedMarket = previousMarketId ? findMarketById(action.event, previousMarketId) : null;
3237
+ if (!syncedMarket || resolveMarketTradingState(syncedMarket).isTradingDisabled) {
2919
3238
  return {
2920
- event: nextEvent,
2921
- market: preservedMarket,
2922
- outcome: preservedOutcome != null ? preservedOutcome : resolveDefaultOutcome(preservedMarket)
3239
+ event: action.event,
3240
+ market: null,
3241
+ outcome: null,
3242
+ tradeSide: (_e = state.tradeSide) != null ? _e : TradeSide.Buy
2923
3243
  };
2924
3244
  }
2925
- const defaultMarket = resolveDefaultMarket(nextEvent);
3245
+ const syncedOutcome = previousOutcomeId ? findOutcomeById(syncedMarket, previousOutcomeId) : null;
2926
3246
  return {
2927
- event: nextEvent,
2928
- market: defaultMarket,
2929
- outcome: resolveDefaultOutcome(defaultMarket)
3247
+ event: action.event,
3248
+ market: syncedMarket,
3249
+ outcome: syncedOutcome,
3250
+ tradeSide: (_f = state.tradeSide) != null ? _f : TradeSide.Buy
2930
3251
  };
2931
3252
  }
3253
+ case "SET_TRADE_SIDE": {
3254
+ if (((_g = state.tradeSide) != null ? _g : TradeSide.Buy) === action.tradeSide) return state;
3255
+ return __spreadProps(__spreadValues({}, state), { tradeSide: action.tradeSide });
3256
+ }
2932
3257
  case "SELECT_MARKET": {
2933
- const market = (_b = (_a = findMarketById(state.event, action.marketId)) != null ? _a : action.market) != null ? _b : null;
3258
+ const market = (_i = (_h = findMarketById(state.event, action.marketId)) != null ? _h : action.market) != null ? _i : null;
2934
3259
  if (!market) return state;
2935
3260
  if (resolveMarketTradingState(market).kind === "resolved") return state;
2936
3261
  return __spreadProps(__spreadValues({}, state), {
@@ -2939,6 +3264,9 @@ function tradingReducer(state, action) {
2939
3264
  });
2940
3265
  }
2941
3266
  case "SELECT_OUTCOME": {
3267
+ if (((_j = state.outcome) == null ? void 0 : _j.id) === action.outcomeId) {
3268
+ return state;
3269
+ }
2942
3270
  if (state.market) {
2943
3271
  const outcomeInCurrentMarket = findOutcomeById(state.market, action.outcomeId);
2944
3272
  if (outcomeInCurrentMarket) {
@@ -2990,7 +3318,8 @@ function logAction(actionType, payload, prev, next, enableLogs) {
2990
3318
  var initialState = {
2991
3319
  event: null,
2992
3320
  market: null,
2993
- outcome: null
3321
+ outcome: null,
3322
+ tradeSide: TradeSide.Buy
2994
3323
  };
2995
3324
  var EventTradingContext = (0, import_react7.createContext)(void 0);
2996
3325
  var useEventTradingContext = () => {
@@ -3000,9 +3329,15 @@ var EventTradingProvider = ({
3000
3329
  children,
3001
3330
  enableLogs = false
3002
3331
  }) => {
3332
+ var _a, _b;
3003
3333
  const [state, rawDispatch] = (0, import_react7.useReducer)(tradingReducer, initialState);
3004
3334
  const stateRef = (0, import_react7.useRef)(state);
3335
+ const pendingAtomicSelectionRef = (0, import_react7.useRef)(null);
3005
3336
  stateRef.current = state;
3337
+ const pendingAtomicSelection = pendingAtomicSelectionRef.current;
3338
+ if (pendingAtomicSelection && ((_a = state.market) == null ? void 0 : _a.id) === pendingAtomicSelection.marketId && ((_b = state.outcome) == null ? void 0 : _b.id) === pendingAtomicSelection.outcomeId) {
3339
+ pendingAtomicSelectionRef.current = null;
3340
+ }
3006
3341
  const dispatch = (0, import_react7.useCallback)(
3007
3342
  (action) => {
3008
3343
  const prev = stateRef.current;
@@ -3025,24 +3360,45 @@ var EventTradingProvider = ({
3025
3360
  [dispatch]
3026
3361
  );
3027
3362
  const selectOutcome = (0, import_react7.useCallback)(
3028
- (outcomeId) => dispatch({ type: "SELECT_OUTCOME", outcomeId }),
3363
+ (outcomeId) => {
3364
+ var _a2, _b2;
3365
+ if (((_a2 = stateRef.current.outcome) == null ? void 0 : _a2.id) === outcomeId) return;
3366
+ if (((_b2 = pendingAtomicSelectionRef.current) == null ? void 0 : _b2.outcomeId) === outcomeId) return;
3367
+ dispatch({ type: "SELECT_OUTCOME", outcomeId });
3368
+ },
3029
3369
  [dispatch]
3030
3370
  );
3031
3371
  const selectMarketAndOutcome = (0, import_react7.useCallback)(
3032
- (marketId, outcomeId) => dispatch({ type: "SELECT_MARKET_AND_OUTCOME", marketId, outcomeId }),
3372
+ (marketId, outcomeId) => {
3373
+ var _a2, _b2, _c, _d;
3374
+ if (((_a2 = stateRef.current.market) == null ? void 0 : _a2.id) === marketId && ((_b2 = stateRef.current.outcome) == null ? void 0 : _b2.id) === outcomeId) {
3375
+ return;
3376
+ }
3377
+ if (((_c = pendingAtomicSelectionRef.current) == null ? void 0 : _c.marketId) === marketId && ((_d = pendingAtomicSelectionRef.current) == null ? void 0 : _d.outcomeId) === outcomeId) {
3378
+ return;
3379
+ }
3380
+ pendingAtomicSelectionRef.current = { marketId, outcomeId };
3381
+ dispatch({ type: "SELECT_MARKET_AND_OUTCOME", marketId, outcomeId });
3382
+ },
3383
+ [dispatch]
3384
+ );
3385
+ const setTradeSide = (0, import_react7.useCallback)(
3386
+ (tradeSide) => dispatch({ type: "SET_TRADE_SIDE", tradeSide }),
3033
3387
  [dispatch]
3034
3388
  );
3035
3389
  const value = (0, import_react7.useMemo)(
3036
3390
  () => {
3037
- var _a, _b, _c, _d, _e, _f, _g, _h;
3391
+ var _a2, _b2, _c, _d, _e, _f, _g, _h, _i;
3038
3392
  return {
3039
3393
  selectedEvent: state.event,
3040
3394
  selectedMarket: state.market,
3041
3395
  selectedOutcome: state.outcome,
3042
- selectedEventId: (_b = (_a = state.event) == null ? void 0 : _a.id) != null ? _b : null,
3396
+ selectedEventId: (_b2 = (_a2 = state.event) == null ? void 0 : _a2.id) != null ? _b2 : null,
3043
3397
  selectedMarketId: (_d = (_c = state.market) == null ? void 0 : _c.id) != null ? _d : null,
3044
3398
  selectedOutcomeId: (_f = (_e = state.outcome) == null ? void 0 : _e.id) != null ? _f : null,
3045
3399
  selectedVenue: (_h = (_g = state.market) == null ? void 0 : _g.venue) != null ? _h : null,
3400
+ tradeSide: (_i = state.tradeSide) != null ? _i : TradeSide.Buy,
3401
+ setTradeSide,
3046
3402
  initializeFromEvent,
3047
3403
  syncEvent,
3048
3404
  selectMarket,
@@ -3050,7 +3406,15 @@ var EventTradingProvider = ({
3050
3406
  selectMarketAndOutcome
3051
3407
  };
3052
3408
  },
3053
- [state, initializeFromEvent, syncEvent, selectMarket, selectOutcome, selectMarketAndOutcome]
3409
+ [
3410
+ state,
3411
+ initializeFromEvent,
3412
+ syncEvent,
3413
+ selectMarket,
3414
+ selectOutcome,
3415
+ selectMarketAndOutcome,
3416
+ setTradeSide
3417
+ ]
3054
3418
  );
3055
3419
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(EventTradingContext.Provider, { value, children });
3056
3420
  };
@@ -3253,7 +3617,7 @@ function useRampSession() {
3253
3617
  }
3254
3618
 
3255
3619
  // src/withdraw/use-withdraw-flow.ts
3256
- var import_react11 = require("react");
3620
+ var import_react13 = require("react");
3257
3621
 
3258
3622
  // src/execution/use-quote-managed.ts
3259
3623
  var import_react_query6 = require("@tanstack/react-query");
@@ -3293,7 +3657,7 @@ function useWithdrawManaged(options) {
3293
3657
  mutationFn: (params) => client.withdrawManaged(params),
3294
3658
  onSuccess: (data) => {
3295
3659
  var _a;
3296
- invalidateBalanceQueries(queryClient);
3660
+ invalidateUserMoneyState(queryClient);
3297
3661
  (_a = options == null ? void 0 : options.onSuccess) == null ? void 0 : _a.call(options, data);
3298
3662
  },
3299
3663
  onError: options == null ? void 0 : options.onError
@@ -3405,7 +3769,7 @@ function useSyncBalances(options) {
3405
3769
  mutationFn: () => client.syncManagedBalances(),
3406
3770
  onSuccess: () => {
3407
3771
  var _a;
3408
- invalidateBalanceQueries(queryClient);
3772
+ invalidateUserMoneyState(queryClient);
3409
3773
  (_a = options == null ? void 0 : options.onSuccess) == null ? void 0 : _a.call(options);
3410
3774
  },
3411
3775
  onError: options == null ? void 0 : options.onError
@@ -3414,12 +3778,18 @@ function useSyncBalances(options) {
3414
3778
 
3415
3779
  // src/execution/use-execution-progress.ts
3416
3780
  var import_react10 = require("react");
3417
- var TERMINAL_ORDER_STATUSES = /* @__PURE__ */ new Set(["filled", "partial_fill", "failed", "cancelled"]);
3781
+ var TERMINAL_ORDER_STATUSES = /* @__PURE__ */ new Set([
3782
+ "filled",
3783
+ "partial_fill",
3784
+ "failed",
3785
+ "cancelled",
3786
+ "expired"
3787
+ ]);
3418
3788
  var ORDER_POLL_INTERVAL_MS = 5e3;
3419
3789
  function mapOrderStatusToTerminalEvent(status) {
3420
3790
  if (status === "filled") return "filled";
3421
3791
  if (status === "partial_fill") return "partial_fill";
3422
- if (status === "failed" || status === "cancelled") return "failed";
3792
+ if (status === "failed" || status === "cancelled" || status === "expired") return "failed";
3423
3793
  return null;
3424
3794
  }
3425
3795
  function useExecutionProgress({
@@ -3475,19 +3845,26 @@ function useExecutionProgress({
3475
3845
  submittedOrderVenueByIdRef.current.set(msg.orderId, trimmedVenue);
3476
3846
  }
3477
3847
  const { event } = msg;
3478
- if (event === "filled" || event === "partial_fill" || event === "failed" || event === "bridge_ws_subscribe_failed") {
3479
- const mappedEvent = event === "bridge_ws_subscribe_failed" ? "failed" : event;
3848
+ if (event === "filled" || event === "partial_fill" || event === "failed" || event === "bridge_ws_subscribe_failed" || event === "expired" || event === "dag_cancelled") {
3849
+ const mappedEvent = event === "filled" || event === "partial_fill" ? event : "failed";
3480
3850
  const resolvedVenue = trimmedVenue || submittedOrderVenueByIdRef.current.get(msg.orderId) || "";
3481
3851
  if (resolvedVenue) {
3482
3852
  submittedOrderVenueByIdRef.current.set(msg.orderId, resolvedVenue);
3483
3853
  }
3854
+ 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;
3484
3855
  const nextTerminalEvent = {
3485
3856
  orderId: msg.orderId,
3486
3857
  venue: resolvedVenue,
3487
3858
  event: mappedEvent,
3488
3859
  filledAmountRaw: msg.filledAmountRaw,
3489
3860
  remainingAmountRaw: msg.remainingAmountRaw,
3490
- errorReason: event === "bridge_ws_subscribe_failed" ? (_a = msg.errorReason) != null ? _a : "Bridge event subscription failed." : msg.errorReason,
3861
+ actualSharesRaw: msg.actualSharesRaw,
3862
+ actualToWinRaw: msg.actualToWinRaw,
3863
+ quotedSharesRaw: msg.quotedSharesRaw,
3864
+ quotedToWinRaw: msg.quotedToWinRaw,
3865
+ executionPriceRaw: msg.executionPriceRaw,
3866
+ quotedPriceRaw: msg.quotedPriceRaw,
3867
+ errorReason: (_a = msg.errorReason) != null ? _a : fallbackErrorReason,
3491
3868
  timestamp: msg.timestamp
3492
3869
  };
3493
3870
  setTerminalOrderEvents((prev) => {
@@ -3565,15 +3942,29 @@ function useExecutionProgress({
3565
3942
  });
3566
3943
  return;
3567
3944
  }
3945
+ const buildFailedProgress = (prev) => {
3946
+ var _a2, _b2, _c2, _d, _e, _f, _g, _h, _i, _j, _k, _l;
3947
+ const seq = (_b2 = (_a2 = msg.sequence) != null ? _a2 : prev == null ? void 0 : prev.currentSequence) != null ? _b2 : 0;
3948
+ const stepType = (_d = (_c2 = msg.stepType) != null ? _c2 : prev == null ? void 0 : prev.currentStepType) != null ? _d : null;
3949
+ const baseStepTypes = (_e = prev == null ? void 0 : prev.stepTypes) != null ? _e : {};
3950
+ const stepTypes = seq && stepType ? __spreadProps(__spreadValues({}, baseStepTypes), { [seq]: stepType }) : baseStepTypes;
3951
+ return {
3952
+ dagRunId: (_g = (_f = msg.dagRunId) != null ? _f : prev == null ? void 0 : prev.dagRunId) != null ? _g : "",
3953
+ totalSteps: (_i = (_h = msg.totalSteps) != null ? _h : prev == null ? void 0 : prev.totalSteps) != null ? _i : 0,
3954
+ currentSequence: seq,
3955
+ currentStepType: stepType,
3956
+ completedSequences: (_j = prev == null ? void 0 : prev.completedSequences) != null ? _j : [],
3957
+ stepTypes,
3958
+ status: "failed",
3959
+ errorReason: (_l = (_k = msg.errorReason) != null ? _k : prev == null ? void 0 : prev.errorReason) != null ? _l : null
3960
+ };
3961
+ };
3962
+ if (event === "step_failed") {
3963
+ setDagProgress((prev) => buildFailedProgress(prev));
3964
+ return;
3965
+ }
3568
3966
  if (event === "dag_failed") {
3569
- setDagProgress((prev) => {
3570
- var _a2;
3571
- if (!prev) return prev;
3572
- return __spreadProps(__spreadValues({}, prev), {
3573
- status: "failed",
3574
- errorReason: (_a2 = msg.errorReason) != null ? _a2 : null
3575
- });
3576
- });
3967
+ setDagProgress((prev) => buildFailedProgress(prev));
3577
3968
  return;
3578
3969
  }
3579
3970
  }, []);
@@ -3598,7 +3989,7 @@ function useExecutionProgress({
3598
3989
  }
3599
3990
  };
3600
3991
  const reconcile = () => __async(null, null, function* () {
3601
- var _a, _b, _c;
3992
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
3602
3993
  if (cancelled || pollInFlightRef.current) return;
3603
3994
  const pending = orderIds.filter((id) => !terminalOrderIdsRef.current.has(id));
3604
3995
  if (pending.length === 0) {
@@ -3630,7 +4021,13 @@ function useExecutionProgress({
3630
4021
  venue: (_a = order.venue) != null ? _a : "",
3631
4022
  event: mapped,
3632
4023
  filledAmountRaw: (_b = order.filledAmountRaw) != null ? _b : void 0,
3633
- errorReason: (_c = order.errorMessage) != null ? _c : void 0,
4024
+ actualSharesRaw: (_c = order.actualSharesRaw) != null ? _c : void 0,
4025
+ actualToWinRaw: (_d = order.actualToWinRaw) != null ? _d : void 0,
4026
+ quotedSharesRaw: (_e = order.quotedSharesRaw) != null ? _e : void 0,
4027
+ quotedToWinRaw: (_f = order.quotedToWinRaw) != null ? _f : void 0,
4028
+ executionPriceRaw: (_g = order.executionPrice) != null ? _g : void 0,
4029
+ quotedPriceRaw: (_h = order.quotedPriceRaw) != null ? _h : void 0,
4030
+ errorReason: (_i = order.errorMessage) != null ? _i : void 0,
3634
4031
  timestamp: new Date(order.updatedAt).getTime() || Date.now()
3635
4032
  });
3636
4033
  }
@@ -3710,11 +4107,27 @@ var computeClosedPositionTotals = (group) => {
3710
4107
 
3711
4108
  // src/execution/use-redeem.ts
3712
4109
  var import_react_query13 = require("@tanstack/react-query");
4110
+ var RedeemRejectedError = class extends Error {
4111
+ constructor(message, response) {
4112
+ super(message);
4113
+ this.name = "RedeemRejectedError";
4114
+ this.response = response;
4115
+ }
4116
+ };
4117
+ var isLegRejected = (status) => status === "ineligible" || status === "rejected";
3713
4118
  var useRedeem = () => {
3714
4119
  const client = useAggClient();
3715
4120
  const queryClient = (0, import_react_query13.useQueryClient)();
3716
4121
  return (0, import_react_query13.useMutation)({
3717
- mutationFn: (body) => client.redeem(body),
4122
+ mutationFn: (body) => __async(null, null, function* () {
4123
+ const response = yield client.redeem(body);
4124
+ if (response.results.length > 0 && response.results.every((r) => isLegRejected(r.status))) {
4125
+ const reasons = response.results.map((r) => r.reason).filter((r) => Boolean(r));
4126
+ const message = reasons.length > 0 ? reasons.join("; ") : "Redeem rejected";
4127
+ throw new RedeemRejectedError(message, response);
4128
+ }
4129
+ return response;
4130
+ }),
3718
4131
  onSuccess: () => {
3719
4132
  queryClient.invalidateQueries({ queryKey: executionKeys.positionsPrefix() });
3720
4133
  queryClient.invalidateQueries({ queryKey: executionKeys.balances() });
@@ -3765,6 +4178,144 @@ var useRedeemEligibleCount = () => {
3765
4178
  return (_a = query.data) != null ? _a : 0;
3766
4179
  };
3767
4180
 
4181
+ // src/execution/use-redeem-lifecycle.ts
4182
+ var import_react12 = require("react");
4183
+
4184
+ // src/execution/use-redeem-lifecycles.ts
4185
+ var import_react11 = require("react");
4186
+ var computeDerivedState = (legs, expectedCount) => {
4187
+ const legCount = Object.keys(legs).length;
4188
+ let allTerminal = legCount === expectedCount;
4189
+ let allConfirmed = allTerminal;
4190
+ let anyFailed = false;
4191
+ let errorMessage = null;
4192
+ for (const leg of Object.values(legs)) {
4193
+ if (leg.status === "submitted") allTerminal = false;
4194
+ if (leg.status !== "confirmed") allConfirmed = false;
4195
+ if (leg.status === "failed") {
4196
+ anyFailed = true;
4197
+ if (errorMessage === null && leg.errorMessage) errorMessage = leg.errorMessage;
4198
+ }
4199
+ }
4200
+ return {
4201
+ terminal: allTerminal,
4202
+ allConfirmed: allTerminal && allConfirmed,
4203
+ anyFailed,
4204
+ errorMessage
4205
+ };
4206
+ };
4207
+ var seedState = (input) => {
4208
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
4209
+ const legs = {};
4210
+ for (const id of (_a = input.preFailedOutcomeIds) != null ? _a : []) {
4211
+ legs[id] = {
4212
+ status: "failed",
4213
+ txHash: null,
4214
+ errorMessage: (_c = (_b = input.preFailedReasons) == null ? void 0 : _b[id]) != null ? _c : null
4215
+ };
4216
+ }
4217
+ for (const id of (_d = input.preConfirmedOutcomeIds) != null ? _d : []) {
4218
+ legs[id] = {
4219
+ status: "confirmed",
4220
+ txHash: (_f = (_e = input.preConfirmedTxHashes) == null ? void 0 : _e[id]) != null ? _f : null,
4221
+ errorMessage: null
4222
+ };
4223
+ }
4224
+ const expectedCount = input.expectedOutcomeIds.length + ((_h = (_g = input.preFailedOutcomeIds) == null ? void 0 : _g.length) != null ? _h : 0) + ((_j = (_i = input.preConfirmedOutcomeIds) == null ? void 0 : _i.length) != null ? _j : 0);
4225
+ const derived = computeDerivedState(legs, expectedCount);
4226
+ return {
4227
+ pending: !derived.terminal,
4228
+ terminal: derived.terminal,
4229
+ allConfirmed: derived.allConfirmed,
4230
+ anyFailed: derived.anyFailed,
4231
+ errorMessage: derived.errorMessage,
4232
+ legs
4233
+ };
4234
+ };
4235
+ function useRedeemLifecycles(inputs) {
4236
+ const inputsByRedeemId = (0, import_react11.useMemo)(() => {
4237
+ const map = {};
4238
+ for (const input of inputs) {
4239
+ map[input.redeemId] = input;
4240
+ }
4241
+ return map;
4242
+ }, [inputs]);
4243
+ const [stateMap, setStateMap] = (0, import_react11.useState)(() => {
4244
+ const next = {};
4245
+ for (const [id, input] of Object.entries(inputsByRedeemId)) {
4246
+ next[id] = seedState(input);
4247
+ }
4248
+ return next;
4249
+ });
4250
+ (0, import_react11.useEffect)(() => {
4251
+ setStateMap((prev) => {
4252
+ let changed = false;
4253
+ const next = {};
4254
+ for (const [id, input] of Object.entries(inputsByRedeemId)) {
4255
+ const existing = prev[id];
4256
+ if (existing) {
4257
+ next[id] = existing;
4258
+ } else {
4259
+ next[id] = seedState(input);
4260
+ changed = true;
4261
+ }
4262
+ }
4263
+ if (Object.keys(next).length !== Object.keys(prev).length) changed = true;
4264
+ return changed ? next : prev;
4265
+ });
4266
+ }, [inputsByRedeemId]);
4267
+ useOnRedeemEvent(
4268
+ (0, import_react11.useMemo)(() => {
4269
+ if (Object.keys(inputsByRedeemId).length === 0) return null;
4270
+ return (event) => {
4271
+ const input = inputsByRedeemId[event.redeemId];
4272
+ if (!input) return;
4273
+ setStateMap((prev) => {
4274
+ var _a, _b, _c, _d;
4275
+ const existing = prev[event.redeemId];
4276
+ if (!existing) return prev;
4277
+ const nextLegs = __spreadProps(__spreadValues({}, existing.legs), {
4278
+ [event.venueMarketOutcomeId]: {
4279
+ status: event.status,
4280
+ txHash: event.txHash,
4281
+ errorMessage: event.errorMessage
4282
+ }
4283
+ });
4284
+ const expectedCount = input.expectedOutcomeIds.length + ((_b = (_a = input.preFailedOutcomeIds) == null ? void 0 : _a.length) != null ? _b : 0) + ((_d = (_c = input.preConfirmedOutcomeIds) == null ? void 0 : _c.length) != null ? _d : 0);
4285
+ const derived = computeDerivedState(nextLegs, expectedCount);
4286
+ const nextState = {
4287
+ pending: !derived.terminal,
4288
+ terminal: derived.terminal,
4289
+ allConfirmed: derived.allConfirmed,
4290
+ anyFailed: derived.anyFailed,
4291
+ errorMessage: derived.errorMessage,
4292
+ legs: nextLegs
4293
+ };
4294
+ return __spreadProps(__spreadValues({}, prev), { [event.redeemId]: nextState });
4295
+ });
4296
+ };
4297
+ }, [inputsByRedeemId])
4298
+ );
4299
+ return stateMap;
4300
+ }
4301
+
4302
+ // src/execution/use-redeem-lifecycle.ts
4303
+ var INITIAL_STATE = {
4304
+ pending: true,
4305
+ terminal: false,
4306
+ allConfirmed: false,
4307
+ anyFailed: false,
4308
+ errorMessage: null,
4309
+ legs: {}
4310
+ };
4311
+ function useRedeemLifecycle(input) {
4312
+ var _a;
4313
+ const inputs = (0, import_react12.useMemo)(() => input ? [input] : [], [input]);
4314
+ const map = useRedeemLifecycles(inputs);
4315
+ if (!input) return INITIAL_STATE;
4316
+ return (_a = map[input.redeemId]) != null ? _a : INITIAL_STATE;
4317
+ }
4318
+
3768
4319
  // src/withdraw/use-withdraw-flow.ts
3769
4320
  var EVM_ADDRESS_REGEX = /^0x[a-fA-F0-9]{40}$/;
3770
4321
  var SOLANA_ADDRESS_REGEX = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;
@@ -3780,7 +4331,9 @@ var WITHDRAWAL_SUPPORTED_CHAIN_IDS = /* @__PURE__ */ new Set([
3780
4331
  // Base
3781
4332
  56,
3782
4333
  // BNB
3783
- SOLANA_CHAIN_ID
4334
+ SOLANA_CHAIN_ID,
4335
+ 1337
4336
+ // Hyperliquid
3784
4337
  ]);
3785
4338
  var isValidDestinationAddress = (address, chainId) => {
3786
4339
  if (chainId === SOLANA_CHAIN_ID) return SOLANA_ADDRESS_REGEX.test(address);
@@ -3831,20 +4384,20 @@ function useWithdrawFlow(options) {
3831
4384
  const withdrawMutation = useWithdrawManaged();
3832
4385
  const syncBalances = useSyncBalances();
3833
4386
  const ws = useAggWebSocket();
3834
- (0, import_react11.useEffect)(() => {
4387
+ (0, import_react13.useEffect)(() => {
3835
4388
  if (!open) return;
3836
4389
  syncBalances.mutate(void 0, {
3837
4390
  onError: () => {
3838
4391
  }
3839
4392
  });
3840
4393
  }, [open]);
3841
- const [withdrawDestination, setWithdrawDestination] = (0, import_react11.useState)("");
3842
- const [withdrawAmount, setWithdrawAmount] = (0, import_react11.useState)("");
3843
- const [withdrawToken, setWithdrawToken] = (0, import_react11.useState)("USDC");
3844
- const [withdrawNetwork, setWithdrawNetwork] = (0, import_react11.useState)("");
3845
- const [withdrawSummary, setWithdrawSummary] = (0, import_react11.useState)(DEFAULT_WITHDRAW_SUMMARY);
3846
- const [withdrawalId, setWithdrawalId] = (0, import_react11.useState)(null);
3847
- const networkOptions = (0, import_react11.useMemo)(
4394
+ const [withdrawDestination, setWithdrawDestination] = (0, import_react13.useState)("");
4395
+ const [withdrawAmount, setWithdrawAmount] = (0, import_react13.useState)("");
4396
+ const [withdrawToken, setWithdrawToken] = (0, import_react13.useState)("USDC");
4397
+ const [withdrawNetwork, setWithdrawNetwork] = (0, import_react13.useState)("");
4398
+ const [withdrawSummary, setWithdrawSummary] = (0, import_react13.useState)(DEFAULT_WITHDRAW_SUMMARY);
4399
+ const [withdrawalId, setWithdrawalId] = (0, import_react13.useState)(null);
4400
+ const networkOptions = (0, import_react13.useMemo)(
3848
4401
  () => (supportedChains != null ? supportedChains : []).filter((chain) => WITHDRAWAL_SUPPORTED_CHAIN_IDS.has(chain.chainId)).map((chain) => ({
3849
4402
  value: String(chain.chainId),
3850
4403
  label: chain.name
@@ -3852,13 +4405,13 @@ function useWithdrawFlow(options) {
3852
4405
  [supportedChains]
3853
4406
  );
3854
4407
  const resolvedWithdrawNetwork = withdrawNetwork || ((_a = networkOptions[0]) == null ? void 0 : _a.value) || "";
3855
- (0, import_react11.useEffect)(() => {
4408
+ (0, import_react13.useEffect)(() => {
3856
4409
  if (!networkOptions.length) return;
3857
4410
  if (!withdrawNetwork || !networkOptions.some((option) => option.value === withdrawNetwork)) {
3858
4411
  setWithdrawNetwork(networkOptions[0].value);
3859
4412
  }
3860
4413
  }, [networkOptions, withdrawNetwork]);
3861
- const tokenOptions = (0, import_react11.useMemo)(() => {
4414
+ const tokenOptions = (0, import_react13.useMemo)(() => {
3862
4415
  var _a2, _b2, _c;
3863
4416
  const selectedChainId = Number(resolvedWithdrawNetwork);
3864
4417
  const supportedTokensForNetwork = (_b2 = (_a2 = supportedChains == null ? void 0 : supportedChains.find((chain) => chain.chainId === selectedChainId)) == null ? void 0 : _a2.tokens) != null ? _b2 : [];
@@ -3869,17 +4422,17 @@ function useWithdrawFlow(options) {
3869
4422
  }));
3870
4423
  }, [balances, resolvedWithdrawNetwork, supportedChains]);
3871
4424
  const resolvedWithdrawToken = tokenOptions.some((option) => option.value === withdrawToken) ? withdrawToken : ((_b = tokenOptions[0]) == null ? void 0 : _b.value) || "";
3872
- (0, import_react11.useEffect)(() => {
4425
+ (0, import_react13.useEffect)(() => {
3873
4426
  if (!tokenOptions.length) return;
3874
4427
  if (!tokenOptions.some((option) => option.value === withdrawToken)) {
3875
4428
  setWithdrawToken(tokenOptions[0].value);
3876
4429
  }
3877
4430
  }, [tokenOptions, withdrawToken]);
3878
- const selectedCashEntry = (0, import_react11.useMemo)(
4431
+ const selectedCashEntry = (0, import_react13.useMemo)(
3879
4432
  () => balances == null ? void 0 : balances.cash.find((cashEntry) => cashEntry.tokenSymbol === resolvedWithdrawToken),
3880
4433
  [balances, resolvedWithdrawToken]
3881
4434
  );
3882
- const selectedTokenDecimals = (0, import_react11.useMemo)(() => {
4435
+ const selectedTokenDecimals = (0, import_react13.useMemo)(() => {
3883
4436
  var _a2, _b2, _c, _d;
3884
4437
  const selectedChainId = Number(resolvedWithdrawNetwork);
3885
4438
  return (_d = (_c = (_b2 = (_a2 = supportedChains == null ? void 0 : supportedChains.find((chain) => chain.chainId === selectedChainId)) == null ? void 0 : _a2.tokens.find((token) => token.symbol === resolvedWithdrawToken)) == null ? void 0 : _b2.decimals) != null ? _c : selectedCashEntry == null ? void 0 : selectedCashEntry.decimals) != null ? _d : 6;
@@ -3889,18 +4442,18 @@ function useWithdrawFlow(options) {
3889
4442
  selectedCashEntry == null ? void 0 : selectedCashEntry.decimals,
3890
4443
  supportedChains
3891
4444
  ]);
3892
- const exactBalance = (0, import_react11.useMemo)(() => {
4445
+ const exactBalance = (0, import_react13.useMemo)(() => {
3893
4446
  if (!selectedCashEntry) return "0";
3894
4447
  return formatRawTokenAmount(selectedCashEntry.totalRaw, selectedCashEntry.decimals);
3895
4448
  }, [selectedCashEntry]);
3896
- const balanceDisplay = (0, import_react11.useMemo)(() => {
4449
+ const balanceDisplay = (0, import_react13.useMemo)(() => {
3897
4450
  if (!selectedCashEntry) return `0.00 ${resolvedWithdrawToken || withdrawToken}`;
3898
4451
  return `${formatRawTokenAmountForDisplay(
3899
4452
  selectedCashEntry.totalRaw,
3900
4453
  selectedCashEntry.decimals
3901
4454
  )} ${resolvedWithdrawToken}`;
3902
4455
  }, [resolvedWithdrawToken, selectedCashEntry, withdrawToken]);
3903
- const resetFlowState = (0, import_react11.useCallback)(() => {
4456
+ const resetFlowState = (0, import_react13.useCallback)(() => {
3904
4457
  setWithdrawDestination("");
3905
4458
  setWithdrawAmount("");
3906
4459
  setWithdrawToken("USDC");
@@ -3908,17 +4461,17 @@ function useWithdrawFlow(options) {
3908
4461
  setWithdrawSummary(DEFAULT_WITHDRAW_SUMMARY);
3909
4462
  setWithdrawalId(null);
3910
4463
  }, []);
3911
- const handleWithdrawOpenChange = (0, import_react11.useCallback)(
4464
+ const handleWithdrawOpenChange = (0, import_react13.useCallback)(
3912
4465
  (isOpen) => {
3913
4466
  if (!isOpen) resetFlowState();
3914
4467
  onOpenChange(isOpen);
3915
4468
  },
3916
4469
  [onOpenChange, resetFlowState]
3917
4470
  );
3918
- (0, import_react11.useEffect)(() => {
4471
+ (0, import_react13.useEffect)(() => {
3919
4472
  if (!open) resetFlowState();
3920
4473
  }, [open, resetFlowState]);
3921
- const handleWithdrawProvider = (0, import_react11.useCallback)(() => __async(null, null, function* () {
4474
+ const handleWithdrawProvider = (0, import_react13.useCallback)(() => __async(null, null, function* () {
3922
4475
  var _a2, _b2;
3923
4476
  const destinationChainId = Number(resolvedWithdrawNetwork);
3924
4477
  const trimmedDestination = withdrawDestination.trim();
@@ -4004,25 +4557,73 @@ function useWithdrawFlow(options) {
4004
4557
  onWithdrawAmountChange: setWithdrawAmount,
4005
4558
  onWithdrawTokenChange: setWithdrawToken,
4006
4559
  onWithdrawNetworkChange: setWithdrawNetwork,
4007
- onMaxClick: (0, import_react11.useCallback)(() => {
4560
+ onMaxClick: (0, import_react13.useCallback)(() => {
4008
4561
  setWithdrawAmount(exactBalance === "0" ? "0" : exactBalance);
4009
4562
  }, [exactBalance]),
4010
- onSelectWithdrawProvider: (0, import_react11.useCallback)(
4563
+ onSelectWithdrawProvider: (0, import_react13.useCallback)(
4011
4564
  (_providerId) => __async(null, null, function* () {
4012
4565
  return handleWithdrawProvider();
4013
4566
  }),
4014
4567
  [handleWithdrawProvider]
4015
4568
  ),
4016
- onDoneWithdraw: (0, import_react11.useCallback)(() => handleWithdrawOpenChange(false), [handleWithdrawOpenChange])
4569
+ onDoneWithdraw: (0, import_react13.useCallback)(() => handleWithdrawOpenChange(false), [handleWithdrawOpenChange])
4017
4570
  };
4018
4571
  }
4019
4572
 
4573
+ // src/withdraw/use-withdraw-estimate.ts
4574
+ var import_react14 = require("react");
4575
+ function useWithdrawEstimate({
4576
+ amount,
4577
+ selectedToken,
4578
+ selectedNetwork
4579
+ }) {
4580
+ return (0, import_react14.useMemo)(() => {
4581
+ const numAmount = Number(amount);
4582
+ if (!amount || isNaN(numAmount) || numAmount <= 0 || !selectedToken || !selectedNetwork) {
4583
+ return null;
4584
+ }
4585
+ const network = selectedNetwork.toLowerCase();
4586
+ let feeVal = 0.1;
4587
+ let reserveVal = 0.2;
4588
+ if (network === "1" || network === "mainnet" || network === "ethereum") {
4589
+ feeVal = 1.22;
4590
+ reserveVal = 0.3;
4591
+ } else if (network === "137" || network === "polygon") {
4592
+ feeVal = 0.05;
4593
+ reserveVal = 0.15;
4594
+ } else if (network === "42161" || network === "arbitrum") {
4595
+ feeVal = 0.05;
4596
+ reserveVal = 0.15;
4597
+ } else if (network === "8453" || network === "base") {
4598
+ feeVal = 0.05;
4599
+ reserveVal = 0.15;
4600
+ } else if (network === "56" || network === "bnb" || network === "bsc") {
4601
+ feeVal = 0.1;
4602
+ reserveVal = 0.2;
4603
+ } else if (network === "792703809" || network === "solana") {
4604
+ feeVal = 0.01;
4605
+ reserveVal = 0.04;
4606
+ } else if (network === "1337" || network === "hyperliquid") {
4607
+ feeVal = 0.02;
4608
+ reserveVal = 0.08;
4609
+ }
4610
+ const youReceiveVal = Math.max(0, numAmount - feeVal);
4611
+ return {
4612
+ estimatedFees: `~$${feeVal.toFixed(2)}`,
4613
+ networkReserve: `~$${reserveVal.toFixed(2)}`,
4614
+ youReceive: `~${youReceiveVal.toFixed(2)} ${selectedToken}`
4615
+ };
4616
+ }, [amount, selectedToken, selectedNetwork]);
4617
+ }
4618
+
4020
4619
  // src/withdraw/use-withdrawal-lifecycle.ts
4021
- var import_react12 = require("react");
4620
+ var import_react15 = require("react");
4022
4621
  var import_react_query15 = require("@tanstack/react-query");
4023
- var INITIAL_STATE = {
4622
+ var INITIAL_STATE2 = {
4024
4623
  pending: true,
4025
4624
  status: null,
4625
+ requestedAmountRaw: null,
4626
+ completedAmountRaw: null,
4026
4627
  terminal: false,
4027
4628
  lastLeg: null,
4028
4629
  legs: [],
@@ -4053,14 +4654,16 @@ var mergeLegs = (prev, snapshot, delta) => {
4053
4654
  return next;
4054
4655
  };
4055
4656
  var restToLifecycleState = (response) => {
4056
- var _a;
4657
+ var _a, _b;
4057
4658
  return {
4058
4659
  pending: false,
4059
4660
  status: response.status,
4661
+ requestedAmountRaw: response.requested.amountRaw,
4662
+ completedAmountRaw: (_a = response.completedAmountRaw) != null ? _a : null,
4060
4663
  terminal: response.status === "completed" || response.status === "partial" || response.status === "failed",
4061
4664
  lastLeg: null,
4062
4665
  legs: response.legs.map(restLegToWsLeg),
4063
- errorMessage: (_a = response.errorMessage) != null ? _a : null,
4666
+ errorMessage: (_b = response.errorMessage) != null ? _b : null,
4064
4667
  // No server timestamp on the REST response — we use 0 as "older than any
4065
4668
  // WS timestamp" so a subsequent WS event always wins. Callers that read
4066
4669
  // `timestamp` should treat 0/null interchangeably as "unset".
@@ -4071,14 +4674,14 @@ function useWithdrawalLifecycle(withdrawalId) {
4071
4674
  const client = useAggClient();
4072
4675
  const wsConnected = useAggWebSocketConnectionState();
4073
4676
  const queryClient = (0, import_react_query15.useQueryClient)();
4074
- const [state, setState] = (0, import_react12.useState)(INITIAL_STATE);
4075
- const stateRef = (0, import_react12.useRef)(state);
4677
+ const [state, setState] = (0, import_react15.useState)(INITIAL_STATE2);
4678
+ const stateRef = (0, import_react15.useRef)(state);
4076
4679
  stateRef.current = state;
4077
- const balanceRefetchedForRef = (0, import_react12.useRef)(null);
4078
- (0, import_react12.useEffect)(() => {
4079
- setState(INITIAL_STATE);
4680
+ const balanceRefetchedForRef = (0, import_react15.useRef)(null);
4681
+ (0, import_react15.useEffect)(() => {
4682
+ setState(INITIAL_STATE2);
4080
4683
  }, [withdrawalId]);
4081
- (0, import_react12.useEffect)(() => {
4684
+ (0, import_react15.useEffect)(() => {
4082
4685
  if (!withdrawalId) return;
4083
4686
  let cancelled = false;
4084
4687
  (() => __async(null, null, function* () {
@@ -4097,17 +4700,19 @@ function useWithdrawalLifecycle(withdrawalId) {
4097
4700
  cancelled = true;
4098
4701
  };
4099
4702
  }, [client, withdrawalId, wsConnected]);
4100
- const handler = (0, import_react12.useMemo)(() => {
4703
+ const handler = (0, import_react15.useMemo)(() => {
4101
4704
  if (!withdrawalId) return null;
4102
4705
  return (msg) => {
4103
4706
  if (msg.withdrawalId !== withdrawalId) return;
4104
4707
  setState((prev) => {
4105
- var _a, _b;
4708
+ var _a, _b, _c, _d;
4106
4709
  return {
4107
4710
  pending: false,
4108
4711
  status: msg.status,
4712
+ requestedAmountRaw: (_a = msg.requestedAmountRaw) != null ? _a : prev.requestedAmountRaw,
4713
+ completedAmountRaw: (_b = msg.completedAmountRaw) != null ? _b : prev.completedAmountRaw,
4109
4714
  terminal: msg.terminal,
4110
- lastLeg: (_a = msg.leg) != null ? _a : null,
4715
+ lastLeg: (_c = msg.leg) != null ? _c : null,
4111
4716
  // `legs[]` is the cumulative server-known truth. Snapshots
4112
4717
  // (`pending` / terminal rollup) carry a full `legs[]` and replace
4113
4718
  // it. Intermediate per-leg deltas carry only `leg` (no `legs[]`)
@@ -4115,23 +4720,23 @@ function useWithdrawalLifecycle(withdrawalId) {
4115
4720
  // (sourceChainId, destChainId, type) so the timeline UI doesn't
4116
4721
  // collapse to empty between snapshots.
4117
4722
  legs: mergeLegs(prev.legs, msg.legs, msg.leg),
4118
- errorMessage: (_b = msg.errorMessage) != null ? _b : null,
4723
+ errorMessage: (_d = msg.errorMessage) != null ? _d : null,
4119
4724
  timestamp: msg.timestamp
4120
4725
  };
4121
4726
  });
4122
4727
  };
4123
4728
  }, [withdrawalId]);
4124
4729
  useOnWithdrawalLifecycle(handler);
4125
- (0, import_react12.useEffect)(() => {
4730
+ (0, import_react15.useEffect)(() => {
4126
4731
  if (!withdrawalId) return;
4127
4732
  if (!state.terminal) return;
4128
4733
  if (balanceRefetchedForRef.current === withdrawalId) return;
4129
4734
  balanceRefetchedForRef.current = withdrawalId;
4130
- invalidateBalanceQueries(queryClient);
4735
+ invalidateUserMoneyState(queryClient);
4131
4736
  client.syncManagedBalances().catch(() => {
4132
4737
  });
4133
4738
  }, [client, queryClient, state.terminal, withdrawalId]);
4134
- const reset = (0, import_react12.useCallback)(() => setState(INITIAL_STATE), []);
4739
+ const reset = (0, import_react15.useCallback)(() => setState(INITIAL_STATE2), []);
4135
4740
  return { state, reset };
4136
4741
  }
4137
4742
 
@@ -4139,7 +4744,7 @@ function useWithdrawalLifecycle(withdrawalId) {
4139
4744
  var import_sdk4 = require("@agg-build/sdk");
4140
4745
 
4141
4746
  // src/use-geo-block.ts
4142
- var import_react13 = require("react");
4747
+ var import_react16 = require("react");
4143
4748
  var DEFAULT_STATE = {
4144
4749
  isLocationBlocked: false,
4145
4750
  isTradingBlocked: false,
@@ -4147,7 +4752,7 @@ var DEFAULT_STATE = {
4147
4752
  };
4148
4753
  function useGeoBlock() {
4149
4754
  var _a, _b;
4150
- const authContext = (0, import_react13.useContext)(AggAuthContext);
4755
+ const authContext = (0, import_react16.useContext)(AggAuthContext);
4151
4756
  if (process.env.NEXT_PUBLIC_GEO_BLOCK_DISABLE === "true") return DEFAULT_STATE;
4152
4757
  const isBlocked = (_b = (_a = authContext == null ? void 0 : authContext.user) == null ? void 0 : _a.isLocationBlocked) != null ? _b : false;
4153
4758
  if (!isBlocked) return DEFAULT_STATE;
@@ -4159,7 +4764,7 @@ function useGeoBlock() {
4159
4764
  }
4160
4765
 
4161
4766
  // src/use-agg-auth.ts
4162
- var import_react14 = require("react");
4767
+ var import_react17 = require("react");
4163
4768
  function useAggAuth(options = {}) {
4164
4769
  const {
4165
4770
  isAuthenticated,
@@ -4169,7 +4774,7 @@ function useAggAuth(options = {}) {
4169
4774
  signIn: signInWithProvider,
4170
4775
  signOut
4171
4776
  } = useAggAuthContext();
4172
- const signIn = (0, import_react14.useCallback)(
4777
+ const signIn = (0, import_react17.useCallback)(
4173
4778
  (statement) => __async(null, null, function* () {
4174
4779
  if (!options.signMessage) {
4175
4780
  throw new Error(
@@ -4193,11 +4798,11 @@ function useAggAuth(options = {}) {
4193
4798
  }
4194
4799
 
4195
4800
  // src/use-link-account.ts
4196
- var import_react15 = require("react");
4801
+ var import_react18 = require("react");
4197
4802
  function useLinkAccount() {
4198
4803
  const client = useAggClient();
4199
- const [isLoading, setIsLoading] = (0, import_react15.useState)(false);
4200
- const [error, setError] = (0, import_react15.useState)(null);
4804
+ const [isLoading, setIsLoading] = (0, import_react18.useState)(false);
4805
+ const [error, setError] = (0, import_react18.useState)(null);
4201
4806
  const run = (fn) => {
4202
4807
  setIsLoading(true);
4203
4808
  setError(null);
@@ -4207,11 +4812,11 @@ function useLinkAccount() {
4207
4812
  throw err;
4208
4813
  }).finally(() => setIsLoading(false));
4209
4814
  };
4210
- const startLink = (0, import_react15.useCallback)(
4815
+ const startLink = (0, import_react18.useCallback)(
4211
4816
  (body) => run(() => client.linkAccount(body)),
4212
4817
  [client]
4213
4818
  );
4214
- const confirmLink = (0, import_react15.useCallback)(
4819
+ const confirmLink = (0, import_react18.useCallback)(
4215
4820
  (token) => run(() => client.linkAccountConfirm(token)),
4216
4821
  [client]
4217
4822
  );
@@ -4228,17 +4833,19 @@ var requestAggAuthChooserOpen = () => {
4228
4833
  // src/use-categories.ts
4229
4834
  var import_react_query16 = require("@tanstack/react-query");
4230
4835
  function useCategories(options) {
4231
- var _a, _b, _c, _d;
4836
+ var _a, _b, _c, _d, _e, _f;
4232
4837
  const client = useAggClient();
4233
- const enabled = (_a = options == null ? void 0 : options.enabled) != null ? _a : true;
4234
- const limit = (_b = options == null ? void 0 : options.limit) != null ? _b : 20;
4838
+ const queryKeyScope = (_a = options == null ? void 0 : options.queryKeyScope) != null ? _a : "categories";
4839
+ const parentId = (_b = options == null ? void 0 : options.parentId) != null ? _b : null;
4840
+ const enabled = (_c = options == null ? void 0 : options.enabled) != null ? _c : true;
4841
+ const limit = (_d = options == null ? void 0 : options.limit) != null ? _d : 20;
4235
4842
  const query = (0, import_react_query16.useInfiniteQuery)({
4236
- queryKey: ["categories", limit],
4843
+ queryKey: [queryKeyScope, "parent", parentId != null ? parentId : "__root__", limit],
4237
4844
  queryFn: (_0) => __async(null, [_0], function* ({ pageParam }) {
4238
- const res = yield client.getCategories({
4845
+ const res = yield client.getCategories(__spreadValues({
4239
4846
  limit,
4240
4847
  cursor: pageParam
4241
- });
4848
+ }, parentId != null ? { parentId } : {}));
4242
4849
  return res;
4243
4850
  }),
4244
4851
  initialPageParam: void 0,
@@ -4248,7 +4855,7 @@ function useCategories(options) {
4248
4855
  },
4249
4856
  enabled
4250
4857
  });
4251
- const categories = (_d = (_c = query.data) == null ? void 0 : _c.pages.flatMap((p) => p.data)) != null ? _d : [];
4858
+ const categories = (_f = (_e = query.data) == null ? void 0 : _e.pages.flatMap((p) => p.data)) != null ? _f : [];
4252
4859
  const hasNextPage = !!query.hasNextPage;
4253
4860
  return __spreadProps(__spreadValues({}, query), {
4254
4861
  categories,
@@ -4257,10 +4864,10 @@ function useCategories(options) {
4257
4864
  }
4258
4865
 
4259
4866
  // src/use-debounced-value.ts
4260
- var import_react16 = require("react");
4867
+ var import_react19 = require("react");
4261
4868
  function useDebouncedValue(value, delay) {
4262
- const [debouncedValue, setDebouncedValue] = (0, import_react16.useState)(value);
4263
- (0, import_react16.useEffect)(() => {
4869
+ const [debouncedValue, setDebouncedValue] = (0, import_react19.useState)(value);
4870
+ (0, import_react19.useEffect)(() => {
4264
4871
  const timeoutId = window.setTimeout(() => {
4265
4872
  setDebouncedValue(value);
4266
4873
  }, delay);
@@ -4276,11 +4883,22 @@ var import_react_query17 = require("@tanstack/react-query");
4276
4883
  function useExecutionOrders(options = {}) {
4277
4884
  var _a, _b;
4278
4885
  const client = useAggClient();
4279
- const { status, limit = 50, enabled = true, refetchIntervalMs = false } = options;
4886
+ const {
4887
+ status,
4888
+ orderId,
4889
+ quoteId,
4890
+ limit = 50,
4891
+ enabled = true,
4892
+ refetchIntervalMs = false
4893
+ } = options;
4280
4894
  const query = (0, import_react_query17.useInfiniteQuery)({
4281
- queryKey: ["execution-orders", status != null ? status : "all", limit],
4895
+ // quoteId + orderId are part of the cache key — different filters
4896
+ // produce different result sets, so they have to vary the key.
4897
+ queryKey: ["execution-orders", status != null ? status : "all", quoteId != null ? quoteId : null, orderId != null ? orderId : null, limit],
4282
4898
  queryFn: ({ pageParam }) => client.getExecutionOrders({
4283
4899
  status,
4900
+ orderId,
4901
+ quoteId,
4284
4902
  limit,
4285
4903
  cursor: pageParam
4286
4904
  }),
@@ -4302,10 +4920,36 @@ function useExecutionOrders(options = {}) {
4302
4920
 
4303
4921
  // src/use-user-activity.ts
4304
4922
  var import_react_query18 = require("@tanstack/react-query");
4923
+ var DEFAULT_PENDING_REFETCH_INTERVAL_MS = 15e3;
4924
+ var PENDING_ACTIVITY_STATUSES = /* @__PURE__ */ new Set([
4925
+ "pending",
4926
+ // trade pre-fill lifecycle
4927
+ "signing",
4928
+ "pending_bridge",
4929
+ "submitting",
4930
+ "submitted",
4931
+ // withdrawal lifecycle
4932
+ "bridging",
4933
+ "transferring"
4934
+ ]);
4935
+ var hasPendingActivity = (pages) => {
4936
+ if (!pages) return false;
4937
+ for (const page of pages) {
4938
+ for (const item of page.data) {
4939
+ if (PENDING_ACTIVITY_STATUSES.has(item.status.toLowerCase())) return true;
4940
+ }
4941
+ }
4942
+ return false;
4943
+ };
4305
4944
  function useUserActivity(options = {}) {
4306
4945
  var _a, _b;
4307
4946
  const client = useAggClient();
4308
- const { type, limit = 50, enabled = true } = options;
4947
+ const {
4948
+ type,
4949
+ limit = 50,
4950
+ enabled = true,
4951
+ pendingRefetchIntervalMs = DEFAULT_PENDING_REFETCH_INTERVAL_MS
4952
+ } = options;
4309
4953
  const query = (0, import_react_query18.useInfiniteQuery)({
4310
4954
  queryKey: ["user-activity", type != null ? type : "all", limit],
4311
4955
  queryFn: ({ pageParam }) => client.getUserActivity({
@@ -4318,7 +4962,17 @@ function useUserActivity(options = {}) {
4318
4962
  var _a2;
4319
4963
  return lastPage.hasMore ? (_a2 = lastPage.nextCursor) != null ? _a2 : void 0 : void 0;
4320
4964
  },
4321
- enabled
4965
+ enabled,
4966
+ // Keep the previously-loaded pages visible while a refetch is in
4967
+ // flight (typically after a deposit / withdraw cache invalidation).
4968
+ // Without this the feed flashes to the skeleton mid-session, which
4969
+ // is worse UX than briefly showing slightly-stale rows.
4970
+ placeholderData: import_react_query18.keepPreviousData,
4971
+ refetchInterval: (q) => {
4972
+ if (pendingRefetchIntervalMs === false) return false;
4973
+ const data = q.state.data;
4974
+ return hasPendingActivity(data == null ? void 0 : data.pages) ? pendingRefetchIntervalMs : false;
4975
+ }
4322
4976
  });
4323
4977
  const activities = (_b = (_a = query.data) == null ? void 0 : _a.pages.flatMap((page) => page.data)) != null ? _b : [];
4324
4978
  const hasNextPage = !!query.hasNextPage;
@@ -4329,13 +4983,13 @@ function useUserActivity(options = {}) {
4329
4983
  }
4330
4984
 
4331
4985
  // src/use-external-id.ts
4332
- var import_react17 = require("react");
4986
+ var import_react20 = require("react");
4333
4987
  function useExternalId(options = {}) {
4334
4988
  const client = useAggClient();
4335
4989
  const { onSuccess, onError: onErrorCb } = options;
4336
- const [isLoading, setIsLoading] = (0, import_react17.useState)(false);
4337
- const [error, setError] = (0, import_react17.useState)(null);
4338
- const linkExternalId = (0, import_react17.useCallback)(
4990
+ const [isLoading, setIsLoading] = (0, import_react20.useState)(false);
4991
+ const [error, setError] = (0, import_react20.useState)(null);
4992
+ const linkExternalId = (0, import_react20.useCallback)(
4339
4993
  (assertion) => __async(null, null, function* () {
4340
4994
  setIsLoading(true);
4341
4995
  setError(null);
@@ -4386,17 +5040,17 @@ function useExecutionPositions(options = {}) {
4386
5040
  }
4387
5041
 
4388
5042
  // src/use-live-candle-overlay.ts
4389
- var import_react21 = require("react");
5043
+ var import_react24 = require("react");
4390
5044
 
4391
5045
  // src/use-live-candles.ts
4392
- var import_react20 = require("react");
5046
+ var import_react23 = require("react");
4393
5047
  var import_sdk3 = require("@agg-build/sdk");
4394
5048
 
4395
5049
  // src/use-market-chart.ts
4396
5050
  var import_react_query20 = require("@tanstack/react-query");
4397
5051
 
4398
5052
  // src/market-data/subscription.ts
4399
- var import_react18 = require("react");
5053
+ var import_react21 = require("react");
4400
5054
  function useMarketDataSubscription({
4401
5055
  marketId,
4402
5056
  additionalMarketIds,
@@ -4405,7 +5059,7 @@ function useMarketDataSubscription({
4405
5059
  trades = false
4406
5060
  }) {
4407
5061
  const ws = useAggWebSocket();
4408
- const allIds = (0, import_react18.useMemo)(() => {
5062
+ const allIds = (0, import_react21.useMemo)(() => {
4409
5063
  const ids = /* @__PURE__ */ new Set();
4410
5064
  if (marketId) ids.add(marketId);
4411
5065
  if (additionalMarketIds) {
@@ -4416,7 +5070,7 @@ function useMarketDataSubscription({
4416
5070
  return [...ids];
4417
5071
  }, [marketId, additionalMarketIds]);
4418
5072
  const stableKey = allIds.join("|");
4419
- (0, import_react18.useEffect)(() => {
5073
+ (0, import_react21.useEffect)(() => {
4420
5074
  if (!ws || !allIds.length || !enabled || !orderbook && !trades) return;
4421
5075
  const unsubscribers = [];
4422
5076
  for (const id of allIds) {
@@ -4453,24 +5107,23 @@ function useMarketChart(options) {
4453
5107
  endTs = null,
4454
5108
  countBack = null,
4455
5109
  enabled = true,
4456
- live
5110
+ live,
5111
+ refetchIntervalMs = null,
5112
+ rangeKey
4457
5113
  } = options;
5114
+ const resolvedRangeKey = rangeKey != null ? rangeKey : interval;
4458
5115
  const liveEnabled = live != null ? live : enableLiveUpdates;
4459
5116
  const outcomeIds = (() => {
4460
5117
  const ids = /* @__PURE__ */ new Set();
4461
- if (marketId) {
4462
- ids.add(marketId);
4463
- }
5118
+ if (marketId) ids.add(marketId);
4464
5119
  if (venueMarketIds) {
4465
5120
  for (const venueMarketId of venueMarketIds) {
4466
- if (venueMarketId) {
4467
- ids.add(venueMarketId);
4468
- }
5121
+ if (venueMarketId) ids.add(venueMarketId);
4469
5122
  }
4470
5123
  }
4471
- return [...ids];
5124
+ return [...ids].sort();
4472
5125
  })();
4473
- const primaryOutcomeId = (_a = outcomeIds[0]) != null ? _a : null;
5126
+ const primaryOutcomeId = (_a = marketId != null ? marketId : venueMarketIds == null ? void 0 : venueMarketIds.find(Boolean)) != null ? _a : null;
4474
5127
  const isQueryEnabled = enabled && outcomeIds.length > 0 && endTs != null && (startTs != null || countBack != null);
4475
5128
  useMarketDataSubscription({
4476
5129
  marketId: primaryOutcomeId,
@@ -4481,7 +5134,11 @@ function useMarketChart(options) {
4481
5134
  });
4482
5135
  const queries = (0, import_react_query20.useQueries)({
4483
5136
  queries: outcomeIds.map((outcomeId) => ({
4484
- queryKey: marketDataKeys.chart(outcomeId, interval, startTs, endTs, countBack),
5137
+ // Cache key is intentionally time-free. The rolling window's
5138
+ // startTs/endTs advance on every bucket but the user expects the same
5139
+ // chart on revisit — see comment on `marketDataKeys.chart`. queryFn
5140
+ // closes over the current window so refetches still fetch fresh data.
5141
+ queryKey: marketDataKeys.chart(outcomeId, interval, resolvedRangeKey, countBack),
4485
5142
  queryFn: (_0) => __async(null, [_0], function* ({ signal }) {
4486
5143
  const response = yield client.getChartBars(
4487
5144
  {
@@ -4502,11 +5159,17 @@ function useMarketChart(options) {
4502
5159
  });
4503
5160
  }),
4504
5161
  enabled: isQueryEnabled,
4505
- staleTime: 3e4,
4506
- gcTime: 5 * 6e4,
5162
+ // Treat data as fresh for one bucket — within that window the
5163
+ // existing entry serves remounts without a refetch, and the
5164
+ // `refetchInterval` below schedules the next bucket's refresh.
5165
+ staleTime: refetchIntervalMs != null && refetchIntervalMs > 0 ? refetchIntervalMs : 3e4,
5166
+ // 60 min — survives typical tab/page revisits without re-fetching.
5167
+ gcTime: 60 * 6e4,
4507
5168
  refetchOnWindowFocus: false,
4508
5169
  retry: 1,
4509
- placeholderData: import_react_query20.keepPreviousData
5170
+ placeholderData: import_react_query20.keepPreviousData,
5171
+ refetchInterval: refetchIntervalMs != null && refetchIntervalMs > 0 ? refetchIntervalMs : false,
5172
+ refetchIntervalInBackground: false
4510
5173
  }))
4511
5174
  });
4512
5175
  const successfulDatasets = queries.flatMap((query) => {
@@ -4535,13 +5198,13 @@ function useMarketChart(options) {
4535
5198
  }
4536
5199
 
4537
5200
  // src/use-live-market-stores.ts
4538
- var import_react19 = require("react");
5201
+ var import_react22 = require("react");
4539
5202
  function useLiveMarketStores(venueMarketIds) {
4540
5203
  const ws = useAggWebSocket();
4541
- const [, forceRender] = (0, import_react19.useReducer)((c) => c + 1, 0);
4542
- const subsRef = (0, import_react19.useRef)(/* @__PURE__ */ new Map());
4543
- const stableKey = (0, import_react19.useMemo)(() => venueMarketIds.slice().sort().join("|"), [venueMarketIds]);
4544
- (0, import_react19.useEffect)(() => {
5204
+ const [, forceRender] = (0, import_react22.useReducer)((c) => c + 1, 0);
5205
+ const subsRef = (0, import_react22.useRef)(/* @__PURE__ */ new Map());
5206
+ const stableKey = (0, import_react22.useMemo)(() => venueMarketIds.slice().sort().join("|"), [venueMarketIds]);
5207
+ (0, import_react22.useEffect)(() => {
4545
5208
  if (!ws || venueMarketIds.length === 0) return;
4546
5209
  const current = subsRef.current;
4547
5210
  const desired = new Set(venueMarketIds);
@@ -4578,7 +5241,7 @@ function candleToLive(c, source) {
4578
5241
  function useLiveCandles(options) {
4579
5242
  var _a;
4580
5243
  const { market, interval = "5m", mode = "venue", startTs, endTs } = options;
4581
- const venueMarketIds = (0, import_react20.useMemo)(() => {
5244
+ const venueMarketIds = (0, import_react23.useMemo)(() => {
4582
5245
  if (!market) return [];
4583
5246
  if (mode === "venue") return [market.id];
4584
5247
  const ids = [market.id];
@@ -4598,7 +5261,7 @@ function useLiveCandles(options) {
4598
5261
  endTs: endTs != null ? endTs : null,
4599
5262
  enabled: !!restMarketId && startTs != null && endTs != null
4600
5263
  });
4601
- const liveData = (0, import_react20.useMemo)(() => {
5264
+ const liveData = (0, import_react23.useMemo)(() => {
4602
5265
  if (builders2.length === 0) return { closed: [], forming: null };
4603
5266
  if (mode === "venue" || builders2.length === 1) {
4604
5267
  return {
@@ -4611,7 +5274,7 @@ function useLiveCandles(options) {
4611
5274
  forming: (0, import_sdk3.mergeCandles)(builders2.map((b) => b.getForming(interval)))
4612
5275
  };
4613
5276
  }, [builders2, interval, mode]);
4614
- const candles = (0, import_react20.useMemo)(() => {
5277
+ const candles = (0, import_react23.useMemo)(() => {
4615
5278
  const byTime = /* @__PURE__ */ new Map();
4616
5279
  if (chartData) {
4617
5280
  const venueEntries = Object.values(chartData.venues);
@@ -4636,7 +5299,7 @@ function useLiveCandles(options) {
4636
5299
  merged.sort((a, b) => a.time - b.time);
4637
5300
  return merged;
4638
5301
  }, [chartData, liveData.closed]);
4639
- const liveCandle = (0, import_react20.useMemo)(() => {
5302
+ const liveCandle = (0, import_react23.useMemo)(() => {
4640
5303
  if (!liveData.forming) return null;
4641
5304
  return candleToLive(liveData.forming, "live");
4642
5305
  }, [liveData.forming]);
@@ -4684,7 +5347,7 @@ function useLiveCandleOverlay(options) {
4684
5347
  startTs,
4685
5348
  endTs
4686
5349
  });
4687
- const scaleCandle = (0, import_react21.useCallback)(
5350
+ const scaleCandle = (0, import_react24.useCallback)(
4688
5351
  (candle) => ({
4689
5352
  time: candle.time,
4690
5353
  open: candle.o * scale,
@@ -4695,8 +5358,8 @@ function useLiveCandleOverlay(options) {
4695
5358
  }),
4696
5359
  [scale]
4697
5360
  );
4698
- const scaledCandles = (0, import_react21.useMemo)(() => rawCandles.map(scaleCandle), [rawCandles, scaleCandle]);
4699
- const liveCandle = (0, import_react21.useMemo)(() => rawLive ? scaleCandle(rawLive) : null, [rawLive, scaleCandle]);
5361
+ const scaledCandles = (0, import_react24.useMemo)(() => rawCandles.map(scaleCandle), [rawCandles, scaleCandle]);
5362
+ const liveCandle = (0, import_react24.useMemo)(() => rawLive ? scaleCandle(rawLive) : null, [rawLive, scaleCandle]);
4700
5363
  return {
4701
5364
  liveCandle,
4702
5365
  scaledCandles,
@@ -4707,7 +5370,7 @@ function useLiveCandleOverlay(options) {
4707
5370
  }
4708
5371
 
4709
5372
  // src/use-event-orderbook-data.ts
4710
- var import_react22 = require("react");
5373
+ var import_react25 = require("react");
4711
5374
  function extractSelectedOutcomeIds(selectedMarket) {
4712
5375
  var _a, _b, _c;
4713
5376
  if (!selectedMarket) return [];
@@ -4727,17 +5390,17 @@ function useEventOrderbookData(venueMarkets, selectedMarketId) {
4727
5390
  const {
4728
5391
  features: { enableLiveUpdates }
4729
5392
  } = useAggUiConfig();
4730
- const selectedMarket = (0, import_react22.useMemo)(() => {
5393
+ const selectedMarket = (0, import_react25.useMemo)(() => {
4731
5394
  var _a;
4732
5395
  if (!selectedMarketId || !(venueMarkets == null ? void 0 : venueMarkets.length)) return null;
4733
5396
  return (_a = venueMarkets.find((m) => m.id === selectedMarketId)) != null ? _a : null;
4734
5397
  }, [venueMarkets, selectedMarketId]);
4735
- const selectedOutcomeIds = (0, import_react22.useMemo)(
5398
+ const selectedOutcomeIds = (0, import_react25.useMemo)(
4736
5399
  () => extractSelectedOutcomeIds(selectedMarket),
4737
5400
  [selectedMarket]
4738
5401
  );
4739
5402
  const selectedKey = selectedOutcomeIds.join("|");
4740
- (0, import_react22.useEffect)(() => {
5403
+ (0, import_react25.useEffect)(() => {
4741
5404
  if (!ws || !enableLiveUpdates || !selectedOutcomeIds.length) return;
4742
5405
  const unsubscribers = selectedOutcomeIds.map((id) => ws.subscribe(id, "orderbook"));
4743
5406
  return () => {
@@ -4829,7 +5492,7 @@ function useLiveMarket(canonicalMarketId) {
4829
5492
  }
4830
5493
 
4831
5494
  // src/use-live-outcome-prices.ts
4832
- var import_react23 = require("react");
5495
+ var import_react26 = require("react");
4833
5496
  var import_react_query22 = require("@tanstack/react-query");
4834
5497
  var EMPTY_PRICES = /* @__PURE__ */ new Map();
4835
5498
  var buildMidpointFingerprint = (outcomeIds, queries) => {
@@ -4845,7 +5508,7 @@ function useLiveOutcomePrices(venueMarkets) {
4845
5508
  const {
4846
5509
  features: { enableLiveUpdates }
4847
5510
  } = useAggUiConfig();
4848
- const outcomeIds = (0, import_react23.useMemo)(() => {
5511
+ const outcomeIds = (0, import_react26.useMemo)(() => {
4849
5512
  var _a;
4850
5513
  if (!(venueMarkets == null ? void 0 : venueMarkets.length)) return [];
4851
5514
  const ids = /* @__PURE__ */ new Set();
@@ -4867,11 +5530,11 @@ function useLiveOutcomePrices(venueMarkets) {
4867
5530
  }))
4868
5531
  });
4869
5532
  const fingerprint = buildMidpointFingerprint(outcomeIds, queries);
4870
- const prevRef = (0, import_react23.useRef)({
5533
+ const prevRef = (0, import_react26.useRef)({
4871
5534
  fingerprint: "",
4872
5535
  prices: EMPTY_PRICES
4873
5536
  });
4874
- const data = (0, import_react23.useMemo)(() => {
5537
+ const data = (0, import_react26.useMemo)(() => {
4875
5538
  var _a, _b, _c, _d;
4876
5539
  if (!(venueMarkets == null ? void 0 : venueMarkets.length)) return EMPTY_PRICES;
4877
5540
  if (fingerprint === prevRef.current.fingerprint) {
@@ -4904,6 +5567,128 @@ function findLivePriceById(livePrices, id) {
4904
5567
  return livePrices.get(id);
4905
5568
  }
4906
5569
 
5570
+ // src/use-live-best-prices.ts
5571
+ var import_react27 = require("react");
5572
+ var import_react_query23 = require("@tanstack/react-query");
5573
+ var EMPTY = /* @__PURE__ */ new Map();
5574
+ var extractOutcomeBestPrices = (state) => {
5575
+ var _a, _b;
5576
+ const ob = state == null ? void 0 : state.orderbook;
5577
+ if (!ob) return {};
5578
+ const bestBid = (_a = ob.bids[0]) == null ? void 0 : _a.price;
5579
+ const bestAsk = (_b = ob.asks[0]) == null ? void 0 : _b.price;
5580
+ return {
5581
+ bestBid: bestBid != null ? bestBid : void 0,
5582
+ bestAsk: bestAsk != null ? bestAsk : void 0
5583
+ };
5584
+ };
5585
+ var buildFingerprint = (outcomeIds, queries) => {
5586
+ var _a, _b, _c, _d;
5587
+ const parts = [];
5588
+ for (let i = 0; i < outcomeIds.length; i++) {
5589
+ const ob = (_b = (_a = queries[i]) == null ? void 0 : _a.data) == null ? void 0 : _b.orderbook;
5590
+ const bid = (_c = ob == null ? void 0 : ob.bids[0]) == null ? void 0 : _c.price;
5591
+ const ask = (_d = ob == null ? void 0 : ob.asks[0]) == null ? void 0 : _d.price;
5592
+ parts.push(`${outcomeIds[i]}:${bid != null ? bid : "_"}:${ask != null ? ask : "_"}`);
5593
+ }
5594
+ return parts.join("|");
5595
+ };
5596
+ function useLiveBestPrices(venueMarkets) {
5597
+ const {
5598
+ features: { enableLiveUpdates }
5599
+ } = useAggUiConfig();
5600
+ const outcomeIds = (0, import_react27.useMemo)(() => {
5601
+ var _a, _b;
5602
+ if (!(venueMarkets == null ? void 0 : venueMarkets.length)) return [];
5603
+ const ids = /* @__PURE__ */ new Set();
5604
+ for (const vm of venueMarkets) {
5605
+ for (const outcome of (_a = vm.venueMarketOutcomes) != null ? _a : []) {
5606
+ if (outcome.id) ids.add(outcome.id);
5607
+ for (const ref of (_b = outcome.matchedVenueMarketOutcomes) != null ? _b : []) {
5608
+ if (ref.venueMarketOutcomeId) ids.add(ref.venueMarketOutcomeId);
5609
+ }
5610
+ }
5611
+ }
5612
+ return [...ids].sort();
5613
+ }, [venueMarkets]);
5614
+ const queries = (0, import_react_query23.useQueries)({
5615
+ queries: outcomeIds.map((id) => ({
5616
+ queryKey: marketDataKeys.live(id),
5617
+ queryFn: () => createMarketLiveState(id),
5618
+ enabled: false,
5619
+ staleTime: Infinity,
5620
+ gcTime: 5 * 6e4,
5621
+ initialData: () => createMarketLiveState(id)
5622
+ }))
5623
+ });
5624
+ const fingerprint = buildFingerprint(outcomeIds, queries);
5625
+ const prevRef = (0, import_react27.useRef)({
5626
+ fingerprint: "",
5627
+ result: EMPTY
5628
+ });
5629
+ return (0, import_react27.useMemo)(() => {
5630
+ var _a, _b, _c, _d;
5631
+ if (!(venueMarkets == null ? void 0 : venueMarkets.length) || !enableLiveUpdates) return EMPTY;
5632
+ if (fingerprint === prevRef.current.fingerprint) return prevRef.current.result;
5633
+ const perOutcome = /* @__PURE__ */ new Map();
5634
+ for (let i = 0; i < outcomeIds.length; i++) {
5635
+ const state = (_a = queries[i]) == null ? void 0 : _a.data;
5636
+ const best = extractOutcomeBestPrices(state);
5637
+ if (best.bestBid != null || best.bestAsk != null) {
5638
+ perOutcome.set(outcomeIds[i], best);
5639
+ }
5640
+ }
5641
+ if (perOutcome.size === 0) {
5642
+ prevRef.current = { fingerprint, result: EMPTY };
5643
+ return EMPTY;
5644
+ }
5645
+ const result = new Map(perOutcome);
5646
+ for (const vm of venueMarkets) {
5647
+ for (const outcome of (_b = vm.venueMarketOutcomes) != null ? _b : []) {
5648
+ const refs = (_c = outcome.matchedVenueMarketOutcomes) != null ? _c : [];
5649
+ if (!refs.length) continue;
5650
+ const group = [outcome.id, ...refs.map((ref) => ref.venueMarketOutcomeId)];
5651
+ let groupBestAsk;
5652
+ let groupBestBid;
5653
+ for (const id of group) {
5654
+ const entry = perOutcome.get(id);
5655
+ if (!entry) continue;
5656
+ if (entry.bestAsk != null && (groupBestAsk == null || entry.bestAsk < groupBestAsk)) {
5657
+ groupBestAsk = entry.bestAsk;
5658
+ }
5659
+ if (entry.bestBid != null && (groupBestBid == null || entry.bestBid > groupBestBid)) {
5660
+ groupBestBid = entry.bestBid;
5661
+ }
5662
+ }
5663
+ if (groupBestAsk == null && groupBestBid == null) continue;
5664
+ for (const id of group) {
5665
+ const prev = (_d = result.get(id)) != null ? _d : {};
5666
+ const nextBid = groupBestBid != null ? groupBestBid : prev.bestBid;
5667
+ const nextAsk = groupBestAsk != null ? groupBestAsk : prev.bestAsk;
5668
+ if (nextBid == null && nextAsk == null) continue;
5669
+ result.set(id, __spreadValues(__spreadValues({}, nextBid != null ? { bestBid: nextBid } : {}), nextAsk != null ? { bestAsk: nextAsk } : {}));
5670
+ }
5671
+ }
5672
+ }
5673
+ prevRef.current = { fingerprint, result };
5674
+ return result;
5675
+ }, [venueMarkets, enableLiveUpdates, fingerprint, outcomeIds, queries]);
5676
+ }
5677
+ function mergeBestPricesPreferringLive(rest, live) {
5678
+ var _a, _b, _c;
5679
+ if (!live.size) return rest != null ? rest : EMPTY;
5680
+ if (!rest || !rest.size) return live;
5681
+ const merged = new Map(rest);
5682
+ for (const [id, liveEntry] of live) {
5683
+ const prev = (_a = merged.get(id)) != null ? _a : {};
5684
+ merged.set(id, {
5685
+ bestBid: (_b = liveEntry.bestBid) != null ? _b : prev.bestBid,
5686
+ bestAsk: (_c = liveEntry.bestAsk) != null ? _c : prev.bestAsk
5687
+ });
5688
+ }
5689
+ return merged;
5690
+ }
5691
+
4907
5692
  // src/use-live-trades.ts
4908
5693
  function useLiveTrades(canonicalMarketId) {
4909
5694
  const {
@@ -4920,19 +5705,146 @@ function useLiveTrades(canonicalMarketId) {
4920
5705
  }
4921
5706
 
4922
5707
  // src/use-midpoints.ts
4923
- var import_react24 = require("react");
4924
- var import_react_query23 = require("@tanstack/react-query");
5708
+ var import_react_query24 = require("@tanstack/react-query");
5709
+ var import_react28 = require("react");
4925
5710
  var normalizeVenueMarketIds = (venueMarkets) => {
4926
- return [...new Set((venueMarkets != null ? venueMarkets : []).map((market) => market.id).filter(Boolean))].sort(
4927
- (left, right) => left.localeCompare(right)
5711
+ var _a;
5712
+ const ids = /* @__PURE__ */ new Set();
5713
+ for (const market of venueMarkets != null ? venueMarkets : []) {
5714
+ if (market.id) ids.add(market.id);
5715
+ for (const sibling of (_a = market.matchedVenueMarkets) != null ? _a : []) {
5716
+ if (sibling.id) ids.add(sibling.id);
5717
+ }
5718
+ }
5719
+ return [...ids].sort((left, right) => left.localeCompare(right));
5720
+ };
5721
+ var normalizeOutcomeLabel = (label) => {
5722
+ return typeof label === "string" ? label.trim().toLowerCase() : "";
5723
+ };
5724
+ var resolveBestMidpointCandidateOutcomeIds = (venueMarkets) => {
5725
+ var _a, _b;
5726
+ if (!(venueMarkets == null ? void 0 : venueMarkets.length)) return [];
5727
+ const candidateIds = [];
5728
+ for (const market of venueMarkets) {
5729
+ const outcomes = (_a = market.venueMarketOutcomes) != null ? _a : [];
5730
+ const yesOutcome = outcomes.find((outcome) => normalizeOutcomeLabel(outcome.label) === "yes");
5731
+ if (yesOutcome == null ? void 0 : yesOutcome.id) {
5732
+ candidateIds.push(yesOutcome.id);
5733
+ continue;
5734
+ }
5735
+ const firstOutcomeId = (_b = outcomes[0]) == null ? void 0 : _b.id;
5736
+ if (firstOutcomeId) {
5737
+ candidateIds.push(firstOutcomeId);
5738
+ }
5739
+ }
5740
+ return [...new Set(candidateIds)];
5741
+ };
5742
+ var resolveSiblingOutcomeMidpoint = (matched, ref) => {
5743
+ var _a, _b;
5744
+ if (!(matched == null ? void 0 : matched.length)) return null;
5745
+ const sibling = matched.find((m) => m.venueMarketId === ref.venueMarketId);
5746
+ if (!((_a = sibling == null ? void 0 : sibling.outcomes) == null ? void 0 : _a.length)) return null;
5747
+ const sibOutcome = sibling.outcomes.find(
5748
+ (o) => o.venueMarketOutcomeId === ref.venueMarketOutcomeId
4928
5749
  );
5750
+ if ((sibOutcome == null ? void 0 : sibOutcome.midpoint) == null) return null;
5751
+ return { midpoint: sibOutcome.midpoint, venue: (_b = sibling.venue) != null ? _b : null };
5752
+ };
5753
+ var extractBestPrices = (data, venueMarkets) => {
5754
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
5755
+ const bestPrices = /* @__PURE__ */ new Map();
5756
+ const venuesByOutcome = /* @__PURE__ */ new Map();
5757
+ if (!(data == null ? void 0 : data.length)) return { bestPrices, bestPriceVenuesByOutcomeId: venuesByOutcome };
5758
+ const setEntry = (outcomeId, next) => {
5759
+ const prev = bestPrices.get(outcomeId);
5760
+ const merged = __spreadValues({}, prev != null ? prev : {});
5761
+ if (next.bestBid != null) merged.bestBid = next.bestBid;
5762
+ if (next.bestAsk != null) merged.bestAsk = next.bestAsk;
5763
+ if (merged.bestBid != null || merged.bestAsk != null) bestPrices.set(outcomeId, merged);
5764
+ const prevVenues = venuesByOutcome.get(outcomeId);
5765
+ const mergedVenues = __spreadValues({}, prevVenues != null ? prevVenues : {});
5766
+ if (next.bestBidVenue != null) mergedVenues.bestBidVenue = next.bestBidVenue;
5767
+ if (next.bestAskVenue != null) mergedVenues.bestAskVenue = next.bestAskVenue;
5768
+ if (mergedVenues.bestBidVenue || mergedVenues.bestAskVenue) {
5769
+ venuesByOutcome.set(outcomeId, mergedVenues);
5770
+ }
5771
+ };
5772
+ for (const item of data) {
5773
+ const venue = (_a = item.venue) != null ? _a : null;
5774
+ for (const o of (_b = item.outcomes) != null ? _b : []) {
5775
+ if (o.bestBid != null || o.bestAsk != null) {
5776
+ setEntry(o.venueMarketOutcomeId, {
5777
+ bestBid: o.bestBid,
5778
+ bestAsk: o.bestAsk,
5779
+ bestBidVenue: o.bestBid != null ? venue : null,
5780
+ bestAskVenue: o.bestAsk != null ? venue : null
5781
+ });
5782
+ }
5783
+ }
5784
+ }
5785
+ for (const item of data) {
5786
+ for (const m of (_c = item.matched) != null ? _c : []) {
5787
+ const venue = (_d = m.venue) != null ? _d : null;
5788
+ for (const o of (_e = m.outcomes) != null ? _e : []) {
5789
+ if (bestPrices.has(o.venueMarketOutcomeId)) continue;
5790
+ if (o.bestBid != null || o.bestAsk != null) {
5791
+ setEntry(o.venueMarketOutcomeId, {
5792
+ bestBid: o.bestBid,
5793
+ bestAsk: o.bestAsk,
5794
+ bestBidVenue: o.bestBid != null ? venue : null,
5795
+ bestAskVenue: o.bestAsk != null ? venue : null
5796
+ });
5797
+ }
5798
+ }
5799
+ }
5800
+ }
5801
+ if (venueMarkets == null ? void 0 : venueMarkets.length) {
5802
+ for (const market of venueMarkets) {
5803
+ for (const outcome of (_f = market.venueMarketOutcomes) != null ? _f : []) {
5804
+ const refs = (_g = outcome.matchedVenueMarketOutcomes) != null ? _g : [];
5805
+ if (!refs.length) continue;
5806
+ const group = [outcome.id, ...refs.map((ref) => ref.venueMarketOutcomeId)];
5807
+ let bestAsk;
5808
+ let bestBid;
5809
+ let bestAskVenue;
5810
+ let bestBidVenue;
5811
+ for (const id of group) {
5812
+ const entry = bestPrices.get(id);
5813
+ const venues = venuesByOutcome.get(id);
5814
+ if (!entry) continue;
5815
+ if (entry.bestAsk != null && (bestAsk == null || entry.bestAsk < bestAsk)) {
5816
+ bestAsk = entry.bestAsk;
5817
+ bestAskVenue = (_h = venues == null ? void 0 : venues.bestAskVenue) != null ? _h : bestAskVenue;
5818
+ }
5819
+ if (entry.bestBid != null && (bestBid == null || entry.bestBid > bestBid)) {
5820
+ bestBid = entry.bestBid;
5821
+ bestBidVenue = (_i = venues == null ? void 0 : venues.bestBidVenue) != null ? _i : bestBidVenue;
5822
+ }
5823
+ }
5824
+ if (bestAsk == null && bestBid == null) continue;
5825
+ for (const id of group) {
5826
+ setEntry(id, {
5827
+ bestBid,
5828
+ bestAsk,
5829
+ bestBidVenue,
5830
+ bestAskVenue
5831
+ });
5832
+ }
5833
+ }
5834
+ }
5835
+ }
5836
+ return { bestPrices, bestPriceVenuesByOutcomeId: venuesByOutcome };
4929
5837
  };
4930
5838
  function useMidpoints(venueMarkets) {
4931
5839
  const client = useAggClient();
4932
- const ids = (0, import_react24.useMemo)(() => normalizeVenueMarketIds(venueMarkets), [venueMarkets]);
4933
- const { data, isLoading } = (0, import_react_query23.useQuery)({
5840
+ const ids = (0, import_react28.useMemo)(() => normalizeVenueMarketIds(venueMarkets), [venueMarkets]);
5841
+ const bestMidpointCandidateOutcomeIds = (0, import_react28.useMemo)(
5842
+ () => resolveBestMidpointCandidateOutcomeIds(venueMarkets),
5843
+ [venueMarkets]
5844
+ );
5845
+ const { data, isLoading } = (0, import_react_query24.useQuery)({
4934
5846
  queryKey: ["midpoints", ids],
4935
- queryFn: () => client.getMidpoints(ids),
5847
+ queryFn: () => client.getMidpoints(ids, { bestPrice: true }),
4936
5848
  enabled: ids.length > 0,
4937
5849
  staleTime: Infinity,
4938
5850
  gcTime: 30 * 6e4,
@@ -4940,73 +5852,156 @@ function useMidpoints(venueMarkets) {
4940
5852
  refetchOnWindowFocus: false,
4941
5853
  refetchOnReconnect: false
4942
5854
  });
4943
- const result = (0, import_react24.useMemo)(() => {
4944
- var _a, _b, _c, _d, _e, _f;
5855
+ const result = (0, import_react28.useMemo)(() => {
5856
+ var _a, _b, _c, _d, _e;
4945
5857
  const map = /* @__PURE__ */ new Map();
4946
5858
  const venueMap = /* @__PURE__ */ new Map();
4947
5859
  if (!(data == null ? void 0 : data.data) || !venueMarkets) return { map, venueMap };
5860
+ const itemByMarketId = new Map(data.data.map((item) => [item.venueMarketId, item]));
4948
5861
  for (const item of data.data) {
4949
- if ((_a = item.outcomes) == null ? void 0 : _a.length) {
4950
- for (const o of item.outcomes) {
4951
- if (o.midpoint != null) {
4952
- map.set(o.venueMarketOutcomeId, o.midpoint);
4953
- if (item.venue) venueMap.set(o.venueMarketOutcomeId, item.venue);
4954
- }
4955
- }
4956
- if ((_b = item.matched) == null ? void 0 : _b.length) {
4957
- const market = venueMarkets.find((vm) => vm.id === item.venueMarketId);
4958
- if (market) {
4959
- const primaryYesOutcome = market.venueMarketOutcomes.find(
4960
- (o) => {
4961
- var _a2;
4962
- return ((_a2 = o.label) == null ? void 0 : _a2.toLowerCase()) === "yes";
4963
- }
4964
- );
4965
- const primaryYesMidpoint = primaryYesOutcome ? (_c = map.get(primaryYesOutcome.id)) != null ? _c : null : null;
4966
- let bestMatchedMidpoint = null;
4967
- let bestMatchedVenue = null;
4968
- for (const m of item.matched) {
4969
- if (m.midpoint == null) continue;
4970
- if (bestMatchedMidpoint == null || m.midpoint < bestMatchedMidpoint) {
4971
- bestMatchedMidpoint = m.midpoint;
4972
- bestMatchedVenue = (_d = m.venue) != null ? _d : null;
4973
- }
4974
- }
4975
- if (bestMatchedMidpoint != null && (primaryYesMidpoint == null || bestMatchedMidpoint < primaryYesMidpoint)) {
4976
- for (const outcome of market.venueMarketOutcomes) {
4977
- const isYes = ((_e = outcome.label) == null ? void 0 : _e.toLowerCase()) === "yes";
4978
- map.set(outcome.id, isYes ? bestMatchedMidpoint : 1 - bestMatchedMidpoint);
4979
- if (bestMatchedVenue) venueMap.set(outcome.id, bestMatchedVenue);
4980
- }
4981
- }
5862
+ if (!((_a = item.outcomes) == null ? void 0 : _a.length)) continue;
5863
+ for (const o of item.outcomes) {
5864
+ if (o.midpoint == null) continue;
5865
+ map.set(o.venueMarketOutcomeId, o.midpoint);
5866
+ if (item.venue) venueMap.set(o.venueMarketOutcomeId, item.venue);
5867
+ }
5868
+ }
5869
+ for (const market of venueMarkets) {
5870
+ const item = itemByMarketId.get(market.id);
5871
+ if (!item) continue;
5872
+ for (const outcome of market.venueMarketOutcomes) {
5873
+ const refs = (_b = outcome.matchedVenueMarketOutcomes) != null ? _b : [];
5874
+ if (!refs.length) continue;
5875
+ let best = (_c = map.get(outcome.id)) != null ? _c : null;
5876
+ let bestVenue = (_d = item.venue) != null ? _d : null;
5877
+ for (const ref of refs) {
5878
+ const sib = resolveSiblingOutcomeMidpoint(item.matched, ref);
5879
+ if (sib == null) continue;
5880
+ if (best == null || sib.midpoint < best) {
5881
+ best = sib.midpoint;
5882
+ bestVenue = (_e = sib.venue) != null ? _e : bestVenue;
4982
5883
  }
4983
5884
  }
4984
- continue;
4985
- }
4986
- if (item.midpoint != null) {
4987
- const market = venueMarkets.find((vm) => vm.id === item.venueMarketId);
4988
- if (!market) continue;
4989
- for (const outcome of market.venueMarketOutcomes) {
4990
- const isYes = ((_f = outcome.label) == null ? void 0 : _f.toLowerCase()) === "yes";
4991
- map.set(outcome.id, isYes ? item.midpoint : 1 - item.midpoint);
4992
- if (item.venue) venueMap.set(outcome.id, item.venue);
5885
+ if (best != null) {
5886
+ map.set(outcome.id, best);
5887
+ if (bestVenue) venueMap.set(outcome.id, bestVenue);
4993
5888
  }
4994
5889
  }
4995
5890
  }
4996
5891
  return { map, venueMap };
4997
5892
  }, [data, venueMarkets]);
5893
+ const { bestMidpoint, bestMidpointVenue } = (0, import_react28.useMemo)(() => {
5894
+ let value;
5895
+ let venue;
5896
+ for (const outcomeId of bestMidpointCandidateOutcomeIds) {
5897
+ const midpoint = result.map.get(outcomeId);
5898
+ if (midpoint == null) continue;
5899
+ if (value == null || midpoint < value) {
5900
+ value = midpoint;
5901
+ venue = result.venueMap.get(outcomeId);
5902
+ }
5903
+ }
5904
+ if (value == null) {
5905
+ for (const [outcomeId, midpoint] of result.map) {
5906
+ if (value == null || midpoint < value) {
5907
+ value = midpoint;
5908
+ venue = result.venueMap.get(outcomeId);
5909
+ }
5910
+ }
5911
+ }
5912
+ return { bestMidpoint: value, bestMidpointVenue: venue };
5913
+ }, [bestMidpointCandidateOutcomeIds, result.map, result.venueMap]);
5914
+ const { bestPrices, bestPriceVenuesByOutcomeId } = (0, import_react28.useMemo)(
5915
+ () => extractBestPrices(data == null ? void 0 : data.data, venueMarkets),
5916
+ [data == null ? void 0 : data.data, venueMarkets]
5917
+ );
4998
5918
  return {
4999
5919
  prices: result.map,
5920
+ bestMidpointsByOutcomeId: result.map,
5000
5921
  venueByOutcomeId: result.venueMap,
5001
- isLoading: isLoading && ids.length > 0
5922
+ bestPrices,
5923
+ bestPriceVenuesByOutcomeId,
5924
+ isLoading: isLoading && ids.length > 0,
5925
+ bestMidpoint,
5926
+ bestMidpointVenue
5002
5927
  };
5003
5928
  }
5004
5929
 
5930
+ // src/use-tradable-venues.ts
5931
+ var import_react29 = require("react");
5932
+ function useTradableVenues(venueMarkets) {
5933
+ const { prices, isLoading } = useMidpoints(venueMarkets);
5934
+ const tradableVenues = (0, import_react29.useMemo)(() => {
5935
+ var _a;
5936
+ if (isLoading) return null;
5937
+ if (!venueMarkets || venueMarkets.length === 0) return /* @__PURE__ */ new Set();
5938
+ const set = /* @__PURE__ */ new Set();
5939
+ for (const market of venueMarkets) {
5940
+ const outcomes = (_a = market.venueMarketOutcomes) != null ? _a : [];
5941
+ for (const outcome of outcomes) {
5942
+ if (prices.has(outcome.id)) {
5943
+ set.add(market.venue);
5944
+ break;
5945
+ }
5946
+ }
5947
+ }
5948
+ return set;
5949
+ }, [venueMarkets, prices, isLoading]);
5950
+ return { tradableVenues, isLoading };
5951
+ }
5952
+
5953
+ // src/use-rolling-chart-window.ts
5954
+ var import_react30 = require("react");
5955
+ var RANGE_SECONDS_BY_RANGE = {
5956
+ "1H": 60 * 60,
5957
+ "6H": 6 * 60 * 60,
5958
+ "1D": 24 * 60 * 60,
5959
+ "1W": 7 * 24 * 60 * 60,
5960
+ "1M": 30 * 24 * 60 * 60,
5961
+ ALL: 6 * 30 * 24 * 60 * 60
5962
+ };
5963
+ var rangeToSeconds = (range) => RANGE_SECONDS_BY_RANGE[range];
5964
+ var resolveRollingWindow = (params) => {
5965
+ var _a;
5966
+ const interval = (_a = params.interval) != null ? _a : timeRangeToInterval(params.range);
5967
+ const intervalSeconds = getIntervalSeconds(interval);
5968
+ const rangeSeconds = rangeToSeconds(params.range);
5969
+ const endTs = Math.ceil(params.nowSec / intervalSeconds) * intervalSeconds;
5970
+ return {
5971
+ range: params.range,
5972
+ interval,
5973
+ rangeSeconds,
5974
+ intervalSeconds,
5975
+ nowSec: params.nowSec,
5976
+ endTs,
5977
+ startTs: endTs - rangeSeconds,
5978
+ refetchIntervalMs: intervalSeconds * 1e3
5979
+ };
5980
+ };
5981
+ var useRollingChartWindow = (options) => {
5982
+ var _a;
5983
+ const tickMs = (_a = options.tickMs) != null ? _a : 1e3;
5984
+ const optionsNowMs = options.nowMs;
5985
+ const nowMs = (0, import_react30.useMemo)(() => optionsNowMs != null ? optionsNowMs : (() => Date.now()), [optionsNowMs]);
5986
+ const [nowSec, setNowSec] = (0, import_react30.useState)(() => Math.floor(nowMs() / 1e3));
5987
+ (0, import_react30.useEffect)(() => {
5988
+ setNowSec(Math.floor(nowMs() / 1e3));
5989
+ const handle = setInterval(() => {
5990
+ setNowSec(Math.floor(nowMs() / 1e3));
5991
+ }, tickMs);
5992
+ return () => clearInterval(handle);
5993
+ }, [tickMs, nowMs]);
5994
+ return (0, import_react30.useMemo)(
5995
+ () => resolveRollingWindow({ range: options.range, nowSec, interval: options.interval }),
5996
+ [options.range, options.interval, nowSec]
5997
+ );
5998
+ };
5999
+
5005
6000
  // src/use-market-orderbook.ts
5006
- var import_react_query24 = require("@tanstack/react-query");
6001
+ var import_react_query25 = require("@tanstack/react-query");
5007
6002
  function useMarketOrderbook(options) {
5008
6003
  var _a, _b, _c, _d, _e, _f, _g;
5009
- const queryClient = (0, import_react_query24.useQueryClient)();
6004
+ const queryClient = (0, import_react_query25.useQueryClient)();
5010
6005
  const ws = useAggWebSocket();
5011
6006
  const isConnected = useAggWebSocketConnectionState();
5012
6007
  const {
@@ -5023,7 +6018,7 @@ function useMarketOrderbook(options) {
5023
6018
  enabled: enabled && !!selectedOutcomeId,
5024
6019
  orderbook: true
5025
6020
  });
5026
- const liveQueries = (0, import_react_query24.useQueries)({
6021
+ const liveQueries = (0, import_react_query25.useQueries)({
5027
6022
  queries: subscriptionIds.map((subscriptionId) => ({
5028
6023
  queryKey: marketDataKeys.live(subscriptionId),
5029
6024
  queryFn: () => createMarketLiveState(subscriptionId),
@@ -5089,7 +6084,7 @@ function useMarketOrderbook(options) {
5089
6084
  }
5090
6085
 
5091
6086
  // src/use-order-book.ts
5092
- var import_react_query25 = require("@tanstack/react-query");
6087
+ var import_react_query26 = require("@tanstack/react-query");
5093
6088
  function useOrderBook(options) {
5094
6089
  const client = useAggClient();
5095
6090
  const { orderbooks, enabled = true, canonicalMarketId } = options;
@@ -5102,7 +6097,7 @@ function useOrderBook(options) {
5102
6097
  venueMarketOutcomeId: outcome.id
5103
6098
  })) : void 0
5104
6099
  });
5105
- const batchedResult = (0, import_react_query25.useQuery)({
6100
+ const batchedResult = (0, import_react_query26.useQuery)({
5106
6101
  queryKey: requestedVenueMarketIds.length ? ["orderbooks", requestedVenueMarketIds, null] : ["orderbooks", "__disabled__", null],
5107
6102
  queryFn: ({ signal }) => client.getOrderbooks(
5108
6103
  {
@@ -5115,7 +6110,7 @@ function useOrderBook(options) {
5115
6110
  gcTime: 5 * 6e4,
5116
6111
  refetchOnWindowFocus: false,
5117
6112
  retry: 1,
5118
- placeholderData: import_react_query25.keepPreviousData
6113
+ placeholderData: import_react_query26.keepPreviousData
5119
6114
  });
5120
6115
  const data = (() => {
5121
6116
  var _a, _b;
@@ -5170,7 +6165,7 @@ function useOrderBook(options) {
5170
6165
  }
5171
6166
 
5172
6167
  // src/use-orderbook-quote.ts
5173
- var import_react_query26 = require("@tanstack/react-query");
6168
+ var import_react_query27 = require("@tanstack/react-query");
5174
6169
  var QUOTE_DEBOUNCE_MS = 300;
5175
6170
  var createUnavailableOrderbookError = (message, code, retryable) => {
5176
6171
  const error = new Error(message);
@@ -5232,7 +6227,7 @@ function useOrderbookQuote(options) {
5232
6227
  const { marketId, side, size, enabled = true } = options;
5233
6228
  const debouncedSize = useDebouncedValue(size, QUOTE_DEBOUNCE_MS);
5234
6229
  const shouldFetch = enabled && !!marketId && debouncedSize > 0;
5235
- const query = (0, import_react_query26.useQuery)({
6230
+ const query = (0, import_react_query27.useQuery)({
5236
6231
  queryKey: marketId ? marketDataKeys.orderbookQuote(marketId, side, debouncedSize) : ["market-data", "orderbook-quote", "__disabled__"],
5237
6232
  queryFn: () => __async(null, null, function* () {
5238
6233
  var _a2, _b, _c, _d;
@@ -5263,7 +6258,7 @@ function useOrderbookQuote(options) {
5263
6258
  staleTime: 1e4,
5264
6259
  gcTime: 5 * 6e4,
5265
6260
  retry: 1,
5266
- placeholderData: import_react_query26.keepPreviousData
6261
+ placeholderData: import_react_query27.keepPreviousData
5267
6262
  });
5268
6263
  return {
5269
6264
  data: (_a = query.data) != null ? _a : null,
@@ -5274,12 +6269,12 @@ function useOrderbookQuote(options) {
5274
6269
  }
5275
6270
 
5276
6271
  // src/use-orders.ts
5277
- var import_react_query27 = require("@tanstack/react-query");
6272
+ var import_react_query28 = require("@tanstack/react-query");
5278
6273
  function useOrders(options = {}) {
5279
6274
  var _a, _b, _c, _d;
5280
6275
  const client = useAggClient();
5281
6276
  const { userId, status, limit = 50, offset = 0, enabled = true } = options;
5282
- const query = (0, import_react_query27.useQuery)({
6277
+ const query = (0, import_react_query28.useQuery)({
5283
6278
  queryKey: ["orders", userId != null ? userId : "me", status != null ? status : "all", limit, offset],
5284
6279
  queryFn: () => client.getOrders({
5285
6280
  userId,
@@ -5296,16 +6291,16 @@ function useOrders(options = {}) {
5296
6291
  }
5297
6292
 
5298
6293
  // src/use-search.ts
5299
- var import_react_query28 = require("@tanstack/react-query");
5300
- var import_react25 = require("react");
6294
+ var import_react_query29 = require("@tanstack/react-query");
6295
+ var import_react31 = require("react");
5301
6296
  function useSearch(options) {
5302
6297
  var _a, _b, _c;
5303
- const client = (0, import_react25.useContext)(AggClientContext);
5304
- const queryClient = (0, import_react25.useContext)(import_react_query28.QueryClientContext);
5305
- const [fallbackQueryClient] = (0, import_react25.useState)(() => new import_react_query28.QueryClient());
5306
- const { q, type, categoryIds, limit = 20, enabled = true } = options;
6298
+ const client = (0, import_react31.useContext)(AggClientContext);
6299
+ const queryClient = (0, import_react31.useContext)(import_react_query29.QueryClientContext);
6300
+ const [fallbackQueryClient] = (0, import_react31.useState)(() => new import_react_query29.QueryClient());
6301
+ const { q, type, categoryIds, limit = 20, enabled = true, deep = false } = options;
5307
6302
  const isEnabled = enabled && q.length > 0;
5308
- (0, import_react25.useEffect)(() => {
6303
+ (0, import_react31.useEffect)(() => {
5309
6304
  if (queryClient) return void 0;
5310
6305
  fallbackQueryClient.mount();
5311
6306
  return () => {
@@ -5315,9 +6310,11 @@ function useSearch(options) {
5315
6310
  if (isEnabled && !client) {
5316
6311
  throw new Error("useSearch must be used within an <AggProvider>");
5317
6312
  }
5318
- const query = (0, import_react_query28.useInfiniteQuery)(
6313
+ const query = (0, import_react_query29.useInfiniteQuery)(
5319
6314
  {
5320
- queryKey: ["search", q, type, (_a = categoryIds == null ? void 0 : categoryIds.join(",")) != null ? _a : "", limit],
6315
+ // deep is part of the key TanStack treats deep vs light as
6316
+ // independent queries so users can have both modes cached side-by-side.
6317
+ queryKey: ["search", q, type, (_a = categoryIds == null ? void 0 : categoryIds.join(",")) != null ? _a : "", limit, deep],
5321
6318
  queryFn: (_0) => __async(null, [_0], function* ({ pageParam }) {
5322
6319
  if (!client) {
5323
6320
  throw new Error("useSearch must be used within an <AggProvider>");
@@ -5327,7 +6324,8 @@ function useSearch(options) {
5327
6324
  type,
5328
6325
  categoryIds,
5329
6326
  limit,
5330
- cursor: pageParam
6327
+ cursor: pageParam,
6328
+ deep
5331
6329
  });
5332
6330
  return res;
5333
6331
  }),
@@ -5337,7 +6335,7 @@ function useSearch(options) {
5337
6335
  if (!lastPage.hasMore) return void 0;
5338
6336
  return (_a2 = lastPage.nextCursor) != null ? _a2 : void 0;
5339
6337
  },
5340
- placeholderData: import_react_query28.keepPreviousData,
6338
+ placeholderData: import_react_query29.keepPreviousData,
5341
6339
  enabled: isEnabled && !!client
5342
6340
  },
5343
6341
  queryClient != null ? queryClient : fallbackQueryClient
@@ -5355,8 +6353,95 @@ function useSearch(options) {
5355
6353
  };
5356
6354
  }
5357
6355
 
6356
+ // src/use-market-search.ts
6357
+ var import_react32 = require("react");
6358
+ function useMarketSearch(options) {
6359
+ var _a;
6360
+ const {
6361
+ type,
6362
+ categoryIds,
6363
+ limit = 20,
6364
+ debounceMs = 200,
6365
+ enableSuggestions = true,
6366
+ minLength = 1
6367
+ } = options;
6368
+ const [query, setQueryState] = (0, import_react32.useState)("");
6369
+ const [submittedQuery, setSubmittedQuery] = (0, import_react32.useState)(null);
6370
+ const debouncedQuery = useDebouncedValue(query, debounceMs);
6371
+ const trimmedDebounced = debouncedQuery.trim();
6372
+ const suggestionsEnabled = enableSuggestions && trimmedDebounced.length >= minLength;
6373
+ const suggestionsQuery = useSearch({
6374
+ q: trimmedDebounced,
6375
+ type,
6376
+ categoryIds,
6377
+ limit,
6378
+ enabled: suggestionsEnabled,
6379
+ deep: false
6380
+ });
6381
+ const submittedQ = (_a = submittedQuery == null ? void 0 : submittedQuery.trim()) != null ? _a : "";
6382
+ const resultsQuery = useSearch({
6383
+ q: submittedQ,
6384
+ type,
6385
+ categoryIds,
6386
+ limit,
6387
+ enabled: submittedQ.length > 0,
6388
+ deep: true
6389
+ });
6390
+ const setQuery = (0, import_react32.useCallback)((value) => {
6391
+ setQueryState(value);
6392
+ }, []);
6393
+ const submit = (0, import_react32.useCallback)(
6394
+ (q) => {
6395
+ const target = (q != null ? q : query).trim();
6396
+ if (target.length === 0) return;
6397
+ setSubmittedQuery(target);
6398
+ },
6399
+ [query]
6400
+ );
6401
+ const clear = (0, import_react32.useCallback)(() => {
6402
+ setQueryState("");
6403
+ setSubmittedQuery(null);
6404
+ }, []);
6405
+ return {
6406
+ /** Current input value (controlled). */
6407
+ query,
6408
+ /** Update the input value. Triggers the debounced typeahead. */
6409
+ setQuery,
6410
+ /** The query value that produced the current `results`, or null if none. */
6411
+ submittedQuery,
6412
+ /** Fire a deep search. Use this on Enter / Search button. */
6413
+ submit,
6414
+ /** Reset both input and results state. */
6415
+ clear,
6416
+ /**
6417
+ * Typeahead state. Backed by a light /search call (no reranker).
6418
+ * `data` is paginated like `useSearch.data` (flattened across pages).
6419
+ */
6420
+ suggestions: {
6421
+ data: suggestionsQuery.data,
6422
+ isLoading: suggestionsQuery.isLoading,
6423
+ isError: suggestionsQuery.isError,
6424
+ error: suggestionsQuery.error
6425
+ },
6426
+ /**
6427
+ * Full-page results state. Backed by a deep /search call (reranker on).
6428
+ * Cursor pagination is exposed via `fetchNextPage` / `hasNextPage`.
6429
+ */
6430
+ results: {
6431
+ data: resultsQuery.data,
6432
+ isLoading: resultsQuery.isLoading,
6433
+ isError: resultsQuery.isError,
6434
+ error: resultsQuery.error,
6435
+ hasNextPage: resultsQuery.hasNextPage,
6436
+ fetchNextPage: resultsQuery.fetchNextPage,
6437
+ isFetchingNextPage: resultsQuery.isFetchingNextPage
6438
+ }
6439
+ };
6440
+ }
6441
+
5358
6442
  // src/use-smart-route.ts
5359
- var import_react_query29 = require("@tanstack/react-query");
6443
+ var import_react_query30 = require("@tanstack/react-query");
6444
+ var SMART_ROUTE_STALE_TIME_MS = 2e4;
5360
6445
  function useSmartRoute(options) {
5361
6446
  var _a, _b;
5362
6447
  const client = useAggClient();
@@ -5371,10 +6456,12 @@ function useSmartRoute(options) {
5371
6456
  chainBalances,
5372
6457
  slipCapBps,
5373
6458
  compareVenues,
5374
- enabled = true
6459
+ deepEstimate,
6460
+ enabled = true,
6461
+ staleTimeMs = SMART_ROUTE_STALE_TIME_MS
5375
6462
  } = options;
5376
6463
  const resolvedVenueMarketOutcomeId = (_a = venueMarketOutcomeId != null ? venueMarketOutcomeId : venueMarketId) != null ? _a : outcomeId;
5377
- const query = (0, import_react_query29.useQuery)({
6464
+ const query = (0, import_react_query30.useQuery)({
5378
6465
  queryKey: [
5379
6466
  "smart-route",
5380
6467
  resolvedVenueMarketOutcomeId,
@@ -5384,7 +6471,8 @@ function useSmartRoute(options) {
5384
6471
  sellShares != null ? sellShares : null,
5385
6472
  chainBalances ? JSON.stringify(chainBalances) : null,
5386
6473
  slipCapBps != null ? slipCapBps : null,
5387
- compareVenues != null ? compareVenues : false
6474
+ compareVenues != null ? compareVenues : false,
6475
+ deepEstimate != null ? deepEstimate : false
5388
6476
  ],
5389
6477
  queryFn: (_0) => __async(null, [_0], function* ({ signal }) {
5390
6478
  return client.getSmartRoute(
@@ -5396,17 +6484,19 @@ function useSmartRoute(options) {
5396
6484
  sellShares,
5397
6485
  chainBalances,
5398
6486
  slipCapBps,
5399
- compareVenues
6487
+ compareVenues,
6488
+ deepEstimate
5400
6489
  },
5401
6490
  { signal }
5402
6491
  );
5403
6492
  }),
5404
6493
  enabled: enabled && !!resolvedVenueMarketOutcomeId && ((maxSpend != null ? maxSpend : 0) > 0 || (sellShares != null ? sellShares : 0) > 0),
5405
- staleTime: 1e4,
6494
+ staleTime: staleTimeMs,
6495
+ refetchInterval: staleTimeMs > 0 ? staleTimeMs : false,
5406
6496
  gcTime: 6e4,
5407
6497
  refetchOnWindowFocus: false,
5408
6498
  retry: 1,
5409
- placeholderData: import_react_query29.keepPreviousData
6499
+ placeholderData: import_react_query30.keepPreviousData
5410
6500
  });
5411
6501
  const error = query.error;
5412
6502
  return {
@@ -5419,12 +6509,12 @@ function useSmartRoute(options) {
5419
6509
  }
5420
6510
 
5421
6511
  // src/use-user-holdings.ts
5422
- var import_react_query30 = require("@tanstack/react-query");
6512
+ var import_react_query31 = require("@tanstack/react-query");
5423
6513
  function useUserHoldings(options) {
5424
6514
  var _a, _b;
5425
6515
  const client = useAggClient();
5426
6516
  const { venue, venueMarketId, venueEventId, enabled = true } = options;
5427
- const query = (0, import_react_query30.useInfiniteQuery)({
6517
+ const query = (0, import_react_query31.useInfiniteQuery)({
5428
6518
  queryKey: ["user-holdings", venue, venueMarketId, venueEventId],
5429
6519
  queryFn: (_0) => __async(null, [_0], function* ({ pageParam }) {
5430
6520
  return client.getUserHoldings({
@@ -5450,15 +6540,15 @@ function useUserHoldings(options) {
5450
6540
  }
5451
6541
 
5452
6542
  // src/use-enriched-venue-event.ts
5453
- var import_react27 = require("react");
6543
+ var import_react34 = require("react");
5454
6544
 
5455
6545
  // src/use-venue-event.ts
5456
- var import_react_query31 = require("@tanstack/react-query");
6546
+ var import_react_query32 = require("@tanstack/react-query");
5457
6547
  function useVenueEvent(options) {
5458
6548
  var _a;
5459
6549
  const client = useAggClient();
5460
6550
  const { eventId, enabled = true } = options;
5461
- const query = (0, import_react_query31.useQuery)({
6551
+ const query = (0, import_react_query32.useQuery)({
5462
6552
  queryKey: ["venue-event", eventId],
5463
6553
  queryFn: (_0) => __async(null, [_0], function* ({ signal }) {
5464
6554
  return client.getVenueEventById(eventId, { signal });
@@ -5477,13 +6567,13 @@ function useVenueEvent(options) {
5477
6567
  }
5478
6568
 
5479
6569
  // src/use-venue-markets.ts
5480
- var import_react_query32 = require("@tanstack/react-query");
5481
- var import_react26 = require("react");
6570
+ var import_react_query33 = require("@tanstack/react-query");
6571
+ var import_react33 = require("react");
5482
6572
  function useVenueMarkets(options) {
5483
6573
  var _a, _b, _c, _d, _e;
5484
- const client = (0, import_react26.useContext)(AggClientContext);
5485
- const queryClient = (0, import_react26.useContext)(import_react_query32.QueryClientContext);
5486
- const [fallbackQueryClient] = (0, import_react26.useState)(() => new import_react_query32.QueryClient());
6574
+ const client = (0, import_react33.useContext)(AggClientContext);
6575
+ const queryClient = (0, import_react33.useContext)(import_react_query33.QueryClientContext);
6576
+ const [fallbackQueryClient] = (0, import_react33.useState)(() => new import_react_query33.QueryClient());
5487
6577
  const venue = options == null ? void 0 : options.venue;
5488
6578
  const venueEventId = options == null ? void 0 : options.venueEventId;
5489
6579
  const search = options == null ? void 0 : options.search;
@@ -5494,7 +6584,7 @@ function useVenueMarkets(options) {
5494
6584
  const limit = (_b = options == null ? void 0 : options.limit) != null ? _b : 20;
5495
6585
  const sortBy = options == null ? void 0 : options.sortBy;
5496
6586
  const sortDir = options == null ? void 0 : options.sortDir;
5497
- (0, import_react26.useEffect)(() => {
6587
+ (0, import_react33.useEffect)(() => {
5498
6588
  if (queryClient) return void 0;
5499
6589
  fallbackQueryClient.mount();
5500
6590
  return () => {
@@ -5504,7 +6594,7 @@ function useVenueMarkets(options) {
5504
6594
  if (enabled && !client) {
5505
6595
  throw new Error("useVenueMarkets must be used within an <AggProvider>");
5506
6596
  }
5507
- const query = (0, import_react_query32.useInfiniteQuery)(
6597
+ const query = (0, import_react_query33.useInfiniteQuery)(
5508
6598
  {
5509
6599
  queryKey: [
5510
6600
  "venue-markets",
@@ -5574,7 +6664,7 @@ function useEnrichedVenueEvent(options) {
5574
6664
  sortBy: "yesPrice",
5575
6665
  sortDir: "desc"
5576
6666
  });
5577
- const enrichedEvent = (0, import_react27.useMemo)(() => {
6667
+ const enrichedEvent = (0, import_react34.useMemo)(() => {
5578
6668
  if (!event) return void 0;
5579
6669
  if (markets.length === 0) return event;
5580
6670
  return mergeEventWithFullMarkets(event, markets);
@@ -5588,13 +6678,13 @@ function useEnrichedVenueEvent(options) {
5588
6678
  }
5589
6679
 
5590
6680
  // src/use-venue-events.ts
5591
- var import_react_query33 = require("@tanstack/react-query");
5592
- var import_react28 = require("react");
6681
+ var import_react_query34 = require("@tanstack/react-query");
6682
+ var import_react35 = require("react");
5593
6683
  function useVenueEvents(options) {
5594
6684
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
5595
- const client = (0, import_react28.useContext)(AggClientContext);
5596
- const queryClient = (0, import_react28.useContext)(import_react_query33.QueryClientContext);
5597
- const [fallbackQueryClient] = (0, import_react28.useState)(() => new import_react_query33.QueryClient());
6685
+ const client = (0, import_react35.useContext)(AggClientContext);
6686
+ const queryClient = (0, import_react35.useContext)(import_react_query34.QueryClientContext);
6687
+ const [fallbackQueryClient] = (0, import_react35.useState)(() => new import_react_query34.QueryClient());
5598
6688
  const venues = options == null ? void 0 : options.venues;
5599
6689
  const search = options == null ? void 0 : options.search;
5600
6690
  const categoryIds = options == null ? void 0 : options.categoryIds;
@@ -5604,12 +6694,13 @@ function useVenueEvents(options) {
5604
6694
  const status = options == null ? void 0 : options.status;
5605
6695
  const sortBy = options == null ? void 0 : options.sortBy;
5606
6696
  const sortDir = options == null ? void 0 : options.sortDir;
6697
+ const recurrence = options == null ? void 0 : options.recurrence;
5607
6698
  const queryKeyScope = (_d = options == null ? void 0 : options.queryKeyScope) != null ? _d : "events";
5608
6699
  const minYesPrice = options == null ? void 0 : options.minYesPrice;
5609
6700
  const maxYesPrice = options == null ? void 0 : options.maxYesPrice;
5610
6701
  const endDateFrom = options == null ? void 0 : options.endDateFrom;
5611
6702
  const initialPages = options == null ? void 0 : options.initialPages;
5612
- (0, import_react28.useEffect)(() => {
6703
+ (0, import_react35.useEffect)(() => {
5613
6704
  if (queryClient) return void 0;
5614
6705
  fallbackQueryClient.mount();
5615
6706
  return () => {
@@ -5619,7 +6710,7 @@ function useVenueEvents(options) {
5619
6710
  if (enabled && !client) {
5620
6711
  throw new Error("useVenueEvents must be used within an <AggProvider>");
5621
6712
  }
5622
- const query = (0, import_react_query33.useInfiniteQuery)(
6713
+ const query = (0, import_react_query34.useInfiniteQuery)(
5623
6714
  {
5624
6715
  queryKey: [
5625
6716
  queryKeyScope,
@@ -5630,6 +6721,7 @@ function useVenueEvents(options) {
5630
6721
  (_g = status == null ? void 0 : status.join(",")) != null ? _g : "",
5631
6722
  sortBy != null ? sortBy : "",
5632
6723
  sortDir != null ? sortDir : "",
6724
+ recurrence != null ? recurrence : "",
5633
6725
  minYesPrice != null ? minYesPrice : "",
5634
6726
  maxYesPrice != null ? maxYesPrice : "",
5635
6727
  endDateFrom != null ? endDateFrom : "",
@@ -5647,6 +6739,7 @@ function useVenueEvents(options) {
5647
6739
  status,
5648
6740
  sortBy,
5649
6741
  sortDir,
6742
+ recurrence,
5650
6743
  limit,
5651
6744
  minYesPrice,
5652
6745
  maxYesPrice,
@@ -5662,13 +6755,13 @@ function useVenueEvents(options) {
5662
6755
  return (_a2 = lastPage.nextCursor) != null ? _a2 : void 0;
5663
6756
  },
5664
6757
  // TODO: RMIK - Comment out to show skeletons on category switch
5665
- placeholderData: import_react_query33.keepPreviousData,
6758
+ placeholderData: import_react_query34.keepPreviousData,
5666
6759
  enabled: enabled && !!client
5667
6760
  },
5668
6761
  queryClient != null ? queryClient : fallbackQueryClient
5669
6762
  );
5670
- const prefetchedRef = (0, import_react28.useRef)(false);
5671
- (0, import_react28.useEffect)(() => {
6763
+ const prefetchedRef = (0, import_react35.useRef)(false);
6764
+ (0, import_react35.useEffect)(() => {
5672
6765
  var _a2, _b2;
5673
6766
  if (prefetchedRef.current) return;
5674
6767
  if (!initialPages || initialPages <= 1) return;
@@ -5686,7 +6779,7 @@ function useVenueEvents(options) {
5686
6779
  query.hasNextPage,
5687
6780
  query.fetchNextPage
5688
6781
  ]);
5689
- const events = (0, import_react28.useMemo)(
6782
+ const events = (0, import_react35.useMemo)(
5690
6783
  () => {
5691
6784
  var _a2, _b2;
5692
6785
  return (_b2 = (_a2 = query.data) == null ? void 0 : _a2.pages.flatMap((page) => page.data)) != null ? _b2 : [];
@@ -5704,7 +6797,7 @@ function useVenueEvents(options) {
5704
6797
  }
5705
6798
 
5706
6799
  // src/use-venue-market-midpoints.ts
5707
- var import_react_query34 = require("@tanstack/react-query");
6800
+ var import_react_query35 = require("@tanstack/react-query");
5708
6801
  var MAX_VENUE_MARKET_IDS_PER_REQUEST = 200;
5709
6802
  var normalizeVenueMarketIds2 = (venueMarketIds) => {
5710
6803
  return [
@@ -5740,7 +6833,7 @@ function useVenueMarketMidpoints(options) {
5740
6833
  const client = useAggClient();
5741
6834
  const enabled = (_a = options.enabled) != null ? _a : true;
5742
6835
  const requestedVenueMarketIds = normalizeVenueMarketIds2(options.venueMarketIds);
5743
- const query = (0, import_react_query34.useQuery)({
6836
+ const query = (0, import_react_query35.useQuery)({
5744
6837
  queryKey: requestedVenueMarketIds.length ? ["venue-market-midpoints", requestedVenueMarketIds] : ["venue-market-midpoints", "__disabled__"],
5745
6838
  queryFn: (_0) => __async(null, [_0], function* ({ signal }) {
5746
6839
  const venueMarketIdChunks = chunkVenueMarketIds(requestedVenueMarketIds);
@@ -5749,7 +6842,7 @@ function useVenueMarketMidpoints(options) {
5749
6842
  }
5750
6843
  const chunkResponses = yield Promise.all(
5751
6844
  venueMarketIdChunks.map((venueMarketIds) => {
5752
- return client.getMidpoints({ venueMarketIds }, { signal });
6845
+ return client.getMidpoints({ venueMarketIds, bestPrice: true }, { signal });
5753
6846
  })
5754
6847
  );
5755
6848
  return mergeMidpointResponses(chunkResponses);
@@ -5759,7 +6852,7 @@ function useVenueMarketMidpoints(options) {
5759
6852
  gcTime: 5 * 6e4,
5760
6853
  refetchOnWindowFocus: false,
5761
6854
  retry: 1,
5762
- placeholderData: import_react_query34.keepPreviousData
6855
+ placeholderData: import_react_query35.keepPreviousData
5763
6856
  });
5764
6857
  const midpointRows = (_c = (_b = query.data) == null ? void 0 : _b.data) != null ? _c : [];
5765
6858
  const midpointsByVenueMarketId = mapMidpointsByVenueMarketId(midpointRows);
@@ -5794,60 +6887,68 @@ function computePriceGaps(input) {
5794
6887
  }
5795
6888
 
5796
6889
  // src/use-viewport-midpoints.ts
5797
- var import_react29 = require("react");
5798
- var normalizeOutcomeLabel = (value) => value.trim().toLowerCase();
5799
- var resolveYesMidpoint = (outcomes) => {
5800
- if (!(outcomes == null ? void 0 : outcomes.length)) return void 0;
5801
- const yesOutcome = outcomes.find((outcome) => normalizeOutcomeLabel(outcome.label) === "yes");
5802
- return yesOutcome == null ? void 0 : yesOutcome.midpoint;
6890
+ var import_react36 = require("react");
6891
+ var buildOutcomeMidpointMap = (outcomes) => {
6892
+ const m = /* @__PURE__ */ new Map();
6893
+ if (!outcomes) return m;
6894
+ for (const o of outcomes) {
6895
+ if (o.midpoint != null) m.set(o.venueMarketOutcomeId, o.midpoint);
6896
+ }
6897
+ return m;
5803
6898
  };
5804
6899
  var resolveUncachedVisibleMarketIds = (visibleMarkets, cache, inFlightIds) => {
6900
+ var _a;
6901
+ const seen = /* @__PURE__ */ new Set();
5805
6902
  const idsToFetch = [];
6903
+ const consider = (id) => {
6904
+ if (!id) return;
6905
+ if (seen.has(id)) return;
6906
+ if (inFlightIds.has(id)) return;
6907
+ if (cache.has(id)) return;
6908
+ seen.add(id);
6909
+ idsToFetch.push(id);
6910
+ };
5806
6911
  for (const market of visibleMarkets) {
5807
- if (inFlightIds.has(market.id)) continue;
5808
- if (cache.has(market.id)) continue;
5809
- idsToFetch.push(market.id);
6912
+ consider(market.id);
6913
+ for (const sibling of (_a = market.matchedVenueMarkets) != null ? _a : []) {
6914
+ consider(sibling.id);
6915
+ }
5810
6916
  }
5811
6917
  return idsToFetch;
5812
6918
  };
5813
6919
  var buildCachedMidpointEntries = (requestedVenueMarketIds, rows) => {
5814
- var _a, _b, _c;
6920
+ var _a;
5815
6921
  const rowsByVenueMarketId = new Map(rows.map((item) => [item.venueMarketId, item]));
5816
6922
  const nextCacheEntries = /* @__PURE__ */ new Map();
5817
6923
  for (const venueMarketId of requestedVenueMarketIds) {
5818
6924
  const item = rowsByVenueMarketId.get(venueMarketId);
5819
- const yesMidpoint = resolveYesMidpoint(item == null ? void 0 : item.outcomes);
5820
6925
  nextCacheEntries.set(venueMarketId, __spreadProps(__spreadValues({}, (item == null ? void 0 : item.venue) ? { venue: item.venue } : {}), {
5821
- midpoint: (_a = yesMidpoint != null ? yesMidpoint : item == null ? void 0 : item.midpoint) != null ? _a : null,
5822
- spread: (_b = item == null ? void 0 : item.spread) != null ? _b : null,
5823
- matched: ((_c = item == null ? void 0 : item.matched) != null ? _c : []).map((matched) => {
5824
- var _a2, _b2;
5825
- return __spreadValues({
5826
- venueMarketId: matched.venueMarketId,
5827
- midpoint: (_a2 = matched.midpoint) != null ? _a2 : null,
5828
- spread: (_b2 = matched.spread) != null ? _b2 : null
5829
- }, matched.venue ? { venue: matched.venue } : {});
5830
- })
6926
+ ownOutcomes: buildOutcomeMidpointMap(item == null ? void 0 : item.outcomes),
6927
+ matched: ((_a = item == null ? void 0 : item.matched) != null ? _a : []).map((sib) => __spreadProps(__spreadValues({
6928
+ venueMarketId: sib.venueMarketId
6929
+ }, sib.venue ? { venue: sib.venue } : {}), {
6930
+ outcomes: buildOutcomeMidpointMap(sib.outcomes)
6931
+ }))
5831
6932
  }));
5832
6933
  }
5833
6934
  return nextCacheEntries;
5834
6935
  };
5835
6936
  function useViewportMidpoints(visibleMarkets) {
5836
6937
  const client = useAggClient();
5837
- const [cache, setCache] = (0, import_react29.useState)(() => /* @__PURE__ */ new Map());
5838
- const inFlightRef = (0, import_react29.useRef)(/* @__PURE__ */ new Set());
5839
- const visibleRef = (0, import_react29.useRef)(visibleMarkets);
6938
+ const [cache, setCache] = (0, import_react36.useState)(() => /* @__PURE__ */ new Map());
6939
+ const inFlightRef = (0, import_react36.useRef)(/* @__PURE__ */ new Set());
6940
+ const visibleRef = (0, import_react36.useRef)(visibleMarkets);
5840
6941
  visibleRef.current = visibleMarkets;
5841
- const visibleFp = (0, import_react29.useMemo)(
6942
+ const visibleFp = (0, import_react36.useMemo)(
5842
6943
  () => [...new Set(visibleMarkets.map((m) => m.id))].sort().join("|"),
5843
6944
  [visibleMarkets]
5844
6945
  );
5845
- (0, import_react29.useEffect)(() => {
6946
+ (0, import_react36.useEffect)(() => {
5846
6947
  const toFetch = resolveUncachedVisibleMarketIds(visibleRef.current, cache, inFlightRef.current);
5847
6948
  if (!toFetch.length) return;
5848
6949
  let cancelled = false;
5849
6950
  for (const id of toFetch) inFlightRef.current.add(id);
5850
- client.getMidpoints(toFetch).then((resp) => {
6951
+ client.getMidpoints(toFetch, { bestPrice: true }).then((resp) => {
5851
6952
  var _a;
5852
6953
  if (cancelled) return;
5853
6954
  const nextCacheEntries = buildCachedMidpointEntries(toFetch, (_a = resp.data) != null ? _a : []);
@@ -5866,29 +6967,31 @@ function useViewportMidpoints(visibleMarkets) {
5866
6967
  cancelled = true;
5867
6968
  };
5868
6969
  }, [visibleFp, cache]);
5869
- const { prices, venueByOutcomeId } = (0, import_react29.useMemo)(() => {
5870
- var _a, _b, _c, _d, _e, _f;
6970
+ const { prices, venueByOutcomeId } = (0, import_react36.useMemo)(() => {
6971
+ var _a, _b, _c, _d;
5871
6972
  const map = /* @__PURE__ */ new Map();
5872
6973
  const venueMap = /* @__PURE__ */ new Map();
5873
6974
  for (const market of visibleMarkets) {
5874
6975
  const entry = cache.get(market.id);
5875
6976
  if (!entry) continue;
5876
- let mid = entry.midpoint;
5877
- let midVenue = (_a = entry.venue) != null ? _a : market.venue;
5878
- for (const m of entry.matched) {
5879
- const matchedFromCache = (_b = cache.get(m.venueMarketId)) == null ? void 0 : _b.midpoint;
5880
- const candidateMidpoint = matchedFromCache != null ? matchedFromCache : m.midpoint;
5881
- if (candidateMidpoint == null) continue;
5882
- if (mid == null || candidateMidpoint < mid) {
5883
- mid = candidateMidpoint;
5884
- midVenue = (_e = (_d = (_c = cache.get(m.venueMarketId)) == null ? void 0 : _c.venue) != null ? _d : m.venue) != null ? _e : market.venue;
5885
- }
5886
- }
5887
- if (mid == null) continue;
6977
+ const ownVenue = (_a = entry.venue) != null ? _a : market.venue;
5888
6978
  for (const outcome of market.venueMarketOutcomes) {
5889
- const isYes = ((_f = outcome.label) == null ? void 0 : _f.toLowerCase()) === "yes";
5890
- map.set(outcome.id, isYes ? mid : 1 - mid);
5891
- venueMap.set(outcome.id, midVenue);
6979
+ let best = (_b = entry.ownOutcomes.get(outcome.id)) != null ? _b : null;
6980
+ let bestVenue = best != null ? ownVenue : null;
6981
+ for (const ref of (_c = outcome.matchedVenueMarketOutcomes) != null ? _c : []) {
6982
+ const sib = entry.matched.find((m) => m.venueMarketId === ref.venueMarketId);
6983
+ if (!sib) continue;
6984
+ const sibMidpoint = sib.outcomes.get(ref.venueMarketOutcomeId);
6985
+ if (sibMidpoint == null) continue;
6986
+ if (best == null || sibMidpoint < best) {
6987
+ best = sibMidpoint;
6988
+ bestVenue = (_d = sib.venue) != null ? _d : bestVenue;
6989
+ }
6990
+ }
6991
+ if (best != null) {
6992
+ map.set(outcome.id, best);
6993
+ if (bestVenue) venueMap.set(outcome.id, bestVenue);
6994
+ }
5892
6995
  }
5893
6996
  }
5894
6997
  return { prices: map, venueByOutcomeId: venueMap };
@@ -5897,15 +7000,15 @@ function useViewportMidpoints(visibleMarkets) {
5897
7000
  }
5898
7001
 
5899
7002
  // src/use-visible-ids.ts
5900
- var import_react30 = require("react");
7003
+ var import_react37 = require("react");
5901
7004
  function useVisibleIds(options = {}) {
5902
7005
  const { rootMargin = "0px", threshold = 0 } = options;
5903
- const [visibleIds, setVisibleIds] = (0, import_react30.useState)(() => /* @__PURE__ */ new Set());
5904
- const observerRef = (0, import_react30.useRef)(null);
5905
- const elementsRef = (0, import_react30.useRef)(/* @__PURE__ */ new Map());
5906
- const elementIdRef = (0, import_react30.useRef)(/* @__PURE__ */ new WeakMap());
5907
- const callbackRefsRef = (0, import_react30.useRef)(/* @__PURE__ */ new Map());
5908
- (0, import_react30.useEffect)(() => {
7006
+ const [visibleIds, setVisibleIds] = (0, import_react37.useState)(() => /* @__PURE__ */ new Set());
7007
+ const observerRef = (0, import_react37.useRef)(null);
7008
+ const elementsRef = (0, import_react37.useRef)(/* @__PURE__ */ new Map());
7009
+ const elementIdRef = (0, import_react37.useRef)(/* @__PURE__ */ new WeakMap());
7010
+ const callbackRefsRef = (0, import_react37.useRef)(/* @__PURE__ */ new Map());
7011
+ (0, import_react37.useEffect)(() => {
5909
7012
  if (typeof IntersectionObserver === "undefined") return;
5910
7013
  const observer = new IntersectionObserver(
5911
7014
  (entries) => {
@@ -5937,7 +7040,7 @@ function useVisibleIds(options = {}) {
5937
7040
  observerRef.current = null;
5938
7041
  };
5939
7042
  }, [rootMargin, threshold]);
5940
- const register = (0, import_react30.useCallback)((id) => {
7043
+ const register = (0, import_react37.useCallback)((id) => {
5941
7044
  const existing = callbackRefsRef.current.get(id);
5942
7045
  if (existing) return existing;
5943
7046
  const callback = (el) => {
@@ -5970,12 +7073,12 @@ function useVisibleIds(options = {}) {
5970
7073
  }
5971
7074
 
5972
7075
  // src/use-app-config.ts
5973
- var import_react_query35 = require("@tanstack/react-query");
7076
+ var import_react_query36 = require("@tanstack/react-query");
5974
7077
  var FIVE_MINUTES = 5 * 60 * 1e3;
5975
7078
  function useAppConfig() {
5976
- var _a, _b, _c, _d, _e, _f;
7079
+ var _a, _b, _c, _d, _e, _f, _g, _h;
5977
7080
  const client = useAggClient();
5978
- const query = (0, import_react_query35.useQuery)({
7081
+ const query = (0, import_react_query36.useQuery)({
5979
7082
  queryKey: ["agg", "app-config"],
5980
7083
  queryFn: () => client.getAppConfig(),
5981
7084
  staleTime: FIVE_MINUTES
@@ -5984,6 +7087,7 @@ function useAppConfig() {
5984
7087
  disabledVenues: (_b = (_a = query.data) == null ? void 0 : _a.disabledVenues) != null ? _b : [],
5985
7088
  disabledCategoryPresets: (_d = (_c = query.data) == null ? void 0 : _c.disabledCategoryPresets) != null ? _d : [],
5986
7089
  earlyAccessEnabled: (_f = (_e = query.data) == null ? void 0 : _e.earlyAccessEnabled) != null ? _f : false,
7090
+ authOptions: (_h = (_g = query.data) == null ? void 0 : _g.authOptions) != null ? _h : [],
5987
7091
  isLoading: query.isLoading,
5988
7092
  error: query.error
5989
7093
  };
@@ -6004,6 +7108,8 @@ function useAppConfig() {
6004
7108
  MatchType,
6005
7109
  QueryClient,
6006
7110
  QueryClientProvider,
7111
+ RedeemRejectedError,
7112
+ TradeSide,
6007
7113
  TurnstileChallengeError,
6008
7114
  Venue,
6009
7115
  computeClosedPositionTotals,
@@ -6018,9 +7124,13 @@ function useAppConfig() {
6018
7124
  getWalletAddressFromUserProfile,
6019
7125
  invalidateBalanceQueries,
6020
7126
  invalidatePositionQueries,
7127
+ invalidateUserActivityQueries,
7128
+ invalidateUserMoneyState,
7129
+ mergeBestPricesPreferringLive,
6021
7130
  optimizedImageUrl,
6022
7131
  parseEmail,
6023
7132
  parseEmailStrict,
7133
+ rangeToSeconds,
6024
7134
  requestAggAuthChooserOpen,
6025
7135
  resolveAggUiLabels,
6026
7136
  resolveDefaultTradingMarket,
@@ -6028,6 +7138,7 @@ function useAppConfig() {
6028
7138
  resolveMarketTradingState,
6029
7139
  resolveMarketWinningOutcome,
6030
7140
  resolveOrderEligibility,
7141
+ resolveRollingWindow,
6031
7142
  resolveTradingStateKind,
6032
7143
  sortVenues,
6033
7144
  timeRangeToInterval,
@@ -6058,6 +7169,7 @@ function useAppConfig() {
6058
7169
  useGeoBlock,
6059
7170
  useLabels,
6060
7171
  useLinkAccount,
7172
+ useLiveBestPrices,
6061
7173
  useLiveCandleOverlay,
6062
7174
  useLiveCandles,
6063
7175
  useLiveMarket,
@@ -6067,11 +7179,14 @@ function useAppConfig() {
6067
7179
  useManagedBalances,
6068
7180
  useMarketChart,
6069
7181
  useMarketOrderbook,
7182
+ useMarketSearch,
6070
7183
  useMidpoints,
6071
7184
  useOnBalanceUpdate,
7185
+ useOnOrderEvent,
6072
7186
  useOnOrderSubmitted,
6073
7187
  useOnRedeemEvent,
6074
7188
  useOnWithdrawalLifecycle,
7189
+ useOptionalAggClient,
6075
7190
  useOrderBook,
6076
7191
  useOrderbookQuote,
6077
7192
  useOrders,
@@ -6082,11 +7197,15 @@ function useAppConfig() {
6082
7197
  useRampSession,
6083
7198
  useRedeem,
6084
7199
  useRedeemEligibleCount,
7200
+ useRedeemLifecycle,
7201
+ useRedeemLifecycles,
7202
+ useRollingChartWindow,
6085
7203
  useSdkLabels,
6086
7204
  useSdkUiConfig,
6087
7205
  useSearch,
6088
7206
  useSmartRoute,
6089
7207
  useSyncBalances,
7208
+ useTradableVenues,
6090
7209
  useUserActivity,
6091
7210
  useUserHoldings,
6092
7211
  useVenueEvent,
@@ -6095,7 +7214,9 @@ function useAppConfig() {
6095
7214
  useVenueMarkets,
6096
7215
  useViewportMidpoints,
6097
7216
  useVisibleIds,
7217
+ useWithdrawEstimate,
6098
7218
  useWithdrawFlow,
6099
7219
  useWithdrawManaged,
6100
- useWithdrawalLifecycle
7220
+ useWithdrawalLifecycle,
7221
+ userActivityQueryKeys
6101
7222
  });