@rhinestone/deposit-modal 0.12.2 → 0.14.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 +73 -18
- package/bridge-transcript.json +653 -0
- package/dist/ClaimModal-IKTJU43Y.cjs +13 -0
- package/dist/ClaimModal-SEKNWRMA.mjs +13 -0
- package/dist/{DepositModalReown-VG66OTIU.cjs → DepositModalReown-46LPVFB6.cjs} +58 -35
- package/dist/{DepositModalReown-TEC3MEZ4.mjs → DepositModalReown-Q2JMLT47.mjs} +45 -22
- package/dist/{QRCode-WUC652SH.mjs → QRCode-5RGIZZHL.mjs} +1 -1
- package/dist/{QRCode-5DXFNKI2.cjs → QRCode-JKXG4RHN.cjs} +2 -2
- package/dist/WithdrawModal-5ICGD4HJ.mjs +12 -0
- package/dist/WithdrawModal-VP6PMIRO.cjs +12 -0
- package/dist/{chunk-O7BCVQ6L.cjs → chunk-4KCSH4T3.cjs} +157 -199
- package/dist/chunk-6KG642KH.cjs +31 -0
- package/dist/{chunk-PWLEBV5V.cjs → chunk-7ICSHJFE.cjs} +296 -220
- package/dist/{chunk-J46WDSRD.mjs → chunk-7SR7ENVJ.mjs} +165 -89
- package/dist/{chunk-2TPSF77V.mjs → chunk-CFKC77SV.mjs} +455 -261
- package/dist/{chunk-75DVGSAX.cjs → chunk-DW2EQA2U.cjs} +6 -3
- package/dist/{chunk-FXXUIK4E.mjs → chunk-IN77XSWO.mjs} +899 -153
- package/dist/chunk-K4H6TGBE.mjs +31 -0
- package/dist/{chunk-SDSKIJC7.mjs → chunk-KTUVSKR4.mjs} +2410 -1177
- package/dist/{chunk-HL5NUKZW.cjs → chunk-LZFRL2AL.cjs} +3 -3
- package/dist/{chunk-UQIJU6HV.cjs → chunk-MTFJSE52.cjs} +499 -191
- package/dist/{chunk-FLVLYO64.mjs → chunk-PKML3XVS.mjs} +430 -122
- package/dist/{chunk-4ZXQPFNU.mjs → chunk-RN5VKWI6.mjs} +4 -1
- package/dist/{chunk-BRYNGLDM.cjs → chunk-V2OBGLJD.cjs} +961 -215
- package/dist/{chunk-3STTWRAN.mjs → chunk-VUATPOWJ.mjs} +147 -189
- package/dist/{chunk-JE4R5VA3.mjs → chunk-WUJIKCFU.mjs} +1 -1
- package/dist/chunk-X2IPAPXU.cjs +163 -0
- package/dist/{chunk-OIN4CXCP.cjs → chunk-YCQZJQO6.cjs} +2343 -1110
- package/dist/{chunk-TM7VGHAG.cjs → chunk-YWMWI7PZ.cjs} +462 -268
- package/dist/chunk-ZEO6ADM3.mjs +163 -0
- package/dist/claim.cjs +7 -6
- package/dist/claim.d.cts +11 -3
- package/dist/claim.d.ts +11 -3
- package/dist/claim.mjs +6 -5
- package/dist/{constants-FuzG3h4m.d.cts → constants-DBrWhJWE.d.cts} +12 -7
- package/dist/{constants-FuzG3h4m.d.ts → constants-DBrWhJWE.d.ts} +12 -7
- package/dist/constants.cjs +3 -9
- package/dist/constants.d.cts +2 -3
- package/dist/constants.d.ts +2 -3
- package/dist/constants.mjs +4 -10
- package/dist/deposit.cjs +8 -8
- package/dist/deposit.d.cts +2 -2
- package/dist/deposit.d.ts +2 -2
- package/dist/deposit.mjs +7 -7
- package/dist/embed.cjs +1476 -0
- package/dist/embed.d.cts +183 -0
- package/dist/embed.d.ts +183 -0
- package/dist/embed.mjs +1476 -0
- package/dist/index.cjs +11 -16
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.mjs +14 -19
- package/dist/modal-ui-state-OD1RmKkK.d.cts +30 -0
- package/dist/modal-ui-state-OD1RmKkK.d.ts +30 -0
- package/dist/polymarket.cjs +17 -7
- package/dist/polymarket.mjs +13 -3
- package/dist/styles.css +124 -98
- package/dist/types-Bho4OA03.d.ts +982 -0
- package/dist/types-DP_3KwlD.d.cts +982 -0
- package/dist/withdraw.cjs +6 -6
- package/dist/withdraw.d.cts +11 -3
- package/dist/withdraw.d.ts +11 -3
- package/dist/withdraw.mjs +5 -5
- package/package.json +59 -6
- package/dist/chunk-IAGFDSNC.mjs +0 -11
- package/dist/chunk-L32UI7LA.cjs +0 -11
- package/dist/types-BO4iP6fG.d.cts +0 -612
- package/dist/types-oFblf65g.d.ts +0 -612
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
MODAL_VERSION,
|
|
3
|
+
serviceHeaders
|
|
4
|
+
} from "./chunk-K4H6TGBE.mjs";
|
|
4
5
|
import {
|
|
5
|
-
CHAIN_BY_ID,
|
|
6
6
|
CHAIN_DISPLAY_ORDER,
|
|
7
7
|
HYPERCORE_CHAIN_ID,
|
|
8
|
-
HYPERCORE_MAINNET_CAIP2,
|
|
9
8
|
HYPERCORE_SOURCE_TOKENS,
|
|
10
9
|
HYPERCORE_SPOT_CAIP2,
|
|
11
10
|
ICON_CDN,
|
|
@@ -27,7 +26,7 @@ import {
|
|
|
27
26
|
setRuntimeTokens,
|
|
28
27
|
toEvmCaip2,
|
|
29
28
|
tokenIconUrl
|
|
30
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-VUATPOWJ.mjs";
|
|
31
30
|
|
|
32
31
|
// src/components/ui/Modal.tsx
|
|
33
32
|
import {
|
|
@@ -85,7 +84,7 @@ function Modal({
|
|
|
85
84
|
(event) => {
|
|
86
85
|
if (event.key === "Escape") {
|
|
87
86
|
event.preventDefault();
|
|
88
|
-
onClose();
|
|
87
|
+
onClose("escape");
|
|
89
88
|
return;
|
|
90
89
|
}
|
|
91
90
|
if (event.key === "Tab" && contentRef.current) {
|
|
@@ -111,7 +110,7 @@ function Modal({
|
|
|
111
110
|
const handleOverlayClick = useCallback(
|
|
112
111
|
(event) => {
|
|
113
112
|
if (closeOnOverlayClick && event.target === overlayRef.current) {
|
|
114
|
-
onClose();
|
|
113
|
+
onClose("overlay");
|
|
115
114
|
}
|
|
116
115
|
},
|
|
117
116
|
[closeOnOverlayClick, onClose]
|
|
@@ -172,9 +171,6 @@ import {
|
|
|
172
171
|
ArrowRight,
|
|
173
172
|
ArrowUpRight,
|
|
174
173
|
AlertTriangle,
|
|
175
|
-
Percent,
|
|
176
|
-
Clock,
|
|
177
|
-
CirclePlus,
|
|
178
174
|
CircleArrowOutUpLeft,
|
|
179
175
|
CreditCard,
|
|
180
176
|
Landmark,
|
|
@@ -218,9 +214,6 @@ var InfoIcon = Info;
|
|
|
218
214
|
var CopyIcon = Copy;
|
|
219
215
|
var ArrowUpRightIcon = ArrowUpRight;
|
|
220
216
|
var AlertTriangleIcon = AlertTriangle;
|
|
221
|
-
var PercentIcon = Percent;
|
|
222
|
-
var ClockIcon = Clock;
|
|
223
|
-
var PlusCircleIcon = CirclePlus;
|
|
224
217
|
var CircleArrowOutUpLeftIcon = CircleArrowOutUpLeft;
|
|
225
218
|
var CardIcon = CreditCard;
|
|
226
219
|
var BankIcon = Landmark;
|
|
@@ -467,7 +460,7 @@ function normalizeForLog(value, depth = 0) {
|
|
|
467
460
|
const output = {};
|
|
468
461
|
for (const [key, raw] of Object.entries(input)) {
|
|
469
462
|
const keyLower = key.toLowerCase();
|
|
470
|
-
if (keyLower.includes("signature") || keyLower.includes("privatekey") || keyLower.includes("sessiondetails")) {
|
|
463
|
+
if (keyLower.includes("signature") || keyLower.includes("privatekey") || keyLower.includes("sessiondetails") || keyLower.includes("rpcurl") || keyLower.includes("apikey") || keyLower.includes("authorization")) {
|
|
471
464
|
output[key] = "[Redacted]";
|
|
472
465
|
continue;
|
|
473
466
|
}
|
|
@@ -579,17 +572,14 @@ function parseChainCatalog(body) {
|
|
|
579
572
|
return { all, byCaip2, byChainId };
|
|
580
573
|
}
|
|
581
574
|
function aliasHyperCoreOrigin(byCaip2, all) {
|
|
575
|
+
if (byCaip2.has(HYPERCORE_SPOT_CAIP2)) return;
|
|
582
576
|
const origin = all.find((c) => isHyperCoreCaip2(c.caip2) && c.deposit) ?? all.find((c) => isHyperCoreCaip2(c.caip2));
|
|
583
|
-
if (
|
|
584
|
-
byCaip2.set(HYPERCORE_MAINNET_CAIP2, origin);
|
|
585
|
-
if (!byCaip2.has(HYPERCORE_SPOT_CAIP2)) {
|
|
586
|
-
byCaip2.set(HYPERCORE_SPOT_CAIP2, origin);
|
|
587
|
-
}
|
|
577
|
+
if (origin) byCaip2.set(HYPERCORE_SPOT_CAIP2, origin);
|
|
588
578
|
}
|
|
589
579
|
function catalogKeyForChain(chainId) {
|
|
590
580
|
if (chainId === "solana") return SOLANA_MAINNET_CAIP2;
|
|
591
581
|
if (chainId === "hypercore" || chainId === HYPERCORE_CHAIN_ID) {
|
|
592
|
-
return
|
|
582
|
+
return HYPERCORE_SPOT_CAIP2;
|
|
593
583
|
}
|
|
594
584
|
return chainId;
|
|
595
585
|
}
|
|
@@ -817,7 +807,8 @@ function parseQuoteOutput(raw) {
|
|
|
817
807
|
};
|
|
818
808
|
}
|
|
819
809
|
function parseFeeLine(raw) {
|
|
820
|
-
if (typeof raw !== "object" || raw === null || Array.isArray(raw))
|
|
810
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw))
|
|
811
|
+
return null;
|
|
821
812
|
const line = raw;
|
|
822
813
|
const usd = line.usd;
|
|
823
814
|
if (typeof usd !== "number" || !Number.isFinite(usd) || usd < 0) return null;
|
|
@@ -854,6 +845,13 @@ function resolveAppFeeBps(appFees, sourceChainCaip2, sourceToken) {
|
|
|
854
845
|
const bps = override ?? appFees?.feeBps ?? 0;
|
|
855
846
|
return bps > 0 ? bps : 0;
|
|
856
847
|
}
|
|
848
|
+
var PermitDepositSubmitError = class extends Error {
|
|
849
|
+
constructor(message, safeToTransfer) {
|
|
850
|
+
super(message);
|
|
851
|
+
this.safeToTransfer = safeToTransfer;
|
|
852
|
+
this.name = "PermitDepositSubmitError";
|
|
853
|
+
}
|
|
854
|
+
};
|
|
857
855
|
function createDepositService(baseUrl, options) {
|
|
858
856
|
const normalizedBaseUrl = baseUrl.replace(/\/$/, "");
|
|
859
857
|
const debug = options?.debug === true;
|
|
@@ -894,7 +892,7 @@ function createDepositService(baseUrl, options) {
|
|
|
894
892
|
try {
|
|
895
893
|
const response = await fetch(apiUrl("/qr/tokens"), {
|
|
896
894
|
method: "GET",
|
|
897
|
-
headers:
|
|
895
|
+
headers: serviceHeaders()
|
|
898
896
|
});
|
|
899
897
|
if (!response.ok) {
|
|
900
898
|
debugLog(debug, scope, "getTopTokens:unavailable", {
|
|
@@ -921,7 +919,7 @@ function createDepositService(baseUrl, options) {
|
|
|
921
919
|
try {
|
|
922
920
|
const response = await fetch(apiUrl("/chains"), {
|
|
923
921
|
method: "GET",
|
|
924
|
-
headers:
|
|
922
|
+
headers: serviceHeaders()
|
|
925
923
|
});
|
|
926
924
|
if (!response.ok) {
|
|
927
925
|
debugLog(debug, scope, "getChains:unavailable", {
|
|
@@ -975,18 +973,15 @@ function createDepositService(baseUrl, options) {
|
|
|
975
973
|
});
|
|
976
974
|
const response = await fetch(url, {
|
|
977
975
|
method: "POST",
|
|
978
|
-
headers:
|
|
976
|
+
headers: serviceHeaders(),
|
|
979
977
|
body: JSON.stringify({ account: params })
|
|
980
978
|
});
|
|
981
979
|
if (!response.ok) {
|
|
982
980
|
const error = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
983
|
-
debugError(
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
error,
|
|
988
|
-
{ status: response.status, salt: params.salt }
|
|
989
|
-
);
|
|
981
|
+
debugError(debug, scope, "registerManagedAccount:failed", error, {
|
|
982
|
+
status: response.status,
|
|
983
|
+
salt: params.salt
|
|
984
|
+
});
|
|
990
985
|
const detail = Array.isArray(error.details) ? error.details.map((d) => d?.message).filter(Boolean).join("; ") : void 0;
|
|
991
986
|
const base = error.error || `Account registration failed: ${response.status}`;
|
|
992
987
|
throw new Error(detail ? `${base}: ${detail}` : base);
|
|
@@ -1003,100 +998,104 @@ function createDepositService(baseUrl, options) {
|
|
|
1003
998
|
};
|
|
1004
999
|
},
|
|
1005
1000
|
async fetchPortfolio(address, options2) {
|
|
1006
|
-
return cachedPortfolio(
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
const error = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
1015
|
-
debugError(
|
|
1016
|
-
debug,
|
|
1017
|
-
scope,
|
|
1018
|
-
"fetchPortfolio:failed",
|
|
1019
|
-
error,
|
|
1020
|
-
{ status: response.status, address }
|
|
1021
|
-
);
|
|
1022
|
-
throw new Error(
|
|
1023
|
-
error.error || `Portfolio fetch failed: ${response.status}`
|
|
1024
|
-
);
|
|
1025
|
-
}
|
|
1026
|
-
const data = await response.json();
|
|
1027
|
-
const direct = normalizeDirectPortfolio(data);
|
|
1028
|
-
if (direct.tokens.length > 0) {
|
|
1029
|
-
debugLog(debug, scope, "fetchPortfolio:success", {
|
|
1030
|
-
address,
|
|
1031
|
-
source: "direct",
|
|
1032
|
-
tokenCount: direct.tokens.length,
|
|
1033
|
-
totalUsd: direct.totalUsd
|
|
1001
|
+
return cachedPortfolio(
|
|
1002
|
+
`evm:${address.toLowerCase()}`,
|
|
1003
|
+
async () => {
|
|
1004
|
+
const url = apiUrl(`/portfolio/${address}?includeUnsupported=true`);
|
|
1005
|
+
debugLog(debug, scope, "fetchPortfolio:request", { url, address });
|
|
1006
|
+
const response = await fetch(url, {
|
|
1007
|
+
method: "GET",
|
|
1008
|
+
headers: serviceHeaders()
|
|
1034
1009
|
});
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1010
|
+
if (!response.ok) {
|
|
1011
|
+
const error = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
1012
|
+
debugError(debug, scope, "fetchPortfolio:failed", error, {
|
|
1013
|
+
status: response.status,
|
|
1014
|
+
address
|
|
1015
|
+
});
|
|
1016
|
+
throw new Error(
|
|
1017
|
+
error.error || `Portfolio fetch failed: ${response.status}`
|
|
1018
|
+
);
|
|
1019
|
+
}
|
|
1020
|
+
const data = await response.json();
|
|
1021
|
+
const direct = normalizeDirectPortfolio(data);
|
|
1022
|
+
if (direct.tokens.length > 0) {
|
|
1023
|
+
debugLog(debug, scope, "fetchPortfolio:success", {
|
|
1024
|
+
address,
|
|
1025
|
+
source: "direct",
|
|
1026
|
+
tokenCount: direct.tokens.length,
|
|
1027
|
+
totalUsd: direct.totalUsd
|
|
1028
|
+
});
|
|
1029
|
+
return direct;
|
|
1030
|
+
}
|
|
1031
|
+
const portfolioData = extractOrchestratorPortfolio(data);
|
|
1032
|
+
if (portfolioData) {
|
|
1033
|
+
const normalized = normalizeOrchestratorPortfolio(portfolioData);
|
|
1034
|
+
debugLog(debug, scope, "fetchPortfolio:success", {
|
|
1035
|
+
address,
|
|
1036
|
+
source: "orchestrator",
|
|
1037
|
+
tokenCount: normalized.tokens.length,
|
|
1038
|
+
totalUsd: normalized.totalUsd
|
|
1039
|
+
});
|
|
1040
|
+
return normalized;
|
|
1041
|
+
}
|
|
1042
|
+
debugLog(debug, scope, "fetchPortfolio:empty", { address });
|
|
1043
|
+
return { tokens: [], totalUsd: 0 };
|
|
1044
|
+
},
|
|
1045
|
+
options2?.forceRefresh
|
|
1046
|
+
);
|
|
1047
|
+
},
|
|
1048
|
+
async fetchSolanaPortfolio(address, options2) {
|
|
1049
|
+
return cachedPortfolio(
|
|
1050
|
+
`sol:${address}`,
|
|
1051
|
+
async () => {
|
|
1052
|
+
const url = apiUrl(`/portfolio/solana/${address}`);
|
|
1053
|
+
debugLog(debug, scope, "fetchSolanaPortfolio:request", {
|
|
1054
|
+
url,
|
|
1055
|
+
address
|
|
1056
|
+
});
|
|
1057
|
+
const response = await fetch(url, {
|
|
1058
|
+
method: "GET",
|
|
1059
|
+
headers: serviceHeaders()
|
|
1060
|
+
});
|
|
1061
|
+
if (!response.ok) {
|
|
1062
|
+
const error = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
1063
|
+
debugError(debug, scope, "fetchSolanaPortfolio:failed", error, {
|
|
1064
|
+
status: response.status,
|
|
1065
|
+
address
|
|
1066
|
+
});
|
|
1067
|
+
throw new Error(
|
|
1068
|
+
error.error || `Solana portfolio fetch failed: ${response.status}`
|
|
1069
|
+
);
|
|
1070
|
+
}
|
|
1071
|
+
const data = await response.json();
|
|
1072
|
+
const normalized = normalizeDirectPortfolio(data);
|
|
1073
|
+
debugLog(debug, scope, "fetchSolanaPortfolio:success", {
|
|
1041
1074
|
address,
|
|
1042
|
-
source: "orchestrator",
|
|
1043
1075
|
tokenCount: normalized.tokens.length,
|
|
1044
1076
|
totalUsd: normalized.totalUsd
|
|
1045
1077
|
});
|
|
1046
1078
|
return normalized;
|
|
1047
|
-
}
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
}, options2?.forceRefresh);
|
|
1051
|
-
},
|
|
1052
|
-
async fetchSolanaPortfolio(address, options2) {
|
|
1053
|
-
return cachedPortfolio(`sol:${address}`, async () => {
|
|
1054
|
-
const url = apiUrl(`/portfolio/solana/${address}`);
|
|
1055
|
-
debugLog(debug, scope, "fetchSolanaPortfolio:request", { url, address });
|
|
1056
|
-
const response = await fetch(url, {
|
|
1057
|
-
method: "GET",
|
|
1058
|
-
headers: SERVICE_HEADERS
|
|
1059
|
-
});
|
|
1060
|
-
if (!response.ok) {
|
|
1061
|
-
const error = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
1062
|
-
debugError(
|
|
1063
|
-
debug,
|
|
1064
|
-
scope,
|
|
1065
|
-
"fetchSolanaPortfolio:failed",
|
|
1066
|
-
error,
|
|
1067
|
-
{ status: response.status, address }
|
|
1068
|
-
);
|
|
1069
|
-
throw new Error(
|
|
1070
|
-
error.error || `Solana portfolio fetch failed: ${response.status}`
|
|
1071
|
-
);
|
|
1072
|
-
}
|
|
1073
|
-
const data = await response.json();
|
|
1074
|
-
const normalized = normalizeDirectPortfolio(data);
|
|
1075
|
-
debugLog(debug, scope, "fetchSolanaPortfolio:success", {
|
|
1076
|
-
address,
|
|
1077
|
-
tokenCount: normalized.tokens.length,
|
|
1078
|
-
totalUsd: normalized.totalUsd
|
|
1079
|
-
});
|
|
1080
|
-
return normalized;
|
|
1081
|
-
}, options2?.forceRefresh);
|
|
1079
|
+
},
|
|
1080
|
+
options2?.forceRefresh
|
|
1081
|
+
);
|
|
1082
1082
|
},
|
|
1083
1083
|
async checkAccount(address) {
|
|
1084
1084
|
const url = apiUrl(`/check/${address}`);
|
|
1085
1085
|
debugLog(debug, scope, "checkAccount:request", { url, address });
|
|
1086
1086
|
const response = await fetch(url, {
|
|
1087
1087
|
method: "GET",
|
|
1088
|
-
headers:
|
|
1088
|
+
headers: serviceHeaders()
|
|
1089
1089
|
});
|
|
1090
1090
|
if (!response.ok) {
|
|
1091
1091
|
const error = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
1092
|
-
debugError(
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1092
|
+
debugError(debug, scope, "checkAccount:failed", error, {
|
|
1093
|
+
status: response.status,
|
|
1094
|
+
address
|
|
1095
|
+
});
|
|
1096
|
+
throw new Error(
|
|
1097
|
+
error.error || `Account check failed: ${response.status}`
|
|
1098
1098
|
);
|
|
1099
|
-
throw new Error(error.error || `Account check failed: ${response.status}`);
|
|
1100
1099
|
}
|
|
1101
1100
|
const data = await response.json();
|
|
1102
1101
|
const result = {
|
|
@@ -1116,11 +1115,13 @@ function createDepositService(baseUrl, options) {
|
|
|
1116
1115
|
const normalized = txHash.startsWith("0x") || txHash.startsWith("0X") ? txHash.toLowerCase() : txHash;
|
|
1117
1116
|
const txHashParam = encodeURIComponent(normalized);
|
|
1118
1117
|
const url = apiUrl(
|
|
1119
|
-
`/deposits?account=${encodeURIComponent(
|
|
1118
|
+
`/deposits?account=${encodeURIComponent(
|
|
1119
|
+
address
|
|
1120
|
+
)}&txHash=${txHashParam}&limit=1`
|
|
1120
1121
|
);
|
|
1121
1122
|
const response = await fetch(url, {
|
|
1122
1123
|
method: "GET",
|
|
1123
|
-
headers:
|
|
1124
|
+
headers: serviceHeaders(),
|
|
1124
1125
|
cache: "no-store"
|
|
1125
1126
|
});
|
|
1126
1127
|
if (!response.ok) {
|
|
@@ -1148,7 +1149,7 @@ function createDepositService(baseUrl, options) {
|
|
|
1148
1149
|
);
|
|
1149
1150
|
const response = await fetch(url, {
|
|
1150
1151
|
method: "GET",
|
|
1151
|
-
headers:
|
|
1152
|
+
headers: serviceHeaders(),
|
|
1152
1153
|
cache: "no-store"
|
|
1153
1154
|
});
|
|
1154
1155
|
if (!response.ok) {
|
|
@@ -1172,7 +1173,7 @@ function createDepositService(baseUrl, options) {
|
|
|
1172
1173
|
);
|
|
1173
1174
|
const response = await fetch(url, {
|
|
1174
1175
|
method: "GET",
|
|
1175
|
-
headers:
|
|
1176
|
+
headers: serviceHeaders(),
|
|
1176
1177
|
cache: "no-store"
|
|
1177
1178
|
});
|
|
1178
1179
|
if (!response.ok) {
|
|
@@ -1194,7 +1195,7 @@ function createDepositService(baseUrl, options) {
|
|
|
1194
1195
|
async getPositions(address) {
|
|
1195
1196
|
const url = apiUrl(`/positions/${address}`);
|
|
1196
1197
|
debugLog(debug, scope, "getPositions:request", { url, address });
|
|
1197
|
-
const response = await fetch(url, { headers:
|
|
1198
|
+
const response = await fetch(url, { headers: serviceHeaders() });
|
|
1198
1199
|
if (!response.ok) {
|
|
1199
1200
|
const error = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
1200
1201
|
debugError(debug, scope, "getPositions:failed", error, {
|
|
@@ -1228,7 +1229,7 @@ function createDepositService(baseUrl, options) {
|
|
|
1228
1229
|
});
|
|
1229
1230
|
const response = await fetch(url, {
|
|
1230
1231
|
method: "POST",
|
|
1231
|
-
headers:
|
|
1232
|
+
headers: serviceHeaders(),
|
|
1232
1233
|
body: JSON.stringify({ account, market, chainId, asset, amount })
|
|
1233
1234
|
});
|
|
1234
1235
|
if (!response.ok) {
|
|
@@ -1264,7 +1265,7 @@ function createDepositService(baseUrl, options) {
|
|
|
1264
1265
|
});
|
|
1265
1266
|
const response = await fetch(url, {
|
|
1266
1267
|
method: "POST",
|
|
1267
|
-
headers:
|
|
1268
|
+
headers: serviceHeaders(),
|
|
1268
1269
|
body: JSON.stringify({
|
|
1269
1270
|
depositWallet,
|
|
1270
1271
|
owner,
|
|
@@ -1306,18 +1307,15 @@ function createDepositService(baseUrl, options) {
|
|
|
1306
1307
|
});
|
|
1307
1308
|
const response = await fetch(url, {
|
|
1308
1309
|
method: "GET",
|
|
1309
|
-
headers:
|
|
1310
|
+
headers: serviceHeaders(),
|
|
1310
1311
|
cache: "no-store"
|
|
1311
1312
|
});
|
|
1312
1313
|
if (!response.ok) {
|
|
1313
1314
|
const error = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
1314
|
-
debugError(
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
error,
|
|
1319
|
-
{ status: response.status, recipient: shortRef(params.recipient) }
|
|
1320
|
-
);
|
|
1315
|
+
debugError(debug, scope, "fetchDepositHistory:failed", error, {
|
|
1316
|
+
status: response.status,
|
|
1317
|
+
recipient: shortRef(params.recipient)
|
|
1318
|
+
});
|
|
1321
1319
|
throw new Error(
|
|
1322
1320
|
error.error || `Deposit history fetch failed: ${response.status}`
|
|
1323
1321
|
);
|
|
@@ -1359,7 +1357,7 @@ function createDepositService(baseUrl, options) {
|
|
|
1359
1357
|
});
|
|
1360
1358
|
const response = await fetch(url, {
|
|
1361
1359
|
method: "GET",
|
|
1362
|
-
headers:
|
|
1360
|
+
headers: serviceHeaders(),
|
|
1363
1361
|
cache: "no-store"
|
|
1364
1362
|
});
|
|
1365
1363
|
if (!response.ok) {
|
|
@@ -1391,7 +1389,10 @@ function createDepositService(baseUrl, options) {
|
|
|
1391
1389
|
const body = {
|
|
1392
1390
|
account: params.account,
|
|
1393
1391
|
// HyperCore has its own CAIP-2 namespace — never the eip155 placeholder.
|
|
1394
|
-
|
|
1392
|
+
// The branch is unreachable against today's processor whatever venue it
|
|
1393
|
+
// names: `sourceToken` is validated as a 20-byte 0x address on every
|
|
1394
|
+
// chain, and a HyperCore source token is a 16-byte Core spot tokenId.
|
|
1395
|
+
sourceChainId: params.sourceChainId === "hypercore" ? HYPERCORE_SPOT_CAIP2 : `eip155:${params.sourceChainId}`,
|
|
1395
1396
|
sourceToken: params.sourceToken,
|
|
1396
1397
|
amount: params.amount
|
|
1397
1398
|
};
|
|
@@ -1404,7 +1405,7 @@ function createDepositService(baseUrl, options) {
|
|
|
1404
1405
|
try {
|
|
1405
1406
|
const response = await fetch(url, {
|
|
1406
1407
|
method: "POST",
|
|
1407
|
-
headers:
|
|
1408
|
+
headers: serviceHeaders(),
|
|
1408
1409
|
body: JSON.stringify(body),
|
|
1409
1410
|
cache: "no-store"
|
|
1410
1411
|
});
|
|
@@ -1432,6 +1433,154 @@ function createDepositService(baseUrl, options) {
|
|
|
1432
1433
|
return null;
|
|
1433
1434
|
}
|
|
1434
1435
|
},
|
|
1436
|
+
async preparePermitDeposit(params) {
|
|
1437
|
+
const url = apiUrl("/deposits/permit/prepare");
|
|
1438
|
+
debugLog(debug, scope, "preparePermitDeposit:request", {
|
|
1439
|
+
url,
|
|
1440
|
+
account: shortRef(params.account),
|
|
1441
|
+
sourceChain: params.sourceChain,
|
|
1442
|
+
token: params.token,
|
|
1443
|
+
amount: params.amount
|
|
1444
|
+
});
|
|
1445
|
+
try {
|
|
1446
|
+
const response = await fetch(url, {
|
|
1447
|
+
method: "POST",
|
|
1448
|
+
headers: serviceHeaders(),
|
|
1449
|
+
body: JSON.stringify({ ...params, kind: "auto" }),
|
|
1450
|
+
cache: "no-store"
|
|
1451
|
+
});
|
|
1452
|
+
if (!response.ok) {
|
|
1453
|
+
debugLog(debug, scope, "preparePermitDeposit:unavailable", {
|
|
1454
|
+
status: response.status
|
|
1455
|
+
});
|
|
1456
|
+
return null;
|
|
1457
|
+
}
|
|
1458
|
+
const data = await response.json();
|
|
1459
|
+
if (!data || typeof data.available !== "boolean") {
|
|
1460
|
+
debugLog(debug, scope, "preparePermitDeposit:unavailable", {
|
|
1461
|
+
status: response.status,
|
|
1462
|
+
reason: "malformed"
|
|
1463
|
+
});
|
|
1464
|
+
return null;
|
|
1465
|
+
}
|
|
1466
|
+
if (data.available === false) {
|
|
1467
|
+
const reason = data.reason;
|
|
1468
|
+
if (reason !== "permit2-approval-required" && reason !== "unsupported-token" && reason !== "unsupported-owner") {
|
|
1469
|
+
return null;
|
|
1470
|
+
}
|
|
1471
|
+
debugLog(debug, scope, "preparePermitDeposit:unavailable", {
|
|
1472
|
+
status: response.status,
|
|
1473
|
+
reason
|
|
1474
|
+
});
|
|
1475
|
+
const approval = data.approval;
|
|
1476
|
+
const parsedApproval = approval && typeof approval.token === "string" && typeof approval.spender === "string" && typeof approval.minimumAmount === "string" ? {
|
|
1477
|
+
token: approval.token,
|
|
1478
|
+
spender: approval.spender,
|
|
1479
|
+
minimumAmount: approval.minimumAmount
|
|
1480
|
+
} : void 0;
|
|
1481
|
+
return {
|
|
1482
|
+
available: false,
|
|
1483
|
+
reason,
|
|
1484
|
+
...parsedApproval && { approval: parsedApproval }
|
|
1485
|
+
};
|
|
1486
|
+
}
|
|
1487
|
+
const authorization = data.authorization;
|
|
1488
|
+
if (!authorization || typeof authorization.typedData !== "object" || authorization.typedData === null || typeof authorization.nonce !== "string") {
|
|
1489
|
+
return null;
|
|
1490
|
+
}
|
|
1491
|
+
if (authorization.kind === "erc3009" && typeof authorization.validAfter === "string" && typeof authorization.validBefore === "string") {
|
|
1492
|
+
debugLog(debug, scope, "preparePermitDeposit:success", {
|
|
1493
|
+
kind: authorization.kind,
|
|
1494
|
+
nonce: authorization.nonce
|
|
1495
|
+
});
|
|
1496
|
+
return {
|
|
1497
|
+
available: true,
|
|
1498
|
+
authorization: {
|
|
1499
|
+
kind: "erc3009",
|
|
1500
|
+
typedData: authorization.typedData,
|
|
1501
|
+
nonce: authorization.nonce,
|
|
1502
|
+
validAfter: authorization.validAfter,
|
|
1503
|
+
validBefore: authorization.validBefore
|
|
1504
|
+
}
|
|
1505
|
+
};
|
|
1506
|
+
}
|
|
1507
|
+
if ((authorization.kind === "erc2612" || authorization.kind === "permit2") && typeof authorization.deadline === "string") {
|
|
1508
|
+
debugLog(debug, scope, "preparePermitDeposit:success", {
|
|
1509
|
+
kind: authorization.kind,
|
|
1510
|
+
nonce: authorization.nonce
|
|
1511
|
+
});
|
|
1512
|
+
return {
|
|
1513
|
+
available: true,
|
|
1514
|
+
authorization: {
|
|
1515
|
+
kind: authorization.kind,
|
|
1516
|
+
typedData: authorization.typedData,
|
|
1517
|
+
nonce: authorization.nonce,
|
|
1518
|
+
deadline: authorization.deadline
|
|
1519
|
+
}
|
|
1520
|
+
};
|
|
1521
|
+
}
|
|
1522
|
+
return null;
|
|
1523
|
+
} catch (error) {
|
|
1524
|
+
debugError(debug, scope, "preparePermitDeposit:error", error);
|
|
1525
|
+
return null;
|
|
1526
|
+
}
|
|
1527
|
+
},
|
|
1528
|
+
async submitPermitDeposit(params) {
|
|
1529
|
+
const url = apiUrl("/deposits/permit");
|
|
1530
|
+
debugLog(debug, scope, "submitPermitDeposit:request", {
|
|
1531
|
+
url,
|
|
1532
|
+
account: shortRef(params.account),
|
|
1533
|
+
sourceChain: params.sourceChain,
|
|
1534
|
+
token: params.token,
|
|
1535
|
+
amount: params.amount,
|
|
1536
|
+
nonce: params.nonce
|
|
1537
|
+
});
|
|
1538
|
+
let response;
|
|
1539
|
+
try {
|
|
1540
|
+
response = await fetch(url, {
|
|
1541
|
+
method: "POST",
|
|
1542
|
+
headers: serviceHeaders(),
|
|
1543
|
+
body: JSON.stringify(params)
|
|
1544
|
+
});
|
|
1545
|
+
} catch (error) {
|
|
1546
|
+
const message = error instanceof Error ? error.message : "Network error";
|
|
1547
|
+
throw new PermitDepositSubmitError(message, false);
|
|
1548
|
+
}
|
|
1549
|
+
if (!response.ok) {
|
|
1550
|
+
const error = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
1551
|
+
debugError(debug, scope, "submitPermitDeposit:failed", error, {
|
|
1552
|
+
status: response.status,
|
|
1553
|
+
account: shortRef(params.account)
|
|
1554
|
+
});
|
|
1555
|
+
const safeToTransfer = [400, 401, 403, 404, 422].includes(
|
|
1556
|
+
response.status
|
|
1557
|
+
);
|
|
1558
|
+
throw new PermitDepositSubmitError(
|
|
1559
|
+
error.error || `Permit deposit failed: ${response.status}`,
|
|
1560
|
+
safeToTransfer
|
|
1561
|
+
);
|
|
1562
|
+
}
|
|
1563
|
+
const result = await response.json();
|
|
1564
|
+
if (typeof result?.txHash !== "string" || result.txHash.length === 0) {
|
|
1565
|
+
debugError(debug, scope, "submitPermitDeposit:failed", result, {
|
|
1566
|
+
reason: "missing txHash"
|
|
1567
|
+
});
|
|
1568
|
+
throw new PermitDepositSubmitError(
|
|
1569
|
+
"Permit deposit response missing txHash",
|
|
1570
|
+
false
|
|
1571
|
+
);
|
|
1572
|
+
}
|
|
1573
|
+
debugLog(debug, scope, "submitPermitDeposit:success", {
|
|
1574
|
+
depositId: result.depositId,
|
|
1575
|
+
txHash: shortRef(result.txHash),
|
|
1576
|
+
status: result.status
|
|
1577
|
+
});
|
|
1578
|
+
return {
|
|
1579
|
+
depositId: result.depositId ?? "",
|
|
1580
|
+
txHash: result.txHash,
|
|
1581
|
+
status: result.status ?? "processing"
|
|
1582
|
+
};
|
|
1583
|
+
},
|
|
1435
1584
|
async fetchPrices(symbols) {
|
|
1436
1585
|
const list = symbols.filter((s) => s.length > 0);
|
|
1437
1586
|
if (list.length === 0) return {};
|
|
@@ -1441,7 +1590,7 @@ function createDepositService(baseUrl, options) {
|
|
|
1441
1590
|
try {
|
|
1442
1591
|
const response = await fetch(url, {
|
|
1443
1592
|
method: "GET",
|
|
1444
|
-
headers:
|
|
1593
|
+
headers: serviceHeaders(),
|
|
1445
1594
|
cache: "no-store"
|
|
1446
1595
|
});
|
|
1447
1596
|
if (!response.ok) {
|
|
@@ -1466,12 +1615,14 @@ function createDepositService(baseUrl, options) {
|
|
|
1466
1615
|
const list = caip2Ids.filter((id) => id.length > 0);
|
|
1467
1616
|
if (list.length === 0) return {};
|
|
1468
1617
|
const url = apiUrl(
|
|
1469
|
-
`/prices?${new URLSearchParams({
|
|
1618
|
+
`/prices?${new URLSearchParams({
|
|
1619
|
+
addresses: list.join(",")
|
|
1620
|
+
}).toString()}`
|
|
1470
1621
|
);
|
|
1471
1622
|
try {
|
|
1472
1623
|
const response = await fetch(url, {
|
|
1473
1624
|
method: "GET",
|
|
1474
|
-
headers:
|
|
1625
|
+
headers: serviceHeaders(),
|
|
1475
1626
|
cache: "no-store"
|
|
1476
1627
|
});
|
|
1477
1628
|
if (!response.ok) {
|
|
@@ -1496,7 +1647,7 @@ function createDepositService(baseUrl, options) {
|
|
|
1496
1647
|
});
|
|
1497
1648
|
const response = await fetch(url, {
|
|
1498
1649
|
method: "POST",
|
|
1499
|
-
headers:
|
|
1650
|
+
headers: serviceHeaders(),
|
|
1500
1651
|
body: JSON.stringify(params)
|
|
1501
1652
|
});
|
|
1502
1653
|
if (!response.ok) {
|
|
@@ -1528,7 +1679,7 @@ function createDepositService(baseUrl, options) {
|
|
|
1528
1679
|
});
|
|
1529
1680
|
const response = await fetch(url, {
|
|
1530
1681
|
method: "POST",
|
|
1531
|
-
headers:
|
|
1682
|
+
headers: serviceHeaders(),
|
|
1532
1683
|
body: JSON.stringify(params)
|
|
1533
1684
|
});
|
|
1534
1685
|
if (!response.ok) {
|
|
@@ -1565,7 +1716,7 @@ function createDepositService(baseUrl, options) {
|
|
|
1565
1716
|
debugLog(debug, scope, "getSwappedConnectExchanges:request");
|
|
1566
1717
|
const response = await fetch(url, {
|
|
1567
1718
|
method: "GET",
|
|
1568
|
-
headers:
|
|
1719
|
+
headers: serviceHeaders(),
|
|
1569
1720
|
cache: "no-store"
|
|
1570
1721
|
});
|
|
1571
1722
|
if (!response.ok) {
|
|
@@ -1618,7 +1769,7 @@ function createDepositService(baseUrl, options) {
|
|
|
1618
1769
|
try {
|
|
1619
1770
|
const response = await fetch(url, {
|
|
1620
1771
|
method: "GET",
|
|
1621
|
-
headers:
|
|
1772
|
+
headers: serviceHeaders(),
|
|
1622
1773
|
cache: "no-store"
|
|
1623
1774
|
});
|
|
1624
1775
|
if (!response.ok) {
|
|
@@ -1704,7 +1855,7 @@ function createDepositService(baseUrl, options) {
|
|
|
1704
1855
|
try {
|
|
1705
1856
|
const response = await fetch(url, {
|
|
1706
1857
|
method: "GET",
|
|
1707
|
-
headers:
|
|
1858
|
+
headers: serviceHeaders(),
|
|
1708
1859
|
cache: "no-store"
|
|
1709
1860
|
});
|
|
1710
1861
|
if (!response.ok) {
|
|
@@ -1731,7 +1882,7 @@ function createDepositService(baseUrl, options) {
|
|
|
1731
1882
|
);
|
|
1732
1883
|
const response = await fetch(url, {
|
|
1733
1884
|
method: "GET",
|
|
1734
|
-
headers:
|
|
1885
|
+
headers: serviceHeaders(),
|
|
1735
1886
|
cache: "no-store"
|
|
1736
1887
|
});
|
|
1737
1888
|
if (!response.ok) return null;
|
|
@@ -1800,9 +1951,15 @@ function normalizeOrchestratorPortfolio(data) {
|
|
|
1800
1951
|
if (!resolvedTokenAddress) {
|
|
1801
1952
|
continue;
|
|
1802
1953
|
}
|
|
1803
|
-
const registrySymbol = getTokenSymbol(
|
|
1954
|
+
const registrySymbol = getTokenSymbol(
|
|
1955
|
+
resolvedTokenAddress,
|
|
1956
|
+
chainBalance.chainId
|
|
1957
|
+
);
|
|
1804
1958
|
const symbol = registrySymbol !== "Token" ? registrySymbol : normalizedName || "Token";
|
|
1805
|
-
const decimals = registrySymbol !== "Token" ? getTokenDecimalsByAddress(
|
|
1959
|
+
const decimals = registrySymbol !== "Token" ? getTokenDecimalsByAddress(
|
|
1960
|
+
resolvedTokenAddress,
|
|
1961
|
+
chainBalance.chainId
|
|
1962
|
+
) : tokenData.tokenDecimals ?? 18;
|
|
1806
1963
|
tokens.push({
|
|
1807
1964
|
chainId: chainBalance.chainId,
|
|
1808
1965
|
address: resolvedTokenAddress,
|
|
@@ -1823,8 +1980,8 @@ function normalizeDirectToken(token) {
|
|
|
1823
1980
|
const rawChainId = extractNumber(token, "chainId") ?? extractNumber(token.chain, "id");
|
|
1824
1981
|
const rawChainString = extractString(token, "chainId") ?? extractString(token.chain, "id");
|
|
1825
1982
|
const chainId = rawChainId ?? (rawChainString ? isSolanaCaip2(rawChainString) || rawChainString.toLowerCase() === "solana" ? "solana" : (
|
|
1826
|
-
// HyperCore
|
|
1827
|
-
// instead of dropping it as an unparseable chain string.
|
|
1983
|
+
// HyperCore is a non-EVM source under its own namespace; keep its
|
|
1984
|
+
// USDC instead of dropping it as an unparseable chain string.
|
|
1828
1985
|
isHyperCoreCaip2(rawChainString) || rawChainString.toLowerCase() === "hypercore" ? "hypercore" : parseEvmChainId(rawChainString)
|
|
1829
1986
|
) : null);
|
|
1830
1987
|
if (chainId === null) return null;
|
|
@@ -1909,32 +2066,65 @@ import {
|
|
|
1909
2066
|
useContext as useContext2,
|
|
1910
2067
|
useEffect as useEffect2,
|
|
1911
2068
|
useMemo as useMemo2,
|
|
1912
|
-
useState as useState2
|
|
2069
|
+
useState as useState2,
|
|
2070
|
+
useSyncExternalStore
|
|
1913
2071
|
} from "react";
|
|
1914
2072
|
|
|
1915
2073
|
// src/core/public-client.ts
|
|
1916
2074
|
import { createPublicClient, http } from "viem";
|
|
1917
2075
|
var clientCache = /* @__PURE__ */ new Map();
|
|
1918
2076
|
var runtimeChainById = /* @__PURE__ */ new Map();
|
|
2077
|
+
var BOOTSTRAP_RPC_URL = {
|
|
2078
|
+
1: "https://eth.merkle.io",
|
|
2079
|
+
10: "https://mainnet.optimism.io",
|
|
2080
|
+
56: "https://56.rpc.thirdweb.com",
|
|
2081
|
+
100: "https://rpc.gnosischain.com",
|
|
2082
|
+
130: "https://mainnet.unichain.org",
|
|
2083
|
+
137: "https://polygon.drpc.org",
|
|
2084
|
+
143: "https://rpc.monad.xyz",
|
|
2085
|
+
146: "https://rpc.soniclabs.com",
|
|
2086
|
+
999: "https://rpc.hyperliquid.xyz/evm",
|
|
2087
|
+
1868: "https://rpc.soneium.org",
|
|
2088
|
+
8453: "https://mainnet.base.org",
|
|
2089
|
+
9745: "https://rpc.plasma.to",
|
|
2090
|
+
42161: "https://arb1.arbitrum.io/rpc",
|
|
2091
|
+
747474: "https://rpc.katana.network"
|
|
2092
|
+
};
|
|
2093
|
+
var runtimeChainsVersion = 0;
|
|
2094
|
+
var runtimeChainListeners = /* @__PURE__ */ new Set();
|
|
2095
|
+
function subscribeToRuntimeChains(listener) {
|
|
2096
|
+
runtimeChainListeners.add(listener);
|
|
2097
|
+
return () => {
|
|
2098
|
+
runtimeChainListeners.delete(listener);
|
|
2099
|
+
};
|
|
2100
|
+
}
|
|
2101
|
+
function getRuntimeChainsVersion() {
|
|
2102
|
+
return runtimeChainsVersion;
|
|
2103
|
+
}
|
|
1919
2104
|
function setRuntimeChains(chains) {
|
|
2105
|
+
let changed = false;
|
|
1920
2106
|
for (const chain of chains) {
|
|
1921
2107
|
const known = runtimeChainById.get(chain.id);
|
|
1922
2108
|
if (known === chain) continue;
|
|
1923
2109
|
runtimeChainById.set(chain.id, chain);
|
|
2110
|
+
changed = true;
|
|
1924
2111
|
for (const key of clientCache.keys()) {
|
|
1925
2112
|
if (key.startsWith(`${chain.id}|`)) clientCache.delete(key);
|
|
1926
2113
|
}
|
|
1927
2114
|
}
|
|
2115
|
+
if (!changed) return;
|
|
2116
|
+
runtimeChainsVersion += 1;
|
|
2117
|
+
for (const listener of runtimeChainListeners) listener();
|
|
1928
2118
|
}
|
|
1929
2119
|
function getPublicClient(chainId, rpcUrls) {
|
|
1930
2120
|
const url = rpcUrlFor(rpcUrls, chainId);
|
|
1931
2121
|
const cacheKey = `${chainId}|${url ?? ""}`;
|
|
1932
2122
|
let client = clientCache.get(cacheKey);
|
|
1933
2123
|
if (!client) {
|
|
1934
|
-
const chain =
|
|
2124
|
+
const chain = runtimeChainById.get(chainId);
|
|
1935
2125
|
client = createPublicClient({
|
|
1936
2126
|
chain,
|
|
1937
|
-
transport: http(url)
|
|
2127
|
+
transport: http(url ?? (chain ? void 0 : BOOTSTRAP_RPC_URL[chainId]))
|
|
1938
2128
|
});
|
|
1939
2129
|
clientCache.set(cacheKey, client);
|
|
1940
2130
|
}
|
|
@@ -2095,7 +2285,8 @@ function publishRuntimeChainMeta(catalog) {
|
|
|
2095
2285
|
chainId,
|
|
2096
2286
|
name: chain.name,
|
|
2097
2287
|
iconUrl: chain.iconUrl ?? void 0,
|
|
2098
|
-
nativeSymbol: chain.nativeToken.symbol
|
|
2288
|
+
nativeSymbol: chain.nativeToken.symbol,
|
|
2289
|
+
explorerUrl: chain.explorer?.url
|
|
2099
2290
|
}));
|
|
2100
2291
|
})
|
|
2101
2292
|
);
|
|
@@ -2204,6 +2395,20 @@ function useChainName() {
|
|
|
2204
2395
|
};
|
|
2205
2396
|
}, [catalog]);
|
|
2206
2397
|
}
|
|
2398
|
+
function useRuntimeChainsVersion() {
|
|
2399
|
+
return useSyncExternalStore(
|
|
2400
|
+
subscribeToRuntimeChains,
|
|
2401
|
+
getRuntimeChainsVersion,
|
|
2402
|
+
getRuntimeChainsVersion
|
|
2403
|
+
);
|
|
2404
|
+
}
|
|
2405
|
+
function useReadClient(chainId, rpcUrls) {
|
|
2406
|
+
const version = useRuntimeChainsVersion();
|
|
2407
|
+
return useMemo2(
|
|
2408
|
+
() => getPublicClient(chainId, rpcUrls),
|
|
2409
|
+
[chainId, rpcUrls, version]
|
|
2410
|
+
);
|
|
2411
|
+
}
|
|
2207
2412
|
function useExplorerTxUrl() {
|
|
2208
2413
|
const { catalog } = useChainCatalog();
|
|
2209
2414
|
return useMemo2(() => {
|
|
@@ -2671,6 +2876,524 @@ function formatReceiveEstimate(params) {
|
|
|
2671
2876
|
return sameSymbol ? `${formatted} ${params.targetSymbol}` : `~${formatted} ${params.targetSymbol}`;
|
|
2672
2877
|
}
|
|
2673
2878
|
|
|
2879
|
+
// src/core/analytics.tsx
|
|
2880
|
+
import {
|
|
2881
|
+
createContext as createContext3,
|
|
2882
|
+
useCallback as useCallback2,
|
|
2883
|
+
useContext as useContext3,
|
|
2884
|
+
useEffect as useEffect4,
|
|
2885
|
+
useMemo as useMemo3,
|
|
2886
|
+
useRef as useRef3
|
|
2887
|
+
} from "react";
|
|
2888
|
+
|
|
2889
|
+
// src/core/analytics-ingest.ts
|
|
2890
|
+
var DEFAULT_ANALYTICS_INGEST_URL = "https://v1.orchestrator.rhinestone.dev/deposit-processor/analytics/events";
|
|
2891
|
+
var MAX_BATCH = 20;
|
|
2892
|
+
var MAX_QUEUE = 200;
|
|
2893
|
+
var FLUSH_DELAY_MS = 5e3;
|
|
2894
|
+
var MAX_BODY_BYTES = 48 * 1024;
|
|
2895
|
+
var TOKEN_REFRESH_MARGIN_MS = 6e4;
|
|
2896
|
+
var TOKEN_TIMEOUT_MS = 3e3;
|
|
2897
|
+
var MAX_ATTEMPTS = 3;
|
|
2898
|
+
var MAX_BACKOFF_MS = 3e4;
|
|
2899
|
+
var ENVELOPE_FIELDS = /* @__PURE__ */ new Set([
|
|
2900
|
+
"type",
|
|
2901
|
+
"timestamp",
|
|
2902
|
+
"session_id",
|
|
2903
|
+
"modal",
|
|
2904
|
+
"widget_version",
|
|
2905
|
+
"session_properties",
|
|
2906
|
+
"funding_method"
|
|
2907
|
+
]);
|
|
2908
|
+
function createIngestTransport(options) {
|
|
2909
|
+
const {
|
|
2910
|
+
ingestUrl,
|
|
2911
|
+
backendUrl,
|
|
2912
|
+
proxyOrigin,
|
|
2913
|
+
sessionId,
|
|
2914
|
+
modal,
|
|
2915
|
+
widgetVersion,
|
|
2916
|
+
sessionProperties,
|
|
2917
|
+
onFailure
|
|
2918
|
+
} = options;
|
|
2919
|
+
const fetchImpl = options.fetchImpl ?? (typeof globalThis.fetch === "function" ? globalThis.fetch.bind(globalThis) : void 0);
|
|
2920
|
+
const now = options.now ?? (() => Date.now());
|
|
2921
|
+
const createEventId = options.createEventId ?? randomUuid;
|
|
2922
|
+
const mintUrl = `${backendUrl.replace(/\/$/, "")}/analytics/ingest-token`;
|
|
2923
|
+
const queue = [];
|
|
2924
|
+
let sequence = 0;
|
|
2925
|
+
let dropped = 0;
|
|
2926
|
+
let token = null;
|
|
2927
|
+
let mintUnavailable = false;
|
|
2928
|
+
let mintFailures = 0;
|
|
2929
|
+
let mintBackoffUntil = 0;
|
|
2930
|
+
let timer = null;
|
|
2931
|
+
let sending = false;
|
|
2932
|
+
let disposed = false;
|
|
2933
|
+
let pendingTerminal = false;
|
|
2934
|
+
let terminalRequested = false;
|
|
2935
|
+
let mintAbort = null;
|
|
2936
|
+
const sleepers = /* @__PURE__ */ new Set();
|
|
2937
|
+
function report(reason, status) {
|
|
2938
|
+
try {
|
|
2939
|
+
onFailure({ reason, status, droppedEvents: dropped });
|
|
2940
|
+
} catch {
|
|
2941
|
+
}
|
|
2942
|
+
}
|
|
2943
|
+
function drop(batch, reason, status) {
|
|
2944
|
+
dropped += batch.length;
|
|
2945
|
+
report(reason, status);
|
|
2946
|
+
}
|
|
2947
|
+
function toWireEvent(event) {
|
|
2948
|
+
const payload = {};
|
|
2949
|
+
for (const [key, value] of Object.entries(event)) {
|
|
2950
|
+
if (!ENVELOPE_FIELDS.has(key)) payload[key] = value;
|
|
2951
|
+
}
|
|
2952
|
+
const wire = {
|
|
2953
|
+
event_id: createEventId(),
|
|
2954
|
+
session_id: sessionId,
|
|
2955
|
+
sequence: sequence++,
|
|
2956
|
+
type: String(event.type),
|
|
2957
|
+
timestamp: String(event.timestamp),
|
|
2958
|
+
widget_version: widgetVersion,
|
|
2959
|
+
proxy_origin: proxyOrigin,
|
|
2960
|
+
modal,
|
|
2961
|
+
session_properties: sessionProperties,
|
|
2962
|
+
payload
|
|
2963
|
+
};
|
|
2964
|
+
if (modal === "deposit") wire.funding_method = event.funding_method ?? null;
|
|
2965
|
+
return wire;
|
|
2966
|
+
}
|
|
2967
|
+
function takeBatch() {
|
|
2968
|
+
const batch = queue.slice(0, MAX_BATCH);
|
|
2969
|
+
while (batch.length > 1 && bodyOf(batch).length > MAX_BODY_BYTES) {
|
|
2970
|
+
batch.pop();
|
|
2971
|
+
}
|
|
2972
|
+
queue.splice(0, batch.length);
|
|
2973
|
+
return batch;
|
|
2974
|
+
}
|
|
2975
|
+
function bodyOf(batch) {
|
|
2976
|
+
return JSON.stringify({ events: batch });
|
|
2977
|
+
}
|
|
2978
|
+
function backoff(attempt) {
|
|
2979
|
+
return Math.min(1e3 * 2 ** (attempt - 1), MAX_BACKOFF_MS);
|
|
2980
|
+
}
|
|
2981
|
+
function sleep(ms) {
|
|
2982
|
+
return new Promise((resolve) => {
|
|
2983
|
+
const timeout = setTimeout(finish, ms);
|
|
2984
|
+
function finish() {
|
|
2985
|
+
clearTimeout(timeout);
|
|
2986
|
+
sleepers.delete(finish);
|
|
2987
|
+
resolve();
|
|
2988
|
+
}
|
|
2989
|
+
sleepers.add(finish);
|
|
2990
|
+
});
|
|
2991
|
+
}
|
|
2992
|
+
function interruptForUnload() {
|
|
2993
|
+
for (const wake of [...sleepers]) wake();
|
|
2994
|
+
mintAbort?.abort();
|
|
2995
|
+
}
|
|
2996
|
+
function retryDelay(response, attempt) {
|
|
2997
|
+
const seconds = Number(response.headers?.get?.("Retry-After"));
|
|
2998
|
+
if (Number.isFinite(seconds) && seconds > 0) {
|
|
2999
|
+
return Math.min(seconds * 1e3, MAX_BACKOFF_MS);
|
|
3000
|
+
}
|
|
3001
|
+
return backoff(attempt);
|
|
3002
|
+
}
|
|
3003
|
+
async function mintToken() {
|
|
3004
|
+
if (mintUnavailable || !fetchImpl) return;
|
|
3005
|
+
const controller = typeof AbortController === "function" ? new AbortController() : null;
|
|
3006
|
+
mintAbort = controller;
|
|
3007
|
+
const timeout = controller ? setTimeout(() => controller.abort(), TOKEN_TIMEOUT_MS) : null;
|
|
3008
|
+
let response;
|
|
3009
|
+
try {
|
|
3010
|
+
response = await fetchImpl(mintUrl, {
|
|
3011
|
+
method: "POST",
|
|
3012
|
+
headers: serviceHeaders(),
|
|
3013
|
+
signal: controller?.signal
|
|
3014
|
+
});
|
|
3015
|
+
} catch {
|
|
3016
|
+
if (!terminalRequested) {
|
|
3017
|
+
mintFailures += 1;
|
|
3018
|
+
mintBackoffUntil = now() + backoff(mintFailures);
|
|
3019
|
+
}
|
|
3020
|
+
return;
|
|
3021
|
+
} finally {
|
|
3022
|
+
if (timeout !== null) clearTimeout(timeout);
|
|
3023
|
+
mintAbort = null;
|
|
3024
|
+
}
|
|
3025
|
+
if (response.status === 404 || response.status === 401 || response.status === 403) {
|
|
3026
|
+
mintUnavailable = true;
|
|
3027
|
+
report("token_unavailable", response.status);
|
|
3028
|
+
return;
|
|
3029
|
+
}
|
|
3030
|
+
if (!response.ok) {
|
|
3031
|
+
mintFailures += 1;
|
|
3032
|
+
mintBackoffUntil = now() + backoff(mintFailures);
|
|
3033
|
+
return;
|
|
3034
|
+
}
|
|
3035
|
+
try {
|
|
3036
|
+
const data = await response.json();
|
|
3037
|
+
const value = typeof data.token === "string" ? data.token : "";
|
|
3038
|
+
const expiresAt = Date.parse(String(data.expiresAt));
|
|
3039
|
+
if (!value || Number.isNaN(expiresAt)) throw new Error("malformed");
|
|
3040
|
+
token = { value, expiresAt };
|
|
3041
|
+
mintFailures = 0;
|
|
3042
|
+
mintBackoffUntil = 0;
|
|
3043
|
+
} catch {
|
|
3044
|
+
mintUnavailable = true;
|
|
3045
|
+
report("token_unavailable", response.status);
|
|
3046
|
+
}
|
|
3047
|
+
}
|
|
3048
|
+
async function ensureToken() {
|
|
3049
|
+
if (mintUnavailable) return;
|
|
3050
|
+
if (token && token.expiresAt - now() > TOKEN_REFRESH_MARGIN_MS) return;
|
|
3051
|
+
if (now() < mintBackoffUntil) return;
|
|
3052
|
+
await mintToken();
|
|
3053
|
+
}
|
|
3054
|
+
async function deliver(batch, isTerminal) {
|
|
3055
|
+
if (!fetchImpl) return drop(batch, "unsupported");
|
|
3056
|
+
let attempt = 0;
|
|
3057
|
+
let refreshed = false;
|
|
3058
|
+
let unattributed = false;
|
|
3059
|
+
for (; ; ) {
|
|
3060
|
+
const terminal = isTerminal || terminalRequested;
|
|
3061
|
+
attempt += 1;
|
|
3062
|
+
const headers = {
|
|
3063
|
+
"Content-Type": "application/json"
|
|
3064
|
+
};
|
|
3065
|
+
if (token && !unattributed) headers.Authorization = `Bearer ${token.value}`;
|
|
3066
|
+
let response;
|
|
3067
|
+
try {
|
|
3068
|
+
response = await fetchImpl(ingestUrl, {
|
|
3069
|
+
method: "POST",
|
|
3070
|
+
headers,
|
|
3071
|
+
body: bodyOf(batch),
|
|
3072
|
+
keepalive: true
|
|
3073
|
+
});
|
|
3074
|
+
} catch {
|
|
3075
|
+
if (terminal || attempt >= MAX_ATTEMPTS) {
|
|
3076
|
+
return drop(batch, "network");
|
|
3077
|
+
}
|
|
3078
|
+
await sleep(backoff(attempt));
|
|
3079
|
+
continue;
|
|
3080
|
+
}
|
|
3081
|
+
if (response.ok) return;
|
|
3082
|
+
const status = response.status;
|
|
3083
|
+
if (status === 401) {
|
|
3084
|
+
token = null;
|
|
3085
|
+
if (!refreshed && !terminal) {
|
|
3086
|
+
refreshed = true;
|
|
3087
|
+
await mintToken();
|
|
3088
|
+
if (token) continue;
|
|
3089
|
+
}
|
|
3090
|
+
if (!unattributed) {
|
|
3091
|
+
unattributed = true;
|
|
3092
|
+
continue;
|
|
3093
|
+
}
|
|
3094
|
+
return drop(batch, "unauthorized", status);
|
|
3095
|
+
}
|
|
3096
|
+
if (status === 409) return drop(batch, "conflict", status);
|
|
3097
|
+
if (status === 429 || status >= 500) {
|
|
3098
|
+
if (terminal || attempt >= MAX_ATTEMPTS) {
|
|
3099
|
+
return drop(batch, status === 429 ? "throttled" : "unavailable", status);
|
|
3100
|
+
}
|
|
3101
|
+
await sleep(retryDelay(response, attempt));
|
|
3102
|
+
continue;
|
|
3103
|
+
}
|
|
3104
|
+
return drop(batch, "rejected", status);
|
|
3105
|
+
}
|
|
3106
|
+
}
|
|
3107
|
+
async function run(requestedTerminal) {
|
|
3108
|
+
if (requestedTerminal) terminalRequested = true;
|
|
3109
|
+
if (sending) {
|
|
3110
|
+
if (requestedTerminal) {
|
|
3111
|
+
pendingTerminal = true;
|
|
3112
|
+
interruptForUnload();
|
|
3113
|
+
}
|
|
3114
|
+
return;
|
|
3115
|
+
}
|
|
3116
|
+
sending = true;
|
|
3117
|
+
try {
|
|
3118
|
+
while (queue.length > 0) {
|
|
3119
|
+
const terminal = requestedTerminal || terminalRequested;
|
|
3120
|
+
const batch = takeBatch();
|
|
3121
|
+
if (!terminal) await ensureToken();
|
|
3122
|
+
await deliver(batch, terminal);
|
|
3123
|
+
if (!terminal && disposed) break;
|
|
3124
|
+
}
|
|
3125
|
+
} finally {
|
|
3126
|
+
sending = false;
|
|
3127
|
+
}
|
|
3128
|
+
if (pendingTerminal) {
|
|
3129
|
+
pendingTerminal = false;
|
|
3130
|
+
await run(true);
|
|
3131
|
+
return;
|
|
3132
|
+
}
|
|
3133
|
+
if (!disposed && queue.length === 0) terminalRequested = false;
|
|
3134
|
+
}
|
|
3135
|
+
function clearFlushTimer() {
|
|
3136
|
+
if (timer !== null) {
|
|
3137
|
+
clearTimeout(timer);
|
|
3138
|
+
timer = null;
|
|
3139
|
+
}
|
|
3140
|
+
}
|
|
3141
|
+
function scheduleFlush() {
|
|
3142
|
+
if (timer !== null || disposed) return;
|
|
3143
|
+
timer = setTimeout(() => {
|
|
3144
|
+
timer = null;
|
|
3145
|
+
void run(false);
|
|
3146
|
+
}, FLUSH_DELAY_MS);
|
|
3147
|
+
}
|
|
3148
|
+
return {
|
|
3149
|
+
enqueue(event) {
|
|
3150
|
+
if (disposed) return;
|
|
3151
|
+
queue.push(toWireEvent(event));
|
|
3152
|
+
if (queue.length > MAX_QUEUE) {
|
|
3153
|
+
dropped += queue.length - MAX_QUEUE;
|
|
3154
|
+
queue.splice(0, queue.length - MAX_QUEUE);
|
|
3155
|
+
}
|
|
3156
|
+
if (queue.length >= MAX_BATCH) {
|
|
3157
|
+
clearFlushTimer();
|
|
3158
|
+
void run(false);
|
|
3159
|
+
} else {
|
|
3160
|
+
scheduleFlush();
|
|
3161
|
+
}
|
|
3162
|
+
},
|
|
3163
|
+
flush(flushOptions) {
|
|
3164
|
+
const terminal = flushOptions?.terminal ?? false;
|
|
3165
|
+
if (disposed && !terminal) return;
|
|
3166
|
+
clearFlushTimer();
|
|
3167
|
+
void run(terminal);
|
|
3168
|
+
},
|
|
3169
|
+
dispose() {
|
|
3170
|
+
if (disposed) return;
|
|
3171
|
+
disposed = true;
|
|
3172
|
+
clearFlushTimer();
|
|
3173
|
+
void run(true);
|
|
3174
|
+
}
|
|
3175
|
+
};
|
|
3176
|
+
}
|
|
3177
|
+
function randomUuid() {
|
|
3178
|
+
if (typeof globalThis.crypto?.randomUUID === "function") {
|
|
3179
|
+
return globalThis.crypto.randomUUID();
|
|
3180
|
+
}
|
|
3181
|
+
const bytes = new Uint8Array(16);
|
|
3182
|
+
globalThis.crypto?.getRandomValues?.(bytes);
|
|
3183
|
+
if (!bytes.some(Boolean)) {
|
|
3184
|
+
for (let index = 0; index < bytes.length; index += 1) {
|
|
3185
|
+
bytes[index] = Math.floor(Math.random() * 256);
|
|
3186
|
+
}
|
|
3187
|
+
}
|
|
3188
|
+
bytes[6] = bytes[6] & 15 | 64;
|
|
3189
|
+
bytes[8] = bytes[8] & 63 | 128;
|
|
3190
|
+
const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0"));
|
|
3191
|
+
return `${hex.slice(0, 4).join("")}-${hex.slice(4, 6).join("")}-${hex.slice(6, 8).join("")}-${hex.slice(8, 10).join("")}-${hex.slice(10).join("")}`;
|
|
3192
|
+
}
|
|
3193
|
+
function resolveProxyOrigin(backendUrl) {
|
|
3194
|
+
if (!backendUrl.trim()) return null;
|
|
3195
|
+
try {
|
|
3196
|
+
const { origin } = new URL(backendUrl, globalThis.location?.href);
|
|
3197
|
+
return origin.startsWith("http") ? origin : null;
|
|
3198
|
+
} catch {
|
|
3199
|
+
return null;
|
|
3200
|
+
}
|
|
3201
|
+
}
|
|
3202
|
+
|
|
3203
|
+
// src/core/analytics.tsx
|
|
3204
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
3205
|
+
var AnalyticsContext = createContext3(null);
|
|
3206
|
+
var noopDepositEmitter = () => {
|
|
3207
|
+
};
|
|
3208
|
+
var noopWithdrawEmitter = () => {
|
|
3209
|
+
};
|
|
3210
|
+
var noopClaimEmitter = () => {
|
|
3211
|
+
};
|
|
3212
|
+
function cloneAndFreeze(value) {
|
|
3213
|
+
if (Array.isArray(value)) {
|
|
3214
|
+
return Object.freeze(value.map(cloneAndFreeze));
|
|
3215
|
+
}
|
|
3216
|
+
if (value && typeof value === "object") {
|
|
3217
|
+
const clone = Object.fromEntries(
|
|
3218
|
+
Object.entries(value).map(([key, child]) => [key, cloneAndFreeze(child)])
|
|
3219
|
+
);
|
|
3220
|
+
return Object.freeze(clone);
|
|
3221
|
+
}
|
|
3222
|
+
return value;
|
|
3223
|
+
}
|
|
3224
|
+
function AnalyticsSession(props) {
|
|
3225
|
+
const sessionIdRef = useRef3(void 0);
|
|
3226
|
+
if (sessionIdRef.current === void 0) {
|
|
3227
|
+
sessionIdRef.current = (props.createSessionId ?? randomUuid)();
|
|
3228
|
+
}
|
|
3229
|
+
const sessionPropertiesRef = useRef3(void 0);
|
|
3230
|
+
if (sessionPropertiesRef.current === void 0) {
|
|
3231
|
+
sessionPropertiesRef.current = cloneAndFreeze(props.sessionProperties);
|
|
3232
|
+
}
|
|
3233
|
+
const onEventRef = useRef3(props.onEvent);
|
|
3234
|
+
onEventRef.current = props.onEvent;
|
|
3235
|
+
const nowRef = useRef3(props.now ?? (() => /* @__PURE__ */ new Date()));
|
|
3236
|
+
nowRef.current = props.now ?? (() => /* @__PURE__ */ new Date());
|
|
3237
|
+
const modal = props.modal;
|
|
3238
|
+
const reportedFailuresRef = useRef3(/* @__PURE__ */ new Set());
|
|
3239
|
+
const emitFailure = useCallback2(
|
|
3240
|
+
({ reason, status, droppedEvents }) => {
|
|
3241
|
+
if (reportedFailuresRef.current.has(reason)) return;
|
|
3242
|
+
reportedFailuresRef.current.add(reason);
|
|
3243
|
+
const event = {
|
|
3244
|
+
type: "analytics_ingest_failure",
|
|
3245
|
+
session_id: sessionIdRef.current,
|
|
3246
|
+
modal,
|
|
3247
|
+
widget_version: MODAL_VERSION,
|
|
3248
|
+
timestamp: nowRef.current().toISOString(),
|
|
3249
|
+
reason,
|
|
3250
|
+
...status === void 0 ? {} : { status },
|
|
3251
|
+
dropped_events: droppedEvents
|
|
3252
|
+
};
|
|
3253
|
+
onEventRef.current?.(event);
|
|
3254
|
+
},
|
|
3255
|
+
[modal]
|
|
3256
|
+
);
|
|
3257
|
+
function createIngest() {
|
|
3258
|
+
if (props.enableIngest === false) {
|
|
3259
|
+
return { transport: null, initialFailure: null };
|
|
3260
|
+
}
|
|
3261
|
+
const proxyOrigin = resolveProxyOrigin(props.backendUrl ?? "");
|
|
3262
|
+
if (!proxyOrigin || typeof globalThis.fetch !== "function") {
|
|
3263
|
+
return {
|
|
3264
|
+
transport: null,
|
|
3265
|
+
initialFailure: { reason: "unsupported", droppedEvents: 0 }
|
|
3266
|
+
};
|
|
3267
|
+
}
|
|
3268
|
+
return {
|
|
3269
|
+
transport: createIngestTransport({
|
|
3270
|
+
ingestUrl: props.ingestUrl ?? DEFAULT_ANALYTICS_INGEST_URL,
|
|
3271
|
+
backendUrl: props.backendUrl,
|
|
3272
|
+
proxyOrigin,
|
|
3273
|
+
sessionId: sessionIdRef.current,
|
|
3274
|
+
modal,
|
|
3275
|
+
widgetVersion: MODAL_VERSION,
|
|
3276
|
+
sessionProperties: sessionPropertiesRef.current,
|
|
3277
|
+
onFailure: (failure) => emitFailure(failure),
|
|
3278
|
+
fetchImpl: props.fetchImpl,
|
|
3279
|
+
createEventId: props.createEventId
|
|
3280
|
+
}),
|
|
3281
|
+
initialFailure: null
|
|
3282
|
+
};
|
|
3283
|
+
}
|
|
3284
|
+
const ingestRef = useRef3(void 0);
|
|
3285
|
+
if (ingestRef.current === void 0) {
|
|
3286
|
+
ingestRef.current = createIngest();
|
|
3287
|
+
}
|
|
3288
|
+
const pendingDisposalRef = useRef3(null);
|
|
3289
|
+
const enqueue = useCallback2(
|
|
3290
|
+
(event) => {
|
|
3291
|
+
try {
|
|
3292
|
+
ingestRef.current?.transport?.enqueue(
|
|
3293
|
+
event
|
|
3294
|
+
);
|
|
3295
|
+
} catch {
|
|
3296
|
+
}
|
|
3297
|
+
},
|
|
3298
|
+
[]
|
|
3299
|
+
);
|
|
3300
|
+
useEffect4(() => {
|
|
3301
|
+
if (pendingDisposalRef.current !== null) {
|
|
3302
|
+
clearTimeout(pendingDisposalRef.current);
|
|
3303
|
+
pendingDisposalRef.current = null;
|
|
3304
|
+
}
|
|
3305
|
+
const setup = ingestRef.current;
|
|
3306
|
+
if (setup.initialFailure) emitFailure(setup.initialFailure);
|
|
3307
|
+
const transport = setup.transport;
|
|
3308
|
+
if (!transport) return;
|
|
3309
|
+
const flush = () => transport.flush({ terminal: true });
|
|
3310
|
+
const onVisibilityChange = () => {
|
|
3311
|
+
if (document.visibilityState === "hidden") flush();
|
|
3312
|
+
};
|
|
3313
|
+
window.addEventListener("pagehide", flush);
|
|
3314
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
3315
|
+
return () => {
|
|
3316
|
+
window.removeEventListener("pagehide", flush);
|
|
3317
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
3318
|
+
pendingDisposalRef.current = setTimeout(() => {
|
|
3319
|
+
pendingDisposalRef.current = null;
|
|
3320
|
+
transport.dispose();
|
|
3321
|
+
}, 0);
|
|
3322
|
+
};
|
|
3323
|
+
}, [emitFailure]);
|
|
3324
|
+
const emitDeposit = useCallback2(
|
|
3325
|
+
(...[payload, fundingMethod]) => {
|
|
3326
|
+
if (modal !== "deposit") return;
|
|
3327
|
+
const event = {
|
|
3328
|
+
...payload,
|
|
3329
|
+
session_id: sessionIdRef.current,
|
|
3330
|
+
modal,
|
|
3331
|
+
widget_version: MODAL_VERSION,
|
|
3332
|
+
timestamp: nowRef.current().toISOString(),
|
|
3333
|
+
session_properties: sessionPropertiesRef.current,
|
|
3334
|
+
funding_method: fundingMethod
|
|
3335
|
+
};
|
|
3336
|
+
onEventRef.current?.(
|
|
3337
|
+
event
|
|
3338
|
+
);
|
|
3339
|
+
enqueue(event);
|
|
3340
|
+
},
|
|
3341
|
+
[enqueue, modal, nowRef, onEventRef]
|
|
3342
|
+
);
|
|
3343
|
+
const emitWithdraw = useCallback2(
|
|
3344
|
+
(payload) => {
|
|
3345
|
+
if (modal !== "withdraw") return;
|
|
3346
|
+
const event = {
|
|
3347
|
+
...payload,
|
|
3348
|
+
session_id: sessionIdRef.current,
|
|
3349
|
+
modal,
|
|
3350
|
+
widget_version: MODAL_VERSION,
|
|
3351
|
+
timestamp: nowRef.current().toISOString(),
|
|
3352
|
+
session_properties: sessionPropertiesRef.current
|
|
3353
|
+
};
|
|
3354
|
+
onEventRef.current?.(event);
|
|
3355
|
+
enqueue(event);
|
|
3356
|
+
},
|
|
3357
|
+
[enqueue, modal, nowRef, onEventRef]
|
|
3358
|
+
);
|
|
3359
|
+
const emitClaim = useCallback2(
|
|
3360
|
+
(payload) => {
|
|
3361
|
+
if (modal !== "claim") return;
|
|
3362
|
+
const event = {
|
|
3363
|
+
...payload,
|
|
3364
|
+
session_id: sessionIdRef.current,
|
|
3365
|
+
modal,
|
|
3366
|
+
widget_version: MODAL_VERSION,
|
|
3367
|
+
timestamp: nowRef.current().toISOString(),
|
|
3368
|
+
session_properties: sessionPropertiesRef.current
|
|
3369
|
+
};
|
|
3370
|
+
onEventRef.current?.(event);
|
|
3371
|
+
enqueue(event);
|
|
3372
|
+
},
|
|
3373
|
+
[enqueue, modal, nowRef, onEventRef]
|
|
3374
|
+
);
|
|
3375
|
+
const context = useMemo3(
|
|
3376
|
+
() => modal === "deposit" ? { modal, emit: emitDeposit } : modal === "withdraw" ? { modal, emit: emitWithdraw } : { modal, emit: emitClaim },
|
|
3377
|
+
[modal, emitDeposit, emitWithdraw, emitClaim]
|
|
3378
|
+
);
|
|
3379
|
+
return /* @__PURE__ */ jsx11(AnalyticsContext.Provider, { value: context, children: props.children });
|
|
3380
|
+
}
|
|
3381
|
+
function useDepositAnalyticsEmitter() {
|
|
3382
|
+
const context = useContext3(AnalyticsContext);
|
|
3383
|
+
if (!context || context.modal !== "deposit") return noopDepositEmitter;
|
|
3384
|
+
return context.emit;
|
|
3385
|
+
}
|
|
3386
|
+
function useWithdrawAnalyticsEmitter() {
|
|
3387
|
+
const context = useContext3(AnalyticsContext);
|
|
3388
|
+
if (!context || context.modal !== "withdraw") return noopWithdrawEmitter;
|
|
3389
|
+
return context.emit;
|
|
3390
|
+
}
|
|
3391
|
+
function useClaimAnalyticsEmitter() {
|
|
3392
|
+
const context = useContext3(AnalyticsContext);
|
|
3393
|
+
if (!context || context.modal !== "claim") return noopClaimEmitter;
|
|
3394
|
+
return context.emit;
|
|
3395
|
+
}
|
|
3396
|
+
|
|
2674
3397
|
// src/core/theme.ts
|
|
2675
3398
|
var RADIUS_SCALE = {
|
|
2676
3399
|
none: { sm: "0", md: "0", lg: "0" },
|
|
@@ -2770,15 +3493,32 @@ var CUSTOM_PRIMARY_VARS = [
|
|
|
2770
3493
|
"--rs-primary-foreground",
|
|
2771
3494
|
"--rs-border-accent"
|
|
2772
3495
|
];
|
|
3496
|
+
var DARK_SCHEME_QUERY = "(prefers-color-scheme: dark)";
|
|
3497
|
+
var NOTHING_TO_STOP = () => {
|
|
3498
|
+
};
|
|
3499
|
+
function resolveThemeMode(mode) {
|
|
3500
|
+
if (mode !== "system") return mode;
|
|
3501
|
+
return globalThis.matchMedia?.(DARK_SCHEME_QUERY).matches ? "dark" : "light";
|
|
3502
|
+
}
|
|
3503
|
+
function followSystemAppearance(mode, onChange) {
|
|
3504
|
+
if (mode !== "system") return NOTHING_TO_STOP;
|
|
3505
|
+
const query = globalThis.matchMedia?.(DARK_SCHEME_QUERY);
|
|
3506
|
+
if (!query) return NOTHING_TO_STOP;
|
|
3507
|
+
query.addEventListener("change", onChange);
|
|
3508
|
+
return () => query.removeEventListener("change", onChange);
|
|
3509
|
+
}
|
|
2773
3510
|
function applyTheme(element, theme) {
|
|
2774
|
-
if (!element) return;
|
|
3511
|
+
if (!element) return NOTHING_TO_STOP;
|
|
2775
3512
|
const parent = element.parentElement;
|
|
2776
3513
|
const targets = parent?.classList.contains("rs-modal-content") ? [element, parent] : [element];
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
3514
|
+
const paintMode = () => {
|
|
3515
|
+
const resolved = resolveThemeMode(theme?.mode);
|
|
3516
|
+
for (const t of targets) {
|
|
3517
|
+
if (resolved) t.setAttribute("data-theme", resolved);
|
|
3518
|
+
else t.removeAttribute("data-theme");
|
|
3519
|
+
}
|
|
3520
|
+
};
|
|
3521
|
+
paintMode();
|
|
2782
3522
|
if (theme?.fontColor) {
|
|
2783
3523
|
setVar(targets, "--rs-foreground", theme.fontColor);
|
|
2784
3524
|
}
|
|
@@ -2828,6 +3568,7 @@ function applyTheme(element, theme) {
|
|
|
2828
3568
|
setVar(targets, "--rs-radius-lg", scale.lg);
|
|
2829
3569
|
setVar(targets, "--rs-radius", scale.md);
|
|
2830
3570
|
}
|
|
3571
|
+
return followSystemAppearance(theme?.mode, paintMode);
|
|
2831
3572
|
}
|
|
2832
3573
|
|
|
2833
3574
|
// src/core/backend-url.ts
|
|
@@ -2858,9 +3599,6 @@ export {
|
|
|
2858
3599
|
CopyIcon,
|
|
2859
3600
|
ArrowUpRightIcon,
|
|
2860
3601
|
AlertTriangleIcon,
|
|
2861
|
-
PercentIcon,
|
|
2862
|
-
ClockIcon,
|
|
2863
|
-
PlusCircleIcon,
|
|
2864
3602
|
CircleArrowOutUpLeftIcon,
|
|
2865
3603
|
CardIcon,
|
|
2866
3604
|
BankIcon,
|
|
@@ -2884,6 +3622,7 @@ export {
|
|
|
2884
3622
|
SwappedConnectFeeChangedError,
|
|
2885
3623
|
SUPPORTED_CONNECT_EXCHANGE_COUNT,
|
|
2886
3624
|
resolveAppFeeBps,
|
|
3625
|
+
PermitDepositSubmitError,
|
|
2887
3626
|
createDepositService,
|
|
2888
3627
|
rpcUrlFor,
|
|
2889
3628
|
RpcUrlsProvider,
|
|
@@ -2899,6 +3638,7 @@ export {
|
|
|
2899
3638
|
useTargetTokens,
|
|
2900
3639
|
useIsDepositChain,
|
|
2901
3640
|
useChainName,
|
|
3641
|
+
useReadClient,
|
|
2902
3642
|
useExplorerTxUrl,
|
|
2903
3643
|
ChainCatalogProvider,
|
|
2904
3644
|
useLatestRef,
|
|
@@ -2918,6 +3658,12 @@ export {
|
|
|
2918
3658
|
estimateReceiveAmount,
|
|
2919
3659
|
formatQuotedReceive,
|
|
2920
3660
|
formatReceiveEstimate,
|
|
3661
|
+
AnalyticsSession,
|
|
3662
|
+
useDepositAnalyticsEmitter,
|
|
3663
|
+
useWithdrawAnalyticsEmitter,
|
|
3664
|
+
useClaimAnalyticsEmitter,
|
|
3665
|
+
resolveThemeMode,
|
|
3666
|
+
followSystemAppearance,
|
|
2921
3667
|
applyTheme,
|
|
2922
3668
|
checkBackendUrl
|
|
2923
3669
|
};
|