@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
@@ -2,15 +2,16 @@
2
2
  import {
3
3
  Settlement,
4
4
  formatProbabilityCents,
5
+ getDisplayOutcomePrice,
5
6
  getTradingDateLabel,
6
7
  getTradingPriceLabel,
7
8
  getTradingValueLabel,
8
9
  getTradingVenueLabel,
9
10
  resolveOrderEligibilityMessage
10
- } from "./chunk-5PSAIGOT.mjs";
11
+ } from "./chunk-54PCEK6G.mjs";
11
12
  import {
12
13
  GeoBlockBanner
13
- } from "./chunk-5MDFM2MX.mjs";
14
+ } from "./chunk-NWJHFGBZ.mjs";
14
15
  import {
15
16
  AGG_TERMS_OF_SERVICE_URL,
16
17
  Button,
@@ -35,9 +36,8 @@ import {
35
36
  cn,
36
37
  formatUsd,
37
38
  getMotionClassName,
38
- normalizeVenueMarketCluster,
39
39
  skeletonViews
40
- } from "./chunk-QFW5NDJ6.mjs";
40
+ } from "./chunk-SJLHOAKK.mjs";
41
41
 
42
42
  // src/trading/types.ts
43
43
  import { Venue, enumGuard, isFiniteNonNeg, safeParse } from "@agg-build/sdk";
@@ -86,6 +86,7 @@ import {
86
86
  resolveEventTradingState,
87
87
  resolveMarketTradingState,
88
88
  resolveOrderEligibility,
89
+ TradeSide,
89
90
  useAggAuthContext,
90
91
  useAggBalanceState,
91
92
  useAggClient as useAggClient2,
@@ -96,9 +97,10 @@ import {
96
97
  useExecutionProgress,
97
98
  useGeoBlock,
98
99
  useLabels,
100
+ useLiveBestPrices,
99
101
  useLiveOutcomePrices,
100
- useMidpoints,
101
102
  useQueryClient,
103
+ mergeBestPricesPreferringLive,
102
104
  useSdkUiConfig,
103
105
  useSmartRoute
104
106
  } from "@agg-build/hooks";
@@ -244,176 +246,6 @@ var PLACE_ORDER_OUTCOME_BUTTON_CLASS_NAMES = {
244
246
  inactive: "border-transparent bg-agg-secondary-hover font-agg-normal text-agg-foreground hover:bg-agg-tertiary"
245
247
  };
246
248
 
247
- // src/trading/place-order/index.place-order.execution-steps.ts
248
- import { Venue as Venue2 } from "@agg-build/sdk";
249
- var WAIT_STEP_TYPES = /* @__PURE__ */ new Set(["_wait", "wait"]);
250
- var CHECKING_BALANCE_STEP_TYPES = /* @__PURE__ */ new Set([
251
- "check-balance",
252
- "check-position",
253
- "position-reserve",
254
- "position-release"
255
- ]);
256
- var VENUE_BUY_SELL_REGEX = /^(?:buy|sell)-([a-z]+)$/;
257
- var VENUE_FINALIZE_REGEX = /^([a-z]+)-finalize$/;
258
- var VENUE_NAME_MAP = {
259
- kalshi: Venue2.kalshi,
260
- polymarket: Venue2.polymarket,
261
- limitless: Venue2.limitless,
262
- opinion: Venue2.opinion,
263
- predict: Venue2.predict,
264
- probable: Venue2.probable,
265
- myriad: Venue2.myriad,
266
- hyperliquid: Venue2.hyperliquid
267
- };
268
- var parseVenueName = (raw) => VENUE_NAME_MAP[raw];
269
- var NON_VENUE_FINALIZE_PREFIXES = /* @__PURE__ */ new Set(["bridge"]);
270
- var classifyExecutionStepType = (stepType) => {
271
- if (!stepType) return null;
272
- if (WAIT_STEP_TYPES.has(stepType)) return null;
273
- if (CHECKING_BALANCE_STEP_TYPES.has(stepType)) {
274
- return { kind: "checking-balance" };
275
- }
276
- const buySellMatch = stepType.match(VENUE_BUY_SELL_REGEX);
277
- if (buySellMatch) {
278
- const venue = parseVenueName(buySellMatch[1]);
279
- if (venue) return { kind: "executing-venue", venue };
280
- }
281
- const finalizeMatch = stepType.match(VENUE_FINALIZE_REGEX);
282
- if (finalizeMatch && !NON_VENUE_FINALIZE_PREFIXES.has(finalizeMatch[1])) {
283
- const venue = parseVenueName(finalizeMatch[1]);
284
- if (venue) return { kind: "executing-venue", venue };
285
- }
286
- if (stepType === "submit-verify-order-status") {
287
- return null;
288
- }
289
- return { kind: "submitting" };
290
- };
291
- var buildPhaseTimeline = (dag) => {
292
- const timeline = [];
293
- const completed = new Set(dag.completedSequences);
294
- for (let seq = 1; seq <= dag.totalSteps; seq++) {
295
- const stepType = dag.stepTypes[seq];
296
- if (!stepType) continue;
297
- const classified = classifyExecutionStepType(stepType);
298
- if (!classified) continue;
299
- const isCompleted = completed.has(seq);
300
- const last = timeline[timeline.length - 1];
301
- if (last && last.kind === classified.kind && last.venue === classified.venue) {
302
- last.lastSeq = seq;
303
- last.allCompleted = last.allCompleted && isCompleted;
304
- continue;
305
- }
306
- timeline.push({
307
- kind: classified.kind,
308
- venue: classified.venue,
309
- firstSeq: seq,
310
- lastSeq: seq,
311
- allCompleted: isCompleted
312
- });
313
- }
314
- return timeline;
315
- };
316
- var phaseRowId = (phase) => phase.venue ? `${phase.kind}:${phase.venue}` : phase.kind;
317
- var phaseRowLabel = (phase, labels) => {
318
- switch (phase.kind) {
319
- case "finding-route":
320
- return labels.findingBestRoute;
321
- case "checking-balance":
322
- return labels.checkingBalance;
323
- case "submitting":
324
- return labels.submittingOrderProgress;
325
- case "wallet-confirm":
326
- return labels.confirmTransactionInWallet;
327
- case "executing-venue":
328
- return labels.executingOnVenue(getTradingVenueLabel(phase.venue));
329
- case "filled":
330
- return labels.executionConfirmed;
331
- case "failed":
332
- return labels.orderFailureTitle;
333
- }
334
- };
335
- var buildSubmissionDisplayRows = ({
336
- phase,
337
- dagProgress,
338
- executionVenue,
339
- isAwaitingWalletConfirmation,
340
- labels
341
- }) => {
342
- if (phase === "finding-route") {
343
- return [
344
- {
345
- id: "finding-route",
346
- label: labels.findingBestRoute,
347
- status: "pending"
348
- }
349
- ];
350
- }
351
- const rows = [
352
- {
353
- id: "finding-route",
354
- label: labels.findingBestRoute,
355
- status: "complete"
356
- }
357
- ];
358
- const pushPhase = (phaseEntry, status) => {
359
- const id = phaseRowId(phaseEntry);
360
- if (rows.some((row) => row.id === id)) return;
361
- rows.push({
362
- id,
363
- label: phaseRowLabel(phaseEntry, labels),
364
- status,
365
- venue: phaseEntry.venue
366
- });
367
- };
368
- if (dagProgress && dagProgress.totalSteps > 0) {
369
- const timeline = buildPhaseTimeline(dagProgress);
370
- let activeEmitted = false;
371
- for (const entry of timeline) {
372
- const id = phaseRowId(entry);
373
- const alreadyShown = rows.some((row) => row.id === id);
374
- if (entry.allCompleted) {
375
- if (alreadyShown) continue;
376
- pushPhase(entry, "complete");
377
- continue;
378
- }
379
- if (activeEmitted) break;
380
- if (alreadyShown) continue;
381
- if (isAwaitingWalletConfirmation && entry.kind === "submitting") {
382
- pushPhase({ kind: "wallet-confirm" }, "pending");
383
- } else {
384
- pushPhase(entry, "pending");
385
- }
386
- activeEmitted = true;
387
- }
388
- if (!activeEmitted) {
389
- const last = rows[rows.length - 1];
390
- if (last && last.id.startsWith("executing-venue")) {
391
- last.status = "pending";
392
- } else {
393
- const fallbackVenue = executionVenue;
394
- rows.push({
395
- id: fallbackVenue ? `executing-venue:${fallbackVenue}` : "executing-venue",
396
- label: phaseRowLabel({ kind: "executing-venue", venue: fallbackVenue }, labels),
397
- status: "pending",
398
- venue: fallbackVenue
399
- });
400
- }
401
- }
402
- return rows;
403
- }
404
- if (isAwaitingWalletConfirmation) {
405
- pushPhase({ kind: "wallet-confirm" }, "pending");
406
- return rows;
407
- }
408
- if (phase === "submitting") {
409
- pushPhase({ kind: "submitting" }, "pending");
410
- return rows;
411
- }
412
- pushPhase({ kind: "submitting" }, "complete");
413
- pushPhase({ kind: "executing-venue", venue: executionVenue }, "pending");
414
- return rows;
415
- };
416
-
417
249
  // src/trading/place-order/index.place-order.execution-debug.ts
418
250
  var REDACTED = "[redacted]";
419
251
  var SENSITIVE_FIELD_PATTERNS = [
@@ -685,7 +517,194 @@ var enableExecutionDebugInBrowser = (initial) => {
685
517
  return store;
686
518
  };
687
519
 
520
+ // src/trading/place-order/index.place-order.execution-steps.ts
521
+ import { Venue as Venue2 } from "@agg-build/sdk";
522
+ var WAIT_STEP_TYPES = /* @__PURE__ */ new Set(["_wait", "wait"]);
523
+ var CHECKING_BALANCE_STEP_TYPES = /* @__PURE__ */ new Set([
524
+ "check-balance",
525
+ "check-position",
526
+ "position-reserve",
527
+ "position-release"
528
+ ]);
529
+ var VENUE_BUY_SELL_REGEX = /^(?:buy|sell)-([a-z]+)$/;
530
+ var VENUE_FINALIZE_REGEX = /^([a-z]+)-finalize$/;
531
+ var VENUE_NAME_MAP = {
532
+ kalshi: Venue2.kalshi,
533
+ polymarket: Venue2.polymarket,
534
+ limitless: Venue2.limitless,
535
+ opinion: Venue2.opinion,
536
+ predict: Venue2.predict,
537
+ probable: Venue2.probable,
538
+ myriad: Venue2.myriad,
539
+ hyperliquid: Venue2.hyperliquid
540
+ };
541
+ var parseVenueName = (raw) => VENUE_NAME_MAP[raw];
542
+ var NON_VENUE_FINALIZE_PREFIXES = /* @__PURE__ */ new Set(["bridge"]);
543
+ var classifyExecutionStepType = (stepType) => {
544
+ if (!stepType) return null;
545
+ if (WAIT_STEP_TYPES.has(stepType)) return null;
546
+ if (CHECKING_BALANCE_STEP_TYPES.has(stepType)) {
547
+ return { kind: "checking-balance" };
548
+ }
549
+ const buySellMatch = stepType.match(VENUE_BUY_SELL_REGEX);
550
+ if (buySellMatch) {
551
+ const venue = parseVenueName(buySellMatch[1]);
552
+ if (venue) return { kind: "executing-venue", venue };
553
+ }
554
+ const finalizeMatch = stepType.match(VENUE_FINALIZE_REGEX);
555
+ if (finalizeMatch && !NON_VENUE_FINALIZE_PREFIXES.has(finalizeMatch[1])) {
556
+ const venue = parseVenueName(finalizeMatch[1]);
557
+ if (venue) return { kind: "executing-venue", venue };
558
+ }
559
+ if (stepType === "submit-verify-order-status") {
560
+ return null;
561
+ }
562
+ return { kind: "submitting" };
563
+ };
564
+ var buildPhaseTimeline = (dag) => {
565
+ const timeline = [];
566
+ const completed = new Set(dag.completedSequences);
567
+ for (let seq = 1; seq <= dag.totalSteps; seq++) {
568
+ const stepType = dag.stepTypes[seq];
569
+ if (!stepType) continue;
570
+ const classified = classifyExecutionStepType(stepType);
571
+ if (!classified) continue;
572
+ const isCompleted = completed.has(seq);
573
+ const last = timeline[timeline.length - 1];
574
+ if (last && last.kind === classified.kind && last.venue === classified.venue) {
575
+ last.lastSeq = seq;
576
+ last.allCompleted = last.allCompleted && isCompleted;
577
+ continue;
578
+ }
579
+ timeline.push({
580
+ kind: classified.kind,
581
+ venue: classified.venue,
582
+ firstSeq: seq,
583
+ lastSeq: seq,
584
+ allCompleted: isCompleted
585
+ });
586
+ }
587
+ const blockHasProgress = (entry) => {
588
+ if (entry.allCompleted) return true;
589
+ for (let s = entry.firstSeq; s <= entry.lastSeq; s++) {
590
+ if (completed.has(s)) return true;
591
+ }
592
+ return false;
593
+ };
594
+ for (let i = timeline.length - 2; i >= 0; i--) {
595
+ if (timeline[i].allCompleted) continue;
596
+ for (let j = i + 1; j < timeline.length; j++) {
597
+ if (blockHasProgress(timeline[j])) {
598
+ timeline[i].allCompleted = true;
599
+ break;
600
+ }
601
+ }
602
+ }
603
+ return timeline;
604
+ };
605
+ var phaseRowId = (phase) => phase.venue ? `${phase.kind}:${phase.venue}` : phase.kind;
606
+ var phaseRowLabel = (phase, labels) => {
607
+ switch (phase.kind) {
608
+ case "finding-route":
609
+ return labels.findingBestRoute;
610
+ case "checking-balance":
611
+ return labels.checkingBalance;
612
+ case "submitting":
613
+ return labels.submittingOrderProgress;
614
+ case "wallet-confirm":
615
+ return labels.confirmTransactionInWallet;
616
+ case "executing-venue":
617
+ return labels.executingOnVenue(getTradingVenueLabel(phase.venue));
618
+ case "filled":
619
+ return labels.executionConfirmed;
620
+ case "failed":
621
+ return labels.orderFailureTitle;
622
+ }
623
+ };
624
+ var buildSubmissionDisplayRows = ({
625
+ phase,
626
+ dagProgress,
627
+ executionVenue,
628
+ isAwaitingWalletConfirmation,
629
+ labels
630
+ }) => {
631
+ if (phase === "finding-route") {
632
+ return [
633
+ {
634
+ id: "finding-route",
635
+ label: labels.findingBestRoute,
636
+ status: "pending"
637
+ }
638
+ ];
639
+ }
640
+ const rows = [
641
+ {
642
+ id: "finding-route",
643
+ label: labels.findingBestRoute,
644
+ status: "complete"
645
+ }
646
+ ];
647
+ const pushPhase = (phaseEntry, status) => {
648
+ const id = phaseRowId(phaseEntry);
649
+ if (rows.some((row) => row.id === id)) return;
650
+ rows.push({
651
+ id,
652
+ label: phaseRowLabel(phaseEntry, labels),
653
+ status,
654
+ venue: phaseEntry.venue
655
+ });
656
+ };
657
+ if (dagProgress && dagProgress.totalSteps > 0) {
658
+ const timeline = buildPhaseTimeline(dagProgress);
659
+ let activeEmitted = false;
660
+ for (const entry of timeline) {
661
+ const id = phaseRowId(entry);
662
+ const alreadyShown = rows.some((row) => row.id === id);
663
+ if (entry.allCompleted) {
664
+ if (alreadyShown) continue;
665
+ pushPhase(entry, "complete");
666
+ continue;
667
+ }
668
+ if (activeEmitted) break;
669
+ if (alreadyShown) continue;
670
+ if (isAwaitingWalletConfirmation && entry.kind === "submitting") {
671
+ pushPhase({ kind: "wallet-confirm" }, "pending");
672
+ } else {
673
+ pushPhase(entry, "pending");
674
+ }
675
+ activeEmitted = true;
676
+ }
677
+ if (!activeEmitted) {
678
+ const last = rows[rows.length - 1];
679
+ if (last && last.id.startsWith("executing-venue")) {
680
+ last.status = "pending";
681
+ } else {
682
+ const fallbackVenue = executionVenue;
683
+ rows.push({
684
+ id: fallbackVenue ? `executing-venue:${fallbackVenue}` : "executing-venue",
685
+ label: phaseRowLabel({ kind: "executing-venue", venue: fallbackVenue }, labels),
686
+ status: "pending",
687
+ venue: fallbackVenue
688
+ });
689
+ }
690
+ }
691
+ return rows;
692
+ }
693
+ if (isAwaitingWalletConfirmation) {
694
+ pushPhase({ kind: "wallet-confirm" }, "pending");
695
+ return rows;
696
+ }
697
+ if (phase === "submitting") {
698
+ pushPhase({ kind: "submitting" }, "pending");
699
+ return rows;
700
+ }
701
+ pushPhase({ kind: "submitting" }, "complete");
702
+ pushPhase({ kind: "executing-venue", venue: executionVenue }, "pending");
703
+ return rows;
704
+ };
705
+
688
706
  // src/trading/place-order/index.place-order.utils.ts
707
+ var ATOMIC_UNITS = 1e6;
689
708
  var routePriceLabelFormatter = new Intl.NumberFormat("en-US", {
690
709
  minimumFractionDigits: 0,
691
710
  maximumFractionDigits: 1
@@ -770,7 +789,13 @@ var parseFilledAmountRawDollars = (filledAmountRaw) => {
770
789
  if (!filledAmountRaw) return null;
771
790
  const raw = Number(filledAmountRaw);
772
791
  if (!Number.isFinite(raw) || raw <= 0) return null;
773
- return raw / 1e6;
792
+ return raw / ATOMIC_UNITS;
793
+ };
794
+ var parseDecimalString = (value) => {
795
+ if (value == null) return null;
796
+ const parsed = Number(value);
797
+ if (!Number.isFinite(parsed) || parsed <= 0) return null;
798
+ return parsed;
774
799
  };
775
800
  var resolvePlaceOrderQuoteResult = ({
776
801
  labels,
@@ -896,18 +921,17 @@ var buildLiveRouteCards = ({
896
921
  const isSplit = quoteData.fills.length > 1;
897
922
  const primaryWinnerVenue = quoteData.fills.length === 1 ? primaryVenue : void 0;
898
923
  const isPrimaryRouteGeoBlocked = quoteData.fills.length > 0 && quoteData.fills.some((f) => geoBlockedVenues.has(f.venue));
899
- const primaryCard = primaryResult ? isPrimaryRouteGeoBlocked ? {
924
+ const primaryCard = primaryResult ? isPrimaryRouteGeoBlocked ? isSplit ? null : {
900
925
  id: "live-route",
901
926
  hint: labels.venueUnavailableInRegion,
902
- kind: isSplit ? "split" : "venue",
903
- label: isSplit ? labels.orderSplitting : getTradingVenueLabel(
927
+ kind: "venue",
928
+ label: getTradingVenueLabel(
904
929
  parsedPrimaryVenue.success ? parsedPrimaryVenue.data : void 0
905
930
  ),
906
931
  numericValue: tradeSide === "sell" ? quoteData.rawExecCost : quoteData.totalFilled,
907
932
  quoteData,
908
- rows: isSplit ? mapQuoteDataToRoutingRows(quoteData) : void 0,
909
933
  value: primaryResult.value,
910
- venue: isSplit ? void 0 : parsedPrimaryVenue.success ? parsedPrimaryVenue.data : void 0,
934
+ venue: parsedPrimaryVenue.success ? parsedPrimaryVenue.data : void 0,
911
935
  isUnavailable: true
912
936
  } : {
913
937
  id: "live-route",
@@ -1197,6 +1221,42 @@ var MARKET_RESOLVED_ERROR_PATTERN = /\b(resolved|no longer accepting orders|acce
1197
1221
  var VENUE_UNAVAILABLE_ERROR_PATTERN = /\b(unavailable|unreachable|timeout|timed out|expired|canceled|cancelled|failed with no fills)\b/i;
1198
1222
  var ALCHEMY_SPONSORSHIP_ERROR_PATTERN = /\bsponsorship failed: sender has no balance of the token for erc20 sponsorship\b/i;
1199
1223
  var ALCHEMY_PREPARE_CALLS_ERROR_PATTERN = /\bwallet_prepareCalls\b/i;
1224
+ var DAG_CHECK_BALANCE_SHORTFALL_PATTERN = /\bInsufficient balance on chain\s+\d+\s+token\s+\S+:/i;
1225
+ var ALCHEMY_BALANCE_REVERT_PATTERN = /\b(transfer amount exceeds balance|transferFrom failed|insufficient balance|insufficient funds)\b/i;
1226
+ var ALCHEMY_REVERT_DATA_SELECTOR_PATTERN = /\brevertData["']?:?\s*['"]?(0x[0-9a-fA-F]{8})/i;
1227
+ var REVERT_SELECTOR_MESSAGES = {
1228
+ // Solady TransferFromFailed() — ERC-20 transferFrom revert. Same recovery
1229
+ // as the plaintext "transfer amount exceeds balance": refresh balance and
1230
+ // re-quote (the P0-A tombstone + FE refetch in #1445 + #1446 handle the
1231
+ // server-side dedup).
1232
+ "0x7939f424": "Your balance changed since the quote. Please refresh and try again.",
1233
+ // Solady InsufficientBalance() — Solady's own balance-shortfall variant.
1234
+ "0xf4d678b8": "Your balance changed since the quote. Please refresh and try again."
1235
+ };
1236
+ function lookupRevertSelectorMessage(message) {
1237
+ var _a, _b;
1238
+ const match = message.match(ALCHEMY_REVERT_DATA_SELECTOR_PATTERN);
1239
+ if (!match) return null;
1240
+ const selector = (_a = match[1]) == null ? void 0 : _a.toLowerCase();
1241
+ if (!selector) return null;
1242
+ return (_b = REVERT_SELECTOR_MESSAGES[selector]) != null ? _b : null;
1243
+ }
1244
+ var ALCHEMY_SPONSORSHIP_POLICY_PATTERN = /\b(SPONSORSHIP_FAILED|sponsorship.*(quota|cap|exhausted|disabled)|policy.*(disabled|not found|exhausted))\b/i;
1245
+ var ALCHEMY_POLICY_MAX_COUNT_PATTERN = /\bSponsorship failed: Policy (max count|count) exceeded\b/i;
1246
+ var VENUE_TERMINATED_STATUS_PATTERN = /\bterminated with status=(\w+)/i;
1247
+ var friendlyTerminatedStatusMessage = (status) => {
1248
+ const normalized = status.toLowerCase();
1249
+ if (normalized === "cancelled" || normalized === "canceled") {
1250
+ return "Your order was canceled before it could fill \u2014 the price level moved between quote and submission. Please try again.";
1251
+ }
1252
+ if (normalized === "expired") {
1253
+ return "Your order expired before it could fill. Please try again.";
1254
+ }
1255
+ if (normalized === "rejected") {
1256
+ return "The venue rejected your order. Please try again.";
1257
+ }
1258
+ return "Your order did not fill. Please try again.";
1259
+ };
1200
1260
  var tryParseJsonErrorValue = (value) => {
1201
1261
  try {
1202
1262
  return JSON.parse(value);
@@ -1226,13 +1286,35 @@ var extractPlaceOrderErrorMessage = (value) => {
1226
1286
  };
1227
1287
  var normalizePlaceOrderErrorMessage = ({
1228
1288
  errorMessage,
1229
- fallbackMessage
1289
+ fallbackMessage,
1290
+ labels
1230
1291
  }) => {
1292
+ var _a, _b;
1231
1293
  const extractedMessage = extractPlaceOrderErrorMessage(errorMessage);
1232
1294
  if (!extractedMessage) return fallbackMessage;
1233
- if (ALCHEMY_SPONSORSHIP_ERROR_PATTERN.test(extractedMessage) || ALCHEMY_PREPARE_CALLS_ERROR_PATTERN.test(extractedMessage)) {
1295
+ if (DAG_CHECK_BALANCE_SHORTFALL_PATTERN.test(extractedMessage)) {
1296
+ return (_a = labels == null ? void 0 : labels.quoteBalanceMismatch) != null ? _a : "Quote balance mismatch. Try a different amount.";
1297
+ }
1298
+ if (ALCHEMY_BALANCE_REVERT_PATTERN.test(extractedMessage)) {
1299
+ return "Your balance changed since the quote. Please refresh and try again.";
1300
+ }
1301
+ const selectorMessage = lookupRevertSelectorMessage(extractedMessage);
1302
+ if (selectorMessage) {
1303
+ return selectorMessage;
1304
+ }
1305
+ if (ALCHEMY_POLICY_MAX_COUNT_PATTERN.test(extractedMessage)) {
1306
+ return "Sponsored execution is temporarily unavailable (sponsor policy capacity reached). Please try again in a few minutes.";
1307
+ }
1308
+ if (ALCHEMY_SPONSORSHIP_POLICY_PATTERN.test(extractedMessage) || ALCHEMY_SPONSORSHIP_ERROR_PATTERN.test(extractedMessage)) {
1234
1309
  return "Sponsored execution is temporarily unavailable. Please try again.";
1235
1310
  }
1311
+ if (ALCHEMY_PREPARE_CALLS_ERROR_PATTERN.test(extractedMessage)) {
1312
+ return "Sponsored execution is temporarily unavailable. Please try again.";
1313
+ }
1314
+ const terminatedMatch = extractedMessage.match(VENUE_TERMINATED_STATUS_PATTERN);
1315
+ if (terminatedMatch) {
1316
+ return friendlyTerminatedStatusMessage((_b = terminatedMatch[1]) != null ? _b : "");
1317
+ }
1236
1318
  return extractedMessage;
1237
1319
  };
1238
1320
  var resolvePlaceOrderFailureKind = ({
@@ -1360,14 +1442,84 @@ var resolvePlaceOrderFailureActions = ({
1360
1442
  }
1361
1443
  ];
1362
1444
  };
1445
+ var resolveEventExecutionPrice = ({
1446
+ event,
1447
+ quoteData,
1448
+ submittedOrders
1449
+ }) => {
1450
+ var _a, _b, _c, _d, _e;
1451
+ const quoteVwap = quoteData && quoteData.totalFilled > 0 ? quoteData.rawExecCost / quoteData.totalFilled : 0;
1452
+ return (_e = (_d = (_b = parseDecimalString(event.executionPriceRaw)) != null ? _b : (_a = submittedOrders == null ? void 0 : submittedOrders.find((order) => order.orderId === event.orderId)) == null ? void 0 : _a.price) != null ? _d : (_c = quoteData == null ? void 0 : quoteData.fills.find((fill) => fill.venue === event.venue)) == null ? void 0 : _c.avgPrice) != null ? _e : quoteVwap > 0 ? quoteVwap : null;
1453
+ };
1454
+ var resolveActualExecutionEconomics = ({
1455
+ quoteData,
1456
+ tradeSide,
1457
+ terminalOrderEvents,
1458
+ submittedOrders
1459
+ }) => {
1460
+ var _a, _b;
1461
+ const fillEvents = (terminalOrderEvents != null ? terminalOrderEvents : []).filter(
1462
+ (event) => event.event === "filled" || event.event === "partial_fill"
1463
+ );
1464
+ const quoteVwap = quoteData && quoteData.totalFilled > 0 ? quoteData.rawExecCost / quoteData.totalFilled : 0;
1465
+ const hasActualFillData = fillEvents.some(
1466
+ (event) => event.filledAmountRaw != null || event.actualSharesRaw != null
1467
+ );
1468
+ if (!hasActualFillData) {
1469
+ return {
1470
+ hasActualFillData: false,
1471
+ actualRawExecCost: (_a = quoteData == null ? void 0 : quoteData.rawExecCost) != null ? _a : 0,
1472
+ actualTotalFilled: (_b = quoteData == null ? void 0 : quoteData.totalFilled) != null ? _b : 0,
1473
+ avgExecutionPrice: quoteVwap
1474
+ };
1475
+ }
1476
+ let usdSideTotal = 0;
1477
+ let sharesSideTotal = 0;
1478
+ let priceWeight = 0;
1479
+ let priceWeightedSum = 0;
1480
+ for (const event of fillEvents) {
1481
+ const eventPrice = resolveEventExecutionPrice({ event, quoteData, submittedOrders });
1482
+ if (tradeSide === "buy") {
1483
+ const filledUsd = parseFilledAmountRawDollars(event.filledAmountRaw);
1484
+ if (filledUsd == null) continue;
1485
+ const actualShares = parseFilledAmountRawDollars(event.actualSharesRaw);
1486
+ const shares = actualShares != null ? actualShares : eventPrice != null && eventPrice > 0 ? filledUsd / eventPrice : 0;
1487
+ usdSideTotal += filledUsd;
1488
+ sharesSideTotal += shares;
1489
+ if (filledUsd > 0 && eventPrice != null && eventPrice > 0) {
1490
+ priceWeight += filledUsd;
1491
+ priceWeightedSum += eventPrice * filledUsd;
1492
+ }
1493
+ } else {
1494
+ const shares = parseFilledAmountRawDollars(event.actualSharesRaw);
1495
+ if (shares == null) continue;
1496
+ const payout = eventPrice != null && eventPrice > 0 ? shares * eventPrice : 0;
1497
+ sharesSideTotal += shares;
1498
+ usdSideTotal += payout;
1499
+ if (shares > 0 && eventPrice != null && eventPrice > 0) {
1500
+ priceWeight += shares;
1501
+ priceWeightedSum += eventPrice * shares;
1502
+ }
1503
+ }
1504
+ }
1505
+ const avgExecutionPrice = priceWeight > 0 ? priceWeightedSum / priceWeight : sharesSideTotal > 0 && usdSideTotal > 0 ? usdSideTotal / sharesSideTotal : quoteVwap;
1506
+ return {
1507
+ hasActualFillData: true,
1508
+ actualRawExecCost: usdSideTotal,
1509
+ actualTotalFilled: sharesSideTotal,
1510
+ avgExecutionPrice
1511
+ };
1512
+ };
1363
1513
  var getPlaceOrderUnfilledRemaining = ({
1364
1514
  originalAmount,
1515
+ tradeSide,
1365
1516
  terminalOrderEvents
1366
1517
  }) => {
1367
1518
  const filled = (terminalOrderEvents != null ? terminalOrderEvents : []).reduce((acc, event) => {
1368
1519
  var _a;
1369
1520
  if (event.event !== "filled" && event.event !== "partial_fill") return acc;
1370
- return acc + ((_a = parseFilledAmountRawDollars(event.filledAmountRaw)) != null ? _a : 0);
1521
+ const raw = tradeSide === "buy" ? event.filledAmountRaw : event.actualSharesRaw;
1522
+ return acc + ((_a = parseFilledAmountRawDollars(raw)) != null ? _a : 0);
1371
1523
  }, 0);
1372
1524
  return Math.max(0, originalAmount - filled);
1373
1525
  };
@@ -1387,7 +1539,8 @@ var buildPlaceOrderFailureSummary = ({
1387
1539
  var _a;
1388
1540
  const normalizedErrorMessage = normalizePlaceOrderErrorMessage({
1389
1541
  errorMessage,
1390
- fallbackMessage: labels.orderFailed
1542
+ fallbackMessage: labels.orderFailed,
1543
+ labels
1391
1544
  });
1392
1545
  const submittedOrderId = resolvePrimarySubmittedOrderId({
1393
1546
  orderId,
@@ -1471,7 +1624,8 @@ var buildPlaceOrderFailureSummary = ({
1471
1624
  const perEventKind = resolvePlaceOrderFailureKind({
1472
1625
  errorMessage: normalizePlaceOrderErrorMessage({
1473
1626
  errorMessage: terminalEvent.errorReason,
1474
- fallbackMessage: labels.orderFailed
1627
+ fallbackMessage: labels.orderFailed,
1628
+ labels
1475
1629
  }),
1476
1630
  terminalEvent
1477
1631
  });
@@ -1878,6 +2032,14 @@ var resolveRefetchedQuoteData = (result) => {
1878
2032
  if (!data || typeof data !== "object" || !("quoteId" in data)) return null;
1879
2033
  return data;
1880
2034
  };
2035
+ var isFillRejection400 = (err) => {
2036
+ var _a;
2037
+ if (!err || typeof err !== "object") return false;
2038
+ const direct = err.status;
2039
+ if (direct === 400) return true;
2040
+ const nested = (_a = err.response) == null ? void 0 : _a.status;
2041
+ return nested === 400;
2042
+ };
1881
2043
  var LoadingGlyph = ({
1882
2044
  className,
1883
2045
  enableAnimations
@@ -2117,7 +2279,7 @@ var PlaceOrderSlippageControl = ({
2117
2279
  {
2118
2280
  name: "warning-filled",
2119
2281
  size: "small",
2120
- className: "mt-0.5 !h-4 !w-4 shrink-0 text-agg-warning",
2282
+ className: "mt-0.5 h-4! w-4! shrink-0 text-agg-warning",
2121
2283
  color: "currentColor"
2122
2284
  }
2123
2285
  ),
@@ -2263,7 +2425,7 @@ var renderRouteBreakdownRow = (row) => {
2263
2425
  className: "agg-route-breakdown-row flex items-center justify-between gap-4 text-left",
2264
2426
  children: [
2265
2427
  /* @__PURE__ */ jsxs3("div", { className: "agg-route-breakdown-market flex min-w-0 items-center gap-2", children: [
2266
- /* @__PURE__ */ jsx4(VenueLogo, { venue: row.venue, className: "!size-3", ariaLabel: venueLabel }),
2428
+ /* @__PURE__ */ jsx4(VenueLogo, { venue: row.venue, className: "size-3!", ariaLabel: venueLabel }),
2267
2429
  /* @__PURE__ */ jsx4("p", { className: "agg-route-breakdown-label truncate text-agg-sm leading-agg-5 text-agg-foreground", children: row.label })
2268
2430
  ] }),
2269
2431
  /* @__PURE__ */ jsxs3("div", { className: "agg-route-breakdown-value flex shrink-0 items-center gap-2 text-agg-sm leading-agg-5", children: [
@@ -2302,7 +2464,7 @@ var renderRouteCard = ({
2302
2464
  "transition-[background-color,border-color,color] duration-200 ease-in-out"
2303
2465
  ),
2304
2466
  card.isUnavailable ? "cursor-not-allowed" : "cursor-pointer",
2305
- isSelected && !card.isUnavailable ? "border border-agg-trade-highlight-border bg-gradient-to-b from-agg-trade-highlight-surface-from to-agg-trade-highlight-surface-to" : "border-transparent bg-agg-secondary-hover"
2467
+ isSelected && !card.isUnavailable ? "border border-agg-trade-highlight-border bg-linear-to-b from-agg-trade-highlight-surface-from to-agg-trade-highlight-surface-to" : "border-transparent bg-agg-secondary-hover"
2306
2468
  ),
2307
2469
  onClick: () => onSelect(card.id),
2308
2470
  children: /* @__PURE__ */ jsxs3("div", { className: "agg-route-card-content relative z-10 flex flex-col gap-3", children: [
@@ -2584,9 +2746,10 @@ var PlaceOrder = ({
2584
2746
  onSuccess,
2585
2747
  onError,
2586
2748
  onExecutionStateChange,
2587
- resolvedClaim
2749
+ resolvedClaim,
2750
+ midpointsResult
2588
2751
  }) => {
2589
- 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;
2752
+ 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;
2590
2753
  const {
2591
2754
  enableDebug: isExecutionDebugEnabled,
2592
2755
  features: { enableAnimations, showFeesBreakdown },
@@ -2662,14 +2825,24 @@ var PlaceOrder = ({
2662
2825
  const livePrices = useLiveOutcomePrices(
2663
2826
  scopedSelectedMarket ? [scopedSelectedMarket] : void 0
2664
2827
  );
2665
- const midpointsClusterMarkets = useMemo2(() => {
2666
- if (!scopedSelectedMarket) return [];
2667
- return normalizeVenueMarketCluster(
2668
- resolvedEventTradingState.displayMarkets,
2669
- scopedSelectedMarket.id
2670
- );
2671
- }, [resolvedEventTradingState.displayMarkets, scopedSelectedMarket]);
2672
- const { prices: clusterMidpoints } = useMidpoints(midpointsClusterMarkets);
2828
+ const wsBestPrices = useLiveBestPrices(scopedSelectedMarket ? [scopedSelectedMarket] : void 0);
2829
+ const clusterMidpointResult = midpointsResult != null ? midpointsResult : {
2830
+ prices: /* @__PURE__ */ new Map(),
2831
+ bestMidpointsByOutcomeId: /* @__PURE__ */ new Map(),
2832
+ venueByOutcomeId: /* @__PURE__ */ new Map(),
2833
+ bestPrices: /* @__PURE__ */ new Map(),
2834
+ bestPriceVenuesByOutcomeId: /* @__PURE__ */ new Map(),
2835
+ isLoading: false,
2836
+ bestMidpoint: void 0,
2837
+ bestMidpointVenue: void 0
2838
+ };
2839
+ const clusterBestMidpointsByOutcomeId = (_i = clusterMidpointResult.bestMidpointsByOutcomeId) != null ? _i : clusterMidpointResult.prices;
2840
+ const clusterBestMidpoint = clusterMidpointResult.bestMidpoint;
2841
+ const clusterBestPricesRest = clusterMidpointResult.bestPrices;
2842
+ const clusterBestPrices = useMemo2(
2843
+ () => mergeBestPricesPreferringLive(clusterBestPricesRest, wsBestPrices),
2844
+ [clusterBestPricesRest, wsBestPrices]
2845
+ );
2673
2846
  const outcomes = useMemo2(
2674
2847
  () => mapVenueMarketOutcomesToPlaceOrderOutcomes(scopedSelectedMarket == null ? void 0 : scopedSelectedMarket.venueMarketOutcomes),
2675
2848
  [scopedSelectedMarket == null ? void 0 : scopedSelectedMarket.venueMarketOutcomes]
@@ -2687,6 +2860,7 @@ var PlaceOrder = ({
2687
2860
  const [submissionProgressState, setSubmissionProgressState] = useState3(null);
2688
2861
  const executionDebugStoreRef = useRef2(null);
2689
2862
  const executionDebugAttemptIdRef = useRef2(null);
2863
+ const submittedSelectionRef = useRef2(null);
2690
2864
  useEffect2(() => {
2691
2865
  if (!isExecutionDebugEnabled) {
2692
2866
  executionDebugStoreRef.current = null;
@@ -2762,15 +2936,16 @@ var PlaceOrder = ({
2762
2936
  isSell,
2763
2937
  scopedSelectedMarket,
2764
2938
  scopedSelectedOutcome,
2765
- (_j = (_i = smartRoute.data) == null ? void 0 : _i.positionAvailability) == null ? void 0 : _j.totalSellableShares
2939
+ (_k = (_j = smartRoute.data) == null ? void 0 : _j.positionAvailability) == null ? void 0 : _k.totalSellableShares
2766
2940
  ]);
2767
- const isCurrentSellableSharesLoading = isSell && isAuthenticated && !(typeof ((_l = (_k = smartRoute.data) == null ? void 0 : _k.positionAvailability) == null ? void 0 : _l.totalSellableShares) === "number") && (isExecutionPositionsLoading || isExecutionPositionsFetching);
2941
+ const isCurrentSellableSharesLoading = isSell && isAuthenticated && !(typeof ((_m = (_l = smartRoute.data) == null ? void 0 : _l.positionAvailability) == null ? void 0 : _m.totalSellableShares) === "number") && (isExecutionPositionsLoading || isExecutionPositionsFetching);
2768
2942
  const displayedCurrentSellableShares = useMemo2(() => {
2769
2943
  if (!Number.isFinite(currentSellableShares) || currentSellableShares <= 0) return 0;
2770
2944
  return Math.floor(currentSellableShares * 100) / 100;
2771
2945
  }, [currentSellableShares]);
2772
2946
  const isAtMaxSellableShares = isSell && displayedCurrentSellableShares > 0 && Math.abs(internalAmount - displayedCurrentSellableShares) < 1e-9;
2773
2947
  useEffect2(() => {
2948
+ if (submissionProgressState != null) return;
2774
2949
  if (!isSell || isCurrentSellableSharesLoading) return;
2775
2950
  if (scopedSelectedOutcomeId === sellFilledForOutcomeId) return;
2776
2951
  setInternalAmount(displayedCurrentSellableShares);
@@ -2782,7 +2957,8 @@ var PlaceOrder = ({
2782
2957
  scopedSelectedOutcomeId,
2783
2958
  sellFilledForOutcomeId,
2784
2959
  displayedCurrentSellableShares,
2785
- onAmountChange
2960
+ onAmountChange,
2961
+ submissionProgressState
2786
2962
  ]);
2787
2963
  const routeCards = useMemo2(
2788
2964
  () => smartRoute.data ? buildLiveRouteCards({
@@ -2812,12 +2988,16 @@ var PlaceOrder = ({
2812
2988
  setSelectedRouteCardId(resolvedSelectedRouteCardId);
2813
2989
  }
2814
2990
  }, [resolvedSelectedRouteCardId, routeCards.length, selectedRouteCardId]);
2991
+ const isSubmissionLocked = submissionProgressState != null;
2992
+ const isSubmissionLockedRef = useRef2(isSubmissionLocked);
2993
+ isSubmissionLockedRef.current = isSubmissionLocked;
2815
2994
  useEffect2(() => {
2995
+ if (isSubmissionLockedRef.current) return;
2816
2996
  setSubmissionFeedback(null);
2817
2997
  setSubmissionProgressState(null);
2818
2998
  }, [internalAmount, internalSlippage, internalTab, scopedSelectedOutcomeId]);
2819
2999
  const orderedRouteCards = routeCards;
2820
- const selectedRouteCard = (_n = (_m = orderedRouteCards.find((card) => card.id === resolvedSelectedRouteCardId)) != null ? _m : orderedRouteCards[0]) != null ? _n : null;
3000
+ const selectedRouteCard = (_o = (_n = orderedRouteCards.find((card) => card.id === resolvedSelectedRouteCardId)) != null ? _n : orderedRouteCards[0]) != null ? _o : null;
2821
3001
  const isKalshiRoute = useMemo2(() => {
2822
3002
  if (selectedRouteCard) {
2823
3003
  return selectedRouteCard.venue === "kalshi" || selectedRouteCard.quoteData.fills.some((f) => f.venue === "kalshi");
@@ -2841,7 +3021,7 @@ var PlaceOrder = ({
2841
3021
  } = useKalshiKycFlow({
2842
3022
  isKalshiVerified,
2843
3023
  userId: user == null ? void 0 : user.id,
2844
- walletAddress: (_o = getWalletAddressFromUserProfile(user)) != null ? _o : null,
3024
+ walletAddress: (_p = getWalletAddressFromUserProfile(user)) != null ? _p : null,
2845
3025
  onError
2846
3026
  });
2847
3027
  const handleRouteCardSelect = useCallback2(
@@ -2858,29 +3038,37 @@ var PlaceOrder = ({
2858
3038
  [resolvedSelectedRouteCardId, routeCards]
2859
3039
  );
2860
3040
  const executionProgress = useExecutionProgress({
2861
- orderIds: (_p = submissionProgressState == null ? void 0 : submissionProgressState.orderIds) != null ? _p : null,
2862
- enabled: ((submissionProgressState == null ? void 0 : submissionProgressState.phase) === "submitting" || (submissionProgressState == null ? void 0 : submissionProgressState.phase) === "executing") && !!((_q = submissionProgressState == null ? void 0 : submissionProgressState.orderIds) == null ? void 0 : _q.length)
3041
+ orderIds: (_q = submissionProgressState == null ? void 0 : submissionProgressState.orderIds) != null ? _q : null,
3042
+ enabled: ((submissionProgressState == null ? void 0 : submissionProgressState.phase) === "submitting" || (submissionProgressState == null ? void 0 : submissionProgressState.phase) === "executing") && !!((_r = submissionProgressState == null ? void 0 : submissionProgressState.orderIds) == null ? void 0 : _r.length)
2863
3043
  });
2864
- const selectedOutcomeLabel = (_t = (_s = (_r = outcomes.find((outcome) => outcome.id === scopedSelectedOutcomeId)) == null ? void 0 : _r.label) != null ? _s : scopedSelectedOutcome == null ? void 0 : scopedSelectedOutcome.label) != null ? _t : "";
2865
- const headerImage = (_v = (_u = scopedSelectedMarket == null ? void 0 : scopedSelectedMarket.image) != null ? _u : scopedSelectedEvent == null ? void 0 : scopedSelectedEvent.image) != null ? _v : null;
2866
- const headerTitle = (_x = (_w = scopedSelectedEvent == null ? void 0 : scopedSelectedEvent.title) != null ? _w : scopedSelectedMarket == null ? void 0 : scopedSelectedMarket.question) != null ? _x : "";
2867
- const headerSubtitle = (_y = scopedSelectedMarket == null ? void 0 : scopedSelectedMarket.question) != null ? _y : "";
3044
+ const selectedOutcomeLabel = (_u = (_t = (_s = outcomes.find((outcome) => outcome.id === scopedSelectedOutcomeId)) == null ? void 0 : _s.label) != null ? _t : scopedSelectedOutcome == null ? void 0 : scopedSelectedOutcome.label) != null ? _u : "";
3045
+ const headerImage = (_w = (_v = scopedSelectedMarket == null ? void 0 : scopedSelectedMarket.image) != null ? _v : scopedSelectedEvent == null ? void 0 : scopedSelectedEvent.image) != null ? _w : null;
3046
+ const headerTitle = (_y = (_x = scopedSelectedEvent == null ? void 0 : scopedSelectedEvent.title) != null ? _x : scopedSelectedMarket == null ? void 0 : scopedSelectedMarket.question) != null ? _y : "";
3047
+ const headerSubtitle = (_z = scopedSelectedMarket == null ? void 0 : scopedSelectedMarket.question) != null ? _z : "";
2868
3048
  const buildExecutionSummary = useCallback2(
2869
3049
  (quoteData, executionVenue, orderId, partialFillSummary) => {
2870
3050
  var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2;
2871
3051
  if (!quoteData) return void 0;
2872
- const avgPriceValue = quoteData.totalFilled > 0 ? quoteData.rawExecCost / quoteData.totalFilled : 0;
2873
- const avgPriceLabel = quoteData.totalFilled > 0 ? getTradingRoutePriceLabel(avgPriceValue) : "\u2014";
2874
- const actionPriceLabel = quoteData.totalFilled > 0 ? `~${avgPriceLabel}` : avgPriceLabel;
3052
+ const actualEconomics = resolveActualExecutionEconomics({
3053
+ quoteData,
3054
+ tradeSide: internalTab,
3055
+ terminalOrderEvents: executionProgress.terminalOrderEvents,
3056
+ submittedOrders: executionProgress.submittedOrders
3057
+ });
3058
+ const usdSide = actualEconomics.hasActualFillData ? actualEconomics.actualRawExecCost : quoteData.rawExecCost;
3059
+ const sharesSide = actualEconomics.hasActualFillData ? actualEconomics.actualTotalFilled : quoteData.totalFilled;
3060
+ const avgPriceValue = actualEconomics.hasActualFillData ? actualEconomics.avgExecutionPrice : quoteData.totalFilled > 0 ? quoteData.rawExecCost / quoteData.totalFilled : 0;
3061
+ const avgPriceLabel = avgPriceValue > 0 ? getTradingRoutePriceLabel(avgPriceValue) : "\u2014";
3062
+ const actionPriceLabel = avgPriceValue > 0 ? `~${avgPriceLabel}` : avgPriceLabel;
2875
3063
  const actionLabel2 = internalTab === "buy" ? (_b2 = (_a2 = tradingLabels.boughtOutcomeAtPrice) == null ? void 0 : _a2.call(tradingLabels, selectedOutcomeLabel, actionPriceLabel)) != null ? _b2 : `Bought ${selectedOutcomeLabel} at ${actionPriceLabel}` : (_d2 = (_c2 = tradingLabels.soldOutcomeAtPrice) == null ? void 0 : _c2.call(tradingLabels, selectedOutcomeLabel, actionPriceLabel)) != null ? _d2 : `Sold ${selectedOutcomeLabel} at ${actionPriceLabel}`;
2876
- const sharesLabel = quoteData.totalFilled.toLocaleString("en-US", {
3064
+ const sharesLabel = sharesSide.toLocaleString("en-US", {
2877
3065
  minimumFractionDigits: 2,
2878
3066
  maximumFractionDigits: 2
2879
3067
  });
2880
- const payoutLabel = formatUsd(quoteData.rawExecCost);
3068
+ const payoutLabel = formatUsd(usdSide);
2881
3069
  const amountLabel = internalTab === "sell" ? sharesLabel : payoutLabel;
2882
- const toWinLabel = internalTab === "sell" ? payoutLabel : formatUsd(quoteData.totalFilled);
2883
- const potentialReturnValue = getPlaceOrderPotentialReturn(quoteData);
3070
+ const toWinLabel = internalTab === "sell" ? payoutLabel : formatUsd(sharesSide);
3071
+ const potentialReturnValue = actualEconomics.hasActualFillData ? 0 : getPlaceOrderPotentialReturn(quoteData);
2884
3072
  const potentialReturnLabel = potentialReturnValue > 0 ? formatUsd(potentialReturnValue) : void 0;
2885
3073
  const eventTitle = (_f2 = (_e2 = scopedSelectedEvent == null ? void 0 : scopedSelectedEvent.title) != null ? _e2 : scopedSelectedMarket == null ? void 0 : scopedSelectedMarket.question) != null ? _f2 : "";
2886
3074
  const eventDateSource = (_g2 = scopedSelectedEvent == null ? void 0 : scopedSelectedEvent.endDate) != null ? _g2 : scopedSelectedMarket == null ? void 0 : scopedSelectedMarket.endDate;
@@ -2922,6 +3110,7 @@ var PlaceOrder = ({
2922
3110
  },
2923
3111
  [
2924
3112
  executionProgress.submittedOrders,
3113
+ executionProgress.terminalOrderEvents,
2925
3114
  headerImage,
2926
3115
  internalTab,
2927
3116
  scopedSelectedEvent == null ? void 0 : scopedSelectedEvent.endDate,
@@ -2944,26 +3133,7 @@ var PlaceOrder = ({
2944
3133
  });
2945
3134
  });
2946
3135
  }
2947
- if (executionProgress.phase === "balance_updated") {
2948
- setSubmissionProgressState((prev) => {
2949
- var _a2, _b2;
2950
- if (!prev || prev.phase !== "submitting" && prev.phase !== "executing") return prev;
2951
- return __spreadProps(__spreadValues({}, prev), {
2952
- phase: "success",
2953
- summary: buildExecutionSummary(
2954
- selectedRouteCard == null ? void 0 : selectedRouteCard.quoteData,
2955
- prev.executionVenue,
2956
- (_b2 = prev.orderId) != null ? _b2 : (_a2 = executionProgress.submittedOrders[0]) == null ? void 0 : _a2.orderId
2957
- )
2958
- });
2959
- });
2960
- }
2961
- }, [
2962
- buildExecutionSummary,
2963
- executionProgress.phase,
2964
- executionProgress.submittedOrders,
2965
- selectedRouteCard == null ? void 0 : selectedRouteCard.quoteData
2966
- ]);
3136
+ }, [executionProgress.phase, executionProgress.submittedOrders]);
2967
3137
  useEffect2(() => {
2968
3138
  var _a2, _b2;
2969
3139
  const dp = executionProgress.dagProgress;
@@ -3003,7 +3173,8 @@ var PlaceOrder = ({
3003
3173
  if (dp.status === "failed") {
3004
3174
  const errorMessage = normalizePlaceOrderErrorMessage({
3005
3175
  errorMessage: dp.errorReason,
3006
- fallbackMessage: tradingLabels.orderFailed
3176
+ fallbackMessage: tradingLabels.orderFailed,
3177
+ labels: tradingLabels
3007
3178
  });
3008
3179
  return __spreadProps(__spreadValues({}, prev), {
3009
3180
  phase: "failed",
@@ -3056,7 +3227,8 @@ var PlaceOrder = ({
3056
3227
  );
3057
3228
  const errorMessage = normalizePlaceOrderErrorMessage({
3058
3229
  errorMessage: firstFailedEvent == null ? void 0 : firstFailedEvent.errorReason,
3059
- fallbackMessage: tradingLabels.orderFailed
3230
+ fallbackMessage: tradingLabels.orderFailed,
3231
+ labels: tradingLabels
3060
3232
  });
3061
3233
  return __spreadProps(__spreadValues({}, prev), {
3062
3234
  phase: "failed",
@@ -3071,8 +3243,24 @@ var PlaceOrder = ({
3071
3243
  executionProgress.terminalOrderEvents,
3072
3244
  selectedRouteCard == null ? void 0 : selectedRouteCard.quoteData,
3073
3245
  submissionProgressState == null ? void 0 : submissionProgressState.orderIds,
3074
- tradingLabels.orderFailed
3246
+ tradingLabels
3075
3247
  ]);
3248
+ const estDurationMs = (selectedRouteCard == null ? void 0 : selectedRouteCard.quoteData) && typeof selectedRouteCard.quoteData.estDurationMs === "number" ? selectedRouteCard.quoteData.estDurationMs : 6e4;
3249
+ useEffect2(() => {
3250
+ const phase = submissionProgressState == null ? void 0 : submissionProgressState.phase;
3251
+ if (phase !== "submitting" && phase !== "executing") return;
3252
+ const timeoutMs = Math.max(6e4, 2 * estDurationMs);
3253
+ const id = setTimeout(() => {
3254
+ setSubmissionProgressState((prev) => {
3255
+ if (!prev || prev.phase === "success" || prev.phase === "failed") return prev;
3256
+ return __spreadProps(__spreadValues({}, prev), {
3257
+ phase: "failed",
3258
+ errorMessage: "Couldn't confirm the order in time. Your trade may still complete in the background \u2014 check your activity feed."
3259
+ });
3260
+ });
3261
+ }, timeoutMs);
3262
+ return () => clearTimeout(id);
3263
+ }, [submissionProgressState == null ? void 0 : submissionProgressState.phase, estDurationMs]);
3076
3264
  useEffect2(() => {
3077
3265
  var _a2, _b2;
3078
3266
  if (!submissionProgressState) return;
@@ -3116,7 +3304,7 @@ var PlaceOrder = ({
3116
3304
  onError == null ? void 0 : onError(new Error(submissionProgressState.errorMessage));
3117
3305
  }
3118
3306
  }, [submissionProgressState, onExecutionStateChange, onSuccess, onError, queryClient]);
3119
- const activeQuoteData = (_A = (_z = selectedRouteCard == null ? void 0 : selectedRouteCard.quoteData) != null ? _z : smartRoute.data) != null ? _A : null;
3307
+ const activeQuoteData = (_B = (_A = selectedRouteCard == null ? void 0 : selectedRouteCard.quoteData) != null ? _A : smartRoute.data) != null ? _B : null;
3120
3308
  const visibleRouteCards = orderedRouteCards.length > PLACE_ORDER_ROUTE_COLLAPSED_CARD_COUNT && !isRoutesExpanded ? orderedRouteCards.slice(0, PLACE_ORDER_ROUTE_COLLAPSED_CARD_COUNT) : orderedRouteCards;
3121
3309
  const hasEnteredAmount = internalAmount > 0;
3122
3310
  const isInsufficientBalance = !isSell && isAuthenticated && hasEnteredAmount && !isBalanceLoading && internalAmount > totalBalance;
@@ -3140,29 +3328,32 @@ var PlaceOrder = ({
3140
3328
  if (!smartRoute.error) return null;
3141
3329
  return normalizePlaceOrderErrorMessage({
3142
3330
  errorMessage: smartRoute.error.message,
3143
- fallbackMessage: tradingLabels.quoteUnavailable
3331
+ fallbackMessage: tradingLabels.quoteUnavailable,
3332
+ labels: tradingLabels
3144
3333
  });
3145
- }, [smartRoute.error, tradingLabels.quoteUnavailable]);
3334
+ }, [smartRoute.error, tradingLabels]);
3146
3335
  const progressActionLabel = (internalTab === "buy" ? tradingLabels.buyingOutcome(selectedOutcomeLabel) : tradingLabels.sellingOutcome(selectedOutcomeLabel)).trim();
3147
3336
  const canRetryRemaining = useMemo2(() => {
3148
3337
  const remaining = getPlaceOrderUnfilledRemaining({
3149
3338
  originalAmount: internalAmount,
3339
+ tradeSide: internalTab,
3150
3340
  terminalOrderEvents: executionProgress.terminalOrderEvents
3151
3341
  });
3152
3342
  const minRemainder = isSell ? MIN_SELL_ORDER_SHARES : MIN_BUY_ORDER_AMOUNT;
3153
3343
  return remaining >= minRemainder;
3154
- }, [executionProgress.terminalOrderEvents, internalAmount, isSell]);
3344
+ }, [executionProgress.terminalOrderEvents, internalAmount, internalTab, isSell]);
3155
3345
  const PARTIAL_FILL_AUTO_SUCCESS_THRESHOLD = 0.95;
3156
3346
  const shouldAutoSkipPartialFill = useMemo2(() => {
3157
3347
  if (internalAmount <= 0) return false;
3158
3348
  const remaining = getPlaceOrderUnfilledRemaining({
3159
3349
  originalAmount: internalAmount,
3350
+ tradeSide: internalTab,
3160
3351
  terminalOrderEvents: executionProgress.terminalOrderEvents
3161
3352
  });
3162
3353
  const filled = Math.max(0, internalAmount - remaining);
3163
3354
  const fillRatio = filled / internalAmount;
3164
3355
  return fillRatio >= PARTIAL_FILL_AUTO_SUCCESS_THRESHOLD || !canRetryRemaining;
3165
- }, [canRetryRemaining, executionProgress.terminalOrderEvents, internalAmount]);
3356
+ }, [canRetryRemaining, executionProgress.terminalOrderEvents, internalAmount, internalTab]);
3166
3357
  const failureSummary = useMemo2(() => {
3167
3358
  var _a2;
3168
3359
  if ((submissionProgressState == null ? void 0 : submissionProgressState.phase) !== "failed") return void 0;
@@ -3201,7 +3392,7 @@ var PlaceOrder = ({
3201
3392
  }
3202
3393
  return (_d2 = selectedRouteCard.hint) != null ? _d2 : "";
3203
3394
  }, [selectedRouteCard, tradingLabels]);
3204
- const displayedToWinValue = (_B = selectedRouteCard == null ? void 0 : selectedRouteCard.numericValue) != null ? _B : 0;
3395
+ const displayedToWinValue = (_C = selectedRouteCard == null ? void 0 : selectedRouteCard.numericValue) != null ? _C : 0;
3205
3396
  const activeFeeBreakdown = activeQuoteData == null ? void 0 : activeQuoteData.feeBreakdown;
3206
3397
  const estimatedFeesValue = useMemo2(() => {
3207
3398
  if (!activeFeeBreakdown) return null;
@@ -3242,13 +3433,13 @@ var PlaceOrder = ({
3242
3433
  ];
3243
3434
  }, [activeFeeBreakdown, tradingLabels]);
3244
3435
  const isActionLoading = isPrimaryActionLoading || executeManaged.isPending;
3245
- const selectedRouteGeoBlocked = (_C = selectedRouteCard == null ? void 0 : selectedRouteCard.isUnavailable) != null ? _C : false;
3436
+ const selectedRouteGeoBlocked = (_D = selectedRouteCard == null ? void 0 : selectedRouteCard.isUnavailable) != null ? _D : false;
3246
3437
  const geoBlockedVenuesFromWarnings = useMemo2(
3247
3438
  () => {
3248
3439
  var _a2;
3249
3440
  return extractGeoBlockedVenues((_a2 = smartRoute.data) == null ? void 0 : _a2.warnings);
3250
3441
  },
3251
- [(_D = smartRoute.data) == null ? void 0 : _D.warnings]
3442
+ [(_E = smartRoute.data) == null ? void 0 : _E.warnings]
3252
3443
  );
3253
3444
  const isPrimaryVenueGeoBlocked = useMemo2(() => {
3254
3445
  var _a2, _b2;
@@ -3262,18 +3453,26 @@ var PlaceOrder = ({
3262
3453
  const shouldShowSmartRouting = orderEligibility.canPlaceOrder && hasEnteredAmount && (orderedRouteCards.length > 0 || smartRoute.isFetching);
3263
3454
  const shouldShowRouteToggle = orderedRouteCards.length > PLACE_ORDER_ROUTE_COLLAPSED_CARD_COUNT;
3264
3455
  const handleStartNewTrade = useCallback2(() => {
3456
+ const submittedSelection = submittedSelectionRef.current;
3457
+ submittedSelectionRef.current = null;
3265
3458
  setSubmissionProgressState(null);
3266
3459
  setSubmissionFeedback(null);
3267
- setInternalAmount(0);
3460
+ setInternalAmount(PLACE_ORDER_DEFAULT_AMOUNT);
3268
3461
  setSellFilledForOutcomeId(null);
3269
3462
  setInternalSlippage(DEFAULT_SLIPPAGE_VALUE);
3270
3463
  setInternalTab("buy");
3464
+ tradingContext == null ? void 0 : tradingContext.setTradeSide(TradeSide.Buy);
3271
3465
  setIsRoutesExpanded(false);
3272
3466
  setSelectedRouteCardId(null);
3273
- onAmountChange == null ? void 0 : onAmountChange(0);
3467
+ onAmountChange == null ? void 0 : onAmountChange(PLACE_ORDER_DEFAULT_AMOUNT);
3274
3468
  onSlippageChange == null ? void 0 : onSlippageChange(formatPercentageValue(DEFAULT_SLIPPAGE_VALUE));
3275
3469
  onTabChange == null ? void 0 : onTabChange("buy");
3276
- if (scopedSelectedEvent) {
3470
+ if (submittedSelection && tradingContext) {
3471
+ tradingContext.selectMarketAndOutcome(
3472
+ submittedSelection.marketId,
3473
+ submittedSelection.outcomeId
3474
+ );
3475
+ } else if (scopedSelectedEvent) {
3277
3476
  tradingContext == null ? void 0 : tradingContext.initializeFromEvent(scopedSelectedEvent);
3278
3477
  }
3279
3478
  }, [onAmountChange, onSlippageChange, onTabChange, scopedSelectedEvent, tradingContext]);
@@ -3356,6 +3555,12 @@ var PlaceOrder = ({
3356
3555
  finalStatus: "failed"
3357
3556
  });
3358
3557
  }
3558
+ if (isFillRejection400(error)) {
3559
+ try {
3560
+ yield smartRoute.refetch();
3561
+ } catch (e) {
3562
+ }
3563
+ }
3359
3564
  throw error;
3360
3565
  }
3361
3566
  }),
@@ -3368,7 +3573,7 @@ var PlaceOrder = ({
3368
3573
  scopedSelectedEvent == null ? void 0 : scopedSelectedEvent.id,
3369
3574
  scopedSelectedMarket == null ? void 0 : scopedSelectedMarket.id,
3370
3575
  scopedSelectedOutcomeId,
3371
- smartRoute.data,
3576
+ smartRoute,
3372
3577
  tradingLabels.quoteUnavailable
3373
3578
  ]
3374
3579
  );
@@ -3420,6 +3625,7 @@ var PlaceOrder = ({
3420
3625
  if ((failureSummary == null ? void 0 : failureSummary.kind) === "partial_fill" && internalAmount > 0) {
3421
3626
  const remaining = getPlaceOrderUnfilledRemaining({
3422
3627
  originalAmount: internalAmount,
3628
+ tradeSide: internalTab,
3423
3629
  terminalOrderEvents: executionProgress.terminalOrderEvents
3424
3630
  });
3425
3631
  if (remaining > 0) {
@@ -3468,7 +3674,8 @@ var PlaceOrder = ({
3468
3674
  } catch (error) {
3469
3675
  const errorMessage = normalizePlaceOrderErrorMessage({
3470
3676
  errorMessage: error instanceof Error ? error.message : String(error),
3471
- fallbackMessage: tradingLabels.orderFailed
3677
+ fallbackMessage: tradingLabels.orderFailed,
3678
+ labels: tradingLabels
3472
3679
  });
3473
3680
  setSubmissionProgressState({
3474
3681
  phase: "failed",
@@ -3546,6 +3753,7 @@ var PlaceOrder = ({
3546
3753
  const handleTabChange = (nextTab) => {
3547
3754
  if (!orderEligibility.canPlaceOrder) return;
3548
3755
  setInternalTab(nextTab);
3756
+ tradingContext == null ? void 0 : tradingContext.setTradeSide(nextTab);
3549
3757
  if (nextTab === "sell") {
3550
3758
  setInternalAmount(0);
3551
3759
  setSellFilledForOutcomeId(null);
@@ -3601,13 +3809,20 @@ var PlaceOrder = ({
3601
3809
  }
3602
3810
  if (!selectedRouteCard) return;
3603
3811
  setSubmissionFeedback(null);
3812
+ if (scopedSelectedMarket && scopedSelectedOutcomeId) {
3813
+ submittedSelectionRef.current = {
3814
+ marketId: scopedSelectedMarket.id,
3815
+ outcomeId: scopedSelectedOutcomeId
3816
+ };
3817
+ }
3604
3818
  try {
3605
3819
  setSubmissionProgressState({ phase: "finding-route" });
3606
3820
  yield handleExecuteQuote(selectedRouteCard.quoteData);
3607
3821
  } catch (error) {
3608
3822
  const errorMessage = normalizePlaceOrderErrorMessage({
3609
3823
  errorMessage: error instanceof Error ? error.message : String(error),
3610
- fallbackMessage: tradingLabels.orderFailed
3824
+ fallbackMessage: tradingLabels.orderFailed,
3825
+ labels: tradingLabels
3611
3826
  });
3612
3827
  setSubmissionProgressState({
3613
3828
  phase: "failed",
@@ -3704,10 +3919,18 @@ var PlaceOrder = ({
3704
3919
  ),
3705
3920
  outcomes.length >= 2 ? /* @__PURE__ */ jsx4("div", { className: "agg-outcomes flex w-full max-w-full gap-2", children: outcomes.map((outcome, index) => {
3706
3921
  var _a2, _b2, _c2;
3707
- const price = (_b2 = (_a2 = clusterMidpoints.get(outcome.id)) != null ? _a2 : livePrices.get(outcome.id)) != null ? _b2 : outcome.price;
3922
+ const price = getDisplayOutcomePrice({
3923
+ outcomeId: outcome.id,
3924
+ outcomeLabel: outcome.label,
3925
+ selection: (_a2 = tradingContext == null ? void 0 : tradingContext.tradeSide) != null ? _a2 : isSell ? "sell" : "buy",
3926
+ bestPrices: clusterBestPrices,
3927
+ bestMidpoint: clusterBestMidpoint,
3928
+ bestMidpointsByOutcomeId: clusterBestMidpointsByOutcomeId,
3929
+ livePrices,
3930
+ fallbackPrice: outcome.price
3931
+ });
3708
3932
  const isActive = outcome.id === scopedSelectedOutcomeId;
3709
3933
  const isPositive = resolveIsPositiveOutcome(outcome, index);
3710
- const displayLabel = ((_c2 = outcome.title) == null ? void 0 : _c2.trim()) || outcome.label;
3711
3934
  return /* @__PURE__ */ jsxs3(
3712
3935
  "button",
3713
3936
  {
@@ -3724,7 +3947,7 @@ var PlaceOrder = ({
3724
3947
  "leading-agg-5! flex-1 min-w-0 gap-1 md:gap-2"
3725
3948
  ),
3726
3949
  "aria-pressed": isActive,
3727
- "aria-label": `${displayLabel} ${formatProbabilityCents(price)}`,
3950
+ "aria-label": `${(_b2 = outcome.title) != null ? _b2 : outcome.label} ${formatProbabilityCents(price)}`,
3728
3951
  disabled: !orderEligibility.canPlaceOrder || isResolvedOutcomeCtaLocked,
3729
3952
  onClick: () => handleOutcomeChange(outcome.id),
3730
3953
  children: [
@@ -3734,7 +3957,7 @@ var PlaceOrder = ({
3734
3957
  as: "span",
3735
3958
  variant: isActive ? "body-strong" : "body",
3736
3959
  className: cn("whitespace-nowrap truncate"),
3737
- children: displayLabel
3960
+ children: (_c2 = outcome.title) != null ? _c2 : outcome.label
3738
3961
  }
3739
3962
  ),
3740
3963
  /* @__PURE__ */ jsx4(Typography, { as: "span", variant: isActive ? "body-strong" : "body", children: formatProbabilityCents(price) })