@rhinestone/deposit-modal 0.14.0 → 0.15.0

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 (69) hide show
  1. package/README.md +12 -12
  2. package/bridge-transcript.json +14 -0
  3. package/dist/ClaimModal-GFDBVCN5.cjs +11 -0
  4. package/dist/ClaimModal-VQS3AKEL.mjs +11 -0
  5. package/dist/{DepositModalReown-Q2JMLT47.mjs → DepositModalReown-KOJ7VEY7.mjs} +30 -29
  6. package/dist/{DepositModalReown-46LPVFB6.cjs → DepositModalReown-R37SSHUF.cjs} +79 -78
  7. package/dist/WithdrawModal-QVXHMH43.mjs +12 -0
  8. package/dist/WithdrawModal-RY2NMFLE.cjs +12 -0
  9. package/dist/{caip-D8aRWdEY.d.cts → caip-BMi-9t09.d.cts} +27 -3
  10. package/dist/{caip-D8aRWdEY.d.ts → caip-BMi-9t09.d.ts} +27 -3
  11. package/dist/{chunk-V2OBGLJD.cjs → chunk-3OOY67VJ.cjs} +1103 -253
  12. package/dist/{chunk-6KG642KH.cjs → chunk-5P2PVLS4.cjs} +1 -1
  13. package/dist/{chunk-IN77XSWO.mjs → chunk-5VONFVQN.mjs} +976 -126
  14. package/dist/chunk-6HUHVXCY.cjs +704 -0
  15. package/dist/{chunk-PKML3XVS.mjs → chunk-7UQ6OUEE.mjs} +166 -45
  16. package/dist/{chunk-K4H6TGBE.mjs → chunk-CXBMIZUF.mjs} +1 -1
  17. package/dist/{chunk-MTFJSE52.cjs → chunk-DTVZUBHI.cjs} +236 -115
  18. package/dist/{chunk-VUATPOWJ.mjs → chunk-EAGMY3QE.mjs} +74 -17
  19. package/dist/{chunk-RN5VKWI6.mjs → chunk-FTWKAJGN.mjs} +1 -1
  20. package/dist/{chunk-KTUVSKR4.mjs → chunk-IKUYZA7A.mjs} +265 -523
  21. package/dist/{chunk-DW2EQA2U.cjs → chunk-LVCD6RHF.cjs} +2 -2
  22. package/dist/{chunk-4KCSH4T3.cjs → chunk-OY5N3E6L.cjs} +86 -29
  23. package/dist/chunk-QJ7RCCU7.mjs +704 -0
  24. package/dist/chunk-UCBUCX2W.mjs +3169 -0
  25. package/dist/{chunk-YCQZJQO6.cjs → chunk-VPDCGD2D.cjs} +622 -880
  26. package/dist/{chunk-7ICSHJFE.cjs → chunk-X4D52IZK.cjs} +1501 -176
  27. package/dist/claim.cjs +5 -7
  28. package/dist/claim.d.cts +3 -3
  29. package/dist/claim.d.ts +3 -3
  30. package/dist/claim.mjs +4 -6
  31. package/dist/{constants-DBrWhJWE.d.cts → constants-BT4ctuHo.d.cts} +7 -6
  32. package/dist/{constants-DBrWhJWE.d.ts → constants-D21ZdNOP.d.ts} +7 -6
  33. package/dist/constants.cjs +3 -3
  34. package/dist/constants.d.cts +3 -3
  35. package/dist/constants.d.ts +3 -3
  36. package/dist/constants.mjs +2 -2
  37. package/dist/deposit.cjs +7 -8
  38. package/dist/deposit.d.cts +3 -3
  39. package/dist/deposit.d.ts +3 -3
  40. package/dist/deposit.mjs +6 -7
  41. package/dist/embed.cjs +135 -44
  42. package/dist/embed.d.cts +2 -2
  43. package/dist/embed.d.ts +2 -2
  44. package/dist/embed.mjs +116 -25
  45. package/dist/index.cjs +13 -11
  46. package/dist/index.d.cts +3 -3
  47. package/dist/index.d.ts +3 -3
  48. package/dist/index.mjs +12 -10
  49. package/dist/polymarket.cjs +6 -6
  50. package/dist/polymarket.mjs +2 -2
  51. package/dist/styles.css +132 -100
  52. package/dist/{types-Bho4OA03.d.ts → types-CQ0NHqCy.d.ts} +146 -11
  53. package/dist/{types-DP_3KwlD.d.cts → types-CxiLX5sv.d.cts} +146 -11
  54. package/dist/withdraw.cjs +6 -6
  55. package/dist/withdraw.d.cts +4 -4
  56. package/dist/withdraw.d.ts +4 -4
  57. package/dist/withdraw.mjs +5 -5
  58. package/package.json +7 -6
  59. package/dist/ClaimModal-IKTJU43Y.cjs +0 -13
  60. package/dist/ClaimModal-SEKNWRMA.mjs +0 -13
  61. package/dist/WithdrawModal-5ICGD4HJ.mjs +0 -12
  62. package/dist/WithdrawModal-VP6PMIRO.cjs +0 -12
  63. package/dist/chunk-7SR7ENVJ.mjs +0 -1844
  64. package/dist/chunk-CFKC77SV.mjs +0 -1062
  65. package/dist/chunk-LZFRL2AL.cjs +0 -81
  66. package/dist/chunk-WUJIKCFU.mjs +0 -81
  67. package/dist/chunk-X2IPAPXU.cjs +0 -163
  68. package/dist/chunk-YWMWI7PZ.cjs +0 -1062
  69. package/dist/chunk-ZEO6ADM3.mjs +0 -163
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  MODAL_VERSION,
3
3
  serviceHeaders
4
- } from "./chunk-K4H6TGBE.mjs";
4
+ } from "./chunk-CXBMIZUF.mjs";
5
5
  import {
6
6
  CHAIN_DISPLAY_ORDER,
7
7
  HYPERCORE_CHAIN_ID,
@@ -10,9 +10,14 @@ import {
10
10
  ICON_CDN,
11
11
  NATIVE_TOKEN_ADDRESS,
12
12
  SOLANA_MAINNET_CAIP2,
13
+ STELLAR_PUBNET_CAIP2,
14
+ TRON_MAINNET_CAIP2,
15
+ displayChainIdForCaip2,
13
16
  findTokenDecimals,
17
+ getChainIcon,
14
18
  getChainName,
15
19
  getExplorerTxUrl,
20
+ getRuntimeTokenByAddress,
16
21
  getSolanaTokenByMint,
17
22
  getTokenAddress,
18
23
  getTokenDecimalsByAddress,
@@ -26,7 +31,7 @@ import {
26
31
  setRuntimeTokens,
27
32
  toEvmCaip2,
28
33
  tokenIconUrl
29
- } from "./chunk-VUATPOWJ.mjs";
34
+ } from "./chunk-EAGMY3QE.mjs";
30
35
 
31
36
  // src/components/ui/Modal.tsx
32
37
  import {
@@ -50,7 +55,8 @@ function Modal({
50
55
  children,
51
56
  className = "",
52
57
  inline = false,
53
- closeOnOverlayClick = false
58
+ closeOnOverlayClick = false,
59
+ ariaLabel
54
60
  }) {
55
61
  const overlayRef = useRef(null);
56
62
  const contentRef = useRef(null);
@@ -137,7 +143,7 @@ function Modal({
137
143
  onKeyDown: handleKeyDown,
138
144
  role: "dialog",
139
145
  "aria-modal": "true",
140
- "aria-labelledby": "rs-modal-title",
146
+ "aria-label": ariaLabel,
141
147
  children: /* @__PURE__ */ jsx(
142
148
  "div",
143
149
  {
@@ -360,9 +366,82 @@ function CdnIcon({
360
366
  }
361
367
  CdnIcon.displayName = "CdnIcon";
362
368
 
369
+ // src/components/ui/ListRow.tsx
370
+ import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
371
+ function ListRow({
372
+ leading,
373
+ leadingMedia,
374
+ title,
375
+ subtitle,
376
+ meta,
377
+ trailing,
378
+ action,
379
+ className = "",
380
+ onClick,
381
+ disabled,
382
+ ...props
383
+ }) {
384
+ const inner = /* @__PURE__ */ jsxs3(Fragment2, { children: [
385
+ leadingMedia ? /* @__PURE__ */ jsx5("span", { className: "rs-list-row-leading rs-list-row-leading--media", children: /* @__PURE__ */ jsx5(CdnIcon, { src: leadingMedia }) }) : leading ? /* @__PURE__ */ jsx5("span", { className: "rs-list-row-leading", children: leading }) : null,
386
+ /* @__PURE__ */ jsxs3("div", { className: "rs-list-row-body", children: [
387
+ /* @__PURE__ */ jsxs3("div", { className: "rs-list-row-text", children: [
388
+ /* @__PURE__ */ jsx5("span", { className: "rs-list-row-title", children: title }),
389
+ subtitle && /* @__PURE__ */ jsx5("span", { className: "rs-list-row-subtitle", children: subtitle })
390
+ ] }),
391
+ action ? /* @__PURE__ */ jsx5(
392
+ "button",
393
+ {
394
+ type: "button",
395
+ className: "rs-list-row-action",
396
+ disabled,
397
+ onClick: (e) => {
398
+ e.stopPropagation();
399
+ action.onClick();
400
+ },
401
+ children: action.label
402
+ }
403
+ ) : meta && /* @__PURE__ */ jsx5("div", { className: "rs-list-row-meta", children: meta })
404
+ ] }),
405
+ /* @__PURE__ */ jsx5("span", { className: "rs-list-row-chevron", children: trailing ?? (disabled ? null : /* @__PURE__ */ jsx5(ChevronRightIcon, {})) })
406
+ ] });
407
+ if (action) {
408
+ const handleKey = (e) => {
409
+ if (disabled) return;
410
+ if (e.key === "Enter" || e.key === " ") {
411
+ e.preventDefault();
412
+ onClick?.(e);
413
+ }
414
+ };
415
+ return /* @__PURE__ */ jsx5(
416
+ "div",
417
+ {
418
+ className: `rs-list-row ${className}`.trim(),
419
+ role: "button",
420
+ tabIndex: disabled ? -1 : 0,
421
+ "aria-disabled": disabled || void 0,
422
+ onClick: disabled ? void 0 : (e) => onClick?.(e),
423
+ onKeyDown: handleKey,
424
+ children: inner
425
+ }
426
+ );
427
+ }
428
+ return /* @__PURE__ */ jsx5(
429
+ "button",
430
+ {
431
+ type: "button",
432
+ className: `rs-list-row ${className}`.trim(),
433
+ onClick,
434
+ disabled,
435
+ ...props,
436
+ children: inner
437
+ }
438
+ );
439
+ }
440
+ ListRow.displayName = "ListRow";
441
+
363
442
  // src/components/ui/PoweredBy.tsx
364
- import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
365
- var rhinestoneLogo = /* @__PURE__ */ jsxs3(
443
+ import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
444
+ var rhinestoneLogo = /* @__PURE__ */ jsxs4(
366
445
  "svg",
367
446
  {
368
447
  className: "rs-powered-by-logo",
@@ -371,8 +450,8 @@ var rhinestoneLogo = /* @__PURE__ */ jsxs3(
371
450
  xmlns: "http://www.w3.org/2000/svg",
372
451
  "aria-hidden": "true",
373
452
  children: [
374
- /* @__PURE__ */ jsxs3("g", { fill: "currentColor", clipPath: "url(#rs-pb-clip)", children: [
375
- /* @__PURE__ */ jsx5(
453
+ /* @__PURE__ */ jsxs4("g", { fill: "currentColor", clipPath: "url(#rs-pb-clip)", children: [
454
+ /* @__PURE__ */ jsx6(
376
455
  "path",
377
456
  {
378
457
  opacity: "0.5",
@@ -381,8 +460,8 @@ var rhinestoneLogo = /* @__PURE__ */ jsxs3(
381
460
  d: "M10.48 14.82a4.3 4.3 0 0 1-2.9 1 4.3 4.3 0 0 1-2.4-1 25 25 0 0 1-2.08-1.95l-.13-.13c-.78-.78-1.46-1.46-1.94-2.08a4.3 4.3 0 0 1-1-2.9c.05-.96.48-1.72 1-2.4a25 25 0 0 1 1.94-2.08l.07-.06.06-.07a25 25 0 0 1 2.08-1.94 4.3 4.3 0 0 1 2.9-1c.96.05 1.73.48 2.4 1 .62.49 1.3 1.17 2.08 1.94l.13.13c.77.78 1.46 1.46 1.94 2.09a4.3 4.3 0 0 1 1 2.9 4.3 4.3 0 0 1-1 2.39c-.48.62-1.17 1.3-1.94 2.08l-.07.07-.06.06c-.78.78-1.46 1.46-2.08 1.94m-8.9-6.63c.07 1.02.9 1.86 2.56 3.52s2.5 2.5 3.53 2.56h.32c1.03-.06 1.86-.9 3.53-2.56s2.5-2.5 2.56-3.52v-.33c-.07-1.03-.9-1.86-2.56-3.52-1.67-1.67-2.5-2.5-3.53-2.56h-.32c-1.03.06-1.86.89-3.53 2.56-1.66 1.66-2.5 2.5-2.56 3.52z"
382
461
  }
383
462
  ),
384
- /* @__PURE__ */ jsx5("path", { d: "M3.66 8.01q.02-.27.28-.35a4.6 4.6 0 0 0 2.53-1.48q.72-.8 1-2.05a.4.4 0 0 1 .36-.29c.17 0 .32.12.36.29a4.6 4.6 0 0 0 1.47 2.52c.55.49 1.21.8 2.06 1a.4.4 0 0 1 .28.36.4.4 0 0 1-.28.36 4.6 4.6 0 0 0-2.53 1.47 4.6 4.6 0 0 0-1 2.06.4.4 0 0 1-.36.28.4.4 0 0 1-.36-.28A4.6 4.6 0 0 0 6 9.38a4.6 4.6 0 0 0-2.06-1.01.4.4 0 0 1-.28-.36m26.46-3.44c0 .51.38.87.96.87s.95-.36.95-.87c0-.52-.37-.86-.95-.86s-.96.34-.96.86m.2 1.44v5.33h1.53V6.01zm-4.4 5.33h-1.55V3.88h1.54v2.98c.25-.5.8-1.01 1.6-1.01 1.29 0 1.87.83 1.87 2.28v3.21h-1.54V8.3c0-.77-.34-1.16-.92-1.16-.67 0-1 .53-1 1.3zm-4.45 0h-1.54V6.01h1.54l-.27 1.22a.1.1 0 0 0 .02.1.1.1 0 0 0 .1.04q.09 0 .1-.09c.24-.84.93-1.36 1.64-1.36q.4.01.57.05v1.42l-.67-.04c-.67 0-1.5.31-1.5 2zm13 0h-1.55V6.01h1.54l-.02.9a1.8 1.8 0 0 1 1.61-1.06c1.3 0 1.88.83 1.88 2.28v3.21H36.4V8.3c0-.77-.35-1.16-.93-1.16-.67 0-1 .53-1 1.3z" }),
385
- /* @__PURE__ */ jsx5(
463
+ /* @__PURE__ */ jsx6("path", { d: "M3.66 8.01q.02-.27.28-.35a4.6 4.6 0 0 0 2.53-1.48q.72-.8 1-2.05a.4.4 0 0 1 .36-.29c.17 0 .32.12.36.29a4.6 4.6 0 0 0 1.47 2.52c.55.49 1.21.8 2.06 1a.4.4 0 0 1 .28.36.4.4 0 0 1-.28.36 4.6 4.6 0 0 0-2.53 1.47 4.6 4.6 0 0 0-1 2.06.4.4 0 0 1-.36.28.4.4 0 0 1-.36-.28A4.6 4.6 0 0 0 6 9.38a4.6 4.6 0 0 0-2.06-1.01.4.4 0 0 1-.28-.36m26.46-3.44c0 .51.38.87.96.87s.95-.36.95-.87c0-.52-.37-.86-.95-.86s-.96.34-.96.86m.2 1.44v5.33h1.53V6.01zm-4.4 5.33h-1.55V3.88h1.54v2.98c.25-.5.8-1.01 1.6-1.01 1.29 0 1.87.83 1.87 2.28v3.21h-1.54V8.3c0-.77-.34-1.16-.92-1.16-.67 0-1 .53-1 1.3zm-4.45 0h-1.54V6.01h1.54l-.27 1.22a.1.1 0 0 0 .02.1.1.1 0 0 0 .1.04q.09 0 .1-.09c.24-.84.93-1.36 1.64-1.36q.4.01.57.05v1.42l-.67-.04c-.67 0-1.5.31-1.5 2zm13 0h-1.55V6.01h1.54l-.02.9a1.8 1.8 0 0 1 1.61-1.06c1.3 0 1.88.83 1.88 2.28v3.21H36.4V8.3c0-.77-.35-1.16-.93-1.16-.67 0-1 .53-1 1.3z" }),
464
+ /* @__PURE__ */ jsx6(
386
465
  "path",
387
466
  {
388
467
  fillRule: "evenodd",
@@ -390,8 +469,8 @@ var rhinestoneLogo = /* @__PURE__ */ jsxs3(
390
469
  d: "M38.74 8.69c0 1.63 1.01 2.82 2.7 2.82 1.51 0 2.32-.82 2.55-1.73l-1.43-.26c-.1.37-.47.82-1.12.82-.67 0-1.23-.6-1.24-1.31H44q.05-.19.06-.56a2.55 2.55 0 0 0-2.6-2.63c-1.5 0-2.72 1.2-2.72 2.85m3.82-.58h-2.3a1.2 1.2 0 0 1 1.18-1.13c.6 0 1.14.45 1.12 1.13"
391
470
  }
392
471
  ),
393
- /* @__PURE__ */ jsx5("path", { d: "M47.1 11.51c-1.2 0-2.33-.41-2.55-1.65l1.43-.21q.27.8 1.1.79c.5 0 .77-.24.77-.55 0-.27-.2-.45-.75-.55l-.5-.1c-1.1-.24-1.77-.74-1.77-1.63 0-1.06.91-1.78 2.25-1.78 1.26 0 2.2.59 2.32 1.68l-1.41.22c-.07-.52-.43-.82-.91-.82-.5 0-.75.26-.75.57 0 .25.17.42.63.51l.5.1c1.28.26 1.94.77 1.94 1.75 0 1.01-1.03 1.66-2.3 1.66" }),
394
- /* @__PURE__ */ jsx5(
472
+ /* @__PURE__ */ jsx6("path", { d: "M47.1 11.51c-1.2 0-2.33-.41-2.55-1.65l1.43-.21q.27.8 1.1.79c.5 0 .77-.24.77-.55 0-.27-.2-.45-.75-.55l-.5-.1c-1.1-.24-1.77-.74-1.77-1.63 0-1.06.91-1.78 2.25-1.78 1.26 0 2.2.59 2.32 1.68l-1.41.22c-.07-.52-.43-.82-.91-.82-.5 0-.75.26-.75.57 0 .25.17.42.63.51l.5.1c1.28.26 1.94.77 1.94 1.75 0 1.01-1.03 1.66-2.3 1.66" }),
473
+ /* @__PURE__ */ jsx6(
395
474
  "path",
396
475
  {
397
476
  fillRule: "evenodd",
@@ -399,8 +478,8 @@ var rhinestoneLogo = /* @__PURE__ */ jsxs3(
399
478
  d: "M54.44 8.68c0 1.53 1.08 2.83 2.78 2.83s2.79-1.3 2.79-2.83c0-1.55-1.1-2.84-2.79-2.84-1.7 0-2.78 1.29-2.78 2.84m4.02 0c0 .98-.59 1.45-1.24 1.45-.64 0-1.23-.47-1.23-1.45 0-.97.59-1.47 1.23-1.47.65 0 1.24.48 1.24 1.47"
400
479
  }
401
480
  ),
402
- /* @__PURE__ */ jsx5("path", { d: "M62.4 11.34h-1.53V6.01h1.54l-.02.9a1.8 1.8 0 0 1 1.6-1.06c1.3 0 1.89.83 1.89 2.28v3.21h-1.54V8.3c0-.77-.34-1.16-.93-1.16-.66 0-1 .53-1 1.3z" }),
403
- /* @__PURE__ */ jsx5(
481
+ /* @__PURE__ */ jsx6("path", { d: "M62.4 11.34h-1.53V6.01h1.54l-.02.9a1.8 1.8 0 0 1 1.6-1.06c1.3 0 1.89.83 1.89 2.28v3.21h-1.54V8.3c0-.77-.34-1.16-.93-1.16-.66 0-1 .53-1 1.3z" }),
482
+ /* @__PURE__ */ jsx6(
404
483
  "path",
405
484
  {
406
485
  fillRule: "evenodd",
@@ -408,16 +487,16 @@ var rhinestoneLogo = /* @__PURE__ */ jsxs3(
408
487
  d: "M66.68 8.69c0 1.63 1.02 2.82 2.71 2.82 1.51 0 2.31-.82 2.55-1.73l-1.44-.26c-.1.37-.47.82-1.12.82-.67 0-1.23-.6-1.24-1.31h3.8q.06-.19.06-.56a2.55 2.55 0 0 0-2.6-2.63c-1.5 0-2.72 1.2-2.72 2.85m3.82-.58h-2.3a1.2 1.2 0 0 1 1.18-1.13c.6 0 1.15.45 1.12 1.13"
409
488
  }
410
489
  ),
411
- /* @__PURE__ */ jsx5("path", { d: "M52.44 9.05V7.26h1.53V6h-1.53V4.42h-1.53V6h-1.1v1.26h1.1v1.85l.02.49a1.9 1.9 0 0 0 1.67 1.67c.22.03.47.03.62.03h.65V9.87h-.61c-.4 0-.59 0-.7-.12-.12-.11-.12-.3-.12-.64z" })
490
+ /* @__PURE__ */ jsx6("path", { d: "M52.44 9.05V7.26h1.53V6h-1.53V4.42h-1.53V6h-1.1v1.26h1.1v1.85l.02.49a1.9 1.9 0 0 0 1.67 1.67c.22.03.47.03.62.03h.65V9.87h-.61c-.4 0-.59 0-.7-.12-.12-.11-.12-.3-.12-.64z" })
412
491
  ] }),
413
- /* @__PURE__ */ jsx5("defs", { children: /* @__PURE__ */ jsx5("clipPath", { id: "rs-pb-clip", children: /* @__PURE__ */ jsx5("path", { fill: "#fff", d: "M0 0h72v16H0z" }) }) })
492
+ /* @__PURE__ */ jsx6("defs", { children: /* @__PURE__ */ jsx6("clipPath", { id: "rs-pb-clip", children: /* @__PURE__ */ jsx6("path", { fill: "#fff", d: "M0 0h72v16H0z" }) }) })
414
493
  ]
415
494
  }
416
495
  );
417
496
  function PoweredBy() {
418
- return /* @__PURE__ */ jsxs3("div", { className: "rs-powered-by", "aria-label": "Powered by Rhinestone", children: [
419
- /* @__PURE__ */ jsx5("span", { children: "Powered by" }),
420
- /* @__PURE__ */ jsx5(
497
+ return /* @__PURE__ */ jsxs4("div", { className: "rs-powered-by", "aria-label": "Powered by Rhinestone", children: [
498
+ /* @__PURE__ */ jsx6("span", { children: "Powered by" }),
499
+ /* @__PURE__ */ jsx6(
421
500
  "a",
422
501
  {
423
502
  className: "rs-powered-by-link",
@@ -505,7 +584,7 @@ function parseExplorer(value) {
505
584
  return { url, addressPath, txPath };
506
585
  }
507
586
  function parseVmType(value) {
508
- return value === "evm" || value === "svm" || value === "tvm" ? value : null;
587
+ return value === "evm" || value === "svm" || value === "tvm" || value === "stellar" ? value : null;
509
588
  }
510
589
  function parseOptionalString(value) {
511
590
  return typeof value === "string" && value.trim() !== "" ? value.trim() : null;
@@ -578,6 +657,8 @@ function aliasHyperCoreOrigin(byCaip2, all) {
578
657
  }
579
658
  function catalogKeyForChain(chainId) {
580
659
  if (chainId === "solana") return SOLANA_MAINNET_CAIP2;
660
+ if (chainId === "tron") return TRON_MAINNET_CAIP2;
661
+ if (chainId === "stellar") return STELLAR_PUBNET_CAIP2;
581
662
  if (chainId === "hypercore" || chainId === HYPERCORE_CHAIN_ID) {
582
663
  return HYPERCORE_SPOT_CAIP2;
583
664
  }
@@ -852,6 +933,13 @@ var PermitDepositSubmitError = class extends Error {
852
933
  this.name = "PermitDepositSubmitError";
853
934
  }
854
935
  };
936
+ var RegistrationError = class extends Error {
937
+ constructor(message, status) {
938
+ super(message);
939
+ this.status = status;
940
+ this.name = "RegistrationError";
941
+ }
942
+ };
855
943
  function createDepositService(baseUrl, options) {
856
944
  const normalizedBaseUrl = baseUrl.replace(/\/$/, "");
857
945
  const debug = options?.debug === true;
@@ -984,7 +1072,10 @@ function createDepositService(baseUrl, options) {
984
1072
  });
985
1073
  const detail = Array.isArray(error.details) ? error.details.map((d) => d?.message).filter(Boolean).join("; ") : void 0;
986
1074
  const base = error.error || `Account registration failed: ${response.status}`;
987
- throw new Error(detail ? `${base}: ${detail}` : base);
1075
+ throw new RegistrationError(
1076
+ detail ? `${base}: ${detail}` : base,
1077
+ response.status
1078
+ );
988
1079
  }
989
1080
  const result = await response.json();
990
1081
  debugLog(debug, scope, "registerManagedAccount:success", {
@@ -2228,7 +2319,7 @@ function needsViemChains(catalog, overrides) {
2228
2319
  }
2229
2320
 
2230
2321
  // src/core/chain-catalog-context.tsx
2231
- import { jsx as jsx6 } from "react/jsx-runtime";
2322
+ import { jsx as jsx7 } from "react/jsx-runtime";
2232
2323
  var EMPTY = {
2233
2324
  catalog: null,
2234
2325
  viemChains: null,
@@ -2265,14 +2356,25 @@ function peekRuntimeChains(backendUrl, overrides) {
2265
2356
  }
2266
2357
  function publishCatalogTokens(catalog) {
2267
2358
  setRuntimeTokens(
2268
- catalog.all.flatMap(
2269
- (chain) => chain.chainId === null || !Array.isArray(chain.supportedTokens) ? [] : chain.supportedTokens.map((token) => ({
2270
- chainId: chain.chainId,
2359
+ catalog.all.flatMap((chain) => {
2360
+ const chainId = displayChainIdForCaip2(chain.caip2);
2361
+ if (chainId === null || !Array.isArray(chain.supportedTokens)) return [];
2362
+ const tokens = chain.supportedTokens.map((token) => ({
2363
+ chainId,
2271
2364
  symbol: token.symbol,
2272
2365
  address: token.address,
2273
2366
  decimals: token.decimals
2274
- }))
2275
- )
2367
+ }));
2368
+ if (typeof chainId === "string") {
2369
+ tokens.push({
2370
+ chainId,
2371
+ symbol: chain.nativeToken.symbol,
2372
+ address: "native",
2373
+ decimals: chain.nativeToken.decimals
2374
+ });
2375
+ }
2376
+ return tokens;
2377
+ })
2276
2378
  );
2277
2379
  }
2278
2380
  function publishRuntimeChainMeta(catalog) {
@@ -2280,13 +2382,17 @@ function publishRuntimeChainMeta(catalog) {
2280
2382
  catalog.all.flatMap((chain) => {
2281
2383
  const ids = [];
2282
2384
  if (chain.chainId !== null) ids.push(chain.chainId);
2385
+ const sentinel = displayChainIdForCaip2(chain.caip2);
2386
+ if (sentinel !== null && sentinel !== chain.chainId) ids.push(sentinel);
2283
2387
  if (isHyperCoreCaip2(chain.caip2)) ids.push(HYPERCORE_CHAIN_ID);
2284
2388
  return ids.map((chainId) => ({
2285
2389
  chainId,
2286
2390
  name: chain.name,
2287
2391
  iconUrl: chain.iconUrl ?? void 0,
2288
2392
  nativeSymbol: chain.nativeToken.symbol,
2289
- explorerUrl: chain.explorer?.url
2393
+ explorerUrl: chain.explorer?.url,
2394
+ explorerTxPath: chain.explorer?.txPath,
2395
+ explorerAddressPath: chain.explorer?.addressPath
2290
2396
  }));
2291
2397
  })
2292
2398
  );
@@ -2497,7 +2603,7 @@ function ChainCatalogProvider({
2497
2603
  }),
2498
2604
  [catalog, viemChains, isLoading, shortlist, clientCapableChainIds]
2499
2605
  );
2500
- return /* @__PURE__ */ jsx6(ChainCatalogContext.Provider, { value, children });
2606
+ return /* @__PURE__ */ jsx7(ChainCatalogContext.Provider, { value, children });
2501
2607
  }
2502
2608
 
2503
2609
  // src/core/useLatestRef.ts
@@ -2511,16 +2617,16 @@ function useLatestRef(value) {
2511
2617
  }
2512
2618
 
2513
2619
  // src/components/ui/Spinner.tsx
2514
- import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
2620
+ import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
2515
2621
  function Spinner({ className }) {
2516
- return /* @__PURE__ */ jsxs4(
2622
+ return /* @__PURE__ */ jsxs5(
2517
2623
  "svg",
2518
2624
  {
2519
2625
  className: `rs-spinner ${className || ""}`,
2520
2626
  fill: "none",
2521
2627
  viewBox: "0 0 20 21",
2522
2628
  children: [
2523
- /* @__PURE__ */ jsx7(
2629
+ /* @__PURE__ */ jsx8(
2524
2630
  "path",
2525
2631
  {
2526
2632
  d: "M10 0.5C8.02 0.5 6.08 1.08 4.44 2.18C2.79 3.28 1.51 4.84 0.76 6.67C0.00 8.50 -0.19 10.51 0.19 12.45C0.57 14.39 1.53 16.17 2.92 17.57C4.32 18.96 6.10 19.92 8.04 20.30C9.98 20.69 11.99 20.49 13.82 19.73C15.65 18.98 17.21 17.70 18.31 16.05C19.41 14.41 20 12.47 20 10.5C20 7.84 18.94 5.30 17.07 3.42C15.19 1.55 12.65 0.5 10 0.5ZM10 17.77C8.56 17.77 7.15 17.34 5.95 16.54C4.76 15.74 3.83 14.61 3.28 13.28C2.73 11.95 2.58 10.49 2.86 9.08C3.14 7.67 3.84 6.37 4.85 5.35C5.87 4.34 7.17 3.64 8.58 3.36C9.99 3.08 11.45 3.23 12.78 3.78C14.11 4.33 15.24 5.26 16.04 6.45C16.84 7.65 17.27 9.06 17.27 10.5C17.27 12.42 16.50 14.27 15.14 15.64C13.77 17.00 11.92 17.77 10 17.77Z",
@@ -2528,7 +2634,7 @@ function Spinner({ className }) {
2528
2634
  opacity: 0.3
2529
2635
  }
2530
2636
  ),
2531
- /* @__PURE__ */ jsx7(
2637
+ /* @__PURE__ */ jsx8(
2532
2638
  "path",
2533
2639
  {
2534
2640
  d: "M10 3.22C11.74 3.22 13.42 3.84 14.75 4.95C16.08 6.07 16.96 7.61 17.25 9.31C17.30 9.64 17.46 9.94 17.71 10.15C17.96 10.37 18.28 10.49 18.62 10.5C18.82 10.50 19.01 10.45 19.20 10.37C19.38 10.29 19.54 10.16 19.67 10.01C19.80 9.86 19.89 9.68 19.95 9.49C20.00 9.30 20.01 9.10 19.98 8.90C19.59 6.56 18.38 4.42 16.55 2.88C14.72 1.34 12.40 0.5 10 0.5C7.59 0.5 5.27 1.34 3.44 2.88C1.61 4.42 0.40 6.56 0.01 8.90C-0.01 9.10 -0.00 9.30 0.04 9.49C0.10 9.68 0.19 9.86 0.32 10.01C0.45 10.16 0.61 10.29 0.79 10.37C0.98 10.45 1.17 10.50 1.37 10.5C1.71 10.49 2.03 10.37 2.28 10.15C2.53 9.94 2.69 9.64 2.74 9.31C3.03 7.61 3.91 6.07 5.24 4.95C6.57 3.84 8.25 3.22 10 3.22Z",
@@ -2541,7 +2647,7 @@ function Spinner({ className }) {
2541
2647
  }
2542
2648
 
2543
2649
  // src/components/ui/Button.tsx
2544
- import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
2650
+ import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
2545
2651
  function Button({
2546
2652
  children,
2547
2653
  variant = "accent",
@@ -2561,79 +2667,25 @@ function Button({
2561
2667
  className
2562
2668
  ].filter(Boolean).join(" ");
2563
2669
  const showInlineLoadingText = loading && loadingText !== void 0;
2564
- return /* @__PURE__ */ jsx8(
2670
+ return /* @__PURE__ */ jsx9(
2565
2671
  "button",
2566
2672
  {
2567
2673
  className: classes,
2568
2674
  disabled: disabled || loading,
2569
2675
  "aria-busy": loading || void 0,
2570
2676
  ...props,
2571
- children: showInlineLoadingText ? /* @__PURE__ */ jsxs5("span", { className: "rs-button__loading-row", children: [
2572
- /* @__PURE__ */ jsx8(Spinner, { className: "rs-spinner--sm" }),
2573
- /* @__PURE__ */ jsx8("span", { children: loadingText })
2574
- ] }) : /* @__PURE__ */ jsxs5(Fragment2, { children: [
2575
- /* @__PURE__ */ jsx8("span", { className: loading ? "rs-button__content--hidden" : "", children }),
2576
- loading && /* @__PURE__ */ jsx8("span", { className: "rs-button__spinner", children: /* @__PURE__ */ jsx8(Spinner, { className: "rs-spinner--sm" }) })
2677
+ children: showInlineLoadingText ? /* @__PURE__ */ jsxs6("span", { className: "rs-button__loading-row", children: [
2678
+ /* @__PURE__ */ jsx9(Spinner, { className: "rs-spinner--sm" }),
2679
+ /* @__PURE__ */ jsx9("span", { children: loadingText })
2680
+ ] }) : /* @__PURE__ */ jsxs6(Fragment3, { children: [
2681
+ /* @__PURE__ */ jsx9("span", { className: loading ? "rs-button__content--hidden" : "", children }),
2682
+ loading && /* @__PURE__ */ jsx9("span", { className: "rs-button__spinner", children: /* @__PURE__ */ jsx9(Spinner, { className: "rs-spinner--sm" }) })
2577
2683
  ] })
2578
2684
  }
2579
2685
  );
2580
2686
  }
2581
2687
  Button.displayName = "Button";
2582
2688
 
2583
- // src/components/ui/Callout.tsx
2584
- import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
2585
- function CircleAlertIcon() {
2586
- return /* @__PURE__ */ jsx9(
2587
- "svg",
2588
- {
2589
- width: "16",
2590
- height: "16",
2591
- viewBox: "0 0 16 16",
2592
- fill: "none",
2593
- xmlns: "http://www.w3.org/2000/svg",
2594
- "aria-hidden": "true",
2595
- children: /* @__PURE__ */ jsx9(
2596
- "path",
2597
- {
2598
- d: "M10 5.99L6 9.99M6 5.99L10 9.99M14.66 7.99C14.66 11.68 11.68 14.66 8 14.66C4.31 14.66 1.33 11.68 1.33 7.99C1.33 4.31 4.31 1.33 8 1.33C11.68 1.33 14.66 4.31 14.66 7.99Z",
2599
- stroke: "currentColor",
2600
- strokeWidth: "1.33",
2601
- strokeLinecap: "round",
2602
- strokeLinejoin: "round"
2603
- }
2604
- )
2605
- }
2606
- );
2607
- }
2608
- function Callout({ variant = "error", children, role }) {
2609
- return /* @__PURE__ */ jsxs6(
2610
- "div",
2611
- {
2612
- className: `rs-callout rs-callout--${variant}`,
2613
- role: role ?? (variant === "error" ? "alert" : "status"),
2614
- children: [
2615
- /* @__PURE__ */ jsx9("span", { className: "rs-callout-icon", children: variant === "error" ? /* @__PURE__ */ jsx9(CircleAlertIcon, {}) : /* @__PURE__ */ jsx9(AlertTriangleIcon, {}) }),
2616
- /* @__PURE__ */ jsx9("span", { className: "rs-callout-text", children })
2617
- ]
2618
- }
2619
- );
2620
- }
2621
- Callout.displayName = "Callout";
2622
-
2623
- // src/components/ui/TokenIcon.tsx
2624
- import { jsx as jsx10 } from "react/jsx-runtime";
2625
- function TokenIcon({ symbol, className, fallback }) {
2626
- return /* @__PURE__ */ jsx10(
2627
- CdnIcon,
2628
- {
2629
- src: tokenIconUrl(symbol),
2630
- className: `rs-token-icon ${className ?? ""}`.trimEnd(),
2631
- fallback
2632
- }
2633
- );
2634
- }
2635
- TokenIcon.displayName = "TokenIcon";
2636
-
2637
2689
  // src/core/formatters.ts
2638
2690
  var currencyFormatter = new Intl.NumberFormat("en-US", {
2639
2691
  style: "currency",
@@ -2768,6 +2820,11 @@ function resolveTokenDisplay(token, chain, fallback) {
2768
2820
  (x) => x.address.toLowerCase() === token.toLowerCase()
2769
2821
  );
2770
2822
  if (t) return { symbol: t.symbol, decimals: t.decimals };
2823
+ } else if (chain === "tron" || chain === "stellar") {
2824
+ const published = getRuntimeTokenByAddress(chain, token);
2825
+ if (published) {
2826
+ return { symbol: published.symbol, decimals: published.decimals };
2827
+ }
2771
2828
  } else if (EVM_ADDRESS_RE.test(token)) {
2772
2829
  const symbol = getTokenSymbol(token, chain);
2773
2830
  const decimals = findTokenDecimals(token, chain);
@@ -2825,6 +2882,9 @@ function isRecognizedToken(address, chain) {
2825
2882
  (t) => t.address.toLowerCase() === address.toLowerCase()
2826
2883
  );
2827
2884
  }
2885
+ if (chain === "tron" || chain === "stellar") {
2886
+ return getRuntimeTokenByAddress(chain, address) !== void 0;
2887
+ }
2828
2888
  return EVM_ADDRESS_RE.test(address) && isRegistryTokenOnChain(address, chain);
2829
2889
  }
2830
2890
  function estimateReceiveAmount(params) {
@@ -2894,8 +2954,12 @@ var FLUSH_DELAY_MS = 5e3;
2894
2954
  var MAX_BODY_BYTES = 48 * 1024;
2895
2955
  var TOKEN_REFRESH_MARGIN_MS = 6e4;
2896
2956
  var TOKEN_TIMEOUT_MS = 3e3;
2957
+ var CLOSE_MINT_WAIT_MS = 1500;
2897
2958
  var MAX_ATTEMPTS = 3;
2898
2959
  var MAX_BACKOFF_MS = 3e4;
2960
+ var IDLE = 0;
2961
+ var CLOSING = 1;
2962
+ var DISMISSAL = 2;
2899
2963
  var ENVELOPE_FIELDS = /* @__PURE__ */ new Set([
2900
2964
  "type",
2901
2965
  "timestamp",
@@ -2930,8 +2994,9 @@ function createIngestTransport(options) {
2930
2994
  let timer = null;
2931
2995
  let sending = false;
2932
2996
  let disposed = false;
2933
- let pendingTerminal = false;
2934
- let terminalRequested = false;
2997
+ let pendingRun = false;
2998
+ let urgency = IDLE;
2999
+ let minting = null;
2935
3000
  let mintAbort = null;
2936
3001
  const sleepers = /* @__PURE__ */ new Set();
2937
3002
  function report(reason, status) {
@@ -3013,7 +3078,7 @@ function createIngestTransport(options) {
3013
3078
  signal: controller?.signal
3014
3079
  });
3015
3080
  } catch {
3016
- if (!terminalRequested) {
3081
+ if (urgency !== DISMISSAL) {
3017
3082
  mintFailures += 1;
3018
3083
  mintBackoffUntil = now() + backoff(mintFailures);
3019
3084
  }
@@ -3045,19 +3110,28 @@ function createIngestTransport(options) {
3045
3110
  report("token_unavailable", response.status);
3046
3111
  }
3047
3112
  }
3048
- async function ensureToken() {
3113
+ function startMint() {
3114
+ if (!minting) {
3115
+ minting = mintToken().finally(() => {
3116
+ minting = null;
3117
+ });
3118
+ }
3119
+ return minting;
3120
+ }
3121
+ async function ensureToken(maxWaitMs) {
3049
3122
  if (mintUnavailable) return;
3050
3123
  if (token && token.expiresAt - now() > TOKEN_REFRESH_MARGIN_MS) return;
3051
3124
  if (now() < mintBackoffUntil) return;
3052
- await mintToken();
3125
+ const pending = startMint();
3126
+ await (maxWaitMs === void 0 ? pending : Promise.race([pending, sleep(maxWaitMs)]));
3053
3127
  }
3054
- async function deliver(batch, isTerminal) {
3128
+ async function deliver(batch) {
3055
3129
  if (!fetchImpl) return drop(batch, "unsupported");
3056
3130
  let attempt = 0;
3057
3131
  let refreshed = false;
3058
3132
  let unattributed = false;
3059
3133
  for (; ; ) {
3060
- const terminal = isTerminal || terminalRequested;
3134
+ const terminal = urgency === DISMISSAL;
3061
3135
  attempt += 1;
3062
3136
  const headers = {
3063
3137
  "Content-Type": "application/json"
@@ -3084,7 +3158,7 @@ function createIngestTransport(options) {
3084
3158
  token = null;
3085
3159
  if (!refreshed && !terminal) {
3086
3160
  refreshed = true;
3087
- await mintToken();
3161
+ await startMint();
3088
3162
  if (token) continue;
3089
3163
  }
3090
3164
  if (!unattributed) {
@@ -3104,33 +3178,47 @@ function createIngestTransport(options) {
3104
3178
  return drop(batch, "rejected", status);
3105
3179
  }
3106
3180
  }
3107
- async function run(requestedTerminal) {
3108
- if (requestedTerminal) terminalRequested = true;
3181
+ function escalate(level) {
3182
+ if (level <= urgency) return;
3183
+ urgency = level;
3184
+ if (level === DISMISSAL) interruptForUnload();
3185
+ }
3186
+ function onDismissal(event) {
3187
+ if (event.type === "pagehide" || document.visibilityState === "hidden") {
3188
+ escalate(DISMISSAL);
3189
+ }
3190
+ }
3191
+ function dismissalGuard(attach) {
3192
+ if (typeof window === "undefined" || typeof document === "undefined") return;
3193
+ const bind = attach ? "addEventListener" : "removeEventListener";
3194
+ window[bind]("pagehide", onDismissal);
3195
+ document[bind]("visibilitychange", onDismissal);
3196
+ }
3197
+ async function run(level) {
3198
+ escalate(level);
3109
3199
  if (sending) {
3110
- if (requestedTerminal) {
3111
- pendingTerminal = true;
3112
- interruptForUnload();
3113
- }
3200
+ pendingRun = true;
3114
3201
  return;
3115
3202
  }
3116
3203
  sending = true;
3117
3204
  try {
3118
3205
  while (queue.length > 0) {
3119
- const terminal = requestedTerminal || terminalRequested;
3120
3206
  const batch = takeBatch();
3121
- if (!terminal) await ensureToken();
3122
- await deliver(batch, terminal);
3123
- if (!terminal && disposed) break;
3207
+ if (urgency !== DISMISSAL) {
3208
+ await ensureToken(urgency === CLOSING ? CLOSE_MINT_WAIT_MS : void 0);
3209
+ }
3210
+ await deliver(batch);
3124
3211
  }
3125
3212
  } finally {
3126
3213
  sending = false;
3127
3214
  }
3128
- if (pendingTerminal) {
3129
- pendingTerminal = false;
3130
- await run(true);
3215
+ if (pendingRun) {
3216
+ pendingRun = false;
3217
+ await run(urgency);
3131
3218
  return;
3132
3219
  }
3133
- if (!disposed && queue.length === 0) terminalRequested = false;
3220
+ if (!disposed) urgency = IDLE;
3221
+ else dismissalGuard(false);
3134
3222
  }
3135
3223
  function clearFlushTimer() {
3136
3224
  if (timer !== null) {
@@ -3142,35 +3230,37 @@ function createIngestTransport(options) {
3142
3230
  if (timer !== null || disposed) return;
3143
3231
  timer = setTimeout(() => {
3144
3232
  timer = null;
3145
- void run(false);
3233
+ void run(IDLE);
3146
3234
  }, FLUSH_DELAY_MS);
3147
3235
  }
3148
3236
  return {
3149
3237
  enqueue(event) {
3150
3238
  if (disposed) return;
3151
3239
  queue.push(toWireEvent(event));
3240
+ if (sequence === 1) void ensureToken();
3152
3241
  if (queue.length > MAX_QUEUE) {
3153
3242
  dropped += queue.length - MAX_QUEUE;
3154
3243
  queue.splice(0, queue.length - MAX_QUEUE);
3155
3244
  }
3156
3245
  if (queue.length >= MAX_BATCH) {
3157
3246
  clearFlushTimer();
3158
- void run(false);
3247
+ void run(IDLE);
3159
3248
  } else {
3160
3249
  scheduleFlush();
3161
3250
  }
3162
3251
  },
3163
3252
  flush(flushOptions) {
3164
- const terminal = flushOptions?.terminal ?? false;
3165
- if (disposed && !terminal) return;
3253
+ const dismissal = flushOptions?.terminal ?? false;
3254
+ if (disposed && !dismissal) return;
3166
3255
  clearFlushTimer();
3167
- void run(terminal);
3256
+ void run(dismissal ? DISMISSAL : IDLE);
3168
3257
  },
3169
3258
  dispose() {
3170
3259
  if (disposed) return;
3171
3260
  disposed = true;
3172
3261
  clearFlushTimer();
3173
- void run(true);
3262
+ dismissalGuard(true);
3263
+ void run(CLOSING);
3174
3264
  }
3175
3265
  };
3176
3266
  }
@@ -3201,7 +3291,7 @@ function resolveProxyOrigin(backendUrl) {
3201
3291
  }
3202
3292
 
3203
3293
  // src/core/analytics.tsx
3204
- import { jsx as jsx11 } from "react/jsx-runtime";
3294
+ import { jsx as jsx10 } from "react/jsx-runtime";
3205
3295
  var AnalyticsContext = createContext3(null);
3206
3296
  var noopDepositEmitter = () => {
3207
3297
  };
@@ -3230,6 +3320,7 @@ function AnalyticsSession(props) {
3230
3320
  if (sessionPropertiesRef.current === void 0) {
3231
3321
  sessionPropertiesRef.current = cloneAndFreeze(props.sessionProperties);
3232
3322
  }
3323
+ if (props.sessionIdRef) props.sessionIdRef.current = sessionIdRef.current;
3233
3324
  const onEventRef = useRef3(props.onEvent);
3234
3325
  onEventRef.current = props.onEvent;
3235
3326
  const nowRef = useRef3(props.now ?? (() => /* @__PURE__ */ new Date()));
@@ -3376,7 +3467,7 @@ function AnalyticsSession(props) {
3376
3467
  () => modal === "deposit" ? { modal, emit: emitDeposit } : modal === "withdraw" ? { modal, emit: emitWithdraw } : { modal, emit: emitClaim },
3377
3468
  [modal, emitDeposit, emitWithdraw, emitClaim]
3378
3469
  );
3379
- return /* @__PURE__ */ jsx11(AnalyticsContext.Provider, { value: context, children: props.children });
3470
+ return /* @__PURE__ */ jsx10(AnalyticsContext.Provider, { value: context, children: props.children });
3380
3471
  }
3381
3472
  function useDepositAnalyticsEmitter() {
3382
3473
  const context = useContext3(AnalyticsContext);
@@ -3394,6 +3485,747 @@ function useClaimAnalyticsEmitter() {
3394
3485
  return context.emit;
3395
3486
  }
3396
3487
 
3488
+ // src/core/history-recovery.ts
3489
+ import { isAddress } from "viem";
3490
+ var RECOVERABLE_STATUSES = /* @__PURE__ */ new Set(["failed", "rejected"]);
3491
+ function recoverySigningChainId(row) {
3492
+ return parseEvmChainId(row.targetChain);
3493
+ }
3494
+ function sourceDepositTxHash(row) {
3495
+ return row.sourceTxHash ?? row.txHash;
3496
+ }
3497
+ function toRecoverableDeposit(row, options = {}) {
3498
+ if (!row.id) return null;
3499
+ if (!RECOVERABLE_STATUSES.has((row.status ?? "").toLowerCase())) return null;
3500
+ const sourceChainId = parseEvmChainId(row.chain);
3501
+ const targetChainId = recoverySigningChainId(row);
3502
+ if (sourceChainId === null || targetChainId === null) return null;
3503
+ const signer = row.recipient;
3504
+ if (!signer || !isAddress(signer)) return null;
3505
+ if (options.recipient && options.recipient.toLowerCase() !== signer.toLowerCase()) {
3506
+ return null;
3507
+ }
3508
+ return {
3509
+ depositId: row.id,
3510
+ signer,
3511
+ destinationPrefill: signer,
3512
+ sourceChainId,
3513
+ targetChainId,
3514
+ token: row.token,
3515
+ amountRaw: row.sourceAmount && row.sourceAmount !== "0" ? row.sourceAmount : row.amount,
3516
+ sourceTxHash: sourceDepositTxHash(row)
3517
+ };
3518
+ }
3519
+ function recoveryFailureCause(sourceChainName) {
3520
+ return sourceChainName ? `This deposit couldn't be completed. Your funds are still on ${sourceChainName}.` : "This deposit couldn't be completed and your funds were not moved.";
3521
+ }
3522
+
3523
+ // src/core/recovery-lookup.ts
3524
+ function isRecoveryTxHash(value) {
3525
+ return /^0x[a-fA-F0-9]{64}$/.test(value);
3526
+ }
3527
+ var RECOVERY_LOOKUP_MISS_COPY = {
3528
+ not_found: "No deposits found for this transaction.",
3529
+ none_eligible: "This transaction has no failed or rejected deposits available to recover."
3530
+ };
3531
+ function classifyRecoveryLookup(rows, options = {}) {
3532
+ const inScope = options.recipient ? rows.filter(
3533
+ (row) => row.recipient?.toLowerCase() === options.recipient?.toLowerCase()
3534
+ ) : rows;
3535
+ const eligible = inScope.map((row) => toRecoverableDeposit(row, options)).filter((deposit) => deposit !== null);
3536
+ return {
3537
+ rows: inScope,
3538
+ eligible,
3539
+ miss: inScope.length === 0 ? "not_found" : eligible.length === 0 ? "none_eligible" : null
3540
+ };
3541
+ }
3542
+
3543
+ // src/components/recovery/RecoveryLookupScreen.tsx
3544
+ import { useEffect as useEffect5, useState as useState3 } from "react";
3545
+
3546
+ // src/components/ui/Callout.tsx
3547
+ import { jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
3548
+ function CircleAlertIcon() {
3549
+ return /* @__PURE__ */ jsx11(
3550
+ "svg",
3551
+ {
3552
+ width: "16",
3553
+ height: "16",
3554
+ viewBox: "0 0 16 16",
3555
+ fill: "none",
3556
+ xmlns: "http://www.w3.org/2000/svg",
3557
+ "aria-hidden": "true",
3558
+ children: /* @__PURE__ */ jsx11(
3559
+ "path",
3560
+ {
3561
+ d: "M10 5.99L6 9.99M6 5.99L10 9.99M14.66 7.99C14.66 11.68 11.68 14.66 8 14.66C4.31 14.66 1.33 11.68 1.33 7.99C1.33 4.31 4.31 1.33 8 1.33C11.68 1.33 14.66 4.31 14.66 7.99Z",
3562
+ stroke: "currentColor",
3563
+ strokeWidth: "1.33",
3564
+ strokeLinecap: "round",
3565
+ strokeLinejoin: "round"
3566
+ }
3567
+ )
3568
+ }
3569
+ );
3570
+ }
3571
+ function Callout({ variant = "error", children, role }) {
3572
+ return /* @__PURE__ */ jsxs7(
3573
+ "div",
3574
+ {
3575
+ className: `rs-callout rs-callout--${variant}`,
3576
+ role: role ?? (variant === "error" ? "alert" : "status"),
3577
+ children: [
3578
+ /* @__PURE__ */ jsx11("span", { className: "rs-callout-icon", children: variant === "error" ? /* @__PURE__ */ jsx11(CircleAlertIcon, {}) : /* @__PURE__ */ jsx11(AlertTriangleIcon, {}) }),
3579
+ /* @__PURE__ */ jsx11("span", { className: "rs-callout-text", children })
3580
+ ]
3581
+ }
3582
+ );
3583
+ }
3584
+ Callout.displayName = "Callout";
3585
+
3586
+ // src/components/ui/Input.tsx
3587
+ import { forwardRef } from "react";
3588
+ import { jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
3589
+ var Input = forwardRef(
3590
+ ({ label, error, hint, variant, className = "", ...props }, ref) => {
3591
+ const inputVariant = error ? "error" : variant || "default";
3592
+ return /* @__PURE__ */ jsxs8("div", { className: "rs-input-wrapper", children: [
3593
+ label && /* @__PURE__ */ jsx12("label", { className: "rs-input-label", children: label }),
3594
+ /* @__PURE__ */ jsx12(
3595
+ "input",
3596
+ {
3597
+ ref,
3598
+ className: `rs-input rs-input--${inputVariant} ${className}`,
3599
+ ...props
3600
+ }
3601
+ ),
3602
+ error ? /* @__PURE__ */ jsxs8("p", { className: "rs-input-error", children: [
3603
+ /* @__PURE__ */ jsx12(AlertTriangleIcon, { className: "rs-input-error-icon" }),
3604
+ error
3605
+ ] }) : hint && /* @__PURE__ */ jsx12("p", { className: "rs-input-hint", children: hint })
3606
+ ] });
3607
+ }
3608
+ );
3609
+ Input.displayName = "Input";
3610
+
3611
+ // src/components/recovery/RecoveryLookupScreen.tsx
3612
+ import { jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
3613
+ function RecoveryLookupScreen({
3614
+ title,
3615
+ subtitle,
3616
+ hint,
3617
+ submitLabel = "Find deposit",
3618
+ defaultTxHash,
3619
+ loading,
3620
+ error,
3621
+ onSubmit,
3622
+ onInvalid
3623
+ }) {
3624
+ const [txHash, setTxHash] = useState3(defaultTxHash ?? "");
3625
+ const onInvalidRef = useLatestRef(onInvalid);
3626
+ const trimmed = txHash.trim();
3627
+ const valid = isRecoveryTxHash(trimmed);
3628
+ useEffect5(() => {
3629
+ if (trimmed.length > 0 && !valid) {
3630
+ onInvalidRef.current?.();
3631
+ }
3632
+ }, [trimmed, valid, onInvalidRef]);
3633
+ return /* @__PURE__ */ jsxs9("div", { className: "rs-screen", children: [
3634
+ /* @__PURE__ */ jsxs9("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
3635
+ /* @__PURE__ */ jsx13(
3636
+ BodyHeader,
3637
+ {
3638
+ icon: /* @__PURE__ */ jsx13(HandCoinsIcon, {}),
3639
+ title,
3640
+ subtitle
3641
+ }
3642
+ ),
3643
+ /* @__PURE__ */ jsx13(
3644
+ Input,
3645
+ {
3646
+ label: "Transaction hash",
3647
+ placeholder: "0x\u2026",
3648
+ value: txHash,
3649
+ onChange: (e) => setTxHash(e.target.value),
3650
+ hint,
3651
+ error: trimmed.length > 0 && !valid ? "Enter a valid transaction hash" : void 0
3652
+ }
3653
+ ),
3654
+ error && /* @__PURE__ */ jsx13(Callout, { variant: "error", children: error }),
3655
+ /* @__PURE__ */ jsx13(
3656
+ Button,
3657
+ {
3658
+ onClick: () => valid && onSubmit(trimmed.startsWith("0x") ? trimmed.toLowerCase() : trimmed),
3659
+ loading,
3660
+ loadingText: "Searching\u2026",
3661
+ disabled: !valid,
3662
+ fullWidth: true,
3663
+ children: submitLabel
3664
+ }
3665
+ )
3666
+ ] }),
3667
+ /* @__PURE__ */ jsx13(PoweredBy, {})
3668
+ ] });
3669
+ }
3670
+ RecoveryLookupScreen.displayName = "RecoveryLookupScreen";
3671
+
3672
+ // src/components/recovery/recovery-display.ts
3673
+ import { formatUnits as formatUnits2 } from "viem";
3674
+ function describeRecoveryDeposit(params) {
3675
+ const token = params.token ?? "0x";
3676
+ const decimals = getTokenDecimalsByAddress(token, params.chainId);
3677
+ const symbol = getTokenSymbol(token, params.chainId);
3678
+ const raw = toBigInt(params.amountRaw);
3679
+ const human = Number(formatUnits2(raw, decimals));
3680
+ return {
3681
+ symbol,
3682
+ decimals,
3683
+ amount: formatTokenAmount(human, symbol) ?? formatUnits2(raw, decimals),
3684
+ chainName: getChainName(params.chainId),
3685
+ chainIcon: getChainIcon(params.chainId)
3686
+ };
3687
+ }
3688
+ function formatRecoveryAmount(amountRaw, decimals, symbol) {
3689
+ const raw = toBigInt(amountRaw);
3690
+ return formatTokenAmount(Number(formatUnits2(raw, decimals)), symbol) ?? formatUnits2(raw, decimals);
3691
+ }
3692
+ function toBigInt(value) {
3693
+ try {
3694
+ return BigInt(value || "0");
3695
+ } catch {
3696
+ return 0n;
3697
+ }
3698
+ }
3699
+ function shortenHash(hash) {
3700
+ return `${hash.slice(0, 10)}\u2026${hash.slice(-8)}`;
3701
+ }
3702
+ function shortenAddress(addr) {
3703
+ return addr.length > 12 ? `${addr.slice(0, 6)}\u2026${addr.slice(-4)}` : addr;
3704
+ }
3705
+
3706
+ // src/core/recovery.ts
3707
+ var RECOVER_DOMAIN = {
3708
+ name: "Rhinestone Deposit Recovery",
3709
+ version: "1"
3710
+ };
3711
+ var RECOVER_TYPES = {
3712
+ RecoverDeposit: [
3713
+ { name: "depositId", type: "uint256" },
3714
+ { name: "destination", type: "address" }
3715
+ ]
3716
+ };
3717
+ var RecoveryError = class extends Error {
3718
+ constructor(message, status, code, retryable = false, phase = "response") {
3719
+ super(message);
3720
+ this.name = "RecoveryError";
3721
+ this.status = status;
3722
+ this.code = code;
3723
+ this.retryable = retryable;
3724
+ this.phase = phase;
3725
+ }
3726
+ };
3727
+ function formatRecoveryError(status, code, serverMessage) {
3728
+ switch (code) {
3729
+ case "DEPOSIT_NOT_RECOVERABLE":
3730
+ return {
3731
+ message: "This deposit can't be recovered \u2014 it may already have been claimed.",
3732
+ retryable: false
3733
+ };
3734
+ case "RECOVERY_UNSUPPORTED":
3735
+ return {
3736
+ message: "This deposit can't be recovered automatically. Contact support to get your funds back.",
3737
+ retryable: false
3738
+ };
3739
+ case "SIGNATURE_INVALID":
3740
+ return {
3741
+ message: "That signature wasn't accepted for this wallet. Contact support to recover this deposit.",
3742
+ retryable: false
3743
+ };
3744
+ case "VERIFICATION_UNAVAILABLE":
3745
+ return {
3746
+ message: "Couldn't verify your signature just now. Try again shortly.",
3747
+ retryable: true
3748
+ };
3749
+ case "REFUND_RECONCILIATION_REQUIRED":
3750
+ return {
3751
+ message: "Your recovery is being reviewed. Contact support with this deposit if it doesn't arrive.",
3752
+ retryable: false
3753
+ };
3754
+ case "REFUND_FAILED":
3755
+ return {
3756
+ message: serverMessage ?? "The recovery couldn't be completed. Please try again or contact support.",
3757
+ retryable: true
3758
+ };
3759
+ default:
3760
+ if (status === 0) {
3761
+ return {
3762
+ message: "Couldn't reach the recovery service. Check your connection and try again.",
3763
+ retryable: true
3764
+ };
3765
+ }
3766
+ return {
3767
+ message: serverMessage ?? "The recovery couldn't be completed. Please try again or contact support.",
3768
+ retryable: true
3769
+ };
3770
+ }
3771
+ }
3772
+ async function submitSignedRecovery(params) {
3773
+ const { backendUrl, chainId, depositId, signer, destination, signRecovery, debug } = params;
3774
+ const scope = "service:recovery";
3775
+ const typedData = {
3776
+ domain: RECOVER_DOMAIN,
3777
+ types: RECOVER_TYPES,
3778
+ primaryType: "RecoverDeposit",
3779
+ message: { depositId: BigInt(depositId), destination }
3780
+ };
3781
+ let signature;
3782
+ try {
3783
+ signature = await signRecovery({
3784
+ typedData,
3785
+ chainId,
3786
+ signer,
3787
+ depositId,
3788
+ destination
3789
+ });
3790
+ } catch (error) {
3791
+ debugError(debug, scope, "signRecovery:failed", error);
3792
+ throw new RecoveryError(
3793
+ "Signature request was declined. Approve it in your wallet to recover this deposit.",
3794
+ 0,
3795
+ void 0,
3796
+ true,
3797
+ "signature"
3798
+ );
3799
+ }
3800
+ if (!signature) {
3801
+ throw new RecoveryError(
3802
+ "Signature request was declined. Approve it in your wallet to recover this deposit.",
3803
+ 0,
3804
+ void 0,
3805
+ true,
3806
+ "signature"
3807
+ );
3808
+ }
3809
+ const url = `${backendUrl.replace(/\/$/, "")}/deposits/recover`;
3810
+ debugLog(debug, scope, "submitSignedRecovery:request", {
3811
+ url,
3812
+ depositId,
3813
+ signer
3814
+ });
3815
+ let response;
3816
+ try {
3817
+ response = await fetch(url, {
3818
+ method: "POST",
3819
+ // The shared const, so recovery carries `x-deposit-modal-version` like
3820
+ // every other backend call. Without it this path would be invisible in the
3821
+ // per-client version telemetry the processor records.
3822
+ headers: serviceHeaders(),
3823
+ // `depositId` as a string: it is a uint256 upstream and JSON numbers lose
3824
+ // precision well before that range.
3825
+ body: JSON.stringify({ depositId, destination, signature })
3826
+ });
3827
+ } catch (error) {
3828
+ debugError(debug, scope, "submitSignedRecovery:network", error);
3829
+ const { message, retryable } = formatRecoveryError(0);
3830
+ throw new RecoveryError(message, 0, void 0, retryable, "request");
3831
+ }
3832
+ if (!response.ok) {
3833
+ const body = await response.json().catch(() => ({}));
3834
+ debugError(debug, scope, "submitSignedRecovery:failed", body, {
3835
+ status: response.status
3836
+ });
3837
+ const { message, retryable } = formatRecoveryError(
3838
+ response.status,
3839
+ body.code,
3840
+ body.error
3841
+ );
3842
+ throw new RecoveryError(
3843
+ message,
3844
+ response.status,
3845
+ body.code,
3846
+ retryable,
3847
+ "response"
3848
+ );
3849
+ }
3850
+ const result = await response.json();
3851
+ debugLog(debug, scope, "submitSignedRecovery:success", {
3852
+ transactionHash: result.transactionHash
3853
+ });
3854
+ return result;
3855
+ }
3856
+
3857
+ // src/core/claim-analytics.tsx
3858
+ import {
3859
+ createContext as createContext4,
3860
+ useContext as useContext4,
3861
+ useMemo as useMemo4
3862
+ } from "react";
3863
+ import { jsx as jsx14 } from "react/jsx-runtime";
3864
+ function claimFailureReasonForError(error) {
3865
+ if (!(error instanceof RecoveryError)) return "refund_failed";
3866
+ switch (error.code) {
3867
+ case "SIGNATURE_INVALID":
3868
+ return "signature_invalid";
3869
+ case "DEPOSIT_NOT_RECOVERABLE":
3870
+ return "recovery_deposit_not_recoverable";
3871
+ case "RECOVERY_UNSUPPORTED":
3872
+ return "recovery_unsupported";
3873
+ case "VERIFICATION_UNAVAILABLE":
3874
+ return "signature_verification_unavailable";
3875
+ case "REFUND_RECONCILIATION_REQUIRED":
3876
+ return "refund_reconciliation_required";
3877
+ case "REFUND_FAILED":
3878
+ return "refund_failed";
3879
+ default:
3880
+ if (error.phase === "signature") return "signature_rejected";
3881
+ if (error.phase === "request") return "refund_service_unreachable";
3882
+ return "refund_failed";
3883
+ }
3884
+ }
3885
+ function createClaimAnalyticsController(emit, correlation) {
3886
+ const emitCorrelated = correlation ? (payload) => emit({ ...payload, ...correlation }) : emit;
3887
+ let step = null;
3888
+ let afterHandoff = false;
3889
+ let opened = false;
3890
+ let closed = false;
3891
+ const dedupe = /* @__PURE__ */ new Set();
3892
+ const send = (payload) => {
3893
+ controller.openSession();
3894
+ emitCorrelated(payload);
3895
+ };
3896
+ const emitOnce = (key, payload) => {
3897
+ if (dedupe.has(key)) return;
3898
+ dedupe.add(key);
3899
+ send(payload);
3900
+ };
3901
+ const rearmStep = (rearmed) => {
3902
+ for (const key of [...dedupe]) {
3903
+ if (key.includes(`:${rearmed}:`)) dedupe.delete(key);
3904
+ }
3905
+ };
3906
+ const controller = {
3907
+ openSession() {
3908
+ if (opened) return;
3909
+ opened = true;
3910
+ emitCorrelated({ type: "claim_modal_open" });
3911
+ },
3912
+ openStep(nextStep) {
3913
+ controller.openSession();
3914
+ if (step === nextStep) return;
3915
+ step = nextStep;
3916
+ emitOnce(`step-open:${nextStep}`, {
3917
+ type: "claim_modal_step_open",
3918
+ step: nextStep
3919
+ });
3920
+ },
3921
+ completeStep(completedStep = step ?? void 0) {
3922
+ if (!completedStep) return;
3923
+ emitOnce(`step-complete:${completedStep}`, {
3924
+ type: "claim_modal_step_complete",
3925
+ step: completedStep
3926
+ });
3927
+ },
3928
+ rearmStep(rearmed) {
3929
+ rearmStep(rearmed);
3930
+ },
3931
+ // One per submitted search, never deduplicated: the searched hash is
3932
+ // deliberately not in the stream, so collapsing two searches that returned
3933
+ // the same counts would make the second one unrecoverable.
3934
+ lookupResult(matches, eligible) {
3935
+ send({
3936
+ type: "claim_modal_lookup_result",
3937
+ matches,
3938
+ eligible
3939
+ });
3940
+ },
3941
+ selectDeposit({ depositId, transactionHash, autoSelected }) {
3942
+ emitOnce(`deposit-selected:${depositId}`, {
3943
+ type: "claim_modal_deposit_selected",
3944
+ deposit_id: depositId,
3945
+ transaction_hash: transactionHash,
3946
+ auto_selected: autoSelected
3947
+ });
3948
+ },
3949
+ friction(reason, eventStep = step ?? void 0) {
3950
+ if (!eventStep) return;
3951
+ emitOnce(`friction:${eventStep}:${reason}`, {
3952
+ type: "claim_modal_friction",
3953
+ step: eventStep,
3954
+ reason
3955
+ });
3956
+ },
3957
+ failure(reason, retryable, eventStep = step ?? void 0) {
3958
+ if (!eventStep) return;
3959
+ emitOnce(`failure:${eventStep}:${reason}`, {
3960
+ type: "claim_modal_failure",
3961
+ step: eventStep,
3962
+ reason,
3963
+ retryable
3964
+ });
3965
+ },
3966
+ retry(reason, eventStep = step ?? void 0) {
3967
+ if (!eventStep) return;
3968
+ send({ type: "claim_modal_retry", step: eventStep, reason });
3969
+ rearmStep(eventStep);
3970
+ },
3971
+ handoff({ depositId, transactionHash, refundTransactionHash }, eventStep) {
3972
+ const handoffStep = eventStep ?? step ?? "submit";
3973
+ if (step !== handoffStep) controller.openStep(handoffStep);
3974
+ afterHandoff = true;
3975
+ emitOnce(`handoff:${refundTransactionHash}`, {
3976
+ type: "claim_modal_handoff",
3977
+ step: handoffStep,
3978
+ deposit_id: depositId,
3979
+ transaction_hash: transactionHash,
3980
+ refund_transaction_hash: refundTransactionHash
3981
+ });
3982
+ },
3983
+ // Keyed by step so a retry re-arms it: a second failed submit is a second
3984
+ // terminal outcome, not a duplicate of the first.
3985
+ outcome(outcome) {
3986
+ if (!step) return;
3987
+ emitOnce(`outcome:${step}:${outcome}`, {
3988
+ type: "claim_modal_ui_outcome",
3989
+ step,
3990
+ outcome
3991
+ });
3992
+ },
3993
+ abandon(reason) {
3994
+ if (!step || afterHandoff) return;
3995
+ emitOnce(`abandon:${step}:${reason}`, {
3996
+ type: "claim_modal_abandoned",
3997
+ step,
3998
+ reason
3999
+ });
4000
+ },
4001
+ close(source) {
4002
+ if (closed) return;
4003
+ closed = true;
4004
+ send({
4005
+ type: "claim_modal_close",
4006
+ source,
4007
+ step,
4008
+ after_handoff: afterHandoff
4009
+ });
4010
+ },
4011
+ /** "Claim another deposit" on the success screen: a fresh attempt in the
4012
+ * same session, so the envelope and its session id stay. */
4013
+ resetAttempt() {
4014
+ step = null;
4015
+ afterHandoff = false;
4016
+ dedupe.clear();
4017
+ },
4018
+ get step() {
4019
+ return step;
4020
+ },
4021
+ get afterHandoff() {
4022
+ return afterHandoff;
4023
+ }
4024
+ };
4025
+ return controller;
4026
+ }
4027
+ var ClaimAnalyticsControllerContext = createContext4(null);
4028
+ var noopController = createClaimAnalyticsController(() => {
4029
+ });
4030
+ function ClaimAnalyticsControllerProvider({
4031
+ children,
4032
+ controllerRef,
4033
+ correlation
4034
+ }) {
4035
+ const emit = useClaimAnalyticsEmitter();
4036
+ const controller = useMemo4(
4037
+ () => createClaimAnalyticsController(emit, correlation),
4038
+ [emit, correlation]
4039
+ );
4040
+ if (controllerRef) controllerRef.current = controller;
4041
+ return /* @__PURE__ */ jsx14(ClaimAnalyticsControllerContext.Provider, { value: controller, children });
4042
+ }
4043
+ function useClaimAnalyticsController() {
4044
+ return useContext4(ClaimAnalyticsControllerContext) ?? noopController;
4045
+ }
4046
+
4047
+ // src/components/ui/TokenIcon.tsx
4048
+ import { jsx as jsx15 } from "react/jsx-runtime";
4049
+ function TokenIcon({ symbol, className, fallback }) {
4050
+ return /* @__PURE__ */ jsx15(
4051
+ CdnIcon,
4052
+ {
4053
+ src: tokenIconUrl(symbol),
4054
+ className: `rs-token-icon ${className ?? ""}`.trimEnd(),
4055
+ fallback
4056
+ }
4057
+ );
4058
+ }
4059
+ TokenIcon.displayName = "TokenIcon";
4060
+
4061
+ // src/components/recovery/RecoveryOutcomeScreen.tsx
4062
+ import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
4063
+ function RecoveryOutcomeScreen({
4064
+ result,
4065
+ error,
4066
+ children
4067
+ }) {
4068
+ const success = !!result;
4069
+ const explorerTxUrl = useExplorerTxUrl();
4070
+ const txUrl = result ? explorerTxUrl(result.chainId, result.txHash) : null;
4071
+ return /* @__PURE__ */ jsxs10("div", { className: "rs-screen", children: [
4072
+ /* @__PURE__ */ jsxs10("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
4073
+ /* @__PURE__ */ jsx16(
4074
+ BodyHeader,
4075
+ {
4076
+ icon: success ? /* @__PURE__ */ jsx16(CheckIcon, {}) : /* @__PURE__ */ jsx16(AlertTriangleIcon, {}),
4077
+ variant: success ? "success" : "error",
4078
+ title: success ? "Refund submitted" : "Refund failed",
4079
+ subtitle: success ? "Your funds are being returned on the source chain." : void 0
4080
+ }
4081
+ ),
4082
+ result ? /* @__PURE__ */ jsxs10("div", { className: "rs-review-details", children: [
4083
+ /* @__PURE__ */ jsxs10("div", { className: "rs-review-detail-row", children: [
4084
+ /* @__PURE__ */ jsx16("span", { children: "Amount" }),
4085
+ /* @__PURE__ */ jsxs10("span", { className: "rs-review-detail-value", children: [
4086
+ /* @__PURE__ */ jsxs10("span", { children: [
4087
+ result.amountDisplay,
4088
+ " ",
4089
+ result.symbol
4090
+ ] }),
4091
+ /* @__PURE__ */ jsx16("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx16(TokenIcon, { symbol: result.symbol }) })
4092
+ ] })
4093
+ ] }),
4094
+ /* @__PURE__ */ jsxs10("div", { className: "rs-review-detail-row", children: [
4095
+ /* @__PURE__ */ jsx16("span", { children: "Sent to" }),
4096
+ /* @__PURE__ */ jsx16("span", { className: "rs-review-detail-value", children: shortenAddress(result.destination) })
4097
+ ] }),
4098
+ /* @__PURE__ */ jsxs10("div", { className: "rs-review-detail-row", children: [
4099
+ /* @__PURE__ */ jsx16("span", { children: "Refund transaction" }),
4100
+ txUrl ? /* @__PURE__ */ jsxs10(
4101
+ "a",
4102
+ {
4103
+ className: "rs-review-detail-value rs-link",
4104
+ href: txUrl,
4105
+ target: "_blank",
4106
+ rel: "noreferrer",
4107
+ children: [
4108
+ shortenHash(result.txHash),
4109
+ /* @__PURE__ */ jsx16(ExternalLinkIcon, {})
4110
+ ]
4111
+ }
4112
+ ) : /* @__PURE__ */ jsx16("span", { className: "rs-review-detail-value", children: shortenHash(result.txHash) })
4113
+ ] })
4114
+ ] }) : /* @__PURE__ */ jsx16(Callout, { variant: "error", children: error }),
4115
+ /* @__PURE__ */ jsx16("div", { className: "rs-screen-button-row", children })
4116
+ ] }),
4117
+ /* @__PURE__ */ jsx16(PoweredBy, {})
4118
+ ] });
4119
+ }
4120
+ RecoveryOutcomeScreen.displayName = "RecoveryOutcomeScreen";
4121
+
4122
+ // src/components/recovery/RecoveryReviewScreen.tsx
4123
+ import { useEffect as useEffect6, useState as useState4 } from "react";
4124
+ import { isAddress as isAddress2 } from "viem";
4125
+ import { jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
4126
+ function RecoveryReviewScreen({
4127
+ chainId,
4128
+ token,
4129
+ amountRaw,
4130
+ txHash,
4131
+ defaultDestination,
4132
+ destinationHint,
4133
+ submitting,
4134
+ onSubmit,
4135
+ onDestinationInvalid
4136
+ }) {
4137
+ const { symbol, amount, chainName, chainIcon } = describeRecoveryDeposit({
4138
+ chainId,
4139
+ token,
4140
+ amountRaw
4141
+ });
4142
+ const explorerTxUrl = useExplorerTxUrl();
4143
+ const [destination, setDestination] = useState4(
4144
+ defaultDestination ?? ""
4145
+ );
4146
+ const destinationValid = isAddress2(destination);
4147
+ const onDestinationInvalidRef = useLatestRef(onDestinationInvalid);
4148
+ useEffect6(() => {
4149
+ if (destination.length > 0 && !destinationValid) {
4150
+ onDestinationInvalidRef.current?.();
4151
+ }
4152
+ }, [destination, destinationValid, onDestinationInvalidRef]);
4153
+ const txUrl = txHash ? explorerTxUrl(chainId, txHash) : null;
4154
+ const txShort = txHash ? shortenHash(txHash) : "\u2014";
4155
+ return /* @__PURE__ */ jsxs11("div", { className: "rs-screen", children: [
4156
+ /* @__PURE__ */ jsxs11("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
4157
+ /* @__PURE__ */ jsx17(
4158
+ BodyHeader,
4159
+ {
4160
+ icon: /* @__PURE__ */ jsx17(HandCoinsIcon, {}),
4161
+ title: "Review refund",
4162
+ subtitle: "This returns the funds on the source chain. It does not retry the original deposit."
4163
+ }
4164
+ ),
4165
+ /* @__PURE__ */ jsxs11("div", { className: "rs-review-details", children: [
4166
+ /* @__PURE__ */ jsxs11("div", { className: "rs-review-detail-row", children: [
4167
+ /* @__PURE__ */ jsx17("span", { children: "Amount" }),
4168
+ /* @__PURE__ */ jsxs11("span", { className: "rs-review-detail-value", children: [
4169
+ /* @__PURE__ */ jsxs11("span", { children: [
4170
+ amount,
4171
+ " ",
4172
+ symbol
4173
+ ] }),
4174
+ /* @__PURE__ */ jsx17("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx17(TokenIcon, { symbol }) })
4175
+ ] })
4176
+ ] }),
4177
+ /* @__PURE__ */ jsxs11("div", { className: "rs-review-detail-row", children: [
4178
+ /* @__PURE__ */ jsx17("span", { children: "Source chain" }),
4179
+ /* @__PURE__ */ jsxs11("span", { className: "rs-review-detail-value", children: [
4180
+ /* @__PURE__ */ jsx17("span", { children: chainName }),
4181
+ chainIcon && /* @__PURE__ */ jsx17("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx17(CdnIcon, { src: chainIcon }) })
4182
+ ] })
4183
+ ] }),
4184
+ /* @__PURE__ */ jsxs11("div", { className: "rs-review-detail-row", children: [
4185
+ /* @__PURE__ */ jsx17("span", { children: "Deposit transaction" }),
4186
+ txUrl ? /* @__PURE__ */ jsxs11(
4187
+ "a",
4188
+ {
4189
+ className: "rs-review-detail-value rs-link",
4190
+ href: txUrl,
4191
+ target: "_blank",
4192
+ rel: "noreferrer",
4193
+ children: [
4194
+ txShort,
4195
+ /* @__PURE__ */ jsx17(ExternalLinkIcon, {})
4196
+ ]
4197
+ }
4198
+ ) : /* @__PURE__ */ jsx17("span", { className: "rs-review-detail-value", children: txShort })
4199
+ ] })
4200
+ ] }),
4201
+ /* @__PURE__ */ jsx17(
4202
+ Input,
4203
+ {
4204
+ label: "Send to",
4205
+ placeholder: "0x\u2026",
4206
+ value: destination,
4207
+ onChange: (e) => setDestination(e.target.value),
4208
+ hint: destinationHint,
4209
+ error: destination.length > 0 && !destinationValid ? "Enter a valid address" : void 0
4210
+ }
4211
+ ),
4212
+ /* @__PURE__ */ jsx17(
4213
+ Button,
4214
+ {
4215
+ onClick: () => destinationValid && onSubmit(destination),
4216
+ loading: submitting,
4217
+ loadingText: "Refunding\u2026",
4218
+ disabled: !destinationValid,
4219
+ fullWidth: true,
4220
+ children: "Claim refund"
4221
+ }
4222
+ )
4223
+ ] }),
4224
+ /* @__PURE__ */ jsx17(PoweredBy, {})
4225
+ ] });
4226
+ }
4227
+ RecoveryReviewScreen.displayName = "RecoveryReviewScreen";
4228
+
3397
4229
  // src/core/theme.ts
3398
4230
  var RADIUS_SCALE = {
3399
4231
  none: { sm: "0", md: "0", lg: "0" },
@@ -3607,6 +4439,7 @@ export {
3607
4439
  AppleIcon,
3608
4440
  BodyHeader,
3609
4441
  CdnIcon,
4442
+ ListRow,
3610
4443
  PoweredBy,
3611
4444
  Spinner,
3612
4445
  catalogKeyForChain,
@@ -3623,6 +4456,7 @@ export {
3623
4456
  SUPPORTED_CONNECT_EXCHANGE_COUNT,
3624
4457
  resolveAppFeeBps,
3625
4458
  PermitDepositSubmitError,
4459
+ RegistrationError,
3626
4460
  createDepositService,
3627
4461
  rpcUrlFor,
3628
4462
  RpcUrlsProvider,
@@ -3658,10 +4492,26 @@ export {
3658
4492
  estimateReceiveAmount,
3659
4493
  formatQuotedReceive,
3660
4494
  formatReceiveEstimate,
4495
+ randomUuid,
3661
4496
  AnalyticsSession,
3662
4497
  useDepositAnalyticsEmitter,
3663
4498
  useWithdrawAnalyticsEmitter,
3664
- useClaimAnalyticsEmitter,
4499
+ recoverySigningChainId,
4500
+ sourceDepositTxHash,
4501
+ toRecoverableDeposit,
4502
+ recoveryFailureCause,
4503
+ RECOVERY_LOOKUP_MISS_COPY,
4504
+ classifyRecoveryLookup,
4505
+ RecoveryLookupScreen,
4506
+ describeRecoveryDeposit,
4507
+ formatRecoveryAmount,
4508
+ RecoveryError,
4509
+ submitSignedRecovery,
4510
+ claimFailureReasonForError,
4511
+ ClaimAnalyticsControllerProvider,
4512
+ useClaimAnalyticsController,
4513
+ RecoveryOutcomeScreen,
4514
+ RecoveryReviewScreen,
3665
4515
  resolveThemeMode,
3666
4516
  followSystemAppearance,
3667
4517
  applyTheme,