@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,3 +1,15 @@
1
+ import {
2
+ MULTICALL3_ADDRESS,
3
+ POLYMARKET_COLLATERAL_OFFRAMP_ADDRESS,
4
+ POLYMARKET_ICON_URL,
5
+ POLYMARKET_POLYGON_CHAIN_ID,
6
+ POLYMARKET_PUSD_ADDRESS,
7
+ POLYMARKET_USDCE_ADDRESS,
8
+ SAFE_ABI,
9
+ executePolymarketSafeTransfer,
10
+ fetchPolymarketProxyWallet,
11
+ readPolymarketBalances
12
+ } from "./chunk-FTWKAJGN.mjs";
1
13
  import {
2
14
  AnalyticsSession,
3
15
  AppleIcon,
@@ -47,8 +59,11 @@ import {
47
59
  currencyFormatter,
48
60
  debugError,
49
61
  debugLog,
62
+ depositBoundsViolation,
63
+ describePolicyRefusal,
50
64
  failureMessageForEvent,
51
65
  fetchTokenPriceUsd,
66
+ formatExpectedDuration,
52
67
  formatQuotedReceive,
53
68
  formatReceiveEstimate,
54
69
  formatTokenAmount,
@@ -60,6 +75,7 @@ import {
60
75
  getExchangeLogoSrc,
61
76
  getPublicClient,
62
77
  isDepositEvent,
78
+ isDepositPolicyRefusal,
63
79
  isDisplayStablecoinSymbol,
64
80
  isFailedEvent,
65
81
  isHistoryEntryVisible,
@@ -78,27 +94,18 @@ import {
78
94
  useChainCatalog,
79
95
  useChainName,
80
96
  useDepositAnalyticsEmitter,
97
+ useDepositBounds,
81
98
  useDepositChainIds,
99
+ useDepositOffer,
82
100
  useExplorerTxUrl,
83
101
  useHistoryPanel,
84
102
  useIsDepositChain,
85
103
  useLatestRef,
104
+ useRestrictedListExclusion,
86
105
  useRpcUrls,
87
106
  useStableRpcUrls,
88
107
  warnRemovedProps
89
- } from "./chunk-EA5CE2UZ.mjs";
90
- import {
91
- MULTICALL3_ADDRESS,
92
- POLYMARKET_COLLATERAL_OFFRAMP_ADDRESS,
93
- POLYMARKET_ICON_URL,
94
- POLYMARKET_POLYGON_CHAIN_ID,
95
- POLYMARKET_PUSD_ADDRESS,
96
- POLYMARKET_USDCE_ADDRESS,
97
- SAFE_ABI,
98
- executePolymarketSafeTransfer,
99
- fetchPolymarketProxyWallet,
100
- readPolymarketBalances
101
- } from "./chunk-FTWKAJGN.mjs";
108
+ } from "./chunk-AIZKGFVA.mjs";
102
109
  import {
103
110
  HYPERCORE_CHAIN_ID,
104
111
  HYPERCORE_MIN_DEPOSIT_USD,
@@ -122,7 +129,6 @@ import {
122
129
  isStablecoinSymbol,
123
130
  isVirtualDestination,
124
131
  parseEvmChainId,
125
- publishShortlistTokens,
126
132
  targetChainToChainId,
127
133
  toEvmCaip2
128
134
  } from "./chunk-EAGMY3QE.mjs";
@@ -722,6 +728,7 @@ function AssetSelectStep({
722
728
  const [loading, setLoading] = useState2(true);
723
729
  const [error, setError] = useState2(null);
724
730
  const isDepositChain = useIsDepositChain();
731
+ const isExcludedByRestrictedList = useRestrictedListExclusion();
725
732
  const { catalog } = useChainCatalog();
726
733
  const chainName = useChainName();
727
734
  const defaultAssetId = useMemo(() => {
@@ -803,6 +810,9 @@ function AssetSelectStep({
803
810
  return false;
804
811
  }
805
812
  const isNativeToken = a.token.toLowerCase() === NATIVE_TOKEN_ADDRESS;
813
+ if (isNativeToken && isExcludedByRestrictedList(a.chainId, a.token)) {
814
+ return false;
815
+ }
806
816
  if (!isNativeToken && !(typeof a.balanceUsd === "number" && a.balanceUsd >= 0.01))
807
817
  return false;
808
818
  return true;
@@ -816,7 +826,7 @@ function AssetSelectStep({
816
826
  if (balB < balA) return -1;
817
827
  return 0;
818
828
  });
819
- }, [assets, isDepositChain]);
829
+ }, [assets, isDepositChain, isExcludedByRestrictedList]);
820
830
  useEffect2(() => {
821
831
  if (!defaultAssetId || selectedAssetId) return;
822
832
  if (rows.some((asset) => asset.id === defaultAssetId)) {
@@ -1247,6 +1257,11 @@ function AmountStep({
1247
1257
  const exceedsBalance = Boolean(
1248
1258
  sourceAmountUnits !== null && balance !== null && sourceAmountUnits > balance
1249
1259
  );
1260
+ const boundsFor = useDepositBounds();
1261
+ const boundViolation = depositBoundsViolation(
1262
+ boundsFor(asset.chainId, asset.token),
1263
+ sourceAmountUnits
1264
+ );
1250
1265
  const balanceAfterUsd = appBalanceUsd !== void 0 ? appBalanceUsd + numericAmount : null;
1251
1266
  const handlePresetClick = (percentage) => {
1252
1267
  if (balance === null) return;
@@ -1270,7 +1285,7 @@ function AmountStep({
1270
1285
  if (error) setError(null);
1271
1286
  };
1272
1287
  const handleContinue = async () => {
1273
- if (chainMismatch) return;
1288
+ if (chainMismatch || boundViolation) return;
1274
1289
  let effectiveAmount = numericAmount;
1275
1290
  if (isBelowMin && minDepositUsd !== null) {
1276
1291
  effectiveAmount = minDepositUsd;
@@ -1304,11 +1319,11 @@ function AmountStep({
1304
1319
  balance ?? void 0
1305
1320
  );
1306
1321
  };
1307
- const continueLabel = exceedsBalance ? "Insufficient balance" : isAboveMax ? "Continue with max allowed deposit" : isBelowMin ? "Continue with minimum deposit" : "Continue";
1322
+ const continueLabel = exceedsBalance ? "Insufficient balance" : boundViolation ?? (isAboveMax ? "Continue with max allowed deposit" : isBelowMin ? "Continue with minimum deposit" : "Continue");
1308
1323
  const knowsBalance = address !== void 0;
1309
1324
  const needsPricing = !knowsBalance && !isSourceStablecoin;
1310
1325
  const blockedOnPricing = needsPricing && !hasPricing;
1311
- const continueDisabled = chainMismatch || exceedsBalance || blockedOnPricing || numericAmount === 0 && !isBelowMin || knowsBalance && balance === null;
1326
+ const continueDisabled = chainMismatch || exceedsBalance || boundViolation !== null || blockedOnPricing || numericAmount === 0 && !isBelowMin || knowsBalance && balance === null;
1312
1327
  const chainName = useChainName();
1313
1328
  const sourceChainName = chainName(asset.chainId);
1314
1329
  const targetChainName = chainName(targetChainId);
@@ -1650,6 +1665,14 @@ function ConfirmStep({
1650
1665
  const [permitUnavailable, setPermitUnavailable] = useState4(null);
1651
1666
  const [permitDisabled, setPermitDisabled] = useState4(false);
1652
1667
  const [submissionUncertain, setSubmissionUncertain] = useState4(false);
1668
+ const [previewRefusal, setPreviewRefusal] = useState4(null);
1669
+ const [permitRefusal, setPermitRefusal] = useState4(null);
1670
+ const [previewSettledKey, setPreviewSettledKey] = useState4(
1671
+ null
1672
+ );
1673
+ const [permitSettledKey, setPermitSettledKey] = useState4(
1674
+ null
1675
+ );
1653
1676
  const hasAttemptedSwitch = useRef3(false);
1654
1677
  const onSubmittingChangeRef = useRef3(onSubmittingChange);
1655
1678
  onSubmittingChangeRef.current = onSubmittingChange;
@@ -1700,6 +1723,21 @@ function ConfirmStep({
1700
1723
  address.toLowerCase()
1701
1724
  ]);
1702
1725
  const permit = permitEligible && !permitDisabled && permitResult?.requestKey === permitRequestKey ? permitResult.prepared : null;
1726
+ const boundsFor = useDepositBounds();
1727
+ const activeRefusal = (previewRefusal?.requestKey === quoteRequestKey ? previewRefusal.refusal : null) ?? (permitRefusal?.requestKey === permitRequestKey ? permitRefusal.refusal : null);
1728
+ const blockedReason = activeRefusal ? describePolicyRefusal(
1729
+ activeRefusal,
1730
+ boundsFor(quoteSource.chainId, quoteSource.token)
1731
+ ) : null;
1732
+ const requestsAmount = (() => {
1733
+ try {
1734
+ return parseUnits2(amount, asset.decimals) > 0n;
1735
+ } catch {
1736
+ return false;
1737
+ }
1738
+ })();
1739
+ const previewPending = setupReady && requestsAmount && previewSettledKey !== quoteRequestKey;
1740
+ const permitPending = permitEligible && !permitDisabled && requestsAmount && permitSettledKey !== permitRequestKey;
1703
1741
  const receiveDisplay = (() => {
1704
1742
  if (directTransfer) return `${formattedSendAmount} ${asset.symbol}`;
1705
1743
  if (quote) {
@@ -1722,7 +1760,8 @@ function ConfirmStep({
1722
1760
  if (estimate !== void 0) return estimate;
1723
1761
  return targetSymbol;
1724
1762
  })();
1725
- const estimatedTimeDisplay = quote && Number.isFinite(quote.estimatedFillTimeSeconds) ? quote.estimatedFillTimeSeconds < 60 ? "< 1 min" : `~${Math.round(quote.estimatedFillTimeSeconds / 60)} min` : estimatedTime;
1763
+ const servedExpectedSeconds = quote?.timing?.expectedSeconds ?? (quote && Number.isFinite(quote.estimatedFillTimeSeconds) ? quote.estimatedFillTimeSeconds : void 0);
1764
+ const estimatedTimeDisplay = servedExpectedSeconds !== void 0 ? formatExpectedDuration(servedExpectedSeconds) : estimatedTime;
1726
1765
  useEffect4(() => {
1727
1766
  if (chainMismatch && switchChain && !hasAttemptedSwitch.current) {
1728
1767
  hasAttemptedSwitch.current = true;
@@ -1755,11 +1794,22 @@ function ConfirmStep({
1755
1794
  amount: units.toString()
1756
1795
  }).then((result) => {
1757
1796
  if (cancelled) return;
1797
+ setPreviewSettledKey(quoteRequestKey);
1798
+ if (isDepositPolicyRefusal(result)) {
1799
+ setQuoteResult(null);
1800
+ setPreviewRefusal({
1801
+ requestKey: quoteRequestKey,
1802
+ refusal: result.policyRefusal
1803
+ });
1804
+ return;
1805
+ }
1806
+ setPreviewRefusal(null);
1758
1807
  setQuoteResult(
1759
1808
  result === null ? null : { requestKey: quoteRequestKey, quote: result }
1760
1809
  );
1761
1810
  }).catch(() => {
1762
1811
  if (cancelled) return;
1812
+ setPreviewSettledKey(quoteRequestKey);
1763
1813
  setQuoteResult(null);
1764
1814
  });
1765
1815
  return () => {
@@ -1792,7 +1842,16 @@ function ConfirmStep({
1792
1842
  amount: units.toString(),
1793
1843
  owner: address
1794
1844
  }).then((prepared) => {
1795
- if (cancelled || prepared === null) return;
1845
+ if (cancelled) return;
1846
+ setPermitSettledKey(permitRequestKey);
1847
+ if (prepared === null) return;
1848
+ if (isDepositPolicyRefusal(prepared)) {
1849
+ setPermitRefusal({
1850
+ requestKey: permitRequestKey,
1851
+ refusal: prepared.policyRefusal
1852
+ });
1853
+ return;
1854
+ }
1796
1855
  if (!prepared.available) {
1797
1856
  setPermitUnavailable(prepared.reason);
1798
1857
  return;
@@ -1817,6 +1876,7 @@ function ConfirmStep({
1817
1876
  prepared: authorization
1818
1877
  });
1819
1878
  }).catch(() => {
1879
+ if (!cancelled) setPermitSettledKey(permitRequestKey);
1820
1880
  });
1821
1881
  return () => {
1822
1882
  cancelled = true;
@@ -1858,6 +1918,11 @@ function ConfirmStep({
1858
1918
  setError("Insufficient balance");
1859
1919
  return;
1860
1920
  }
1921
+ if (previewPending || permitPending) return;
1922
+ if (blockedReason) {
1923
+ setError(blockedReason);
1924
+ return;
1925
+ }
1861
1926
  if (!quote && mustHaveQuote) {
1862
1927
  setError("Quote unavailable \u2014 please try again");
1863
1928
  return;
@@ -1996,7 +2061,7 @@ function ConfirmStep({
1996
2061
  fee: { display: feeDisplay, struck: feesFullySponsored }
1997
2062
  }
1998
2063
  ),
1999
- error && /* @__PURE__ */ jsx10(Callout, { variant: "error", children: error }),
2064
+ (error ?? blockedReason) && /* @__PURE__ */ jsx10(Callout, { variant: "error", children: error ?? blockedReason }),
2000
2065
  /* @__PURE__ */ jsx10(
2001
2066
  Button,
2002
2067
  {
@@ -2005,7 +2070,9 @@ function ConfirmStep({
2005
2070
  loadingText: permit ? "Waiting for signature..." : "Submitting transaction...",
2006
2071
  disabled: (
2007
2072
  // An earlier send whose outcome is unknown. Never re-offered.
2008
- submissionUncertain || // Signing is off-chain, so a chain mismatch only blocks the
2073
+ submissionUncertain || // The deposit on screen would be rejected at ingest.
2074
+ blockedReason !== null || // A refusal for what is on screen may still be in flight.
2075
+ previewPending || permitPending || // Signing is off-chain, so a chain mismatch only blocks the
2009
2076
  // transfer path.
2010
2077
  chainMismatch && !permit || !amount || Number(amount) <= 0 || // Fee-charging route: block until the authoritative quote resolves
2011
2078
  // (covers both loading and an unavailable preview). Fee-free routes
@@ -2047,6 +2114,7 @@ function QrReviewStep({
2047
2114
  const [quote, setQuote] = useState5({ state: "loading", value: null });
2048
2115
  const targetChainId = targetChainToChainId(targetChain);
2049
2116
  const targetSymbol = getTargetTokenSymbol(targetToken, targetChainId);
2117
+ const boundsFor = useDepositBounds();
2050
2118
  useEffect5(() => {
2051
2119
  let cancelled = false;
2052
2120
  let units;
@@ -2068,6 +2136,14 @@ function QrReviewStep({
2068
2136
  amount: units.toString()
2069
2137
  }).then((result) => {
2070
2138
  if (cancelled) return;
2139
+ if (isDepositPolicyRefusal(result)) {
2140
+ setQuote({
2141
+ state: "refused",
2142
+ value: null,
2143
+ refusal: result.policyRefusal
2144
+ });
2145
+ return;
2146
+ }
2071
2147
  setQuote(
2072
2148
  result ? { state: "ready", value: result } : { state: "unavailable", value: null }
2073
2149
  );
@@ -2095,9 +2171,10 @@ function QrReviewStep({
2095
2171
  });
2096
2172
  return estimate ?? targetSymbol;
2097
2173
  })();
2098
- const estimatedTime = quote.value && Number.isFinite(quote.value.estimatedFillTimeSeconds) ? quote.value.estimatedFillTimeSeconds < 60 ? "< 1 min" : `~${Math.round(quote.value.estimatedFillTimeSeconds / 60)} min` : quote.state === "loading" ? "\u2026" : "\u2014";
2174
+ const expectedSeconds = quote.value?.timing?.expectedSeconds ?? (quote.value && Number.isFinite(quote.value.estimatedFillTimeSeconds) ? quote.value.estimatedFillTimeSeconds : void 0);
2175
+ const estimatedTime = expectedSeconds !== void 0 ? formatExpectedDuration(expectedSeconds) : quote.state === "loading" ? "\u2026" : "\u2014";
2099
2176
  const { display: quotedFee, struck } = quoteFeeRow(quote.value?.fees);
2100
- const feeDisplay = quote.state === "unavailable" ? "\u2014" : quotedFee;
2177
+ const feeDisplay = quote.state === "unavailable" || quote.state === "refused" ? "\u2014" : quotedFee;
2101
2178
  return /* @__PURE__ */ jsxs9("div", { className: "rs-screen", children: [
2102
2179
  /* @__PURE__ */ jsxs9("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
2103
2180
  /* @__PURE__ */ jsx11(BodyHeader, { icon: /* @__PURE__ */ jsx11(TransferCryptoIcon, {}), title: "Fee estimate" }),
@@ -2116,6 +2193,10 @@ function QrReviewStep({
2116
2193
  fee: { display: feeDisplay, struck }
2117
2194
  }
2118
2195
  ),
2196
+ quote.state === "refused" && quote.refusal && /* @__PURE__ */ jsx11(Callout, { variant: "error", children: describePolicyRefusal(
2197
+ quote.refusal,
2198
+ boundsFor(asset.chainId, asset.token)
2199
+ ) }),
2119
2200
  /* @__PURE__ */ jsx11(Button, { onClick: onClose, fullWidth: true, children: "Close" })
2120
2201
  ] }),
2121
2202
  /* @__PURE__ */ jsx11(PoweredBy, {})
@@ -2650,17 +2731,15 @@ function chainLabel(chainId, catalogChain) {
2650
2731
  const name = catalogChain?.name ?? getChainName(chainId);
2651
2732
  return name.replace(/\s+(One|Mainnet|Smart Chain|Chain)$/i, "");
2652
2733
  }
2653
- function computeTokensForChain(chainId, topTokens, catalogChain) {
2654
- const fromBackend = topTokens?.[String(chainId)]?.map((t) => t.symbol);
2655
- if (fromBackend) return fromBackend;
2734
+ function computeTokensForChain(chainId, offer, catalogChain) {
2735
+ const listed = offer.tokensFor(chainId)?.map((t) => t.symbol);
2736
+ if (listed) return listed;
2656
2737
  return Array.isArray(catalogChain?.supportedTokens) ? catalogChain.supportedTokens.map((t) => t.symbol) : [];
2657
2738
  }
2658
- function selectionAsAsset(chainId, symbol, topTokens, catalogChain) {
2739
+ function selectionAsAsset(chainId, symbol, offer, catalogChain) {
2659
2740
  if (typeof chainId !== "number" || !symbol) return void 0;
2660
- const fromShortlist = topTokens?.[String(chainId)]?.find(
2661
- (t) => t.symbol === symbol
2662
- );
2663
- const fromCatalog = Array.isArray(catalogChain?.supportedTokens) ? catalogChain.supportedTokens.find((t) => t.symbol === symbol) : void 0;
2741
+ const fromShortlist = offer.tokensFor(chainId)?.find((t) => t.symbol === symbol);
2742
+ const fromCatalog = !offer.restricted && Array.isArray(catalogChain?.supportedTokens) ? catalogChain.supportedTokens.find((t) => t.symbol === symbol) : void 0;
2664
2743
  const address = fromShortlist?.address ?? fromCatalog?.address;
2665
2744
  const decimals = fromShortlist?.decimals ?? fromCatalog?.decimals;
2666
2745
  if (!address || decimals === void 0) return void 0;
@@ -2705,25 +2784,10 @@ function DepositAddressStep({
2705
2784
  onError
2706
2785
  }) {
2707
2786
  const hasSolana = Boolean(solanaDepositAddress);
2708
- const [topTokens, setTopTokens] = useState7(null);
2709
- const [topTokensSettled, setTopTokensSettled] = useState7(false);
2710
- useEffect7(() => {
2711
- let active = true;
2712
- setTopTokens(null);
2713
- setTopTokensSettled(false);
2714
- service.getTopTokens().then((t) => {
2715
- if (!active) return;
2716
- setTopTokens(t);
2717
- setTopTokensSettled(true);
2718
- if (t) publishShortlistTokens(t);
2719
- });
2720
- return () => {
2721
- active = false;
2722
- };
2723
- }, [service]);
2787
+ const offer = useDepositOffer();
2724
2788
  const BASE_CHAIN_ID2 = 8453;
2725
2789
  const evmChainIds = useDepositChainIds();
2726
- const { catalog, isLoading: catalogLoading } = useChainCatalog();
2790
+ const { catalog, isLoading: catalogLoading, shortlist } = useChainCatalog();
2727
2791
  const catalogFor = useCallback2(
2728
2792
  (chain) => {
2729
2793
  if (!catalog) return void 0;
@@ -2740,9 +2804,9 @@ function DepositAddressStep({
2740
2804
  if (acceptsDeposits("hypercore")) extras.push("hypercore");
2741
2805
  options.splice(1, 0, ...extras);
2742
2806
  return options.filter(
2743
- (chain) => topTokens?.[String(chain)]?.length !== 0 && computeTokensForChain(chain, topTokens, catalogFor(chain)).length > 0
2807
+ (chain) => offer.isChainOffered(chain) && computeTokensForChain(chain, offer, catalogFor(chain)).length > 0
2744
2808
  );
2745
- }, [evmChainIds, hasSolana, topTokens, catalogFor]);
2809
+ }, [evmChainIds, hasSolana, offer, catalogFor]);
2746
2810
  const preferredChainId = (options) => options.includes(BASE_CHAIN_ID2) ? BASE_CHAIN_ID2 : options[0] ?? BASE_CHAIN_ID2;
2747
2811
  const [sourceChainId, setSourceChainId] = useState7(() => initialSource?.chainId ?? preferredChainId(chainOptions));
2748
2812
  const chainChosenByUser = useRef5(initialSource !== void 0);
@@ -2756,17 +2820,17 @@ function DepositAddressStep({
2756
2820
  setSourceChainId(pendingChain2);
2757
2821
  return;
2758
2822
  }
2759
- if (catalogLoading || topTokens === null) return;
2823
+ if (catalogLoading || offer.status !== "ready") return;
2760
2824
  pendingChainRef.current = void 0;
2761
2825
  }
2762
2826
  const stale = chainChosenByUser.current ? !chainOptions.includes(sourceChainId) : sourceChainId !== preferredChainId(chainOptions);
2763
2827
  if (stale) setSourceChainId(preferredChainId(chainOptions));
2764
- }, [chainOptions, sourceChainId, catalogLoading, topTokens]);
2828
+ }, [chainOptions, sourceChainId, catalogLoading, offer.status]);
2765
2829
  const isSolana = sourceChainId === "solana";
2766
2830
  const isHyperCore = sourceChainId === "hypercore";
2767
2831
  const tokensForChain = useMemo3(
2768
- () => computeTokensForChain(sourceChainId, topTokens, catalogFor(sourceChainId)),
2769
- [sourceChainId, topTokens, catalogFor]
2832
+ () => computeTokensForChain(sourceChainId, offer, catalogFor(sourceChainId)),
2833
+ [sourceChainId, offer, catalogFor]
2770
2834
  );
2771
2835
  const defaultToken = pickFallbackToken(
2772
2836
  tokensForChain,
@@ -2804,13 +2868,13 @@ function DepositAddressStep({
2804
2868
  () => resolveSourceTokenIdentity({
2805
2869
  chain: sourceChainId,
2806
2870
  symbol: sourceTokenSymbol,
2807
- shortlist: topTokens,
2808
- catalogTokens: catalogFor(sourceChainId)?.supportedTokens
2871
+ shortlist,
2872
+ catalogTokens: offer.restricted ? void 0 : catalogFor(sourceChainId)?.supportedTokens
2809
2873
  }),
2810
- [sourceChainId, sourceTokenSymbol, topTokens, catalogFor]
2874
+ [sourceChainId, sourceTokenSymbol, shortlist, offer.restricted, catalogFor]
2811
2875
  );
2812
2876
  const pendingChain = pendingChainRef.current;
2813
- const sourceSelectionSettled = !catalogLoading && topTokensSettled && chainOptions.length > 0 && (pendingChain === void 0 || pendingChain === sourceChainId) && (chainChosenByUser.current ? chainOptions.includes(sourceChainId) : sourceChainId === preferredChainId(chainOptions));
2877
+ const sourceSelectionSettled = !catalogLoading && offer.status === "ready" && chainOptions.length > 0 && (pendingChain === void 0 || pendingChain === sourceChainId) && (chainChosenByUser.current ? chainOptions.includes(sourceChainId) : sourceChainId === preferredChainId(chainOptions));
2814
2878
  useEffect7(() => {
2815
2879
  if (!sourceTokenIdentity) return;
2816
2880
  if (!sourceSelectionSettled) return;
@@ -2870,7 +2934,7 @@ function DepositAddressStep({
2870
2934
  (nextChain) => {
2871
2935
  const nextTokens = computeTokensForChain(
2872
2936
  nextChain,
2873
- topTokens,
2937
+ offer,
2874
2938
  catalogFor(nextChain)
2875
2939
  );
2876
2940
  chainChosenByUser.current = true;
@@ -2880,7 +2944,7 @@ function DepositAddressStep({
2880
2944
  setTokenDropdownOpen(false);
2881
2945
  setCopied(false);
2882
2946
  },
2883
- [sourceTokenSymbol, topTokens, catalogFor]
2947
+ [sourceTokenSymbol, offer, catalogFor]
2884
2948
  );
2885
2949
  const onDepositSubmittedRef = useRef5(onDepositSubmitted);
2886
2950
  onDepositSubmittedRef.current = onDepositSubmitted;
@@ -3013,14 +3077,23 @@ function DepositAddressStep({
3013
3077
  const reviewAsset = selectionAsAsset(
3014
3078
  sourceChainId,
3015
3079
  sourceTokenSymbol,
3016
- topTokens,
3080
+ offer,
3017
3081
  catalogFor(sourceChainId)
3018
3082
  );
3083
+ if (offer.status === "error") {
3084
+ return /* @__PURE__ */ jsx14("div", { className: "rs-screen", children: /* @__PURE__ */ jsxs12("div", { className: "rs-screen-body", children: [
3085
+ /* @__PURE__ */ jsx14(BodyHeader, { icon: /* @__PURE__ */ jsx14(TransferCryptoIcon, {}), title: "Transfer crypto" }),
3086
+ /* @__PURE__ */ jsx14(Callout, { variant: "error", children: "The tokens this app accepts could not be loaded, so there is no deposit address to show." }),
3087
+ /* @__PURE__ */ jsx14(Button, { onClick: offer.retry, fullWidth: true, children: "Try again" })
3088
+ ] }) });
3089
+ }
3019
3090
  if (chainOptions.length === 0) {
3020
- if (catalogLoading) return /* @__PURE__ */ jsx14(DepositAddressSkeleton, { uiConfig });
3091
+ if (catalogLoading || offer.status === "loading") {
3092
+ return /* @__PURE__ */ jsx14(DepositAddressSkeleton, { uiConfig });
3093
+ }
3021
3094
  return /* @__PURE__ */ jsx14("div", { className: "rs-screen", children: /* @__PURE__ */ jsxs12("div", { className: "rs-screen-body", children: [
3022
3095
  /* @__PURE__ */ jsx14(BodyHeader, { icon: /* @__PURE__ */ jsx14(TransferCryptoIcon, {}), title: "Transfer crypto" }),
3023
- /* @__PURE__ */ jsx14(Callout, { variant: "error", children: "Supported chains are unavailable right now, so there is no deposit address to show. Close and try again in a moment." })
3096
+ /* @__PURE__ */ jsx14(Callout, { variant: "error", children: catalog ? "This app does not accept deposits from any chain available here." : "Supported chains are unavailable right now, so there is no deposit address to show. Close and try again in a moment." })
3024
3097
  ] }) });
3025
3098
  }
3026
3099
  return /* @__PURE__ */ jsxs12("div", { className: "rs-screen rs-step--with-notifications", children: [
@@ -4547,6 +4620,11 @@ function SolanaAmountStep({
4547
4620
  const exceedsBalance = Boolean(
4548
4621
  sourceAmountUnits !== null && sourceAmountUnits > spendableBalance
4549
4622
  );
4623
+ const boundsFor = useDepositBounds();
4624
+ const boundViolation = depositBoundsViolation(
4625
+ boundsFor("solana", token.mint),
4626
+ sourceAmountUnits
4627
+ );
4550
4628
  const balanceAfterUsd = appBalanceUsd !== void 0 ? appBalanceUsd + numericAmount : null;
4551
4629
  const handlePresetClick = (percentage) => {
4552
4630
  const formatted = computePresetAmount(percentage);
@@ -4567,6 +4645,7 @@ function SolanaAmountStep({
4567
4645
  if (error) setError(null);
4568
4646
  };
4569
4647
  const handleContinue = () => {
4648
+ if (boundViolation) return;
4570
4649
  let effective = numericAmount;
4571
4650
  if (isBelowMin && minDepositUsd !== null) {
4572
4651
  effective = minDepositUsd;
@@ -4610,8 +4689,8 @@ function SolanaAmountStep({
4610
4689
  setError(null);
4611
4690
  onContinue(token, sourceAmountStr, effective.toString());
4612
4691
  };
4613
- const continueLabel = exceedsBalance ? "Insufficient balance" : isAboveMax ? "Continue with max allowed deposit" : isBelowMin ? "Continue with minimum deposit" : "Continue";
4614
- const continueDisabled = exceedsBalance || numericAmount === 0 && !isBelowMin;
4692
+ const continueLabel = exceedsBalance ? "Insufficient balance" : boundViolation ?? (isAboveMax ? "Continue with max allowed deposit" : isBelowMin ? "Continue with minimum deposit" : "Continue");
4693
+ const continueDisabled = exceedsBalance || boundViolation !== null || numericAmount === 0 && !isBelowMin;
4615
4694
  return /* @__PURE__ */ jsxs18("div", { className: "rs-screen", children: [
4616
4695
  /* @__PURE__ */ jsxs18("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
4617
4696
  /* @__PURE__ */ jsx22(BodyHeader, { icon: /* @__PURE__ */ jsx22(WalletIcon, {}), title: "Wallet deposit" }),
@@ -5750,6 +5829,33 @@ function getEnabledProviders(config) {
5750
5829
  }
5751
5830
 
5752
5831
  // src/core/dapp-imports/status.ts
5832
+ function narrowDappImportAvailability(availability, isExcluded) {
5833
+ let changed = false;
5834
+ const narrowed = {};
5835
+ for (const [providerId, entry] of Object.entries(availability)) {
5836
+ if (!entry || entry === "loading" || entry === "error") {
5837
+ narrowed[providerId] = entry;
5838
+ continue;
5839
+ }
5840
+ const assets = entry.assets.filter(
5841
+ (asset) => !isExcluded(asset.depositChainId, asset.depositToken)
5842
+ );
5843
+ if (assets.length === entry.assets.length) {
5844
+ narrowed[providerId] = entry;
5845
+ continue;
5846
+ }
5847
+ changed = true;
5848
+ narrowed[providerId] = assets.length === 0 ? null : {
5849
+ ...entry,
5850
+ assets,
5851
+ totalUsd: assets.reduce(
5852
+ (sum, asset) => sum + (asset.balanceUsd ?? 0),
5853
+ 0
5854
+ )
5855
+ };
5856
+ }
5857
+ return changed ? narrowed : availability;
5858
+ }
5753
5859
  function computeDappImportStatus(providerId, inputs) {
5754
5860
  const { owner, availability, availabilityOwner, setup } = inputs;
5755
5861
  if (!owner) return "needs-connect";
@@ -7177,7 +7283,7 @@ async function fetchPinnedQuote(params) {
7177
7283
  timeoutId = setTimeout(resolve, SWAPPED_QUOTE_FEE_TIMEOUT_MS, null);
7178
7284
  })
7179
7285
  ]);
7180
- return quote ?? void 0;
7286
+ return quote && !isDepositPolicyRefusal(quote) ? quote : void 0;
7181
7287
  } catch {
7182
7288
  return void 0;
7183
7289
  } finally {
@@ -8087,7 +8193,17 @@ function DepositFlow({
8087
8193
  providerId: initialAssetMigrationProvider.id
8088
8194
  });
8089
8195
  }, [analytics, initialAssetMigrationProvider, flowSlice, storeApi]);
8090
- const dappImportAvailability = useDepositStore((s) => s.dappImport.availability);
8196
+ const storedDappImportAvailability = useDepositStore(
8197
+ (s) => s.dappImport.availability
8198
+ );
8199
+ const isExcludedByRestrictedList = useRestrictedListExclusion();
8200
+ const dappImportAvailability = useMemo8(
8201
+ () => narrowDappImportAvailability(
8202
+ storedDappImportAvailability,
8203
+ isExcludedByRestrictedList
8204
+ ),
8205
+ [storedDappImportAvailability, isExcludedByRestrictedList]
8206
+ );
8091
8207
  const dappImportAvailabilityOwner = useDepositStore(
8092
8208
  (s) => s.dappImport.availabilityOwner
8093
8209
  );
@@ -9643,7 +9759,7 @@ function DepositFlow({
9643
9759
  import { jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
9644
9760
  var ReownDepositInner = lazy2(async () => {
9645
9761
  await loadReownDependencies();
9646
- const module = await import("./DepositModalReown-R7UROJPJ.mjs");
9762
+ const module = await import("./DepositModalReown-VCY65DJX.mjs");
9647
9763
  return { default: module.DepositModalReown };
9648
9764
  });
9649
9765
  function buildDepositAnalyticsSessionProperties({