@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.
- package/dist/{chunk-PFOSEY46.mjs → chunk-3ZSNHGAB.mjs} +835 -401
- package/dist/{chunk-5PSAIGOT.mjs → chunk-54PCEK6G.mjs} +137 -61
- package/dist/{chunk-7JKGAWU5.mjs → chunk-ENAGASVU.mjs} +1538 -1369
- package/dist/{chunk-K23CJ5UP.mjs → chunk-J7K2U44E.mjs} +481 -258
- package/dist/{chunk-5MDFM2MX.mjs → chunk-NWJHFGBZ.mjs} +1 -1
- package/dist/{chunk-QFW5NDJ6.mjs → chunk-SJLHOAKK.mjs} +1001 -1015
- package/dist/{chunk-PYKD4W4T.mjs → chunk-YP75TIY6.mjs} +601 -326
- package/dist/events.js +2038 -1559
- package/dist/events.mjs +3 -3
- package/dist/index.js +5417 -4261
- package/dist/index.mjs +56 -50
- package/dist/modals.js +3262 -2384
- package/dist/modals.mjs +3 -3
- package/dist/pages.js +3677 -2709
- package/dist/pages.mjs +6 -6
- package/dist/primitives.js +992 -918
- package/dist/primitives.mjs +5 -1
- package/dist/styles.css +1 -1
- package/dist/tailwind.css +1 -1
- package/dist/trading.js +1360 -1129
- package/dist/trading.mjs +4 -4
- package/dist/types/deposit/deposit-modal.types.d.mts +10 -1
- package/dist/types/deposit/deposit-modal.types.d.ts +10 -1
- package/dist/types/deposit/index.d.mts +1 -1
- package/dist/types/deposit/index.d.ts +1 -1
- package/dist/types/deposit/steps/crypto-transfer.d.mts +1 -2
- package/dist/types/deposit/steps/crypto-transfer.d.ts +1 -2
- package/dist/types/deposit/steps/deposit-method.d.mts +2 -1
- package/dist/types/deposit/steps/deposit-method.d.ts +2 -1
- package/dist/types/events/item/event-list-item.types.d.mts +3 -1
- package/dist/types/events/item/event-list-item.types.d.ts +3 -1
- package/dist/types/events/item/event-list-item.utils.d.mts +26 -2
- package/dist/types/events/item/event-list-item.utils.d.ts +26 -2
- package/dist/types/events/item-details/event-list-item-details.types.d.mts +30 -1
- package/dist/types/events/item-details/event-list-item-details.types.d.ts +30 -1
- package/dist/types/events/market-details/index.d.mts +1 -1
- package/dist/types/events/market-details/index.d.ts +1 -1
- package/dist/types/events/market-details/market-details.types.d.mts +27 -2
- package/dist/types/events/market-details/market-details.types.d.ts +27 -2
- package/dist/types/events/market-details/market-details.utils.d.mts +18 -4
- package/dist/types/events/market-details/market-details.utils.d.ts +18 -4
- package/dist/types/events/market-details/orderbook-aggregation.d.mts +38 -2
- package/dist/types/events/market-details/orderbook-aggregation.d.ts +38 -2
- package/dist/types/events/shared/chart-auto-fallback.d.mts +43 -0
- package/dist/types/events/shared/chart-auto-fallback.d.ts +43 -0
- package/dist/types/events/shared/display-outcome-price.d.mts +14 -0
- package/dist/types/events/shared/display-outcome-price.d.ts +14 -0
- package/dist/types/events/shared/display-outcome-venue.d.mts +30 -0
- package/dist/types/events/shared/display-outcome-venue.d.ts +30 -0
- package/dist/types/events/shared/display-reference-price.d.mts +4 -0
- package/dist/types/events/shared/display-reference-price.d.ts +4 -0
- package/dist/types/events/shared/select-outcome-price.d.mts +21 -0
- package/dist/types/events/shared/select-outcome-price.d.ts +21 -0
- package/dist/types/pages/user-profile/components/available-balance-card.d.mts +2 -1
- package/dist/types/pages/user-profile/components/available-balance-card.d.ts +2 -1
- package/dist/types/pages/user-profile/components/positions-value-card.d.mts +2 -1
- package/dist/types/pages/user-profile/components/positions-value-card.d.ts +2 -1
- package/dist/types/pages/user-profile/index.d.mts +2 -2
- package/dist/types/pages/user-profile/index.d.ts +2 -2
- package/dist/types/pages/user-profile/user-profile.types.d.mts +54 -1
- package/dist/types/pages/user-profile/user-profile.types.d.ts +54 -1
- package/dist/types/primitives/chart/chart.utils.d.mts +9 -10
- package/dist/types/primitives/chart/chart.utils.d.ts +9 -10
- package/dist/types/primitives/icon/index.d.mts +2 -1
- package/dist/types/primitives/icon/index.d.ts +2 -1
- package/dist/types/primitives/icon/registry.d.mts +8 -0
- package/dist/types/primitives/icon/registry.d.ts +8 -0
- package/dist/types/primitives/icon/svg/circle-xmark.d.mts +5 -0
- package/dist/types/primitives/icon/svg/circle-xmark.d.ts +5 -0
- package/dist/types/primitives/icon/svg/spinner.d.mts +5 -0
- package/dist/types/primitives/icon/svg/spinner.d.ts +5 -0
- package/dist/types/primitives/toast/index.d.mts +2 -0
- package/dist/types/primitives/toast/index.d.ts +2 -0
- package/dist/types/primitives/tooltip/tooltip.types.d.mts +1 -0
- package/dist/types/primitives/tooltip/tooltip.types.d.ts +1 -0
- package/dist/types/primitives/typography/index.d.mts +1 -1
- package/dist/types/primitives/typography/index.d.ts +1 -1
- package/dist/types/primitives/typography/typography.types.d.mts +2 -0
- package/dist/types/primitives/typography/typography.types.d.ts +2 -0
- package/dist/types/shared/transfer-fee-summary.d.mts +10 -0
- package/dist/types/shared/transfer-fee-summary.d.ts +10 -0
- package/dist/types/shared/utils.d.mts +3 -0
- package/dist/types/shared/utils.d.ts +3 -0
- package/dist/types/trading/place-order/index.d.mts +1 -1
- package/dist/types/trading/place-order/index.d.ts +1 -1
- package/dist/types/trading/place-order/index.place-order.execution-steps.d.mts +9 -0
- package/dist/types/trading/place-order/index.place-order.execution-steps.d.ts +9 -0
- package/dist/types/trading/place-order/index.place-order.types.d.mts +15 -2
- package/dist/types/trading/place-order/index.place-order.types.d.ts +15 -2
- package/dist/types/trading/place-order/index.place-order.utils.d.mts +49 -6
- package/dist/types/trading/place-order/index.place-order.utils.d.ts +49 -6
- package/dist/types/withdraw/index.d.mts +1 -1
- package/dist/types/withdraw/index.d.ts +1 -1
- package/dist/types/withdraw/steps/withdraw-success.d.mts +13 -7
- package/dist/types/withdraw/steps/withdraw-success.d.ts +13 -7
- package/dist/types/withdraw/steps/withdraw-success.utils.d.mts +2 -0
- package/dist/types/withdraw/steps/withdraw-success.utils.d.ts +2 -0
- package/dist/types/withdraw/withdraw-modal.types.d.mts +5 -0
- package/dist/types/withdraw/withdraw-modal.types.d.ts +5 -0
- 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-
|
|
11
|
+
} from "./chunk-54PCEK6G.mjs";
|
|
11
12
|
import {
|
|
12
13
|
GeoBlockBanner
|
|
13
|
-
} from "./chunk-
|
|
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-
|
|
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 /
|
|
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:
|
|
903
|
-
label:
|
|
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:
|
|
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 (
|
|
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
|
-
|
|
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
|
|
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: "
|
|
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-
|
|
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
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
)
|
|
2671
|
-
|
|
2672
|
-
|
|
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
|
-
(
|
|
2939
|
+
(_k = (_j = smartRoute.data) == null ? void 0 : _j.positionAvailability) == null ? void 0 : _k.totalSellableShares
|
|
2766
2940
|
]);
|
|
2767
|
-
const isCurrentSellableSharesLoading = isSell && isAuthenticated && !(typeof ((
|
|
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 = (
|
|
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: (
|
|
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: (
|
|
2862
|
-
enabled: ((submissionProgressState == null ? void 0 : submissionProgressState.phase) === "submitting" || (submissionProgressState == null ? void 0 : submissionProgressState.phase) === "executing") && !!((
|
|
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 = (
|
|
2865
|
-
const headerImage = (
|
|
2866
|
-
const headerTitle = (
|
|
2867
|
-
const headerSubtitle = (
|
|
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
|
|
2873
|
-
|
|
2874
|
-
|
|
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 =
|
|
3064
|
+
const sharesLabel = sharesSide.toLocaleString("en-US", {
|
|
2877
3065
|
minimumFractionDigits: 2,
|
|
2878
3066
|
maximumFractionDigits: 2
|
|
2879
3067
|
});
|
|
2880
|
-
const payoutLabel = formatUsd(
|
|
3068
|
+
const payoutLabel = formatUsd(usdSide);
|
|
2881
3069
|
const amountLabel = internalTab === "sell" ? sharesLabel : payoutLabel;
|
|
2882
|
-
const toWinLabel = internalTab === "sell" ? payoutLabel : formatUsd(
|
|
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
|
-
|
|
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
|
|
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 = (
|
|
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
|
|
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 = (
|
|
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 = (
|
|
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
|
-
[(
|
|
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(
|
|
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(
|
|
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 (
|
|
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
|
|
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 = (
|
|
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": `${
|
|
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:
|
|
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) })
|