@agg-build/ui 1.2.6 → 1.2.8

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 (32) hide show
  1. package/dist/{chunk-2HI6K7JF.mjs → chunk-2YVW6J5N.mjs} +12 -6
  2. package/dist/{chunk-5FXMHTVR.mjs → chunk-BW4DQYWM.mjs} +1 -1
  3. package/dist/{chunk-34L7ZKJW.mjs → chunk-HQRT3B3L.mjs} +3 -2
  4. package/dist/{chunk-WPF47BQQ.mjs → chunk-IIEE4FVO.mjs} +9 -2
  5. package/dist/{chunk-TBKDLNOE.mjs → chunk-RPIYL7EA.mjs} +29 -8
  6. package/dist/{chunk-E45WOOMN.mjs → chunk-SMGKYWEP.mjs} +22 -8
  7. package/dist/{chunk-FS3FGVAG.mjs → chunk-U6YU5OE7.mjs} +671 -152
  8. package/dist/events.js +51 -15
  9. package/dist/events.mjs +3 -3
  10. package/dist/index.js +771 -196
  11. package/dist/index.mjs +27 -20
  12. package/dist/modals.js +8 -1
  13. package/dist/modals.mjs +3 -3
  14. package/dist/pages.js +735 -174
  15. package/dist/pages.mjs +6 -6
  16. package/dist/primitives.js +3 -2
  17. package/dist/primitives.mjs +1 -1
  18. package/dist/styles.css +1 -1
  19. package/dist/tailwind.css +1 -1
  20. package/dist/trading.js +670 -150
  21. package/dist/trading.mjs +4 -4
  22. package/dist/types/primitives/switch-button/switch-button.constants.d.mts +1 -1
  23. package/dist/types/primitives/switch-button/switch-button.constants.d.ts +1 -1
  24. package/dist/types/primitives/tooltip/index.d.mts +1 -1
  25. package/dist/types/primitives/tooltip/index.d.ts +1 -1
  26. package/dist/types/primitives/tooltip/tooltip.types.d.mts +2 -0
  27. package/dist/types/primitives/tooltip/tooltip.types.d.ts +2 -0
  28. package/dist/types/trading/place-order/index.place-order.execution-debug.d.mts +183 -0
  29. package/dist/types/trading/place-order/index.place-order.execution-debug.d.ts +183 -0
  30. package/dist/types/trading/place-order/index.place-order.execution-steps.d.mts +72 -0
  31. package/dist/types/trading/place-order/index.place-order.execution-steps.d.ts +72 -0
  32. package/package.json +1 -1
@@ -7,10 +7,10 @@ import {
7
7
  getTradingValueLabel,
8
8
  getTradingVenueLabel,
9
9
  resolveOrderEligibilityMessage
10
- } from "./chunk-TBKDLNOE.mjs";
10
+ } from "./chunk-RPIYL7EA.mjs";
11
11
  import {
12
12
  GeoBlockBanner
13
- } from "./chunk-5FXMHTVR.mjs";
13
+ } from "./chunk-BW4DQYWM.mjs";
14
14
  import {
15
15
  AGG_TERMS_OF_SERVICE_URL,
16
16
  Button,
@@ -37,7 +37,7 @@ import {
37
37
  getMotionClassName,
38
38
  normalizeVenueMarketCluster,
39
39
  skeletonViews
40
- } from "./chunk-34L7ZKJW.mjs";
40
+ } from "./chunk-HQRT3B3L.mjs";
41
41
 
42
42
  // src/trading/types.ts
43
43
  import { Venue, enumGuard, isFiniteNonNeg, safeParse } from "@agg-build/sdk";
@@ -244,6 +244,447 @@ var PLACE_ORDER_OUTCOME_BUTTON_CLASS_NAMES = {
244
244
  inactive: "border-transparent bg-agg-secondary-hover font-agg-normal text-agg-foreground hover:bg-agg-tertiary"
245
245
  };
246
246
 
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
+ // src/trading/place-order/index.place-order.execution-debug.ts
418
+ var REDACTED = "[redacted]";
419
+ var SENSITIVE_FIELD_PATTERNS = [
420
+ "token",
421
+ "authorization",
422
+ "cookie",
423
+ "secret",
424
+ "signature",
425
+ "privatekey",
426
+ "private_key",
427
+ "accesstoken",
428
+ "access_token",
429
+ "refreshtoken",
430
+ "refresh_token",
431
+ "jwt",
432
+ "password",
433
+ "apikey",
434
+ "api_key",
435
+ "email",
436
+ "headers"
437
+ ];
438
+ var isSensitiveFieldName = (name) => {
439
+ const normalized = name.toLowerCase();
440
+ return SENSITIVE_FIELD_PATTERNS.some((pattern) => normalized.includes(pattern));
441
+ };
442
+ var sanitizeExecutionDebugValue = (input) => {
443
+ const ancestors = /* @__PURE__ */ new Set();
444
+ const walk = (value) => {
445
+ if (value === null || value === void 0) return value;
446
+ if (typeof value !== "object") return value;
447
+ if (ancestors.has(value)) return "[circular]";
448
+ ancestors.add(value);
449
+ try {
450
+ if (Array.isArray(value)) {
451
+ return value.map((entry) => walk(entry));
452
+ }
453
+ if (value instanceof Error) {
454
+ return {
455
+ name: value.name,
456
+ message: value.message,
457
+ stack: value.stack
458
+ };
459
+ }
460
+ const out = {};
461
+ for (const [key, raw] of Object.entries(value)) {
462
+ if (isSensitiveFieldName(key)) {
463
+ out[key] = REDACTED;
464
+ continue;
465
+ }
466
+ out[key] = walk(raw);
467
+ }
468
+ return out;
469
+ } finally {
470
+ ancestors.delete(value);
471
+ }
472
+ };
473
+ return walk(input);
474
+ };
475
+ var cloneEnvironment = (env) => __spreadProps(__spreadValues({}, env), {
476
+ packageVersions: env.packageVersions ? __spreadValues({}, env.packageVersions) : void 0
477
+ });
478
+ var buildEnvironment = (overrides) => {
479
+ var _a;
480
+ const url = typeof window !== "undefined" ? (_a = window.location) == null ? void 0 : _a.href : void 0;
481
+ const userAgent = typeof navigator !== "undefined" && typeof navigator.userAgent === "string" ? navigator.userAgent : void 0;
482
+ return __spreadValues({
483
+ url,
484
+ userAgent,
485
+ capturedAt: Date.now()
486
+ }, overrides);
487
+ };
488
+ var generateAttemptId = () => {
489
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
490
+ return crypto.randomUUID();
491
+ }
492
+ return `attempt-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
493
+ };
494
+ var createExecutionDebugStore = (initial) => {
495
+ let attempts = [];
496
+ let environment = buildEnvironment(initial);
497
+ const findAttempt = (attemptId) => attempts.find((attempt) => attempt.attemptId === attemptId);
498
+ const touch = (attempt) => {
499
+ attempt.updatedAt = Date.now();
500
+ };
501
+ return {
502
+ appendAttempt(input = {}) {
503
+ var _a, _b;
504
+ const now = Date.now();
505
+ const attempt = {
506
+ attemptId: (_a = input.attemptId) != null ? _a : generateAttemptId(),
507
+ startedAt: now,
508
+ updatedAt: now,
509
+ status: (_b = input.status) != null ? _b : "quoting",
510
+ quoteId: input.quoteId,
511
+ orderId: input.orderId,
512
+ orderIds: input.orderIds,
513
+ quote: input.quote,
514
+ selectedRoute: input.selectedRoute,
515
+ bridge: input.bridge,
516
+ venueExecution: input.venueExecution,
517
+ rawEvents: [],
518
+ normalizedSteps: [],
519
+ errors: []
520
+ };
521
+ attempts = [...attempts, attempt];
522
+ return attempt;
523
+ },
524
+ updateAttempt(attemptId, patch) {
525
+ const attempt = findAttempt(attemptId);
526
+ if (!attempt) return;
527
+ if (patch.status !== void 0) attempt.status = patch.status;
528
+ if (patch.quoteId !== void 0) attempt.quoteId = patch.quoteId;
529
+ if (patch.orderId !== void 0) attempt.orderId = patch.orderId;
530
+ if (patch.orderIds !== void 0) attempt.orderIds = patch.orderIds;
531
+ if (patch.quote !== void 0) attempt.quote = patch.quote;
532
+ if (patch.selectedRoute !== void 0) attempt.selectedRoute = patch.selectedRoute;
533
+ if (patch.bridge !== void 0) attempt.bridge = patch.bridge;
534
+ if (patch.venueExecution !== void 0) attempt.venueExecution = patch.venueExecution;
535
+ if (patch.finalStatus !== void 0) attempt.finalStatus = patch.finalStatus;
536
+ touch(attempt);
537
+ },
538
+ appendEvent(attemptId, event) {
539
+ var _a;
540
+ const attempt = findAttempt(attemptId);
541
+ if (!attempt) return;
542
+ attempt.rawEvents.push({
543
+ kind: event.kind,
544
+ label: event.label,
545
+ data: event.data,
546
+ timestamp: (_a = event.timestamp) != null ? _a : Date.now()
547
+ });
548
+ touch(attempt);
549
+ },
550
+ appendError(attemptId, error) {
551
+ var _a;
552
+ const attempt = findAttempt(attemptId);
553
+ if (!attempt) return;
554
+ attempt.errors.push({
555
+ message: error.message,
556
+ name: error.name,
557
+ code: error.code,
558
+ stack: error.stack,
559
+ failedStep: error.failedStep,
560
+ data: error.data,
561
+ timestamp: (_a = error.timestamp) != null ? _a : Date.now()
562
+ });
563
+ touch(attempt);
564
+ },
565
+ setNormalizedSteps(attemptId, steps) {
566
+ const attempt = findAttempt(attemptId);
567
+ if (!attempt) return;
568
+ attempt.normalizedSteps = steps;
569
+ touch(attempt);
570
+ },
571
+ getSnapshot() {
572
+ return {
573
+ attempts: attempts.map((attempt) => __spreadProps(__spreadValues({}, attempt), {
574
+ rawEvents: [...attempt.rawEvents],
575
+ normalizedSteps: [...attempt.normalizedSteps],
576
+ errors: [...attempt.errors]
577
+ })),
578
+ environment: cloneEnvironment(environment)
579
+ };
580
+ },
581
+ getFailedAttempts() {
582
+ return attempts.filter(
583
+ (attempt) => attempt.status === "failed" || attempt.finalStatus === "failed" || attempt.errors.length > 0
584
+ ).map((attempt) => __spreadProps(__spreadValues({}, attempt), {
585
+ rawEvents: [...attempt.rawEvents],
586
+ normalizedSteps: [...attempt.normalizedSteps],
587
+ errors: [...attempt.errors]
588
+ }));
589
+ },
590
+ clear() {
591
+ attempts = [];
592
+ environment = buildEnvironment(initial);
593
+ }
594
+ };
595
+ };
596
+ var writeClipboardLegacy = (text) => {
597
+ if (typeof document === "undefined") return false;
598
+ const textarea = document.createElement("textarea");
599
+ textarea.value = text;
600
+ textarea.setAttribute("readonly", "");
601
+ textarea.style.position = "fixed";
602
+ textarea.style.top = "-1000px";
603
+ textarea.style.opacity = "0";
604
+ document.body.appendChild(textarea);
605
+ try {
606
+ textarea.select();
607
+ return document.execCommand("copy");
608
+ } catch (e) {
609
+ return false;
610
+ } finally {
611
+ document.body.removeChild(textarea);
612
+ }
613
+ };
614
+ var tryWriteClipboard = (text, consoleImpl) => __async(null, null, function* () {
615
+ var _a;
616
+ if (typeof navigator !== "undefined" && ((_a = navigator.clipboard) == null ? void 0 : _a.writeText)) {
617
+ try {
618
+ yield navigator.clipboard.writeText(text);
619
+ consoleImpl.info("[agg-execution-debug] Copied execution data to clipboard.");
620
+ return;
621
+ } catch (e) {
622
+ }
623
+ }
624
+ if (writeClipboardLegacy(text)) {
625
+ consoleImpl.info("[agg-execution-debug] Copied execution data to clipboard.");
626
+ return;
627
+ }
628
+ consoleImpl.warn(
629
+ "[agg-execution-debug] Clipboard copy was blocked by the browser. The JSON is logged below \u2014 right-click the entry and copy."
630
+ );
631
+ consoleImpl.log(text);
632
+ });
633
+ var installExecutionDebugWindow = ({
634
+ store,
635
+ consoleImpl
636
+ }) => {
637
+ if (typeof window === "undefined") return () => {
638
+ };
639
+ const targetConsole = consoleImpl != null ? consoleImpl : console;
640
+ const previous = {
641
+ executionData: window.executionData,
642
+ getExecutionData: window.getExecutionData,
643
+ getFailedExecutionData: window.getFailedExecutionData,
644
+ clearExecutionData: window.clearExecutionData,
645
+ storeRef: window.__aggExecutionDebugStore
646
+ };
647
+ const refresh = () => {
648
+ window.executionData = sanitizeExecutionDebugValue(store.getSnapshot());
649
+ };
650
+ refresh();
651
+ window.__aggExecutionDebugStore = store;
652
+ window.getExecutionData = () => {
653
+ const data = sanitizeExecutionDebugValue(store.getSnapshot());
654
+ window.executionData = data;
655
+ void tryWriteClipboard(JSON.stringify(data, null, 2), targetConsole);
656
+ return data;
657
+ };
658
+ window.getFailedExecutionData = () => {
659
+ const failed = sanitizeExecutionDebugValue({ attempts: store.getFailedAttempts() });
660
+ void tryWriteClipboard(JSON.stringify(failed, null, 2), targetConsole);
661
+ return failed;
662
+ };
663
+ window.clearExecutionData = () => {
664
+ store.clear();
665
+ refresh();
666
+ };
667
+ targetConsole.info(
668
+ "AGG execution debug enabled. Run window.getFailedExecutionData() after a failed order to copy logs."
669
+ );
670
+ return () => {
671
+ if (typeof window === "undefined") return;
672
+ window.executionData = previous.executionData;
673
+ window.getExecutionData = previous.getExecutionData;
674
+ window.getFailedExecutionData = previous.getFailedExecutionData;
675
+ window.clearExecutionData = previous.clearExecutionData;
676
+ window.__aggExecutionDebugStore = previous.storeRef;
677
+ };
678
+ };
679
+ var enableExecutionDebugInBrowser = (initial) => {
680
+ if (typeof window === "undefined") return null;
681
+ const existing = window.__aggExecutionDebugStore;
682
+ if (existing) return existing;
683
+ const store = createExecutionDebugStore(initial);
684
+ installExecutionDebugWindow({ store });
685
+ return store;
686
+ };
687
+
247
688
  // src/trading/place-order/index.place-order.utils.ts
248
689
  var routePriceLabelFormatter = new Intl.NumberFormat("en-US", {
249
690
  minimumFractionDigits: 0,
@@ -454,18 +895,19 @@ var buildLiveRouteCards = ({
454
895
  const parsedPrimaryVenue = parseVenue(primaryVenue);
455
896
  const isSplit = quoteData.fills.length > 1;
456
897
  const primaryWinnerVenue = quoteData.fills.length === 1 ? primaryVenue : void 0;
457
- const isPrimaryRouteGeoBlocked = quoteData.fills.length > 0 && quoteData.fills.every((f) => geoBlockedVenues.has(f.venue));
898
+ const isPrimaryRouteGeoBlocked = quoteData.fills.length > 0 && quoteData.fills.some((f) => geoBlockedVenues.has(f.venue));
458
899
  const primaryCard = primaryResult ? isPrimaryRouteGeoBlocked ? {
459
900
  id: "live-route",
460
901
  hint: labels.venueUnavailableInRegion,
461
- kind: "venue",
462
- label: getTradingVenueLabel(
902
+ kind: isSplit ? "split" : "venue",
903
+ label: isSplit ? labels.orderSplitting : getTradingVenueLabel(
463
904
  parsedPrimaryVenue.success ? parsedPrimaryVenue.data : void 0
464
905
  ),
465
906
  numericValue: tradeSide === "sell" ? quoteData.rawExecCost : quoteData.totalFilled,
466
907
  quoteData,
908
+ rows: isSplit ? mapQuoteDataToRoutingRows(quoteData) : void 0,
467
909
  value: primaryResult.value,
468
- venue: parsedPrimaryVenue.success ? parsedPrimaryVenue.data : void 0,
910
+ venue: isSplit ? void 0 : parsedPrimaryVenue.success ? parsedPrimaryVenue.data : void 0,
469
911
  isUnavailable: true
470
912
  } : {
471
913
  id: "live-route",
@@ -1430,21 +1872,6 @@ PlaceOrderSuccessView.displayName = "PlaceOrderSuccessView";
1430
1872
 
1431
1873
  // src/trading/place-order/index.tsx
1432
1874
  import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
1433
- var DEFAULT_STEP_LABELS = {
1434
- "check-balance": "Checking balance",
1435
- "check-position": "Checking position",
1436
- "lane-bridge": "Bridging funds",
1437
- bridge: "Bridging funds",
1438
- "bridge-to-user": "Transferring to wallet",
1439
- "sweep-bridge": "Completing bridge",
1440
- "submit-order": "Submitting order",
1441
- "order-bridge-execute": "Executing order",
1442
- "transfer-to-user": "Transferring to wallet"
1443
- };
1444
- var getDefaultStepLabel = (stepType) => {
1445
- var _a;
1446
- return (_a = DEFAULT_STEP_LABELS[stepType]) != null ? _a : stepType.replace(/-/g, " ").replace(/^\w/, (c) => c.toUpperCase());
1447
- };
1448
1875
  var resolveRefetchedQuoteData = (result) => {
1449
1876
  if (!result || typeof result !== "object" || !("data" in result)) return null;
1450
1877
  const data = result.data;
@@ -1944,7 +2371,6 @@ var renderRouteCard = ({
1944
2371
  }
1945
2372
  );
1946
2373
  };
1947
- var normalizeOrderIdLabelInput2 = (orderId) => orderId.replace(/^#+/, "");
1948
2374
  var renderSubmissionSurface = ({
1949
2375
  actionLabel,
1950
2376
  className,
@@ -1956,81 +2382,12 @@ var renderSubmissionSurface = ({
1956
2382
  progressState,
1957
2383
  tradingLabels
1958
2384
  }) => {
1959
- const resolveStepGroups = () => {
1960
- var _a, _b, _c;
1961
- if (progressState.phase === "finding-route") {
1962
- return [
1963
- [
1964
- {
1965
- id: "finding-route",
1966
- label: tradingLabels.findingBestRoute,
1967
- status: "pending"
1968
- }
1969
- ]
1970
- ];
1971
- }
1972
- const dag = progressState.dagProgress;
1973
- if (dag && dag.totalSteps > 0) {
1974
- const steps = [
1975
- {
1976
- id: "finding-route",
1977
- label: tradingLabels.findingBestRoute,
1978
- status: "complete"
1979
- }
1980
- ];
1981
- for (let i = 1; i <= dag.totalSteps; i++) {
1982
- const isCompleted = dag.completedSequences.includes(i);
1983
- const isCurrent = i === dag.currentSequence && !isCompleted;
1984
- const stepType = (_a = dag.stepTypes[i]) != null ? _a : null;
1985
- const stepLabel = stepType ? getDefaultStepLabel(stepType) : `Step ${i} of ${dag.totalSteps}`;
1986
- const prev = steps[steps.length - 1];
1987
- if (prev && prev.label === stepLabel) {
1988
- if (prev.status === "complete" && !isCompleted) {
1989
- prev.status = "pending";
1990
- }
1991
- continue;
1992
- }
1993
- steps.push({
1994
- id: `dag-step-${i}`,
1995
- label: stepLabel,
1996
- status: isCompleted ? "complete" : isCurrent ? "pending" : "pending"
1997
- });
1998
- }
1999
- return [steps];
2000
- }
2001
- const baseSteps = [
2002
- {
2003
- id: "finding-route",
2004
- label: tradingLabels.findingBestRoute,
2005
- status: "complete"
2006
- },
2007
- {
2008
- id: "submitting-order",
2009
- label: tradingLabels.submittingOrderProgress,
2010
- status: "complete"
2011
- }
2012
- ];
2013
- const submittedOrderId = (_c = progressState.orderId) != null ? _c : (_b = progressState.orderIds) == null ? void 0 : _b[0];
2014
- if (submittedOrderId) {
2015
- baseSteps.push({
2016
- id: "order-submitted",
2017
- label: tradingLabels.orderSubmittedProgress(normalizeOrderIdLabelInput2(submittedOrderId)),
2018
- status: "complete"
2019
- });
2020
- }
2021
- return [
2022
- baseSteps,
2023
- [
2024
- {
2025
- id: "executing-order",
2026
- label: tradingLabels.executingOnVenue(getTradingVenueLabel(progressState.executionVenue)),
2027
- status: "pending",
2028
- venue: progressState.executionVenue
2029
- }
2030
- ]
2031
- ];
2032
- };
2033
- const stepGroups = resolveStepGroups();
2385
+ const displayRows = buildSubmissionDisplayRows({
2386
+ phase: progressState.phase,
2387
+ dagProgress: progressState.dagProgress,
2388
+ executionVenue: progressState.executionVenue,
2389
+ labels: tradingLabels
2390
+ });
2034
2391
  return /* @__PURE__ */ jsx4(
2035
2392
  Card,
2036
2393
  {
@@ -2052,51 +2409,50 @@ var renderSubmissionSurface = ({
2052
2409
  /* @__PURE__ */ jsx4(LoadingGlyph, { enableAnimations, className: "h-4 w-4 text-current" }),
2053
2410
  /* @__PURE__ */ jsx4("span", { children: actionLabel })
2054
2411
  ] }),
2055
- /* @__PURE__ */ jsx4("div", { className: "agg-order-submission-steps flex flex-col gap-4", children: stepGroups.map((steps, groupIndex) => {
2056
- return /* @__PURE__ */ jsx4(
2057
- "div",
2058
- {
2059
- className: "agg-order-submission-group flex flex-col gap-2",
2060
- children: steps.map((step) => {
2061
- return /* @__PURE__ */ jsxs3(
2062
- "div",
2063
- {
2064
- className: "agg-order-submission-step flex items-center gap-2 text-agg-sm leading-agg-5 text-agg-foreground",
2065
- children: [
2066
- step.status === "complete" ? /* @__PURE__ */ jsx4(
2067
- Icon,
2068
- {
2069
- name: "check-circle",
2070
- size: "small",
2071
- className: "h-3 w-3 shrink-0 text-agg-primary",
2072
- "aria-hidden": "true"
2073
- }
2074
- ) : /* @__PURE__ */ jsx4(
2075
- LoadingGlyph,
2076
- {
2077
- enableAnimations,
2078
- className: "h-3 w-3 shrink-0 text-agg-primary"
2079
- }
2080
- ),
2081
- /* @__PURE__ */ jsx4("p", { className: "min-w-0 flex-1", children: step.label }),
2082
- step.venue ? /* @__PURE__ */ jsx4(
2083
- VenueLogo,
2084
- {
2085
- venue: step.venue,
2086
- size: "small",
2087
- ariaLabel: getTradingVenueLabel(step.venue),
2088
- className: "h-4 w-4"
2089
- }
2090
- ) : null
2091
- ]
2092
- },
2093
- step.id
2094
- );
2095
- })
2096
- },
2097
- `step-group-${groupIndex}`
2098
- );
2099
- }) })
2412
+ /* @__PURE__ */ jsx4(
2413
+ "div",
2414
+ {
2415
+ className: "agg-order-submission-steps agg-order-submission-group flex flex-col gap-2",
2416
+ "data-testid": "agg-order-submission-steps",
2417
+ children: displayRows.map((step) => {
2418
+ return /* @__PURE__ */ jsxs3(
2419
+ "div",
2420
+ {
2421
+ className: "agg-order-submission-step flex items-center gap-2 text-agg-sm leading-agg-5 text-agg-foreground",
2422
+ "data-status": step.status,
2423
+ children: [
2424
+ step.status === "complete" ? /* @__PURE__ */ jsx4(
2425
+ Icon,
2426
+ {
2427
+ name: "check-circle",
2428
+ size: "small",
2429
+ className: "h-3 w-3 shrink-0 text-agg-primary",
2430
+ "aria-hidden": "true"
2431
+ }
2432
+ ) : /* @__PURE__ */ jsx4(
2433
+ LoadingGlyph,
2434
+ {
2435
+ enableAnimations,
2436
+ className: "h-3 w-3 shrink-0 text-agg-primary"
2437
+ }
2438
+ ),
2439
+ /* @__PURE__ */ jsx4("p", { className: "min-w-0 flex-1", children: step.label }),
2440
+ step.venue ? /* @__PURE__ */ jsx4(
2441
+ VenueLogo,
2442
+ {
2443
+ venue: step.venue,
2444
+ size: "small",
2445
+ ariaLabel: getTradingVenueLabel(step.venue),
2446
+ className: "h-4 w-4"
2447
+ }
2448
+ ) : null
2449
+ ]
2450
+ },
2451
+ step.id
2452
+ );
2453
+ })
2454
+ }
2455
+ )
2100
2456
  ] })
2101
2457
  ] })
2102
2458
  }
@@ -2232,6 +2588,7 @@ var PlaceOrder = ({
2232
2588
  }) => {
2233
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;
2234
2590
  const {
2591
+ enableDebug: isExecutionDebugEnabled,
2235
2592
  features: { enableAnimations, showFeesBreakdown },
2236
2593
  general: { locale }
2237
2594
  } = useSdkUiConfig();
@@ -2328,6 +2685,27 @@ var PlaceOrder = ({
2328
2685
  const [isSplitDetailOpen, setIsSplitDetailOpen] = useState3(false);
2329
2686
  const [submissionFeedback, setSubmissionFeedback] = useState3(null);
2330
2687
  const [submissionProgressState, setSubmissionProgressState] = useState3(null);
2688
+ const executionDebugStoreRef = useRef2(null);
2689
+ const executionDebugAttemptIdRef = useRef2(null);
2690
+ useEffect2(() => {
2691
+ if (!isExecutionDebugEnabled) {
2692
+ executionDebugStoreRef.current = null;
2693
+ return;
2694
+ }
2695
+ executionDebugStoreRef.current = enableExecutionDebugInBrowser();
2696
+ }, [isExecutionDebugEnabled]);
2697
+ useEffect2(() => {
2698
+ if (!isExecutionDebugEnabled) return;
2699
+ const store = executionDebugStoreRef.current;
2700
+ if (!store) return;
2701
+ store.clear();
2702
+ executionDebugAttemptIdRef.current = null;
2703
+ }, [
2704
+ isExecutionDebugEnabled,
2705
+ scopedSelectedEvent == null ? void 0 : scopedSelectedEvent.id,
2706
+ scopedSelectedMarket == null ? void 0 : scopedSelectedMarket.id,
2707
+ scopedSelectedOutcomeId
2708
+ ]);
2331
2709
  const debouncedAmount = useDebouncedValue(internalAmount, 300);
2332
2710
  const isSell = useMemo2(() => internalTab === "sell", [internalTab]);
2333
2711
  const {
@@ -2587,8 +2965,39 @@ var PlaceOrder = ({
2587
2965
  selectedRouteCard == null ? void 0 : selectedRouteCard.quoteData
2588
2966
  ]);
2589
2967
  useEffect2(() => {
2968
+ var _a2, _b2;
2590
2969
  const dp = executionProgress.dagProgress;
2591
2970
  if (!dp) return;
2971
+ const debugStore = executionDebugStoreRef.current;
2972
+ const debugAttemptId = executionDebugAttemptIdRef.current;
2973
+ if (debugStore && debugAttemptId) {
2974
+ debugStore.appendEvent(debugAttemptId, {
2975
+ kind: "ws_update",
2976
+ label: "dag_progress",
2977
+ data: dp
2978
+ });
2979
+ const normalizedRows = buildSubmissionDisplayRows({
2980
+ phase: "executing",
2981
+ dagProgress: dp,
2982
+ labels: tradingLabels
2983
+ });
2984
+ debugStore.setNormalizedSteps(debugAttemptId, normalizedRows);
2985
+ debugStore.appendEvent(debugAttemptId, {
2986
+ kind: "normalized_steps",
2987
+ data: normalizedRows
2988
+ });
2989
+ if (dp.status === "failed") {
2990
+ debugStore.appendError(debugAttemptId, {
2991
+ message: (_a2 = dp.errorReason) != null ? _a2 : "DAG execution failed",
2992
+ failedStep: (_b2 = dp.currentStepType) != null ? _b2 : void 0,
2993
+ data: { currentSequence: dp.currentSequence, totalSteps: dp.totalSteps }
2994
+ });
2995
+ debugStore.updateAttempt(debugAttemptId, {
2996
+ status: "failed",
2997
+ finalStatus: "failed"
2998
+ });
2999
+ }
3000
+ }
2592
3001
  setSubmissionProgressState((prev) => {
2593
3002
  if (!prev) return prev;
2594
3003
  if (dp.status === "failed") {
@@ -2604,7 +3013,7 @@ var PlaceOrder = ({
2604
3013
  }
2605
3014
  return __spreadProps(__spreadValues({}, prev), { dagProgress: dp });
2606
3015
  });
2607
- }, [executionProgress.dagProgress, tradingLabels.orderFailed]);
3016
+ }, [executionProgress.dagProgress, tradingLabels]);
2608
3017
  useEffect2(() => {
2609
3018
  const orderIds = submissionProgressState == null ? void 0 : submissionProgressState.orderIds;
2610
3019
  if (!(orderIds == null ? void 0 : orderIds.length)) return;
@@ -2612,6 +3021,17 @@ var PlaceOrder = ({
2612
3021
  orderIds,
2613
3022
  executionProgress.terminalOrderEvents
2614
3023
  );
3024
+ const debugStore = executionDebugStoreRef.current;
3025
+ const debugAttemptId = executionDebugAttemptIdRef.current;
3026
+ if (debugStore && debugAttemptId && executionProgress.terminalOrderEvents.length > 0) {
3027
+ debugStore.appendEvent(debugAttemptId, {
3028
+ kind: "terminal_event",
3029
+ data: {
3030
+ aggregateStatus,
3031
+ events: executionProgress.terminalOrderEvents
3032
+ }
3033
+ });
3034
+ }
2615
3035
  if (aggregateStatus === "pending") return;
2616
3036
  setSubmissionProgressState((prev) => {
2617
3037
  var _a2, _b2, _c2;
@@ -2654,14 +3074,45 @@ var PlaceOrder = ({
2654
3074
  tradingLabels.orderFailed
2655
3075
  ]);
2656
3076
  useEffect2(() => {
3077
+ var _a2, _b2;
2657
3078
  if (!submissionProgressState) return;
2658
3079
  onExecutionStateChange == null ? void 0 : onExecutionStateChange(submissionProgressState);
3080
+ const debugStore = executionDebugStoreRef.current;
3081
+ const debugAttemptId = executionDebugAttemptIdRef.current;
3082
+ if (debugStore && debugAttemptId) {
3083
+ debugStore.appendEvent(debugAttemptId, {
3084
+ kind: "state_change",
3085
+ label: submissionProgressState.phase,
3086
+ data: {
3087
+ phase: submissionProgressState.phase,
3088
+ executionVenue: submissionProgressState.executionVenue,
3089
+ orderIds: submissionProgressState.orderIds,
3090
+ errorMessage: submissionProgressState.errorMessage
3091
+ }
3092
+ });
3093
+ }
2659
3094
  if (submissionProgressState.phase === "success" && submissionProgressState.summary) {
2660
3095
  invalidateBalanceQueries(queryClient);
2661
3096
  invalidatePositionQueries(queryClient);
3097
+ if (debugStore && debugAttemptId) {
3098
+ debugStore.updateAttempt(debugAttemptId, {
3099
+ status: "succeeded",
3100
+ finalStatus: "succeeded"
3101
+ });
3102
+ }
2662
3103
  onSuccess == null ? void 0 : onSuccess(submissionProgressState.summary);
2663
3104
  }
2664
3105
  if (submissionProgressState.phase === "failed" && submissionProgressState.errorMessage) {
3106
+ if (debugStore && debugAttemptId) {
3107
+ debugStore.appendError(debugAttemptId, {
3108
+ message: submissionProgressState.errorMessage,
3109
+ failedStep: (_b2 = (_a2 = submissionProgressState.dagProgress) == null ? void 0 : _a2.currentStepType) != null ? _b2 : void 0
3110
+ });
3111
+ debugStore.updateAttempt(debugAttemptId, {
3112
+ status: "failed",
3113
+ finalStatus: "failed"
3114
+ });
3115
+ }
2665
3116
  onError == null ? void 0 : onError(new Error(submissionProgressState.errorMessage));
2666
3117
  }
2667
3118
  }, [submissionProgressState, onExecutionStateChange, onSuccess, onError, queryClient]);
@@ -2835,23 +3286,91 @@ var PlaceOrder = ({
2835
3286
  };
2836
3287
  const handleExecuteQuote = useCallback2(
2837
3288
  (quoteData) => __async(null, null, function* () {
3289
+ var _a2, _b2, _c2;
2838
3290
  const quoteId = quoteData == null ? void 0 : quoteData.quoteId;
2839
3291
  if (!quoteId) {
2840
3292
  throw new Error(tradingLabels.quoteUnavailable);
2841
3293
  }
3294
+ const debugStore = executionDebugStoreRef.current;
3295
+ const venues = (_b2 = (_a2 = quoteData == null ? void 0 : quoteData.fills) == null ? void 0 : _a2.map((fill) => fill.venue).filter(Boolean)) != null ? _b2 : [];
3296
+ const debugAttempt = debugStore == null ? void 0 : debugStore.appendAttempt({
3297
+ status: "executing",
3298
+ quoteId,
3299
+ quote: {
3300
+ request: {
3301
+ venueMarketOutcomeId: scopedSelectedOutcomeId,
3302
+ amount: internalAmount,
3303
+ slippage: internalSlippage,
3304
+ tradeSide: isSell ? "sell" : "buy"
3305
+ },
3306
+ response: smartRoute.data,
3307
+ selectedRoute: quoteData,
3308
+ side: isSell ? "sell" : "buy",
3309
+ marketId: scopedSelectedMarket == null ? void 0 : scopedSelectedMarket.id,
3310
+ eventId: scopedSelectedEvent == null ? void 0 : scopedSelectedEvent.id,
3311
+ outcomeId: scopedSelectedOutcomeId != null ? scopedSelectedOutcomeId : void 0,
3312
+ venues,
3313
+ capturedAt: Date.now()
3314
+ },
3315
+ selectedRoute: quoteData
3316
+ });
3317
+ executionDebugAttemptIdRef.current = (_c2 = debugAttempt == null ? void 0 : debugAttempt.attemptId) != null ? _c2 : null;
2842
3318
  if (onPrimaryAction) {
3319
+ debugStore == null ? void 0 : debugStore.appendEvent(debugAttempt.attemptId, {
3320
+ kind: "execute_request",
3321
+ label: "delegated_to_partner",
3322
+ data: { quoteId }
3323
+ });
2843
3324
  onPrimaryAction({ quoteId });
2844
3325
  return;
2845
3326
  }
2846
- const response = yield executeManaged.mutateAsync({ quoteId });
2847
- setSubmissionProgressState({
2848
- executionVenue: resolveExecutionVenueFromQuote(quoteData),
2849
- orderId: response.orderIds[0],
2850
- orderIds: response.orderIds,
2851
- phase: "submitting"
2852
- });
3327
+ try {
3328
+ const response = yield executeManaged.mutateAsync({ quoteId });
3329
+ if (debugAttempt) {
3330
+ debugStore == null ? void 0 : debugStore.appendEvent(debugAttempt.attemptId, {
3331
+ kind: "execute_response",
3332
+ data: { orderIds: response.orderIds }
3333
+ });
3334
+ debugStore == null ? void 0 : debugStore.updateAttempt(debugAttempt.attemptId, {
3335
+ orderId: response.orderIds[0],
3336
+ orderIds: response.orderIds
3337
+ });
3338
+ }
3339
+ setSubmissionProgressState({
3340
+ executionVenue: resolveExecutionVenueFromQuote(quoteData),
3341
+ orderId: response.orderIds[0],
3342
+ orderIds: response.orderIds,
3343
+ phase: "submitting"
3344
+ });
3345
+ } catch (error) {
3346
+ if (debugAttempt) {
3347
+ const err = error instanceof Error ? error : new Error(String(error));
3348
+ debugStore == null ? void 0 : debugStore.appendError(debugAttempt.attemptId, {
3349
+ message: err.message,
3350
+ name: err.name,
3351
+ stack: err.stack,
3352
+ failedStep: "execute_request"
3353
+ });
3354
+ debugStore == null ? void 0 : debugStore.updateAttempt(debugAttempt.attemptId, {
3355
+ status: "failed",
3356
+ finalStatus: "failed"
3357
+ });
3358
+ }
3359
+ throw error;
3360
+ }
2853
3361
  }),
2854
- [executeManaged, onPrimaryAction, tradingLabels.quoteUnavailable]
3362
+ [
3363
+ executeManaged,
3364
+ internalAmount,
3365
+ internalSlippage,
3366
+ isSell,
3367
+ onPrimaryAction,
3368
+ scopedSelectedEvent == null ? void 0 : scopedSelectedEvent.id,
3369
+ scopedSelectedMarket == null ? void 0 : scopedSelectedMarket.id,
3370
+ scopedSelectedOutcomeId,
3371
+ smartRoute.data,
3372
+ tradingLabels.quoteUnavailable
3373
+ ]
2855
3374
  );
2856
3375
  const handleSkipToSuccess = useCallback2(() => {
2857
3376
  const primaryFilledEvent = executionProgress.terminalOrderEvents.find(