@agg-build/ui 1.2.9 → 1.2.11

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.
Files changed (100) hide show
  1. package/dist/{chunk-PFOSEY46.mjs → chunk-3ZSNHGAB.mjs} +835 -401
  2. package/dist/{chunk-5PSAIGOT.mjs → chunk-54PCEK6G.mjs} +137 -61
  3. package/dist/{chunk-7JKGAWU5.mjs → chunk-ENAGASVU.mjs} +1538 -1369
  4. package/dist/{chunk-K23CJ5UP.mjs → chunk-J7K2U44E.mjs} +481 -258
  5. package/dist/{chunk-5MDFM2MX.mjs → chunk-NWJHFGBZ.mjs} +1 -1
  6. package/dist/{chunk-QFW5NDJ6.mjs → chunk-SJLHOAKK.mjs} +1001 -1015
  7. package/dist/{chunk-PYKD4W4T.mjs → chunk-YP75TIY6.mjs} +601 -326
  8. package/dist/events.js +2038 -1559
  9. package/dist/events.mjs +3 -3
  10. package/dist/index.js +5417 -4261
  11. package/dist/index.mjs +56 -50
  12. package/dist/modals.js +3262 -2384
  13. package/dist/modals.mjs +3 -3
  14. package/dist/pages.js +3677 -2709
  15. package/dist/pages.mjs +6 -6
  16. package/dist/primitives.js +992 -918
  17. package/dist/primitives.mjs +5 -1
  18. package/dist/styles.css +1 -1
  19. package/dist/tailwind.css +1 -1
  20. package/dist/trading.js +1360 -1129
  21. package/dist/trading.mjs +4 -4
  22. package/dist/types/deposit/deposit-modal.types.d.mts +10 -1
  23. package/dist/types/deposit/deposit-modal.types.d.ts +10 -1
  24. package/dist/types/deposit/index.d.mts +1 -1
  25. package/dist/types/deposit/index.d.ts +1 -1
  26. package/dist/types/deposit/steps/crypto-transfer.d.mts +1 -2
  27. package/dist/types/deposit/steps/crypto-transfer.d.ts +1 -2
  28. package/dist/types/deposit/steps/deposit-method.d.mts +2 -1
  29. package/dist/types/deposit/steps/deposit-method.d.ts +2 -1
  30. package/dist/types/events/item/event-list-item.types.d.mts +3 -1
  31. package/dist/types/events/item/event-list-item.types.d.ts +3 -1
  32. package/dist/types/events/item/event-list-item.utils.d.mts +26 -2
  33. package/dist/types/events/item/event-list-item.utils.d.ts +26 -2
  34. package/dist/types/events/item-details/event-list-item-details.types.d.mts +30 -1
  35. package/dist/types/events/item-details/event-list-item-details.types.d.ts +30 -1
  36. package/dist/types/events/market-details/index.d.mts +1 -1
  37. package/dist/types/events/market-details/index.d.ts +1 -1
  38. package/dist/types/events/market-details/market-details.types.d.mts +27 -2
  39. package/dist/types/events/market-details/market-details.types.d.ts +27 -2
  40. package/dist/types/events/market-details/market-details.utils.d.mts +18 -4
  41. package/dist/types/events/market-details/market-details.utils.d.ts +18 -4
  42. package/dist/types/events/market-details/orderbook-aggregation.d.mts +38 -2
  43. package/dist/types/events/market-details/orderbook-aggregation.d.ts +38 -2
  44. package/dist/types/events/shared/chart-auto-fallback.d.mts +43 -0
  45. package/dist/types/events/shared/chart-auto-fallback.d.ts +43 -0
  46. package/dist/types/events/shared/display-outcome-price.d.mts +14 -0
  47. package/dist/types/events/shared/display-outcome-price.d.ts +14 -0
  48. package/dist/types/events/shared/display-outcome-venue.d.mts +30 -0
  49. package/dist/types/events/shared/display-outcome-venue.d.ts +30 -0
  50. package/dist/types/events/shared/display-reference-price.d.mts +4 -0
  51. package/dist/types/events/shared/display-reference-price.d.ts +4 -0
  52. package/dist/types/events/shared/select-outcome-price.d.mts +21 -0
  53. package/dist/types/events/shared/select-outcome-price.d.ts +21 -0
  54. package/dist/types/pages/user-profile/components/available-balance-card.d.mts +2 -1
  55. package/dist/types/pages/user-profile/components/available-balance-card.d.ts +2 -1
  56. package/dist/types/pages/user-profile/components/positions-value-card.d.mts +2 -1
  57. package/dist/types/pages/user-profile/components/positions-value-card.d.ts +2 -1
  58. package/dist/types/pages/user-profile/index.d.mts +2 -2
  59. package/dist/types/pages/user-profile/index.d.ts +2 -2
  60. package/dist/types/pages/user-profile/user-profile.types.d.mts +54 -1
  61. package/dist/types/pages/user-profile/user-profile.types.d.ts +54 -1
  62. package/dist/types/primitives/chart/chart.utils.d.mts +9 -10
  63. package/dist/types/primitives/chart/chart.utils.d.ts +9 -10
  64. package/dist/types/primitives/icon/index.d.mts +2 -1
  65. package/dist/types/primitives/icon/index.d.ts +2 -1
  66. package/dist/types/primitives/icon/registry.d.mts +8 -0
  67. package/dist/types/primitives/icon/registry.d.ts +8 -0
  68. package/dist/types/primitives/icon/svg/circle-xmark.d.mts +5 -0
  69. package/dist/types/primitives/icon/svg/circle-xmark.d.ts +5 -0
  70. package/dist/types/primitives/icon/svg/spinner.d.mts +5 -0
  71. package/dist/types/primitives/icon/svg/spinner.d.ts +5 -0
  72. package/dist/types/primitives/toast/index.d.mts +2 -0
  73. package/dist/types/primitives/toast/index.d.ts +2 -0
  74. package/dist/types/primitives/tooltip/tooltip.types.d.mts +1 -0
  75. package/dist/types/primitives/tooltip/tooltip.types.d.ts +1 -0
  76. package/dist/types/primitives/typography/index.d.mts +1 -1
  77. package/dist/types/primitives/typography/index.d.ts +1 -1
  78. package/dist/types/primitives/typography/typography.types.d.mts +2 -0
  79. package/dist/types/primitives/typography/typography.types.d.ts +2 -0
  80. package/dist/types/shared/transfer-fee-summary.d.mts +10 -0
  81. package/dist/types/shared/transfer-fee-summary.d.ts +10 -0
  82. package/dist/types/shared/utils.d.mts +3 -0
  83. package/dist/types/shared/utils.d.ts +3 -0
  84. package/dist/types/trading/place-order/index.d.mts +1 -1
  85. package/dist/types/trading/place-order/index.d.ts +1 -1
  86. package/dist/types/trading/place-order/index.place-order.execution-steps.d.mts +9 -0
  87. package/dist/types/trading/place-order/index.place-order.execution-steps.d.ts +9 -0
  88. package/dist/types/trading/place-order/index.place-order.types.d.mts +15 -2
  89. package/dist/types/trading/place-order/index.place-order.types.d.ts +15 -2
  90. package/dist/types/trading/place-order/index.place-order.utils.d.mts +49 -6
  91. package/dist/types/trading/place-order/index.place-order.utils.d.ts +49 -6
  92. package/dist/types/withdraw/index.d.mts +1 -1
  93. package/dist/types/withdraw/index.d.ts +1 -1
  94. package/dist/types/withdraw/steps/withdraw-success.d.mts +13 -7
  95. package/dist/types/withdraw/steps/withdraw-success.d.ts +13 -7
  96. package/dist/types/withdraw/steps/withdraw-success.utils.d.mts +2 -0
  97. package/dist/types/withdraw/steps/withdraw-success.utils.d.ts +2 -0
  98. package/dist/types/withdraw/withdraw-modal.types.d.mts +5 -0
  99. package/dist/types/withdraw/withdraw-modal.types.d.ts +5 -0
  100. package/package.json +3 -3
@@ -34,10 +34,11 @@ export type ResolvedMarket = {
34
34
  export declare const resolveMarketFromVenueMarkets: (venueMarkets: VenueMarket[], marketId: string | undefined) => ResolvedMarket | undefined;
35
35
  export declare const resolveDisplayOutcomeLabels: (labels: string[]) => string[];
36
36
  export declare const resolveInitialOutcomeLabel: (labels: string[], defaultOutcomeLabel: string | undefined) => string | undefined;
37
- export declare const resolveScopedSelectedOutcome: ({ venueMarkets, selectedOutcomeId, defaultOutcomeLabel, }: {
37
+ export declare const resolveScopedSelectedOutcome: ({ venueMarkets, selectedOutcomeId, defaultOutcomeLabel, suppressFallbackWhenSelectedOutcomeOutOfScope, }: {
38
38
  venueMarkets: VenueMarket[];
39
39
  selectedOutcomeId: string | null | undefined;
40
40
  defaultOutcomeLabel: string | undefined;
41
+ suppressFallbackWhenSelectedOutcomeOutOfScope?: boolean;
41
42
  }) => {
42
43
  outcomeId: string | null;
43
44
  outcomeLabel: string | undefined;
@@ -45,21 +46,34 @@ export declare const resolveScopedSelectedOutcome: ({ venueMarkets, selectedOutc
45
46
  export declare const resolveAverageProbabilityByLabel: (venueMarkets: VenueMarket[], labels: string[]) => Map<string, number | undefined>;
46
47
  export declare const formatProbabilityPercent: (value: number | null | undefined, formatPercent?: (value: number) => string) => string;
47
48
  export declare const resolveOutcomeTone: (label: string, index: number) => MarketDetailsOrderBookTone;
48
- export declare const resolveHeaderOutcomeItems: (venueMarkets: VenueMarket[]) => MarketDetailsHeaderOutcomeItem[];
49
- export declare const resolveSubtitle: ({ venueMarkets, volume, formatCompactCurrency, labels, }: {
49
+ export declare const resolveHeaderOutcomeItems: (venueMarkets: VenueMarket[], scopedMarket?: VenueMarket | null) => MarketDetailsHeaderOutcomeItem[];
50
+ export declare const resolveSubtitle: ({ venueMarkets, volume, formatCompactCurrency, labels, tradableVenues, }: {
50
51
  venueMarkets: VenueMarket[];
51
52
  volume: number | undefined;
52
53
  formatCompactCurrency: (value: number) => string;
53
54
  labels: AggUiLabels;
55
+ /**
56
+ * Optional runtime-derived set of venues that have a live orderbook.
57
+ * Forwarded to `getVenueSummary` to filter `venueCount` to only
58
+ * tradeable venues. When omitted the count includes all venues
59
+ * regardless of orderbook availability.
60
+ */
61
+ tradableVenues?: ReadonlySet<string> | null;
54
62
  }) => string;
55
63
  export declare const resolveOtherTabRows: (market: ResolvedMarket, labels: AggUiLabels) => MarketDetailsMetaRow[];
56
- export declare const buildMarketDetailsModel: ({ venueMarkets, marketId, title, image, formatCompactCurrency, labels, }: {
64
+ export declare const buildMarketDetailsModel: ({ venueMarkets, marketId, title, image, formatCompactCurrency, labels, tradableVenues, }: {
57
65
  venueMarkets: VenueMarket[];
58
66
  marketId: string | undefined;
59
67
  title: string | undefined;
60
68
  image: string | null | undefined;
61
69
  formatCompactCurrency: (value: number) => string;
62
70
  labels: AggUiLabels;
71
+ /**
72
+ * Forwarded to `resolveSubtitle` → `getVenueSummary` so the "X venues"
73
+ * subtitle reflects only venues with a live orderbook. Optional;
74
+ * subtitle counts all cluster venues when omitted.
75
+ */
76
+ tradableVenues?: ReadonlySet<string> | null;
63
77
  }) => {
64
78
  market: ResolvedMarket;
65
79
  primaryVenueMarket: VenueMarket;
@@ -16,13 +16,49 @@ export type AggregatedOrderbookRows = {
16
16
  includedOutcomeIds: string[];
17
17
  missingOutcomeIds: string[];
18
18
  };
19
- export declare const collectEligibleVenueOutcomes: ({ venueMarkets, selectedOutcomeLabel, }: {
19
+ /**
20
+ * Pick the eligible outcome on each venue-market that corresponds to the
21
+ * user's selected side.
22
+ *
23
+ * Selected-outcome-first (when `selectedOutcomeId` is provided): find
24
+ * that exact outcome in the cluster, emit it, walk its `matchedVenueMarketOutcomes`
25
+ * refs to align siblings by id. **Return immediately** — no fallback to
26
+ * other markets via label. This matches the server-side smart-route CTE
27
+ * which keys off the specific outcome id and does not fall through to
28
+ * label-based discovery. Critical for inversely-framed per-team kalshi
29
+ * binaries where the user's "No" outcome has no MVMO refs (matcher only
30
+ * emits Yes-side rows), but a different market's "No" outcome (e.g.
31
+ * polymarket-No with title "Khamzat Chimaev") DOES have refs pointing
32
+ * to the OPPOSITE semantic side. Falling through to that parent in the
33
+ * label loop emits cross-side outcomes — observed in the orderbook
34
+ * showing 80¢ Chimaev-wins prices when the user clicked the 19¢
35
+ * Strickland-wins side. The selected-outcome short-circuit prevents it.
36
+ *
37
+ * MVMO-first label loop (when `selectedOutcomeId` is null): scan the
38
+ * cluster for any market whose selected-outcome carries MVMO refs and
39
+ * use it as the parent. Walk the refs to align siblings.
40
+ *
41
+ * Label-fallback: for any sibling not covered by an MVMO ref (unmatched
42
+ * markets, or older API responses that pre-date the refs), fall back to
43
+ * label matching with anchor-set guard so we don't regress on the
44
+ * historically-correct cases.
45
+ */
46
+ export declare const collectEligibleVenueOutcomes: ({ venueMarkets, selectedOutcomeLabel, selectedOutcomeId, }: {
20
47
  venueMarkets: VenueMarket[];
21
48
  selectedOutcomeLabel: string | null | undefined;
49
+ /**
50
+ * The exact outcome id the user clicked. When provided AND found in the
51
+ * cluster, the function emits that outcome + only its MVMO siblings, then
52
+ * returns — bypassing the label-based parent-discovery loop. Required to
53
+ * keep inversely-framed-binary surfaces (chart/orderbook) on the same
54
+ * semantic side as the user's selection.
55
+ */
56
+ selectedOutcomeId?: string | null;
22
57
  }) => EligibleVenueOutcome[];
23
- export declare const collectEligibleVenueOutcomeIds: ({ venueMarkets, selectedOutcomeLabel, }: {
58
+ export declare const collectEligibleVenueOutcomeIds: ({ venueMarkets, selectedOutcomeLabel, selectedOutcomeId, }: {
24
59
  venueMarkets: VenueMarket[];
25
60
  selectedOutcomeLabel: string | null | undefined;
61
+ selectedOutcomeId?: string | null;
26
62
  }) => string[];
27
63
  export declare const mergeVenueOutcomeOrderbooks: ({ eligibleOutcomes, orderbooksByOutcomeId, }: {
28
64
  eligibleOutcomes: EligibleVenueOutcome[];
@@ -16,13 +16,49 @@ export type AggregatedOrderbookRows = {
16
16
  includedOutcomeIds: string[];
17
17
  missingOutcomeIds: string[];
18
18
  };
19
- export declare const collectEligibleVenueOutcomes: ({ venueMarkets, selectedOutcomeLabel, }: {
19
+ /**
20
+ * Pick the eligible outcome on each venue-market that corresponds to the
21
+ * user's selected side.
22
+ *
23
+ * Selected-outcome-first (when `selectedOutcomeId` is provided): find
24
+ * that exact outcome in the cluster, emit it, walk its `matchedVenueMarketOutcomes`
25
+ * refs to align siblings by id. **Return immediately** — no fallback to
26
+ * other markets via label. This matches the server-side smart-route CTE
27
+ * which keys off the specific outcome id and does not fall through to
28
+ * label-based discovery. Critical for inversely-framed per-team kalshi
29
+ * binaries where the user's "No" outcome has no MVMO refs (matcher only
30
+ * emits Yes-side rows), but a different market's "No" outcome (e.g.
31
+ * polymarket-No with title "Khamzat Chimaev") DOES have refs pointing
32
+ * to the OPPOSITE semantic side. Falling through to that parent in the
33
+ * label loop emits cross-side outcomes — observed in the orderbook
34
+ * showing 80¢ Chimaev-wins prices when the user clicked the 19¢
35
+ * Strickland-wins side. The selected-outcome short-circuit prevents it.
36
+ *
37
+ * MVMO-first label loop (when `selectedOutcomeId` is null): scan the
38
+ * cluster for any market whose selected-outcome carries MVMO refs and
39
+ * use it as the parent. Walk the refs to align siblings.
40
+ *
41
+ * Label-fallback: for any sibling not covered by an MVMO ref (unmatched
42
+ * markets, or older API responses that pre-date the refs), fall back to
43
+ * label matching with anchor-set guard so we don't regress on the
44
+ * historically-correct cases.
45
+ */
46
+ export declare const collectEligibleVenueOutcomes: ({ venueMarkets, selectedOutcomeLabel, selectedOutcomeId, }: {
20
47
  venueMarkets: VenueMarket[];
21
48
  selectedOutcomeLabel: string | null | undefined;
49
+ /**
50
+ * The exact outcome id the user clicked. When provided AND found in the
51
+ * cluster, the function emits that outcome + only its MVMO siblings, then
52
+ * returns — bypassing the label-based parent-discovery loop. Required to
53
+ * keep inversely-framed-binary surfaces (chart/orderbook) on the same
54
+ * semantic side as the user's selection.
55
+ */
56
+ selectedOutcomeId?: string | null;
22
57
  }) => EligibleVenueOutcome[];
23
- export declare const collectEligibleVenueOutcomeIds: ({ venueMarkets, selectedOutcomeLabel, }: {
58
+ export declare const collectEligibleVenueOutcomeIds: ({ venueMarkets, selectedOutcomeLabel, selectedOutcomeId, }: {
24
59
  venueMarkets: VenueMarket[];
25
60
  selectedOutcomeLabel: string | null | undefined;
61
+ selectedOutcomeId?: string | null;
26
62
  }) => string[];
27
63
  export declare const mergeVenueOutcomeOrderbooks: ({ eligibleOutcomes, orderbooksByOutcomeId, }: {
28
64
  eligibleOutcomes: EligibleVenueOutcome[];
@@ -0,0 +1,43 @@
1
+ import type { ChartTimeRange, MarketChartData } from "@agg-build/hooks";
2
+ /**
3
+ * True when the chart payload has no usable bars *inside the visible domain*
4
+ * — i.e. the selected range yielded nothing to plot. A `null`/`undefined`
5
+ * payload (query not yet resolved) is also treated as "no data here" because
6
+ * the fallback decision uses this together with an `isLoading` guard.
7
+ *
8
+ * `liveCandle` counts as data: a market that just started trading inside the
9
+ * current bucket has a single forming candle and no closed bars; the chart
10
+ * should still render that.
11
+ *
12
+ * **Domain filtering**: pass `minTimeSec` (the rolling window's `startTs`) to
13
+ * ignore stale "courtesy" bars the API returns outside the requested window.
14
+ * Without this, a market that last traded 11h ago would surface a single
15
+ * out-of-window bar in `candles`, the chart would filter it out visually,
16
+ * but the emptiness check would think the chart has data — auto-fallback
17
+ * never fires and the user sees an empty plot.
18
+ */
19
+ export declare const isMarketChartEmpty: (data: MarketChartData | null | undefined, options?: {
20
+ minTimeSec?: number;
21
+ }) => boolean;
22
+ /**
23
+ * Decide whether the chart should auto-switch to the `ALL` range. We do this
24
+ * exactly once per chart subject (the caller's ref guard) so a user who later
25
+ * manually re-picks the empty range isn't fought by a second auto-switch.
26
+ *
27
+ * Bail conditions, in order:
28
+ * - we've already fallen back for this subject
29
+ * - we're already on `ALL` (nothing wider to fall back to)
30
+ * - the query errored — leave the failure surface to the error UI
31
+ * - the query is still loading — wait for a real answer
32
+ * - we have no payload yet — same reasoning
33
+ * Otherwise: fall back iff the payload is empty within the rolling domain.
34
+ */
35
+ export declare const shouldAutoFallbackToAllRange: ({ chartData, isLoading, error, currentRange, hasAlreadyFallenBack, domainStartTs, }: {
36
+ chartData: MarketChartData | null | undefined;
37
+ isLoading: boolean;
38
+ error: unknown;
39
+ currentRange: ChartTimeRange;
40
+ hasAlreadyFallenBack: boolean;
41
+ /** Rolling-window startTs in seconds. Bars older than this are ignored. */
42
+ domainStartTs?: number;
43
+ }) => boolean;
@@ -0,0 +1,43 @@
1
+ import type { ChartTimeRange, MarketChartData } from "@agg-build/hooks";
2
+ /**
3
+ * True when the chart payload has no usable bars *inside the visible domain*
4
+ * — i.e. the selected range yielded nothing to plot. A `null`/`undefined`
5
+ * payload (query not yet resolved) is also treated as "no data here" because
6
+ * the fallback decision uses this together with an `isLoading` guard.
7
+ *
8
+ * `liveCandle` counts as data: a market that just started trading inside the
9
+ * current bucket has a single forming candle and no closed bars; the chart
10
+ * should still render that.
11
+ *
12
+ * **Domain filtering**: pass `minTimeSec` (the rolling window's `startTs`) to
13
+ * ignore stale "courtesy" bars the API returns outside the requested window.
14
+ * Without this, a market that last traded 11h ago would surface a single
15
+ * out-of-window bar in `candles`, the chart would filter it out visually,
16
+ * but the emptiness check would think the chart has data — auto-fallback
17
+ * never fires and the user sees an empty plot.
18
+ */
19
+ export declare const isMarketChartEmpty: (data: MarketChartData | null | undefined, options?: {
20
+ minTimeSec?: number;
21
+ }) => boolean;
22
+ /**
23
+ * Decide whether the chart should auto-switch to the `ALL` range. We do this
24
+ * exactly once per chart subject (the caller's ref guard) so a user who later
25
+ * manually re-picks the empty range isn't fought by a second auto-switch.
26
+ *
27
+ * Bail conditions, in order:
28
+ * - we've already fallen back for this subject
29
+ * - we're already on `ALL` (nothing wider to fall back to)
30
+ * - the query errored — leave the failure surface to the error UI
31
+ * - the query is still loading — wait for a real answer
32
+ * - we have no payload yet — same reasoning
33
+ * Otherwise: fall back iff the payload is empty within the rolling domain.
34
+ */
35
+ export declare const shouldAutoFallbackToAllRange: ({ chartData, isLoading, error, currentRange, hasAlreadyFallenBack, domainStartTs, }: {
36
+ chartData: MarketChartData | null | undefined;
37
+ isLoading: boolean;
38
+ error: unknown;
39
+ currentRange: ChartTimeRange;
40
+ hasAlreadyFallenBack: boolean;
41
+ /** Rolling-window startTs in seconds. Bars older than this are ignored. */
42
+ domainStartTs?: number;
43
+ }) => boolean;
@@ -0,0 +1,14 @@
1
+ import { type PriceSelection } from "./select-outcome-price";
2
+ export declare const getDisplayOutcomePrice: ({ outcomeId, outcomeLabel, selection, bestPrices, bestMidpoint, bestMidpointsByOutcomeId, livePrices, fallbackPrice, }: {
3
+ outcomeId: string | null | undefined;
4
+ outcomeLabel?: string | null | undefined;
5
+ selection?: PriceSelection;
6
+ bestPrices?: ReadonlyMap<string, {
7
+ bestBid?: number;
8
+ bestAsk?: number;
9
+ }> | null | undefined;
10
+ bestMidpoint?: number | null | undefined;
11
+ bestMidpointsByOutcomeId?: ReadonlyMap<string, number> | null | undefined;
12
+ livePrices?: ReadonlyMap<string, number> | null | undefined;
13
+ fallbackPrice?: number | null | undefined;
14
+ }) => number | undefined;
@@ -0,0 +1,14 @@
1
+ import { type PriceSelection } from "./select-outcome-price";
2
+ export declare const getDisplayOutcomePrice: ({ outcomeId, outcomeLabel, selection, bestPrices, bestMidpoint, bestMidpointsByOutcomeId, livePrices, fallbackPrice, }: {
3
+ outcomeId: string | null | undefined;
4
+ outcomeLabel?: string | null | undefined;
5
+ selection?: PriceSelection;
6
+ bestPrices?: ReadonlyMap<string, {
7
+ bestBid?: number;
8
+ bestAsk?: number;
9
+ }> | null | undefined;
10
+ bestMidpoint?: number | null | undefined;
11
+ bestMidpointsByOutcomeId?: ReadonlyMap<string, number> | null | undefined;
12
+ livePrices?: ReadonlyMap<string, number> | null | undefined;
13
+ fallbackPrice?: number | null | undefined;
14
+ }) => number | undefined;
@@ -0,0 +1,30 @@
1
+ export declare const getDisplayOutcomeVenue: ({ outcomeId, outcomeLabel, selection, bestMidpointVenue, bestVenueByOutcomeId, bestPriceVenuesByOutcomeId, fallbackVenue, }: {
2
+ outcomeId: string | null | undefined;
3
+ outcomeLabel?: string | null | undefined;
4
+ /**
5
+ * Active trade side. When provided, the venue is sourced from
6
+ * `bestPriceVenuesByOutcomeId` (top-of-book side) to mirror the price the
7
+ * UI is showing. Falls through to the midpoint-driven logic only when no
8
+ * side-specific venue is available.
9
+ */
10
+ selection?: "buy" | "sell" | undefined;
11
+ /**
12
+ * Venue that produced the cluster-wide `bestMidpoint`. Mirrors the
13
+ * "yes" branch of `getDisplayOutcomePrice`: when the price comes from a
14
+ * cluster-level aggregate, the logo must come from the same aggregate.
15
+ * Required to keep logo + price in sync when the matched-sibling map
16
+ * doesn't know which market won.
17
+ */
18
+ bestMidpointVenue?: string | null | undefined;
19
+ bestVenueByOutcomeId?: ReadonlyMap<string, string> | null | undefined;
20
+ /**
21
+ * Per-outcome venue for the winning side of the top-of-book. Required so
22
+ * the logo follows the price when the cheapest `bestAsk` (buy) or richest
23
+ * `bestBid` (sell) lives on a matched sibling venue.
24
+ */
25
+ bestPriceVenuesByOutcomeId?: ReadonlyMap<string, {
26
+ bestBidVenue?: string;
27
+ bestAskVenue?: string;
28
+ }> | null | undefined;
29
+ fallbackVenue?: string | null | undefined;
30
+ }) => string | undefined;
@@ -0,0 +1,30 @@
1
+ export declare const getDisplayOutcomeVenue: ({ outcomeId, outcomeLabel, selection, bestMidpointVenue, bestVenueByOutcomeId, bestPriceVenuesByOutcomeId, fallbackVenue, }: {
2
+ outcomeId: string | null | undefined;
3
+ outcomeLabel?: string | null | undefined;
4
+ /**
5
+ * Active trade side. When provided, the venue is sourced from
6
+ * `bestPriceVenuesByOutcomeId` (top-of-book side) to mirror the price the
7
+ * UI is showing. Falls through to the midpoint-driven logic only when no
8
+ * side-specific venue is available.
9
+ */
10
+ selection?: "buy" | "sell" | undefined;
11
+ /**
12
+ * Venue that produced the cluster-wide `bestMidpoint`. Mirrors the
13
+ * "yes" branch of `getDisplayOutcomePrice`: when the price comes from a
14
+ * cluster-level aggregate, the logo must come from the same aggregate.
15
+ * Required to keep logo + price in sync when the matched-sibling map
16
+ * doesn't know which market won.
17
+ */
18
+ bestMidpointVenue?: string | null | undefined;
19
+ bestVenueByOutcomeId?: ReadonlyMap<string, string> | null | undefined;
20
+ /**
21
+ * Per-outcome venue for the winning side of the top-of-book. Required so
22
+ * the logo follows the price when the cheapest `bestAsk` (buy) or richest
23
+ * `bestBid` (sell) lives on a matched sibling venue.
24
+ */
25
+ bestPriceVenuesByOutcomeId?: ReadonlyMap<string, {
26
+ bestBidVenue?: string;
27
+ bestAskVenue?: string;
28
+ }> | null | undefined;
29
+ fallbackVenue?: string | null | undefined;
30
+ }) => string | undefined;
@@ -0,0 +1,4 @@
1
+ export declare const getDisplayReferencePrice: ({ bestMidpoint, fallbackPrice, }: {
2
+ bestMidpoint: number | null | undefined;
3
+ fallbackPrice: number | null | undefined;
4
+ }) => number | undefined;
@@ -0,0 +1,4 @@
1
+ export declare const getDisplayReferencePrice: ({ bestMidpoint, fallbackPrice, }: {
2
+ bestMidpoint: number | null | undefined;
3
+ fallbackPrice: number | null | undefined;
4
+ }) => number | undefined;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Select the most relevant price for an outcome based on buy/sell intent.
3
+ *
4
+ * Precedence:
5
+ * 1. Best bid/ask (if selection intent is provided)
6
+ * 2. Live (WebSocket) price
7
+ * 3. Midpoint from REST
8
+ * 4. Fallback price
9
+ */
10
+ export type PriceSelection = "buy" | "sell" | undefined;
11
+ export declare const selectOutcomePrice: ({ outcomeId, selection, bestPrices, bestMidpointsByOutcomeId, livePrices, fallbackPrice, }: {
12
+ outcomeId: string | null | undefined;
13
+ selection?: PriceSelection;
14
+ bestPrices?: ReadonlyMap<string, {
15
+ bestBid?: number;
16
+ bestAsk?: number;
17
+ }> | null;
18
+ bestMidpointsByOutcomeId?: ReadonlyMap<string, number> | null;
19
+ livePrices?: ReadonlyMap<string, number> | null;
20
+ fallbackPrice?: number | null;
21
+ }) => number | undefined;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Select the most relevant price for an outcome based on buy/sell intent.
3
+ *
4
+ * Precedence:
5
+ * 1. Best bid/ask (if selection intent is provided)
6
+ * 2. Live (WebSocket) price
7
+ * 3. Midpoint from REST
8
+ * 4. Fallback price
9
+ */
10
+ export type PriceSelection = "buy" | "sell" | undefined;
11
+ export declare const selectOutcomePrice: ({ outcomeId, selection, bestPrices, bestMidpointsByOutcomeId, livePrices, fallbackPrice, }: {
12
+ outcomeId: string | null | undefined;
13
+ selection?: PriceSelection;
14
+ bestPrices?: ReadonlyMap<string, {
15
+ bestBid?: number;
16
+ bestAsk?: number;
17
+ }> | null;
18
+ bestMidpointsByOutcomeId?: ReadonlyMap<string, number> | null;
19
+ livePrices?: ReadonlyMap<string, number> | null;
20
+ fallbackPrice?: number | null;
21
+ }) => number | undefined;
@@ -8,10 +8,11 @@ type AvailableBalanceCardProps = {
8
8
  label?: string;
9
9
  valueLabel: string;
10
10
  chains: ChainRow[];
11
+ isLoading?: boolean;
11
12
  className?: string;
12
13
  };
13
14
  export declare const AvailableBalanceCard: {
14
- ({ label, valueLabel, chains, className, }: AvailableBalanceCardProps): JSX.Element;
15
+ ({ label, valueLabel, chains, isLoading, className, }: AvailableBalanceCardProps): JSX.Element;
15
16
  displayName: string;
16
17
  };
17
18
  export {};
@@ -8,10 +8,11 @@ type AvailableBalanceCardProps = {
8
8
  label?: string;
9
9
  valueLabel: string;
10
10
  chains: ChainRow[];
11
+ isLoading?: boolean;
11
12
  className?: string;
12
13
  };
13
14
  export declare const AvailableBalanceCard: {
14
- ({ label, valueLabel, chains, className, }: AvailableBalanceCardProps): JSX.Element;
15
+ ({ label, valueLabel, chains, isLoading, className, }: AvailableBalanceCardProps): JSX.Element;
15
16
  displayName: string;
16
17
  };
17
18
  export {};
@@ -1,10 +1,11 @@
1
1
  type PositionsValueCardProps = {
2
2
  label?: string;
3
3
  valueLabel: string;
4
+ isLoading?: boolean;
4
5
  className?: string;
5
6
  };
6
7
  export declare const PositionsValueCard: {
7
- ({ label, valueLabel, className, }: PositionsValueCardProps): JSX.Element;
8
+ ({ label, valueLabel, isLoading, className, }: PositionsValueCardProps): JSX.Element;
8
9
  displayName: string;
9
10
  };
10
11
  export {};
@@ -1,10 +1,11 @@
1
1
  type PositionsValueCardProps = {
2
2
  label?: string;
3
3
  valueLabel: string;
4
+ isLoading?: boolean;
4
5
  className?: string;
5
6
  };
6
7
  export declare const PositionsValueCard: {
7
- ({ label, valueLabel, className, }: PositionsValueCardProps): JSX.Element;
8
+ ({ label, valueLabel, isLoading, className, }: PositionsValueCardProps): JSX.Element;
8
9
  displayName: string;
9
10
  };
10
11
  export {};
@@ -1,9 +1,9 @@
1
1
  import type { UserProfilePageProps } from "./user-profile.types";
2
- export type { UserProfileActivity, UserProfileBalance, UserProfileConnectedExchange, UserProfileConnectedWallet, UserProfileInfo, UserProfilePageClassNames, UserProfilePageProps, UserProfilePosition, UserProfilePositionFilter, UserProfilePositionVenueShare, UserProfileSocialLink, UserProfileVenueBalance, } from "./user-profile.types";
2
+ export type { UserProfileActivity, UserProfileActivityStatus, UserProfileBalance, UserProfileConnectedExchange, UserProfileConnectedWallet, UserProfileInfo, UserProfilePageClassNames, UserProfilePageProps, UserProfilePosition, UserProfilePositionFilter, UserProfilePositionVenueShare, UserProfileSocialLink, UserProfileTransferStatus, UserProfileVenueBalance, } from "./user-profile.types";
3
3
  export { USER_PROFILE_TAB_ACTIVITY, USER_PROFILE_TAB_OPEN_ORDERS, USER_PROFILE_TAB_POSITIONS, } from "./user-profile.constants";
4
4
  export type { UserProfileTabValue } from "./user-profile.constants";
5
5
  export declare const UserProfilePage: {
6
- ({ user, balanceChainsOverride, venueBalances: _venueBalances, balance, activePositions, closedPositions, activities, onEditProfile, onDeposit, onWithdraw, openOrders, initialPositionFilter, tab, onTabChange, onPositionClick, getPositionHref, onClaim, claimingPositionKeys, onActivityClick, getActivityHref, onOpenOrderClick, onCancelOrder, cancellingOrderIds, isLoadingPositions, isLoadingActivities, isLoadingOpenOrders, positionsError, activitiesError, openOrdersError, hasMoreActivePositions, isLoadingMoreActivePositions, onLoadMoreActivePositions, hasMoreClosedPositions, isLoadingMoreClosedPositions, onLoadMoreClosedPositions, onPositionFilterChange: onPositionFilterChangeProp, hasMoreActivities, isLoadingMoreActivities, onLoadMoreActivities, hasMoreOpenOrders, isLoadingMoreOpenOrders, onLoadMoreOpenOrders, classNames, onError, }: UserProfilePageProps & {
6
+ ({ user, balanceChainsOverride, venueBalances: _venueBalances, balance, activePositions, closedPositions, activities, onEditProfile, onDeposit, onWithdraw, openOrders, initialPositionFilter, tab, onTabChange, onPositionClick, getPositionHref, onClaim, claimingPositionKeys, onClaimResult, onClaimSubmitError, onActivityClick, getActivityHref, onOpenOrderClick, onCancelOrder, cancellingOrderIds, isLoadingPositions, isLoadingActivities, isLoadingOpenOrders, positionsError, activitiesError, openOrdersError, hasMoreActivePositions, isLoadingMoreActivePositions, onLoadMoreActivePositions, hasMoreClosedPositions, isLoadingMoreClosedPositions, onLoadMoreClosedPositions, onPositionFilterChange: onPositionFilterChangeProp, hasMoreActivities, isLoadingMoreActivities, onLoadMoreActivities, hasMoreOpenOrders, isLoadingMoreOpenOrders, onLoadMoreOpenOrders, classNames, onError, }: UserProfilePageProps & {
7
7
  onError?: (error: Error) => void;
8
8
  }): JSX.Element;
9
9
  displayName: string;
@@ -1,9 +1,9 @@
1
1
  import type { UserProfilePageProps } from "./user-profile.types";
2
- export type { UserProfileActivity, UserProfileBalance, UserProfileConnectedExchange, UserProfileConnectedWallet, UserProfileInfo, UserProfilePageClassNames, UserProfilePageProps, UserProfilePosition, UserProfilePositionFilter, UserProfilePositionVenueShare, UserProfileSocialLink, UserProfileVenueBalance, } from "./user-profile.types";
2
+ export type { UserProfileActivity, UserProfileActivityStatus, UserProfileBalance, UserProfileConnectedExchange, UserProfileConnectedWallet, UserProfileInfo, UserProfilePageClassNames, UserProfilePageProps, UserProfilePosition, UserProfilePositionFilter, UserProfilePositionVenueShare, UserProfileSocialLink, UserProfileTransferStatus, UserProfileVenueBalance, } from "./user-profile.types";
3
3
  export { USER_PROFILE_TAB_ACTIVITY, USER_PROFILE_TAB_OPEN_ORDERS, USER_PROFILE_TAB_POSITIONS, } from "./user-profile.constants";
4
4
  export type { UserProfileTabValue } from "./user-profile.constants";
5
5
  export declare const UserProfilePage: {
6
- ({ user, balanceChainsOverride, venueBalances: _venueBalances, balance, activePositions, closedPositions, activities, onEditProfile, onDeposit, onWithdraw, openOrders, initialPositionFilter, tab, onTabChange, onPositionClick, getPositionHref, onClaim, claimingPositionKeys, onActivityClick, getActivityHref, onOpenOrderClick, onCancelOrder, cancellingOrderIds, isLoadingPositions, isLoadingActivities, isLoadingOpenOrders, positionsError, activitiesError, openOrdersError, hasMoreActivePositions, isLoadingMoreActivePositions, onLoadMoreActivePositions, hasMoreClosedPositions, isLoadingMoreClosedPositions, onLoadMoreClosedPositions, onPositionFilterChange: onPositionFilterChangeProp, hasMoreActivities, isLoadingMoreActivities, onLoadMoreActivities, hasMoreOpenOrders, isLoadingMoreOpenOrders, onLoadMoreOpenOrders, classNames, onError, }: UserProfilePageProps & {
6
+ ({ user, balanceChainsOverride, venueBalances: _venueBalances, balance, activePositions, closedPositions, activities, onEditProfile, onDeposit, onWithdraw, openOrders, initialPositionFilter, tab, onTabChange, onPositionClick, getPositionHref, onClaim, claimingPositionKeys, onClaimResult, onClaimSubmitError, onActivityClick, getActivityHref, onOpenOrderClick, onCancelOrder, cancellingOrderIds, isLoadingPositions, isLoadingActivities, isLoadingOpenOrders, positionsError, activitiesError, openOrdersError, hasMoreActivePositions, isLoadingMoreActivePositions, onLoadMoreActivePositions, hasMoreClosedPositions, isLoadingMoreClosedPositions, onLoadMoreClosedPositions, onPositionFilterChange: onPositionFilterChangeProp, hasMoreActivities, isLoadingMoreActivities, onLoadMoreActivities, hasMoreOpenOrders, isLoadingMoreOpenOrders, onLoadMoreOpenOrders, classNames, onError, }: UserProfilePageProps & {
7
7
  onError?: (error: Error) => void;
8
8
  }): JSX.Element;
9
9
  displayName: string;
@@ -65,6 +65,8 @@ export interface UserProfilePosition {
65
65
  title: string;
66
66
  /** Outcome name for the pill only, e.g. "Yes" (no price). */
67
67
  outcomeLabel: string;
68
+ /** Resolved winning outcome name shown in closed position rows, e.g. "No". */
69
+ resolutionLabel?: string | null;
68
70
  /** Per-venue position sizes with logos below the pill. */
69
71
  venueShareBreakdown: UserProfilePositionVenueShare[];
70
72
  /** Total shares/contracts represented by this row. */
@@ -130,6 +132,10 @@ export interface UserProfileTradeActivity {
130
132
  isFailed?: boolean;
131
133
  /** Whether the row should use error-colored text because the activity has an error. */
132
134
  hasError?: boolean;
135
+ /** Error message for the activity. */
136
+ errorMessage?: string;
137
+ /** Normalized lifecycle status driving row tone. Defaults to "completed". */
138
+ status?: UserProfileActivityStatus;
133
139
  /** Activity type, e.g. "Buy", "Sell" */
134
140
  type: string;
135
141
  /** Market thumbnail image URL */
@@ -147,6 +153,14 @@ export interface UserProfileTradeActivity {
147
153
  /** Time label, e.g. "3d ago" */
148
154
  timeLabel: string;
149
155
  }
156
+ /**
157
+ * Normalized UI state for activity rows. Backend statuses collapse into
158
+ * one of four buckets so row tone, status icons, titles, and amounts stay
159
+ * aligned. Unknown statuses fall back to "completed" — a stale row at rest
160
+ * is the safer default than a sticky spinner.
161
+ */
162
+ export type UserProfileActivityStatus = "completed" | "pending" | "failed" | "canceled";
163
+ export type UserProfileTransferStatus = UserProfileActivityStatus;
150
164
  /** Non-trade activity row: withdrawal / deposit / bridge / user_op. */
151
165
  export interface UserProfileTransferActivity {
152
166
  kind: "withdrawal" | "deposit" | "bridge" | "user_op";
@@ -155,6 +169,10 @@ export interface UserProfileTransferActivity {
155
169
  isFailed?: boolean;
156
170
  /** Whether the row should use error-colored text because the activity has an error. */
157
171
  hasError?: boolean;
172
+ /** Error message for the activity. */
173
+ errorMessage?: string;
174
+ /** Normalized status driving icon, title, and amount rendering. Defaults to "completed". */
175
+ status?: UserProfileTransferStatus;
158
176
  /** Header label, e.g. "Withdraw", "Deposit", "Bridge", "Wallet op". */
159
177
  type: string;
160
178
  /** Title, e.g. "Withdraw USDC". */
@@ -254,8 +272,43 @@ export interface UserProfilePageProps {
254
272
  getPositionHref?: (position: UserProfilePosition) => string | undefined;
255
273
  /** Called when the user claims a closed winning position. */
256
274
  onClaim?: (position: UserProfilePosition) => Promise<void> | void;
257
- /** Map of claim key (marketId or position id) to loading state while claim is in-flight. */
275
+ /**
276
+ * Map of claim key (marketId or position id) to loading state while claim is in-flight.
277
+ *
278
+ * Passing this prop overrides the internal lifecycle-driven spinner (the page derives
279
+ * spinner state from the in-flight redeem's WS lifecycle when this prop is omitted).
280
+ * Partners who own the claim flow via `onClaim` typically pass their own state here;
281
+ * partners who let the page own the flow should omit this prop.
282
+ */
258
283
  claimingPositionKeys?: Record<string, boolean>;
284
+ /**
285
+ * Called once per redeem when its lifecycle reaches terminal (every expected leg
286
+ * confirmed or failed on chain). Receives the same `claimKey` that
287
+ * `claimingPositionKeys` uses (i.e. `position.marketId ?? position.id`) plus a
288
+ * summary of the terminal lifecycle state. Use this to fire one-shot success/failure
289
+ * toasts.
290
+ *
291
+ * NOT fired for synchronous submit failures (network errors, `RedeemRejectedError`)
292
+ * — those go through `onClaimSubmitError`.
293
+ *
294
+ * Only fired when the internal claim path is used (i.e. when the caller does NOT
295
+ * pass an `onClaim` prop). Callers that own the claim flow via `onClaim` are
296
+ * responsible for their own toasting.
297
+ */
298
+ onClaimResult?: (claimKey: string, lifecycle: {
299
+ allConfirmed: boolean;
300
+ anyFailed: boolean;
301
+ errorMessage: string | null;
302
+ }) => void;
303
+ /**
304
+ * Called when the redeem mutation itself rejects — i.e. transport error, validation
305
+ * error, or `RedeemRejectedError` (all legs ineligible/rejected at submit time). The
306
+ * redeem never enters the WS lifecycle in these cases, so `onClaimResult` does NOT
307
+ * fire.
308
+ *
309
+ * Only fired when the internal claim path is used.
310
+ */
311
+ onClaimSubmitError?: (claimKey: string, error: Error) => void;
259
312
  /** Called when an activity row is clicked */
260
313
  onActivityClick?: (activity: UserProfileActivity) => void;
261
314
  /** Optional href for an activity row (enables ctrl/cmd/middle-click to open in a new tab). */