@rhinestone/deposit-modal 0.16.0 → 0.18.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 (62) hide show
  1. package/README.md +68 -0
  2. package/dist/{DepositModalReown-IFN6YLZJ.cjs → DepositModalReown-TVO3ZQQK.cjs} +17 -17
  3. package/dist/{DepositModalReown-R7UROJPJ.mjs → DepositModalReown-VCY65DJX.mjs} +4 -4
  4. package/dist/WithdrawModal-GR3HLYXU.cjs +11 -0
  5. package/dist/{WithdrawModal-XKSSHVEJ.mjs → WithdrawModal-RMCYJJ4S.mjs} +3 -3
  6. package/dist/bearer-transport-CVHNBgoV.d.cts +14 -0
  7. package/dist/bearer-transport-CVHNBgoV.d.ts +14 -0
  8. package/dist/{chunk-24N4KMJX.cjs → chunk-34JVJZEZ.cjs} +71 -71
  9. package/dist/{chunk-3HCCR54R.mjs → chunk-3TEVMP76.mjs} +1 -1
  10. package/dist/chunk-ADEWTBSN.cjs +19 -0
  11. package/dist/{chunk-EA5CE2UZ.mjs → chunk-AIZKGFVA.mjs} +675 -233
  12. package/dist/{chunk-F6ROQ6RJ.mjs → chunk-EKC2IRQG.mjs} +185 -69
  13. package/dist/{chunk-V466XQSG.cjs → chunk-JV5OGG53.cjs} +630 -514
  14. package/dist/{chunk-H4O22O7Y.cjs → chunk-N3AAT6BS.cjs} +826 -384
  15. package/dist/{chunk-5CM3ZQ5U.cjs → chunk-N6JJG57R.cjs} +1 -1
  16. package/dist/chunk-O4JZKKCZ.cjs +41 -0
  17. package/dist/chunk-PP4QE32S.mjs +19 -0
  18. package/dist/{chunk-HMB2XQGD.mjs → chunk-R2B6VD4E.mjs} +1 -1
  19. package/dist/chunk-X4EUXBHJ.mjs +41 -0
  20. package/dist/compliance.cjs +14 -0
  21. package/dist/compliance.d.cts +10 -0
  22. package/dist/compliance.d.ts +10 -0
  23. package/dist/compliance.mjs +14 -0
  24. package/dist/constants.cjs +3 -3
  25. package/dist/constants.d.cts +1 -1
  26. package/dist/constants.d.ts +1 -1
  27. package/dist/constants.mjs +3 -3
  28. package/dist/deposit.cjs +4 -4
  29. package/dist/deposit.d.cts +2 -2
  30. package/dist/deposit.d.ts +2 -2
  31. package/dist/deposit.mjs +3 -3
  32. package/dist/embed.cjs +16 -16
  33. package/dist/embed.d.cts +1 -1
  34. package/dist/embed.d.ts +1 -1
  35. package/dist/embed.mjs +8 -8
  36. package/dist/index.cjs +5 -5
  37. package/dist/index.d.cts +1 -1
  38. package/dist/index.d.ts +1 -1
  39. package/dist/index.mjs +4 -4
  40. package/dist/offramp.cjs +25 -0
  41. package/dist/offramp.d.cts +28 -0
  42. package/dist/offramp.d.ts +28 -0
  43. package/dist/offramp.mjs +25 -0
  44. package/dist/onramp.cjs +27 -0
  45. package/dist/onramp.d.cts +37 -0
  46. package/dist/onramp.d.ts +37 -0
  47. package/dist/onramp.mjs +27 -0
  48. package/dist/ramp-types-C6aUz4SZ.d.cts +43 -0
  49. package/dist/ramp-types-C6aUz4SZ.d.ts +43 -0
  50. package/dist/server.cjs +54 -2
  51. package/dist/server.d.cts +13 -1
  52. package/dist/server.d.ts +13 -1
  53. package/dist/server.mjs +52 -0
  54. package/dist/styles.css +22 -0
  55. package/dist/{types-B9SbZQIG.d.ts → types-CZYypODQ.d.ts} +3 -2
  56. package/dist/{types-SwGGf0eH.d.cts → types-CbUs4boj.d.cts} +3 -2
  57. package/dist/withdraw.cjs +4 -4
  58. package/dist/withdraw.d.cts +2 -2
  59. package/dist/withdraw.d.ts +2 -2
  60. package/dist/withdraw.mjs +3 -3
  61. package/package.json +35 -5
  62. package/dist/WithdrawModal-SZEAI473.cjs +0 -11
@@ -1,7 +1,6 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
2
 
3
3
 
4
- var _chunk5CM3ZQ5Ucjs = require('./chunk-5CM3ZQ5U.cjs');
5
4
 
6
5
 
7
6
 
@@ -32,10 +31,11 @@ var _chunk5CM3ZQ5Ucjs = require('./chunk-5CM3ZQ5U.cjs');
32
31
 
33
32
 
34
33
 
34
+ var _chunkOY5N3E6Lcjs = require('./chunk-OY5N3E6L.cjs');
35
35
 
36
36
 
37
37
 
38
- var _chunkOY5N3E6Lcjs = require('./chunk-OY5N3E6L.cjs');
38
+ var _chunkN6JJG57Rcjs = require('./chunk-N6JJG57R.cjs');
39
39
 
40
40
  // src/components/ui/Modal.tsx
41
41
 
@@ -650,12 +650,37 @@ function parseQuotePreview(raw) {
650
650
  );
651
651
  if (Math.abs(totalUsd - breakdownTotalUsd) > 1e-6) return null;
652
652
  const breakdown = Object.fromEntries(parsedEntries);
653
+ const timing = parseDepositTiming(obj.timing);
653
654
  return {
654
655
  settlementLayer: obj.settlementLayer,
655
656
  expiresAt: obj.expiresAt,
656
657
  estimatedFillTimeSeconds: obj.estimatedFillTimeSeconds,
657
658
  fees: { total: { usd: totalUsd }, breakdown },
658
- output
659
+ output,
660
+ ...timing ? { timing } : {}
661
+ };
662
+ }
663
+ function parseDepositTiming(raw) {
664
+ if (typeof raw !== "object" || raw === null) return void 0;
665
+ const o = raw;
666
+ const seconds = (value) => typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
667
+ const expectedSeconds = seconds(o.expectedSeconds);
668
+ const softDelaySeconds = seconds(o.softDelaySeconds);
669
+ const escalatedDelaySeconds = seconds(o.escalatedDelaySeconds);
670
+ if (expectedSeconds === void 0 || softDelaySeconds === void 0 || escalatedDelaySeconds === void 0) {
671
+ return void 0;
672
+ }
673
+ return { expectedSeconds, softDelaySeconds, escalatedDelaySeconds };
674
+ }
675
+ function normalizeHistoryTiming(raw) {
676
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
677
+ return raw;
678
+ }
679
+ const { timing: rawTiming, ...row } = raw;
680
+ const timing = parseDepositTiming(rawTiming);
681
+ return {
682
+ ...row,
683
+ ...timing ? { timing } : {}
659
684
  };
660
685
  }
661
686
  function parseQuoteOutput(raw) {
@@ -711,6 +736,31 @@ function resolveAppFeeBps(appFees, sourceChainCaip2, sourceToken) {
711
736
  const bps = _nullishCoalesce(_nullishCoalesce(override, () => ( _optionalChain([appFees, 'optionalAccess', _8 => _8.feeBps]))), () => ( 0));
712
737
  return bps > 0 ? bps : 0;
713
738
  }
739
+ function isRawAmount(value) {
740
+ return typeof value === "string" && /^\d+$/.test(value);
741
+ }
742
+ function isDepositPolicyRefusal(value) {
743
+ return typeof value === "object" && value !== null && "policyRefusal" in value;
744
+ }
745
+ var DEPOSIT_POLICY_REFUSAL_CODES = [
746
+ "TOKEN-3",
747
+ "BALANCE-3",
748
+ "BALANCE-4"
749
+ ];
750
+ var DEPOSIT_PREFLIGHT_TIMEOUT_MS = 1e4;
751
+ async function readPolicyRefusal(response) {
752
+ if (response.status !== 422) return null;
753
+ try {
754
+ const body = await response.json();
755
+ if (!body || typeof body.code !== "string" || !DEPOSIT_POLICY_REFUSAL_CODES.includes(body.code)) {
756
+ return null;
757
+ }
758
+ const message = typeof body.error === "string" && body.error !== "" ? body.error : "This deposit is not accepted.";
759
+ return { policyRefusal: { code: body.code, message } };
760
+ } catch (e4) {
761
+ return null;
762
+ }
763
+ }
714
764
  var PermitDepositSubmitError = class extends Error {
715
765
  constructor(message, safeToTransfer) {
716
766
  super(message);
@@ -737,62 +787,93 @@ function createDepositService(baseUrl, options) {
737
787
  if (value.length <= 20) return value;
738
788
  return `${value.slice(0, 10)}...${value.slice(-8)}`;
739
789
  }
790
+ function withPreflightTimeout(label, fallback, run) {
791
+ const controller = new AbortController();
792
+ return new Promise((resolve) => {
793
+ const timer = setTimeout(() => {
794
+ debugLog(debug, scope, `${label}:timeout`, {
795
+ timeoutMs: DEPOSIT_PREFLIGHT_TIMEOUT_MS
796
+ });
797
+ controller.abort();
798
+ resolve(fallback);
799
+ }, DEPOSIT_PREFLIGHT_TIMEOUT_MS);
800
+ run(controller.signal).then(
801
+ (value) => {
802
+ clearTimeout(timer);
803
+ resolve(value);
804
+ },
805
+ () => {
806
+ clearTimeout(timer);
807
+ resolve(fallback);
808
+ }
809
+ );
810
+ });
811
+ }
740
812
  const PORTFOLIO_CACHE_TTL_MS = 3e4;
741
813
  const portfolioCache = /* @__PURE__ */ new Map();
742
814
  let topTokensPromise = null;
743
815
  let chainsPromise = null;
744
- function parseTopTokens(value) {
745
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
816
+ function parseDepositOptions(value) {
817
+ if (typeof value !== "object" || value === null) return null;
818
+ const { restricted, tokens: rawTokens } = value;
819
+ if (typeof restricted !== "boolean") return null;
820
+ if (typeof rawTokens !== "object" || rawTokens === null || Array.isArray(rawTokens)) {
746
821
  return null;
747
822
  }
748
- const parsed = {};
749
- for (const [chainKey, list] of Object.entries(value)) {
823
+ const tokens = {};
824
+ for (const [chainKey, list] of Object.entries(rawTokens)) {
750
825
  if (!Array.isArray(list)) return null;
751
- const tokens = [];
826
+ const parsed = [];
752
827
  for (const entry of list) {
753
828
  if (typeof entry !== "object" || entry === null) return null;
754
- const { symbol, address, decimals } = entry;
829
+ const { symbol, address, decimals, minAmount, maxAmount } = entry;
755
830
  if (typeof symbol !== "string" || typeof address !== "string" || typeof decimals !== "number") {
756
831
  return null;
757
832
  }
758
- tokens.push({ symbol, address, decimals });
833
+ parsed.push({
834
+ symbol,
835
+ address,
836
+ decimals,
837
+ ...isRawAmount(minAmount) && { minAmount },
838
+ ...isRawAmount(maxAmount) && { maxAmount }
839
+ });
759
840
  }
760
- parsed[chainKey] = tokens;
841
+ tokens[chainKey] = parsed;
761
842
  }
762
- return parsed;
843
+ return { restricted, tokens };
763
844
  }
764
845
  async function requestTopTokens() {
765
846
  try {
766
847
  const response = await fetch(apiUrl("/qr/tokens"), {
767
848
  method: "GET",
768
- headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, )
849
+ headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, )
769
850
  });
770
851
  if (!response.ok) {
771
852
  debugLog(debug, scope, "getTopTokens:unavailable", {
772
853
  status: response.status
773
854
  });
774
- return null;
855
+ return { ok: false };
775
856
  }
776
- const data = await response.json();
777
- const tokens = parseTopTokens(data.tokens);
778
- if (!tokens) {
857
+ const options2 = parseDepositOptions(await response.json());
858
+ if (!options2) {
779
859
  debugLog(debug, scope, "getTopTokens:malformed");
780
- return null;
860
+ return { ok: false };
781
861
  }
782
862
  debugLog(debug, scope, "getTopTokens:success", {
783
- chains: Object.keys(tokens).length
863
+ chains: Object.keys(options2.tokens).length,
864
+ restricted: options2.restricted
784
865
  });
785
- return tokens;
866
+ return { ok: true, options: options2 };
786
867
  } catch (error) {
787
868
  debugError(debug, scope, "getTopTokens:error", error);
788
- return null;
869
+ return { ok: false };
789
870
  }
790
871
  }
791
872
  async function requestChains() {
792
873
  try {
793
874
  const response = await fetch(apiUrl("/chains"), {
794
875
  method: "GET",
795
- headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, )
876
+ headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, )
796
877
  });
797
878
  if (!response.ok) {
798
879
  debugLog(debug, scope, "getChains:unavailable", {
@@ -846,7 +927,7 @@ function createDepositService(baseUrl, options) {
846
927
  });
847
928
  const response = await fetch(url, {
848
929
  method: "POST",
849
- headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, ),
930
+ headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, ),
850
931
  body: JSON.stringify({ account: params })
851
932
  });
852
933
  if (!response.ok) {
@@ -881,7 +962,7 @@ function createDepositService(baseUrl, options) {
881
962
  debugLog(debug, scope, "fetchPortfolio:request", { url, address });
882
963
  const response = await fetch(url, {
883
964
  method: "GET",
884
- headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, )
965
+ headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, )
885
966
  });
886
967
  if (!response.ok) {
887
968
  const error = await response.json().catch(() => ({ error: "Unknown error" }));
@@ -932,7 +1013,7 @@ function createDepositService(baseUrl, options) {
932
1013
  });
933
1014
  const response = await fetch(url, {
934
1015
  method: "GET",
935
- headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, )
1016
+ headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, )
936
1017
  });
937
1018
  if (!response.ok) {
938
1019
  const error = await response.json().catch(() => ({ error: "Unknown error" }));
@@ -961,7 +1042,7 @@ function createDepositService(baseUrl, options) {
961
1042
  debugLog(debug, scope, "checkAccount:request", { url, address });
962
1043
  const response = await fetch(url, {
963
1044
  method: "GET",
964
- headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, )
1045
+ headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, )
965
1046
  });
966
1047
  if (!response.ok) {
967
1048
  const error = await response.json().catch(() => ({ error: "Unknown error" }));
@@ -997,7 +1078,7 @@ function createDepositService(baseUrl, options) {
997
1078
  );
998
1079
  const response = await fetch(url, {
999
1080
  method: "GET",
1000
- headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, ),
1081
+ headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, ),
1001
1082
  cache: "no-store"
1002
1083
  });
1003
1084
  if (!response.ok) {
@@ -1025,7 +1106,7 @@ function createDepositService(baseUrl, options) {
1025
1106
  );
1026
1107
  const response = await fetch(url, {
1027
1108
  method: "GET",
1028
- headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, ),
1109
+ headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, ),
1029
1110
  cache: "no-store"
1030
1111
  });
1031
1112
  if (!response.ok) {
@@ -1049,7 +1130,7 @@ function createDepositService(baseUrl, options) {
1049
1130
  );
1050
1131
  const response = await fetch(url, {
1051
1132
  method: "GET",
1052
- headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, ),
1133
+ headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, ),
1053
1134
  cache: "no-store"
1054
1135
  });
1055
1136
  if (!response.ok) {
@@ -1071,7 +1152,7 @@ function createDepositService(baseUrl, options) {
1071
1152
  async getPositions(address) {
1072
1153
  const url = apiUrl(`/positions/${address}`);
1073
1154
  debugLog(debug, scope, "getPositions:request", { url, address });
1074
- const response = await fetch(url, { headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, ) });
1155
+ const response = await fetch(url, { headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, ) });
1075
1156
  if (!response.ok) {
1076
1157
  const error = await response.json().catch(() => ({ error: "Unknown error" }));
1077
1158
  debugError(debug, scope, "getPositions:failed", error, {
@@ -1105,7 +1186,7 @@ function createDepositService(baseUrl, options) {
1105
1186
  });
1106
1187
  const response = await fetch(url, {
1107
1188
  method: "POST",
1108
- headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, ),
1189
+ headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, ),
1109
1190
  body: JSON.stringify({ account, market, chainId, asset, amount })
1110
1191
  });
1111
1192
  if (!response.ok) {
@@ -1141,7 +1222,7 @@ function createDepositService(baseUrl, options) {
1141
1222
  });
1142
1223
  const response = await fetch(url, {
1143
1224
  method: "POST",
1144
- headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, ),
1225
+ headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, ),
1145
1226
  body: JSON.stringify({
1146
1227
  depositWallet,
1147
1228
  owner,
@@ -1183,7 +1264,7 @@ function createDepositService(baseUrl, options) {
1183
1264
  });
1184
1265
  const response = await fetch(url, {
1185
1266
  method: "GET",
1186
- headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, ),
1267
+ headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, ),
1187
1268
  cache: "no-store"
1188
1269
  });
1189
1270
  if (!response.ok) {
@@ -1197,7 +1278,7 @@ function createDepositService(baseUrl, options) {
1197
1278
  );
1198
1279
  }
1199
1280
  const data = await response.json();
1200
- const deposits = Array.isArray(_optionalChain([data, 'optionalAccess', _36 => _36.deposits])) ? data.deposits : [];
1281
+ const deposits = Array.isArray(_optionalChain([data, 'optionalAccess', _36 => _36.deposits])) ? data.deposits.map(normalizeHistoryTiming) : [];
1201
1282
  const nextCursor = _nullishCoalesce(_nullishCoalesce(_optionalChain([data, 'optionalAccess', _37 => _37.nextCursor]), () => ( _optionalChain([data, 'optionalAccess', _38 => _38.next_cursor]))), () => ( null));
1202
1283
  debugLog(debug, scope, "fetchDepositHistory:success", {
1203
1284
  recipient: shortRef(params.recipient),
@@ -1233,7 +1314,7 @@ function createDepositService(baseUrl, options) {
1233
1314
  });
1234
1315
  const response = await fetch(url, {
1235
1316
  method: "GET",
1236
- headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, ),
1317
+ headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, ),
1237
1318
  cache: "no-store"
1238
1319
  });
1239
1320
  if (!response.ok) {
@@ -1278,36 +1359,46 @@ function createDepositService(baseUrl, options) {
1278
1359
  sourceToken: params.sourceToken,
1279
1360
  amount: params.amount
1280
1361
  });
1281
- try {
1282
- const response = await fetch(url, {
1283
- method: "POST",
1284
- headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, ),
1285
- body: JSON.stringify(body),
1286
- cache: "no-store"
1287
- });
1288
- if (!response.ok) {
1289
- debugLog(debug, scope, "getQuotePreview:unavailable", {
1290
- status: response.status
1362
+ return withPreflightTimeout("getQuotePreview", null, async (signal) => {
1363
+ try {
1364
+ const response = await fetch(url, {
1365
+ method: "POST",
1366
+ headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, ),
1367
+ body: JSON.stringify(body),
1368
+ cache: "no-store",
1369
+ signal
1291
1370
  });
1292
- return null;
1293
- }
1294
- const quote = parseQuotePreview(await response.json());
1295
- if (!quote) {
1296
- debugLog(debug, scope, "getQuotePreview:unavailable", {
1297
- status: response.status,
1298
- reason: "malformed"
1371
+ if (!response.ok) {
1372
+ const refusal = await readPolicyRefusal(response);
1373
+ if (refusal) {
1374
+ debugLog(debug, scope, "getQuotePreview:refused", {
1375
+ code: refusal.policyRefusal.code
1376
+ });
1377
+ return refusal;
1378
+ }
1379
+ debugLog(debug, scope, "getQuotePreview:unavailable", {
1380
+ status: response.status
1381
+ });
1382
+ return null;
1383
+ }
1384
+ const quote = parseQuotePreview(await response.json());
1385
+ if (!quote) {
1386
+ debugLog(debug, scope, "getQuotePreview:unavailable", {
1387
+ status: response.status,
1388
+ reason: "malformed"
1389
+ });
1390
+ return null;
1391
+ }
1392
+ debugLog(debug, scope, "getQuotePreview:success", {
1393
+ settlementLayer: quote.settlementLayer,
1394
+ totalUsd: quote.fees.total.usd
1299
1395
  });
1396
+ return quote;
1397
+ } catch (error) {
1398
+ debugError(debug, scope, "getQuotePreview:error", error);
1300
1399
  return null;
1301
1400
  }
1302
- debugLog(debug, scope, "getQuotePreview:success", {
1303
- settlementLayer: quote.settlementLayer,
1304
- totalUsd: quote.fees.total.usd
1305
- });
1306
- return quote;
1307
- } catch (error) {
1308
- debugError(debug, scope, "getQuotePreview:error", error);
1309
- return null;
1310
- }
1401
+ });
1311
1402
  },
1312
1403
  async preparePermitDeposit(params) {
1313
1404
  const url = apiUrl("/deposits/permit/prepare");
@@ -1318,88 +1409,98 @@ function createDepositService(baseUrl, options) {
1318
1409
  token: params.token,
1319
1410
  amount: params.amount
1320
1411
  });
1321
- try {
1322
- const response = await fetch(url, {
1323
- method: "POST",
1324
- headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, ),
1325
- body: JSON.stringify({ ...params, kind: "auto" }),
1326
- cache: "no-store"
1327
- });
1328
- if (!response.ok) {
1329
- debugLog(debug, scope, "preparePermitDeposit:unavailable", {
1330
- status: response.status
1331
- });
1332
- return null;
1333
- }
1334
- const data = await response.json();
1335
- if (!data || typeof data.available !== "boolean") {
1336
- debugLog(debug, scope, "preparePermitDeposit:unavailable", {
1337
- status: response.status,
1338
- reason: "malformed"
1412
+ return withPreflightTimeout("preparePermitDeposit", null, async (signal) => {
1413
+ try {
1414
+ const response = await fetch(url, {
1415
+ method: "POST",
1416
+ headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, ),
1417
+ body: JSON.stringify({ ...params, kind: "auto" }),
1418
+ cache: "no-store",
1419
+ signal
1339
1420
  });
1340
- return null;
1341
- }
1342
- if (data.available === false) {
1343
- const reason = data.reason;
1344
- if (reason !== "permit2-approval-required" && reason !== "unsupported-token" && reason !== "unsupported-owner") {
1421
+ if (!response.ok) {
1422
+ const refusal = await readPolicyRefusal(response);
1423
+ if (refusal) {
1424
+ debugLog(debug, scope, "preparePermitDeposit:refused", {
1425
+ code: refusal.policyRefusal.code
1426
+ });
1427
+ return refusal;
1428
+ }
1429
+ debugLog(debug, scope, "preparePermitDeposit:unavailable", {
1430
+ status: response.status
1431
+ });
1345
1432
  return null;
1346
1433
  }
1347
- debugLog(debug, scope, "preparePermitDeposit:unavailable", {
1348
- status: response.status,
1349
- reason
1350
- });
1351
- const approval = data.approval;
1352
- const parsedApproval = approval && typeof approval.token === "string" && typeof approval.spender === "string" && typeof approval.minimumAmount === "string" ? {
1353
- token: approval.token,
1354
- spender: approval.spender,
1355
- minimumAmount: approval.minimumAmount
1356
- } : void 0;
1357
- return {
1358
- available: false,
1359
- reason,
1360
- ...parsedApproval && { approval: parsedApproval }
1361
- };
1362
- }
1363
- const authorization = data.authorization;
1364
- if (!authorization || typeof authorization.typedData !== "object" || authorization.typedData === null || typeof authorization.nonce !== "string") {
1365
- return null;
1366
- }
1367
- if (authorization.kind === "erc3009" && typeof authorization.validAfter === "string" && typeof authorization.validBefore === "string") {
1368
- debugLog(debug, scope, "preparePermitDeposit:success", {
1369
- kind: authorization.kind,
1370
- nonce: authorization.nonce
1371
- });
1372
- return {
1373
- available: true,
1374
- authorization: {
1375
- kind: "erc3009",
1376
- typedData: authorization.typedData,
1377
- nonce: authorization.nonce,
1378
- validAfter: authorization.validAfter,
1379
- validBefore: authorization.validBefore
1434
+ const data = await response.json();
1435
+ if (!data || typeof data.available !== "boolean") {
1436
+ debugLog(debug, scope, "preparePermitDeposit:unavailable", {
1437
+ status: response.status,
1438
+ reason: "malformed"
1439
+ });
1440
+ return null;
1441
+ }
1442
+ if (data.available === false) {
1443
+ const reason = data.reason;
1444
+ if (reason !== "permit2-approval-required" && reason !== "unsupported-token" && reason !== "unsupported-owner") {
1445
+ return null;
1380
1446
  }
1381
- };
1382
- }
1383
- if ((authorization.kind === "erc2612" || authorization.kind === "permit2") && typeof authorization.deadline === "string") {
1384
- debugLog(debug, scope, "preparePermitDeposit:success", {
1385
- kind: authorization.kind,
1386
- nonce: authorization.nonce
1387
- });
1388
- return {
1389
- available: true,
1390
- authorization: {
1447
+ debugLog(debug, scope, "preparePermitDeposit:unavailable", {
1448
+ status: response.status,
1449
+ reason
1450
+ });
1451
+ const approval = data.approval;
1452
+ const parsedApproval = approval && typeof approval.token === "string" && typeof approval.spender === "string" && typeof approval.minimumAmount === "string" ? {
1453
+ token: approval.token,
1454
+ spender: approval.spender,
1455
+ minimumAmount: approval.minimumAmount
1456
+ } : void 0;
1457
+ return {
1458
+ available: false,
1459
+ reason,
1460
+ ...parsedApproval && { approval: parsedApproval }
1461
+ };
1462
+ }
1463
+ const authorization = data.authorization;
1464
+ if (!authorization || typeof authorization.typedData !== "object" || authorization.typedData === null || typeof authorization.nonce !== "string") {
1465
+ return null;
1466
+ }
1467
+ if (authorization.kind === "erc3009" && typeof authorization.validAfter === "string" && typeof authorization.validBefore === "string") {
1468
+ debugLog(debug, scope, "preparePermitDeposit:success", {
1391
1469
  kind: authorization.kind,
1392
- typedData: authorization.typedData,
1393
- nonce: authorization.nonce,
1394
- deadline: authorization.deadline
1395
- }
1396
- };
1470
+ nonce: authorization.nonce
1471
+ });
1472
+ return {
1473
+ available: true,
1474
+ authorization: {
1475
+ kind: "erc3009",
1476
+ typedData: authorization.typedData,
1477
+ nonce: authorization.nonce,
1478
+ validAfter: authorization.validAfter,
1479
+ validBefore: authorization.validBefore
1480
+ }
1481
+ };
1482
+ }
1483
+ if ((authorization.kind === "erc2612" || authorization.kind === "permit2") && typeof authorization.deadline === "string") {
1484
+ debugLog(debug, scope, "preparePermitDeposit:success", {
1485
+ kind: authorization.kind,
1486
+ nonce: authorization.nonce
1487
+ });
1488
+ return {
1489
+ available: true,
1490
+ authorization: {
1491
+ kind: authorization.kind,
1492
+ typedData: authorization.typedData,
1493
+ nonce: authorization.nonce,
1494
+ deadline: authorization.deadline
1495
+ }
1496
+ };
1497
+ }
1498
+ return null;
1499
+ } catch (error) {
1500
+ debugError(debug, scope, "preparePermitDeposit:error", error);
1501
+ return null;
1397
1502
  }
1398
- return null;
1399
- } catch (error) {
1400
- debugError(debug, scope, "preparePermitDeposit:error", error);
1401
- return null;
1402
- }
1503
+ });
1403
1504
  },
1404
1505
  async submitPermitDeposit(params) {
1405
1506
  const url = apiUrl("/deposits/permit");
@@ -1415,7 +1516,7 @@ function createDepositService(baseUrl, options) {
1415
1516
  try {
1416
1517
  response = await fetch(url, {
1417
1518
  method: "POST",
1418
- headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, ),
1519
+ headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, ),
1419
1520
  body: JSON.stringify(params)
1420
1521
  });
1421
1522
  } catch (error) {
@@ -1466,7 +1567,7 @@ function createDepositService(baseUrl, options) {
1466
1567
  try {
1467
1568
  const response = await fetch(url, {
1468
1569
  method: "GET",
1469
- headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, ),
1570
+ headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, ),
1470
1571
  cache: "no-store"
1471
1572
  });
1472
1573
  if (!response.ok) {
@@ -1498,7 +1599,7 @@ function createDepositService(baseUrl, options) {
1498
1599
  try {
1499
1600
  const response = await fetch(url, {
1500
1601
  method: "GET",
1501
- headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, ),
1602
+ headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, ),
1502
1603
  cache: "no-store"
1503
1604
  });
1504
1605
  if (!response.ok) {
@@ -1523,7 +1624,7 @@ function createDepositService(baseUrl, options) {
1523
1624
  });
1524
1625
  const response = await fetch(url, {
1525
1626
  method: "POST",
1526
- headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, ),
1627
+ headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, ),
1527
1628
  body: JSON.stringify(params)
1528
1629
  });
1529
1630
  if (!response.ok) {
@@ -1555,7 +1656,7 @@ function createDepositService(baseUrl, options) {
1555
1656
  });
1556
1657
  const response = await fetch(url, {
1557
1658
  method: "POST",
1558
- headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, ),
1659
+ headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, ),
1559
1660
  body: JSON.stringify(params)
1560
1661
  });
1561
1662
  if (!response.ok) {
@@ -1592,7 +1693,7 @@ function createDepositService(baseUrl, options) {
1592
1693
  debugLog(debug, scope, "getSwappedConnectExchanges:request");
1593
1694
  const response = await fetch(url, {
1594
1695
  method: "GET",
1595
- headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, ),
1696
+ headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, ),
1596
1697
  cache: "no-store"
1597
1698
  });
1598
1699
  if (!response.ok) {
@@ -1645,7 +1746,7 @@ function createDepositService(baseUrl, options) {
1645
1746
  try {
1646
1747
  const response = await fetch(url, {
1647
1748
  method: "GET",
1648
- headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, ),
1749
+ headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, ),
1649
1750
  cache: "no-store"
1650
1751
  });
1651
1752
  if (!response.ok) {
@@ -1708,9 +1809,11 @@ function createDepositService(baseUrl, options) {
1708
1809
  },
1709
1810
  getTopTokens() {
1710
1811
  if (!topTokensPromise) {
1711
- const attempt = requestTopTokens().then((tokens) => {
1712
- if (!tokens && topTokensPromise === attempt) topTokensPromise = null;
1713
- return tokens;
1812
+ const attempt = requestTopTokens().then((result) => {
1813
+ if (!result.ok && topTokensPromise === attempt) {
1814
+ topTokensPromise = null;
1815
+ }
1816
+ return result;
1714
1817
  });
1715
1818
  topTokensPromise = attempt;
1716
1819
  }
@@ -1731,7 +1834,7 @@ function createDepositService(baseUrl, options) {
1731
1834
  try {
1732
1835
  const response = await fetch(url, {
1733
1836
  method: "GET",
1734
- headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, ),
1837
+ headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, ),
1735
1838
  cache: "no-store"
1736
1839
  });
1737
1840
  if (!response.ok) {
@@ -1758,14 +1861,14 @@ function createDepositService(baseUrl, options) {
1758
1861
  );
1759
1862
  const response = await fetch(url, {
1760
1863
  method: "GET",
1761
- headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, ),
1864
+ headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, ),
1762
1865
  cache: "no-store"
1763
1866
  });
1764
1867
  if (!response.ok) return null;
1765
1868
  let body = null;
1766
1869
  try {
1767
1870
  body = await response.json();
1768
- } catch (e4) {
1871
+ } catch (e5) {
1769
1872
  return null;
1770
1873
  }
1771
1874
  if (!body || body.ok !== true) return null;
@@ -1946,6 +2049,60 @@ function useStableRpcUrls(rpcUrls) {
1946
2049
 
1947
2050
 
1948
2051
 
2052
+
2053
+ // src/core/deposit-bounds.ts
2054
+
2055
+ function findListed(options, chain, token) {
2056
+ const normalize2 = (value) => chain === "solana" ? value : value.toLowerCase();
2057
+ return _optionalChain([options, 'access', _71 => _71.tokens, 'access', _72 => _72[String(chain)], 'optionalAccess', _73 => _73.find, 'call', _74 => _74(
2058
+ (listed) => normalize2(listed.address) === normalize2(token)
2059
+ )]);
2060
+ }
2061
+ function isExcludedByRestrictedList(options, chain, token) {
2062
+ return Boolean(_optionalChain([options, 'optionalAccess', _75 => _75.restricted]) && !findListed(options, chain, token));
2063
+ }
2064
+ function findDepositBounds(options, chain, token) {
2065
+ if (!_optionalChain([options, 'optionalAccess', _76 => _76.restricted])) return void 0;
2066
+ const entry = findListed(options, chain, token);
2067
+ if (!entry || entry.minAmount === void 0 && entry.maxAmount === void 0) {
2068
+ return void 0;
2069
+ }
2070
+ return {
2071
+ symbol: entry.symbol,
2072
+ decimals: entry.decimals,
2073
+ ...entry.minAmount !== void 0 && { minAmount: BigInt(entry.minAmount) },
2074
+ ...entry.maxAmount !== void 0 && { maxAmount: BigInt(entry.maxAmount) }
2075
+ };
2076
+ }
2077
+ function boundMessage(bounds, bound) {
2078
+ const raw = _optionalChain([bounds, 'optionalAccess', _77 => _77[bound]]);
2079
+ if (!bounds || raw === void 0) return null;
2080
+ const amount = new Intl.NumberFormat("en-US", {
2081
+ maximumFractionDigits: Math.min(bounds.decimals, 20)
2082
+ }).format(Number(_viem.formatUnits.call(void 0, raw, bounds.decimals)));
2083
+ return `${bound === "minAmount" ? "Minimum" : "Maximum"} deposit is ${amount} ${bounds.symbol}`;
2084
+ }
2085
+ function depositBoundsViolation(bounds, units) {
2086
+ if (!bounds || units === null || units <= 0n) return null;
2087
+ if (bounds.minAmount !== void 0 && units < bounds.minAmount) {
2088
+ return boundMessage(bounds, "minAmount");
2089
+ }
2090
+ if (bounds.maxAmount !== void 0 && units > bounds.maxAmount) {
2091
+ return boundMessage(bounds, "maxAmount");
2092
+ }
2093
+ return null;
2094
+ }
2095
+ function describePolicyRefusal(refusal, bounds) {
2096
+ switch (refusal.code) {
2097
+ case "BALANCE-4":
2098
+ return _nullishCoalesce(boundMessage(bounds, "minAmount"), () => ( "This amount is below the minimum deposit"));
2099
+ case "BALANCE-3":
2100
+ return _nullishCoalesce(boundMessage(bounds, "maxAmount"), () => ( "This amount is above the maximum deposit"));
2101
+ default:
2102
+ return "This token isn't accepted for deposits";
2103
+ }
2104
+ }
2105
+
1949
2106
  // src/core/public-client.ts
1950
2107
 
1951
2108
  var clientCache = /* @__PURE__ */ new Map();
@@ -2017,7 +2174,7 @@ async function loadViemChains() {
2017
2174
  viemChainsPromise = Promise.resolve().then(() => _interopRequireWildcard(require("viem/chains"))).then((module) => {
2018
2175
  const map = /* @__PURE__ */ new Map();
2019
2176
  for (const value of Object.values(module)) {
2020
- if (value && typeof value === "object" && typeof value.id === "number" && _optionalChain([value, 'access', _71 => _71.rpcUrls, 'optionalAccess', _72 => _72.default, 'optionalAccess', _73 => _73.http, 'optionalAccess', _74 => _74.length])) {
2177
+ if (value && typeof value === "object" && typeof value.id === "number" && _optionalChain([value, 'access', _78 => _78.rpcUrls, 'optionalAccess', _79 => _79.default, 'optionalAccess', _80 => _80.http, 'optionalAccess', _81 => _81.length])) {
2021
2178
  const chain = value;
2022
2179
  const existing = map.get(chain.id);
2023
2180
  if (existing) existing.push(chain);
@@ -2031,7 +2188,7 @@ async function loadViemChains() {
2031
2188
  return viemChainsPromise;
2032
2189
  }
2033
2190
  function pickViemChain(candidates, chain) {
2034
- if (!_optionalChain([candidates, 'optionalAccess', _75 => _75.length])) return void 0;
2191
+ if (!_optionalChain([candidates, 'optionalAccess', _82 => _82.length])) return void 0;
2035
2192
  if (candidates.length === 1) return candidates[0];
2036
2193
  const sameNetworkClass = candidates.filter(
2037
2194
  (candidate) => Boolean(candidate.testnet) === chain.testnet
@@ -2047,10 +2204,10 @@ function pickViemChain(candidates, chain) {
2047
2204
  }
2048
2205
  function resolveRpcUrls(chain, override, viemChains) {
2049
2206
  const urls = [];
2050
- if (_optionalChain([override, 'optionalAccess', _76 => _76.trim, 'call', _77 => _77()])) urls.push(override.trim());
2207
+ if (_optionalChain([override, 'optionalAccess', _83 => _83.trim, 'call', _84 => _84()])) urls.push(override.trim());
2051
2208
  if (chain.publicRpcUrl) urls.push(chain.publicRpcUrl);
2052
2209
  if (chain.chainId !== null && chain.vmType === "evm") {
2053
- const http2 = _optionalChain([pickViemChain, 'call', _78 => _78(_optionalChain([viemChains, 'optionalAccess', _79 => _79.get, 'call', _80 => _80(chain.chainId)]), chain), 'optionalAccess', _81 => _81.rpcUrls, 'optionalAccess', _82 => _82.default, 'optionalAccess', _83 => _83.http]);
2210
+ const http2 = _optionalChain([pickViemChain, 'call', _85 => _85(_optionalChain([viemChains, 'optionalAccess', _86 => _86.get, 'call', _87 => _87(chain.chainId)]), chain), 'optionalAccess', _88 => _88.rpcUrls, 'optionalAccess', _89 => _89.default, 'optionalAccess', _90 => _90.http]);
2054
2211
  if (http2) urls.push(...http2);
2055
2212
  }
2056
2213
  return [...new Set(urls)];
@@ -2059,7 +2216,7 @@ function toViemChain(chain, override, viemChains) {
2059
2216
  if (chain.vmType !== "evm" || chain.chainId === null) return null;
2060
2217
  const rpcUrls = resolveRpcUrls(chain, override, viemChains);
2061
2218
  if (rpcUrls.length === 0) return null;
2062
- const bundled = pickViemChain(_optionalChain([viemChains, 'optionalAccess', _84 => _84.get, 'call', _85 => _85(chain.chainId)]), chain);
2219
+ const bundled = pickViemChain(_optionalChain([viemChains, 'optionalAccess', _91 => _91.get, 'call', _92 => _92(chain.chainId)]), chain);
2063
2220
  if (bundled) {
2064
2221
  if (rpcUrls[0] === bundled.rpcUrls.default.http[0]) return bundled;
2065
2222
  return _viem.defineChain.call(void 0, {
@@ -2090,7 +2247,7 @@ function toViemChains(catalog, overrides, viemChains) {
2090
2247
  for (const entry of catalog.all) {
2091
2248
  const chain = toViemChain(
2092
2249
  entry,
2093
- entry.chainId === null ? void 0 : _optionalChain([overrides, 'optionalAccess', _86 => _86[entry.chainId]]),
2250
+ entry.chainId === null ? void 0 : _optionalChain([overrides, 'optionalAccess', _93 => _93[entry.chainId]]),
2094
2251
  viemChains
2095
2252
  );
2096
2253
  if (chain) chains.push(chain);
@@ -2099,7 +2256,7 @@ function toViemChains(catalog, overrides, viemChains) {
2099
2256
  }
2100
2257
  function needsViemChains(catalog, overrides) {
2101
2258
  return catalog.all.some(
2102
- (chain) => chain.vmType === "evm" && chain.chainId !== null && !chain.publicRpcUrl && !_optionalChain([overrides, 'optionalAccess', _87 => _87[chain.chainId], 'optionalAccess', _88 => _88.trim, 'call', _89 => _89()])
2259
+ (chain) => chain.vmType === "evm" && chain.chainId !== null && !chain.publicRpcUrl && !_optionalChain([overrides, 'optionalAccess', _94 => _94[chain.chainId], 'optionalAccess', _95 => _95.trim, 'call', _96 => _96()])
2103
2260
  );
2104
2261
  }
2105
2262
 
@@ -2110,6 +2267,9 @@ var EMPTY = {
2110
2267
  viemChains: null,
2111
2268
  isLoading: true,
2112
2269
  shortlist: null,
2270
+ depositOptions: { status: "loading" },
2271
+ retryDepositOptions: () => {
2272
+ },
2113
2273
  clientCapableChainIds: null
2114
2274
  };
2115
2275
  var ChainCatalogContext = _react.createContext.call(void 0, EMPTY);
@@ -2175,9 +2335,9 @@ function publishRuntimeChainMeta(catalog) {
2175
2335
  name: chain.name,
2176
2336
  iconUrl: _nullishCoalesce(chain.iconUrl, () => ( void 0)),
2177
2337
  nativeSymbol: chain.nativeToken.symbol,
2178
- explorerUrl: _optionalChain([chain, 'access', _90 => _90.explorer, 'optionalAccess', _91 => _91.url]),
2179
- explorerTxPath: _optionalChain([chain, 'access', _92 => _92.explorer, 'optionalAccess', _93 => _93.txPath]),
2180
- explorerAddressPath: _optionalChain([chain, 'access', _94 => _94.explorer, 'optionalAccess', _95 => _95.addressPath])
2338
+ explorerUrl: _optionalChain([chain, 'access', _97 => _97.explorer, 'optionalAccess', _98 => _98.url]),
2339
+ explorerTxPath: _optionalChain([chain, 'access', _99 => _99.explorer, 'optionalAccess', _100 => _100.txPath]),
2340
+ explorerAddressPath: _optionalChain([chain, 'access', _101 => _101.explorer, 'optionalAccess', _102 => _102.addressPath])
2181
2341
  }));
2182
2342
  })
2183
2343
  );
@@ -2250,7 +2410,7 @@ function useTargetTokens() {
2250
2410
  const { catalog, shortlist } = useChainCatalog();
2251
2411
  return _react.useMemo.call(void 0, () => {
2252
2412
  return (chainId) => {
2253
- const fromShortlist = _optionalChain([shortlist, 'optionalAccess', _96 => _96[String(chainId)]]);
2413
+ const fromShortlist = _optionalChain([shortlist, 'optionalAccess', _103 => _103[String(chainId)]]);
2254
2414
  if (fromShortlist) {
2255
2415
  return fromShortlist.map((token) => ({
2256
2416
  symbol: token.symbol,
@@ -2258,8 +2418,8 @@ function useTargetTokens() {
2258
2418
  decimals: token.decimals
2259
2419
  }));
2260
2420
  }
2261
- const entry = _optionalChain([catalog, 'optionalAccess', _97 => _97.byChainId, 'access', _98 => _98.get, 'call', _99 => _99(chainId)]);
2262
- return Array.isArray(_optionalChain([entry, 'optionalAccess', _100 => _100.supportedTokens])) ? entry.supportedTokens.map((token) => ({
2421
+ const entry = _optionalChain([catalog, 'optionalAccess', _104 => _104.byChainId, 'access', _105 => _105.get, 'call', _106 => _106(chainId)]);
2422
+ return Array.isArray(_optionalChain([entry, 'optionalAccess', _107 => _107.supportedTokens])) ? entry.supportedTokens.map((token) => ({
2263
2423
  symbol: token.symbol,
2264
2424
  address: token.address,
2265
2425
  decimals: token.decimals
@@ -2267,6 +2427,48 @@ function useTargetTokens() {
2267
2427
  };
2268
2428
  }, [catalog, shortlist]);
2269
2429
  }
2430
+ function createDepositOffer(state, retry) {
2431
+ const options = state.status === "ready" ? state.options : null;
2432
+ const restricted = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _108 => _108.restricted]), () => ( false));
2433
+ const listed = (chain) => _optionalChain([options, 'optionalAccess', _109 => _109.tokens, 'access', _110 => _110[String(chain)]]);
2434
+ const isChainOffered = (chain) => {
2435
+ if (!options) return false;
2436
+ const entry = listed(chain);
2437
+ return restricted ? (_nullishCoalesce(_optionalChain([entry, 'optionalAccess', _111 => _111.length]), () => ( 0))) > 0 : _optionalChain([entry, 'optionalAccess', _112 => _112.length]) !== 0;
2438
+ };
2439
+ return {
2440
+ status: state.status,
2441
+ restricted,
2442
+ retry,
2443
+ tokensFor: (chain) => {
2444
+ if (!options) return [];
2445
+ const entry = listed(chain);
2446
+ return restricted ? _nullishCoalesce(entry, () => ( [])) : entry;
2447
+ },
2448
+ isChainOffered
2449
+ };
2450
+ }
2451
+ function useDepositOffer() {
2452
+ const { depositOptions, retryDepositOptions } = useChainCatalog();
2453
+ return _react.useMemo.call(void 0,
2454
+ () => createDepositOffer(depositOptions, retryDepositOptions),
2455
+ [depositOptions, retryDepositOptions]
2456
+ );
2457
+ }
2458
+ function useDepositBounds() {
2459
+ const { depositOptions } = useChainCatalog();
2460
+ return _react.useMemo.call(void 0, () => {
2461
+ const options = depositOptions.status === "ready" ? depositOptions.options : null;
2462
+ return (chain, token) => findDepositBounds(options, chain, token);
2463
+ }, [depositOptions]);
2464
+ }
2465
+ function useRestrictedListExclusion() {
2466
+ const { depositOptions } = useChainCatalog();
2467
+ return _react.useMemo.call(void 0, () => {
2468
+ const options = depositOptions.status === "ready" ? depositOptions.options : null;
2469
+ return (chain, token) => isExcludedByRestrictedList(options, chain, token);
2470
+ }, [depositOptions]);
2471
+ }
2270
2472
  function useIsDepositChain() {
2271
2473
  const ids = useDepositChainIds();
2272
2474
  const { clientCapableChainIds } = useChainCatalog();
@@ -2282,7 +2484,7 @@ function useChainName() {
2282
2484
  if (!catalog) return _chunkOY5N3E6Lcjs.getChainName.call(void 0, chainId);
2283
2485
  const key = catalogKeyForChain(chainId);
2284
2486
  const entry = typeof key === "number" ? catalog.byChainId.get(key) : catalog.byCaip2.get(key);
2285
- return _nullishCoalesce(_optionalChain([entry, 'optionalAccess', _101 => _101.name]), () => ( _chunkOY5N3E6Lcjs.getChainName.call(void 0, chainId)));
2487
+ return _nullishCoalesce(_optionalChain([entry, 'optionalAccess', _113 => _113.name]), () => ( _chunkOY5N3E6Lcjs.getChainName.call(void 0, chainId)));
2286
2488
  };
2287
2489
  }, [catalog]);
2288
2490
  }
@@ -2306,7 +2508,7 @@ function useExplorerTxUrl() {
2306
2508
  return (chainId, txHash) => {
2307
2509
  if (chainId === "hypercore") return _chunkOY5N3E6Lcjs.getExplorerTxUrl.call(void 0, chainId, txHash);
2308
2510
  const key = catalog ? catalogKeyForChain(chainId) : void 0;
2309
- const entry = key === void 0 ? void 0 : typeof key === "number" ? _optionalChain([catalog, 'optionalAccess', _102 => _102.byChainId, 'access', _103 => _103.get, 'call', _104 => _104(key)]) : _optionalChain([catalog, 'optionalAccess', _105 => _105.byCaip2, 'access', _106 => _106.get, 'call', _107 => _107(key)]);
2511
+ const entry = key === void 0 ? void 0 : typeof key === "number" ? _optionalChain([catalog, 'optionalAccess', _114 => _114.byChainId, 'access', _115 => _115.get, 'call', _116 => _116(key)]) : _optionalChain([catalog, 'optionalAccess', _117 => _117.byCaip2, 'access', _118 => _118.get, 'call', _119 => _119(key)]);
2310
2512
  return _nullishCoalesce(catalogExplorerTxUrl(entry, txHash), () => ( _chunkOY5N3E6Lcjs.getExplorerTxUrl.call(void 0, chainId, txHash)));
2311
2513
  };
2312
2514
  }, [catalog]);
@@ -2359,19 +2561,36 @@ function ChainCatalogProvider({
2359
2561
  const chains = toViemChains(catalog, overrides, viemChains);
2360
2562
  if (chains.length > 0) setRuntimeChains(chains);
2361
2563
  }, [catalog, viemChains, overrides]);
2362
- const [shortlist, setShortlist] = _react.useState.call(void 0, null);
2564
+ const [depositOptions, setDepositOptions] = _react.useState.call(void 0, {
2565
+ status: "loading"
2566
+ });
2567
+ const [depositOptionsAttempt, setDepositOptionsAttempt] = _react.useState.call(void 0, 0);
2363
2568
  _react.useEffect.call(void 0, () => {
2364
2569
  let active = true;
2365
- setShortlist(null);
2366
- service.getTopTokens().then((tokens) => {
2367
- if (!active || !tokens) return;
2368
- _chunkOY5N3E6Lcjs.publishShortlistTokens.call(void 0, tokens);
2369
- setShortlist(tokens);
2370
- });
2570
+ setDepositOptions({ status: "loading" });
2571
+ service.getTopTokens().then(
2572
+ (result) => {
2573
+ if (!active) return;
2574
+ if (!_optionalChain([result, 'optionalAccess', _120 => _120.ok])) {
2575
+ setDepositOptions({ status: "error" });
2576
+ return;
2577
+ }
2578
+ _chunkOY5N3E6Lcjs.publishShortlistTokens.call(void 0, result.options.tokens);
2579
+ setDepositOptions({ status: "ready", options: result.options });
2580
+ },
2581
+ () => {
2582
+ if (active) setDepositOptions({ status: "error" });
2583
+ }
2584
+ );
2371
2585
  return () => {
2372
2586
  active = false;
2373
2587
  };
2374
- }, [service]);
2588
+ }, [service, depositOptionsAttempt]);
2589
+ const retryDepositOptions = _react.useCallback.call(void 0,
2590
+ () => setDepositOptionsAttempt((attempt) => attempt + 1),
2591
+ []
2592
+ );
2593
+ const shortlist = depositOptions.status === "ready" ? depositOptions.options.tokens : null;
2375
2594
  const clientCapableChainIds = _react.useMemo.call(void 0, () => {
2376
2595
  if (!catalog) return null;
2377
2596
  return new Set(
@@ -2384,9 +2603,19 @@ function ChainCatalogProvider({
2384
2603
  viemChains,
2385
2604
  isLoading,
2386
2605
  shortlist,
2606
+ depositOptions,
2607
+ retryDepositOptions,
2387
2608
  clientCapableChainIds
2388
2609
  }),
2389
- [catalog, viemChains, isLoading, shortlist, clientCapableChainIds]
2610
+ [
2611
+ catalog,
2612
+ viemChains,
2613
+ isLoading,
2614
+ shortlist,
2615
+ depositOptions,
2616
+ retryDepositOptions,
2617
+ clientCapableChainIds
2618
+ ]
2390
2619
  );
2391
2620
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ChainCatalogContext.Provider, { value, children });
2392
2621
  }
@@ -2467,7 +2696,7 @@ function createIngestTransport(options) {
2467
2696
  function report(reason, status) {
2468
2697
  try {
2469
2698
  onFailure({ reason, status, droppedEvents: dropped });
2470
- } catch (e5) {
2699
+ } catch (e6) {
2471
2700
  }
2472
2701
  }
2473
2702
  function drop(batch, reason, status) {
@@ -2521,10 +2750,10 @@ function createIngestTransport(options) {
2521
2750
  }
2522
2751
  function interruptForUnload() {
2523
2752
  for (const wake of [...sleepers]) wake();
2524
- _optionalChain([mintAbort, 'optionalAccess', _108 => _108.abort, 'call', _109 => _109()]);
2753
+ _optionalChain([mintAbort, 'optionalAccess', _121 => _121.abort, 'call', _122 => _122()]);
2525
2754
  }
2526
2755
  function retryDelay(response, attempt) {
2527
- const seconds = Number(_optionalChain([response, 'access', _110 => _110.headers, 'optionalAccess', _111 => _111.get, 'optionalCall', _112 => _112("Retry-After")]));
2756
+ const seconds = Number(_optionalChain([response, 'access', _123 => _123.headers, 'optionalAccess', _124 => _124.get, 'optionalCall', _125 => _125("Retry-After")]));
2528
2757
  if (Number.isFinite(seconds) && seconds > 0) {
2529
2758
  return Math.min(seconds * 1e3, MAX_BACKOFF_MS);
2530
2759
  }
@@ -2539,10 +2768,10 @@ function createIngestTransport(options) {
2539
2768
  try {
2540
2769
  response = await fetchImpl(mintUrl, {
2541
2770
  method: "POST",
2542
- headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, ),
2543
- signal: _optionalChain([controller, 'optionalAccess', _113 => _113.signal])
2771
+ headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, ),
2772
+ signal: _optionalChain([controller, 'optionalAccess', _126 => _126.signal])
2544
2773
  });
2545
- } catch (e6) {
2774
+ } catch (e7) {
2546
2775
  if (urgency !== DISMISSAL) {
2547
2776
  mintFailures += 1;
2548
2777
  mintBackoffUntil = now() + backoff(mintFailures);
@@ -2570,7 +2799,7 @@ function createIngestTransport(options) {
2570
2799
  token = { value, expiresAt };
2571
2800
  mintFailures = 0;
2572
2801
  mintBackoffUntil = 0;
2573
- } catch (e7) {
2802
+ } catch (e8) {
2574
2803
  mintUnavailable = true;
2575
2804
  report("token_unavailable", response.status);
2576
2805
  }
@@ -2610,7 +2839,7 @@ function createIngestTransport(options) {
2610
2839
  body: bodyOf(batch),
2611
2840
  keepalive: true
2612
2841
  });
2613
- } catch (e8) {
2842
+ } catch (e9) {
2614
2843
  if (terminal || attempt >= MAX_ATTEMPTS) {
2615
2844
  return drop(batch, "network");
2616
2845
  }
@@ -2715,7 +2944,7 @@ function createIngestTransport(options) {
2715
2944
  }
2716
2945
  },
2717
2946
  flush(flushOptions) {
2718
- const dismissal = _nullishCoalesce(_optionalChain([flushOptions, 'optionalAccess', _114 => _114.terminal]), () => ( false));
2947
+ const dismissal = _nullishCoalesce(_optionalChain([flushOptions, 'optionalAccess', _127 => _127.terminal]), () => ( false));
2719
2948
  if (disposed && !dismissal) return;
2720
2949
  clearFlushTimer();
2721
2950
  void run(dismissal ? DISMISSAL : IDLE);
@@ -2730,11 +2959,11 @@ function createIngestTransport(options) {
2730
2959
  };
2731
2960
  }
2732
2961
  function randomUuid() {
2733
- if (typeof _optionalChain([globalThis, 'access', _115 => _115.crypto, 'optionalAccess', _116 => _116.randomUUID]) === "function") {
2962
+ if (typeof _optionalChain([globalThis, 'access', _128 => _128.crypto, 'optionalAccess', _129 => _129.randomUUID]) === "function") {
2734
2963
  return globalThis.crypto.randomUUID();
2735
2964
  }
2736
2965
  const bytes = new Uint8Array(16);
2737
- _optionalChain([globalThis, 'access', _117 => _117.crypto, 'optionalAccess', _118 => _118.getRandomValues, 'optionalCall', _119 => _119(bytes)]);
2966
+ _optionalChain([globalThis, 'access', _130 => _130.crypto, 'optionalAccess', _131 => _131.getRandomValues, 'optionalCall', _132 => _132(bytes)]);
2738
2967
  if (!bytes.some(Boolean)) {
2739
2968
  for (let index = 0; index < bytes.length; index += 1) {
2740
2969
  bytes[index] = Math.floor(Math.random() * 256);
@@ -2748,9 +2977,9 @@ function randomUuid() {
2748
2977
  function resolveProxyOrigin(backendUrl) {
2749
2978
  if (!backendUrl.trim()) return null;
2750
2979
  try {
2751
- const { origin } = new URL(backendUrl, _optionalChain([globalThis, 'access', _120 => _120.location, 'optionalAccess', _121 => _121.href]));
2980
+ const { origin } = new URL(backendUrl, _optionalChain([globalThis, 'access', _133 => _133.location, 'optionalAccess', _134 => _134.href]));
2752
2981
  return origin.startsWith("http") ? origin : null;
2753
- } catch (e9) {
2982
+ } catch (e10) {
2754
2983
  return null;
2755
2984
  }
2756
2985
  }
@@ -2800,13 +3029,13 @@ function AnalyticsSession(props) {
2800
3029
  type: "analytics_ingest_failure",
2801
3030
  session_id: sessionIdRef.current,
2802
3031
  modal,
2803
- widget_version: _chunk5CM3ZQ5Ucjs.MODAL_VERSION,
3032
+ widget_version: _chunkN6JJG57Rcjs.MODAL_VERSION,
2804
3033
  timestamp: nowRef.current().toISOString(),
2805
3034
  reason,
2806
3035
  ...status === void 0 ? {} : { status },
2807
3036
  dropped_events: droppedEvents
2808
3037
  };
2809
- _optionalChain([onEventRef, 'access', _122 => _122.current, 'optionalCall', _123 => _123(event)]);
3038
+ _optionalChain([onEventRef, 'access', _135 => _135.current, 'optionalCall', _136 => _136(event)]);
2810
3039
  },
2811
3040
  [modal]
2812
3041
  );
@@ -2828,7 +3057,7 @@ function AnalyticsSession(props) {
2828
3057
  proxyOrigin,
2829
3058
  sessionId: sessionIdRef.current,
2830
3059
  modal,
2831
- widgetVersion: _chunk5CM3ZQ5Ucjs.MODAL_VERSION,
3060
+ widgetVersion: _chunkN6JJG57Rcjs.MODAL_VERSION,
2832
3061
  sessionProperties: sessionPropertiesRef.current,
2833
3062
  onFailure: (failure) => emitFailure(failure),
2834
3063
  fetchImpl: props.fetchImpl,
@@ -2845,10 +3074,10 @@ function AnalyticsSession(props) {
2845
3074
  const enqueue = _react.useCallback.call(void 0,
2846
3075
  (event) => {
2847
3076
  try {
2848
- _optionalChain([ingestRef, 'access', _124 => _124.current, 'optionalAccess', _125 => _125.transport, 'optionalAccess', _126 => _126.enqueue, 'call', _127 => _127(
3077
+ _optionalChain([ingestRef, 'access', _137 => _137.current, 'optionalAccess', _138 => _138.transport, 'optionalAccess', _139 => _139.enqueue, 'call', _140 => _140(
2849
3078
  event
2850
3079
  )]);
2851
- } catch (e10) {
3080
+ } catch (e11) {
2852
3081
  }
2853
3082
  },
2854
3083
  []
@@ -2884,12 +3113,12 @@ function AnalyticsSession(props) {
2884
3113
  ...payload,
2885
3114
  session_id: sessionIdRef.current,
2886
3115
  modal,
2887
- widget_version: _chunk5CM3ZQ5Ucjs.MODAL_VERSION,
3116
+ widget_version: _chunkN6JJG57Rcjs.MODAL_VERSION,
2888
3117
  timestamp: nowRef.current().toISOString(),
2889
3118
  session_properties: sessionPropertiesRef.current,
2890
3119
  funding_method: fundingMethod
2891
3120
  };
2892
- _optionalChain([onEventRef, 'access', _128 => _128.current, 'optionalCall', _129 => _129(
3121
+ _optionalChain([onEventRef, 'access', _141 => _141.current, 'optionalCall', _142 => _142(
2893
3122
  event
2894
3123
  )]);
2895
3124
  enqueue(event);
@@ -2903,11 +3132,11 @@ function AnalyticsSession(props) {
2903
3132
  ...payload,
2904
3133
  session_id: sessionIdRef.current,
2905
3134
  modal,
2906
- widget_version: _chunk5CM3ZQ5Ucjs.MODAL_VERSION,
3135
+ widget_version: _chunkN6JJG57Rcjs.MODAL_VERSION,
2907
3136
  timestamp: nowRef.current().toISOString(),
2908
3137
  session_properties: sessionPropertiesRef.current
2909
3138
  };
2910
- _optionalChain([onEventRef, 'access', _130 => _130.current, 'optionalCall', _131 => _131(event)]);
3139
+ _optionalChain([onEventRef, 'access', _143 => _143.current, 'optionalCall', _144 => _144(event)]);
2911
3140
  enqueue(event);
2912
3141
  },
2913
3142
  [enqueue, modal, nowRef, onEventRef]
@@ -2919,11 +3148,11 @@ function AnalyticsSession(props) {
2919
3148
  ...payload,
2920
3149
  session_id: sessionIdRef.current,
2921
3150
  modal,
2922
- widget_version: _chunk5CM3ZQ5Ucjs.MODAL_VERSION,
3151
+ widget_version: _chunkN6JJG57Rcjs.MODAL_VERSION,
2923
3152
  timestamp: nowRef.current().toISOString(),
2924
3153
  session_properties: sessionPropertiesRef.current
2925
3154
  };
2926
- _optionalChain([onEventRef, 'access', _132 => _132.current, 'optionalCall', _133 => _133(event)]);
3155
+ _optionalChain([onEventRef, 'access', _145 => _145.current, 'optionalCall', _146 => _146(event)]);
2927
3156
  enqueue(event);
2928
3157
  },
2929
3158
  [enqueue, modal, nowRef, onEventRef]
@@ -2986,17 +3215,38 @@ function recoveryFailureCause(sourceChainName) {
2986
3215
  }
2987
3216
 
2988
3217
  // src/core/history-status.ts
2989
- function normalizeStatus(raw, isSpam) {
3218
+ var UNKNOWN = ["pending", false, []];
3219
+ var STATUS_FACTS = [
3220
+ // `delayed` is held up but still coming on the corridor's schedule.
3221
+ ["pending", true, ["pending", "delayed"]],
3222
+ // Nothing emits `submitted` or `bridging`; they are here so the badge and
3223
+ // the arrival line cannot diverge should a row ever carry them.
3224
+ ["processing", true, ["processing", "submitted", "bridging"]],
3225
+ ["completed", false, ["completed", "complete", "bridge-complete", "processed"]],
3226
+ // `rejected` is recoverable upstream exactly like `failed`, so it must not
3227
+ // read as Pending — a row offering recovery would otherwise claim to still
3228
+ // be on its way.
3229
+ ["failed", false, ["failed", "error", "bridge-failed", "rejected"]],
3230
+ // Where a recovered deposit lands. Terminal and not recoverable again.
3231
+ ["refunded", false, ["refunded"]],
3232
+ // These read Pending but are not arriving: the deposit is bound for a refund
3233
+ // or for manual reconciliation rather than for the recipient, so an arrival
3234
+ // expectation would be a claim about a corridor it never enters.
3235
+ ["pending", false, ["ignored", "expecting_refund", "reconciliation_required"]]
3236
+ ];
3237
+ function lookup(raw) {
2990
3238
  const lower = raw.toLowerCase();
2991
- if (lower === "completed" || lower === "complete" || lower === "bridge-complete" || lower === "processed")
2992
- return "completed";
2993
- if (lower === "failed" || lower === "error" || lower === "bridge-failed" || lower === "rejected") {
2994
- return isSpam ? "spam" : "failed";
2995
- }
2996
- if (lower === "refunded") return "refunded";
2997
- if (lower === "processing" || lower === "submitted" || lower === "bridging")
2998
- return "processing";
2999
- return "pending";
3239
+ return _nullishCoalesce(STATUS_FACTS.find((facts) => facts[2].includes(lower)), () => ( UNKNOWN));
3240
+ }
3241
+ function normalizeStatus(raw, isSpam) {
3242
+ const [badge] = lookup(raw);
3243
+ return isSpam && badge === "failed" ? "spam" : badge;
3244
+ }
3245
+ function isInFlight(status) {
3246
+ return status === "pending" || status === "processing";
3247
+ }
3248
+ function expectsArrival(raw) {
3249
+ return lookup(raw)[1];
3000
3250
  }
3001
3251
  var STATUS_LABEL = {
3002
3252
  pending: "Pending",
@@ -3008,7 +3258,7 @@ var STATUS_LABEL = {
3008
3258
  };
3009
3259
  function filterVisibleDeposits(deposits) {
3010
3260
  const sourceHashes = new Set(
3011
- deposits.map((d) => _optionalChain([d, 'access', _134 => _134.sourceTxHash, 'optionalAccess', _135 => _135.toLowerCase, 'call', _136 => _136()])).filter((h) => Boolean(h))
3261
+ deposits.map((d) => _optionalChain([d, 'access', _147 => _147.sourceTxHash, 'optionalAccess', _148 => _148.toLowerCase, 'call', _149 => _149()])).filter((h) => Boolean(h))
3012
3262
  );
3013
3263
  return deposits.filter(
3014
3264
  (d) => !(d.txHash && sourceHashes.has(d.txHash.toLowerCase()))
@@ -3016,20 +3266,37 @@ function filterVisibleDeposits(deposits) {
3016
3266
  }
3017
3267
 
3018
3268
  // src/core/history-badge.ts
3019
- function deriveHistoryBadge(deposits, { recipient, canRecover }) {
3269
+ var RECOVERY_INDICATOR_WINDOW_MS = 30 * 24 * 60 * 60 * 1e3;
3270
+ function deriveHistoryBadgeState(deposits, {
3271
+ recipient,
3272
+ canRecover,
3273
+ evaluatedAt = Date.now()
3274
+ }) {
3020
3275
  const visible = filterVisibleDeposits(deposits);
3021
3276
  if (canRecover) {
3022
- const needsYou = visible.filter(
3023
- (row) => toRecoverableDeposit(row, { recipient }) !== null
3024
- ).length;
3025
- if (needsYou > 0) return { state: "needs-you", count: needsYou };
3026
- }
3027
- const inProgress = visible.filter((row) => {
3028
- const status = normalizeStatus(row.status, row.isSpam);
3029
- return status === "pending" || status === "processing";
3030
- }).length;
3031
- if (inProgress > 0) return { state: "progress", count: inProgress };
3032
- return null;
3277
+ let count = 0;
3278
+ let nextExpiryAt = null;
3279
+ for (const row of visible) {
3280
+ if (toRecoverableDeposit(row, { recipient }) === null) continue;
3281
+ const expiryAt = Date.parse(_nullishCoalesce(row.createdAt, () => ( ""))) + RECOVERY_INDICATOR_WINDOW_MS;
3282
+ if (!(evaluatedAt < expiryAt)) continue;
3283
+ count += 1;
3284
+ nextExpiryAt = nextExpiryAt === null ? expiryAt : Math.min(nextExpiryAt, expiryAt);
3285
+ }
3286
+ if (count > 0) {
3287
+ return {
3288
+ badge: { state: "needs-you", count },
3289
+ nextExpiryAt
3290
+ };
3291
+ }
3292
+ }
3293
+ const inProgress = visible.filter(
3294
+ (row) => isInFlight(normalizeStatus(row.status, row.isSpam))
3295
+ ).length;
3296
+ return {
3297
+ badge: inProgress > 0 ? { state: "progress", count: inProgress } : null,
3298
+ nextExpiryAt: null
3299
+ };
3033
3300
  }
3034
3301
  function historyBadgeAriaLabel(badge) {
3035
3302
  if (!badge) return "Deposit history";
@@ -3109,7 +3376,7 @@ function CdnIcon({
3109
3376
  }
3110
3377
  const isLoading = loadedSrc !== src;
3111
3378
  const settleIfAlreadyComplete = (el) => {
3112
- if (_optionalChain([el, 'optionalAccess', _137 => _137.complete])) setLoadedSrc(src);
3379
+ if (_optionalChain([el, 'optionalAccess', _150 => _150.complete])) setLoadedSrc(src);
3113
3380
  };
3114
3381
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3115
3382
  "img",
@@ -3351,8 +3618,83 @@ function TokenIcon({ symbol, className, fallback }) {
3351
3618
  }
3352
3619
  TokenIcon.displayName = "TokenIcon";
3353
3620
 
3621
+ // src/core/deposit-timing.ts
3622
+ var FALLBACK_SOFT_DELAY_MS = {
3623
+ confirming: 90 * 1e3,
3624
+ received: 90 * 1e3,
3625
+ bridging: 4 * 60 * 1e3
3626
+ };
3627
+ var FALLBACK_ESCALATED_DELAY_MS = 10 * 60 * 1e3;
3628
+ var MIN_SOFT_DELAY_MS = 90 * 1e3;
3629
+ function formatExpectedDuration(seconds) {
3630
+ if (!Number.isFinite(seconds) || seconds <= 0) return "a few seconds";
3631
+ if (seconds < 60) {
3632
+ const whole = Math.round(seconds);
3633
+ return `~${whole} second${whole === 1 ? "" : "s"}`;
3634
+ }
3635
+ return `~${Math.max(1, Math.round(seconds / 60))} min`;
3636
+ }
3637
+ function resolveServedThresholds(timing) {
3638
+ const softMs = Math.max(timing.softDelaySeconds * 1e3, MIN_SOFT_DELAY_MS);
3639
+ return {
3640
+ softMs,
3641
+ escalatedMs: Math.max(timing.escalatedDelaySeconds * 1e3, softMs)
3642
+ };
3643
+ }
3644
+ function resolveServedTimingState(timing, totalElapsedMs) {
3645
+ const { softMs, escalatedMs } = resolveServedThresholds(timing);
3646
+ if (totalElapsedMs >= escalatedMs) return "escalated";
3647
+ if (totalElapsedMs >= softMs) return "soft";
3648
+ return "expected";
3649
+ }
3650
+ function resolvePendingTimingState({
3651
+ timing,
3652
+ totalElapsedMs,
3653
+ phaseId,
3654
+ phaseElapsedMs
3655
+ }) {
3656
+ if (timing) return resolveServedTimingState(timing, totalElapsedMs);
3657
+ if (totalElapsedMs >= FALLBACK_ESCALATED_DELAY_MS) return "escalated";
3658
+ if (phaseId && phaseElapsedMs >= FALLBACK_SOFT_DELAY_MS[phaseId]) {
3659
+ return "soft";
3660
+ }
3661
+ return "expected";
3662
+ }
3663
+ var STATE_ORDER = {
3664
+ expected: 0,
3665
+ soft: 1,
3666
+ escalated: 2
3667
+ };
3668
+ function advancePendingTimingState(previous, next) {
3669
+ return STATE_ORDER[next] > STATE_ORDER[previous] ? next : previous;
3670
+ }
3671
+
3672
+ // src/core/history-timing.ts
3673
+ function resolveHistoryTiming({
3674
+ status,
3675
+ timing,
3676
+ createdAt,
3677
+ nowMs
3678
+ }) {
3679
+ if (!expectsArrival(status) || !timing || !createdAt) {
3680
+ return void 0;
3681
+ }
3682
+ const createdAtMs = Date.parse(createdAt);
3683
+ if (!Number.isFinite(createdAtMs)) return void 0;
3684
+ const elapsedMs = Math.max(0, nowMs - createdAtMs);
3685
+ const state = resolveServedTimingState(timing, elapsedMs);
3686
+ const { softMs, escalatedMs } = resolveServedThresholds(timing);
3687
+ const nextTransitionAtMs = state === "expected" ? createdAtMs + softMs : state === "soft" ? createdAtMs + escalatedMs : void 0;
3688
+ return {
3689
+ state,
3690
+ expectedDuration: formatExpectedDuration(timing.expectedSeconds),
3691
+ ...nextTransitionAtMs !== void 0 ? { nextTransitionAtMs } : {}
3692
+ };
3693
+ }
3694
+
3354
3695
  // src/components/history/DepositHistoryPanel.tsx
3355
3696
 
3697
+ var MAX_TIMER_DELAY_MS = 2147e6;
3356
3698
  function shortenHash(hash) {
3357
3699
  if (hash.length <= 14) return hash;
3358
3700
  return `${hash.slice(0, 6)}\u2026${hash.slice(-4)}`;
@@ -3366,7 +3708,7 @@ function formatDate(iso) {
3366
3708
  month: "short",
3367
3709
  year: "numeric"
3368
3710
  });
3369
- } catch (e11) {
3711
+ } catch (e12) {
3370
3712
  return iso;
3371
3713
  }
3372
3714
  }
@@ -3433,7 +3775,7 @@ function formatAmount(rawAmount, token, chainId) {
3433
3775
  let frac = fracStr.slice(0, 5).replace(/0+$/, "");
3434
3776
  if (frac.length < 2) frac = frac.padEnd(2, "0");
3435
3777
  return `${whole}.${frac}`;
3436
- } catch (e12) {
3778
+ } catch (e13) {
3437
3779
  return rawAmount;
3438
3780
  }
3439
3781
  }
@@ -3456,7 +3798,7 @@ function DepositHistoryPanel({
3456
3798
  }) {
3457
3799
  const rootRef = _react.useRef.call(void 0, null);
3458
3800
  _react.useEffect.call(void 0, () => {
3459
- _optionalChain([rootRef, 'access', _138 => _138.current, 'optionalAccess', _139 => _139.toggleAttribute, 'call', _140 => _140("inert", Boolean(obscured))]);
3801
+ _optionalChain([rootRef, 'access', _151 => _151.current, 'optionalAccess', _152 => _152.toggleAttribute, 'call', _153 => _153("inert", Boolean(obscured))]);
3460
3802
  }, [obscured]);
3461
3803
  const handleKeyDown = _react.useCallback.call(void 0,
3462
3804
  (e) => {
@@ -3472,6 +3814,48 @@ function DepositHistoryPanel({
3472
3814
  () => filterVisibleDeposits(deposits),
3473
3815
  [deposits]
3474
3816
  );
3817
+ const [nowMs, setNowMs] = _react.useState.call(void 0, () => Date.now());
3818
+ const timingPresentations = _react.useMemo.call(void 0,
3819
+ () => visibleDeposits.map(
3820
+ (deposit) => resolveHistoryTiming({
3821
+ status: deposit.status,
3822
+ timing: deposit.timing,
3823
+ createdAt: deposit.createdAt,
3824
+ nowMs
3825
+ })
3826
+ ),
3827
+ [nowMs, visibleDeposits]
3828
+ );
3829
+ _react.useEffect.call(void 0, () => {
3830
+ setNowMs(Date.now());
3831
+ }, [visibleDeposits]);
3832
+ _react.useEffect.call(void 0, () => {
3833
+ const nextBoundary = timingPresentations.reduce(
3834
+ (earliest, presentation) => {
3835
+ const next = _optionalChain([presentation, 'optionalAccess', _154 => _154.nextTransitionAtMs]);
3836
+ if (next === void 0) return earliest;
3837
+ return earliest === void 0 || next < earliest ? next : earliest;
3838
+ },
3839
+ void 0
3840
+ );
3841
+ if (nextBoundary === void 0) return;
3842
+ let timeout;
3843
+ const updateAtBoundary = () => {
3844
+ const current = Date.now();
3845
+ if (current < nextBoundary) {
3846
+ timeout = setTimeout(
3847
+ updateAtBoundary,
3848
+ Math.min(nextBoundary - current, MAX_TIMER_DELAY_MS)
3849
+ );
3850
+ return;
3851
+ }
3852
+ setNowMs(current);
3853
+ };
3854
+ updateAtBoundary();
3855
+ return () => {
3856
+ if (timeout !== void 0) clearTimeout(timeout);
3857
+ };
3858
+ }, [timingPresentations]);
3475
3859
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3476
3860
  "div",
3477
3861
  {
@@ -3548,6 +3932,7 @@ function DepositHistoryPanel({
3548
3932
  HistoryCard,
3549
3933
  {
3550
3934
  deposit,
3935
+ timing: timingPresentations[i],
3551
3936
  position: i,
3552
3937
  recipient,
3553
3938
  onRecover,
@@ -3575,6 +3960,7 @@ function DepositHistoryPanel({
3575
3960
  }
3576
3961
  function HistoryCard({
3577
3962
  deposit,
3963
+ timing,
3578
3964
  position,
3579
3965
  recipient,
3580
3966
  onRecover,
@@ -3608,7 +3994,7 @@ function HistoryCard({
3608
3994
  setExpanded(next);
3609
3995
  const depositId = _nullishCoalesce(deposit.id, () => ( deposit.txHash));
3610
3996
  if (!next || !depositId) return;
3611
- _optionalChain([onRowView, 'optionalCall', _141 => _141({
3997
+ _optionalChain([onRowView, 'optionalCall', _155 => _155({
3612
3998
  depositId,
3613
3999
  status,
3614
4000
  recoverable: eligible !== null,
@@ -3682,10 +4068,20 @@ function HistoryCard({
3682
4068
  }
3683
4069
  )
3684
4070
  ] }),
4071
+ timing && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
4072
+ "span",
4073
+ {
4074
+ className: "rs-history-card-timing",
4075
+ "data-state": timing.state,
4076
+ "aria-live": "polite",
4077
+ "aria-atomic": "true",
4078
+ children: timing.state === "expected" ? `Usually arrives in ${timing.expectedDuration}` : timing.state === "soft" ? "Taking longer than usual" : "Taking much longer than usual"
4079
+ }
4080
+ ),
3685
4081
  recoverable && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3686
4082
  Button,
3687
4083
  {
3688
- onClick: () => _optionalChain([onRecover, 'optionalCall', _142 => _142(recoverable)]),
4084
+ onClick: () => _optionalChain([onRecover, 'optionalCall', _156 => _156(recoverable)]),
3689
4085
  fullWidth: true,
3690
4086
  className: "rs-history-card-recover",
3691
4087
  children: [
@@ -3750,7 +4146,7 @@ function ListRow({
3750
4146
  if (disabled) return;
3751
4147
  if (e.key === "Enter" || e.key === " ") {
3752
4148
  e.preventDefault();
3753
- _optionalChain([onClick, 'optionalCall', _143 => _143(e)]);
4149
+ _optionalChain([onClick, 'optionalCall', _157 => _157(e)]);
3754
4150
  }
3755
4151
  };
3756
4152
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -3760,7 +4156,7 @@ function ListRow({
3760
4156
  role: "button",
3761
4157
  tabIndex: disabled ? -1 : 0,
3762
4158
  "aria-disabled": disabled || void 0,
3763
- onClick: disabled ? void 0 : (e) => _optionalChain([onClick, 'optionalCall', _144 => _144(e)]),
4159
+ onClick: disabled ? void 0 : (e) => _optionalChain([onClick, 'optionalCall', _158 => _158(e)]),
3764
4160
  onKeyDown: handleKey,
3765
4161
  children: inner
3766
4162
  }
@@ -3818,7 +4214,7 @@ var RECOVERY_LOOKUP_MISS_COPY = {
3818
4214
  };
3819
4215
  function classifyRecoveryLookup(rows, options = {}) {
3820
4216
  const inScope = options.recipient ? rows.filter(
3821
- (row) => _optionalChain([row, 'access', _145 => _145.recipient, 'optionalAccess', _146 => _146.toLowerCase, 'call', _147 => _147()]) === _optionalChain([options, 'access', _148 => _148.recipient, 'optionalAccess', _149 => _149.toLowerCase, 'call', _150 => _150()])
4217
+ (row) => _optionalChain([row, 'access', _159 => _159.recipient, 'optionalAccess', _160 => _160.toLowerCase, 'call', _161 => _161()]) === _optionalChain([options, 'access', _162 => _162.recipient, 'optionalAccess', _163 => _163.toLowerCase, 'call', _164 => _164()])
3822
4218
  ) : rows;
3823
4219
  const eligible = inScope.map((row) => toRecoverableDeposit(row, options)).filter((deposit) => deposit !== null);
3824
4220
  return {
@@ -3846,7 +4242,7 @@ function RecoveryLookupScreen({
3846
4242
  const valid = isRecoveryTxHash(trimmed);
3847
4243
  _react.useEffect.call(void 0, () => {
3848
4244
  if (trimmed.length > 0 && !valid) {
3849
- _optionalChain([onInvalidRef, 'access', _151 => _151.current, 'optionalCall', _152 => _152()]);
4245
+ _optionalChain([onInvalidRef, 'access', _165 => _165.current, 'optionalCall', _166 => _166()]);
3850
4246
  }
3851
4247
  }, [trimmed, valid, onInvalidRef]);
3852
4248
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "rs-screen", children: [
@@ -3931,15 +4327,15 @@ function resolveTokenDisplay(token, chain, fallback) {
3931
4327
  const decimals = _chunkOY5N3E6Lcjs.findTokenDecimals.call(void 0, token, chain);
3932
4328
  if (symbol !== "Token" || decimals !== void 0) {
3933
4329
  return {
3934
- symbol: symbol !== "Token" ? symbol : _nullishCoalesce(_optionalChain([fallback, 'optionalAccess', _153 => _153.symbol]), () => ( symbol)),
3935
- decimals: _nullishCoalesce(decimals, () => ( _optionalChain([fallback, 'optionalAccess', _154 => _154.decimals])))
4330
+ symbol: symbol !== "Token" ? symbol : _nullishCoalesce(_optionalChain([fallback, 'optionalAccess', _167 => _167.symbol]), () => ( symbol)),
4331
+ decimals: _nullishCoalesce(decimals, () => ( _optionalChain([fallback, 'optionalAccess', _168 => _168.decimals])))
3936
4332
  };
3937
4333
  }
3938
4334
  }
3939
4335
  }
3940
4336
  return {
3941
- symbol: _nullishCoalesce(_optionalChain([fallback, 'optionalAccess', _155 => _155.symbol]), () => ( "Token")),
3942
- decimals: _optionalChain([fallback, 'optionalAccess', _156 => _156.decimals])
4337
+ symbol: _nullishCoalesce(_optionalChain([fallback, 'optionalAccess', _169 => _169.symbol]), () => ( "Token")),
4338
+ decimals: _optionalChain([fallback, 'optionalAccess', _170 => _170.decimals])
3943
4339
  };
3944
4340
  }
3945
4341
  function maxFractionDigitsFor(symbol) {
@@ -3958,7 +4354,7 @@ function tokenAmountToNumber(rawAmount, decimals) {
3958
4354
  try {
3959
4355
  const value = Number(_viem.formatUnits.call(void 0, BigInt(rawAmount), decimals));
3960
4356
  return Number.isFinite(value) ? value : void 0;
3961
- } catch (e13) {
4357
+ } catch (e14) {
3962
4358
  return void 0;
3963
4359
  }
3964
4360
  }
@@ -4016,7 +4412,7 @@ function formatQuotedReceive(output, fallbackSymbol) {
4016
4412
  let raw;
4017
4413
  try {
4018
4414
  raw = BigInt(output.amount);
4019
- } catch (e14) {
4415
+ } catch (e15) {
4020
4416
  return void 0;
4021
4417
  }
4022
4418
  if (raw <= 0n) return void 0;
@@ -4059,7 +4455,7 @@ function formatRecoveryAmount(amountRaw, decimals, symbol) {
4059
4455
  function toBigInt(value) {
4060
4456
  try {
4061
4457
  return BigInt(value || "0");
4062
- } catch (e15) {
4458
+ } catch (e16) {
4063
4459
  return 0n;
4064
4460
  }
4065
4461
  }
@@ -4193,7 +4589,7 @@ async function submitSignedRecovery(params) {
4193
4589
  // The shared const, so recovery carries `x-deposit-modal-version` like
4194
4590
  // every other backend call. Without it this path would be invisible in the
4195
4591
  // per-client version telemetry the processor records.
4196
- headers: _chunk5CM3ZQ5Ucjs.serviceHeaders.call(void 0, ),
4592
+ headers: _chunkN6JJG57Rcjs.serviceHeaders.call(void 0, ),
4197
4593
  // `depositId` as a string: it is a uint256 upstream and JSON numbers lose
4198
4594
  // precision well before that range.
4199
4595
  body: JSON.stringify({ depositId, destination, signature })
@@ -4552,7 +4948,7 @@ function HistoryFallbackFlow({
4552
4948
  },
4553
4949
  [analytics]
4554
4950
  );
4555
- const lookup = _react.useCallback.call(void 0,
4951
+ const lookup2 = _react.useCallback.call(void 0,
4556
4952
  async (txHash) => {
4557
4953
  const epoch = epochRef.current;
4558
4954
  const isCurrentLookup = () => epochRef.current === epoch;
@@ -4682,7 +5078,7 @@ function HistoryFallbackFlow({
4682
5078
  hint: "The transaction hash from the wallet or exchange you sent from.",
4683
5079
  loading,
4684
5080
  error,
4685
- onSubmit: lookup,
5081
+ onSubmit: lookup2,
4686
5082
  onInvalid: () => analytics.friction("lookup_transaction_hash_invalid", "lookup")
4687
5083
  }
4688
5084
  )
@@ -4789,7 +5185,7 @@ function RecoveryReviewScreen({
4789
5185
  const onDestinationInvalidRef = useLatestRef(onDestinationInvalid);
4790
5186
  _react.useEffect.call(void 0, () => {
4791
5187
  if (destination.length > 0 && !destinationValid) {
4792
- _optionalChain([onDestinationInvalidRef, 'access', _157 => _157.current, 'optionalCall', _158 => _158()]);
5188
+ _optionalChain([onDestinationInvalidRef, 'access', _171 => _171.current, 'optionalCall', _172 => _172()]);
4793
5189
  }
4794
5190
  }, [destination, destinationValid, onDestinationInvalidRef]);
4795
5191
  const txUrl = txHash ? explorerTxUrl(chainId, txHash) : null;
@@ -4947,11 +5343,11 @@ function HistoryRecoveryFlow({
4947
5343
  } catch (err) {
4948
5344
  const recoveryError = err instanceof RecoveryError ? err : void 0;
4949
5345
  setError(
4950
- _nullishCoalesce(_optionalChain([recoveryError, 'optionalAccess', _159 => _159.message]), () => ( formatUserError(
5346
+ _nullishCoalesce(_optionalChain([recoveryError, 'optionalAccess', _173 => _173.message]), () => ( formatUserError(
4951
5347
  err instanceof Error ? err.message : "Recovery failed"
4952
5348
  )))
4953
5349
  );
4954
- const canRetry = _nullishCoalesce(_optionalChain([recoveryError, 'optionalAccess', _160 => _160.retryable]), () => ( true));
5350
+ const canRetry = _nullishCoalesce(_optionalChain([recoveryError, 'optionalAccess', _174 => _174.retryable]), () => ( true));
4955
5351
  setRetryable(canRetry);
4956
5352
  setPhase("failed");
4957
5353
  const reason = claimFailureReasonForError(err);
@@ -5092,8 +5488,8 @@ function HistoryOverlay({
5092
5488
  const endAttempt = _react.useCallback.call(void 0,
5093
5489
  (source, reason) => {
5094
5490
  const claim = claimControllerRef.current;
5095
- _optionalChain([claim, 'optionalAccess', _161 => _161.abandon, 'call', _162 => _162(reason)]);
5096
- _optionalChain([claim, 'optionalAccess', _163 => _163.close, 'call', _164 => _164(source)]);
5491
+ _optionalChain([claim, 'optionalAccess', _175 => _175.abandon, 'call', _176 => _176(reason)]);
5492
+ _optionalChain([claim, 'optionalAccess', _177 => _177.close, 'call', _178 => _178(source)]);
5097
5493
  claimControllerRef.current = null;
5098
5494
  setAttempt(null);
5099
5495
  },
@@ -5151,8 +5547,8 @@ function HistoryOverlay({
5151
5547
  if (!attempt) return;
5152
5548
  return () => {
5153
5549
  const claim = claimControllerRef.current;
5154
- _optionalChain([claim, 'optionalAccess', _165 => _165.abandon, 'call', _166 => _166("modal_close")]);
5155
- _optionalChain([claim, 'optionalAccess', _167 => _167.close, 'call', _168 => _168("host_controlled")]);
5550
+ _optionalChain([claim, 'optionalAccess', _179 => _179.abandon, 'call', _180 => _180("modal_close")]);
5551
+ _optionalChain([claim, 'optionalAccess', _181 => _181.close, 'call', _182 => _182("host_controlled")]);
5156
5552
  };
5157
5553
  }, [attempt]);
5158
5554
  const claimSessionProperties = _react.useMemo.call(void 0,
@@ -5178,7 +5574,7 @@ function HistoryOverlay({
5178
5574
  HistoryRecoveryFlow,
5179
5575
  {
5180
5576
  deposit: recovering,
5181
- entrySource: _nullishCoalesce(_optionalChain([attempt, 'optionalAccess', _169 => _169.entrySource]), () => ( "history_row")),
5577
+ entrySource: _nullishCoalesce(_optionalChain([attempt, 'optionalAccess', _183 => _183.entrySource]), () => ( "history_row")),
5182
5578
  backendUrl,
5183
5579
  signRecovery,
5184
5580
  debug,
@@ -5235,6 +5631,7 @@ function HistoryOverlay({
5235
5631
 
5236
5632
  // src/components/history/useHistoryPanel.ts
5237
5633
 
5634
+ var MAX_TIMEOUT_MS = 2147483647;
5238
5635
  function sortByCreatedAtDesc(items) {
5239
5636
  return [...items].sort((a, b) => {
5240
5637
  const at = a.createdAt ? Date.parse(a.createdAt) : 0;
@@ -5312,13 +5709,26 @@ function useHistoryPanel({
5312
5709
  },
5313
5710
  [recipient, service]
5314
5711
  );
5315
- const badge = _react.useMemo.call(void 0,
5316
- () => deriveHistoryBadge(deposits, { recipient, canRecover }),
5317
- [deposits, recipient, canRecover]
5318
- );
5712
+ const badgeState2 = deriveHistoryBadgeState(deposits, {
5713
+ recipient,
5714
+ canRecover
5715
+ });
5716
+ const badge = badgeState2.badge;
5717
+ _react.useEffect.call(void 0, () => {
5718
+ if (!isOpen || badgeState2.nextExpiryAt === null) return;
5719
+ const delay = Math.min(
5720
+ badgeState2.nextExpiryAt - Date.now(),
5721
+ MAX_TIMEOUT_MS
5722
+ );
5723
+ const timeout = setTimeout(
5724
+ () => setDeposits((current) => current.slice()),
5725
+ delay
5726
+ );
5727
+ return () => clearTimeout(timeout);
5728
+ }, [isOpen, badgeState2.nextExpiryAt]);
5319
5729
  const openPanel = _react.useCallback.call(void 0, () => {
5320
5730
  setIsPanelOpen(true);
5321
- _optionalChain([analytics, 'optionalAccess', _170 => _170.visitOpened, 'call', _171 => _171(badge)]);
5731
+ _optionalChain([analytics, 'optionalAccess', _184 => _184.visitOpened, 'call', _185 => _185(badge)]);
5322
5732
  if (!loadedRef.current || staleRef.current) {
5323
5733
  fetchHistory("initial");
5324
5734
  }
@@ -5326,10 +5736,10 @@ function useHistoryPanel({
5326
5736
  const closePanel = _react.useCallback.call(void 0, () => {
5327
5737
  if (recovering) return;
5328
5738
  setIsPanelOpen(false);
5329
- _optionalChain([analytics, 'optionalAccess', _172 => _172.visitEnded, 'call', _173 => _173()]);
5739
+ _optionalChain([analytics, 'optionalAccess', _186 => _186.visitEnded, 'call', _187 => _187()]);
5330
5740
  }, [analytics, recovering]);
5331
5741
  const loadMore = _react.useCallback.call(void 0, () => {
5332
- _optionalChain([analytics, 'optionalAccess', _174 => _174.loadMore, 'call', _175 => _175(filterVisibleDeposits(deposits).length)]);
5742
+ _optionalChain([analytics, 'optionalAccess', _188 => _188.loadMore, 'call', _189 => _189(filterVisibleDeposits(deposits).length)]);
5333
5743
  fetchHistory("more");
5334
5744
  }, [analytics, deposits, fetchHistory]);
5335
5745
  const markStale = _react.useCallback.call(void 0, () => {
@@ -5357,7 +5767,7 @@ function useHistoryPanel({
5357
5767
  _react.useEffect.call(void 0, () => {
5358
5768
  if (isOpen) return;
5359
5769
  setIsPanelOpen(false);
5360
- _optionalChain([analytics, 'optionalAccess', _176 => _176.visitEnded, 'call', _177 => _177()]);
5770
+ _optionalChain([analytics, 'optionalAccess', _190 => _190.visitEnded, 'call', _191 => _191()]);
5361
5771
  setDeposits([]);
5362
5772
  setHasMore(false);
5363
5773
  setError(null);
@@ -5516,11 +5926,11 @@ var NOTHING_TO_STOP = () => {
5516
5926
  };
5517
5927
  function resolveThemeMode(mode) {
5518
5928
  if (mode !== "system") return mode;
5519
- return _optionalChain([globalThis, 'access', _178 => _178.matchMedia, 'optionalCall', _179 => _179(DARK_SCHEME_QUERY), 'access', _180 => _180.matches]) ? "dark" : "light";
5929
+ return _optionalChain([globalThis, 'access', _192 => _192.matchMedia, 'optionalCall', _193 => _193(DARK_SCHEME_QUERY), 'access', _194 => _194.matches]) ? "dark" : "light";
5520
5930
  }
5521
5931
  function followSystemAppearance(mode, onChange) {
5522
5932
  if (mode !== "system") return NOTHING_TO_STOP;
5523
- const query = _optionalChain([globalThis, 'access', _181 => _181.matchMedia, 'optionalCall', _182 => _182(DARK_SCHEME_QUERY)]);
5933
+ const query = _optionalChain([globalThis, 'access', _195 => _195.matchMedia, 'optionalCall', _196 => _196(DARK_SCHEME_QUERY)]);
5524
5934
  if (!query) return NOTHING_TO_STOP;
5525
5935
  query.addEventListener("change", onChange);
5526
5936
  return () => query.removeEventListener("change", onChange);
@@ -5528,22 +5938,22 @@ function followSystemAppearance(mode, onChange) {
5528
5938
  function applyTheme(element, theme) {
5529
5939
  if (!element) return NOTHING_TO_STOP;
5530
5940
  const parent = element.parentElement;
5531
- const targets = _optionalChain([parent, 'optionalAccess', _183 => _183.classList, 'access', _184 => _184.contains, 'call', _185 => _185("rs-modal-content")]) ? [element, parent] : [element];
5941
+ const targets = _optionalChain([parent, 'optionalAccess', _197 => _197.classList, 'access', _198 => _198.contains, 'call', _199 => _199("rs-modal-content")]) ? [element, parent] : [element];
5532
5942
  const paintMode = () => {
5533
- const resolved = resolveThemeMode(_optionalChain([theme, 'optionalAccess', _186 => _186.mode]));
5943
+ const resolved = resolveThemeMode(_optionalChain([theme, 'optionalAccess', _200 => _200.mode]));
5534
5944
  for (const t of targets) {
5535
5945
  if (resolved) t.setAttribute("data-theme", resolved);
5536
5946
  else t.removeAttribute("data-theme");
5537
5947
  }
5538
5948
  };
5539
5949
  paintMode();
5540
- if (_optionalChain([theme, 'optionalAccess', _187 => _187.fontColor])) {
5950
+ if (_optionalChain([theme, 'optionalAccess', _201 => _201.fontColor])) {
5541
5951
  setVar(targets, "--rs-foreground", theme.fontColor);
5542
5952
  }
5543
- if (_optionalChain([theme, 'optionalAccess', _188 => _188.iconColor])) {
5953
+ if (_optionalChain([theme, 'optionalAccess', _202 => _202.iconColor])) {
5544
5954
  setVar(targets, "--rs-icon", theme.iconColor);
5545
5955
  }
5546
- if (_optionalChain([theme, 'optionalAccess', _189 => _189.ctaColor])) {
5956
+ if (_optionalChain([theme, 'optionalAccess', _203 => _203.ctaColor])) {
5547
5957
  const derived = deriveCustomPrimary(theme.ctaColor);
5548
5958
  if (derived) {
5549
5959
  setVar(targets, "--rs-primary", derived.base);
@@ -5568,25 +5978,25 @@ function applyTheme(element, theme) {
5568
5978
  }
5569
5979
  } else {
5570
5980
  for (const v of CUSTOM_PRIMARY_VARS) clearVar(targets, v);
5571
- if (_optionalChain([theme, 'optionalAccess', _190 => _190.ctaHoverColor])) {
5981
+ if (_optionalChain([theme, 'optionalAccess', _204 => _204.ctaHoverColor])) {
5572
5982
  setVar(targets, "--rs-primary-hover", theme.ctaHoverColor);
5573
5983
  }
5574
5984
  }
5575
- if (_optionalChain([theme, 'optionalAccess', _191 => _191.borderColor])) {
5985
+ if (_optionalChain([theme, 'optionalAccess', _205 => _205.borderColor])) {
5576
5986
  setVar(targets, "--rs-border", theme.borderColor);
5577
5987
  setVar(targets, "--rs-border-surface", theme.borderColor);
5578
5988
  }
5579
- if (_optionalChain([theme, 'optionalAccess', _192 => _192.backgroundColor])) {
5989
+ if (_optionalChain([theme, 'optionalAccess', _206 => _206.backgroundColor])) {
5580
5990
  setVar(targets, "--rs-background", theme.backgroundColor);
5581
5991
  }
5582
- if (_optionalChain([theme, 'optionalAccess', _193 => _193.radius])) {
5992
+ if (_optionalChain([theme, 'optionalAccess', _207 => _207.radius])) {
5583
5993
  const scale = RADIUS_SCALE[theme.radius];
5584
5994
  setVar(targets, "--rs-radius-sm", scale.sm);
5585
5995
  setVar(targets, "--rs-radius-md", scale.md);
5586
5996
  setVar(targets, "--rs-radius-lg", scale.lg);
5587
5997
  setVar(targets, "--rs-radius", scale.md);
5588
5998
  }
5589
- return followSystemAppearance(_optionalChain([theme, 'optionalAccess', _194 => _194.mode]), paintMode);
5999
+ return followSystemAppearance(_optionalChain([theme, 'optionalAccess', _208 => _208.mode]), paintMode);
5590
6000
  }
5591
6001
 
5592
6002
  // src/core/removed-props.ts
@@ -5675,20 +6085,20 @@ function sinkFor(source) {
5675
6085
  if (source.modal === "deposit") {
5676
6086
  const at2 = () => source.controllerRef.current;
5677
6087
  return {
5678
- opened: (detail) => _optionalChain([at2, 'call', _195 => _195(), 'optionalAccess', _196 => _196.historyOpened, 'call', _197 => _197({ ...detail, step: _nullishCoalesce(_optionalChain([at2, 'call', _198 => _198(), 'optionalAccess', _199 => _199.step]), () => ( null)) })]),
5679
- rowViewed: (detail) => _optionalChain([at2, 'call', _200 => _200(), 'optionalAccess', _201 => _201.historyRowViewed, 'call', _202 => _202(detail)]),
5680
- loadMore: (detail) => _optionalChain([at2, 'call', _203 => _203(), 'optionalAccess', _204 => _204.historyLoadMore, 'call', _205 => _205(detail)]),
5681
- fallbackOpened: (detail) => _optionalChain([at2, 'call', _206 => _206(), 'optionalAccess', _207 => _207.historyFallbackOpened, 'call', _208 => _208(detail)]),
5682
- recoveryStarted: (detail) => _optionalChain([at2, 'call', _209 => _209(), 'optionalAccess', _210 => _210.historyRecoveryStarted, 'call', _211 => _211(detail)])
6088
+ opened: (detail) => _optionalChain([at2, 'call', _209 => _209(), 'optionalAccess', _210 => _210.historyOpened, 'call', _211 => _211({ ...detail, step: _nullishCoalesce(_optionalChain([at2, 'call', _212 => _212(), 'optionalAccess', _213 => _213.step]), () => ( null)) })]),
6089
+ rowViewed: (detail) => _optionalChain([at2, 'call', _214 => _214(), 'optionalAccess', _215 => _215.historyRowViewed, 'call', _216 => _216(detail)]),
6090
+ loadMore: (detail) => _optionalChain([at2, 'call', _217 => _217(), 'optionalAccess', _218 => _218.historyLoadMore, 'call', _219 => _219(detail)]),
6091
+ fallbackOpened: (detail) => _optionalChain([at2, 'call', _220 => _220(), 'optionalAccess', _221 => _221.historyFallbackOpened, 'call', _222 => _222(detail)]),
6092
+ recoveryStarted: (detail) => _optionalChain([at2, 'call', _223 => _223(), 'optionalAccess', _224 => _224.historyRecoveryStarted, 'call', _225 => _225(detail)])
5683
6093
  };
5684
6094
  }
5685
6095
  const at = () => source.controllerRef.current;
5686
6096
  return {
5687
- opened: (detail) => _optionalChain([at, 'call', _212 => _212(), 'optionalAccess', _213 => _213.historyOpened, 'call', _214 => _214({ ...detail, step: _nullishCoalesce(_optionalChain([at, 'call', _215 => _215(), 'optionalAccess', _216 => _216.step]), () => ( null)) })]),
5688
- rowViewed: (detail) => _optionalChain([at, 'call', _217 => _217(), 'optionalAccess', _218 => _218.historyRowViewed, 'call', _219 => _219(detail)]),
5689
- loadMore: (detail) => _optionalChain([at, 'call', _220 => _220(), 'optionalAccess', _221 => _221.historyLoadMore, 'call', _222 => _222(detail)]),
5690
- fallbackOpened: (detail) => _optionalChain([at, 'call', _223 => _223(), 'optionalAccess', _224 => _224.historyFallbackOpened, 'call', _225 => _225(detail)]),
5691
- recoveryStarted: (detail) => _optionalChain([at, 'call', _226 => _226(), 'optionalAccess', _227 => _227.historyRecoveryStarted, 'call', _228 => _228(detail)])
6097
+ opened: (detail) => _optionalChain([at, 'call', _226 => _226(), 'optionalAccess', _227 => _227.historyOpened, 'call', _228 => _228({ ...detail, step: _nullishCoalesce(_optionalChain([at, 'call', _229 => _229(), 'optionalAccess', _230 => _230.step]), () => ( null)) })]),
6098
+ rowViewed: (detail) => _optionalChain([at, 'call', _231 => _231(), 'optionalAccess', _232 => _232.historyRowViewed, 'call', _233 => _233(detail)]),
6099
+ loadMore: (detail) => _optionalChain([at, 'call', _234 => _234(), 'optionalAccess', _235 => _235.historyLoadMore, 'call', _236 => _236(detail)]),
6100
+ fallbackOpened: (detail) => _optionalChain([at, 'call', _237 => _237(), 'optionalAccess', _238 => _238.historyFallbackOpened, 'call', _239 => _239(detail)]),
6101
+ recoveryStarted: (detail) => _optionalChain([at, 'call', _240 => _240(), 'optionalAccess', _241 => _241.historyRecoveryStarted, 'call', _242 => _242(detail)])
5692
6102
  };
5693
6103
  }
5694
6104
  function badgeState(badge) {
@@ -5714,7 +6124,7 @@ function createHistoryAnalytics(source) {
5714
6124
  sink.opened({
5715
6125
  history_visit_id: visitId,
5716
6126
  badge: badgeState(badge),
5717
- badge_count: _nullishCoalesce(_optionalChain([badge, 'optionalAccess', _229 => _229.count]), () => ( 0))
6127
+ badge_count: _nullishCoalesce(_optionalChain([badge, 'optionalAccess', _243 => _243.count]), () => ( 0))
5718
6128
  });
5719
6129
  },
5720
6130
  visitEnded() {
@@ -5778,7 +6188,7 @@ function resolveChain(targetChain) {
5778
6188
  return _chunkOY5N3E6Lcjs.targetChainToCaip2.call(void 0, targetChain);
5779
6189
  }
5780
6190
  function resolveToken(targetToken) {
5781
- const raw = _optionalChain([targetToken, 'optionalAccess', _230 => _230.trim, 'call', _231 => _231()]);
6191
+ const raw = _optionalChain([targetToken, 'optionalAccess', _244 => _244.trim, 'call', _245 => _245()]);
5782
6192
  if (!raw) return void 0;
5783
6193
  if (HEX_TOKEN.test(raw)) return raw.toLowerCase();
5784
6194
  if (BASE58_TOKEN.test(raw)) return raw;
@@ -5836,8 +6246,8 @@ function Tooltip({ content, children, className }) {
5836
6246
  function handleOutside(event) {
5837
6247
  const target = event.target;
5838
6248
  if (!target) return;
5839
- if (_optionalChain([triggerRef, 'access', _232 => _232.current, 'optionalAccess', _233 => _233.contains, 'call', _234 => _234(target)])) return;
5840
- if (_optionalChain([bubbleRef, 'access', _235 => _235.current, 'optionalAccess', _236 => _236.contains, 'call', _237 => _237(target)])) return;
6249
+ if (_optionalChain([triggerRef, 'access', _246 => _246.current, 'optionalAccess', _247 => _247.contains, 'call', _248 => _248(target)])) return;
6250
+ if (_optionalChain([bubbleRef, 'access', _249 => _249.current, 'optionalAccess', _250 => _250.contains, 'call', _251 => _251(target)])) return;
5841
6251
  setOpen(false);
5842
6252
  }
5843
6253
  function handleKey(event) {
@@ -6066,7 +6476,7 @@ function asNumber(value) {
6066
6476
  const trimmed = value.trim();
6067
6477
  if (!trimmed) return void 0;
6068
6478
  const caipMatch = trimmed.match(/^eip155:(\d+)$/);
6069
- if (_optionalChain([caipMatch, 'optionalAccess', _238 => _238[1]])) {
6479
+ if (_optionalChain([caipMatch, 'optionalAccess', _252 => _252[1]])) {
6070
6480
  const parsed2 = Number(caipMatch[1]);
6071
6481
  return Number.isFinite(parsed2) ? parsed2 : void 0;
6072
6482
  }
@@ -6085,24 +6495,24 @@ function asAddress(value) {
6085
6495
  return /^0x[a-fA-F0-9]{40}$/.test(value) ? value : void 0;
6086
6496
  }
6087
6497
  function getEventTxHash(event) {
6088
- if (!_optionalChain([event, 'optionalAccess', _239 => _239.type])) return void 0;
6498
+ if (!_optionalChain([event, 'optionalAccess', _253 => _253.type])) return void 0;
6089
6499
  if (event.type === "deposit-received") {
6090
- return asString(_optionalChain([event, 'access', _240 => _240.data, 'optionalAccess', _241 => _241.transactionHash]));
6500
+ return asString(_optionalChain([event, 'access', _254 => _254.data, 'optionalAccess', _255 => _255.transactionHash]));
6091
6501
  }
6092
6502
  if (event.type === "bridge-started" || event.type === "bridge-complete") {
6093
- const deposit = isRecord(_optionalChain([event, 'access', _242 => _242.data, 'optionalAccess', _243 => _243.deposit])) ? event.data.deposit : void 0;
6094
- const source = isRecord(_optionalChain([event, 'access', _244 => _244.data, 'optionalAccess', _245 => _245.source])) ? event.data.source : void 0;
6095
- return _nullishCoalesce(asString(_optionalChain([deposit, 'optionalAccess', _246 => _246.transactionHash])), () => ( asString(_optionalChain([source, 'optionalAccess', _247 => _247.transactionHash]))));
6503
+ const deposit = isRecord(_optionalChain([event, 'access', _256 => _256.data, 'optionalAccess', _257 => _257.deposit])) ? event.data.deposit : void 0;
6504
+ const source = isRecord(_optionalChain([event, 'access', _258 => _258.data, 'optionalAccess', _259 => _259.source])) ? event.data.source : void 0;
6505
+ return _nullishCoalesce(asString(_optionalChain([deposit, 'optionalAccess', _260 => _260.transactionHash])), () => ( asString(_optionalChain([source, 'optionalAccess', _261 => _261.transactionHash]))));
6096
6506
  }
6097
6507
  if (event.type === "bridge-failed" || event.type === "error") {
6098
- const deposit = isRecord(_optionalChain([event, 'access', _248 => _248.data, 'optionalAccess', _249 => _249.deposit])) ? event.data.deposit : void 0;
6099
- const source = isRecord(_optionalChain([event, 'access', _250 => _250.data, 'optionalAccess', _251 => _251.source])) ? event.data.source : void 0;
6100
- return _nullishCoalesce(asString(_optionalChain([deposit, 'optionalAccess', _252 => _252.transactionHash])), () => ( asString(_optionalChain([source, 'optionalAccess', _253 => _253.transactionHash]))));
6508
+ const deposit = isRecord(_optionalChain([event, 'access', _262 => _262.data, 'optionalAccess', _263 => _263.deposit])) ? event.data.deposit : void 0;
6509
+ const source = isRecord(_optionalChain([event, 'access', _264 => _264.data, 'optionalAccess', _265 => _265.source])) ? event.data.source : void 0;
6510
+ return _nullishCoalesce(asString(_optionalChain([deposit, 'optionalAccess', _266 => _266.transactionHash])), () => ( asString(_optionalChain([source, 'optionalAccess', _267 => _267.transactionHash]))));
6101
6511
  }
6102
6512
  return void 0;
6103
6513
  }
6104
6514
  function getEventSourceDetails(event) {
6105
- if (!_optionalChain([event, 'optionalAccess', _254 => _254.type]) || !isRecord(event.data)) return {};
6515
+ if (!_optionalChain([event, 'optionalAccess', _268 => _268.type]) || !isRecord(event.data)) return {};
6106
6516
  if (event.type === "deposit-received") {
6107
6517
  return {
6108
6518
  chainId: asNumber(event.data.chain),
@@ -6114,9 +6524,9 @@ function getEventSourceDetails(event) {
6114
6524
  const deposit = isRecord(event.data.deposit) ? event.data.deposit : void 0;
6115
6525
  if (event.type === "bridge-started" || event.type === "bridge-complete" || event.type === "bridge-failed" || event.type === "error") {
6116
6526
  return {
6117
- chainId: _nullishCoalesce(asNumber(_optionalChain([source, 'optionalAccess', _255 => _255.chain])), () => ( asNumber(_optionalChain([deposit, 'optionalAccess', _256 => _256.chain])))),
6118
- amount: _nullishCoalesce(asAmount(_optionalChain([source, 'optionalAccess', _257 => _257.amount])), () => ( asAmount(_optionalChain([deposit, 'optionalAccess', _258 => _258.amount])))),
6119
- token: _nullishCoalesce(_nullishCoalesce(asAddress(_optionalChain([source, 'optionalAccess', _259 => _259.asset])), () => ( asAddress(_optionalChain([deposit, 'optionalAccess', _260 => _260.asset])))), () => ( asAddress(_optionalChain([deposit, 'optionalAccess', _261 => _261.token]))))
6527
+ chainId: _nullishCoalesce(asNumber(_optionalChain([source, 'optionalAccess', _269 => _269.chain])), () => ( asNumber(_optionalChain([deposit, 'optionalAccess', _270 => _270.chain])))),
6528
+ amount: _nullishCoalesce(asAmount(_optionalChain([source, 'optionalAccess', _271 => _271.amount])), () => ( asAmount(_optionalChain([deposit, 'optionalAccess', _272 => _272.amount])))),
6529
+ token: _nullishCoalesce(_nullishCoalesce(asAddress(_optionalChain([source, 'optionalAccess', _273 => _273.asset])), () => ( asAddress(_optionalChain([deposit, 'optionalAccess', _274 => _274.asset])))), () => ( asAddress(_optionalChain([deposit, 'optionalAccess', _275 => _275.token]))))
6120
6530
  };
6121
6531
  }
6122
6532
  return {};
@@ -6130,7 +6540,7 @@ function asChain(value) {
6130
6540
  return asNumber(value);
6131
6541
  }
6132
6542
  function getEventDestinationDetails(event) {
6133
- if (!_optionalChain([event, 'optionalAccess', _262 => _262.type]) || !isRecord(event.data)) return {};
6543
+ if (!_optionalChain([event, 'optionalAccess', _276 => _276.type]) || !isRecord(event.data)) return {};
6134
6544
  if (event.type !== "bridge-started" && event.type !== "bridge-complete") {
6135
6545
  return {};
6136
6546
  }
@@ -6140,14 +6550,14 @@ function getEventDestinationDetails(event) {
6140
6550
  return {
6141
6551
  chainId: asChain(destination.chain),
6142
6552
  amount: asAmount(destination.amount),
6143
- token: _optionalChain([token, 'optionalAccess', _263 => _263.trim, 'call', _264 => _264()]) || void 0
6553
+ token: _optionalChain([token, 'optionalAccess', _277 => _277.trim, 'call', _278 => _278()]) || void 0
6144
6554
  };
6145
6555
  }
6146
6556
  function isDepositEvent(event) {
6147
- return _optionalChain([event, 'optionalAccess', _265 => _265.type]) === "deposit-received" || _optionalChain([event, 'optionalAccess', _266 => _266.type]) === "bridge-started" || _optionalChain([event, 'optionalAccess', _267 => _267.type]) === "bridge-complete" || _optionalChain([event, 'optionalAccess', _268 => _268.type]) === "bridge-failed" || _optionalChain([event, 'optionalAccess', _269 => _269.type]) === "error";
6557
+ return _optionalChain([event, 'optionalAccess', _279 => _279.type]) === "deposit-received" || _optionalChain([event, 'optionalAccess', _280 => _280.type]) === "bridge-started" || _optionalChain([event, 'optionalAccess', _281 => _281.type]) === "bridge-complete" || _optionalChain([event, 'optionalAccess', _282 => _282.type]) === "bridge-failed" || _optionalChain([event, 'optionalAccess', _283 => _283.type]) === "error";
6148
6558
  }
6149
6559
  function isFailedEvent(event) {
6150
- return _optionalChain([event, 'optionalAccess', _270 => _270.type]) === "bridge-failed" || _optionalChain([event, 'optionalAccess', _271 => _271.type]) === "error";
6560
+ return _optionalChain([event, 'optionalAccess', _284 => _284.type]) === "bridge-failed" || _optionalChain([event, 'optionalAccess', _285 => _285.type]) === "error";
6151
6561
  }
6152
6562
  function isHexString(value) {
6153
6563
  return value.startsWith("0x") || value.startsWith("0X");
@@ -6159,7 +6569,7 @@ function txRefsMatch(a, b) {
6159
6569
  return a === b;
6160
6570
  }
6161
6571
  function formatBridgeFailedMessage(event) {
6162
- const eventData = _nullishCoalesce(_optionalChain([event, 'optionalAccess', _272 => _272.data]), () => ( {}));
6572
+ const eventData = _nullishCoalesce(_optionalChain([event, 'optionalAccess', _286 => _286.data]), () => ( {}));
6163
6573
  const code = typeof eventData.errorCode === "string" ? eventData.errorCode : void 0;
6164
6574
  const backendMessage = typeof eventData.message === "string" ? eventData.message.trim() : "";
6165
6575
  function toUserFacingFailure(raw) {
@@ -6187,7 +6597,7 @@ function formatBridgeFailedMessage(event) {
6187
6597
  return { message: "Bridge failed" };
6188
6598
  }
6189
6599
  function failureMessageForEvent(event) {
6190
- if (_optionalChain([event, 'optionalAccess', _273 => _273.type]) === "error") {
6600
+ if (_optionalChain([event, 'optionalAccess', _287 => _287.type]) === "error") {
6191
6601
  const message = isRecord(event.data) ? asString(event.data.message) : void 0;
6192
6602
  return _nullishCoalesce(message, () => ( "Unknown error"));
6193
6603
  }
@@ -6226,7 +6636,7 @@ async function fetchTokenPriceUsd(service, token) {
6226
6636
  }
6227
6637
  function useTokenPrices(service, tokens) {
6228
6638
  const [prices, setPrices] = _react.useState.call(void 0, {});
6229
- const defined = tokens.filter((t) => Boolean(_optionalChain([t, 'optionalAccess', _274 => _274.symbol])));
6639
+ const defined = tokens.filter((t) => Boolean(_optionalChain([t, 'optionalAccess', _288 => _288.symbol])));
6230
6640
  const entries = [
6231
6641
  ...new Map(
6232
6642
  defined.flatMap((token) => {
@@ -6325,12 +6735,6 @@ var MAX_POLL_INTERVAL = 3e4;
6325
6735
  var BACKOFF_MULTIPLIER = 1.5;
6326
6736
  var SWAPPED_RECEIPT_STATUS_RETRY_INTERVAL_MS = 1e3;
6327
6737
  var SWAPPED_FIAT_STATUS_MAX_ATTEMPTS = 12;
6328
- var ESCALATED_DELAY_MS = 10 * 60 * 1e3;
6329
- var SOFT_DELAY_MS = {
6330
- confirming: 90 * 1e3,
6331
- received: 90 * 1e3,
6332
- bridging: 4 * 60 * 1e3
6333
- };
6334
6738
  var PHASE_TIMINGS_PREFIX = "rhinestone:phase-timings";
6335
6739
  var PAYMENT_METHOD_LABELS = {
6336
6740
  creditcard: "Card",
@@ -6395,7 +6799,7 @@ function loadPhaseTimings(txHash) {
6395
6799
  const parsed = JSON.parse(raw);
6396
6800
  if (typeof parsed.startedAt !== "number") return null;
6397
6801
  return parsed;
6398
- } catch (e16) {
6802
+ } catch (e17) {
6399
6803
  return null;
6400
6804
  }
6401
6805
  }
@@ -6406,7 +6810,7 @@ function savePhaseTimings(txHash, timings) {
6406
6810
  `${PHASE_TIMINGS_PREFIX}:${txHash}`,
6407
6811
  JSON.stringify(timings)
6408
6812
  );
6409
- } catch (e17) {
6813
+ } catch (e18) {
6410
6814
  }
6411
6815
  }
6412
6816
  function isEventForTx(event, txHash) {
@@ -6415,12 +6819,12 @@ function isEventForTx(event, txHash) {
6415
6819
  return txRefsMatch(eventTxHash, txHash);
6416
6820
  }
6417
6821
  function parseWebhookTimestamp(event) {
6418
- if (typeof _optionalChain([event, 'optionalAccess', _275 => _275.time]) !== "string") return void 0;
6822
+ if (typeof _optionalChain([event, 'optionalAccess', _289 => _289.time]) !== "string") return void 0;
6419
6823
  const timestamp = Date.parse(event.time);
6420
6824
  return Number.isFinite(timestamp) ? timestamp : void 0;
6421
6825
  }
6422
6826
  function syncPhaseTimings(previous, event) {
6423
- if (!_optionalChain([event, 'optionalAccess', _276 => _276.type])) return previous;
6827
+ if (!_optionalChain([event, 'optionalAccess', _290 => _290.type])) return previous;
6424
6828
  const timestamp = _nullishCoalesce(parseWebhookTimestamp(event), () => ( Date.now()));
6425
6829
  const setReceived = (event.type === "deposit-received" || event.type === "bridge-started" || event.type === "bridge-complete" || event.type === "bridge-failed" || event.type === "error") && previous.receivedAt === void 0;
6426
6830
  const setBridging = (event.type === "bridge-started" || event.type === "bridge-complete") && previous.bridgingAt === void 0;
@@ -6482,46 +6886,46 @@ function getCurrentPhaseId(state, phaseTimings) {
6482
6886
  if (state.type === "complete") {
6483
6887
  return void 0;
6484
6888
  }
6485
- if (_optionalChain([state, 'access', _277 => _277.lastEvent, 'optionalAccess', _278 => _278.type]) === "bridge-started" || _optionalChain([state, 'access', _279 => _279.lastEvent, 'optionalAccess', _280 => _280.type]) === "bridge-complete")
6889
+ if (_optionalChain([state, 'access', _291 => _291.lastEvent, 'optionalAccess', _292 => _292.type]) === "bridge-started" || _optionalChain([state, 'access', _293 => _293.lastEvent, 'optionalAccess', _294 => _294.type]) === "bridge-complete")
6486
6890
  return "bridging";
6487
- if (_optionalChain([state, 'access', _281 => _281.lastEvent, 'optionalAccess', _282 => _282.type]) === "deposit-received") return "received";
6891
+ if (_optionalChain([state, 'access', _295 => _295.lastEvent, 'optionalAccess', _296 => _296.type]) === "deposit-received") return "received";
6488
6892
  return "confirming";
6489
6893
  }
6490
6894
  function getCompletionDestinationTxHash(event) {
6491
- const eventData = _optionalChain([event, 'optionalAccess', _283 => _283.data]);
6492
- const swapTxHash = _optionalChain([eventData, 'optionalAccess', _284 => _284.swap, 'optionalAccess', _285 => _285.transactionHash]);
6493
- const destinationTxHash = _optionalChain([eventData, 'optionalAccess', _286 => _286.destination, 'optionalAccess', _287 => _287.transactionHash]);
6895
+ const eventData = _optionalChain([event, 'optionalAccess', _297 => _297.data]);
6896
+ const swapTxHash = _optionalChain([eventData, 'optionalAccess', _298 => _298.swap, 'optionalAccess', _299 => _299.transactionHash]);
6897
+ const destinationTxHash = _optionalChain([eventData, 'optionalAccess', _300 => _300.destination, 'optionalAccess', _301 => _301.transactionHash]);
6494
6898
  return _nullishCoalesce(swapTxHash, () => ( destinationTxHash));
6495
6899
  }
6496
6900
  function getTerminalProcessingOutcome(event) {
6497
- if (_optionalChain([event, 'optionalAccess', _288 => _288.type]) === "post-bridge-swap-complete") {
6901
+ if (_optionalChain([event, 'optionalAccess', _302 => _302.type]) === "post-bridge-swap-complete") {
6498
6902
  return {
6499
6903
  type: "complete",
6500
6904
  destinationTxHash: getCompletionDestinationTxHash(event)
6501
6905
  };
6502
6906
  }
6503
- if (_optionalChain([event, 'optionalAccess', _289 => _289.type]) === "post-bridge-swap-failed") {
6907
+ if (_optionalChain([event, 'optionalAccess', _303 => _303.type]) === "post-bridge-swap-failed") {
6504
6908
  return {
6505
6909
  type: "failed",
6506
6910
  message: formatBridgeFailedMessage(event).message
6507
6911
  };
6508
6912
  }
6509
- if (_optionalChain([event, 'optionalAccess', _290 => _290.type]) === "bridge-complete") {
6913
+ if (_optionalChain([event, 'optionalAccess', _304 => _304.type]) === "bridge-complete") {
6510
6914
  return {
6511
6915
  type: "complete",
6512
6916
  destinationTxHash: getCompletionDestinationTxHash(event)
6513
6917
  };
6514
6918
  }
6515
- if (_optionalChain([event, 'optionalAccess', _291 => _291.type]) === "bridge-failed") {
6919
+ if (_optionalChain([event, 'optionalAccess', _305 => _305.type]) === "bridge-failed") {
6516
6920
  return {
6517
6921
  type: "failed",
6518
6922
  message: formatBridgeFailedMessage(event).message
6519
6923
  };
6520
6924
  }
6521
- if (_optionalChain([event, 'optionalAccess', _292 => _292.type]) === "error") {
6925
+ if (_optionalChain([event, 'optionalAccess', _306 => _306.type]) === "error") {
6522
6926
  return {
6523
6927
  type: "failed",
6524
- message: _nullishCoalesce(_optionalChain([event, 'access', _293 => _293.data, 'optionalAccess', _294 => _294.message]), () => ( "Unknown error"))
6928
+ message: _nullishCoalesce(_optionalChain([event, 'access', _307 => _307.data, 'optionalAccess', _308 => _308.message]), () => ( "Unknown error"))
6525
6929
  };
6526
6930
  }
6527
6931
  return null;
@@ -6529,10 +6933,10 @@ function getTerminalProcessingOutcome(event) {
6529
6933
  function getInitialProcessingState(event, txHash) {
6530
6934
  if (!event || !isEventForTx(event, txHash)) return null;
6531
6935
  const terminal = getTerminalProcessingOutcome(event);
6532
- if (_optionalChain([terminal, 'optionalAccess', _295 => _295.type]) === "complete") {
6936
+ if (_optionalChain([terminal, 'optionalAccess', _309 => _309.type]) === "complete") {
6533
6937
  return { type: "complete", lastEvent: event };
6534
6938
  }
6535
- if (_optionalChain([terminal, 'optionalAccess', _296 => _296.type]) === "failed") {
6939
+ if (_optionalChain([terminal, 'optionalAccess', _310 => _310.type]) === "failed") {
6536
6940
  return { type: "failed", message: terminal.message, lastEvent: event };
6537
6941
  }
6538
6942
  if (isDepositEvent(event)) {
@@ -6541,7 +6945,7 @@ function getInitialProcessingState(event, txHash) {
6541
6945
  return null;
6542
6946
  }
6543
6947
  function getSettledSourceTxHash(event, fallbackTxHash) {
6544
- return _nullishCoalesce(_optionalChain([event, 'optionalAccess', _297 => _297.data, 'optionalAccess', _298 => _298.source, 'optionalAccess', _299 => _299.transactionHash]), () => ( fallbackTxHash));
6948
+ return _nullishCoalesce(_optionalChain([event, 'optionalAccess', _311 => _311.data, 'optionalAccess', _312 => _312.source, 'optionalAccess', _313 => _313.transactionHash]), () => ( fallbackTxHash));
6545
6949
  }
6546
6950
  function ProcessingStep({
6547
6951
  smartAccount,
@@ -6610,7 +7014,6 @@ function ProcessingStep({
6610
7014
  }
6611
7015
  return { type: "processing" };
6612
7016
  });
6613
- const [elapsedSeconds, setElapsedSeconds] = _react.useState.call(void 0, 0);
6614
7017
  const [phaseTimings, setPhaseTimings] = _react.useState.call(void 0, () => {
6615
7018
  const saved = loadPhaseTimings(txHash);
6616
7019
  if (saved) {
@@ -6619,7 +7022,15 @@ function ProcessingStep({
6619
7022
  }
6620
7023
  return { startedAt: startTimeRef.current };
6621
7024
  });
6622
- const [hasEscalatedDelay, setHasEscalatedDelay] = _react.useState.call(void 0, false);
7025
+ const [elapsedSeconds, setElapsedSeconds] = _react.useState.call(void 0,
7026
+ () => Math.max(0, Math.floor((Date.now() - startTimeRef.current) / 1e3))
7027
+ );
7028
+ const [latchedTiming, setLatchedTiming] = _react.useState.call(void 0, _optionalChain([quote, 'optionalAccess', _314 => _314.timing]));
7029
+ if (latchedTiming === void 0 && _optionalChain([quote, 'optionalAccess', _315 => _315.timing]) !== void 0) {
7030
+ setLatchedTiming(quote.timing);
7031
+ }
7032
+ const timingStateRef = _react.useRef.call(void 0, "expected");
7033
+ const servedTimingLatchRef = _react.useRef.call(void 0, false);
6623
7034
  const updatePhaseTimings = _react.useCallback.call(void 0,
6624
7035
  (updater) => {
6625
7036
  setPhaseTimings((previous) => {
@@ -6646,7 +7057,7 @@ function ProcessingStep({
6646
7057
  flowLabel
6647
7058
  });
6648
7059
  const context = processingContextRef.current;
6649
- _optionalChain([onDepositCompleteRef, 'access', _300 => _300.current, 'optionalCall', _301 => _301(txHash, void 0, {
7060
+ _optionalChain([onDepositCompleteRef, 'access', _316 => _316.current, 'optionalCall', _317 => _317(txHash, void 0, {
6650
7061
  amount: context.amount,
6651
7062
  sourceChain: context.sourceChain,
6652
7063
  sourceToken: context.sourceToken,
@@ -6679,7 +7090,7 @@ function ProcessingStep({
6679
7090
  destinationTxHash: outcome.destinationTxHash,
6680
7091
  event: event.type
6681
7092
  });
6682
- _optionalChain([onDepositCompleteRef, 'access', _302 => _302.current, 'optionalCall', _303 => _303(
7093
+ _optionalChain([onDepositCompleteRef, 'access', _318 => _318.current, 'optionalCall', _319 => _319(
6683
7094
  sourceTxHash2,
6684
7095
  outcome.destinationTxHash,
6685
7096
  {
@@ -6699,7 +7110,7 @@ function ProcessingStep({
6699
7110
  message: outcome.message,
6700
7111
  event: event.type
6701
7112
  });
6702
- _optionalChain([onDepositFailedRef, 'access', _304 => _304.current, 'optionalCall', _305 => _305(txHash, outcome.message)]);
7113
+ _optionalChain([onDepositFailedRef, 'access', _320 => _320.current, 'optionalCall', _321 => _321(txHash, outcome.message)]);
6703
7114
  }, [
6704
7115
  debug,
6705
7116
  onDepositCompleteRef,
@@ -6710,8 +7121,8 @@ function ProcessingStep({
6710
7121
  const onSettledChangeRef = _react.useRef.call(void 0, onSettledChange);
6711
7122
  onSettledChangeRef.current = onSettledChange;
6712
7123
  _react.useEffect.call(void 0, () => {
6713
- _optionalChain([onSettledChangeRef, 'access', _306 => _306.current, 'optionalCall', _307 => _307(state.type !== "processing")]);
6714
- return () => _optionalChain([onSettledChangeRef, 'access', _308 => _308.current, 'optionalCall', _309 => _309(false)]);
7124
+ _optionalChain([onSettledChangeRef, 'access', _322 => _322.current, 'optionalCall', _323 => _323(state.type !== "processing")]);
7125
+ return () => _optionalChain([onSettledChangeRef, 'access', _324 => _324.current, 'optionalCall', _325 => _325(false)]);
6715
7126
  }, [state.type]);
6716
7127
  _react.useEffect.call(void 0, () => {
6717
7128
  if (directTransfer || state.type !== "processing") return;
@@ -6737,13 +7148,13 @@ function ProcessingStep({
6737
7148
  updatePhaseTimings(
6738
7149
  (previous) => syncPhaseTimings(previous, state.lastEvent)
6739
7150
  );
6740
- }, [_optionalChain([state, 'access', _310 => _310.lastEvent, 'optionalAccess', _311 => _311.time]), _optionalChain([state, 'access', _312 => _312.lastEvent, 'optionalAccess', _313 => _313.type]), updatePhaseTimings]);
7151
+ }, [_optionalChain([state, 'access', _326 => _326.lastEvent, 'optionalAccess', _327 => _327.time]), _optionalChain([state, 'access', _328 => _328.lastEvent, 'optionalAccess', _329 => _329.type]), updatePhaseTimings]);
6741
7152
  const [swappedFiatContext, setSwappedFiatContext] = _react.useState.call(void 0, null);
6742
7153
  _react.useEffect.call(void 0, () => {
6743
7154
  let cancelled = false;
6744
7155
  let timeoutId;
6745
- const isFiatSwappedOrder = isSwappedOrder && _optionalChain([swappedContext, 'optionalAccess', _314 => _314.variant]) === "fiat";
6746
- const expectedOrderUuid = _nullishCoalesce(_optionalChain([swappedContext, 'optionalAccess', _315 => _315.expectedOrderUuid]), () => ( null));
7156
+ const isFiatSwappedOrder = isSwappedOrder && _optionalChain([swappedContext, 'optionalAccess', _330 => _330.variant]) === "fiat";
7157
+ const expectedOrderUuid = _nullishCoalesce(_optionalChain([swappedContext, 'optionalAccess', _331 => _331.expectedOrderUuid]), () => ( null));
6747
7158
  setSwappedFiatContext(null);
6748
7159
  if (isFiatSwappedOrder && !expectedOrderUuid) {
6749
7160
  return () => {
@@ -6779,7 +7190,7 @@ function ProcessingStep({
6779
7190
  if (isFiatSwappedOrder && !hasFiatReceiptPricing(res)) {
6780
7191
  scheduleRetry();
6781
7192
  }
6782
- } catch (e18) {
7193
+ } catch (e19) {
6783
7194
  scheduleRetry();
6784
7195
  }
6785
7196
  }
@@ -6793,8 +7204,8 @@ function ProcessingStep({
6793
7204
  smartAccount,
6794
7205
  txHash,
6795
7206
  isSwappedOrder,
6796
- _optionalChain([swappedContext, 'optionalAccess', _316 => _316.variant]),
6797
- _optionalChain([swappedContext, 'optionalAccess', _317 => _317.expectedOrderUuid])
7207
+ _optionalChain([swappedContext, 'optionalAccess', _332 => _332.variant]),
7208
+ _optionalChain([swappedContext, 'optionalAccess', _333 => _333.expectedOrderUuid])
6798
7209
  ]);
6799
7210
  _react.useEffect.call(void 0, () => {
6800
7211
  if (directTransfer) return;
@@ -6820,17 +7231,17 @@ function ProcessingStep({
6820
7231
  debugLog(debug, "processing", "poll:event", {
6821
7232
  type: lastEvent2.type,
6822
7233
  matchesTx: eventMatchesTx,
6823
- intentId: _optionalChain([eventData, 'optionalAccess', _318 => _318.intentId])
7234
+ intentId: _optionalChain([eventData, 'optionalAccess', _334 => _334.intentId])
6824
7235
  });
6825
7236
  }
6826
7237
  if (!isMounted) return;
6827
- if (_optionalChain([eventForCurrentTx, 'optionalAccess', _319 => _319.type]) === "bridge-complete") {
7238
+ if (_optionalChain([eventForCurrentTx, 'optionalAccess', _335 => _335.type]) === "bridge-complete") {
6828
7239
  setState({ type: "complete", lastEvent: eventForCurrentTx });
6829
7240
  const sourceTxHash2 = getSettledSourceTxHash(
6830
7241
  eventForCurrentTx,
6831
7242
  txHash
6832
7243
  );
6833
- const destinationTxHash2 = _optionalChain([eventForCurrentTx, 'access', _320 => _320.data, 'optionalAccess', _321 => _321.destination, 'optionalAccess', _322 => _322.transactionHash]);
7244
+ const destinationTxHash2 = _optionalChain([eventForCurrentTx, 'access', _336 => _336.data, 'optionalAccess', _337 => _337.destination, 'optionalAccess', _338 => _338.transactionHash]);
6834
7245
  debugLog(debug, "processing", "state:complete", {
6835
7246
  txHash,
6836
7247
  sourceTxHash: sourceTxHash2,
@@ -6838,7 +7249,7 @@ function ProcessingStep({
6838
7249
  event: eventForCurrentTx.type
6839
7250
  });
6840
7251
  const context = processingContextRef.current;
6841
- _optionalChain([onDepositCompleteRef, 'access', _323 => _323.current, 'optionalCall', _324 => _324(sourceTxHash2, destinationTxHash2, {
7252
+ _optionalChain([onDepositCompleteRef, 'access', _339 => _339.current, 'optionalCall', _340 => _340(sourceTxHash2, destinationTxHash2, {
6842
7253
  amount: context.amount,
6843
7254
  sourceChain: context.sourceChain,
6844
7255
  sourceToken: context.sourceToken,
@@ -6849,7 +7260,7 @@ function ProcessingStep({
6849
7260
  })]);
6850
7261
  return;
6851
7262
  }
6852
- if (_optionalChain([eventForCurrentTx, 'optionalAccess', _325 => _325.type]) === "bridge-failed") {
7263
+ if (_optionalChain([eventForCurrentTx, 'optionalAccess', _341 => _341.type]) === "bridge-failed") {
6853
7264
  const formatted = formatBridgeFailedMessage(eventForCurrentTx);
6854
7265
  setState({
6855
7266
  type: "failed",
@@ -6861,11 +7272,11 @@ function ProcessingStep({
6861
7272
  message: formatted.message,
6862
7273
  code: formatted.code
6863
7274
  });
6864
- _optionalChain([onDepositFailedRef, 'access', _326 => _326.current, 'optionalCall', _327 => _327(txHash, formatted.message)]);
7275
+ _optionalChain([onDepositFailedRef, 'access', _342 => _342.current, 'optionalCall', _343 => _343(txHash, formatted.message)]);
6865
7276
  return;
6866
7277
  }
6867
- if (_optionalChain([eventForCurrentTx, 'optionalAccess', _328 => _328.type]) === "error") {
6868
- const errorMessage = _nullishCoalesce(_optionalChain([eventForCurrentTx, 'access', _329 => _329.data, 'optionalAccess', _330 => _330.message]), () => ( "Unknown error"));
7278
+ if (_optionalChain([eventForCurrentTx, 'optionalAccess', _344 => _344.type]) === "error") {
7279
+ const errorMessage = _nullishCoalesce(_optionalChain([eventForCurrentTx, 'access', _345 => _345.data, 'optionalAccess', _346 => _346.message]), () => ( "Unknown error"));
6869
7280
  setState({
6870
7281
  type: "failed",
6871
7282
  message: errorMessage,
@@ -6875,7 +7286,7 @@ function ProcessingStep({
6875
7286
  txHash,
6876
7287
  message: errorMessage
6877
7288
  });
6878
- _optionalChain([onDepositFailedRef, 'access', _331 => _331.current, 'optionalCall', _332 => _332(txHash, errorMessage)]);
7289
+ _optionalChain([onDepositFailedRef, 'access', _347 => _347.current, 'optionalCall', _348 => _348(txHash, errorMessage)]);
6879
7290
  return;
6880
7291
  }
6881
7292
  setState((previous) => ({
@@ -6925,21 +7336,6 @@ function ProcessingStep({
6925
7336
  state.type,
6926
7337
  txHash
6927
7338
  ]);
6928
- _react.useEffect.call(void 0, () => {
6929
- if (directTransfer || state.type !== "processing") return;
6930
- const timeoutId = setTimeout(() => {
6931
- if (escalatedDelayRef.current) return;
6932
- escalatedDelayRef.current = true;
6933
- setHasEscalatedDelay(true);
6934
- const message = "Transfer is taking longer than expected. Your funds are safe and processing will continue automatically.";
6935
- debugLog(debug, "processing", "state:delay-escalated", {
6936
- txHash,
6937
- timeoutMs: ESCALATED_DELAY_MS
6938
- });
6939
- _optionalChain([onErrorRef, 'access', _333 => _333.current, 'optionalCall', _334 => _334(message, "PROCESS_TIMEOUT")]);
6940
- }, ESCALATED_DELAY_MS);
6941
- return () => clearTimeout(timeoutId);
6942
- }, [debug, directTransfer, onErrorRef, state.type, txHash]);
6943
7339
  const isComplete = state.type === "complete";
6944
7340
  const isFailed = state.type === "failed";
6945
7341
  const isProcessing = state.type === "processing";
@@ -6948,18 +7344,18 @@ function ProcessingStep({
6948
7344
  const timelineNowMs = _nullishCoalesce(phaseTimings.endedAt, () => ( Date.now()));
6949
7345
  const flowNoun = flowLabel === "withdraw" ? "withdrawal" : "deposit";
6950
7346
  const flowCapitalized = flowLabel === "withdraw" ? "Withdrawal" : "Deposit";
6951
- const destinationTxHash = _optionalChain([lastEvent, 'optionalAccess', _335 => _335.data, 'optionalAccess', _336 => _336.destination, 'optionalAccess', _337 => _337.transactionHash]) || null;
7347
+ const destinationTxHash = _optionalChain([lastEvent, 'optionalAccess', _349 => _349.data, 'optionalAccess', _350 => _350.destination, 'optionalAccess', _351 => _351.transactionHash]) || null;
6952
7348
  const sourceTxHash = getSettledSourceTxHash(lastEvent, txHash);
6953
7349
  const sourceDetails = getEventSourceDetails(lastEvent);
6954
7350
  const displaySourceChain = _nullishCoalesce(sourceDetails.chainId, () => ( sourceChain));
6955
7351
  const displaySourceToken = _nullishCoalesce(sourceDetails.token, () => ( sourceToken));
6956
7352
  const displayAmount = _nullishCoalesce(sourceDetails.amount, () => ( amount));
6957
7353
  const targetChainId = _chunkOY5N3E6Lcjs.targetChainToChainId.call(void 0, targetChain);
6958
- const settledSourceTxHash = _optionalChain([lastEvent, 'optionalAccess', _338 => _338.data, 'optionalAccess', _339 => _339.source, 'optionalAccess', _340 => _340.transactionHash]);
7354
+ const settledSourceTxHash = _optionalChain([lastEvent, 'optionalAccess', _352 => _352.data, 'optionalAccess', _353 => _353.source, 'optionalAccess', _354 => _354.transactionHash]);
6959
7355
  const sourceExplorerHash = _nullishCoalesce(settledSourceTxHash, () => ( (sourceTxHashPending ? null : sourceTxHash)));
6960
7356
  _react.useEffect.call(void 0, () => {
6961
7357
  if (sourceTxHashPending && settledSourceTxHash) {
6962
- _optionalChain([onSourceTransactionObserved, 'optionalCall', _341 => _341(settledSourceTxHash)]);
7358
+ _optionalChain([onSourceTransactionObserved, 'optionalCall', _355 => _355(settledSourceTxHash)]);
6963
7359
  }
6964
7360
  }, [onSourceTransactionObserved, settledSourceTxHash, sourceTxHashPending]);
6965
7361
  const sourceExplorerUrl = sourceExplorerHash ? explorerTxUrl(displaySourceChain, sourceExplorerHash) : null;
@@ -7039,16 +7435,50 @@ function ProcessingStep({
7039
7435
  const currentPhaseId = getCurrentPhaseId(state, phaseTimings);
7040
7436
  const activePhaseStartedAt = currentPhaseId ? getPhaseStartTime(currentPhaseId, phaseTimings) : void 0;
7041
7437
  const activePhaseElapsedMs = isProcessing && activePhaseStartedAt !== void 0 ? timelineNowMs - activePhaseStartedAt : 0;
7042
- const delayPhaseId = isProcessing && currentPhaseId && activePhaseElapsedMs >= SOFT_DELAY_MS[currentPhaseId] ? currentPhaseId : void 0;
7043
- void delayPhaseId;
7044
- void hasEscalatedDelay;
7438
+ if (latchedTiming !== void 0 && !servedTimingLatchRef.current) {
7439
+ servedTimingLatchRef.current = true;
7440
+ timingStateRef.current = "expected";
7441
+ }
7442
+ const timingState = isProcessing ? advancePendingTimingState(
7443
+ timingStateRef.current,
7444
+ resolvePendingTimingState({
7445
+ timing: latchedTiming,
7446
+ totalElapsedMs: elapsedSeconds * 1e3,
7447
+ phaseId: currentPhaseId,
7448
+ phaseElapsedMs: activePhaseElapsedMs
7449
+ })
7450
+ ) : timingStateRef.current;
7451
+ timingStateRef.current = timingState;
7452
+ const expectedDuration = latchedTiming && timingState === "expected" ? formatExpectedDuration(latchedTiming.expectedSeconds) : void 0;
7453
+ _react.useEffect.call(void 0, () => {
7454
+ if (directTransfer || !isProcessing || timingState !== "escalated") return;
7455
+ if (escalatedDelayRef.current) return;
7456
+ escalatedDelayRef.current = true;
7457
+ debugLog(debug, "processing", "state:delay-escalated", {
7458
+ txHash,
7459
+ timeoutMs: latchedTiming ? resolveServedThresholds(latchedTiming).escalatedMs : FALLBACK_ESCALATED_DELAY_MS,
7460
+ served: latchedTiming !== void 0
7461
+ });
7462
+ _optionalChain([onErrorRef, 'access', _356 => _356.current, 'optionalCall', _357 => _357(
7463
+ "Transfer is taking longer than expected. Your funds are safe and processing will continue automatically.",
7464
+ "PROCESS_TIMEOUT"
7465
+ )]);
7466
+ }, [
7467
+ debug,
7468
+ directTransfer,
7469
+ isProcessing,
7470
+ latchedTiming,
7471
+ onErrorRef,
7472
+ timingState,
7473
+ txHash
7474
+ ]);
7045
7475
  const sourceChainIcon = _chunkOY5N3E6Lcjs.getChainIcon.call(void 0, displaySourceChain);
7046
7476
  const targetChainIcon = _chunkOY5N3E6Lcjs.getChainIcon.call(void 0, targetChainId);
7047
7477
  const sourceChainName = _chunkOY5N3E6Lcjs.getChainName.call(void 0, displaySourceChain);
7048
7478
  const targetChainName = _chunkOY5N3E6Lcjs.getChainName.call(void 0, targetChainId);
7049
7479
  const timerText = formatTimer(elapsedSeconds);
7050
- const feeSponsored = _nullishCoalesce(_optionalChain([uiConfig, 'optionalAccess', _342 => _342.feeSponsored]), () => ( false));
7051
- const feeTooltip = _nullishCoalesce(_optionalChain([uiConfig, 'optionalAccess', _343 => _343.feeTooltip]), () => ( (feeSponsored ? "Network fees are sponsored for this deposit." : "Network fees apply.")));
7480
+ const feeSponsored = _nullishCoalesce(_optionalChain([uiConfig, 'optionalAccess', _358 => _358.feeSponsored]), () => ( false));
7481
+ const feeTooltip = _nullishCoalesce(_optionalChain([uiConfig, 'optionalAccess', _359 => _359.feeTooltip]), () => ( (feeSponsored ? "Network fees are sponsored for this deposit." : "Network fees apply.")));
7052
7482
  const stateTitle = isComplete ? `${flowCapitalized} successful` : isFailed ? `${flowCapitalized} failed` : "Processing...";
7053
7483
  const handleRetry = _nullishCoalesce(onRetry, () => ( onNewDeposit));
7054
7484
  const headerContent = isComplete ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "rs-body-header", children: [
@@ -7059,20 +7489,20 @@ function ProcessingStep({
7059
7489
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "rs-body-header-text", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: "rs-body-header-title", children: stateTitle }) })
7060
7490
  ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, BodyHeader, { icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, WalletIcon, {}), title: stateTitle });
7061
7491
  if (isComplete && isSwappedOrder) {
7062
- const effectivePaymentMethod = _nullishCoalesce(_nullishCoalesce(_optionalChain([swappedContext, 'optionalAccess', _344 => _344.method]), () => ( _optionalChain([swappedFiatContext, 'optionalAccess', _345 => _345.paymentMethod]))), () => ( null));
7492
+ const effectivePaymentMethod = _nullishCoalesce(_nullishCoalesce(_optionalChain([swappedContext, 'optionalAccess', _360 => _360.method]), () => ( _optionalChain([swappedFiatContext, 'optionalAccess', _361 => _361.paymentMethod]))), () => ( null));
7063
7493
  const onrampMethod = effectivePaymentMethod ? formatPaymentMethod(effectivePaymentMethod) : null;
7064
- const onrampMethodIcon = _optionalChain([swappedContext, 'optionalAccess', _346 => _346.variant]) === "connect" && effectivePaymentMethod ? getExchangeLogoSrc(
7494
+ const onrampMethodIcon = _optionalChain([swappedContext, 'optionalAccess', _362 => _362.variant]) === "connect" && effectivePaymentMethod ? getExchangeLogoSrc(
7065
7495
  _nullishCoalesce(onrampMethod, () => ( effectivePaymentMethod)),
7066
7496
  effectivePaymentMethod
7067
7497
  ) : null;
7068
- const connectPaidAmount = _optionalChain([swappedContext, 'optionalAccess', _347 => _347.variant]) === "connect" ? `${formattedSentAmount} ${sourceSymbol}` : null;
7069
- const amountPaid = _nullishCoalesce(connectPaidAmount, () => ( (_optionalChain([swappedFiatContext, 'optionalAccess', _348 => _348.paidAmountUsd]) != null ? `$${swappedFiatContext.paidAmountUsd.toFixed(2)}` : null)));
7498
+ const connectPaidAmount = _optionalChain([swappedContext, 'optionalAccess', _363 => _363.variant]) === "connect" ? `${formattedSentAmount} ${sourceSymbol}` : null;
7499
+ const amountPaid = _nullishCoalesce(connectPaidAmount, () => ( (_optionalChain([swappedFiatContext, 'optionalAccess', _364 => _364.paidAmountUsd]) != null ? `$${swappedFiatContext.paidAmountUsd.toFixed(2)}` : null)));
7070
7500
  const depositedAmount = receiveDisplay;
7071
- const onrampFeeUsd = _nullishCoalesce(_optionalChain([swappedFiatContext, 'optionalAccess', _349 => _349.onrampFeeUsd]), () => ( null));
7501
+ const onrampFeeUsd = _nullishCoalesce(_optionalChain([swappedFiatContext, 'optionalAccess', _365 => _365.onrampFeeUsd]), () => ( null));
7072
7502
  const sponsoredFeeTooltip = "This fee is sponsored for this deposit.";
7073
7503
  const feesTooltip = feeSponsored ? "On-ramp fees are charged by the payment provider. Market and network fees are sponsored for this deposit." : "Fees include on-ramp, market, and network costs for this deposit.";
7074
7504
  const { rows: quoteFeeRows, chargeableUsd } = buildQuoteFeeRows(
7075
- _optionalChain([quote, 'optionalAccess', _350 => _350.fees, 'access', _351 => _351.breakdown]),
7505
+ _optionalChain([quote, 'optionalAccess', _366 => _366.fees, 'access', _367 => _367.breakdown]),
7076
7506
  sponsoredFeeTooltip
7077
7507
  );
7078
7508
  const feeRows = [];
@@ -7159,7 +7589,7 @@ function ProcessingStep({
7159
7589
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "rs-review-detail-value", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Ticker, { value: timerText }) })
7160
7590
  ] }),
7161
7591
  isSwappedOrder ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
7162
- _optionalChain([swappedFiatContext, 'optionalAccess', _352 => _352.paidAmountUsd]) != null && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "rs-review-detail-row", children: [
7592
+ _optionalChain([swappedFiatContext, 'optionalAccess', _368 => _368.paidAmountUsd]) != null && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "rs-review-detail-row", children: [
7163
7593
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: "You pay" }),
7164
7594
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "rs-review-detail-value", children: [
7165
7595
  "$",
@@ -7171,7 +7601,7 @@ function ProcessingStep({
7171
7601
  ] })
7172
7602
  ] })
7173
7603
  ] }),
7174
- _optionalChain([swappedFiatContext, 'optionalAccess', _353 => _353.onrampFeeUsd]) != null && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "rs-review-detail-row", children: [
7604
+ _optionalChain([swappedFiatContext, 'optionalAccess', _369 => _369.onrampFeeUsd]) != null && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "rs-review-detail-row", children: [
7175
7605
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: "On-ramp fee" }),
7176
7606
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "rs-review-detail-value", children: [
7177
7607
  "$",
@@ -7238,7 +7668,7 @@ function ProcessingStep({
7238
7668
  ) })
7239
7669
  ] })
7240
7670
  ] }) : (() => {
7241
- const { display, struck } = quoteFeeRow(_optionalChain([quote, 'optionalAccess', _354 => _354.fees]));
7671
+ const { display, struck } = quoteFeeRow(_optionalChain([quote, 'optionalAccess', _370 => _370.fees]));
7242
7672
  if (display !== null) {
7243
7673
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "rs-review-detail-row", children: [
7244
7674
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: "Fees" }),
@@ -7270,6 +7700,11 @@ function ProcessingStep({
7270
7700
  })()
7271
7701
  ] }),
7272
7702
  isFailed && failureMessage && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Callout, { variant: "error", children: failureMessage }),
7703
+ isProcessing && expectedDuration !== void 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "rs-pending-expectation", children: [
7704
+ "Usually arrives in ",
7705
+ expectedDuration
7706
+ ] }),
7707
+ isProcessing && latchedTiming !== void 0 && timingState !== "expected" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Callout, { variant: "warning", children: timingState === "soft" ? "Taking longer than usual. Your funds are safe and this will complete automatically." : "This is taking much longer than usual. Your funds are safe and processing continues automatically." }),
7273
7708
  isProcessing && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
7274
7709
  Button,
7275
7710
  {
@@ -7382,7 +7817,7 @@ var setupRequestDedupe = /* @__PURE__ */ new Map();
7382
7817
  function readDedupedAccountSetupResult(requestKey) {
7383
7818
  const now = Date.now();
7384
7819
  const existing = setupRequestDedupe.get(requestKey);
7385
- if (_optionalChain([existing, 'optionalAccess', _355 => _355.settled]) && existing.expiresAt > now && existing.result) {
7820
+ if (_optionalChain([existing, 'optionalAccess', _371 => _371.settled]) && existing.expiresAt > now && existing.result) {
7386
7821
  return existing.result;
7387
7822
  }
7388
7823
  return null;
@@ -7416,7 +7851,7 @@ async function runAccountSetup(input, deps) {
7416
7851
  chain: _chunkOY5N3E6Lcjs.targetChainToCaip2.call(void 0, input.targetChain),
7417
7852
  token: input.targetToken,
7418
7853
  recipient: input.recipient,
7419
- ..._optionalChain([input, 'access', _356 => _356.outputTokenRules, 'optionalAccess', _357 => _357.length]) && {
7854
+ ..._optionalChain([input, 'access', _372 => _372.outputTokenRules, 'optionalAccess', _373 => _373.length]) && {
7420
7855
  outputTokenRules: input.outputTokenRules
7421
7856
  },
7422
7857
  ...input.rejectUnmapped != null && {
@@ -7596,4 +8031,11 @@ function mapError(error) {
7596
8031
 
7597
8032
 
7598
8033
 
7599
- exports.Modal = Modal; exports.WalletIcon = WalletIcon; exports.ExternalLinkIcon = ExternalLinkIcon; exports.CheckIcon = CheckIcon; exports.TransferCryptoIcon = TransferCryptoIcon; exports.ChevronLeftIcon = ChevronLeftIcon; exports.ChevronDownIcon = ChevronDownIcon; exports.CloseIcon = CloseIcon; exports.HandCoinsIcon = HandCoinsIcon; exports.InfoIcon = InfoIcon; exports.CopyIcon = CopyIcon; exports.CircleArrowOutUpLeftIcon = CircleArrowOutUpLeftIcon; exports.CardIcon = CardIcon; exports.BankIcon = BankIcon; exports.UnplugIcon = UnplugIcon; exports.MigrateAssetsIcon = MigrateAssetsIcon; exports.AppleIcon = AppleIcon; exports.BodyHeader = BodyHeader; exports.CdnIcon = CdnIcon; exports.ListRow = ListRow; exports.PoweredBy = PoweredBy; exports.Spinner = Spinner; exports.catalogKeyForChain = catalogKeyForChain; exports.debugLog = debugLog; exports.debugError = debugError; exports.getAssetId = getAssetId; exports.chainIdsByValue = chainIdsByValue; exports.portfolioToAssets = portfolioToAssets; exports.isNativeAsset = isNativeAsset; exports.quoteFeeRow = quoteFeeRow; exports.SwappedConnectFeeChangedError = SwappedConnectFeeChangedError; exports.SUPPORTED_CONNECT_EXCHANGE_COUNT = SUPPORTED_CONNECT_EXCHANGE_COUNT; exports.resolveAppFeeBps = resolveAppFeeBps; exports.PermitDepositSubmitError = PermitDepositSubmitError; exports.createDepositService = createDepositService; exports.rpcUrlFor = rpcUrlFor; exports.RpcUrlsProvider = RpcUrlsProvider; exports.useRpcUrls = useRpcUrls; exports.useStableRpcUrls = useStableRpcUrls; exports.getPublicClient = getPublicClient; exports.peekRuntimeChains = peekRuntimeChains; exports.primeRuntimeChains = primeRuntimeChains; exports.useChainCatalog = useChainCatalog; exports.useCatalogChain = useCatalogChain; exports.useDepositChainIds = useDepositChainIds; exports.useDestinationChains = useDestinationChains; exports.useTargetTokens = useTargetTokens; exports.useIsDepositChain = useIsDepositChain; exports.useChainName = useChainName; exports.useReadClient = useReadClient; exports.useExplorerTxUrl = useExplorerTxUrl; exports.ChainCatalogProvider = ChainCatalogProvider; exports.getExchangeLogoSrc = getExchangeLogoSrc; exports.getExchangeLogo = getExchangeLogo; exports.useLatestRef = useLatestRef; exports.Button = Button; exports.Callout = Callout; exports.TokenIcon = TokenIcon; exports.currencyFormatter = currencyFormatter; exports.tokenFormatter = tokenFormatter; exports.isUnsupportedChainSwitchError = isUnsupportedChainSwitchError; exports.formatUserError = formatUserError; exports.Tooltip = Tooltip; exports.markSubmissionUncertain = markSubmissionUncertain; exports.isSubmissionUncertain = isSubmissionUncertain; exports.formatTokenAmount = formatTokenAmount; exports.isDisplayStablecoinSymbol = isDisplayStablecoinSymbol; exports.isRecognizedToken = isRecognizedToken; exports.formatQuotedReceive = formatQuotedReceive; exports.formatReceiveEstimate = formatReceiveEstimate; exports.getEventTxHash = getEventTxHash; exports.getEventSourceDetails = getEventSourceDetails; exports.isDepositEvent = isDepositEvent; exports.isFailedEvent = isFailedEvent; exports.txRefsMatch = txRefsMatch; exports.failureMessageForEvent = failureMessageForEvent; exports.fetchTokenPriceUsd = fetchTokenPriceUsd; exports.useTokenPrices = useTokenPrices; exports.ProcessingStep = ProcessingStep; exports.AnalyticsSession = AnalyticsSession; exports.useDepositAnalyticsEmitter = useDepositAnalyticsEmitter; exports.useWithdrawAnalyticsEmitter = useWithdrawAnalyticsEmitter; exports.SetupError = SetupError; exports.deriveAccountSalt = deriveAccountSalt; exports.computeRequestKey = computeRequestKey; exports.computeCacheKey = computeCacheKey; exports.computeIsCacheable = computeIsCacheable; exports.readDedupedAccountSetupResult = readDedupedAccountSetupResult; exports.runAccountSetupDeduped = runAccountSetupDeduped; exports.HistoryEntryButton = HistoryEntryButton; exports.HistoryOverlay = HistoryOverlay; exports.useHistoryPanel = useHistoryPanel; exports.resolveThemeMode = resolveThemeMode; exports.followSystemAppearance = followSystemAppearance; exports.applyTheme = applyTheme; exports.warnRemovedProps = warnRemovedProps; exports.checkBackendUrl = checkBackendUrl; exports.isHistoryEntryVisible = isHistoryEntryVisible; exports.createHistoryAnalytics = createHistoryAnalytics; exports.analyticsTargetProperties = analyticsTargetProperties;
8034
+
8035
+
8036
+
8037
+
8038
+
8039
+
8040
+
8041
+ exports.Modal = Modal; exports.WalletIcon = WalletIcon; exports.ExternalLinkIcon = ExternalLinkIcon; exports.CheckIcon = CheckIcon; exports.TransferCryptoIcon = TransferCryptoIcon; exports.ChevronLeftIcon = ChevronLeftIcon; exports.ChevronDownIcon = ChevronDownIcon; exports.CloseIcon = CloseIcon; exports.HandCoinsIcon = HandCoinsIcon; exports.InfoIcon = InfoIcon; exports.CopyIcon = CopyIcon; exports.CircleArrowOutUpLeftIcon = CircleArrowOutUpLeftIcon; exports.CardIcon = CardIcon; exports.BankIcon = BankIcon; exports.UnplugIcon = UnplugIcon; exports.MigrateAssetsIcon = MigrateAssetsIcon; exports.AppleIcon = AppleIcon; exports.BodyHeader = BodyHeader; exports.CdnIcon = CdnIcon; exports.ListRow = ListRow; exports.PoweredBy = PoweredBy; exports.Spinner = Spinner; exports.catalogKeyForChain = catalogKeyForChain; exports.debugLog = debugLog; exports.debugError = debugError; exports.getAssetId = getAssetId; exports.chainIdsByValue = chainIdsByValue; exports.portfolioToAssets = portfolioToAssets; exports.isNativeAsset = isNativeAsset; exports.quoteFeeRow = quoteFeeRow; exports.SwappedConnectFeeChangedError = SwappedConnectFeeChangedError; exports.SUPPORTED_CONNECT_EXCHANGE_COUNT = SUPPORTED_CONNECT_EXCHANGE_COUNT; exports.resolveAppFeeBps = resolveAppFeeBps; exports.isDepositPolicyRefusal = isDepositPolicyRefusal; exports.PermitDepositSubmitError = PermitDepositSubmitError; exports.createDepositService = createDepositService; exports.depositBoundsViolation = depositBoundsViolation; exports.describePolicyRefusal = describePolicyRefusal; exports.rpcUrlFor = rpcUrlFor; exports.RpcUrlsProvider = RpcUrlsProvider; exports.useRpcUrls = useRpcUrls; exports.useStableRpcUrls = useStableRpcUrls; exports.getPublicClient = getPublicClient; exports.peekRuntimeChains = peekRuntimeChains; exports.primeRuntimeChains = primeRuntimeChains; exports.useChainCatalog = useChainCatalog; exports.useCatalogChain = useCatalogChain; exports.useDepositChainIds = useDepositChainIds; exports.useDestinationChains = useDestinationChains; exports.useTargetTokens = useTargetTokens; exports.useDepositOffer = useDepositOffer; exports.useDepositBounds = useDepositBounds; exports.useRestrictedListExclusion = useRestrictedListExclusion; exports.useIsDepositChain = useIsDepositChain; exports.useChainName = useChainName; exports.useReadClient = useReadClient; exports.useExplorerTxUrl = useExplorerTxUrl; exports.ChainCatalogProvider = ChainCatalogProvider; exports.getExchangeLogoSrc = getExchangeLogoSrc; exports.getExchangeLogo = getExchangeLogo; exports.useLatestRef = useLatestRef; exports.Button = Button; exports.Callout = Callout; exports.TokenIcon = TokenIcon; exports.currencyFormatter = currencyFormatter; exports.tokenFormatter = tokenFormatter; exports.isUnsupportedChainSwitchError = isUnsupportedChainSwitchError; exports.formatUserError = formatUserError; exports.Tooltip = Tooltip; exports.formatExpectedDuration = formatExpectedDuration; exports.markSubmissionUncertain = markSubmissionUncertain; exports.isSubmissionUncertain = isSubmissionUncertain; exports.formatTokenAmount = formatTokenAmount; exports.isDisplayStablecoinSymbol = isDisplayStablecoinSymbol; exports.isRecognizedToken = isRecognizedToken; exports.formatQuotedReceive = formatQuotedReceive; exports.formatReceiveEstimate = formatReceiveEstimate; exports.getEventTxHash = getEventTxHash; exports.getEventSourceDetails = getEventSourceDetails; exports.isDepositEvent = isDepositEvent; exports.isFailedEvent = isFailedEvent; exports.txRefsMatch = txRefsMatch; exports.failureMessageForEvent = failureMessageForEvent; exports.fetchTokenPriceUsd = fetchTokenPriceUsd; exports.useTokenPrices = useTokenPrices; exports.ProcessingStep = ProcessingStep; exports.AnalyticsSession = AnalyticsSession; exports.useDepositAnalyticsEmitter = useDepositAnalyticsEmitter; exports.useWithdrawAnalyticsEmitter = useWithdrawAnalyticsEmitter; exports.SetupError = SetupError; exports.deriveAccountSalt = deriveAccountSalt; exports.computeRequestKey = computeRequestKey; exports.computeCacheKey = computeCacheKey; exports.computeIsCacheable = computeIsCacheable; exports.readDedupedAccountSetupResult = readDedupedAccountSetupResult; exports.runAccountSetupDeduped = runAccountSetupDeduped; exports.HistoryEntryButton = HistoryEntryButton; exports.HistoryOverlay = HistoryOverlay; exports.useHistoryPanel = useHistoryPanel; exports.resolveThemeMode = resolveThemeMode; exports.followSystemAppearance = followSystemAppearance; exports.applyTheme = applyTheme; exports.warnRemovedProps = warnRemovedProps; exports.checkBackendUrl = checkBackendUrl; exports.isHistoryEntryVisible = isHistoryEntryVisible; exports.createHistoryAnalytics = createHistoryAnalytics; exports.analyticsTargetProperties = analyticsTargetProperties;