@agg-build/ui 1.2.7 → 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-QMWKXDVZ.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-3RG2K7MV.mjs → chunk-U6YU5OE7.mjs} +666 -148
  8. package/dist/events.js +51 -15
  9. package/dist/events.mjs +3 -3
  10. package/dist/index.js +766 -192
  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 +730 -170
  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 +665 -146
  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,
@@ -1431,21 +1872,6 @@ PlaceOrderSuccessView.displayName = "PlaceOrderSuccessView";
1431
1872
 
1432
1873
  // src/trading/place-order/index.tsx
1433
1874
  import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
1434
- var DEFAULT_STEP_LABELS = {
1435
- "check-balance": "Checking balance",
1436
- "check-position": "Checking position",
1437
- "lane-bridge": "Bridging funds",
1438
- bridge: "Bridging funds",
1439
- "bridge-to-user": "Transferring to wallet",
1440
- "sweep-bridge": "Completing bridge",
1441
- "submit-order": "Submitting order",
1442
- "order-bridge-execute": "Executing order",
1443
- "transfer-to-user": "Transferring to wallet"
1444
- };
1445
- var getDefaultStepLabel = (stepType) => {
1446
- var _a;
1447
- return (_a = DEFAULT_STEP_LABELS[stepType]) != null ? _a : stepType.replace(/-/g, " ").replace(/^\w/, (c) => c.toUpperCase());
1448
- };
1449
1875
  var resolveRefetchedQuoteData = (result) => {
1450
1876
  if (!result || typeof result !== "object" || !("data" in result)) return null;
1451
1877
  const data = result.data;
@@ -1945,7 +2371,6 @@ var renderRouteCard = ({
1945
2371
  }
1946
2372
  );
1947
2373
  };
1948
- var normalizeOrderIdLabelInput2 = (orderId) => orderId.replace(/^#+/, "");
1949
2374
  var renderSubmissionSurface = ({
1950
2375
  actionLabel,
1951
2376
  className,
@@ -1957,81 +2382,12 @@ var renderSubmissionSurface = ({
1957
2382
  progressState,
1958
2383
  tradingLabels
1959
2384
  }) => {
1960
- const resolveStepGroups = () => {
1961
- var _a, _b, _c;
1962
- if (progressState.phase === "finding-route") {
1963
- return [
1964
- [
1965
- {
1966
- id: "finding-route",
1967
- label: tradingLabels.findingBestRoute,
1968
- status: "pending"
1969
- }
1970
- ]
1971
- ];
1972
- }
1973
- const dag = progressState.dagProgress;
1974
- if (dag && dag.totalSteps > 0) {
1975
- const steps = [
1976
- {
1977
- id: "finding-route",
1978
- label: tradingLabels.findingBestRoute,
1979
- status: "complete"
1980
- }
1981
- ];
1982
- for (let i = 1; i <= dag.totalSteps; i++) {
1983
- const isCompleted = dag.completedSequences.includes(i);
1984
- const isCurrent = i === dag.currentSequence && !isCompleted;
1985
- const stepType = (_a = dag.stepTypes[i]) != null ? _a : null;
1986
- const stepLabel = stepType ? getDefaultStepLabel(stepType) : `Step ${i} of ${dag.totalSteps}`;
1987
- const prev = steps[steps.length - 1];
1988
- if (prev && prev.label === stepLabel) {
1989
- if (prev.status === "complete" && !isCompleted) {
1990
- prev.status = "pending";
1991
- }
1992
- continue;
1993
- }
1994
- steps.push({
1995
- id: `dag-step-${i}`,
1996
- label: stepLabel,
1997
- status: isCompleted ? "complete" : isCurrent ? "pending" : "pending"
1998
- });
1999
- }
2000
- return [steps];
2001
- }
2002
- const baseSteps = [
2003
- {
2004
- id: "finding-route",
2005
- label: tradingLabels.findingBestRoute,
2006
- status: "complete"
2007
- },
2008
- {
2009
- id: "submitting-order",
2010
- label: tradingLabels.submittingOrderProgress,
2011
- status: "complete"
2012
- }
2013
- ];
2014
- const submittedOrderId = (_c = progressState.orderId) != null ? _c : (_b = progressState.orderIds) == null ? void 0 : _b[0];
2015
- if (submittedOrderId) {
2016
- baseSteps.push({
2017
- id: "order-submitted",
2018
- label: tradingLabels.orderSubmittedProgress(normalizeOrderIdLabelInput2(submittedOrderId)),
2019
- status: "complete"
2020
- });
2021
- }
2022
- return [
2023
- baseSteps,
2024
- [
2025
- {
2026
- id: "executing-order",
2027
- label: tradingLabels.executingOnVenue(getTradingVenueLabel(progressState.executionVenue)),
2028
- status: "pending",
2029
- venue: progressState.executionVenue
2030
- }
2031
- ]
2032
- ];
2033
- };
2034
- const stepGroups = resolveStepGroups();
2385
+ const displayRows = buildSubmissionDisplayRows({
2386
+ phase: progressState.phase,
2387
+ dagProgress: progressState.dagProgress,
2388
+ executionVenue: progressState.executionVenue,
2389
+ labels: tradingLabels
2390
+ });
2035
2391
  return /* @__PURE__ */ jsx4(
2036
2392
  Card,
2037
2393
  {
@@ -2053,51 +2409,50 @@ var renderSubmissionSurface = ({
2053
2409
  /* @__PURE__ */ jsx4(LoadingGlyph, { enableAnimations, className: "h-4 w-4 text-current" }),
2054
2410
  /* @__PURE__ */ jsx4("span", { children: actionLabel })
2055
2411
  ] }),
2056
- /* @__PURE__ */ jsx4("div", { className: "agg-order-submission-steps flex flex-col gap-4", children: stepGroups.map((steps, groupIndex) => {
2057
- return /* @__PURE__ */ jsx4(
2058
- "div",
2059
- {
2060
- className: "agg-order-submission-group flex flex-col gap-2",
2061
- children: steps.map((step) => {
2062
- return /* @__PURE__ */ jsxs3(
2063
- "div",
2064
- {
2065
- className: "agg-order-submission-step flex items-center gap-2 text-agg-sm leading-agg-5 text-agg-foreground",
2066
- children: [
2067
- step.status === "complete" ? /* @__PURE__ */ jsx4(
2068
- Icon,
2069
- {
2070
- name: "check-circle",
2071
- size: "small",
2072
- className: "h-3 w-3 shrink-0 text-agg-primary",
2073
- "aria-hidden": "true"
2074
- }
2075
- ) : /* @__PURE__ */ jsx4(
2076
- LoadingGlyph,
2077
- {
2078
- enableAnimations,
2079
- className: "h-3 w-3 shrink-0 text-agg-primary"
2080
- }
2081
- ),
2082
- /* @__PURE__ */ jsx4("p", { className: "min-w-0 flex-1", children: step.label }),
2083
- step.venue ? /* @__PURE__ */ jsx4(
2084
- VenueLogo,
2085
- {
2086
- venue: step.venue,
2087
- size: "small",
2088
- ariaLabel: getTradingVenueLabel(step.venue),
2089
- className: "h-4 w-4"
2090
- }
2091
- ) : null
2092
- ]
2093
- },
2094
- step.id
2095
- );
2096
- })
2097
- },
2098
- `step-group-${groupIndex}`
2099
- );
2100
- }) })
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
+ )
2101
2456
  ] })
2102
2457
  ] })
2103
2458
  }
@@ -2233,6 +2588,7 @@ var PlaceOrder = ({
2233
2588
  }) => {
2234
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;
2235
2590
  const {
2591
+ enableDebug: isExecutionDebugEnabled,
2236
2592
  features: { enableAnimations, showFeesBreakdown },
2237
2593
  general: { locale }
2238
2594
  } = useSdkUiConfig();
@@ -2329,6 +2685,27 @@ var PlaceOrder = ({
2329
2685
  const [isSplitDetailOpen, setIsSplitDetailOpen] = useState3(false);
2330
2686
  const [submissionFeedback, setSubmissionFeedback] = useState3(null);
2331
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
+ ]);
2332
2709
  const debouncedAmount = useDebouncedValue(internalAmount, 300);
2333
2710
  const isSell = useMemo2(() => internalTab === "sell", [internalTab]);
2334
2711
  const {
@@ -2588,8 +2965,39 @@ var PlaceOrder = ({
2588
2965
  selectedRouteCard == null ? void 0 : selectedRouteCard.quoteData
2589
2966
  ]);
2590
2967
  useEffect2(() => {
2968
+ var _a2, _b2;
2591
2969
  const dp = executionProgress.dagProgress;
2592
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
+ }
2593
3001
  setSubmissionProgressState((prev) => {
2594
3002
  if (!prev) return prev;
2595
3003
  if (dp.status === "failed") {
@@ -2605,7 +3013,7 @@ var PlaceOrder = ({
2605
3013
  }
2606
3014
  return __spreadProps(__spreadValues({}, prev), { dagProgress: dp });
2607
3015
  });
2608
- }, [executionProgress.dagProgress, tradingLabels.orderFailed]);
3016
+ }, [executionProgress.dagProgress, tradingLabels]);
2609
3017
  useEffect2(() => {
2610
3018
  const orderIds = submissionProgressState == null ? void 0 : submissionProgressState.orderIds;
2611
3019
  if (!(orderIds == null ? void 0 : orderIds.length)) return;
@@ -2613,6 +3021,17 @@ var PlaceOrder = ({
2613
3021
  orderIds,
2614
3022
  executionProgress.terminalOrderEvents
2615
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
+ }
2616
3035
  if (aggregateStatus === "pending") return;
2617
3036
  setSubmissionProgressState((prev) => {
2618
3037
  var _a2, _b2, _c2;
@@ -2655,14 +3074,45 @@ var PlaceOrder = ({
2655
3074
  tradingLabels.orderFailed
2656
3075
  ]);
2657
3076
  useEffect2(() => {
3077
+ var _a2, _b2;
2658
3078
  if (!submissionProgressState) return;
2659
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
+ }
2660
3094
  if (submissionProgressState.phase === "success" && submissionProgressState.summary) {
2661
3095
  invalidateBalanceQueries(queryClient);
2662
3096
  invalidatePositionQueries(queryClient);
3097
+ if (debugStore && debugAttemptId) {
3098
+ debugStore.updateAttempt(debugAttemptId, {
3099
+ status: "succeeded",
3100
+ finalStatus: "succeeded"
3101
+ });
3102
+ }
2663
3103
  onSuccess == null ? void 0 : onSuccess(submissionProgressState.summary);
2664
3104
  }
2665
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
+ }
2666
3116
  onError == null ? void 0 : onError(new Error(submissionProgressState.errorMessage));
2667
3117
  }
2668
3118
  }, [submissionProgressState, onExecutionStateChange, onSuccess, onError, queryClient]);
@@ -2836,23 +3286,91 @@ var PlaceOrder = ({
2836
3286
  };
2837
3287
  const handleExecuteQuote = useCallback2(
2838
3288
  (quoteData) => __async(null, null, function* () {
3289
+ var _a2, _b2, _c2;
2839
3290
  const quoteId = quoteData == null ? void 0 : quoteData.quoteId;
2840
3291
  if (!quoteId) {
2841
3292
  throw new Error(tradingLabels.quoteUnavailable);
2842
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;
2843
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
+ });
2844
3324
  onPrimaryAction({ quoteId });
2845
3325
  return;
2846
3326
  }
2847
- const response = yield executeManaged.mutateAsync({ quoteId });
2848
- setSubmissionProgressState({
2849
- executionVenue: resolveExecutionVenueFromQuote(quoteData),
2850
- orderId: response.orderIds[0],
2851
- orderIds: response.orderIds,
2852
- phase: "submitting"
2853
- });
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
+ }
2854
3361
  }),
2855
- [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
+ ]
2856
3374
  );
2857
3375
  const handleSkipToSuccess = useCallback2(() => {
2858
3376
  const primaryFilledEvent = executionProgress.terminalOrderEvents.find(