@rhinestone/deposit-modal 0.9.1 → 0.11.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/dist/{DepositModalReown-JUJI7UHE.mjs → DepositModalReown-6RVLEM3B.mjs} +96 -26
- package/dist/{DepositModalReown-YQSO4SVY.cjs → DepositModalReown-TXTLVZIQ.cjs} +97 -27
- package/dist/caip-D8aRWdEY.d.cts +40 -0
- package/dist/caip-D8aRWdEY.d.ts +40 -0
- package/dist/{chunk-A223BLVC.mjs → chunk-53IFZGSF.mjs} +177 -21
- package/dist/{chunk-VQJHYWAE.cjs → chunk-7RNEYPI4.cjs} +836 -579
- package/dist/{chunk-ITFRTPGF.cjs → chunk-BLJMYCBF.cjs} +92 -90
- package/dist/{chunk-AYWEWI47.mjs → chunk-DYTRG4C7.mjs} +1 -1
- package/dist/{chunk-QGXAAFHU.mjs → chunk-G4FVZQOM.mjs} +23 -21
- package/dist/{chunk-SQOEHQNT.cjs → chunk-GWA6GFTI.cjs} +66 -63
- package/dist/{chunk-EEEQZOTJ.cjs → chunk-HCQWFL3A.cjs} +84 -101
- package/dist/{chunk-WUQZYQRK.mjs → chunk-ITAYM7SB.mjs} +784 -167
- package/dist/{chunk-YEBXUUH3.cjs → chunk-JPRV36DT.cjs} +2 -2
- package/dist/{chunk-EAUF7SGM.cjs → chunk-JYKMR6QI.cjs} +3 -3
- package/dist/{chunk-ILT2PITN.mjs → chunk-MZ53PDIX.mjs} +1 -1
- package/dist/{chunk-6U2H3R3T.cjs → chunk-NPSC5R22.cjs} +862 -245
- package/dist/{chunk-QLZ5RZTA.mjs → chunk-QRR3Y7EK.mjs} +1 -1
- package/dist/{chunk-H577RJN5.cjs → chunk-TENL4H64.cjs} +186 -30
- package/dist/{chunk-N3OHR3T2.mjs → chunk-TRD2FCAR.mjs} +363 -106
- package/dist/{chunk-7OQO6JDC.mjs → chunk-VRNRRN2U.mjs} +12 -9
- package/dist/{chunk-GYEUZSQP.mjs → chunk-WLDTBKRA.mjs} +14 -31
- package/dist/{chunk-XJE5MRY4.cjs → chunk-XVKBCDZI.cjs} +1 -1
- package/dist/claim.cjs +6 -6
- package/dist/claim.d.cts +3 -2
- package/dist/claim.d.ts +3 -2
- package/dist/claim.mjs +5 -5
- package/dist/{caip-523Zrc3r.d.cts → constants-FuzG3h4m.d.cts} +1 -18
- package/dist/{caip-523Zrc3r.d.ts → constants-FuzG3h4m.d.ts} +1 -18
- package/dist/constants.cjs +5 -3
- package/dist/constants.d.cts +3 -2
- package/dist/constants.d.ts +3 -2
- package/dist/constants.mjs +4 -2
- package/dist/deposit.cjs +8 -8
- package/dist/deposit.d.cts +3 -2
- package/dist/deposit.d.ts +3 -2
- package/dist/deposit.mjs +7 -7
- package/dist/index.cjs +12 -10
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.mjs +11 -9
- package/dist/polymarket.cjs +5 -5
- package/dist/polymarket.mjs +2 -2
- package/dist/styles.css +14 -0
- package/dist/{types-C0SGf-21.d.cts → types-C7wag_iL.d.cts} +4 -3
- package/dist/{types-C0SGf-21.d.ts → types-D4b6Cjox.d.ts} +4 -3
- package/dist/withdraw.cjs +6 -6
- package/dist/withdraw.d.cts +3 -2
- package/dist/withdraw.d.ts +3 -2
- package/dist/withdraw.mjs +5 -5
- package/package.json +1 -1
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SERVICE_HEADERS
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-QRR3Y7EK.mjs";
|
|
4
4
|
import {
|
|
5
|
+
CHAIN_BY_ID,
|
|
6
|
+
CHAIN_DISPLAY_ORDER,
|
|
5
7
|
HYPERCORE_CHAIN_ID,
|
|
6
8
|
HYPERCORE_MAINNET_CAIP2,
|
|
7
9
|
HYPERCORE_SOURCE_TOKENS,
|
|
8
10
|
ICON_CDN,
|
|
9
11
|
NATIVE_TOKEN_ADDRESS,
|
|
12
|
+
SOLANA_MAINNET_CAIP2,
|
|
13
|
+
SOURCE_CHAINS,
|
|
10
14
|
findTokenDecimals,
|
|
15
|
+
getBundledTargetTokens,
|
|
16
|
+
getChainName,
|
|
17
|
+
getExplorerTxUrl,
|
|
11
18
|
getSolanaTokenByMint,
|
|
19
|
+
getSupportedChainIds,
|
|
20
|
+
getSupportedTargetTokens,
|
|
12
21
|
getTokenAddress,
|
|
13
22
|
getTokenDecimalsByAddress,
|
|
14
23
|
getTokenSymbol,
|
|
@@ -16,8 +25,12 @@ import {
|
|
|
16
25
|
isRegistryTokenOnChain,
|
|
17
26
|
isSolanaCaip2,
|
|
18
27
|
parseEvmChainId,
|
|
28
|
+
publishShortlistTokens,
|
|
29
|
+
setRuntimeChainMeta,
|
|
30
|
+
setRuntimeTokens,
|
|
31
|
+
toEvmCaip2,
|
|
19
32
|
tokenIconUrl
|
|
20
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-53IFZGSF.mjs";
|
|
21
34
|
|
|
22
35
|
// src/components/ui/Modal.tsx
|
|
23
36
|
import {
|
|
@@ -433,140 +446,6 @@ function PoweredBy() {
|
|
|
433
446
|
}
|
|
434
447
|
PoweredBy.displayName = "PoweredBy";
|
|
435
448
|
|
|
436
|
-
// src/core/useLatestRef.ts
|
|
437
|
-
import { useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
438
|
-
function useLatestRef(value) {
|
|
439
|
-
const ref = useRef2(value);
|
|
440
|
-
useEffect2(() => {
|
|
441
|
-
ref.current = value;
|
|
442
|
-
}, [value]);
|
|
443
|
-
return ref;
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
// src/components/ui/Spinner.tsx
|
|
447
|
-
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
448
|
-
function Spinner({ className }) {
|
|
449
|
-
return /* @__PURE__ */ jsxs4(
|
|
450
|
-
"svg",
|
|
451
|
-
{
|
|
452
|
-
className: `rs-spinner ${className || ""}`,
|
|
453
|
-
fill: "none",
|
|
454
|
-
viewBox: "0 0 20 21",
|
|
455
|
-
children: [
|
|
456
|
-
/* @__PURE__ */ jsx6(
|
|
457
|
-
"path",
|
|
458
|
-
{
|
|
459
|
-
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",
|
|
460
|
-
fill: "currentColor",
|
|
461
|
-
opacity: 0.3
|
|
462
|
-
}
|
|
463
|
-
),
|
|
464
|
-
/* @__PURE__ */ jsx6(
|
|
465
|
-
"path",
|
|
466
|
-
{
|
|
467
|
-
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",
|
|
468
|
-
fill: "currentColor"
|
|
469
|
-
}
|
|
470
|
-
)
|
|
471
|
-
]
|
|
472
|
-
}
|
|
473
|
-
);
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
// src/components/ui/Button.tsx
|
|
477
|
-
import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
478
|
-
function Button({
|
|
479
|
-
children,
|
|
480
|
-
variant = "accent",
|
|
481
|
-
size = "default",
|
|
482
|
-
loading = false,
|
|
483
|
-
loadingText,
|
|
484
|
-
fullWidth = false,
|
|
485
|
-
disabled,
|
|
486
|
-
className = "",
|
|
487
|
-
...props
|
|
488
|
-
}) {
|
|
489
|
-
const classes = [
|
|
490
|
-
"rs-button",
|
|
491
|
-
`rs-button--${variant}`,
|
|
492
|
-
`rs-button--size-${size}`,
|
|
493
|
-
fullWidth ? "rs-button--full-width" : "",
|
|
494
|
-
className
|
|
495
|
-
].filter(Boolean).join(" ");
|
|
496
|
-
const showInlineLoadingText = loading && loadingText !== void 0;
|
|
497
|
-
return /* @__PURE__ */ jsx7(
|
|
498
|
-
"button",
|
|
499
|
-
{
|
|
500
|
-
className: classes,
|
|
501
|
-
disabled: disabled || loading,
|
|
502
|
-
"aria-busy": loading || void 0,
|
|
503
|
-
...props,
|
|
504
|
-
children: showInlineLoadingText ? /* @__PURE__ */ jsxs5("span", { className: "rs-button__loading-row", children: [
|
|
505
|
-
/* @__PURE__ */ jsx7(Spinner, { className: "rs-spinner--sm" }),
|
|
506
|
-
/* @__PURE__ */ jsx7("span", { children: loadingText })
|
|
507
|
-
] }) : /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
508
|
-
/* @__PURE__ */ jsx7("span", { className: loading ? "rs-button__content--hidden" : "", children }),
|
|
509
|
-
loading && /* @__PURE__ */ jsx7("span", { className: "rs-button__spinner", children: /* @__PURE__ */ jsx7(Spinner, { className: "rs-spinner--sm" }) })
|
|
510
|
-
] })
|
|
511
|
-
}
|
|
512
|
-
);
|
|
513
|
-
}
|
|
514
|
-
Button.displayName = "Button";
|
|
515
|
-
|
|
516
|
-
// src/components/ui/Callout.tsx
|
|
517
|
-
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
518
|
-
function CircleAlertIcon() {
|
|
519
|
-
return /* @__PURE__ */ jsx8(
|
|
520
|
-
"svg",
|
|
521
|
-
{
|
|
522
|
-
width: "16",
|
|
523
|
-
height: "16",
|
|
524
|
-
viewBox: "0 0 16 16",
|
|
525
|
-
fill: "none",
|
|
526
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
527
|
-
"aria-hidden": "true",
|
|
528
|
-
children: /* @__PURE__ */ jsx8(
|
|
529
|
-
"path",
|
|
530
|
-
{
|
|
531
|
-
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",
|
|
532
|
-
stroke: "currentColor",
|
|
533
|
-
strokeWidth: "1.33",
|
|
534
|
-
strokeLinecap: "round",
|
|
535
|
-
strokeLinejoin: "round"
|
|
536
|
-
}
|
|
537
|
-
)
|
|
538
|
-
}
|
|
539
|
-
);
|
|
540
|
-
}
|
|
541
|
-
function Callout({ variant = "error", children, role }) {
|
|
542
|
-
return /* @__PURE__ */ jsxs6(
|
|
543
|
-
"div",
|
|
544
|
-
{
|
|
545
|
-
className: `rs-callout rs-callout--${variant}`,
|
|
546
|
-
role: role ?? (variant === "error" ? "alert" : "status"),
|
|
547
|
-
children: [
|
|
548
|
-
/* @__PURE__ */ jsx8("span", { className: "rs-callout-icon", children: variant === "error" ? /* @__PURE__ */ jsx8(CircleAlertIcon, {}) : /* @__PURE__ */ jsx8(AlertTriangleIcon, {}) }),
|
|
549
|
-
/* @__PURE__ */ jsx8("span", { className: "rs-callout-text", children })
|
|
550
|
-
]
|
|
551
|
-
}
|
|
552
|
-
);
|
|
553
|
-
}
|
|
554
|
-
Callout.displayName = "Callout";
|
|
555
|
-
|
|
556
|
-
// src/components/ui/TokenIcon.tsx
|
|
557
|
-
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
558
|
-
function TokenIcon({ symbol, className, fallback }) {
|
|
559
|
-
return /* @__PURE__ */ jsx9(
|
|
560
|
-
CdnIcon,
|
|
561
|
-
{
|
|
562
|
-
src: tokenIconUrl(symbol),
|
|
563
|
-
className: `rs-token-icon ${className ?? ""}`.trimEnd(),
|
|
564
|
-
fallback
|
|
565
|
-
}
|
|
566
|
-
);
|
|
567
|
-
}
|
|
568
|
-
TokenIcon.displayName = "TokenIcon";
|
|
569
|
-
|
|
570
449
|
// src/core/deposit-service.ts
|
|
571
450
|
import { getAddress } from "viem";
|
|
572
451
|
|
|
@@ -623,6 +502,101 @@ function debugError(enabled, scope, message, error, data) {
|
|
|
623
502
|
console.error(`[deposit-modal:${scope}] ${message}`, payload);
|
|
624
503
|
}
|
|
625
504
|
|
|
505
|
+
// src/core/chain-catalog.ts
|
|
506
|
+
function parseToken(value) {
|
|
507
|
+
if (typeof value !== "object" || value === null) return null;
|
|
508
|
+
const { symbol, address, decimals } = value;
|
|
509
|
+
if (typeof symbol !== "string" || typeof address !== "string" || typeof decimals !== "number") {
|
|
510
|
+
return null;
|
|
511
|
+
}
|
|
512
|
+
return { symbol, address, decimals };
|
|
513
|
+
}
|
|
514
|
+
function parseExplorer(value) {
|
|
515
|
+
if (typeof value !== "object" || value === null) return null;
|
|
516
|
+
const { url, addressPath, txPath } = value;
|
|
517
|
+
if (typeof url !== "string" || typeof addressPath !== "string" || typeof txPath !== "string") {
|
|
518
|
+
return null;
|
|
519
|
+
}
|
|
520
|
+
return { url, addressPath, txPath };
|
|
521
|
+
}
|
|
522
|
+
function parseVmType(value) {
|
|
523
|
+
return value === "evm" || value === "svm" || value === "tvm" ? value : null;
|
|
524
|
+
}
|
|
525
|
+
function parseOptionalString(value) {
|
|
526
|
+
return typeof value === "string" && value.trim() !== "" ? value.trim() : null;
|
|
527
|
+
}
|
|
528
|
+
function parseChain(caip2, value) {
|
|
529
|
+
if (typeof value !== "object" || value === null) return null;
|
|
530
|
+
const raw = value;
|
|
531
|
+
const { name, testnet, deposit, destination, refund } = raw;
|
|
532
|
+
if (typeof name !== "string" || typeof testnet !== "boolean" || typeof deposit !== "boolean" || typeof destination !== "boolean" || typeof refund !== "boolean") {
|
|
533
|
+
return null;
|
|
534
|
+
}
|
|
535
|
+
const vmType = parseVmType(raw.vmType);
|
|
536
|
+
const nativeToken = parseToken(raw.nativeToken);
|
|
537
|
+
if (!vmType || !nativeToken) return null;
|
|
538
|
+
let supportedTokens;
|
|
539
|
+
if (raw.supportedTokens === "all") {
|
|
540
|
+
supportedTokens = "all";
|
|
541
|
+
} else if (Array.isArray(raw.supportedTokens)) {
|
|
542
|
+
const tokens = [];
|
|
543
|
+
for (const entry of raw.supportedTokens) {
|
|
544
|
+
const token = parseToken(entry);
|
|
545
|
+
if (!token) return null;
|
|
546
|
+
tokens.push(token);
|
|
547
|
+
}
|
|
548
|
+
supportedTokens = tokens;
|
|
549
|
+
} else {
|
|
550
|
+
return null;
|
|
551
|
+
}
|
|
552
|
+
return {
|
|
553
|
+
caip2,
|
|
554
|
+
// `parseEvmChainId` returns null for `solana:`/`tron:`/`hypercore:` keys,
|
|
555
|
+
// which is the intended answer — those chains have no numeric id, and the
|
|
556
|
+
// modal addresses them by their CAIP-2 string or a sentinel.
|
|
557
|
+
chainId: parseEvmChainId(caip2),
|
|
558
|
+
name,
|
|
559
|
+
testnet,
|
|
560
|
+
deposit,
|
|
561
|
+
destination,
|
|
562
|
+
refund,
|
|
563
|
+
vmType,
|
|
564
|
+
nativeToken,
|
|
565
|
+
explorer: parseExplorer(raw.explorer),
|
|
566
|
+
supportedTokens,
|
|
567
|
+
publicRpcUrl: parseOptionalString(raw.publicRpcUrl),
|
|
568
|
+
iconUrl: parseOptionalString(raw.iconUrl)
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
function parseChainCatalog(body) {
|
|
572
|
+
if (typeof body !== "object" || body === null || Array.isArray(body)) {
|
|
573
|
+
return null;
|
|
574
|
+
}
|
|
575
|
+
const all = [];
|
|
576
|
+
const byCaip2 = /* @__PURE__ */ new Map();
|
|
577
|
+
const byChainId = /* @__PURE__ */ new Map();
|
|
578
|
+
for (const [caip2, value] of Object.entries(body)) {
|
|
579
|
+
const chain = parseChain(caip2, value);
|
|
580
|
+
if (!chain) continue;
|
|
581
|
+
all.push(chain);
|
|
582
|
+
byCaip2.set(chain.caip2, chain);
|
|
583
|
+
if (chain.chainId !== null) byChainId.set(chain.chainId, chain);
|
|
584
|
+
}
|
|
585
|
+
if (all.length === 0) return null;
|
|
586
|
+
return { all, byCaip2, byChainId };
|
|
587
|
+
}
|
|
588
|
+
function catalogKeyForChain(chainId) {
|
|
589
|
+
if (chainId === "solana") return SOLANA_MAINNET_CAIP2;
|
|
590
|
+
if (chainId === "hypercore" || chainId === HYPERCORE_CHAIN_ID) {
|
|
591
|
+
return HYPERCORE_MAINNET_CAIP2;
|
|
592
|
+
}
|
|
593
|
+
return chainId;
|
|
594
|
+
}
|
|
595
|
+
function catalogExplorerTxUrl(chain, txHash) {
|
|
596
|
+
if (!chain?.explorer) return void 0;
|
|
597
|
+
return `${chain.explorer.url}${chain.explorer.txPath}${txHash}`;
|
|
598
|
+
}
|
|
599
|
+
|
|
626
600
|
// src/core/deposit-asset-helpers.ts
|
|
627
601
|
function getAssetId(asset) {
|
|
628
602
|
return `${asset.chainId}:${asset.token.toLowerCase()}`;
|
|
@@ -889,6 +863,7 @@ function createDepositService(baseUrl, options) {
|
|
|
889
863
|
const PORTFOLIO_CACHE_TTL_MS = 3e4;
|
|
890
864
|
const portfolioCache = /* @__PURE__ */ new Map();
|
|
891
865
|
let topTokensPromise = null;
|
|
866
|
+
let chainsPromise = null;
|
|
892
867
|
function parseTopTokens(value) {
|
|
893
868
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
894
869
|
return null;
|
|
@@ -936,6 +911,32 @@ function createDepositService(baseUrl, options) {
|
|
|
936
911
|
return null;
|
|
937
912
|
}
|
|
938
913
|
}
|
|
914
|
+
async function requestChains() {
|
|
915
|
+
try {
|
|
916
|
+
const response = await fetch(apiUrl("/chains"), {
|
|
917
|
+
method: "GET",
|
|
918
|
+
headers: SERVICE_HEADERS
|
|
919
|
+
});
|
|
920
|
+
if (!response.ok) {
|
|
921
|
+
debugLog(debug, scope, "getChains:unavailable", {
|
|
922
|
+
status: response.status
|
|
923
|
+
});
|
|
924
|
+
return null;
|
|
925
|
+
}
|
|
926
|
+
const catalog = parseChainCatalog(await response.json());
|
|
927
|
+
if (!catalog) {
|
|
928
|
+
debugLog(debug, scope, "getChains:malformed");
|
|
929
|
+
return null;
|
|
930
|
+
}
|
|
931
|
+
debugLog(debug, scope, "getChains:success", {
|
|
932
|
+
chains: catalog.all.length
|
|
933
|
+
});
|
|
934
|
+
return catalog;
|
|
935
|
+
} catch (error) {
|
|
936
|
+
debugError(debug, scope, "getChains:error", error);
|
|
937
|
+
return null;
|
|
938
|
+
}
|
|
939
|
+
}
|
|
939
940
|
function cachedPortfolio(key, fetcher, forceRefresh = false) {
|
|
940
941
|
const now = Date.now();
|
|
941
942
|
const entry = portfolioCache.get(key);
|
|
@@ -1184,6 +1185,67 @@ function createDepositService(baseUrl, options) {
|
|
|
1184
1185
|
});
|
|
1185
1186
|
return { lastEvent };
|
|
1186
1187
|
},
|
|
1188
|
+
async getPositions(address) {
|
|
1189
|
+
const url = apiUrl(`/positions/${address}`);
|
|
1190
|
+
debugLog(debug, scope, "getPositions:request", { url, address });
|
|
1191
|
+
const response = await fetch(url, { headers: SERVICE_HEADERS });
|
|
1192
|
+
if (!response.ok) {
|
|
1193
|
+
const error = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
1194
|
+
debugError(debug, scope, "getPositions:failed", error, {
|
|
1195
|
+
status: response.status,
|
|
1196
|
+
address
|
|
1197
|
+
});
|
|
1198
|
+
throw new Error(
|
|
1199
|
+
error.error || `Position lookup failed: ${response.status}`
|
|
1200
|
+
);
|
|
1201
|
+
}
|
|
1202
|
+
const result = await response.json();
|
|
1203
|
+
debugLog(debug, scope, "getPositions:success", {
|
|
1204
|
+
address,
|
|
1205
|
+
count: result.positions?.length ?? 0,
|
|
1206
|
+
totalUsd: result.totalUsd,
|
|
1207
|
+
failures: result.failures?.map((f) => f.venue)
|
|
1208
|
+
});
|
|
1209
|
+
return result;
|
|
1210
|
+
},
|
|
1211
|
+
async prepareUnwind(params) {
|
|
1212
|
+
const { address, account, market, chainId, asset, amount } = params;
|
|
1213
|
+
const url = apiUrl(`/positions/${address}/unwind`);
|
|
1214
|
+
debugLog(debug, scope, "prepareUnwind:request", {
|
|
1215
|
+
url,
|
|
1216
|
+
address,
|
|
1217
|
+
account,
|
|
1218
|
+
market,
|
|
1219
|
+
chainId,
|
|
1220
|
+
asset,
|
|
1221
|
+
amount
|
|
1222
|
+
});
|
|
1223
|
+
const response = await fetch(url, {
|
|
1224
|
+
method: "POST",
|
|
1225
|
+
headers: SERVICE_HEADERS,
|
|
1226
|
+
body: JSON.stringify({ account, market, chainId, asset, amount })
|
|
1227
|
+
});
|
|
1228
|
+
if (!response.ok) {
|
|
1229
|
+
const error = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
1230
|
+
debugError(debug, scope, "prepareUnwind:failed", error, {
|
|
1231
|
+
status: response.status,
|
|
1232
|
+
address,
|
|
1233
|
+
market,
|
|
1234
|
+
asset
|
|
1235
|
+
});
|
|
1236
|
+
throw new Error(
|
|
1237
|
+
error.error || `Unwind preparation failed: ${response.status}`
|
|
1238
|
+
);
|
|
1239
|
+
}
|
|
1240
|
+
const result = await response.json();
|
|
1241
|
+
debugLog(debug, scope, "prepareUnwind:success", {
|
|
1242
|
+
address,
|
|
1243
|
+
amount: result.amount,
|
|
1244
|
+
isFullExit: result.isFullExit,
|
|
1245
|
+
recipient: result.recipient
|
|
1246
|
+
});
|
|
1247
|
+
return result;
|
|
1248
|
+
},
|
|
1187
1249
|
async submitPolymarketWithdraw(params) {
|
|
1188
1250
|
const { depositWallet, owner, nonce, deadline, calls, signature } = params;
|
|
1189
1251
|
const url = apiUrl(`/polymarket/withdraw`);
|
|
@@ -1265,7 +1327,7 @@ function createDepositService(baseUrl, options) {
|
|
|
1265
1327
|
return { deposits, nextCursor };
|
|
1266
1328
|
},
|
|
1267
1329
|
async checkLiquidity(params) {
|
|
1268
|
-
if (params.destinationChainId === "solana") {
|
|
1330
|
+
if (isSolanaCaip2(params.destinationChainId) || params.destinationChainId === "solana") {
|
|
1269
1331
|
const token = getSolanaTokenByMint(params.destinationToken);
|
|
1270
1332
|
return {
|
|
1271
1333
|
hasLiquidity: true,
|
|
@@ -1276,9 +1338,9 @@ function createDepositService(baseUrl, options) {
|
|
|
1276
1338
|
};
|
|
1277
1339
|
}
|
|
1278
1340
|
const searchParams = new URLSearchParams({
|
|
1279
|
-
sourceChainId:
|
|
1341
|
+
sourceChainId: toEvmCaip2(params.sourceChainId),
|
|
1280
1342
|
sourceToken: params.sourceToken,
|
|
1281
|
-
destinationChainId:
|
|
1343
|
+
destinationChainId: params.destinationChainId,
|
|
1282
1344
|
destinationToken: params.destinationToken,
|
|
1283
1345
|
amount: params.amount
|
|
1284
1346
|
});
|
|
@@ -1621,6 +1683,16 @@ function createDepositService(baseUrl, options) {
|
|
|
1621
1683
|
}
|
|
1622
1684
|
return topTokensPromise;
|
|
1623
1685
|
},
|
|
1686
|
+
getChains() {
|
|
1687
|
+
if (!chainsPromise) {
|
|
1688
|
+
const attempt = requestChains().then((catalog) => {
|
|
1689
|
+
if (!catalog && chainsPromise === attempt) chainsPromise = null;
|
|
1690
|
+
return catalog;
|
|
1691
|
+
});
|
|
1692
|
+
chainsPromise = attempt;
|
|
1693
|
+
}
|
|
1694
|
+
return chainsPromise;
|
|
1695
|
+
},
|
|
1624
1696
|
async getSetup() {
|
|
1625
1697
|
const url = apiUrl("/setup");
|
|
1626
1698
|
try {
|
|
@@ -1805,6 +1877,558 @@ function extractNumericString(data, key) {
|
|
|
1805
1877
|
return Number.isFinite(parsed) ? parsed : null;
|
|
1806
1878
|
}
|
|
1807
1879
|
|
|
1880
|
+
// src/core/rpc.ts
|
|
1881
|
+
import { createContext, useContext, useMemo } from "react";
|
|
1882
|
+
function rpcUrlFor(rpcUrls, chain) {
|
|
1883
|
+
const url = rpcUrls?.[chain]?.trim();
|
|
1884
|
+
return url ? url : void 0;
|
|
1885
|
+
}
|
|
1886
|
+
var RpcUrlsContext = createContext(void 0);
|
|
1887
|
+
var RpcUrlsProvider = RpcUrlsContext.Provider;
|
|
1888
|
+
function useRpcUrls() {
|
|
1889
|
+
return useContext(RpcUrlsContext);
|
|
1890
|
+
}
|
|
1891
|
+
function rpcUrlsKey(rpcUrls) {
|
|
1892
|
+
if (!rpcUrls) return "";
|
|
1893
|
+
return Object.entries(rpcUrls).map(([chain, url]) => [chain, url?.trim() ?? ""]).filter(([, url]) => url !== "").map(([chain, url]) => `${chain}=${url}`).sort().join("|");
|
|
1894
|
+
}
|
|
1895
|
+
function useStableRpcUrls(rpcUrls) {
|
|
1896
|
+
const key = rpcUrlsKey(rpcUrls);
|
|
1897
|
+
return useMemo(() => rpcUrls, [key]);
|
|
1898
|
+
}
|
|
1899
|
+
|
|
1900
|
+
// src/core/chain-catalog-context.tsx
|
|
1901
|
+
import {
|
|
1902
|
+
createContext as createContext2,
|
|
1903
|
+
useContext as useContext2,
|
|
1904
|
+
useEffect as useEffect2,
|
|
1905
|
+
useMemo as useMemo2,
|
|
1906
|
+
useState as useState2
|
|
1907
|
+
} from "react";
|
|
1908
|
+
|
|
1909
|
+
// src/core/public-client.ts
|
|
1910
|
+
import { createPublicClient, http } from "viem";
|
|
1911
|
+
var clientCache = /* @__PURE__ */ new Map();
|
|
1912
|
+
var runtimeChainById = /* @__PURE__ */ new Map();
|
|
1913
|
+
function setRuntimeChains(chains) {
|
|
1914
|
+
for (const chain of chains) {
|
|
1915
|
+
const known = runtimeChainById.get(chain.id);
|
|
1916
|
+
if (known === chain) continue;
|
|
1917
|
+
runtimeChainById.set(chain.id, chain);
|
|
1918
|
+
for (const key of clientCache.keys()) {
|
|
1919
|
+
if (key.startsWith(`${chain.id}|`)) clientCache.delete(key);
|
|
1920
|
+
}
|
|
1921
|
+
}
|
|
1922
|
+
}
|
|
1923
|
+
function getPublicClient(chainId, rpcUrls) {
|
|
1924
|
+
const url = rpcUrlFor(rpcUrls, chainId);
|
|
1925
|
+
const cacheKey = `${chainId}|${url ?? ""}`;
|
|
1926
|
+
let client = clientCache.get(cacheKey);
|
|
1927
|
+
if (!client) {
|
|
1928
|
+
const chain = CHAIN_BY_ID[chainId] ?? runtimeChainById.get(chainId);
|
|
1929
|
+
client = createPublicClient({
|
|
1930
|
+
chain,
|
|
1931
|
+
transport: http(url)
|
|
1932
|
+
});
|
|
1933
|
+
clientCache.set(cacheKey, client);
|
|
1934
|
+
}
|
|
1935
|
+
return client;
|
|
1936
|
+
}
|
|
1937
|
+
|
|
1938
|
+
// src/core/chain-objects.ts
|
|
1939
|
+
import { defineChain } from "viem";
|
|
1940
|
+
var viemChainsById = null;
|
|
1941
|
+
var viemChainsPromise = null;
|
|
1942
|
+
async function loadViemChains() {
|
|
1943
|
+
if (viemChainsById) return viemChainsById;
|
|
1944
|
+
if (!viemChainsPromise) {
|
|
1945
|
+
viemChainsPromise = import("viem/chains").then((module) => {
|
|
1946
|
+
const map = /* @__PURE__ */ new Map();
|
|
1947
|
+
for (const value of Object.values(module)) {
|
|
1948
|
+
if (value && typeof value === "object" && typeof value.id === "number" && value.rpcUrls?.default?.http?.length) {
|
|
1949
|
+
const chain = value;
|
|
1950
|
+
const existing = map.get(chain.id);
|
|
1951
|
+
if (existing) existing.push(chain);
|
|
1952
|
+
else map.set(chain.id, [chain]);
|
|
1953
|
+
}
|
|
1954
|
+
}
|
|
1955
|
+
viemChainsById = map;
|
|
1956
|
+
return map;
|
|
1957
|
+
});
|
|
1958
|
+
}
|
|
1959
|
+
return viemChainsPromise;
|
|
1960
|
+
}
|
|
1961
|
+
function pickViemChain(candidates, chain) {
|
|
1962
|
+
if (!candidates?.length) return void 0;
|
|
1963
|
+
if (candidates.length === 1) return candidates[0];
|
|
1964
|
+
const sameNetworkClass = candidates.filter(
|
|
1965
|
+
(candidate) => Boolean(candidate.testnet) === chain.testnet
|
|
1966
|
+
);
|
|
1967
|
+
if (sameNetworkClass.length === 1) return sameNetworkClass[0];
|
|
1968
|
+
const pool = sameNetworkClass.length > 0 ? sameNetworkClass : candidates;
|
|
1969
|
+
const normalized = chain.name.toLowerCase().replace(/\s+/g, "");
|
|
1970
|
+
const byName = pool.find(
|
|
1971
|
+
(candidate) => candidate.name.toLowerCase().replace(/\s+/g, "") === normalized
|
|
1972
|
+
);
|
|
1973
|
+
if (byName) return byName;
|
|
1974
|
+
return void 0;
|
|
1975
|
+
}
|
|
1976
|
+
function resolveRpcUrls(chain, override, viemChains) {
|
|
1977
|
+
const urls = [];
|
|
1978
|
+
if (override?.trim()) urls.push(override.trim());
|
|
1979
|
+
if (chain.publicRpcUrl) urls.push(chain.publicRpcUrl);
|
|
1980
|
+
if (chain.chainId !== null && chain.vmType === "evm") {
|
|
1981
|
+
const http2 = pickViemChain(viemChains?.get(chain.chainId), chain)?.rpcUrls?.default?.http;
|
|
1982
|
+
if (http2) urls.push(...http2);
|
|
1983
|
+
}
|
|
1984
|
+
return [...new Set(urls)];
|
|
1985
|
+
}
|
|
1986
|
+
function toViemChain(chain, override, viemChains) {
|
|
1987
|
+
if (chain.vmType !== "evm" || chain.chainId === null) return null;
|
|
1988
|
+
const rpcUrls = resolveRpcUrls(chain, override, viemChains);
|
|
1989
|
+
if (rpcUrls.length === 0) return null;
|
|
1990
|
+
const bundled = pickViemChain(viemChains?.get(chain.chainId), chain);
|
|
1991
|
+
if (bundled) {
|
|
1992
|
+
if (rpcUrls[0] === bundled.rpcUrls.default.http[0]) return bundled;
|
|
1993
|
+
return defineChain({
|
|
1994
|
+
...bundled,
|
|
1995
|
+
rpcUrls: { ...bundled.rpcUrls, default: { http: rpcUrls } }
|
|
1996
|
+
});
|
|
1997
|
+
}
|
|
1998
|
+
return defineChain({
|
|
1999
|
+
id: chain.chainId,
|
|
2000
|
+
name: chain.name,
|
|
2001
|
+
nativeCurrency: {
|
|
2002
|
+
name: chain.nativeToken.symbol,
|
|
2003
|
+
symbol: chain.nativeToken.symbol,
|
|
2004
|
+
decimals: chain.nativeToken.decimals
|
|
2005
|
+
},
|
|
2006
|
+
rpcUrls: { default: { http: rpcUrls } },
|
|
2007
|
+
blockExplorers: chain.explorer ? {
|
|
2008
|
+
default: {
|
|
2009
|
+
name: "Explorer",
|
|
2010
|
+
url: chain.explorer.url
|
|
2011
|
+
}
|
|
2012
|
+
} : void 0,
|
|
2013
|
+
testnet: chain.testnet
|
|
2014
|
+
});
|
|
2015
|
+
}
|
|
2016
|
+
function toViemChains(catalog, overrides, viemChains) {
|
|
2017
|
+
const chains = [];
|
|
2018
|
+
for (const entry of catalog.all) {
|
|
2019
|
+
const chain = toViemChain(
|
|
2020
|
+
entry,
|
|
2021
|
+
entry.chainId === null ? void 0 : overrides?.[entry.chainId],
|
|
2022
|
+
viemChains
|
|
2023
|
+
);
|
|
2024
|
+
if (chain) chains.push(chain);
|
|
2025
|
+
}
|
|
2026
|
+
return chains;
|
|
2027
|
+
}
|
|
2028
|
+
function needsViemChains(catalog, overrides) {
|
|
2029
|
+
return catalog.all.some(
|
|
2030
|
+
(chain) => chain.vmType === "evm" && chain.chainId !== null && !chain.publicRpcUrl && !overrides?.[chain.chainId]?.trim()
|
|
2031
|
+
);
|
|
2032
|
+
}
|
|
2033
|
+
|
|
2034
|
+
// src/core/chain-catalog-context.tsx
|
|
2035
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
2036
|
+
var EMPTY = {
|
|
2037
|
+
catalog: null,
|
|
2038
|
+
viemChains: null,
|
|
2039
|
+
isLoading: true,
|
|
2040
|
+
shortlist: null,
|
|
2041
|
+
clientCapableChainIds: null
|
|
2042
|
+
};
|
|
2043
|
+
var ChainCatalogContext = createContext2(EMPTY);
|
|
2044
|
+
var resolvedChainsByKey = /* @__PURE__ */ new Map();
|
|
2045
|
+
function overridesKey(overrides) {
|
|
2046
|
+
return Object.entries(overrides ?? {}).map(([id, override]) => `${id}=${override ?? ""}`).sort().join("|");
|
|
2047
|
+
}
|
|
2048
|
+
function runtimeChainsKey(backendUrl, overrides) {
|
|
2049
|
+
return [backendUrl.replace(/\/$/, ""), overridesKey(overrides)].join("#");
|
|
2050
|
+
}
|
|
2051
|
+
var catalogByBackend = /* @__PURE__ */ new Map();
|
|
2052
|
+
function primeChainCatalog(backendUrl, debug = false) {
|
|
2053
|
+
const key = backendUrl.replace(/\/$/, "");
|
|
2054
|
+
let promise = catalogByBackend.get(key);
|
|
2055
|
+
if (!promise) {
|
|
2056
|
+
promise = createDepositService(key, {
|
|
2057
|
+
debug,
|
|
2058
|
+
debugScope: "service:chains"
|
|
2059
|
+
}).getChains();
|
|
2060
|
+
catalogByBackend.set(key, promise);
|
|
2061
|
+
promise.then((catalog) => {
|
|
2062
|
+
if (!catalog) catalogByBackend.delete(key);
|
|
2063
|
+
});
|
|
2064
|
+
}
|
|
2065
|
+
return promise;
|
|
2066
|
+
}
|
|
2067
|
+
function peekRuntimeChains(backendUrl, overrides) {
|
|
2068
|
+
return resolvedChainsByKey.get(runtimeChainsKey(backendUrl, overrides)) ?? null;
|
|
2069
|
+
}
|
|
2070
|
+
function publishCatalogTokens(catalog) {
|
|
2071
|
+
setRuntimeTokens(
|
|
2072
|
+
catalog.all.flatMap(
|
|
2073
|
+
(chain) => chain.chainId === null || !Array.isArray(chain.supportedTokens) ? [] : chain.supportedTokens.map((token) => ({
|
|
2074
|
+
chainId: chain.chainId,
|
|
2075
|
+
symbol: token.symbol,
|
|
2076
|
+
address: token.address,
|
|
2077
|
+
decimals: token.decimals
|
|
2078
|
+
}))
|
|
2079
|
+
)
|
|
2080
|
+
);
|
|
2081
|
+
}
|
|
2082
|
+
function publishRuntimeChainMeta(catalog) {
|
|
2083
|
+
setRuntimeChainMeta(
|
|
2084
|
+
catalog.all.flatMap((chain) => {
|
|
2085
|
+
const ids = [];
|
|
2086
|
+
if (chain.chainId !== null) ids.push(chain.chainId);
|
|
2087
|
+
if (chain.caip2 === HYPERCORE_MAINNET_CAIP2) ids.push(HYPERCORE_CHAIN_ID);
|
|
2088
|
+
return ids.map((chainId) => ({
|
|
2089
|
+
chainId,
|
|
2090
|
+
name: chain.name,
|
|
2091
|
+
iconUrl: chain.iconUrl ?? void 0,
|
|
2092
|
+
nativeSymbol: chain.nativeToken.symbol
|
|
2093
|
+
}));
|
|
2094
|
+
})
|
|
2095
|
+
);
|
|
2096
|
+
}
|
|
2097
|
+
var runtimeChainsByBackend = /* @__PURE__ */ new Map();
|
|
2098
|
+
function primeRuntimeChains(backendUrl, overrides, debug = false) {
|
|
2099
|
+
const url = backendUrl.replace(/\/$/, "");
|
|
2100
|
+
const key = runtimeChainsKey(url, overrides);
|
|
2101
|
+
let promise = runtimeChainsByBackend.get(key);
|
|
2102
|
+
if (!promise) {
|
|
2103
|
+
promise = primeChainCatalog(url, debug).then(async (catalog) => {
|
|
2104
|
+
if (!catalog) return [];
|
|
2105
|
+
publishRuntimeChainMeta(catalog);
|
|
2106
|
+
publishCatalogTokens(catalog);
|
|
2107
|
+
const viemChains = needsViemChains(catalog, overrides) ? await loadViemChains() : null;
|
|
2108
|
+
const chains = toViemChains(catalog, overrides, viemChains);
|
|
2109
|
+
if (chains.length > 0) {
|
|
2110
|
+
setRuntimeChains(chains);
|
|
2111
|
+
resolvedChainsByKey.set(key, chains);
|
|
2112
|
+
}
|
|
2113
|
+
return chains;
|
|
2114
|
+
}).catch(() => []);
|
|
2115
|
+
runtimeChainsByBackend.set(key, promise);
|
|
2116
|
+
promise.then((chains) => {
|
|
2117
|
+
if (chains.length === 0) runtimeChainsByBackend.delete(key);
|
|
2118
|
+
});
|
|
2119
|
+
}
|
|
2120
|
+
return promise;
|
|
2121
|
+
}
|
|
2122
|
+
function useChainCatalog() {
|
|
2123
|
+
return useContext2(ChainCatalogContext);
|
|
2124
|
+
}
|
|
2125
|
+
function useCatalogChain(chainId) {
|
|
2126
|
+
const { catalog } = useChainCatalog();
|
|
2127
|
+
if (!catalog || chainId == null) return void 0;
|
|
2128
|
+
return typeof chainId === "number" ? catalog.byChainId.get(chainId) : catalog.byCaip2.get(chainId);
|
|
2129
|
+
}
|
|
2130
|
+
function useDepositChainIds() {
|
|
2131
|
+
const { catalog } = useChainCatalog();
|
|
2132
|
+
return useMemo2(() => {
|
|
2133
|
+
if (!catalog) return getSupportedChainIds();
|
|
2134
|
+
const ids = catalog.all.filter(
|
|
2135
|
+
(c) => c.deposit && c.vmType === "evm" && c.chainId !== null && // `/chains` enumerates testnets; the bundled list never did, and a
|
|
2136
|
+
// production picker offering Sepolia next to Ethereum is a way to
|
|
2137
|
+
// lose funds. Reading the set at runtime must not quietly widen it
|
|
2138
|
+
// to a different KIND of chain.
|
|
2139
|
+
!c.testnet
|
|
2140
|
+
).map((c) => c.chainId);
|
|
2141
|
+
const rank = (id) => {
|
|
2142
|
+
const i = CHAIN_DISPLAY_ORDER.indexOf(id);
|
|
2143
|
+
return i === -1 ? CHAIN_DISPLAY_ORDER.length : i;
|
|
2144
|
+
};
|
|
2145
|
+
return ids.map((id, i) => ({ id, i })).sort((a, b) => rank(a.id) - rank(b.id) || a.i - b.i).map(({ id }) => id);
|
|
2146
|
+
}, [catalog]);
|
|
2147
|
+
}
|
|
2148
|
+
function useDestinationChains() {
|
|
2149
|
+
const { catalog } = useChainCatalog();
|
|
2150
|
+
return useMemo2(() => {
|
|
2151
|
+
if (!catalog) {
|
|
2152
|
+
return SOURCE_CHAINS.filter(
|
|
2153
|
+
(chain) => getSupportedTargetTokens(chain.id).length > 0
|
|
2154
|
+
).map((chain) => ({ id: chain.id, name: chain.name }));
|
|
2155
|
+
}
|
|
2156
|
+
const rank = (id) => {
|
|
2157
|
+
const i = CHAIN_DISPLAY_ORDER.indexOf(id);
|
|
2158
|
+
return i === -1 ? CHAIN_DISPLAY_ORDER.length : i;
|
|
2159
|
+
};
|
|
2160
|
+
return catalog.all.filter(
|
|
2161
|
+
(c) => c.destination && c.vmType === "evm" && c.chainId !== null && !c.testnet
|
|
2162
|
+
).map((c, i) => ({ id: c.chainId, name: c.name, i })).sort((a, b) => rank(a.id) - rank(b.id) || a.i - b.i).map(({ id, name }) => ({ id, name }));
|
|
2163
|
+
}, [catalog]);
|
|
2164
|
+
}
|
|
2165
|
+
function useTargetTokens() {
|
|
2166
|
+
const { catalog, shortlist } = useChainCatalog();
|
|
2167
|
+
return useMemo2(() => {
|
|
2168
|
+
return (chainId) => {
|
|
2169
|
+
const bundled = getBundledTargetTokens(chainId);
|
|
2170
|
+
if (bundled.length > 0) return bundled;
|
|
2171
|
+
const fromShortlist = shortlist?.[String(chainId)];
|
|
2172
|
+
if (fromShortlist?.length) {
|
|
2173
|
+
return fromShortlist.map((token) => ({
|
|
2174
|
+
symbol: token.symbol,
|
|
2175
|
+
address: token.address,
|
|
2176
|
+
decimals: token.decimals
|
|
2177
|
+
}));
|
|
2178
|
+
}
|
|
2179
|
+
const entry = catalog?.byChainId.get(chainId);
|
|
2180
|
+
return Array.isArray(entry?.supportedTokens) ? entry.supportedTokens.map((token) => ({
|
|
2181
|
+
symbol: token.symbol,
|
|
2182
|
+
address: token.address,
|
|
2183
|
+
decimals: token.decimals
|
|
2184
|
+
})) : [];
|
|
2185
|
+
};
|
|
2186
|
+
}, [catalog, shortlist]);
|
|
2187
|
+
}
|
|
2188
|
+
function useIsDepositChain() {
|
|
2189
|
+
const ids = useDepositChainIds();
|
|
2190
|
+
const { clientCapableChainIds } = useChainCatalog();
|
|
2191
|
+
return useMemo2(() => {
|
|
2192
|
+
const set = new Set(ids);
|
|
2193
|
+
return (chainId) => set.has(chainId) && (clientCapableChainIds === null || clientCapableChainIds.has(chainId));
|
|
2194
|
+
}, [ids, clientCapableChainIds]);
|
|
2195
|
+
}
|
|
2196
|
+
function useChainName() {
|
|
2197
|
+
const { catalog } = useChainCatalog();
|
|
2198
|
+
return useMemo2(() => {
|
|
2199
|
+
return (chainId) => {
|
|
2200
|
+
if (!catalog) return getChainName(chainId);
|
|
2201
|
+
const key = catalogKeyForChain(chainId);
|
|
2202
|
+
const entry = typeof key === "number" ? catalog.byChainId.get(key) : catalog.byCaip2.get(key);
|
|
2203
|
+
return entry?.name ?? getChainName(chainId);
|
|
2204
|
+
};
|
|
2205
|
+
}, [catalog]);
|
|
2206
|
+
}
|
|
2207
|
+
function useExplorerTxUrl() {
|
|
2208
|
+
const { catalog } = useChainCatalog();
|
|
2209
|
+
return useMemo2(() => {
|
|
2210
|
+
return (chainId, txHash) => {
|
|
2211
|
+
if (chainId === "hypercore") return getExplorerTxUrl(chainId, txHash);
|
|
2212
|
+
const key = catalog ? catalogKeyForChain(chainId) : void 0;
|
|
2213
|
+
const entry = key === void 0 ? void 0 : typeof key === "number" ? catalog?.byChainId.get(key) : catalog?.byCaip2.get(key);
|
|
2214
|
+
return catalogExplorerTxUrl(entry, txHash) ?? getExplorerTxUrl(chainId, txHash);
|
|
2215
|
+
};
|
|
2216
|
+
}, [catalog]);
|
|
2217
|
+
}
|
|
2218
|
+
function ChainCatalogProvider({
|
|
2219
|
+
service,
|
|
2220
|
+
rpcUrls,
|
|
2221
|
+
children
|
|
2222
|
+
}) {
|
|
2223
|
+
const [catalog, setCatalog] = useState2(null);
|
|
2224
|
+
const [viemChains, setViemChains] = useState2(null);
|
|
2225
|
+
const [isLoading, setIsLoading] = useState2(true);
|
|
2226
|
+
useEffect2(() => {
|
|
2227
|
+
let active = true;
|
|
2228
|
+
setIsLoading(true);
|
|
2229
|
+
service.getChains().then((next) => {
|
|
2230
|
+
if (!active) return;
|
|
2231
|
+
setCatalog(next);
|
|
2232
|
+
setIsLoading(false);
|
|
2233
|
+
});
|
|
2234
|
+
return () => {
|
|
2235
|
+
active = false;
|
|
2236
|
+
};
|
|
2237
|
+
}, [service]);
|
|
2238
|
+
const overrides = useMemo2(() => {
|
|
2239
|
+
if (!rpcUrls) return void 0;
|
|
2240
|
+
const out = {};
|
|
2241
|
+
for (const [key, url] of Object.entries(rpcUrls)) {
|
|
2242
|
+
const id = Number(key);
|
|
2243
|
+
if (Number.isFinite(id) && typeof url === "string") out[id] = url;
|
|
2244
|
+
}
|
|
2245
|
+
return out;
|
|
2246
|
+
}, [rpcUrls]);
|
|
2247
|
+
const overrideKey = overridesKey(overrides);
|
|
2248
|
+
useEffect2(() => {
|
|
2249
|
+
if (!catalog || viemChains) return;
|
|
2250
|
+
if (!needsViemChains(catalog, overrides)) return;
|
|
2251
|
+
let active = true;
|
|
2252
|
+
loadViemChains().then((chains) => {
|
|
2253
|
+
if (active) setViemChains(chains);
|
|
2254
|
+
});
|
|
2255
|
+
return () => {
|
|
2256
|
+
active = false;
|
|
2257
|
+
};
|
|
2258
|
+
}, [catalog, viemChains, overrideKey]);
|
|
2259
|
+
useEffect2(() => {
|
|
2260
|
+
if (!catalog) return;
|
|
2261
|
+
publishRuntimeChainMeta(catalog);
|
|
2262
|
+
publishCatalogTokens(catalog);
|
|
2263
|
+
const chains = toViemChains(catalog, overrides, viemChains);
|
|
2264
|
+
if (chains.length > 0) setRuntimeChains(chains);
|
|
2265
|
+
}, [catalog, viemChains, overrides]);
|
|
2266
|
+
const [shortlist, setShortlist] = useState2(null);
|
|
2267
|
+
useEffect2(() => {
|
|
2268
|
+
let active = true;
|
|
2269
|
+
setShortlist(null);
|
|
2270
|
+
service.getTopTokens().then((tokens) => {
|
|
2271
|
+
if (!active || !tokens) return;
|
|
2272
|
+
publishShortlistTokens(tokens);
|
|
2273
|
+
setShortlist(tokens);
|
|
2274
|
+
});
|
|
2275
|
+
return () => {
|
|
2276
|
+
active = false;
|
|
2277
|
+
};
|
|
2278
|
+
}, [service]);
|
|
2279
|
+
const clientCapableChainIds = useMemo2(() => {
|
|
2280
|
+
if (!catalog) return null;
|
|
2281
|
+
return new Set(
|
|
2282
|
+
toViemChains(catalog, overrides, viemChains).map((c) => c.id)
|
|
2283
|
+
);
|
|
2284
|
+
}, [catalog, viemChains, overrideKey]);
|
|
2285
|
+
const value = useMemo2(
|
|
2286
|
+
() => ({
|
|
2287
|
+
catalog,
|
|
2288
|
+
viemChains,
|
|
2289
|
+
isLoading,
|
|
2290
|
+
shortlist,
|
|
2291
|
+
clientCapableChainIds
|
|
2292
|
+
}),
|
|
2293
|
+
[catalog, viemChains, isLoading, shortlist, clientCapableChainIds]
|
|
2294
|
+
);
|
|
2295
|
+
return /* @__PURE__ */ jsx6(ChainCatalogContext.Provider, { value, children });
|
|
2296
|
+
}
|
|
2297
|
+
|
|
2298
|
+
// src/core/useLatestRef.ts
|
|
2299
|
+
import { useEffect as useEffect3, useRef as useRef2 } from "react";
|
|
2300
|
+
function useLatestRef(value) {
|
|
2301
|
+
const ref = useRef2(value);
|
|
2302
|
+
useEffect3(() => {
|
|
2303
|
+
ref.current = value;
|
|
2304
|
+
}, [value]);
|
|
2305
|
+
return ref;
|
|
2306
|
+
}
|
|
2307
|
+
|
|
2308
|
+
// src/components/ui/Spinner.tsx
|
|
2309
|
+
import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2310
|
+
function Spinner({ className }) {
|
|
2311
|
+
return /* @__PURE__ */ jsxs4(
|
|
2312
|
+
"svg",
|
|
2313
|
+
{
|
|
2314
|
+
className: `rs-spinner ${className || ""}`,
|
|
2315
|
+
fill: "none",
|
|
2316
|
+
viewBox: "0 0 20 21",
|
|
2317
|
+
children: [
|
|
2318
|
+
/* @__PURE__ */ jsx7(
|
|
2319
|
+
"path",
|
|
2320
|
+
{
|
|
2321
|
+
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",
|
|
2322
|
+
fill: "currentColor",
|
|
2323
|
+
opacity: 0.3
|
|
2324
|
+
}
|
|
2325
|
+
),
|
|
2326
|
+
/* @__PURE__ */ jsx7(
|
|
2327
|
+
"path",
|
|
2328
|
+
{
|
|
2329
|
+
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",
|
|
2330
|
+
fill: "currentColor"
|
|
2331
|
+
}
|
|
2332
|
+
)
|
|
2333
|
+
]
|
|
2334
|
+
}
|
|
2335
|
+
);
|
|
2336
|
+
}
|
|
2337
|
+
|
|
2338
|
+
// src/components/ui/Button.tsx
|
|
2339
|
+
import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2340
|
+
function Button({
|
|
2341
|
+
children,
|
|
2342
|
+
variant = "accent",
|
|
2343
|
+
size = "default",
|
|
2344
|
+
loading = false,
|
|
2345
|
+
loadingText,
|
|
2346
|
+
fullWidth = false,
|
|
2347
|
+
disabled,
|
|
2348
|
+
className = "",
|
|
2349
|
+
...props
|
|
2350
|
+
}) {
|
|
2351
|
+
const classes = [
|
|
2352
|
+
"rs-button",
|
|
2353
|
+
`rs-button--${variant}`,
|
|
2354
|
+
`rs-button--size-${size}`,
|
|
2355
|
+
fullWidth ? "rs-button--full-width" : "",
|
|
2356
|
+
className
|
|
2357
|
+
].filter(Boolean).join(" ");
|
|
2358
|
+
const showInlineLoadingText = loading && loadingText !== void 0;
|
|
2359
|
+
return /* @__PURE__ */ jsx8(
|
|
2360
|
+
"button",
|
|
2361
|
+
{
|
|
2362
|
+
className: classes,
|
|
2363
|
+
disabled: disabled || loading,
|
|
2364
|
+
"aria-busy": loading || void 0,
|
|
2365
|
+
...props,
|
|
2366
|
+
children: showInlineLoadingText ? /* @__PURE__ */ jsxs5("span", { className: "rs-button__loading-row", children: [
|
|
2367
|
+
/* @__PURE__ */ jsx8(Spinner, { className: "rs-spinner--sm" }),
|
|
2368
|
+
/* @__PURE__ */ jsx8("span", { children: loadingText })
|
|
2369
|
+
] }) : /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
2370
|
+
/* @__PURE__ */ jsx8("span", { className: loading ? "rs-button__content--hidden" : "", children }),
|
|
2371
|
+
loading && /* @__PURE__ */ jsx8("span", { className: "rs-button__spinner", children: /* @__PURE__ */ jsx8(Spinner, { className: "rs-spinner--sm" }) })
|
|
2372
|
+
] })
|
|
2373
|
+
}
|
|
2374
|
+
);
|
|
2375
|
+
}
|
|
2376
|
+
Button.displayName = "Button";
|
|
2377
|
+
|
|
2378
|
+
// src/components/ui/Callout.tsx
|
|
2379
|
+
import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2380
|
+
function CircleAlertIcon() {
|
|
2381
|
+
return /* @__PURE__ */ jsx9(
|
|
2382
|
+
"svg",
|
|
2383
|
+
{
|
|
2384
|
+
width: "16",
|
|
2385
|
+
height: "16",
|
|
2386
|
+
viewBox: "0 0 16 16",
|
|
2387
|
+
fill: "none",
|
|
2388
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2389
|
+
"aria-hidden": "true",
|
|
2390
|
+
children: /* @__PURE__ */ jsx9(
|
|
2391
|
+
"path",
|
|
2392
|
+
{
|
|
2393
|
+
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",
|
|
2394
|
+
stroke: "currentColor",
|
|
2395
|
+
strokeWidth: "1.33",
|
|
2396
|
+
strokeLinecap: "round",
|
|
2397
|
+
strokeLinejoin: "round"
|
|
2398
|
+
}
|
|
2399
|
+
)
|
|
2400
|
+
}
|
|
2401
|
+
);
|
|
2402
|
+
}
|
|
2403
|
+
function Callout({ variant = "error", children, role }) {
|
|
2404
|
+
return /* @__PURE__ */ jsxs6(
|
|
2405
|
+
"div",
|
|
2406
|
+
{
|
|
2407
|
+
className: `rs-callout rs-callout--${variant}`,
|
|
2408
|
+
role: role ?? (variant === "error" ? "alert" : "status"),
|
|
2409
|
+
children: [
|
|
2410
|
+
/* @__PURE__ */ jsx9("span", { className: "rs-callout-icon", children: variant === "error" ? /* @__PURE__ */ jsx9(CircleAlertIcon, {}) : /* @__PURE__ */ jsx9(AlertTriangleIcon, {}) }),
|
|
2411
|
+
/* @__PURE__ */ jsx9("span", { className: "rs-callout-text", children })
|
|
2412
|
+
]
|
|
2413
|
+
}
|
|
2414
|
+
);
|
|
2415
|
+
}
|
|
2416
|
+
Callout.displayName = "Callout";
|
|
2417
|
+
|
|
2418
|
+
// src/components/ui/TokenIcon.tsx
|
|
2419
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
2420
|
+
function TokenIcon({ symbol, className, fallback }) {
|
|
2421
|
+
return /* @__PURE__ */ jsx10(
|
|
2422
|
+
CdnIcon,
|
|
2423
|
+
{
|
|
2424
|
+
src: tokenIconUrl(symbol),
|
|
2425
|
+
className: `rs-token-icon ${className ?? ""}`.trimEnd(),
|
|
2426
|
+
fallback
|
|
2427
|
+
}
|
|
2428
|
+
);
|
|
2429
|
+
}
|
|
2430
|
+
TokenIcon.displayName = "TokenIcon";
|
|
2431
|
+
|
|
1808
2432
|
// src/core/formatters.ts
|
|
1809
2433
|
var currencyFormatter = new Intl.NumberFormat("en-US", {
|
|
1810
2434
|
style: "currency",
|
|
@@ -2015,26 +2639,6 @@ function formatReceiveEstimate(params) {
|
|
|
2015
2639
|
return sameSymbol ? `${formatted} ${params.targetSymbol}` : `~${formatted} ${params.targetSymbol}`;
|
|
2016
2640
|
}
|
|
2017
2641
|
|
|
2018
|
-
// src/core/rpc.ts
|
|
2019
|
-
import { createContext, useContext, useMemo } from "react";
|
|
2020
|
-
function rpcUrlFor(rpcUrls, chain) {
|
|
2021
|
-
const url = rpcUrls?.[chain]?.trim();
|
|
2022
|
-
return url ? url : void 0;
|
|
2023
|
-
}
|
|
2024
|
-
var RpcUrlsContext = createContext(void 0);
|
|
2025
|
-
var RpcUrlsProvider = RpcUrlsContext.Provider;
|
|
2026
|
-
function useRpcUrls() {
|
|
2027
|
-
return useContext(RpcUrlsContext);
|
|
2028
|
-
}
|
|
2029
|
-
function rpcUrlsKey(rpcUrls) {
|
|
2030
|
-
if (!rpcUrls) return "";
|
|
2031
|
-
return Object.entries(rpcUrls).map(([chain, url]) => [chain, url?.trim() ?? ""]).filter(([, url]) => url !== "").map(([chain, url]) => `${chain}=${url}`).sort().join("|");
|
|
2032
|
-
}
|
|
2033
|
-
function useStableRpcUrls(rpcUrls) {
|
|
2034
|
-
const key = rpcUrlsKey(rpcUrls);
|
|
2035
|
-
return useMemo(() => rpcUrls, [key]);
|
|
2036
|
-
}
|
|
2037
|
-
|
|
2038
2642
|
// src/core/theme.ts
|
|
2039
2643
|
var RADIUS_SCALE = {
|
|
2040
2644
|
none: { sm: "0", md: "0", lg: "0" },
|
|
@@ -2235,10 +2839,7 @@ export {
|
|
|
2235
2839
|
CdnIcon,
|
|
2236
2840
|
PoweredBy,
|
|
2237
2841
|
Spinner,
|
|
2238
|
-
|
|
2239
|
-
Button,
|
|
2240
|
-
Callout,
|
|
2241
|
-
TokenIcon,
|
|
2842
|
+
catalogKeyForChain,
|
|
2242
2843
|
debugLog,
|
|
2243
2844
|
debugError,
|
|
2244
2845
|
getAssetId,
|
|
@@ -2251,6 +2852,26 @@ export {
|
|
|
2251
2852
|
SwappedConnectFeeChangedError,
|
|
2252
2853
|
resolveAppFeeBps,
|
|
2253
2854
|
createDepositService,
|
|
2855
|
+
rpcUrlFor,
|
|
2856
|
+
RpcUrlsProvider,
|
|
2857
|
+
useRpcUrls,
|
|
2858
|
+
useStableRpcUrls,
|
|
2859
|
+
getPublicClient,
|
|
2860
|
+
peekRuntimeChains,
|
|
2861
|
+
primeRuntimeChains,
|
|
2862
|
+
useChainCatalog,
|
|
2863
|
+
useCatalogChain,
|
|
2864
|
+
useDepositChainIds,
|
|
2865
|
+
useDestinationChains,
|
|
2866
|
+
useTargetTokens,
|
|
2867
|
+
useIsDepositChain,
|
|
2868
|
+
useChainName,
|
|
2869
|
+
useExplorerTxUrl,
|
|
2870
|
+
ChainCatalogProvider,
|
|
2871
|
+
useLatestRef,
|
|
2872
|
+
Button,
|
|
2873
|
+
Callout,
|
|
2874
|
+
TokenIcon,
|
|
2254
2875
|
currencyFormatter,
|
|
2255
2876
|
tokenFormatter,
|
|
2256
2877
|
isUnsupportedChainSwitchError,
|
|
@@ -2264,10 +2885,6 @@ export {
|
|
|
2264
2885
|
estimateReceiveAmount,
|
|
2265
2886
|
formatQuotedReceive,
|
|
2266
2887
|
formatReceiveEstimate,
|
|
2267
|
-
rpcUrlFor,
|
|
2268
|
-
RpcUrlsProvider,
|
|
2269
|
-
useRpcUrls,
|
|
2270
|
-
useStableRpcUrls,
|
|
2271
2888
|
applyTheme,
|
|
2272
2889
|
checkBackendUrl
|
|
2273
2890
|
};
|