@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.mjs CHANGED
@@ -1,11 +1,12 @@
1
1
  import {
2
2
  useRampQuotes,
3
3
  useRampSession
4
- } from "./chunk-FKTRXKYA.mjs";
4
+ } from "./chunk-R6VANZRA.mjs";
5
5
  import {
6
+ useWithdrawEstimate,
6
7
  useWithdrawFlow,
7
8
  useWithdrawalLifecycle
8
- } from "./chunk-KSSPFJM2.mjs";
9
+ } from "./chunk-V34QGQBO.mjs";
9
10
  import {
10
11
  AggAuthContext,
11
12
  AggBalanceProvider,
@@ -19,6 +20,8 @@ import {
19
20
  MarketStatus,
20
21
  MatchStatus,
21
22
  MatchType,
23
+ RedeemRejectedError,
24
+ TradeSide,
22
25
  Venue,
23
26
  __async,
24
27
  __objRest,
@@ -34,10 +37,13 @@ import {
34
37
  executionKeys,
35
38
  getBuilder,
36
39
  getDepositAddress,
40
+ getIntervalSeconds,
37
41
  getOrCreateBuilder,
38
42
  getWalletAddressFromUserProfile,
39
43
  invalidateBalanceQueries,
40
44
  invalidatePositionQueries,
45
+ invalidateUserActivityQueries,
46
+ invalidateUserMoneyState,
41
47
  marketDataKeys,
42
48
  marketOrderbookDataToResponse,
43
49
  mergeMarketChartData,
@@ -71,18 +77,23 @@ import {
71
77
  useLabels,
72
78
  useManagedBalances,
73
79
  useOnBalanceUpdate,
80
+ useOnOrderEvent,
74
81
  useOnOrderSubmitted,
75
82
  useOnRedeemEvent,
76
83
  useOnWithdrawalLifecycle,
84
+ useOptionalAggClient,
77
85
  usePositions,
78
86
  useQuoteManaged,
79
87
  useRedeem,
80
88
  useRedeemEligibleCount,
89
+ useRedeemLifecycle,
90
+ useRedeemLifecycles,
81
91
  useSdkLabels,
82
92
  useSdkUiConfig,
83
93
  useSyncBalances,
84
- useWithdrawManaged
85
- } from "./chunk-U3DRHUR5.mjs";
94
+ useWithdrawManaged,
95
+ userActivityQueryKeys
96
+ } from "./chunk-2C7JR5OH.mjs";
86
97
 
87
98
  // src/index.ts
88
99
  import { QueryClient as QueryClient4, QueryClientProvider, useQueryClient as useQueryClient2 } from "@tanstack/react-query";
@@ -178,17 +189,19 @@ var requestAggAuthChooserOpen = () => {
178
189
  // src/use-categories.ts
179
190
  import { useInfiniteQuery } from "@tanstack/react-query";
180
191
  function useCategories(options) {
181
- var _a, _b, _c, _d;
192
+ var _a, _b, _c, _d, _e, _f;
182
193
  const client = useAggClient();
183
- const enabled = (_a = options == null ? void 0 : options.enabled) != null ? _a : true;
184
- const limit = (_b = options == null ? void 0 : options.limit) != null ? _b : 20;
194
+ const queryKeyScope = (_a = options == null ? void 0 : options.queryKeyScope) != null ? _a : "categories";
195
+ const parentId = (_b = options == null ? void 0 : options.parentId) != null ? _b : null;
196
+ const enabled = (_c = options == null ? void 0 : options.enabled) != null ? _c : true;
197
+ const limit = (_d = options == null ? void 0 : options.limit) != null ? _d : 20;
185
198
  const query = useInfiniteQuery({
186
- queryKey: ["categories", limit],
199
+ queryKey: [queryKeyScope, "parent", parentId != null ? parentId : "__root__", limit],
187
200
  queryFn: (_0) => __async(null, [_0], function* ({ pageParam }) {
188
- const res = yield client.getCategories({
201
+ const res = yield client.getCategories(__spreadValues({
189
202
  limit,
190
203
  cursor: pageParam
191
- });
204
+ }, parentId != null ? { parentId } : {}));
192
205
  return res;
193
206
  }),
194
207
  initialPageParam: void 0,
@@ -198,7 +211,7 @@ function useCategories(options) {
198
211
  },
199
212
  enabled
200
213
  });
201
- const categories = (_d = (_c = query.data) == null ? void 0 : _c.pages.flatMap((p) => p.data)) != null ? _d : [];
214
+ const categories = (_f = (_e = query.data) == null ? void 0 : _e.pages.flatMap((p) => p.data)) != null ? _f : [];
202
215
  const hasNextPage = !!query.hasNextPage;
203
216
  return __spreadProps(__spreadValues({}, query), {
204
217
  categories,
@@ -226,11 +239,22 @@ import { useInfiniteQuery as useInfiniteQuery2 } from "@tanstack/react-query";
226
239
  function useExecutionOrders(options = {}) {
227
240
  var _a, _b;
228
241
  const client = useAggClient();
229
- const { status, limit = 50, enabled = true, refetchIntervalMs = false } = options;
242
+ const {
243
+ status,
244
+ orderId,
245
+ quoteId,
246
+ limit = 50,
247
+ enabled = true,
248
+ refetchIntervalMs = false
249
+ } = options;
230
250
  const query = useInfiniteQuery2({
231
- queryKey: ["execution-orders", status != null ? status : "all", limit],
251
+ // quoteId + orderId are part of the cache key — different filters
252
+ // produce different result sets, so they have to vary the key.
253
+ queryKey: ["execution-orders", status != null ? status : "all", quoteId != null ? quoteId : null, orderId != null ? orderId : null, limit],
232
254
  queryFn: ({ pageParam }) => client.getExecutionOrders({
233
255
  status,
256
+ orderId,
257
+ quoteId,
234
258
  limit,
235
259
  cursor: pageParam
236
260
  }),
@@ -251,11 +275,37 @@ function useExecutionOrders(options = {}) {
251
275
  }
252
276
 
253
277
  // src/use-user-activity.ts
254
- import { useInfiniteQuery as useInfiniteQuery3 } from "@tanstack/react-query";
278
+ import { keepPreviousData, useInfiniteQuery as useInfiniteQuery3 } from "@tanstack/react-query";
279
+ var DEFAULT_PENDING_REFETCH_INTERVAL_MS = 15e3;
280
+ var PENDING_ACTIVITY_STATUSES = /* @__PURE__ */ new Set([
281
+ "pending",
282
+ // trade pre-fill lifecycle
283
+ "signing",
284
+ "pending_bridge",
285
+ "submitting",
286
+ "submitted",
287
+ // withdrawal lifecycle
288
+ "bridging",
289
+ "transferring"
290
+ ]);
291
+ var hasPendingActivity = (pages) => {
292
+ if (!pages) return false;
293
+ for (const page of pages) {
294
+ for (const item of page.data) {
295
+ if (PENDING_ACTIVITY_STATUSES.has(item.status.toLowerCase())) return true;
296
+ }
297
+ }
298
+ return false;
299
+ };
255
300
  function useUserActivity(options = {}) {
256
301
  var _a, _b;
257
302
  const client = useAggClient();
258
- const { type, limit = 50, enabled = true } = options;
303
+ const {
304
+ type,
305
+ limit = 50,
306
+ enabled = true,
307
+ pendingRefetchIntervalMs = DEFAULT_PENDING_REFETCH_INTERVAL_MS
308
+ } = options;
259
309
  const query = useInfiniteQuery3({
260
310
  queryKey: ["user-activity", type != null ? type : "all", limit],
261
311
  queryFn: ({ pageParam }) => client.getUserActivity({
@@ -268,7 +318,17 @@ function useUserActivity(options = {}) {
268
318
  var _a2;
269
319
  return lastPage.hasMore ? (_a2 = lastPage.nextCursor) != null ? _a2 : void 0 : void 0;
270
320
  },
271
- enabled
321
+ enabled,
322
+ // Keep the previously-loaded pages visible while a refetch is in
323
+ // flight (typically after a deposit / withdraw cache invalidation).
324
+ // Without this the feed flashes to the skeleton mid-session, which
325
+ // is worse UX than briefly showing slightly-stale rows.
326
+ placeholderData: keepPreviousData,
327
+ refetchInterval: (q) => {
328
+ if (pendingRefetchIntervalMs === false) return false;
329
+ const data = q.state.data;
330
+ return hasPendingActivity(data == null ? void 0 : data.pages) ? pendingRefetchIntervalMs : false;
331
+ }
272
332
  });
273
333
  const activities = (_b = (_a = query.data) == null ? void 0 : _a.pages.flatMap((page) => page.data)) != null ? _b : [];
274
334
  const hasNextPage = !!query.hasNextPage;
@@ -343,7 +403,7 @@ import { useMemo as useMemo3 } from "react";
343
403
  import { mergeCandles, mergeClosedCandles } from "@agg-build/sdk";
344
404
 
345
405
  // src/use-market-chart.ts
346
- import { keepPreviousData, useQueries } from "@tanstack/react-query";
406
+ import { keepPreviousData as keepPreviousData2, useQueries } from "@tanstack/react-query";
347
407
 
348
408
  // src/market-data/subscription.ts
349
409
  import { useEffect as useEffect2, useMemo } from "react";
@@ -403,24 +463,23 @@ function useMarketChart(options) {
403
463
  endTs = null,
404
464
  countBack = null,
405
465
  enabled = true,
406
- live
466
+ live,
467
+ refetchIntervalMs = null,
468
+ rangeKey
407
469
  } = options;
470
+ const resolvedRangeKey = rangeKey != null ? rangeKey : interval;
408
471
  const liveEnabled = live != null ? live : enableLiveUpdates;
409
472
  const outcomeIds = (() => {
410
473
  const ids = /* @__PURE__ */ new Set();
411
- if (marketId) {
412
- ids.add(marketId);
413
- }
474
+ if (marketId) ids.add(marketId);
414
475
  if (venueMarketIds) {
415
476
  for (const venueMarketId of venueMarketIds) {
416
- if (venueMarketId) {
417
- ids.add(venueMarketId);
418
- }
477
+ if (venueMarketId) ids.add(venueMarketId);
419
478
  }
420
479
  }
421
- return [...ids];
480
+ return [...ids].sort();
422
481
  })();
423
- const primaryOutcomeId = (_a = outcomeIds[0]) != null ? _a : null;
482
+ const primaryOutcomeId = (_a = marketId != null ? marketId : venueMarketIds == null ? void 0 : venueMarketIds.find(Boolean)) != null ? _a : null;
424
483
  const isQueryEnabled = enabled && outcomeIds.length > 0 && endTs != null && (startTs != null || countBack != null);
425
484
  useMarketDataSubscription({
426
485
  marketId: primaryOutcomeId,
@@ -431,7 +490,11 @@ function useMarketChart(options) {
431
490
  });
432
491
  const queries = useQueries({
433
492
  queries: outcomeIds.map((outcomeId) => ({
434
- queryKey: marketDataKeys.chart(outcomeId, interval, startTs, endTs, countBack),
493
+ // Cache key is intentionally time-free. The rolling window's
494
+ // startTs/endTs advance on every bucket but the user expects the same
495
+ // chart on revisit — see comment on `marketDataKeys.chart`. queryFn
496
+ // closes over the current window so refetches still fetch fresh data.
497
+ queryKey: marketDataKeys.chart(outcomeId, interval, resolvedRangeKey, countBack),
435
498
  queryFn: (_0) => __async(null, [_0], function* ({ signal }) {
436
499
  const response = yield client.getChartBars(
437
500
  {
@@ -452,11 +515,17 @@ function useMarketChart(options) {
452
515
  });
453
516
  }),
454
517
  enabled: isQueryEnabled,
455
- staleTime: 3e4,
456
- gcTime: 5 * 6e4,
518
+ // Treat data as fresh for one bucket — within that window the
519
+ // existing entry serves remounts without a refetch, and the
520
+ // `refetchInterval` below schedules the next bucket's refresh.
521
+ staleTime: refetchIntervalMs != null && refetchIntervalMs > 0 ? refetchIntervalMs : 3e4,
522
+ // 60 min — survives typical tab/page revisits without re-fetching.
523
+ gcTime: 60 * 6e4,
457
524
  refetchOnWindowFocus: false,
458
525
  retry: 1,
459
- placeholderData: keepPreviousData
526
+ placeholderData: keepPreviousData2,
527
+ refetchInterval: refetchIntervalMs != null && refetchIntervalMs > 0 ? refetchIntervalMs : false,
528
+ refetchIntervalInBackground: false
460
529
  }))
461
530
  });
462
531
  const successfulDatasets = queries.flatMap((query) => {
@@ -854,6 +923,128 @@ function findLivePriceById(livePrices, id) {
854
923
  return livePrices.get(id);
855
924
  }
856
925
 
926
+ // src/use-live-best-prices.ts
927
+ import { useMemo as useMemo7, useRef as useRef3 } from "react";
928
+ import { useQueries as useQueries3 } from "@tanstack/react-query";
929
+ var EMPTY = /* @__PURE__ */ new Map();
930
+ var extractOutcomeBestPrices = (state) => {
931
+ var _a, _b;
932
+ const ob = state == null ? void 0 : state.orderbook;
933
+ if (!ob) return {};
934
+ const bestBid = (_a = ob.bids[0]) == null ? void 0 : _a.price;
935
+ const bestAsk = (_b = ob.asks[0]) == null ? void 0 : _b.price;
936
+ return {
937
+ bestBid: bestBid != null ? bestBid : void 0,
938
+ bestAsk: bestAsk != null ? bestAsk : void 0
939
+ };
940
+ };
941
+ var buildFingerprint = (outcomeIds, queries) => {
942
+ var _a, _b, _c, _d;
943
+ const parts = [];
944
+ for (let i = 0; i < outcomeIds.length; i++) {
945
+ const ob = (_b = (_a = queries[i]) == null ? void 0 : _a.data) == null ? void 0 : _b.orderbook;
946
+ const bid = (_c = ob == null ? void 0 : ob.bids[0]) == null ? void 0 : _c.price;
947
+ const ask = (_d = ob == null ? void 0 : ob.asks[0]) == null ? void 0 : _d.price;
948
+ parts.push(`${outcomeIds[i]}:${bid != null ? bid : "_"}:${ask != null ? ask : "_"}`);
949
+ }
950
+ return parts.join("|");
951
+ };
952
+ function useLiveBestPrices(venueMarkets) {
953
+ const {
954
+ features: { enableLiveUpdates }
955
+ } = useAggUiConfig();
956
+ const outcomeIds = useMemo7(() => {
957
+ var _a, _b;
958
+ if (!(venueMarkets == null ? void 0 : venueMarkets.length)) return [];
959
+ const ids = /* @__PURE__ */ new Set();
960
+ for (const vm of venueMarkets) {
961
+ for (const outcome of (_a = vm.venueMarketOutcomes) != null ? _a : []) {
962
+ if (outcome.id) ids.add(outcome.id);
963
+ for (const ref of (_b = outcome.matchedVenueMarketOutcomes) != null ? _b : []) {
964
+ if (ref.venueMarketOutcomeId) ids.add(ref.venueMarketOutcomeId);
965
+ }
966
+ }
967
+ }
968
+ return [...ids].sort();
969
+ }, [venueMarkets]);
970
+ const queries = useQueries3({
971
+ queries: outcomeIds.map((id) => ({
972
+ queryKey: marketDataKeys.live(id),
973
+ queryFn: () => createMarketLiveState(id),
974
+ enabled: false,
975
+ staleTime: Infinity,
976
+ gcTime: 5 * 6e4,
977
+ initialData: () => createMarketLiveState(id)
978
+ }))
979
+ });
980
+ const fingerprint = buildFingerprint(outcomeIds, queries);
981
+ const prevRef = useRef3({
982
+ fingerprint: "",
983
+ result: EMPTY
984
+ });
985
+ return useMemo7(() => {
986
+ var _a, _b, _c, _d;
987
+ if (!(venueMarkets == null ? void 0 : venueMarkets.length) || !enableLiveUpdates) return EMPTY;
988
+ if (fingerprint === prevRef.current.fingerprint) return prevRef.current.result;
989
+ const perOutcome = /* @__PURE__ */ new Map();
990
+ for (let i = 0; i < outcomeIds.length; i++) {
991
+ const state = (_a = queries[i]) == null ? void 0 : _a.data;
992
+ const best = extractOutcomeBestPrices(state);
993
+ if (best.bestBid != null || best.bestAsk != null) {
994
+ perOutcome.set(outcomeIds[i], best);
995
+ }
996
+ }
997
+ if (perOutcome.size === 0) {
998
+ prevRef.current = { fingerprint, result: EMPTY };
999
+ return EMPTY;
1000
+ }
1001
+ const result = new Map(perOutcome);
1002
+ for (const vm of venueMarkets) {
1003
+ for (const outcome of (_b = vm.venueMarketOutcomes) != null ? _b : []) {
1004
+ const refs = (_c = outcome.matchedVenueMarketOutcomes) != null ? _c : [];
1005
+ if (!refs.length) continue;
1006
+ const group = [outcome.id, ...refs.map((ref) => ref.venueMarketOutcomeId)];
1007
+ let groupBestAsk;
1008
+ let groupBestBid;
1009
+ for (const id of group) {
1010
+ const entry = perOutcome.get(id);
1011
+ if (!entry) continue;
1012
+ if (entry.bestAsk != null && (groupBestAsk == null || entry.bestAsk < groupBestAsk)) {
1013
+ groupBestAsk = entry.bestAsk;
1014
+ }
1015
+ if (entry.bestBid != null && (groupBestBid == null || entry.bestBid > groupBestBid)) {
1016
+ groupBestBid = entry.bestBid;
1017
+ }
1018
+ }
1019
+ if (groupBestAsk == null && groupBestBid == null) continue;
1020
+ for (const id of group) {
1021
+ const prev = (_d = result.get(id)) != null ? _d : {};
1022
+ const nextBid = groupBestBid != null ? groupBestBid : prev.bestBid;
1023
+ const nextAsk = groupBestAsk != null ? groupBestAsk : prev.bestAsk;
1024
+ if (nextBid == null && nextAsk == null) continue;
1025
+ result.set(id, __spreadValues(__spreadValues({}, nextBid != null ? { bestBid: nextBid } : {}), nextAsk != null ? { bestAsk: nextAsk } : {}));
1026
+ }
1027
+ }
1028
+ }
1029
+ prevRef.current = { fingerprint, result };
1030
+ return result;
1031
+ }, [venueMarkets, enableLiveUpdates, fingerprint, outcomeIds, queries]);
1032
+ }
1033
+ function mergeBestPricesPreferringLive(rest, live) {
1034
+ var _a, _b, _c;
1035
+ if (!live.size) return rest != null ? rest : EMPTY;
1036
+ if (!rest || !rest.size) return live;
1037
+ const merged = new Map(rest);
1038
+ for (const [id, liveEntry] of live) {
1039
+ const prev = (_a = merged.get(id)) != null ? _a : {};
1040
+ merged.set(id, {
1041
+ bestBid: (_b = liveEntry.bestBid) != null ? _b : prev.bestBid,
1042
+ bestAsk: (_c = liveEntry.bestAsk) != null ? _c : prev.bestAsk
1043
+ });
1044
+ }
1045
+ return merged;
1046
+ }
1047
+
857
1048
  // src/use-live-trades.ts
858
1049
  function useLiveTrades(canonicalMarketId) {
859
1050
  const {
@@ -870,19 +1061,146 @@ function useLiveTrades(canonicalMarketId) {
870
1061
  }
871
1062
 
872
1063
  // src/use-midpoints.ts
873
- import { useMemo as useMemo7 } from "react";
874
1064
  import { useQuery as useQuery2 } from "@tanstack/react-query";
1065
+ import { useMemo as useMemo8 } from "react";
875
1066
  var normalizeVenueMarketIds = (venueMarkets) => {
876
- return [...new Set((venueMarkets != null ? venueMarkets : []).map((market) => market.id).filter(Boolean))].sort(
877
- (left, right) => left.localeCompare(right)
1067
+ var _a;
1068
+ const ids = /* @__PURE__ */ new Set();
1069
+ for (const market of venueMarkets != null ? venueMarkets : []) {
1070
+ if (market.id) ids.add(market.id);
1071
+ for (const sibling of (_a = market.matchedVenueMarkets) != null ? _a : []) {
1072
+ if (sibling.id) ids.add(sibling.id);
1073
+ }
1074
+ }
1075
+ return [...ids].sort((left, right) => left.localeCompare(right));
1076
+ };
1077
+ var normalizeOutcomeLabel = (label) => {
1078
+ return typeof label === "string" ? label.trim().toLowerCase() : "";
1079
+ };
1080
+ var resolveBestMidpointCandidateOutcomeIds = (venueMarkets) => {
1081
+ var _a, _b;
1082
+ if (!(venueMarkets == null ? void 0 : venueMarkets.length)) return [];
1083
+ const candidateIds = [];
1084
+ for (const market of venueMarkets) {
1085
+ const outcomes = (_a = market.venueMarketOutcomes) != null ? _a : [];
1086
+ const yesOutcome = outcomes.find((outcome) => normalizeOutcomeLabel(outcome.label) === "yes");
1087
+ if (yesOutcome == null ? void 0 : yesOutcome.id) {
1088
+ candidateIds.push(yesOutcome.id);
1089
+ continue;
1090
+ }
1091
+ const firstOutcomeId = (_b = outcomes[0]) == null ? void 0 : _b.id;
1092
+ if (firstOutcomeId) {
1093
+ candidateIds.push(firstOutcomeId);
1094
+ }
1095
+ }
1096
+ return [...new Set(candidateIds)];
1097
+ };
1098
+ var resolveSiblingOutcomeMidpoint = (matched, ref) => {
1099
+ var _a, _b;
1100
+ if (!(matched == null ? void 0 : matched.length)) return null;
1101
+ const sibling = matched.find((m) => m.venueMarketId === ref.venueMarketId);
1102
+ if (!((_a = sibling == null ? void 0 : sibling.outcomes) == null ? void 0 : _a.length)) return null;
1103
+ const sibOutcome = sibling.outcomes.find(
1104
+ (o) => o.venueMarketOutcomeId === ref.venueMarketOutcomeId
878
1105
  );
1106
+ if ((sibOutcome == null ? void 0 : sibOutcome.midpoint) == null) return null;
1107
+ return { midpoint: sibOutcome.midpoint, venue: (_b = sibling.venue) != null ? _b : null };
1108
+ };
1109
+ var extractBestPrices = (data, venueMarkets) => {
1110
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
1111
+ const bestPrices = /* @__PURE__ */ new Map();
1112
+ const venuesByOutcome = /* @__PURE__ */ new Map();
1113
+ if (!(data == null ? void 0 : data.length)) return { bestPrices, bestPriceVenuesByOutcomeId: venuesByOutcome };
1114
+ const setEntry = (outcomeId, next) => {
1115
+ const prev = bestPrices.get(outcomeId);
1116
+ const merged = __spreadValues({}, prev != null ? prev : {});
1117
+ if (next.bestBid != null) merged.bestBid = next.bestBid;
1118
+ if (next.bestAsk != null) merged.bestAsk = next.bestAsk;
1119
+ if (merged.bestBid != null || merged.bestAsk != null) bestPrices.set(outcomeId, merged);
1120
+ const prevVenues = venuesByOutcome.get(outcomeId);
1121
+ const mergedVenues = __spreadValues({}, prevVenues != null ? prevVenues : {});
1122
+ if (next.bestBidVenue != null) mergedVenues.bestBidVenue = next.bestBidVenue;
1123
+ if (next.bestAskVenue != null) mergedVenues.bestAskVenue = next.bestAskVenue;
1124
+ if (mergedVenues.bestBidVenue || mergedVenues.bestAskVenue) {
1125
+ venuesByOutcome.set(outcomeId, mergedVenues);
1126
+ }
1127
+ };
1128
+ for (const item of data) {
1129
+ const venue = (_a = item.venue) != null ? _a : null;
1130
+ for (const o of (_b = item.outcomes) != null ? _b : []) {
1131
+ if (o.bestBid != null || o.bestAsk != null) {
1132
+ setEntry(o.venueMarketOutcomeId, {
1133
+ bestBid: o.bestBid,
1134
+ bestAsk: o.bestAsk,
1135
+ bestBidVenue: o.bestBid != null ? venue : null,
1136
+ bestAskVenue: o.bestAsk != null ? venue : null
1137
+ });
1138
+ }
1139
+ }
1140
+ }
1141
+ for (const item of data) {
1142
+ for (const m of (_c = item.matched) != null ? _c : []) {
1143
+ const venue = (_d = m.venue) != null ? _d : null;
1144
+ for (const o of (_e = m.outcomes) != null ? _e : []) {
1145
+ if (bestPrices.has(o.venueMarketOutcomeId)) continue;
1146
+ if (o.bestBid != null || o.bestAsk != null) {
1147
+ setEntry(o.venueMarketOutcomeId, {
1148
+ bestBid: o.bestBid,
1149
+ bestAsk: o.bestAsk,
1150
+ bestBidVenue: o.bestBid != null ? venue : null,
1151
+ bestAskVenue: o.bestAsk != null ? venue : null
1152
+ });
1153
+ }
1154
+ }
1155
+ }
1156
+ }
1157
+ if (venueMarkets == null ? void 0 : venueMarkets.length) {
1158
+ for (const market of venueMarkets) {
1159
+ for (const outcome of (_f = market.venueMarketOutcomes) != null ? _f : []) {
1160
+ const refs = (_g = outcome.matchedVenueMarketOutcomes) != null ? _g : [];
1161
+ if (!refs.length) continue;
1162
+ const group = [outcome.id, ...refs.map((ref) => ref.venueMarketOutcomeId)];
1163
+ let bestAsk;
1164
+ let bestBid;
1165
+ let bestAskVenue;
1166
+ let bestBidVenue;
1167
+ for (const id of group) {
1168
+ const entry = bestPrices.get(id);
1169
+ const venues = venuesByOutcome.get(id);
1170
+ if (!entry) continue;
1171
+ if (entry.bestAsk != null && (bestAsk == null || entry.bestAsk < bestAsk)) {
1172
+ bestAsk = entry.bestAsk;
1173
+ bestAskVenue = (_h = venues == null ? void 0 : venues.bestAskVenue) != null ? _h : bestAskVenue;
1174
+ }
1175
+ if (entry.bestBid != null && (bestBid == null || entry.bestBid > bestBid)) {
1176
+ bestBid = entry.bestBid;
1177
+ bestBidVenue = (_i = venues == null ? void 0 : venues.bestBidVenue) != null ? _i : bestBidVenue;
1178
+ }
1179
+ }
1180
+ if (bestAsk == null && bestBid == null) continue;
1181
+ for (const id of group) {
1182
+ setEntry(id, {
1183
+ bestBid,
1184
+ bestAsk,
1185
+ bestBidVenue,
1186
+ bestAskVenue
1187
+ });
1188
+ }
1189
+ }
1190
+ }
1191
+ }
1192
+ return { bestPrices, bestPriceVenuesByOutcomeId: venuesByOutcome };
879
1193
  };
880
1194
  function useMidpoints(venueMarkets) {
881
1195
  const client = useAggClient();
882
- const ids = useMemo7(() => normalizeVenueMarketIds(venueMarkets), [venueMarkets]);
1196
+ const ids = useMemo8(() => normalizeVenueMarketIds(venueMarkets), [venueMarkets]);
1197
+ const bestMidpointCandidateOutcomeIds = useMemo8(
1198
+ () => resolveBestMidpointCandidateOutcomeIds(venueMarkets),
1199
+ [venueMarkets]
1200
+ );
883
1201
  const { data, isLoading } = useQuery2({
884
1202
  queryKey: ["midpoints", ids],
885
- queryFn: () => client.getMidpoints(ids),
1203
+ queryFn: () => client.getMidpoints(ids, { bestPrice: true }),
886
1204
  enabled: ids.length > 0,
887
1205
  staleTime: Infinity,
888
1206
  gcTime: 30 * 6e4,
@@ -890,70 +1208,153 @@ function useMidpoints(venueMarkets) {
890
1208
  refetchOnWindowFocus: false,
891
1209
  refetchOnReconnect: false
892
1210
  });
893
- const result = useMemo7(() => {
894
- var _a, _b, _c, _d, _e, _f;
1211
+ const result = useMemo8(() => {
1212
+ var _a, _b, _c, _d, _e;
895
1213
  const map = /* @__PURE__ */ new Map();
896
1214
  const venueMap = /* @__PURE__ */ new Map();
897
1215
  if (!(data == null ? void 0 : data.data) || !venueMarkets) return { map, venueMap };
1216
+ const itemByMarketId = new Map(data.data.map((item) => [item.venueMarketId, item]));
898
1217
  for (const item of data.data) {
899
- if ((_a = item.outcomes) == null ? void 0 : _a.length) {
900
- for (const o of item.outcomes) {
901
- if (o.midpoint != null) {
902
- map.set(o.venueMarketOutcomeId, o.midpoint);
903
- if (item.venue) venueMap.set(o.venueMarketOutcomeId, item.venue);
1218
+ if (!((_a = item.outcomes) == null ? void 0 : _a.length)) continue;
1219
+ for (const o of item.outcomes) {
1220
+ if (o.midpoint == null) continue;
1221
+ map.set(o.venueMarketOutcomeId, o.midpoint);
1222
+ if (item.venue) venueMap.set(o.venueMarketOutcomeId, item.venue);
1223
+ }
1224
+ }
1225
+ for (const market of venueMarkets) {
1226
+ const item = itemByMarketId.get(market.id);
1227
+ if (!item) continue;
1228
+ for (const outcome of market.venueMarketOutcomes) {
1229
+ const refs = (_b = outcome.matchedVenueMarketOutcomes) != null ? _b : [];
1230
+ if (!refs.length) continue;
1231
+ let best = (_c = map.get(outcome.id)) != null ? _c : null;
1232
+ let bestVenue = (_d = item.venue) != null ? _d : null;
1233
+ for (const ref of refs) {
1234
+ const sib = resolveSiblingOutcomeMidpoint(item.matched, ref);
1235
+ if (sib == null) continue;
1236
+ if (best == null || sib.midpoint < best) {
1237
+ best = sib.midpoint;
1238
+ bestVenue = (_e = sib.venue) != null ? _e : bestVenue;
904
1239
  }
905
1240
  }
906
- if ((_b = item.matched) == null ? void 0 : _b.length) {
907
- const market = venueMarkets.find((vm) => vm.id === item.venueMarketId);
908
- if (market) {
909
- const primaryYesOutcome = market.venueMarketOutcomes.find(
910
- (o) => {
911
- var _a2;
912
- return ((_a2 = o.label) == null ? void 0 : _a2.toLowerCase()) === "yes";
913
- }
914
- );
915
- const primaryYesMidpoint = primaryYesOutcome ? (_c = map.get(primaryYesOutcome.id)) != null ? _c : null : null;
916
- let bestMatchedMidpoint = null;
917
- let bestMatchedVenue = null;
918
- for (const m of item.matched) {
919
- if (m.midpoint == null) continue;
920
- if (bestMatchedMidpoint == null || m.midpoint < bestMatchedMidpoint) {
921
- bestMatchedMidpoint = m.midpoint;
922
- bestMatchedVenue = (_d = m.venue) != null ? _d : null;
923
- }
924
- }
925
- if (bestMatchedMidpoint != null && (primaryYesMidpoint == null || bestMatchedMidpoint < primaryYesMidpoint)) {
926
- for (const outcome of market.venueMarketOutcomes) {
927
- const isYes = ((_e = outcome.label) == null ? void 0 : _e.toLowerCase()) === "yes";
928
- map.set(outcome.id, isYes ? bestMatchedMidpoint : 1 - bestMatchedMidpoint);
929
- if (bestMatchedVenue) venueMap.set(outcome.id, bestMatchedVenue);
930
- }
931
- }
932
- }
933
- }
934
- continue;
935
- }
936
- if (item.midpoint != null) {
937
- const market = venueMarkets.find((vm) => vm.id === item.venueMarketId);
938
- if (!market) continue;
939
- for (const outcome of market.venueMarketOutcomes) {
940
- const isYes = ((_f = outcome.label) == null ? void 0 : _f.toLowerCase()) === "yes";
941
- map.set(outcome.id, isYes ? item.midpoint : 1 - item.midpoint);
942
- if (item.venue) venueMap.set(outcome.id, item.venue);
1241
+ if (best != null) {
1242
+ map.set(outcome.id, best);
1243
+ if (bestVenue) venueMap.set(outcome.id, bestVenue);
943
1244
  }
944
1245
  }
945
1246
  }
946
1247
  return { map, venueMap };
947
1248
  }, [data, venueMarkets]);
1249
+ const { bestMidpoint, bestMidpointVenue } = useMemo8(() => {
1250
+ let value;
1251
+ let venue;
1252
+ for (const outcomeId of bestMidpointCandidateOutcomeIds) {
1253
+ const midpoint = result.map.get(outcomeId);
1254
+ if (midpoint == null) continue;
1255
+ if (value == null || midpoint < value) {
1256
+ value = midpoint;
1257
+ venue = result.venueMap.get(outcomeId);
1258
+ }
1259
+ }
1260
+ if (value == null) {
1261
+ for (const [outcomeId, midpoint] of result.map) {
1262
+ if (value == null || midpoint < value) {
1263
+ value = midpoint;
1264
+ venue = result.venueMap.get(outcomeId);
1265
+ }
1266
+ }
1267
+ }
1268
+ return { bestMidpoint: value, bestMidpointVenue: venue };
1269
+ }, [bestMidpointCandidateOutcomeIds, result.map, result.venueMap]);
1270
+ const { bestPrices, bestPriceVenuesByOutcomeId } = useMemo8(
1271
+ () => extractBestPrices(data == null ? void 0 : data.data, venueMarkets),
1272
+ [data == null ? void 0 : data.data, venueMarkets]
1273
+ );
948
1274
  return {
949
1275
  prices: result.map,
1276
+ bestMidpointsByOutcomeId: result.map,
950
1277
  venueByOutcomeId: result.venueMap,
951
- isLoading: isLoading && ids.length > 0
1278
+ bestPrices,
1279
+ bestPriceVenuesByOutcomeId,
1280
+ isLoading: isLoading && ids.length > 0,
1281
+ bestMidpoint,
1282
+ bestMidpointVenue
952
1283
  };
953
1284
  }
954
1285
 
1286
+ // src/use-tradable-venues.ts
1287
+ import { useMemo as useMemo9 } from "react";
1288
+ function useTradableVenues(venueMarkets) {
1289
+ const { prices, isLoading } = useMidpoints(venueMarkets);
1290
+ const tradableVenues = useMemo9(() => {
1291
+ var _a;
1292
+ if (isLoading) return null;
1293
+ if (!venueMarkets || venueMarkets.length === 0) return /* @__PURE__ */ new Set();
1294
+ const set = /* @__PURE__ */ new Set();
1295
+ for (const market of venueMarkets) {
1296
+ const outcomes = (_a = market.venueMarketOutcomes) != null ? _a : [];
1297
+ for (const outcome of outcomes) {
1298
+ if (prices.has(outcome.id)) {
1299
+ set.add(market.venue);
1300
+ break;
1301
+ }
1302
+ }
1303
+ }
1304
+ return set;
1305
+ }, [venueMarkets, prices, isLoading]);
1306
+ return { tradableVenues, isLoading };
1307
+ }
1308
+
1309
+ // src/use-rolling-chart-window.ts
1310
+ import { useEffect as useEffect5, useMemo as useMemo10, useState as useState4 } from "react";
1311
+ var RANGE_SECONDS_BY_RANGE = {
1312
+ "1H": 60 * 60,
1313
+ "6H": 6 * 60 * 60,
1314
+ "1D": 24 * 60 * 60,
1315
+ "1W": 7 * 24 * 60 * 60,
1316
+ "1M": 30 * 24 * 60 * 60,
1317
+ ALL: 6 * 30 * 24 * 60 * 60
1318
+ };
1319
+ var rangeToSeconds = (range) => RANGE_SECONDS_BY_RANGE[range];
1320
+ var resolveRollingWindow = (params) => {
1321
+ var _a;
1322
+ const interval = (_a = params.interval) != null ? _a : timeRangeToInterval(params.range);
1323
+ const intervalSeconds = getIntervalSeconds(interval);
1324
+ const rangeSeconds = rangeToSeconds(params.range);
1325
+ const endTs = Math.ceil(params.nowSec / intervalSeconds) * intervalSeconds;
1326
+ return {
1327
+ range: params.range,
1328
+ interval,
1329
+ rangeSeconds,
1330
+ intervalSeconds,
1331
+ nowSec: params.nowSec,
1332
+ endTs,
1333
+ startTs: endTs - rangeSeconds,
1334
+ refetchIntervalMs: intervalSeconds * 1e3
1335
+ };
1336
+ };
1337
+ var useRollingChartWindow = (options) => {
1338
+ var _a;
1339
+ const tickMs = (_a = options.tickMs) != null ? _a : 1e3;
1340
+ const optionsNowMs = options.nowMs;
1341
+ const nowMs = useMemo10(() => optionsNowMs != null ? optionsNowMs : (() => Date.now()), [optionsNowMs]);
1342
+ const [nowSec, setNowSec] = useState4(() => Math.floor(nowMs() / 1e3));
1343
+ useEffect5(() => {
1344
+ setNowSec(Math.floor(nowMs() / 1e3));
1345
+ const handle = setInterval(() => {
1346
+ setNowSec(Math.floor(nowMs() / 1e3));
1347
+ }, tickMs);
1348
+ return () => clearInterval(handle);
1349
+ }, [tickMs, nowMs]);
1350
+ return useMemo10(
1351
+ () => resolveRollingWindow({ range: options.range, nowSec, interval: options.interval }),
1352
+ [options.range, options.interval, nowSec]
1353
+ );
1354
+ };
1355
+
955
1356
  // src/use-market-orderbook.ts
956
- import { useQueries as useQueries3, useQueryClient } from "@tanstack/react-query";
1357
+ import { useQueries as useQueries4, useQueryClient } from "@tanstack/react-query";
957
1358
  function useMarketOrderbook(options) {
958
1359
  var _a, _b, _c, _d, _e, _f, _g;
959
1360
  const queryClient = useQueryClient();
@@ -973,7 +1374,7 @@ function useMarketOrderbook(options) {
973
1374
  enabled: enabled && !!selectedOutcomeId,
974
1375
  orderbook: true
975
1376
  });
976
- const liveQueries = useQueries3({
1377
+ const liveQueries = useQueries4({
977
1378
  queries: subscriptionIds.map((subscriptionId) => ({
978
1379
  queryKey: marketDataKeys.live(subscriptionId),
979
1380
  queryFn: () => createMarketLiveState(subscriptionId),
@@ -1039,7 +1440,7 @@ function useMarketOrderbook(options) {
1039
1440
  }
1040
1441
 
1041
1442
  // src/use-order-book.ts
1042
- import { keepPreviousData as keepPreviousData2, useQuery as useQuery3 } from "@tanstack/react-query";
1443
+ import { keepPreviousData as keepPreviousData3, useQuery as useQuery3 } from "@tanstack/react-query";
1043
1444
  function useOrderBook(options) {
1044
1445
  const client = useAggClient();
1045
1446
  const { orderbooks, enabled = true, canonicalMarketId } = options;
@@ -1065,7 +1466,7 @@ function useOrderBook(options) {
1065
1466
  gcTime: 5 * 6e4,
1066
1467
  refetchOnWindowFocus: false,
1067
1468
  retry: 1,
1068
- placeholderData: keepPreviousData2
1469
+ placeholderData: keepPreviousData3
1069
1470
  });
1070
1471
  const data = (() => {
1071
1472
  var _a, _b;
@@ -1120,7 +1521,7 @@ function useOrderBook(options) {
1120
1521
  }
1121
1522
 
1122
1523
  // src/use-orderbook-quote.ts
1123
- import { keepPreviousData as keepPreviousData3, useQuery as useQuery4 } from "@tanstack/react-query";
1524
+ import { keepPreviousData as keepPreviousData4, useQuery as useQuery4 } from "@tanstack/react-query";
1124
1525
  var QUOTE_DEBOUNCE_MS = 300;
1125
1526
  var createUnavailableOrderbookError = (message, code, retryable) => {
1126
1527
  const error = new Error(message);
@@ -1213,7 +1614,7 @@ function useOrderbookQuote(options) {
1213
1614
  staleTime: 1e4,
1214
1615
  gcTime: 5 * 6e4,
1215
1616
  retry: 1,
1216
- placeholderData: keepPreviousData3
1617
+ placeholderData: keepPreviousData4
1217
1618
  });
1218
1619
  return {
1219
1620
  data: (_a = query.data) != null ? _a : null,
@@ -1249,18 +1650,18 @@ function useOrders(options = {}) {
1249
1650
  import {
1250
1651
  QueryClient,
1251
1652
  QueryClientContext,
1252
- keepPreviousData as keepPreviousData4,
1653
+ keepPreviousData as keepPreviousData5,
1253
1654
  useInfiniteQuery as useInfiniteQuery5
1254
1655
  } from "@tanstack/react-query";
1255
- import { useContext as useContext2, useEffect as useEffect5, useState as useState4 } from "react";
1656
+ import { useContext as useContext2, useEffect as useEffect6, useState as useState5 } from "react";
1256
1657
  function useSearch(options) {
1257
1658
  var _a, _b, _c;
1258
1659
  const client = useContext2(AggClientContext);
1259
1660
  const queryClient = useContext2(QueryClientContext);
1260
- const [fallbackQueryClient] = useState4(() => new QueryClient());
1261
- const { q, type, categoryIds, limit = 20, enabled = true } = options;
1661
+ const [fallbackQueryClient] = useState5(() => new QueryClient());
1662
+ const { q, type, categoryIds, limit = 20, enabled = true, deep = false } = options;
1262
1663
  const isEnabled = enabled && q.length > 0;
1263
- useEffect5(() => {
1664
+ useEffect6(() => {
1264
1665
  if (queryClient) return void 0;
1265
1666
  fallbackQueryClient.mount();
1266
1667
  return () => {
@@ -1272,7 +1673,9 @@ function useSearch(options) {
1272
1673
  }
1273
1674
  const query = useInfiniteQuery5(
1274
1675
  {
1275
- queryKey: ["search", q, type, (_a = categoryIds == null ? void 0 : categoryIds.join(",")) != null ? _a : "", limit],
1676
+ // deep is part of the key TanStack treats deep vs light as
1677
+ // independent queries so users can have both modes cached side-by-side.
1678
+ queryKey: ["search", q, type, (_a = categoryIds == null ? void 0 : categoryIds.join(",")) != null ? _a : "", limit, deep],
1276
1679
  queryFn: (_0) => __async(null, [_0], function* ({ pageParam }) {
1277
1680
  if (!client) {
1278
1681
  throw new Error("useSearch must be used within an <AggProvider>");
@@ -1282,7 +1685,8 @@ function useSearch(options) {
1282
1685
  type,
1283
1686
  categoryIds,
1284
1687
  limit,
1285
- cursor: pageParam
1688
+ cursor: pageParam,
1689
+ deep
1286
1690
  });
1287
1691
  return res;
1288
1692
  }),
@@ -1292,7 +1696,7 @@ function useSearch(options) {
1292
1696
  if (!lastPage.hasMore) return void 0;
1293
1697
  return (_a2 = lastPage.nextCursor) != null ? _a2 : void 0;
1294
1698
  },
1295
- placeholderData: keepPreviousData4,
1699
+ placeholderData: keepPreviousData5,
1296
1700
  enabled: isEnabled && !!client
1297
1701
  },
1298
1702
  queryClient != null ? queryClient : fallbackQueryClient
@@ -1310,8 +1714,95 @@ function useSearch(options) {
1310
1714
  };
1311
1715
  }
1312
1716
 
1717
+ // src/use-market-search.ts
1718
+ import { useCallback as useCallback5, useState as useState6 } from "react";
1719
+ function useMarketSearch(options) {
1720
+ var _a;
1721
+ const {
1722
+ type,
1723
+ categoryIds,
1724
+ limit = 20,
1725
+ debounceMs = 200,
1726
+ enableSuggestions = true,
1727
+ minLength = 1
1728
+ } = options;
1729
+ const [query, setQueryState] = useState6("");
1730
+ const [submittedQuery, setSubmittedQuery] = useState6(null);
1731
+ const debouncedQuery = useDebouncedValue(query, debounceMs);
1732
+ const trimmedDebounced = debouncedQuery.trim();
1733
+ const suggestionsEnabled = enableSuggestions && trimmedDebounced.length >= minLength;
1734
+ const suggestionsQuery = useSearch({
1735
+ q: trimmedDebounced,
1736
+ type,
1737
+ categoryIds,
1738
+ limit,
1739
+ enabled: suggestionsEnabled,
1740
+ deep: false
1741
+ });
1742
+ const submittedQ = (_a = submittedQuery == null ? void 0 : submittedQuery.trim()) != null ? _a : "";
1743
+ const resultsQuery = useSearch({
1744
+ q: submittedQ,
1745
+ type,
1746
+ categoryIds,
1747
+ limit,
1748
+ enabled: submittedQ.length > 0,
1749
+ deep: true
1750
+ });
1751
+ const setQuery = useCallback5((value) => {
1752
+ setQueryState(value);
1753
+ }, []);
1754
+ const submit = useCallback5(
1755
+ (q) => {
1756
+ const target = (q != null ? q : query).trim();
1757
+ if (target.length === 0) return;
1758
+ setSubmittedQuery(target);
1759
+ },
1760
+ [query]
1761
+ );
1762
+ const clear = useCallback5(() => {
1763
+ setQueryState("");
1764
+ setSubmittedQuery(null);
1765
+ }, []);
1766
+ return {
1767
+ /** Current input value (controlled). */
1768
+ query,
1769
+ /** Update the input value. Triggers the debounced typeahead. */
1770
+ setQuery,
1771
+ /** The query value that produced the current `results`, or null if none. */
1772
+ submittedQuery,
1773
+ /** Fire a deep search. Use this on Enter / Search button. */
1774
+ submit,
1775
+ /** Reset both input and results state. */
1776
+ clear,
1777
+ /**
1778
+ * Typeahead state. Backed by a light /search call (no reranker).
1779
+ * `data` is paginated like `useSearch.data` (flattened across pages).
1780
+ */
1781
+ suggestions: {
1782
+ data: suggestionsQuery.data,
1783
+ isLoading: suggestionsQuery.isLoading,
1784
+ isError: suggestionsQuery.isError,
1785
+ error: suggestionsQuery.error
1786
+ },
1787
+ /**
1788
+ * Full-page results state. Backed by a deep /search call (reranker on).
1789
+ * Cursor pagination is exposed via `fetchNextPage` / `hasNextPage`.
1790
+ */
1791
+ results: {
1792
+ data: resultsQuery.data,
1793
+ isLoading: resultsQuery.isLoading,
1794
+ isError: resultsQuery.isError,
1795
+ error: resultsQuery.error,
1796
+ hasNextPage: resultsQuery.hasNextPage,
1797
+ fetchNextPage: resultsQuery.fetchNextPage,
1798
+ isFetchingNextPage: resultsQuery.isFetchingNextPage
1799
+ }
1800
+ };
1801
+ }
1802
+
1313
1803
  // src/use-smart-route.ts
1314
- import { useQuery as useQuery6, keepPreviousData as keepPreviousData5 } from "@tanstack/react-query";
1804
+ import { keepPreviousData as keepPreviousData6, useQuery as useQuery6 } from "@tanstack/react-query";
1805
+ var SMART_ROUTE_STALE_TIME_MS = 2e4;
1315
1806
  function useSmartRoute(options) {
1316
1807
  var _a, _b;
1317
1808
  const client = useAggClient();
@@ -1326,7 +1817,9 @@ function useSmartRoute(options) {
1326
1817
  chainBalances,
1327
1818
  slipCapBps,
1328
1819
  compareVenues,
1329
- enabled = true
1820
+ deepEstimate,
1821
+ enabled = true,
1822
+ staleTimeMs = SMART_ROUTE_STALE_TIME_MS
1330
1823
  } = options;
1331
1824
  const resolvedVenueMarketOutcomeId = (_a = venueMarketOutcomeId != null ? venueMarketOutcomeId : venueMarketId) != null ? _a : outcomeId;
1332
1825
  const query = useQuery6({
@@ -1339,7 +1832,8 @@ function useSmartRoute(options) {
1339
1832
  sellShares != null ? sellShares : null,
1340
1833
  chainBalances ? JSON.stringify(chainBalances) : null,
1341
1834
  slipCapBps != null ? slipCapBps : null,
1342
- compareVenues != null ? compareVenues : false
1835
+ compareVenues != null ? compareVenues : false,
1836
+ deepEstimate != null ? deepEstimate : false
1343
1837
  ],
1344
1838
  queryFn: (_0) => __async(null, [_0], function* ({ signal }) {
1345
1839
  return client.getSmartRoute(
@@ -1351,17 +1845,19 @@ function useSmartRoute(options) {
1351
1845
  sellShares,
1352
1846
  chainBalances,
1353
1847
  slipCapBps,
1354
- compareVenues
1848
+ compareVenues,
1849
+ deepEstimate
1355
1850
  },
1356
1851
  { signal }
1357
1852
  );
1358
1853
  }),
1359
1854
  enabled: enabled && !!resolvedVenueMarketOutcomeId && ((maxSpend != null ? maxSpend : 0) > 0 || (sellShares != null ? sellShares : 0) > 0),
1360
- staleTime: 1e4,
1855
+ staleTime: staleTimeMs,
1856
+ refetchInterval: staleTimeMs > 0 ? staleTimeMs : false,
1361
1857
  gcTime: 6e4,
1362
1858
  refetchOnWindowFocus: false,
1363
1859
  retry: 1,
1364
- placeholderData: keepPreviousData5
1860
+ placeholderData: keepPreviousData6
1365
1861
  });
1366
1862
  const error = query.error;
1367
1863
  return {
@@ -1405,7 +1901,7 @@ function useUserHoldings(options) {
1405
1901
  }
1406
1902
 
1407
1903
  // src/use-enriched-venue-event.ts
1408
- import { useMemo as useMemo8 } from "react";
1904
+ import { useMemo as useMemo11 } from "react";
1409
1905
 
1410
1906
  // src/use-venue-event.ts
1411
1907
  import { useQuery as useQuery7 } from "@tanstack/react-query";
@@ -1433,12 +1929,12 @@ function useVenueEvent(options) {
1433
1929
 
1434
1930
  // src/use-venue-markets.ts
1435
1931
  import { QueryClient as QueryClient2, QueryClientContext as QueryClientContext2, useInfiniteQuery as useInfiniteQuery7 } from "@tanstack/react-query";
1436
- import { useContext as useContext3, useEffect as useEffect6, useState as useState5 } from "react";
1932
+ import { useContext as useContext3, useEffect as useEffect7, useState as useState7 } from "react";
1437
1933
  function useVenueMarkets(options) {
1438
1934
  var _a, _b, _c, _d, _e;
1439
1935
  const client = useContext3(AggClientContext);
1440
1936
  const queryClient = useContext3(QueryClientContext2);
1441
- const [fallbackQueryClient] = useState5(() => new QueryClient2());
1937
+ const [fallbackQueryClient] = useState7(() => new QueryClient2());
1442
1938
  const venue = options == null ? void 0 : options.venue;
1443
1939
  const venueEventId = options == null ? void 0 : options.venueEventId;
1444
1940
  const search = options == null ? void 0 : options.search;
@@ -1449,7 +1945,7 @@ function useVenueMarkets(options) {
1449
1945
  const limit = (_b = options == null ? void 0 : options.limit) != null ? _b : 20;
1450
1946
  const sortBy = options == null ? void 0 : options.sortBy;
1451
1947
  const sortDir = options == null ? void 0 : options.sortDir;
1452
- useEffect6(() => {
1948
+ useEffect7(() => {
1453
1949
  if (queryClient) return void 0;
1454
1950
  fallbackQueryClient.mount();
1455
1951
  return () => {
@@ -1529,7 +2025,7 @@ function useEnrichedVenueEvent(options) {
1529
2025
  sortBy: "yesPrice",
1530
2026
  sortDir: "desc"
1531
2027
  });
1532
- const enrichedEvent = useMemo8(() => {
2028
+ const enrichedEvent = useMemo11(() => {
1533
2029
  if (!event) return void 0;
1534
2030
  if (markets.length === 0) return event;
1535
2031
  return mergeEventWithFullMarkets(event, markets);
@@ -1546,15 +2042,15 @@ function useEnrichedVenueEvent(options) {
1546
2042
  import {
1547
2043
  QueryClient as QueryClient3,
1548
2044
  QueryClientContext as QueryClientContext3,
1549
- keepPreviousData as keepPreviousData6,
2045
+ keepPreviousData as keepPreviousData7,
1550
2046
  useInfiniteQuery as useInfiniteQuery8
1551
2047
  } from "@tanstack/react-query";
1552
- import { useContext as useContext4, useEffect as useEffect7, useMemo as useMemo9, useRef as useRef3, useState as useState6 } from "react";
2048
+ import { useContext as useContext4, useEffect as useEffect8, useMemo as useMemo12, useRef as useRef4, useState as useState8 } from "react";
1553
2049
  function useVenueEvents(options) {
1554
2050
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
1555
2051
  const client = useContext4(AggClientContext);
1556
2052
  const queryClient = useContext4(QueryClientContext3);
1557
- const [fallbackQueryClient] = useState6(() => new QueryClient3());
2053
+ const [fallbackQueryClient] = useState8(() => new QueryClient3());
1558
2054
  const venues = options == null ? void 0 : options.venues;
1559
2055
  const search = options == null ? void 0 : options.search;
1560
2056
  const categoryIds = options == null ? void 0 : options.categoryIds;
@@ -1564,12 +2060,13 @@ function useVenueEvents(options) {
1564
2060
  const status = options == null ? void 0 : options.status;
1565
2061
  const sortBy = options == null ? void 0 : options.sortBy;
1566
2062
  const sortDir = options == null ? void 0 : options.sortDir;
2063
+ const recurrence = options == null ? void 0 : options.recurrence;
1567
2064
  const queryKeyScope = (_d = options == null ? void 0 : options.queryKeyScope) != null ? _d : "events";
1568
2065
  const minYesPrice = options == null ? void 0 : options.minYesPrice;
1569
2066
  const maxYesPrice = options == null ? void 0 : options.maxYesPrice;
1570
2067
  const endDateFrom = options == null ? void 0 : options.endDateFrom;
1571
2068
  const initialPages = options == null ? void 0 : options.initialPages;
1572
- useEffect7(() => {
2069
+ useEffect8(() => {
1573
2070
  if (queryClient) return void 0;
1574
2071
  fallbackQueryClient.mount();
1575
2072
  return () => {
@@ -1590,6 +2087,7 @@ function useVenueEvents(options) {
1590
2087
  (_g = status == null ? void 0 : status.join(",")) != null ? _g : "",
1591
2088
  sortBy != null ? sortBy : "",
1592
2089
  sortDir != null ? sortDir : "",
2090
+ recurrence != null ? recurrence : "",
1593
2091
  minYesPrice != null ? minYesPrice : "",
1594
2092
  maxYesPrice != null ? maxYesPrice : "",
1595
2093
  endDateFrom != null ? endDateFrom : "",
@@ -1607,6 +2105,7 @@ function useVenueEvents(options) {
1607
2105
  status,
1608
2106
  sortBy,
1609
2107
  sortDir,
2108
+ recurrence,
1610
2109
  limit,
1611
2110
  minYesPrice,
1612
2111
  maxYesPrice,
@@ -1622,13 +2121,13 @@ function useVenueEvents(options) {
1622
2121
  return (_a2 = lastPage.nextCursor) != null ? _a2 : void 0;
1623
2122
  },
1624
2123
  // TODO: RMIK - Comment out to show skeletons on category switch
1625
- placeholderData: keepPreviousData6,
2124
+ placeholderData: keepPreviousData7,
1626
2125
  enabled: enabled && !!client
1627
2126
  },
1628
2127
  queryClient != null ? queryClient : fallbackQueryClient
1629
2128
  );
1630
- const prefetchedRef = useRef3(false);
1631
- useEffect7(() => {
2129
+ const prefetchedRef = useRef4(false);
2130
+ useEffect8(() => {
1632
2131
  var _a2, _b2;
1633
2132
  if (prefetchedRef.current) return;
1634
2133
  if (!initialPages || initialPages <= 1) return;
@@ -1646,7 +2145,7 @@ function useVenueEvents(options) {
1646
2145
  query.hasNextPage,
1647
2146
  query.fetchNextPage
1648
2147
  ]);
1649
- const events = useMemo9(
2148
+ const events = useMemo12(
1650
2149
  () => {
1651
2150
  var _a2, _b2;
1652
2151
  return (_b2 = (_a2 = query.data) == null ? void 0 : _a2.pages.flatMap((page) => page.data)) != null ? _b2 : [];
@@ -1664,7 +2163,7 @@ function useVenueEvents(options) {
1664
2163
  }
1665
2164
 
1666
2165
  // src/use-venue-market-midpoints.ts
1667
- import { keepPreviousData as keepPreviousData7, useQuery as useQuery8 } from "@tanstack/react-query";
2166
+ import { keepPreviousData as keepPreviousData8, useQuery as useQuery8 } from "@tanstack/react-query";
1668
2167
  var MAX_VENUE_MARKET_IDS_PER_REQUEST = 200;
1669
2168
  var normalizeVenueMarketIds2 = (venueMarketIds) => {
1670
2169
  return [
@@ -1709,7 +2208,7 @@ function useVenueMarketMidpoints(options) {
1709
2208
  }
1710
2209
  const chunkResponses = yield Promise.all(
1711
2210
  venueMarketIdChunks.map((venueMarketIds) => {
1712
- return client.getMidpoints({ venueMarketIds }, { signal });
2211
+ return client.getMidpoints({ venueMarketIds, bestPrice: true }, { signal });
1713
2212
  })
1714
2213
  );
1715
2214
  return mergeMidpointResponses(chunkResponses);
@@ -1719,7 +2218,7 @@ function useVenueMarketMidpoints(options) {
1719
2218
  gcTime: 5 * 6e4,
1720
2219
  refetchOnWindowFocus: false,
1721
2220
  retry: 1,
1722
- placeholderData: keepPreviousData7
2221
+ placeholderData: keepPreviousData8
1723
2222
  });
1724
2223
  const midpointRows = (_c = (_b = query.data) == null ? void 0 : _b.data) != null ? _c : [];
1725
2224
  const midpointsByVenueMarketId = mapMidpointsByVenueMarketId(midpointRows);
@@ -1754,60 +2253,68 @@ function computePriceGaps(input) {
1754
2253
  }
1755
2254
 
1756
2255
  // src/use-viewport-midpoints.ts
1757
- import { useEffect as useEffect8, useMemo as useMemo10, useRef as useRef4, useState as useState7 } from "react";
1758
- var normalizeOutcomeLabel = (value) => value.trim().toLowerCase();
1759
- var resolveYesMidpoint = (outcomes) => {
1760
- if (!(outcomes == null ? void 0 : outcomes.length)) return void 0;
1761
- const yesOutcome = outcomes.find((outcome) => normalizeOutcomeLabel(outcome.label) === "yes");
1762
- return yesOutcome == null ? void 0 : yesOutcome.midpoint;
2256
+ import { useEffect as useEffect9, useMemo as useMemo13, useRef as useRef5, useState as useState9 } from "react";
2257
+ var buildOutcomeMidpointMap = (outcomes) => {
2258
+ const m = /* @__PURE__ */ new Map();
2259
+ if (!outcomes) return m;
2260
+ for (const o of outcomes) {
2261
+ if (o.midpoint != null) m.set(o.venueMarketOutcomeId, o.midpoint);
2262
+ }
2263
+ return m;
1763
2264
  };
1764
2265
  var resolveUncachedVisibleMarketIds = (visibleMarkets, cache, inFlightIds) => {
2266
+ var _a;
2267
+ const seen = /* @__PURE__ */ new Set();
1765
2268
  const idsToFetch = [];
2269
+ const consider = (id) => {
2270
+ if (!id) return;
2271
+ if (seen.has(id)) return;
2272
+ if (inFlightIds.has(id)) return;
2273
+ if (cache.has(id)) return;
2274
+ seen.add(id);
2275
+ idsToFetch.push(id);
2276
+ };
1766
2277
  for (const market of visibleMarkets) {
1767
- if (inFlightIds.has(market.id)) continue;
1768
- if (cache.has(market.id)) continue;
1769
- idsToFetch.push(market.id);
2278
+ consider(market.id);
2279
+ for (const sibling of (_a = market.matchedVenueMarkets) != null ? _a : []) {
2280
+ consider(sibling.id);
2281
+ }
1770
2282
  }
1771
2283
  return idsToFetch;
1772
2284
  };
1773
2285
  var buildCachedMidpointEntries = (requestedVenueMarketIds, rows) => {
1774
- var _a, _b, _c;
2286
+ var _a;
1775
2287
  const rowsByVenueMarketId = new Map(rows.map((item) => [item.venueMarketId, item]));
1776
2288
  const nextCacheEntries = /* @__PURE__ */ new Map();
1777
2289
  for (const venueMarketId of requestedVenueMarketIds) {
1778
2290
  const item = rowsByVenueMarketId.get(venueMarketId);
1779
- const yesMidpoint = resolveYesMidpoint(item == null ? void 0 : item.outcomes);
1780
2291
  nextCacheEntries.set(venueMarketId, __spreadProps(__spreadValues({}, (item == null ? void 0 : item.venue) ? { venue: item.venue } : {}), {
1781
- midpoint: (_a = yesMidpoint != null ? yesMidpoint : item == null ? void 0 : item.midpoint) != null ? _a : null,
1782
- spread: (_b = item == null ? void 0 : item.spread) != null ? _b : null,
1783
- matched: ((_c = item == null ? void 0 : item.matched) != null ? _c : []).map((matched) => {
1784
- var _a2, _b2;
1785
- return __spreadValues({
1786
- venueMarketId: matched.venueMarketId,
1787
- midpoint: (_a2 = matched.midpoint) != null ? _a2 : null,
1788
- spread: (_b2 = matched.spread) != null ? _b2 : null
1789
- }, matched.venue ? { venue: matched.venue } : {});
1790
- })
2292
+ ownOutcomes: buildOutcomeMidpointMap(item == null ? void 0 : item.outcomes),
2293
+ matched: ((_a = item == null ? void 0 : item.matched) != null ? _a : []).map((sib) => __spreadProps(__spreadValues({
2294
+ venueMarketId: sib.venueMarketId
2295
+ }, sib.venue ? { venue: sib.venue } : {}), {
2296
+ outcomes: buildOutcomeMidpointMap(sib.outcomes)
2297
+ }))
1791
2298
  }));
1792
2299
  }
1793
2300
  return nextCacheEntries;
1794
2301
  };
1795
2302
  function useViewportMidpoints(visibleMarkets) {
1796
2303
  const client = useAggClient();
1797
- const [cache, setCache] = useState7(() => /* @__PURE__ */ new Map());
1798
- const inFlightRef = useRef4(/* @__PURE__ */ new Set());
1799
- const visibleRef = useRef4(visibleMarkets);
2304
+ const [cache, setCache] = useState9(() => /* @__PURE__ */ new Map());
2305
+ const inFlightRef = useRef5(/* @__PURE__ */ new Set());
2306
+ const visibleRef = useRef5(visibleMarkets);
1800
2307
  visibleRef.current = visibleMarkets;
1801
- const visibleFp = useMemo10(
2308
+ const visibleFp = useMemo13(
1802
2309
  () => [...new Set(visibleMarkets.map((m) => m.id))].sort().join("|"),
1803
2310
  [visibleMarkets]
1804
2311
  );
1805
- useEffect8(() => {
2312
+ useEffect9(() => {
1806
2313
  const toFetch = resolveUncachedVisibleMarketIds(visibleRef.current, cache, inFlightRef.current);
1807
2314
  if (!toFetch.length) return;
1808
2315
  let cancelled = false;
1809
2316
  for (const id of toFetch) inFlightRef.current.add(id);
1810
- client.getMidpoints(toFetch).then((resp) => {
2317
+ client.getMidpoints(toFetch, { bestPrice: true }).then((resp) => {
1811
2318
  var _a;
1812
2319
  if (cancelled) return;
1813
2320
  const nextCacheEntries = buildCachedMidpointEntries(toFetch, (_a = resp.data) != null ? _a : []);
@@ -1826,29 +2333,31 @@ function useViewportMidpoints(visibleMarkets) {
1826
2333
  cancelled = true;
1827
2334
  };
1828
2335
  }, [visibleFp, cache]);
1829
- const { prices, venueByOutcomeId } = useMemo10(() => {
1830
- var _a, _b, _c, _d, _e, _f;
2336
+ const { prices, venueByOutcomeId } = useMemo13(() => {
2337
+ var _a, _b, _c, _d;
1831
2338
  const map = /* @__PURE__ */ new Map();
1832
2339
  const venueMap = /* @__PURE__ */ new Map();
1833
2340
  for (const market of visibleMarkets) {
1834
2341
  const entry = cache.get(market.id);
1835
2342
  if (!entry) continue;
1836
- let mid = entry.midpoint;
1837
- let midVenue = (_a = entry.venue) != null ? _a : market.venue;
1838
- for (const m of entry.matched) {
1839
- const matchedFromCache = (_b = cache.get(m.venueMarketId)) == null ? void 0 : _b.midpoint;
1840
- const candidateMidpoint = matchedFromCache != null ? matchedFromCache : m.midpoint;
1841
- if (candidateMidpoint == null) continue;
1842
- if (mid == null || candidateMidpoint < mid) {
1843
- mid = candidateMidpoint;
1844
- midVenue = (_e = (_d = (_c = cache.get(m.venueMarketId)) == null ? void 0 : _c.venue) != null ? _d : m.venue) != null ? _e : market.venue;
1845
- }
1846
- }
1847
- if (mid == null) continue;
2343
+ const ownVenue = (_a = entry.venue) != null ? _a : market.venue;
1848
2344
  for (const outcome of market.venueMarketOutcomes) {
1849
- const isYes = ((_f = outcome.label) == null ? void 0 : _f.toLowerCase()) === "yes";
1850
- map.set(outcome.id, isYes ? mid : 1 - mid);
1851
- venueMap.set(outcome.id, midVenue);
2345
+ let best = (_b = entry.ownOutcomes.get(outcome.id)) != null ? _b : null;
2346
+ let bestVenue = best != null ? ownVenue : null;
2347
+ for (const ref of (_c = outcome.matchedVenueMarketOutcomes) != null ? _c : []) {
2348
+ const sib = entry.matched.find((m) => m.venueMarketId === ref.venueMarketId);
2349
+ if (!sib) continue;
2350
+ const sibMidpoint = sib.outcomes.get(ref.venueMarketOutcomeId);
2351
+ if (sibMidpoint == null) continue;
2352
+ if (best == null || sibMidpoint < best) {
2353
+ best = sibMidpoint;
2354
+ bestVenue = (_d = sib.venue) != null ? _d : bestVenue;
2355
+ }
2356
+ }
2357
+ if (best != null) {
2358
+ map.set(outcome.id, best);
2359
+ if (bestVenue) venueMap.set(outcome.id, bestVenue);
2360
+ }
1852
2361
  }
1853
2362
  }
1854
2363
  return { prices: map, venueByOutcomeId: venueMap };
@@ -1857,15 +2366,15 @@ function useViewportMidpoints(visibleMarkets) {
1857
2366
  }
1858
2367
 
1859
2368
  // src/use-visible-ids.ts
1860
- import { useCallback as useCallback5, useEffect as useEffect9, useRef as useRef5, useState as useState8 } from "react";
2369
+ import { useCallback as useCallback6, useEffect as useEffect10, useRef as useRef6, useState as useState10 } from "react";
1861
2370
  function useVisibleIds(options = {}) {
1862
2371
  const { rootMargin = "0px", threshold = 0 } = options;
1863
- const [visibleIds, setVisibleIds] = useState8(() => /* @__PURE__ */ new Set());
1864
- const observerRef = useRef5(null);
1865
- const elementsRef = useRef5(/* @__PURE__ */ new Map());
1866
- const elementIdRef = useRef5(/* @__PURE__ */ new WeakMap());
1867
- const callbackRefsRef = useRef5(/* @__PURE__ */ new Map());
1868
- useEffect9(() => {
2372
+ const [visibleIds, setVisibleIds] = useState10(() => /* @__PURE__ */ new Set());
2373
+ const observerRef = useRef6(null);
2374
+ const elementsRef = useRef6(/* @__PURE__ */ new Map());
2375
+ const elementIdRef = useRef6(/* @__PURE__ */ new WeakMap());
2376
+ const callbackRefsRef = useRef6(/* @__PURE__ */ new Map());
2377
+ useEffect10(() => {
1869
2378
  if (typeof IntersectionObserver === "undefined") return;
1870
2379
  const observer = new IntersectionObserver(
1871
2380
  (entries) => {
@@ -1897,7 +2406,7 @@ function useVisibleIds(options = {}) {
1897
2406
  observerRef.current = null;
1898
2407
  };
1899
2408
  }, [rootMargin, threshold]);
1900
- const register = useCallback5((id) => {
2409
+ const register = useCallback6((id) => {
1901
2410
  const existing = callbackRefsRef.current.get(id);
1902
2411
  if (existing) return existing;
1903
2412
  const callback = (el) => {
@@ -1933,7 +2442,7 @@ function useVisibleIds(options = {}) {
1933
2442
  import { useQuery as useQuery9 } from "@tanstack/react-query";
1934
2443
  var FIVE_MINUTES = 5 * 60 * 1e3;
1935
2444
  function useAppConfig() {
1936
- var _a, _b, _c, _d, _e, _f;
2445
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1937
2446
  const client = useAggClient();
1938
2447
  const query = useQuery9({
1939
2448
  queryKey: ["agg", "app-config"],
@@ -1944,6 +2453,7 @@ function useAppConfig() {
1944
2453
  disabledVenues: (_b = (_a = query.data) == null ? void 0 : _a.disabledVenues) != null ? _b : [],
1945
2454
  disabledCategoryPresets: (_d = (_c = query.data) == null ? void 0 : _c.disabledCategoryPresets) != null ? _d : [],
1946
2455
  earlyAccessEnabled: (_f = (_e = query.data) == null ? void 0 : _e.earlyAccessEnabled) != null ? _f : false,
2456
+ authOptions: (_h = (_g = query.data) == null ? void 0 : _g.authOptions) != null ? _h : [],
1947
2457
  isLoading: query.isLoading,
1948
2458
  error: query.error
1949
2459
  };
@@ -1963,6 +2473,8 @@ export {
1963
2473
  MatchType,
1964
2474
  QueryClient4 as QueryClient,
1965
2475
  QueryClientProvider,
2476
+ RedeemRejectedError,
2477
+ TradeSide,
1966
2478
  TurnstileChallengeError,
1967
2479
  Venue,
1968
2480
  computeClosedPositionTotals,
@@ -1977,9 +2489,13 @@ export {
1977
2489
  getWalletAddressFromUserProfile,
1978
2490
  invalidateBalanceQueries,
1979
2491
  invalidatePositionQueries,
2492
+ invalidateUserActivityQueries,
2493
+ invalidateUserMoneyState,
2494
+ mergeBestPricesPreferringLive,
1980
2495
  optimizedImageUrl,
1981
2496
  parseEmail,
1982
2497
  parseEmailStrict,
2498
+ rangeToSeconds,
1983
2499
  requestAggAuthChooserOpen,
1984
2500
  resolveAggUiLabels,
1985
2501
  resolveDefaultMarket as resolveDefaultTradingMarket,
@@ -1987,6 +2503,7 @@ export {
1987
2503
  resolveMarketTradingState,
1988
2504
  resolveMarketWinningOutcome,
1989
2505
  resolveOrderEligibility,
2506
+ resolveRollingWindow,
1990
2507
  resolveTradingStateKind,
1991
2508
  sortVenues,
1992
2509
  timeRangeToInterval,
@@ -2017,6 +2534,7 @@ export {
2017
2534
  useGeoBlock,
2018
2535
  useLabels,
2019
2536
  useLinkAccount,
2537
+ useLiveBestPrices,
2020
2538
  useLiveCandleOverlay,
2021
2539
  useLiveCandles,
2022
2540
  useLiveMarket,
@@ -2026,11 +2544,14 @@ export {
2026
2544
  useManagedBalances,
2027
2545
  useMarketChart,
2028
2546
  useMarketOrderbook,
2547
+ useMarketSearch,
2029
2548
  useMidpoints,
2030
2549
  useOnBalanceUpdate,
2550
+ useOnOrderEvent,
2031
2551
  useOnOrderSubmitted,
2032
2552
  useOnRedeemEvent,
2033
2553
  useOnWithdrawalLifecycle,
2554
+ useOptionalAggClient,
2034
2555
  useOrderBook,
2035
2556
  useOrderbookQuote,
2036
2557
  useOrders,
@@ -2041,11 +2562,15 @@ export {
2041
2562
  useRampSession,
2042
2563
  useRedeem,
2043
2564
  useRedeemEligibleCount,
2565
+ useRedeemLifecycle,
2566
+ useRedeemLifecycles,
2567
+ useRollingChartWindow,
2044
2568
  useSdkLabels,
2045
2569
  useSdkUiConfig,
2046
2570
  useSearch,
2047
2571
  useSmartRoute,
2048
2572
  useSyncBalances,
2573
+ useTradableVenues,
2049
2574
  useUserActivity,
2050
2575
  useUserHoldings,
2051
2576
  useVenueEvent,
@@ -2054,7 +2579,9 @@ export {
2054
2579
  useVenueMarkets,
2055
2580
  useViewportMidpoints,
2056
2581
  useVisibleIds,
2582
+ useWithdrawEstimate,
2057
2583
  useWithdrawFlow,
2058
2584
  useWithdrawManaged,
2059
- useWithdrawalLifecycle
2585
+ useWithdrawalLifecycle,
2586
+ userActivityQueryKeys
2060
2587
  };