@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.
Files changed (68) hide show
  1. package/README.md +73 -18
  2. package/bridge-transcript.json +653 -0
  3. package/dist/ClaimModal-IKTJU43Y.cjs +13 -0
  4. package/dist/ClaimModal-SEKNWRMA.mjs +13 -0
  5. package/dist/{DepositModalReown-VG66OTIU.cjs → DepositModalReown-46LPVFB6.cjs} +58 -35
  6. package/dist/{DepositModalReown-TEC3MEZ4.mjs → DepositModalReown-Q2JMLT47.mjs} +45 -22
  7. package/dist/{QRCode-WUC652SH.mjs → QRCode-5RGIZZHL.mjs} +1 -1
  8. package/dist/{QRCode-5DXFNKI2.cjs → QRCode-JKXG4RHN.cjs} +2 -2
  9. package/dist/WithdrawModal-5ICGD4HJ.mjs +12 -0
  10. package/dist/WithdrawModal-VP6PMIRO.cjs +12 -0
  11. package/dist/{chunk-O7BCVQ6L.cjs → chunk-4KCSH4T3.cjs} +157 -199
  12. package/dist/chunk-6KG642KH.cjs +31 -0
  13. package/dist/{chunk-PWLEBV5V.cjs → chunk-7ICSHJFE.cjs} +296 -220
  14. package/dist/{chunk-J46WDSRD.mjs → chunk-7SR7ENVJ.mjs} +165 -89
  15. package/dist/{chunk-2TPSF77V.mjs → chunk-CFKC77SV.mjs} +455 -261
  16. package/dist/{chunk-75DVGSAX.cjs → chunk-DW2EQA2U.cjs} +6 -3
  17. package/dist/{chunk-FXXUIK4E.mjs → chunk-IN77XSWO.mjs} +899 -153
  18. package/dist/chunk-K4H6TGBE.mjs +31 -0
  19. package/dist/{chunk-SDSKIJC7.mjs → chunk-KTUVSKR4.mjs} +2410 -1177
  20. package/dist/{chunk-HL5NUKZW.cjs → chunk-LZFRL2AL.cjs} +3 -3
  21. package/dist/{chunk-UQIJU6HV.cjs → chunk-MTFJSE52.cjs} +499 -191
  22. package/dist/{chunk-FLVLYO64.mjs → chunk-PKML3XVS.mjs} +430 -122
  23. package/dist/{chunk-4ZXQPFNU.mjs → chunk-RN5VKWI6.mjs} +4 -1
  24. package/dist/{chunk-BRYNGLDM.cjs → chunk-V2OBGLJD.cjs} +961 -215
  25. package/dist/{chunk-3STTWRAN.mjs → chunk-VUATPOWJ.mjs} +147 -189
  26. package/dist/{chunk-JE4R5VA3.mjs → chunk-WUJIKCFU.mjs} +1 -1
  27. package/dist/chunk-X2IPAPXU.cjs +163 -0
  28. package/dist/{chunk-OIN4CXCP.cjs → chunk-YCQZJQO6.cjs} +2343 -1110
  29. package/dist/{chunk-TM7VGHAG.cjs → chunk-YWMWI7PZ.cjs} +462 -268
  30. package/dist/chunk-ZEO6ADM3.mjs +163 -0
  31. package/dist/claim.cjs +7 -6
  32. package/dist/claim.d.cts +11 -3
  33. package/dist/claim.d.ts +11 -3
  34. package/dist/claim.mjs +6 -5
  35. package/dist/{constants-FuzG3h4m.d.cts → constants-DBrWhJWE.d.cts} +12 -7
  36. package/dist/{constants-FuzG3h4m.d.ts → constants-DBrWhJWE.d.ts} +12 -7
  37. package/dist/constants.cjs +3 -9
  38. package/dist/constants.d.cts +2 -3
  39. package/dist/constants.d.ts +2 -3
  40. package/dist/constants.mjs +4 -10
  41. package/dist/deposit.cjs +8 -8
  42. package/dist/deposit.d.cts +2 -2
  43. package/dist/deposit.d.ts +2 -2
  44. package/dist/deposit.mjs +7 -7
  45. package/dist/embed.cjs +1476 -0
  46. package/dist/embed.d.cts +183 -0
  47. package/dist/embed.d.ts +183 -0
  48. package/dist/embed.mjs +1476 -0
  49. package/dist/index.cjs +11 -16
  50. package/dist/index.d.cts +3 -3
  51. package/dist/index.d.ts +3 -3
  52. package/dist/index.mjs +14 -19
  53. package/dist/modal-ui-state-OD1RmKkK.d.cts +30 -0
  54. package/dist/modal-ui-state-OD1RmKkK.d.ts +30 -0
  55. package/dist/polymarket.cjs +17 -7
  56. package/dist/polymarket.mjs +13 -3
  57. package/dist/styles.css +124 -98
  58. package/dist/types-Bho4OA03.d.ts +982 -0
  59. package/dist/types-DP_3KwlD.d.cts +982 -0
  60. package/dist/withdraw.cjs +6 -6
  61. package/dist/withdraw.d.cts +11 -3
  62. package/dist/withdraw.d.ts +11 -3
  63. package/dist/withdraw.mjs +5 -5
  64. package/package.json +59 -6
  65. package/dist/chunk-IAGFDSNC.mjs +0 -11
  66. package/dist/chunk-L32UI7LA.cjs +0 -11
  67. package/dist/types-BO4iP6fG.d.cts +0 -612
  68. package/dist/types-oFblf65g.d.ts +0 -612
@@ -1,11 +1,10 @@
1
1
  import {
2
- SERVICE_HEADERS
3
- } from "./chunk-IAGFDSNC.mjs";
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-3STTWRAN.mjs";
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 (!origin) return;
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 HYPERCORE_MAINNET_CAIP2;
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)) return null;
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: SERVICE_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: SERVICE_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: SERVICE_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
- debug,
985
- scope,
986
- "registerManagedAccount:failed",
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(`evm:${address.toLowerCase()}`, async () => {
1007
- const url = apiUrl(`/portfolio/${address}?includeUnsupported=true`);
1008
- debugLog(debug, scope, "fetchPortfolio:request", { url, address });
1009
- const response = await fetch(url, {
1010
- method: "GET",
1011
- headers: SERVICE_HEADERS
1012
- });
1013
- if (!response.ok) {
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
- return direct;
1036
- }
1037
- const portfolioData = extractOrchestratorPortfolio(data);
1038
- if (portfolioData) {
1039
- const normalized = normalizeOrchestratorPortfolio(portfolioData);
1040
- debugLog(debug, scope, "fetchPortfolio:success", {
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
- debugLog(debug, scope, "fetchPortfolio:empty", { address });
1049
- return { tokens: [], totalUsd: 0 };
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: SERVICE_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
- debug,
1094
- scope,
1095
- "checkAccount:failed",
1096
- error,
1097
- { status: response.status, address }
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(address)}&txHash=${txHashParam}&limit=1`
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: SERVICE_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: SERVICE_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: SERVICE_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: SERVICE_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: SERVICE_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: SERVICE_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: SERVICE_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
- debug,
1316
- scope,
1317
- "fetchDepositHistory:failed",
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: SERVICE_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
- sourceChainId: params.sourceChainId === "hypercore" ? HYPERCORE_MAINNET_CAIP2 : `eip155:${params.sourceChainId}`,
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: SERVICE_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: SERVICE_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({ addresses: list.join(",") }).toString()}`
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: SERVICE_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: SERVICE_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: SERVICE_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: SERVICE_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: SERVICE_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: SERVICE_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: SERVICE_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(resolvedTokenAddress, chainBalance.chainId);
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(resolvedTokenAddress, chainBalance.chainId) : tokenData.tokenDecimals ?? 18;
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 (`hypercore:mainnet`) is a non-EVM source; keep its USDC
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 = CHAIN_BY_ID[chainId] ?? runtimeChainById.get(chainId);
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
- if (theme?.mode) {
2778
- for (const t of targets) t.setAttribute("data-theme", theme.mode);
2779
- } else {
2780
- for (const t of targets) t.removeAttribute("data-theme");
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
  };