@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.
- package/README.md +12 -12
- package/bridge-transcript.json +14 -0
- package/dist/ClaimModal-GFDBVCN5.cjs +11 -0
- package/dist/ClaimModal-VQS3AKEL.mjs +11 -0
- package/dist/{DepositModalReown-Q2JMLT47.mjs → DepositModalReown-KOJ7VEY7.mjs} +30 -29
- package/dist/{DepositModalReown-46LPVFB6.cjs → DepositModalReown-R37SSHUF.cjs} +79 -78
- package/dist/WithdrawModal-QVXHMH43.mjs +12 -0
- package/dist/WithdrawModal-RY2NMFLE.cjs +12 -0
- package/dist/{caip-D8aRWdEY.d.cts → caip-BMi-9t09.d.cts} +27 -3
- package/dist/{caip-D8aRWdEY.d.ts → caip-BMi-9t09.d.ts} +27 -3
- package/dist/{chunk-V2OBGLJD.cjs → chunk-3OOY67VJ.cjs} +1103 -253
- package/dist/{chunk-6KG642KH.cjs → chunk-5P2PVLS4.cjs} +1 -1
- package/dist/{chunk-IN77XSWO.mjs → chunk-5VONFVQN.mjs} +976 -126
- package/dist/chunk-6HUHVXCY.cjs +704 -0
- package/dist/{chunk-PKML3XVS.mjs → chunk-7UQ6OUEE.mjs} +166 -45
- package/dist/{chunk-K4H6TGBE.mjs → chunk-CXBMIZUF.mjs} +1 -1
- package/dist/{chunk-MTFJSE52.cjs → chunk-DTVZUBHI.cjs} +236 -115
- package/dist/{chunk-VUATPOWJ.mjs → chunk-EAGMY3QE.mjs} +74 -17
- package/dist/{chunk-RN5VKWI6.mjs → chunk-FTWKAJGN.mjs} +1 -1
- package/dist/{chunk-KTUVSKR4.mjs → chunk-IKUYZA7A.mjs} +265 -523
- package/dist/{chunk-DW2EQA2U.cjs → chunk-LVCD6RHF.cjs} +2 -2
- package/dist/{chunk-4KCSH4T3.cjs → chunk-OY5N3E6L.cjs} +86 -29
- package/dist/chunk-QJ7RCCU7.mjs +704 -0
- package/dist/chunk-UCBUCX2W.mjs +3169 -0
- package/dist/{chunk-YCQZJQO6.cjs → chunk-VPDCGD2D.cjs} +622 -880
- package/dist/{chunk-7ICSHJFE.cjs → chunk-X4D52IZK.cjs} +1501 -176
- package/dist/claim.cjs +5 -7
- package/dist/claim.d.cts +3 -3
- package/dist/claim.d.ts +3 -3
- package/dist/claim.mjs +4 -6
- package/dist/{constants-DBrWhJWE.d.cts → constants-BT4ctuHo.d.cts} +7 -6
- package/dist/{constants-DBrWhJWE.d.ts → constants-D21ZdNOP.d.ts} +7 -6
- package/dist/constants.cjs +3 -3
- package/dist/constants.d.cts +3 -3
- package/dist/constants.d.ts +3 -3
- package/dist/constants.mjs +2 -2
- package/dist/deposit.cjs +7 -8
- package/dist/deposit.d.cts +3 -3
- package/dist/deposit.d.ts +3 -3
- package/dist/deposit.mjs +6 -7
- package/dist/embed.cjs +135 -44
- package/dist/embed.d.cts +2 -2
- package/dist/embed.d.ts +2 -2
- package/dist/embed.mjs +116 -25
- package/dist/index.cjs +13 -11
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.mjs +12 -10
- package/dist/polymarket.cjs +6 -6
- package/dist/polymarket.mjs +2 -2
- package/dist/styles.css +132 -100
- package/dist/{types-Bho4OA03.d.ts → types-CQ0NHqCy.d.ts} +146 -11
- package/dist/{types-DP_3KwlD.d.cts → types-CxiLX5sv.d.cts} +146 -11
- package/dist/withdraw.cjs +6 -6
- package/dist/withdraw.d.cts +4 -4
- package/dist/withdraw.d.ts +4 -4
- package/dist/withdraw.mjs +5 -5
- package/package.json +7 -6
- package/dist/ClaimModal-IKTJU43Y.cjs +0 -13
- package/dist/ClaimModal-SEKNWRMA.mjs +0 -13
- package/dist/WithdrawModal-5ICGD4HJ.mjs +0 -12
- package/dist/WithdrawModal-VP6PMIRO.cjs +0 -12
- package/dist/chunk-7SR7ENVJ.mjs +0 -1844
- package/dist/chunk-CFKC77SV.mjs +0 -1062
- package/dist/chunk-LZFRL2AL.cjs +0 -81
- package/dist/chunk-WUJIKCFU.mjs +0 -81
- package/dist/chunk-X2IPAPXU.cjs +0 -163
- package/dist/chunk-YWMWI7PZ.cjs +0 -1062
- package/dist/chunk-ZEO6ADM3.mjs +0 -163
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MODAL_VERSION,
|
|
3
3
|
serviceHeaders
|
|
4
|
-
} from "./chunk-
|
|
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-
|
|
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-
|
|
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
|
|
365
|
-
var rhinestoneLogo = /* @__PURE__ */
|
|
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__ */
|
|
375
|
-
/* @__PURE__ */
|
|
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__ */
|
|
385
|
-
/* @__PURE__ */
|
|
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__ */
|
|
394
|
-
/* @__PURE__ */
|
|
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__ */
|
|
403
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
419
|
-
/* @__PURE__ */
|
|
420
|
-
/* @__PURE__ */
|
|
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
|
|
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
|
|
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
|
-
|
|
2270
|
-
|
|
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__ */
|
|
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
|
|
2620
|
+
import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2515
2621
|
function Spinner({ className }) {
|
|
2516
|
-
return /* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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
|
|
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__ */
|
|
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__ */
|
|
2572
|
-
/* @__PURE__ */
|
|
2573
|
-
/* @__PURE__ */
|
|
2574
|
-
] }) : /* @__PURE__ */
|
|
2575
|
-
/* @__PURE__ */
|
|
2576
|
-
loading && /* @__PURE__ */
|
|
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
|
|
2934
|
-
let
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
3125
|
+
const pending = startMint();
|
|
3126
|
+
await (maxWaitMs === void 0 ? pending : Promise.race([pending, sleep(maxWaitMs)]));
|
|
3053
3127
|
}
|
|
3054
|
-
async function deliver(batch
|
|
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 =
|
|
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
|
|
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
|
-
|
|
3108
|
-
if (
|
|
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
|
-
|
|
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 (
|
|
3122
|
-
|
|
3123
|
-
|
|
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 (
|
|
3129
|
-
|
|
3130
|
-
await run(
|
|
3215
|
+
if (pendingRun) {
|
|
3216
|
+
pendingRun = false;
|
|
3217
|
+
await run(urgency);
|
|
3131
3218
|
return;
|
|
3132
3219
|
}
|
|
3133
|
-
if (!disposed
|
|
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(
|
|
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(
|
|
3247
|
+
void run(IDLE);
|
|
3159
3248
|
} else {
|
|
3160
3249
|
scheduleFlush();
|
|
3161
3250
|
}
|
|
3162
3251
|
},
|
|
3163
3252
|
flush(flushOptions) {
|
|
3164
|
-
const
|
|
3165
|
-
if (disposed && !
|
|
3253
|
+
const dismissal = flushOptions?.terminal ?? false;
|
|
3254
|
+
if (disposed && !dismissal) return;
|
|
3166
3255
|
clearFlushTimer();
|
|
3167
|
-
void run(
|
|
3256
|
+
void run(dismissal ? DISMISSAL : IDLE);
|
|
3168
3257
|
},
|
|
3169
3258
|
dispose() {
|
|
3170
3259
|
if (disposed) return;
|
|
3171
3260
|
disposed = true;
|
|
3172
3261
|
clearFlushTimer();
|
|
3173
|
-
|
|
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
|
|
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__ */
|
|
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
|
-
|
|
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,
|