@agg-build/hooks 2.1.0 → 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  __async,
3
3
  useAggClient
4
- } from "./chunk-V7VCT62L.mjs";
4
+ } from "./chunk-7UDYSDKQ.mjs";
5
5
 
6
6
  // src/use-ramp-quotes.ts
7
7
  import { useMutation } from "@tanstack/react-query";
@@ -463,6 +463,13 @@ var enUsLabels = {
463
463
  categoryTabsAria: "Home page category tabs"
464
464
  },
465
465
  userProfile: {
466
+ balance: {
467
+ availableBalance: "Available Balance",
468
+ balanceByNetwork: "Balance by network",
469
+ paperModeNetwork: "Paper",
470
+ paperModeWarning: "Paper mode is enabled. These are simulated funds for paper trading.",
471
+ networkTooltipDescription: "Funds are stored across networks. We handle routing automatically, but keeping funds on the right network enables faster trades and lower fees. When depositing, you can choose your preferred network."
472
+ },
466
473
  activity: {
467
474
  depositType: "Deposit",
468
475
  redeemType: "Claim",
@@ -828,6 +835,7 @@ var enUsLabels = {
828
835
  orderSkip: "Skip",
829
836
  orderRetryRemaining: "Retry remaining",
830
837
  resolvedEarningsTitle: "Your Earnings",
838
+ resolvedResolutionDateLabel: "Resolution date",
831
839
  resolvedSharesLabel: "Shares",
832
840
  resolvedTotalPayoutLabel: "Total payout",
833
841
  claimWinnings: "Claim Winnings",
@@ -1147,7 +1155,10 @@ var defaultAggUiConfig = {
1147
1155
  }
1148
1156
  },
1149
1157
  formatting: defaultFormatters,
1150
- search: defaultAggUiSearchConfig
1158
+ search: defaultAggUiSearchConfig,
1159
+ trading: {
1160
+ executionMode: "live"
1161
+ }
1151
1162
  };
1152
1163
  var mergeAggUiSearchConfig = (config) => {
1153
1164
  var _a, _b, _c;
@@ -1162,7 +1173,7 @@ var mergeAggUiSearchConfig = (config) => {
1162
1173
  };
1163
1174
  };
1164
1175
  var mergeAggUiConfig = (persisted, config) => {
1165
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V;
1176
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X;
1166
1177
  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;
1167
1178
  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;
1168
1179
  const formatters = createFormatters(locale);
@@ -1203,6 +1214,9 @@ var mergeAggUiConfig = (persisted, config) => {
1203
1214
  formatDate: (_V = (_U = config == null ? void 0 : config.formatting) == null ? void 0 : _U.formatDate) != null ? _V : formatters.formatDate
1204
1215
  },
1205
1216
  search: mergeAggUiSearchConfig(config == null ? void 0 : config.search),
1217
+ trading: {
1218
+ executionMode: (_X = (_W = config == null ? void 0 : config.trading) == null ? void 0 : _W.executionMode) != null ? _X : defaultAggUiConfig.trading.executionMode
1219
+ },
1206
1220
  walletActions: config == null ? void 0 : config.walletActions,
1207
1221
  solanaRpcUrl: config == null ? void 0 : config.solanaRpcUrl
1208
1222
  };
@@ -1232,7 +1246,7 @@ var balanceQueryKeys = {
1232
1246
  execution: () => executionKeys.balances(),
1233
1247
  // Kept as an alias for backward compatibility with existing callers.
1234
1248
  // The balance provider now uses the same canonical execution balances key.
1235
- provider: () => executionKeys.balances(),
1249
+ provider: (mode) => executionKeys.balances(mode),
1236
1250
  venue: (venuesKey) => ["venue-balances", venuesKey],
1237
1251
  venuePrefix: () => ["venue-balances"]
1238
1252
  };
@@ -1318,6 +1332,7 @@ var AggBalanceContext = createContext(null);
1318
1332
  // src/core/providers/balance-provider.tsx
1319
1333
  import { jsx } from "react/jsx-runtime";
1320
1334
  var CHAIN_LABELS = {
1335
+ 0: "Paper",
1321
1336
  1: "Ethereum",
1322
1337
  10: "Optimism",
1323
1338
  56: "BNB",
@@ -1349,17 +1364,23 @@ var EMPTY_MANAGED_BALANCES = {
1349
1364
  function AggBalanceProvider({ children }) {
1350
1365
  const client = useContext(AggClientContext);
1351
1366
  const authContext = useContext(AggAuthContext);
1367
+ const {
1368
+ trading: { executionMode }
1369
+ } = useContext(AggUiContext);
1352
1370
  if (!authContext) {
1353
1371
  throw new Error("AggBalanceProvider must be used within an <AggAuthProvider>");
1354
1372
  }
1355
1373
  const { isAuthenticated } = authContext;
1374
+ const queryExecutionMode = executionMode === "paper" ? "paper" : void 0;
1356
1375
  const balancesQuery = useQuery({
1357
- queryKey: balanceQueryKeys.provider(),
1376
+ queryKey: balanceQueryKeys.provider(queryExecutionMode),
1358
1377
  queryFn: () => __async(null, null, function* () {
1359
1378
  if (!client || !isAuthenticated) {
1360
1379
  return EMPTY_MANAGED_BALANCES;
1361
1380
  }
1362
- return client.getManagedBalances();
1381
+ return client.getManagedBalances(
1382
+ queryExecutionMode ? { mode: queryExecutionMode } : void 0
1383
+ );
1363
1384
  }),
1364
1385
  enabled: Boolean(client && isAuthenticated),
1365
1386
  staleTime: 60 * 1e3,
@@ -1987,6 +2008,98 @@ var applyOrderbookDepth = (data, depth) => {
1987
2008
  });
1988
2009
  };
1989
2010
 
2011
+ // src/market-data/market-resolution-cache.ts
2012
+ var isRecord = (value) => {
2013
+ return typeof value === "object" && value !== null;
2014
+ };
2015
+ var NESTED_COLLECTION_FIELDS = ["pages", "data", "markets", "events", "venueMarkets"];
2016
+ var marketContainsOutcomeId = (market, outcomeId) => {
2017
+ if (!isRecord(market)) return false;
2018
+ const outcomes = market.venueMarketOutcomes;
2019
+ if (!Array.isArray(outcomes)) return false;
2020
+ return outcomes.some((outcome) => isRecord(outcome) && outcome.id === outcomeId);
2021
+ };
2022
+ var cachedDataContainsOutcomeId = (data, outcomeId) => {
2023
+ if (Array.isArray(data)) {
2024
+ return data.some((entry) => cachedDataContainsOutcomeId(entry, outcomeId));
2025
+ }
2026
+ if (!isRecord(data)) return false;
2027
+ if (marketContainsOutcomeId(data, outcomeId)) return true;
2028
+ return NESTED_COLLECTION_FIELDS.some((field) => {
2029
+ const value = data[field];
2030
+ return Array.isArray(value) && value.some((entry) => cachedDataContainsOutcomeId(entry, outcomeId));
2031
+ });
2032
+ };
2033
+ var normalizeLabel = (label) => {
2034
+ return typeof label === "string" ? label.trim().toLowerCase() : "";
2035
+ };
2036
+ var findResolvedOutcome = (resolvedOutcomes, outcome) => {
2037
+ var _a;
2038
+ const externalIdentifier = outcome.externalIdentifier;
2039
+ if (typeof externalIdentifier === "string" && externalIdentifier.length > 0) {
2040
+ const matchedByExternalId = resolvedOutcomes.find(
2041
+ (resolved) => resolved.externalIdentifier === externalIdentifier
2042
+ );
2043
+ if (matchedByExternalId) return matchedByExternalId;
2044
+ }
2045
+ const label = normalizeLabel(outcome.label);
2046
+ if (label) {
2047
+ return (_a = resolvedOutcomes.find((resolved) => normalizeLabel(resolved.label) === label)) != null ? _a : null;
2048
+ }
2049
+ return null;
2050
+ };
2051
+ var applyWinnersToOutcomes = (outcomes, resolution) => {
2052
+ let changed = false;
2053
+ const next = outcomes.map((outcome) => {
2054
+ if (!isRecord(outcome)) return outcome;
2055
+ const resolved = findResolvedOutcome(resolution.outcomes, outcome);
2056
+ if (!resolved) return outcome;
2057
+ const nextWinner = resolved.winner === true;
2058
+ if (outcome.winner === nextWinner) return outcome;
2059
+ changed = true;
2060
+ return __spreadProps(__spreadValues({}, outcome), { winner: nextWinner });
2061
+ });
2062
+ return changed ? next : outcomes;
2063
+ };
2064
+ var applyResolutionToMarket = (market, resolution) => {
2065
+ const outcomes = market.venueMarketOutcomes;
2066
+ if (!Array.isArray(outcomes)) return market;
2067
+ if (!outcomes.some((outcome) => isRecord(outcome) && outcome.id === resolution.outcomeId)) {
2068
+ return market;
2069
+ }
2070
+ const nextOutcomes = applyWinnersToOutcomes(outcomes, resolution);
2071
+ const statusChanged = market.status !== resolution.status;
2072
+ if (!statusChanged && nextOutcomes === outcomes) return market;
2073
+ return __spreadProps(__spreadValues({}, market), { status: resolution.status, venueMarketOutcomes: nextOutcomes });
2074
+ };
2075
+ var applyResolutionToCachedData = (data, resolution) => {
2076
+ if (Array.isArray(data)) {
2077
+ let changed2 = false;
2078
+ const next2 = data.map((entry) => {
2079
+ const updated = applyResolutionToCachedData(entry, resolution);
2080
+ if (updated !== entry) changed2 = true;
2081
+ return updated;
2082
+ });
2083
+ return changed2 ? next2 : data;
2084
+ }
2085
+ if (!isRecord(data)) return data;
2086
+ if (Array.isArray(data.venueMarketOutcomes)) {
2087
+ return applyResolutionToMarket(data, resolution);
2088
+ }
2089
+ let changed = false;
2090
+ const next = __spreadValues({}, data);
2091
+ for (const field of NESTED_COLLECTION_FIELDS) {
2092
+ const value = data[field];
2093
+ if (!Array.isArray(value)) continue;
2094
+ const updated = applyResolutionToCachedData(value, resolution);
2095
+ if (updated !== value) {
2096
+ next[field] = updated;
2097
+ changed = true;
2098
+ }
2099
+ }
2100
+ return changed ? next : data;
2101
+ };
2102
+
1990
2103
  // src/market-data/query-keys.ts
1991
2104
  var marketDataKeys = {
1992
2105
  all: () => ["market-data"],
@@ -2215,6 +2328,62 @@ function AggWebSocketProvider({ children }) {
2215
2328
  const invalidateActivityCaches = useCallback3(() => {
2216
2329
  invalidateUserActivityQueries(queryClient);
2217
2330
  }, [queryClient]);
2331
+ const invalidateResolutionCaches = useCallback3(
2332
+ (resolution) => {
2333
+ const { outcomeId } = resolution;
2334
+ syncLiveQuery(outcomeId, (previous) => {
2335
+ if (!previous) return previous;
2336
+ if (previous.orderbook == null && previous.orderbookError == null) return previous;
2337
+ return __spreadProps(__spreadValues({}, previous), {
2338
+ orderbook: null,
2339
+ orderbookError: null,
2340
+ integrity: "ok"
2341
+ });
2342
+ });
2343
+ const affectedQueries = queryClient.getQueryCache().findAll({
2344
+ predicate: (query) => cachedDataContainsOutcomeId(query.state.data, outcomeId)
2345
+ });
2346
+ for (const query of affectedQueries) {
2347
+ queryClient.setQueryData(
2348
+ query.queryKey,
2349
+ (previous) => applyResolutionToCachedData(previous, resolution)
2350
+ );
2351
+ }
2352
+ queryClient.invalidateQueries({
2353
+ queryKey: ["midpoints"],
2354
+ refetchType: "all"
2355
+ });
2356
+ queryClient.invalidateQueries({
2357
+ queryKey: ["venue-market-midpoints"],
2358
+ refetchType: "all"
2359
+ });
2360
+ queryClient.invalidateQueries({
2361
+ queryKey: ["venue-event"],
2362
+ refetchType: "all"
2363
+ });
2364
+ queryClient.invalidateQueries({
2365
+ queryKey: ["venue-markets"],
2366
+ refetchType: "all"
2367
+ });
2368
+ queryClient.invalidateQueries({
2369
+ queryKey: ["events"],
2370
+ refetchType: "all"
2371
+ });
2372
+ queryClient.invalidateQueries({
2373
+ queryKey: ["event-list"],
2374
+ refetchType: "all"
2375
+ });
2376
+ queryClient.invalidateQueries({
2377
+ queryKey: ["search"],
2378
+ refetchType: "all"
2379
+ });
2380
+ queryClient.invalidateQueries({
2381
+ predicate: (query) => cachedDataContainsOutcomeId(query.state.data, outcomeId),
2382
+ refetchType: "all"
2383
+ });
2384
+ },
2385
+ [queryClient, syncLiveQuery]
2386
+ );
2218
2387
  const callbacks = useMemo2(
2219
2388
  () => ({
2220
2389
  onSnapshot: (marketId, book) => {
@@ -2363,6 +2532,14 @@ function AggWebSocketProvider({ children }) {
2363
2532
  listener(msg);
2364
2533
  }
2365
2534
  },
2535
+ onMarketResolved: (msg) => {
2536
+ invalidateResolutionCaches(msg);
2537
+ if (isClientAuthenticated) {
2538
+ invalidateBalanceCaches();
2539
+ invalidatePositionCaches();
2540
+ invalidateActivityCaches();
2541
+ }
2542
+ },
2366
2543
  onError: (msg) => {
2367
2544
  const outcomeId = resolveSnapshotUnavailableOutcomeId(msg.message);
2368
2545
  if (!outcomeId) return;
@@ -2400,6 +2577,7 @@ function AggWebSocketProvider({ children }) {
2400
2577
  invalidateActivityCaches,
2401
2578
  invalidateBalanceCaches,
2402
2579
  invalidatePositionCaches,
2580
+ invalidateResolutionCaches,
2403
2581
  isClientAuthenticated,
2404
2582
  queryClient,
2405
2583
  syncChartQueries,
@@ -11,7 +11,7 @@ import {
11
11
  useOnWithdrawalLifecycle,
12
12
  useSyncBalances,
13
13
  useWithdrawManaged
14
- } from "./chunk-V7VCT62L.mjs";
14
+ } from "./chunk-7UDYSDKQ.mjs";
15
15
 
16
16
  // src/withdraw/use-withdraw-flow.ts
17
17
  import { useCallback, useEffect, useMemo, useState } from "react";
package/dist/deposit.js CHANGED
@@ -98,8 +98,9 @@ var import_wagmi = require("wagmi");
98
98
 
99
99
  // src/deposit/constants.ts
100
100
  var DEFAULT_SOLANA_RPC_ENDPOINTS = [
101
+ "https://solana-rpc.publicnode.com",
101
102
  "https://api.mainnet.solana.com",
102
- "https://solana-rpc.publicnode.com"
103
+ "https://rpc.ankr.com/solana"
103
104
  ];
104
105
  var DEFAULT_SOLANA_RPC_ENDPOINT = DEFAULT_SOLANA_RPC_ENDPOINTS[0];
105
106
  var SVM_CHAIN_IDS = /* @__PURE__ */ new Set([792703809]);
@@ -397,6 +398,13 @@ var enUsLabels = {
397
398
  categoryTabsAria: "Home page category tabs"
398
399
  },
399
400
  userProfile: {
401
+ balance: {
402
+ availableBalance: "Available Balance",
403
+ balanceByNetwork: "Balance by network",
404
+ paperModeNetwork: "Paper",
405
+ paperModeWarning: "Paper mode is enabled. These are simulated funds for paper trading.",
406
+ networkTooltipDescription: "Funds are stored across networks. We handle routing automatically, but keeping funds on the right network enables faster trades and lower fees. When depositing, you can choose your preferred network."
407
+ },
400
408
  activity: {
401
409
  depositType: "Deposit",
402
410
  redeemType: "Claim",
@@ -762,6 +770,7 @@ var enUsLabels = {
762
770
  orderSkip: "Skip",
763
771
  orderRetryRemaining: "Retry remaining",
764
772
  resolvedEarningsTitle: "Your Earnings",
773
+ resolvedResolutionDateLabel: "Resolution date",
765
774
  resolvedSharesLabel: "Shares",
766
775
  resolvedTotalPayoutLabel: "Total payout",
767
776
  claimWinnings: "Claim Winnings",
@@ -1061,7 +1070,10 @@ var defaultAggUiConfig = {
1061
1070
  }
1062
1071
  },
1063
1072
  formatting: defaultFormatters,
1064
- search: defaultAggUiSearchConfig
1073
+ search: defaultAggUiSearchConfig,
1074
+ trading: {
1075
+ executionMode: "live"
1076
+ }
1065
1077
  };
1066
1078
 
1067
1079
  // src/core/providers/contexts.ts
@@ -1095,7 +1107,7 @@ var balanceQueryKeys = {
1095
1107
  execution: () => executionKeys.balances(),
1096
1108
  // Kept as an alias for backward compatibility with existing callers.
1097
1109
  // The balance provider now uses the same canonical execution balances key.
1098
- provider: () => executionKeys.balances(),
1110
+ provider: (mode) => executionKeys.balances(mode),
1099
1111
  venue: (venuesKey) => ["venue-balances", venuesKey],
1100
1112
  venuePrefix: () => ["venue-balances"]
1101
1113
  };
package/dist/deposit.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  useRampQuotes,
3
3
  useRampSession
4
- } from "./chunk-QKVR32KC.mjs";
4
+ } from "./chunk-5VDUIUJB.mjs";
5
5
  import {
6
6
  __async,
7
7
  useAggAuthState,
@@ -10,7 +10,7 @@ import {
10
10
  useAggUiConfig,
11
11
  useDepositAddresses,
12
12
  useSyncBalances
13
- } from "./chunk-V7VCT62L.mjs";
13
+ } from "./chunk-7UDYSDKQ.mjs";
14
14
 
15
15
  // src/deposit/normalize-wallet-error.ts
16
16
  function normalizeWalletError(error, supportedChains) {
@@ -41,8 +41,9 @@ import { useAccount, useReadContract } from "wagmi";
41
41
 
42
42
  // src/deposit/constants.ts
43
43
  var DEFAULT_SOLANA_RPC_ENDPOINTS = [
44
+ "https://solana-rpc.publicnode.com",
44
45
  "https://api.mainnet.solana.com",
45
- "https://solana-rpc.publicnode.com"
46
+ "https://rpc.ankr.com/solana"
46
47
  ];
47
48
  var DEFAULT_SOLANA_RPC_ENDPOINT = DEFAULT_SOLANA_RPC_ENDPOINTS[0];
48
49
  var SVM_CHAIN_IDS = /* @__PURE__ */ new Set([792703809]);
package/dist/index.d.mts CHANGED
@@ -271,6 +271,12 @@ type VenueMarket = {
271
271
  sportsMarketType?: string | null | undefined;
272
272
  /** Sort rank within a sports section (0=moneyline, 1=spread, 2=total, 3+=other). */
273
273
  sectionRank?: number | null | undefined;
274
+ /** Period identifier for sports markets (e.g., "1H", "2H", "Q1", etc.). */
275
+ period?: string | null | undefined;
276
+ /** Normalized subject category for prop-tab grouping (e.g., game_lines, exact_score, etc.). */
277
+ marketCategory?: string | null | undefined;
278
+ /** Line value for spread/total markets (e.g., 2.5 for totals, 3 for spreads). */
279
+ lineValue?: number | null | undefined;
274
280
  matchedVenueMarkets?: {
275
281
  id: string;
276
282
  venue: Venue;
@@ -324,10 +330,18 @@ type VenueEvent = {
324
330
  startDate?: string | null | undefined;
325
331
  endDate?: string | null | undefined;
326
332
  creationDate?: string | null | undefined;
333
+ /**
334
+ * Scheduled kickoff/start of the underlying game (sports events only).
335
+ * Distinct from `endDate` (market close/expiration), which can sit well
336
+ * after the game. The FE prefers this over `endDate` for the game-date
337
+ * title suffix. Null for non-sports events.
338
+ */
339
+ gameStartTime?: string | null | undefined;
327
340
  slug?: string | null | undefined;
328
341
  subtitle?: string | null | undefined;
329
342
  venues?: Venue[];
330
343
  venueCount?: number | undefined;
344
+ groupMarketCount?: number | undefined;
331
345
  marketCount?: number | undefined;
332
346
  /**
333
347
  * ISO-8601 duration denormalized from Series.recurrence. `null` means
@@ -676,6 +690,13 @@ interface AggUiLabels {
676
690
  categoryTabsAria: string;
677
691
  };
678
692
  userProfile: {
693
+ balance: {
694
+ availableBalance: string;
695
+ balanceByNetwork: string;
696
+ paperModeNetwork: string;
697
+ paperModeWarning: string;
698
+ networkTooltipDescription: string;
699
+ };
679
700
  activity: {
680
701
  depositType: string;
681
702
  redeemType: string;
@@ -1080,6 +1101,7 @@ interface AggUiLabels {
1080
1101
  orderSkip: string;
1081
1102
  orderRetryRemaining: string;
1082
1103
  resolvedEarningsTitle: string;
1104
+ resolvedResolutionDateLabel: string;
1083
1105
  resolvedSharesLabel: string;
1084
1106
  resolvedTotalPayoutLabel: string;
1085
1107
  claimWinnings: string;
@@ -1290,6 +1312,7 @@ declare const resolveAggUiLabels: (locale: string) => AggUiLabels;
1290
1312
 
1291
1313
  type ThemeMode = "light" | "dark";
1292
1314
  type ChartTimeRange = "1H" | "6H" | "1D" | "1W" | "1M" | "ALL";
1315
+ type AggUiTradingExecutionMode = "live" | "paper";
1293
1316
  interface AggUiGeneralConfig {
1294
1317
  /** Locale for number and date formatting */
1295
1318
  locale: string;
@@ -1376,6 +1399,11 @@ interface AggUiSearchConfig {
1376
1399
  isShowingAllResults: boolean;
1377
1400
  }
1378
1401
  type AggUiSearchConfigInput = Partial<AggUiSearchConfig>;
1402
+ interface AggUiTradingConfig {
1403
+ /** Default execution mode used by trading surfaces unless a component prop overrides it. */
1404
+ executionMode: AggUiTradingExecutionMode;
1405
+ }
1406
+ type AggUiTradingConfigInput = Partial<AggUiTradingConfig>;
1379
1407
  interface AggUiConfig {
1380
1408
  /** Enable AGG development logs */
1381
1409
  enableLogs: boolean;
@@ -1399,6 +1427,8 @@ interface AggUiConfig {
1399
1427
  formatting: AggUiFormattingConfig;
1400
1428
  /** Search configuration */
1401
1429
  search: AggUiSearchConfig;
1430
+ /** Trading configuration */
1431
+ trading: AggUiTradingConfig;
1402
1432
  /**
1403
1433
  * Optional wallet action implementations.
1404
1434
  * When walletActions.sendToken is provided, DepositModal uses it for the
@@ -1432,6 +1462,8 @@ interface AggUiConfigInput {
1432
1462
  formatting?: AggUiFormattingConfigInput;
1433
1463
  /** Search config overrides */
1434
1464
  search?: AggUiSearchConfigInput;
1465
+ /** Trading config overrides */
1466
+ trading?: AggUiTradingConfigInput;
1435
1467
  /**
1436
1468
  * Optional wallet action implementations for deposit flows.
1437
1469
  * Provide this once at the provider level for plug-and-play deposit UX.
@@ -3333,10 +3365,42 @@ declare function useLiveOutcomePrices(venueMarkets: VenueMarket[] | null | undef
3333
3365
  */
3334
3366
  declare function findLivePriceById(livePrices: Map<string, number>, id: string): number | undefined;
3335
3367
 
3368
+ interface MarketLiveState {
3369
+ marketId: string;
3370
+ orderbook: OrderbookState | null;
3371
+ orderbookSnapshotVersion: number;
3372
+ orderbookError: string | null;
3373
+ trades: WsTrade[];
3374
+ isConnected: boolean;
3375
+ integrity: "ok" | "resyncing";
3376
+ }
3377
+
3336
3378
  type LiveBestPrices = ReadonlyMap<string, {
3337
3379
  bestBid?: number;
3338
3380
  bestAsk?: number;
3339
3381
  }>;
3382
+ /**
3383
+ * A WS-derived best-price candidate for one outcome, carrying the venue that
3384
+ * produced each side *and* a freshness stamp. This is the richer companion to
3385
+ * {@link LiveBestPrices}: it keeps the venue attribution that the bare
3386
+ * `{ bestBid, bestAsk }` map throws away, so display surfaces can switch the
3387
+ * venue logo to whichever venue currently owns the best live price — keeping
3388
+ * the logo paired with the price instead of pinned to the REST snapshot.
3389
+ */
3390
+ interface LiveBestPriceCandidate {
3391
+ bestBid?: number;
3392
+ bestAsk?: number;
3393
+ /** Venue that owns the cross-venue best bid (best place to sell). */
3394
+ bestBidVenue?: string;
3395
+ /** Venue that owns the cross-venue best ask (cheapest place to buy). */
3396
+ bestAskVenue?: string;
3397
+ midpoint?: number;
3398
+ /** Venue the midpoint is attributed to (cheapest-ask side, then best-bid). */
3399
+ midpointVenue?: string;
3400
+ /** Orderbook timestamp (seconds) of the freshest book backing this candidate. */
3401
+ updatedAt?: number;
3402
+ }
3403
+ type LiveBestPriceCandidates = ReadonlyMap<string, LiveBestPriceCandidate>;
3340
3404
  /**
3341
3405
  * WS-derived cross-venue + cross-outcome best bid/ask per outcome.
3342
3406
  *
@@ -3364,6 +3428,35 @@ declare function mergeBestPricesPreferringLive(rest: ReadonlyMap<string, {
3364
3428
  bestBid?: number;
3365
3429
  bestAsk?: number;
3366
3430
  }>;
3431
+ /**
3432
+ * Pull the per-outcome best bid/ask, attributed venues, midpoint and freshness
3433
+ * out of a single live orderbook state. Pure — exported for unit tests.
3434
+ */
3435
+ declare const extractOutcomeBestCandidate: (state: MarketLiveState | undefined) => LiveBestPriceCandidate;
3436
+ /**
3437
+ * Cross-venue + cross-outcome venue-attributed best-price candidates.
3438
+ *
3439
+ * Pure (no React) so the cross-venue fold can be unit-tested directly:
3440
+ * - Pass 1: per-outcome candidate from each outcome's own aggregated book.
3441
+ * - Pass 2: fold across MVMO groups. Lowest ask wins (cheapest to buy),
3442
+ * highest bid wins (best to sell), and the *winning venue* + freshest
3443
+ * timestamp travel with the chosen price to every member of the group.
3444
+ * This is what lets a different venue's live book switch both the price
3445
+ * and the venue logo on every WS update.
3446
+ *
3447
+ * Mirrors the price fold in {@link useLiveBestPrices} and the REST fold in
3448
+ * `useMidpoints.extractBestPrices`, but additionally tracks venue + freshness.
3449
+ */
3450
+ declare function buildLiveBestPriceCandidates(outcomeIds: string[], states: Array<MarketLiveState | undefined>, venueMarkets: VenueMarket[] | null | undefined): Map<string, LiveBestPriceCandidate>;
3451
+ /**
3452
+ * React hook companion to {@link useLiveBestPrices} that additionally carries
3453
+ * venue attribution + freshness per outcome. Recomputes on every WS update
3454
+ * (snapshot/delta) that moves price, venue ownership, or timestamp.
3455
+ *
3456
+ * Empty until WS books land for the subscribed outcomes. Designed to feed a
3457
+ * unified price+venue selector so the venue logo always follows the live price.
3458
+ */
3459
+ declare function useLiveBestPriceCandidates(venueMarkets: VenueMarket[] | null | undefined): LiveBestPriceCandidates;
3367
3460
 
3368
3461
  /**
3369
3462
  * Subscribe to real-time trade feed for a canonical market.
@@ -5487,4 +5580,4 @@ declare function useAppConfig(): UseAppConfigResult;
5487
5580
  */
5488
5581
  declare function useCachedAppConfig(): UseAppConfigResult;
5489
5582
 
5490
- export { AUTH_CHOOSER_OPEN_EVENT, type AggAuthContextValue, type AggAuthSignInOptions, type AggBalanceContextValue, AggBalanceProvider, AggProvider, type AggProviderProps, AggProvider as AggSdkProvider, type AggProviderProps as AggSdkProviderProps, type AggUiConfig, type AggUiConfigInput, type AggUiLabels, type AggUiLabelsInput, AggUiProvider, CHART_TIME_RANGES, CONFIRMED_MATCH_STATUSES, type ChartTimeRange, type ClosedPositionTotals, type ComputePriceGapsOptions, DEFAULT_AGG_ROOT_CLASS_NAME, type DagStepProgress, type EventListStateContextValue, EventListStateProvider, type EventListStateSnapshot, type EventTradingContextValue, type EventTradingState, type ExecutionProgressPhase, type ExecutionTerminalOrderEvent, type GeoBlockState, type GetOrdersQuery, type GetPositionsQuery, type InvalidateUserActivityOptions, type InvalidateUserMoneyStateOptions, type LiveBestPrices, type LiveCandle, MAX_PRICE_GAP_PCT, MIN_PRICE_GAP_PCT, type MarketChartCandle, type MarketChartData, type MarketChartVenueData, type MarketOrderbookData, type MarketOrderbookIntegrity, MarketStatus, type MarketTradingState, MatchStatus, MatchType, type OrderEligibility, type OrderEligibilityReason, type OrderListItem, type OrderbookResult, type PositionGroup, type PriceGapValue, type RedeemEvent, type RedeemLegLifecycle, type RedeemLifecycleState, RedeemRejectedError, type RollingChartWindow, type ScaledCandlePoint, type SdkUiConfig, type SdkUiConfigInput, type SdkUiProviderProps, type SmartRouteLoadingReason, type ThemeMode, TradeSide, type TradingAction, type TradingState, type TradingStateBase, type TradingStateKind, type UseAggAuthOptions, type UseAggAuthReturn, type UseAppConfigResult, type UseArbFeedResult, type UseCategoriesOptions, type UseCategoryChildrenOptions, type UseEnrichedVenueEventOptions, type UseExecuteManagedOptions, type UseExecutionOrdersOptions, type UseExecutionPositionsOptions, type UseExecutionProgressOptions, type UseExecutionProgressResult, type UseExternalIdOptions, type UseExternalIdReturn, type UseLinkAccountReturn, type UseLiveCandleOverlayOptions, type UseLiveCandleOverlayResult, type UseLiveCandlesOptions, type UseLiveCandlesResult, type UseLiveMarketResult, type UseMarketArbResult, type UseMarketChartOptions, type UseMarketChartResult, type UseMarketOrderbookOptions, type UseMarketOrderbookResult, type UseMarketOrderbookVenueOutcome, type UseMarketSearchOptions, type UseMidpointsOptions, type UseMidpointsResult, type UseOrderBookOptions, type UseOrderbookQuoteOptions, type UseOrderbookQuoteResult, type UseOrdersOptions, type UsePositionsOptions, type UseQuoteManagedOptions, type UseRedeemLifecycleInput, type UseRollingChartWindowOptions, type UseSearchOptions, type UseSmartRouteOptions, type UseSmartRouteResult, type UseTradableVenuesResult, type UseUserActivityOptions, type UseUserHoldingsOptions, type UseVenueEventOptions, type UseVenueEventsOptions, type UseVenueMarketMidpointsOptions, type UseVenueMarketsOptions, type UseViewportMidpointsOptions, type UseVisibleIdsOptions, type UseVisibleIdsResult, type UserActivityInvalidationStrategy, Venue, type VenueAvailabilityState, type VenueEvent, type VenueEventWithMarkets, type VenueMarket, type VenueMarketOutcome, type WalletActionSendTokenParams, type WalletActions, computeClosedPositionTotals, computePriceGaps, defaultAggUiConfig, defaultAggUiConfig as defaultSdkUiConfig, executionKeys, findLivePriceById, getBuilder, getOrCreateBuilder, getVenueAvailabilityState, getVisibleVenueIdsByConfig, getVisibleVenuesByConfig, getWalletAddressFromUserProfile, invalidateBalanceQueries, invalidatePositionQueries, invalidateUserActivityQueries, invalidateUserClaimState, invalidateUserMoneyState, isVenueDisabledByConfig, mergeBestPricesPreferringLive, normalizeVenueId, optimizedImageUrl, parseEmail, parseEmailStrict, rangeToSeconds, requestAggAuthChooserOpen, resolveAggUiLabels, resolveDefaultMarket as resolveDefaultTradingMarket, resolveEventTradingState, resolveMarketTradingState, resolveMarketWinningOutcome, resolveOrderEligibility, resolveRollingWindow, resolveTradingStateKind, sortVenues, timeRangeToInterval, tradingReducer, useAggAuth, useAggAuthContext, useAggAuthState, useAggBalance, useAggBalanceContext, useAggBalanceState, useAggClient, useAggLabels, useAggUiConfig, useAggWebSocket, useAppConfig, useArbFeed, useCachedAppConfig, useCategories, useCategoryChildren, useDebouncedValue, useEnrichedVenueEvent, useEventListState, useEventOrderbookData, useEventTradingContext, useExecuteManaged, useExecutionOrders, useExecutionPositions, useExecutionProgress, useExternalId, useGeoBlock, useLabels, useLinkAccount, useLiveBestPrices, useLiveCandleOverlay, useLiveCandles, useLiveMarket, useLiveMarketStores, useLiveOutcomePrices, useLiveTrades, useMarketArb, useMarketChart, useMarketOrderbook, useMarketSearch, useMidpoints, useOnBalanceUpdate, useOnOrderEvent, useOnOrderSubmitted, useOnRedeemEvent, useOnWithdrawalLifecycle, useOptionalAggClient, useOrderBook, useOrderbookQuote, useOrders, usePositions, useQuoteManaged, useRampQuotes, useRampSession, useRedeem, useRedeemEligibleCount, useRedeemLifecycle, useRedeemLifecycles, useRollingChartWindow, useSdkLabels, useSdkUiConfig, useSearch, useSmartRoute, useTradableVenues, useUserActivity, useUserHoldings, useVenueEvent, useVenueEvents, useVenueMarketMidpoints, useVenueMarkets, useViewportMidpoints, useVisibleIds, userActivityQueryKeys };
5583
+ export { AUTH_CHOOSER_OPEN_EVENT, type AggAuthContextValue, type AggAuthSignInOptions, type AggBalanceContextValue, AggBalanceProvider, AggProvider, type AggProviderProps, AggProvider as AggSdkProvider, type AggProviderProps as AggSdkProviderProps, type AggUiConfig, type AggUiConfigInput, type AggUiLabels, type AggUiLabelsInput, AggUiProvider, type AggUiTradingExecutionMode, CHART_TIME_RANGES, CONFIRMED_MATCH_STATUSES, type ChartTimeRange, type ClosedPositionTotals, type ComputePriceGapsOptions, DEFAULT_AGG_ROOT_CLASS_NAME, type DagStepProgress, type EventListStateContextValue, EventListStateProvider, type EventListStateSnapshot, type EventTradingContextValue, type EventTradingState, type ExecutionProgressPhase, type ExecutionTerminalOrderEvent, type GeoBlockState, type GetOrdersQuery, type GetPositionsQuery, type InvalidateUserActivityOptions, type InvalidateUserMoneyStateOptions, type LiveBestPriceCandidate, type LiveBestPriceCandidates, type LiveBestPrices, type LiveCandle, MAX_PRICE_GAP_PCT, MIN_PRICE_GAP_PCT, type MarketChartCandle, type MarketChartData, type MarketChartVenueData, type MarketOrderbookData, type MarketOrderbookIntegrity, MarketStatus, type MarketTradingState, MatchStatus, MatchType, type OrderEligibility, type OrderEligibilityReason, type OrderListItem, type OrderbookResult, type PositionGroup, type PriceGapValue, type RedeemEvent, type RedeemLegLifecycle, type RedeemLifecycleState, RedeemRejectedError, type RollingChartWindow, type ScaledCandlePoint, type SdkUiConfig, type SdkUiConfigInput, type SdkUiProviderProps, type SmartRouteLoadingReason, type ThemeMode, TradeSide, type TradingAction, type TradingState, type TradingStateBase, type TradingStateKind, type UseAggAuthOptions, type UseAggAuthReturn, type UseAppConfigResult, type UseArbFeedResult, type UseCategoriesOptions, type UseCategoryChildrenOptions, type UseEnrichedVenueEventOptions, type UseExecuteManagedOptions, type UseExecutionOrdersOptions, type UseExecutionPositionsOptions, type UseExecutionProgressOptions, type UseExecutionProgressResult, type UseExternalIdOptions, type UseExternalIdReturn, type UseLinkAccountReturn, type UseLiveCandleOverlayOptions, type UseLiveCandleOverlayResult, type UseLiveCandlesOptions, type UseLiveCandlesResult, type UseLiveMarketResult, type UseMarketArbResult, type UseMarketChartOptions, type UseMarketChartResult, type UseMarketOrderbookOptions, type UseMarketOrderbookResult, type UseMarketOrderbookVenueOutcome, type UseMarketSearchOptions, type UseMidpointsOptions, type UseMidpointsResult, type UseOrderBookOptions, type UseOrderbookQuoteOptions, type UseOrderbookQuoteResult, type UseOrdersOptions, type UsePositionsOptions, type UseQuoteManagedOptions, type UseRedeemLifecycleInput, type UseRollingChartWindowOptions, type UseSearchOptions, type UseSmartRouteOptions, type UseSmartRouteResult, type UseTradableVenuesResult, type UseUserActivityOptions, type UseUserHoldingsOptions, type UseVenueEventOptions, type UseVenueEventsOptions, type UseVenueMarketMidpointsOptions, type UseVenueMarketsOptions, type UseViewportMidpointsOptions, type UseVisibleIdsOptions, type UseVisibleIdsResult, type UserActivityInvalidationStrategy, Venue, type VenueAvailabilityState, type VenueEvent, type VenueEventWithMarkets, type VenueMarket, type VenueMarketOutcome, type WalletActionSendTokenParams, type WalletActions, buildLiveBestPriceCandidates, computeClosedPositionTotals, computePriceGaps, defaultAggUiConfig, defaultAggUiConfig as defaultSdkUiConfig, executionKeys, extractOutcomeBestCandidate, findLivePriceById, getBuilder, getOrCreateBuilder, getVenueAvailabilityState, getVisibleVenueIdsByConfig, getVisibleVenuesByConfig, getWalletAddressFromUserProfile, invalidateBalanceQueries, invalidatePositionQueries, invalidateUserActivityQueries, invalidateUserClaimState, invalidateUserMoneyState, isVenueDisabledByConfig, mergeBestPricesPreferringLive, normalizeVenueId, optimizedImageUrl, parseEmail, parseEmailStrict, rangeToSeconds, requestAggAuthChooserOpen, resolveAggUiLabels, resolveDefaultMarket as resolveDefaultTradingMarket, resolveEventTradingState, resolveMarketTradingState, resolveMarketWinningOutcome, resolveOrderEligibility, resolveRollingWindow, resolveTradingStateKind, sortVenues, timeRangeToInterval, tradingReducer, useAggAuth, useAggAuthContext, useAggAuthState, useAggBalance, useAggBalanceContext, useAggBalanceState, useAggClient, useAggLabels, useAggUiConfig, useAggWebSocket, useAppConfig, useArbFeed, useCachedAppConfig, useCategories, useCategoryChildren, useDebouncedValue, useEnrichedVenueEvent, useEventListState, useEventOrderbookData, useEventTradingContext, useExecuteManaged, useExecutionOrders, useExecutionPositions, useExecutionProgress, useExternalId, useGeoBlock, useLabels, useLinkAccount, useLiveBestPriceCandidates, useLiveBestPrices, useLiveCandleOverlay, useLiveCandles, useLiveMarket, useLiveMarketStores, useLiveOutcomePrices, useLiveTrades, useMarketArb, useMarketChart, useMarketOrderbook, useMarketSearch, useMidpoints, useOnBalanceUpdate, useOnOrderEvent, useOnOrderSubmitted, useOnRedeemEvent, useOnWithdrawalLifecycle, useOptionalAggClient, useOrderBook, useOrderbookQuote, useOrders, usePositions, useQuoteManaged, useRampQuotes, useRampSession, useRedeem, useRedeemEligibleCount, useRedeemLifecycle, useRedeemLifecycles, useRollingChartWindow, useSdkLabels, useSdkUiConfig, useSearch, useSmartRoute, useTradableVenues, useUserActivity, useUserHoldings, useVenueEvent, useVenueEvents, useVenueMarketMidpoints, useVenueMarkets, useViewportMidpoints, useVisibleIds, userActivityQueryKeys };