@rhinestone/deposit-modal 0.19.0 → 0.20.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 (83) hide show
  1. package/README.md +151 -61
  2. package/dist/BankOnrampStep-JG32OCM2.mjs +435 -0
  3. package/dist/BankOnrampStep-NPGXAA7U.cjs +435 -0
  4. package/dist/{DepositModalReown-XBNY6QCI.mjs → DepositModalReown-3FGTPER6.mjs} +6 -5
  5. package/dist/{DepositModalReown-UITYXJ6W.cjs → DepositModalReown-ALVWADG7.cjs} +21 -20
  6. package/dist/WithdrawModal-5YWFJSYY.cjs +12 -0
  7. package/dist/WithdrawModal-LL4Z5WZP.mjs +12 -0
  8. package/dist/{bearer-transport-CVHNBgoV.d.cts → bearer-transport-DZyeDG64.d.cts} +5 -1
  9. package/dist/{bearer-transport-CVHNBgoV.d.ts → bearer-transport-DZyeDG64.d.ts} +5 -1
  10. package/dist/{caip-BMi-9t09.d.cts → caip-nwFFL46o.d.cts} +2 -2
  11. package/dist/{caip-BMi-9t09.d.ts → caip-nwFFL46o.d.ts} +2 -2
  12. package/dist/{chunk-NITKDXHR.mjs → chunk-247GJH57.mjs} +480 -272
  13. package/dist/{chunk-FTWKAJGN.mjs → chunk-2FOPO4N5.mjs} +1 -1
  14. package/dist/{chunk-5NWLS5BQ.mjs → chunk-32ERBFMO.mjs} +1432 -961
  15. package/dist/chunk-5QUWEFD4.mjs +19 -0
  16. package/dist/chunk-6CTJFR3T.mjs +113 -0
  17. package/dist/{chunk-X6N2XPTO.mjs → chunk-B2LZQIGB.mjs} +1 -1
  18. package/dist/{chunk-EG4H7OMC.cjs → chunk-BTEG2VNZ.cjs} +171 -130
  19. package/dist/{chunk-HMUGY66O.cjs → chunk-CXRH5MKO.cjs} +1502 -1031
  20. package/dist/chunk-E7IMWVMN.mjs +346 -0
  21. package/dist/{chunk-PYOC6K24.cjs → chunk-EKFXUF5A.cjs} +1 -1
  22. package/dist/chunk-FKJ6EJHH.cjs +346 -0
  23. package/dist/chunk-FMUSY563.cjs +19 -0
  24. package/dist/{chunk-LVCD6RHF.cjs → chunk-FVJKUTHF.cjs} +2 -2
  25. package/dist/chunk-G264OM23.cjs +224 -0
  26. package/dist/{chunk-BIL4ENC3.mjs → chunk-HP7S7AD6.mjs} +73 -32
  27. package/dist/{chunk-ISLVD5HQ.cjs → chunk-OPT5EW6L.cjs} +10 -5
  28. package/dist/chunk-PYRXOP2Y.cjs +113 -0
  29. package/dist/{chunk-ZGHVJ2XM.mjs → chunk-XBJCZYBX.mjs} +8 -3
  30. package/dist/chunk-YY4ZOAH5.mjs +224 -0
  31. package/dist/{chunk-OCWSMLOP.cjs → chunk-Z4RBTNKX.cjs} +980 -772
  32. package/dist/compliance.cjs +4 -7
  33. package/dist/compliance.d.cts +26 -3
  34. package/dist/compliance.d.ts +26 -3
  35. package/dist/compliance.mjs +6 -9
  36. package/dist/constants-BQDxVNgr.d.cts +29 -0
  37. package/dist/constants-DjGQW5N5.d.ts +29 -0
  38. package/dist/constants.cjs +3 -37
  39. package/dist/constants.d.cts +4 -20
  40. package/dist/constants.d.ts +4 -20
  41. package/dist/constants.mjs +4 -38
  42. package/dist/deposit.cjs +7 -6
  43. package/dist/deposit.d.cts +5 -3
  44. package/dist/deposit.d.ts +5 -3
  45. package/dist/deposit.mjs +6 -5
  46. package/dist/embed.cjs +21 -20
  47. package/dist/embed.d.cts +3 -2
  48. package/dist/embed.d.ts +3 -2
  49. package/dist/embed.mjs +7 -6
  50. package/dist/index.cjs +8 -35
  51. package/dist/index.d.cts +5 -3
  52. package/dist/index.d.ts +5 -3
  53. package/dist/index.mjs +9 -36
  54. package/dist/onramp.cjs +4 -33
  55. package/dist/onramp.d.cts +51 -33
  56. package/dist/onramp.d.ts +51 -33
  57. package/dist/onramp.mjs +5 -34
  58. package/dist/polymarket.cjs +6 -6
  59. package/dist/polymarket.mjs +2 -2
  60. package/dist/ramp-types-HYWd7CW0.d.cts +108 -0
  61. package/dist/ramp-types-HYWd7CW0.d.ts +108 -0
  62. package/dist/styles.css +255 -0
  63. package/dist/{types-BShYNpvO.d.cts → types-BxSrazbq.d.ts} +20 -2
  64. package/dist/{types-BOxa1DE-.d.ts → types-CixUBhrM.d.cts} +20 -2
  65. package/dist/withdraw.cjs +6 -5
  66. package/dist/withdraw.d.cts +4 -3
  67. package/dist/withdraw.d.ts +4 -3
  68. package/dist/withdraw.mjs +5 -4
  69. package/package.json +9 -17
  70. package/dist/WithdrawModal-DY6A55OA.mjs +0 -11
  71. package/dist/WithdrawModal-V42OK7L3.cjs +0 -11
  72. package/dist/chunk-ADEWTBSN.cjs +0 -19
  73. package/dist/chunk-EAGMY3QE.mjs +0 -962
  74. package/dist/chunk-OY5N3E6L.cjs +0 -962
  75. package/dist/chunk-PP4QE32S.mjs +0 -19
  76. package/dist/constants-BT4ctuHo.d.cts +0 -64
  77. package/dist/constants-D21ZdNOP.d.ts +0 -64
  78. package/dist/offramp.cjs +0 -25
  79. package/dist/offramp.d.cts +0 -28
  80. package/dist/offramp.d.ts +0 -28
  81. package/dist/offramp.mjs +0 -25
  82. package/dist/ramp-types-C6aUz4SZ.d.cts +0 -43
  83. package/dist/ramp-types-C6aUz4SZ.d.ts +0 -43
@@ -9,45 +9,30 @@ import {
9
9
  executePolymarketSafeTransfer,
10
10
  fetchPolymarketProxyWallet,
11
11
  readPolymarketBalances
12
- } from "./chunk-FTWKAJGN.mjs";
12
+ } from "./chunk-2FOPO4N5.mjs";
13
13
  import {
14
14
  AnalyticsSession,
15
- AppleIcon,
16
- BankIcon,
17
- BodyHeader,
15
+ AssetMetadataProvider,
18
16
  Button,
19
17
  Callout,
20
- CardIcon,
21
18
  CdnIcon,
22
19
  ChainCatalogProvider,
23
- CheckIcon,
24
- ChevronDownIcon,
25
- ChevronLeftIcon,
26
- CloseIcon,
27
- CopyIcon,
28
- ExternalLinkIcon,
29
- HandCoinsIcon,
30
20
  HistoryEntryButton,
31
21
  HistoryOverlay,
32
- InfoIcon,
33
22
  ListRow,
34
- MigrateAssetsIcon,
35
23
  Modal,
36
24
  PermitDepositSubmitError,
37
25
  PoweredBy,
38
26
  ProcessingStep,
39
27
  RpcUrlsProvider,
28
+ SOLANA_TOKENS,
40
29
  SUPPORTED_CONNECT_EXCHANGE_COUNT,
41
30
  SetupError,
42
- Spinner,
43
- SwappedConnectFeeChangedError,
44
31
  TokenIcon,
45
32
  Tooltip,
46
- TransferCryptoIcon,
47
- UnplugIcon,
48
- WalletIcon,
49
33
  analyticsTargetProperties,
50
34
  applyTheme,
35
+ assetIdFor,
51
36
  catalogKeyForChain,
52
37
  chainIdsByValue,
53
38
  checkBackendUrl,
@@ -62,7 +47,6 @@ import {
62
47
  depositBoundsViolation,
63
48
  describePolicyRefusal,
64
49
  failureMessageForEvent,
65
- fetchTokenPriceUsd,
66
50
  formatExpectedDuration,
67
51
  formatQuotedReceive,
68
52
  formatReceiveEstimate,
@@ -80,16 +64,19 @@ import {
80
64
  isFailedEvent,
81
65
  isHistoryEntryVisible,
82
66
  isNativeAsset,
83
- isRecognizedToken,
67
+ isNativeSol,
84
68
  isSubmissionUncertain,
85
69
  portfolioToAssets,
86
70
  quoteFeeRow,
87
71
  readDedupedAccountSetupResult,
88
72
  resolveAppFeeBps,
73
+ resolveCuratedToken,
74
+ resolveSolanaToken,
89
75
  rpcUrlFor,
90
76
  runAccountSetupDeduped,
91
77
  tokenFormatter,
92
78
  txRefsMatch,
79
+ useAssetStore,
93
80
  useCatalogChain,
94
81
  useChainCatalog,
95
82
  useChainName,
@@ -100,38 +87,54 @@ import {
100
87
  useExplorerTxUrl,
101
88
  useHistoryPanel,
102
89
  useIsDepositChain,
103
- useLatestRef,
90
+ useIsRecognizedToken,
104
91
  useRestrictedListExclusion,
105
92
  useRpcUrls,
106
93
  useStableRpcUrls,
94
+ useTokenDisplay,
95
+ useTokenDisplays,
107
96
  warnRemovedProps
108
- } from "./chunk-5NWLS5BQ.mjs";
97
+ } from "./chunk-32ERBFMO.mjs";
98
+ import {
99
+ AppleIcon,
100
+ BankIcon,
101
+ BodyHeader,
102
+ CardIcon,
103
+ CheckIcon,
104
+ ChevronDownIcon,
105
+ ChevronLeftIcon,
106
+ CloseIcon,
107
+ CopyIcon,
108
+ ExternalLinkIcon,
109
+ HandCoinsIcon,
110
+ InfoIcon,
111
+ MigrateAssetsIcon,
112
+ Spinner,
113
+ TransferCryptoIcon,
114
+ UnplugIcon,
115
+ WalletIcon,
116
+ useLatestRef
117
+ } from "./chunk-YY4ZOAH5.mjs";
109
118
  import {
110
119
  HYPERCORE_CHAIN_ID,
111
120
  HYPERCORE_MIN_DEPOSIT_USD,
112
121
  HYPERCORE_SPOT_CAIP2,
113
122
  NATIVE_TOKEN_ADDRESS,
114
123
  SOLANA_MAINNET_CAIP2,
115
- SOLANA_TOKENS,
116
124
  SUPPORTED_CHAIN_IDS,
117
125
  cdnIconUrl,
118
- findTokenDecimals,
119
126
  getChainBadge,
120
127
  getChainIcon,
121
128
  getChainId,
122
129
  getChainName,
123
- getNativeSymbol,
124
130
  getSupportedChainIds,
125
- getTargetTokenSymbol,
126
- getTargetTokenSymbolsForChain,
127
131
  isHyperCoreDestination,
128
- isNativeSol,
129
132
  isStablecoinSymbol,
130
133
  isVirtualDestination,
131
134
  parseEvmChainId,
132
135
  targetChainToChainId,
133
136
  toEvmCaip2
134
- } from "./chunk-EAGMY3QE.mjs";
137
+ } from "./chunk-E7IMWVMN.mjs";
135
138
 
136
139
  // src/core/reown-dependencies.ts
137
140
  var dependencies;
@@ -164,12 +167,12 @@ function getReownDependencies() {
164
167
  // src/DepositModal.tsx
165
168
  import {
166
169
  useMemo as useMemo9,
167
- useEffect as useEffect14,
168
- useRef as useRef10,
169
- useState as useState14,
170
- useCallback as useCallback8,
171
- lazy as lazy2,
172
- Suspense as Suspense2
170
+ useEffect as useEffect15,
171
+ useRef as useRef11,
172
+ useState as useState15,
173
+ useCallback as useCallback9,
174
+ lazy as lazy3,
175
+ Suspense as Suspense3
173
176
  } from "react";
174
177
 
175
178
  // src/DepositFlow.tsx
@@ -179,7 +182,9 @@ import {
179
182
  useMemo as useMemo8,
180
183
  useEffect as useEffect13,
181
184
  useLayoutEffect as useLayoutEffect2,
182
- useRef as useRef9
185
+ useRef as useRef9,
186
+ lazy as lazy2,
187
+ Suspense as Suspense2
183
188
  } from "react";
184
189
 
185
190
  // src/components/steps/ConnectStep.tsx
@@ -508,6 +513,7 @@ function ConnectStep({
508
513
  transferCryptoErrorReason,
509
514
  fiatPaymentMethods,
510
515
  fiatLoading,
516
+ fiatNotice,
511
517
  onSelectFiatMethod,
512
518
  onPrefetchFiatMethod,
513
519
  recommendedMethod,
@@ -685,6 +691,7 @@ function ConnectStep({
685
691
  ) : void 0
686
692
  }
687
693
  ),
694
+ fiatNotice && (activeTab === "cash" || !hasCash) && /* @__PURE__ */ jsx5(Callout, { variant: "warning", children: fiatNotice }),
688
695
  /* @__PURE__ */ jsx5(
689
696
  "div",
690
697
  {
@@ -801,7 +808,7 @@ function AssetSelectStep({
801
808
  isDepositChain,
802
809
  catalog
803
810
  ]);
804
- const rows = useMemo(() => {
811
+ const filteredRows = useMemo(() => {
805
812
  return assets.filter((a) => {
806
813
  if (!isDepositChain(a.chainId)) return false;
807
814
  try {
@@ -827,6 +834,20 @@ function AssetSelectStep({
827
834
  return 0;
828
835
  });
829
836
  }, [assets, isDepositChain, isExcludedByRestrictedList]);
837
+ const displays = useTokenDisplays(
838
+ filteredRows.map((asset) => ({
839
+ chain: asset.chainId,
840
+ address: asset.token,
841
+ fallback: { symbol: asset.symbol, decimals: asset.decimals }
842
+ }))
843
+ );
844
+ const rows = useMemo(
845
+ () => filteredRows.map((asset, i) => {
846
+ const symbol = displays[i]?.symbol ?? asset.symbol;
847
+ return symbol === asset.symbol ? asset : { ...asset, symbol, name: symbol };
848
+ }),
849
+ [filteredRows, displays]
850
+ );
830
851
  useEffect2(() => {
831
852
  if (!defaultAssetId || selectedAssetId) return;
832
853
  if (rows.some((asset) => asset.id === defaultAssetId)) {
@@ -896,6 +917,7 @@ function AssetSelectStep({
896
917
  /* @__PURE__ */ jsx6("span", { className: "rs-asset-icon", children: /* @__PURE__ */ jsx6(
897
918
  TokenIcon,
898
919
  {
920
+ token: { chain: asset.chainId, address: asset.token },
899
921
  symbol: asset.symbol,
900
922
  fallback: asset.symbol.slice(0, 4)
901
923
  }
@@ -958,7 +980,7 @@ async function fetchNativeAssets(address, publicClient, existing, isDepositChain
958
980
  if (existingIds.has(id)) return [];
959
981
  try {
960
982
  const balance = await publicClient.getBalance({ address });
961
- const nativeSymbol = catalogChain?.nativeToken.symbol ?? getNativeSymbol(connectedChainId);
983
+ const nativeSymbol = catalogChain?.nativeToken.symbol ?? "Token";
962
984
  const nativeDecimals = catalogChain?.nativeToken.decimals ?? 18;
963
985
  return [
964
986
  {
@@ -1140,7 +1162,7 @@ function AmountStep({
1140
1162
  walletClient?.chain?.id && walletClient.chain.id !== asset.chainId
1141
1163
  );
1142
1164
  const targetChainId = targetChainToChainId(targetChain);
1143
- const targetSymbol = getTargetTokenSymbol(targetToken, targetChainId);
1165
+ const targetSymbol = useTokenDisplay(targetChainId, targetToken).symbol;
1144
1166
  const isSourceStablecoin = isStablecoinSymbol(asset.symbol);
1145
1167
  const derivedPriceUsd = useMemo2(() => {
1146
1168
  if (tokenPriceUsdOverride !== void 0 && tokenPriceUsdOverride > 0)
@@ -1457,7 +1479,13 @@ function AmountStep({
1457
1479
  " ",
1458
1480
  asset.symbol
1459
1481
  ] }),
1460
- /* @__PURE__ */ jsx8("span", { className: "rs-amount-detail-icon", children: /* @__PURE__ */ jsx8(TokenIcon, { symbol: asset.symbol }) })
1482
+ /* @__PURE__ */ jsx8("span", { className: "rs-amount-detail-icon", children: /* @__PURE__ */ jsx8(
1483
+ TokenIcon,
1484
+ {
1485
+ token: { chain: asset.chainId, address: asset.token },
1486
+ symbol: asset.symbol
1487
+ }
1488
+ ) })
1461
1489
  ] })
1462
1490
  ] }),
1463
1491
  /* @__PURE__ */ jsxs6("div", { className: "rs-amount-detail-row", children: [
@@ -1468,7 +1496,13 @@ function AmountStep({
1468
1496
  " ",
1469
1497
  targetSymbol
1470
1498
  ] }),
1471
- /* @__PURE__ */ jsx8("span", { className: "rs-amount-detail-icon", children: /* @__PURE__ */ jsx8(TokenIcon, { symbol: targetSymbol }) })
1499
+ /* @__PURE__ */ jsx8("span", { className: "rs-amount-detail-icon", children: /* @__PURE__ */ jsx8(
1500
+ TokenIcon,
1501
+ {
1502
+ token: { chain: targetChainId, address: targetToken },
1503
+ symbol: targetSymbol
1504
+ }
1505
+ ) })
1472
1506
  ] })
1473
1507
  ] }),
1474
1508
  balanceAfterUsd !== null && /* @__PURE__ */ jsxs6("div", { className: "rs-amount-detail-row", children: [
@@ -1517,8 +1551,10 @@ function ReviewDetails({
1517
1551
  estimatedTime,
1518
1552
  sendAmount,
1519
1553
  sendSymbol,
1554
+ sendToken,
1520
1555
  receiveDisplay,
1521
1556
  receiveSymbol,
1557
+ receiveToken,
1522
1558
  fee
1523
1559
  }) {
1524
1560
  return /* @__PURE__ */ jsxs7("div", { className: "rs-review-details", children: [
@@ -1548,14 +1584,14 @@ function ReviewDetails({
1548
1584
  " ",
1549
1585
  sendSymbol
1550
1586
  ] }),
1551
- /* @__PURE__ */ jsx9("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx9(TokenIcon, { symbol: sendSymbol }) })
1587
+ /* @__PURE__ */ jsx9("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx9(TokenIcon, { token: sendToken, symbol: sendSymbol }) })
1552
1588
  ] })
1553
1589
  ] }),
1554
1590
  /* @__PURE__ */ jsxs7("div", { className: "rs-review-detail-row", children: [
1555
1591
  /* @__PURE__ */ jsx9("span", { children: "Receive" }),
1556
1592
  /* @__PURE__ */ jsxs7("span", { className: "rs-review-detail-value", children: [
1557
1593
  /* @__PURE__ */ jsx9("span", { children: receiveDisplay }),
1558
- /* @__PURE__ */ jsx9("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx9(TokenIcon, { symbol: receiveSymbol }) })
1594
+ /* @__PURE__ */ jsx9("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx9(TokenIcon, { token: receiveToken, symbol: receiveSymbol }) })
1559
1595
  ] })
1560
1596
  ] }),
1561
1597
  /* @__PURE__ */ jsxs7("div", { className: "rs-review-detail-row", children: [
@@ -1785,7 +1821,9 @@ function ConfirmStep({
1785
1821
  ]);
1786
1822
  const quote = setupReady && quoteResult?.requestKey === quoteRequestKey ? quoteResult.quote : null;
1787
1823
  const targetChainId = targetChainToChainId(targetChain);
1788
- const targetSymbol = sameRoute ? asset.symbol : getTargetTokenSymbol(targetToken, targetChainId);
1824
+ const resolvedTargetSymbol = useTokenDisplay(targetChainId, targetToken).symbol;
1825
+ const targetSymbol = sameRoute ? asset.symbol : resolvedTargetSymbol;
1826
+ const sourceTrusted = useIsRecognizedToken(asset.chainId, asset.token);
1789
1827
  const sourceChainName = getChainName(asset.chainId);
1790
1828
  const targetChainName = getChainName(targetChainId);
1791
1829
  const sourceChainIcon = getChainIcon(asset.chainId);
@@ -1838,7 +1876,7 @@ function ConfirmStep({
1838
1876
  sourceSymbol: asset.symbol,
1839
1877
  targetSymbol,
1840
1878
  sourceAmountUsd,
1841
- sourceTrusted: isRecognizedToken(asset.token, asset.chainId),
1879
+ sourceTrusted,
1842
1880
  // The target is the curated deposit destination, so a stablecoin target
1843
1881
  // estimates at $1 when unquoted (DepositFlow skips fetching stablecoin
1844
1882
  // target prices). Not applied to the source — that can be a held token.
@@ -2143,8 +2181,10 @@ function ConfirmStep({
2143
2181
  estimatedTime: estimatedTimeDisplay,
2144
2182
  sendAmount: formattedSendAmount,
2145
2183
  sendSymbol: asset.symbol,
2184
+ sendToken: { chain: asset.chainId, address: asset.token },
2146
2185
  receiveDisplay,
2147
2186
  receiveSymbol: targetSymbol,
2187
+ receiveToken: sameRoute ? { chain: asset.chainId, address: asset.token } : { chain: targetChainId, address: targetToken },
2148
2188
  fee: { display: feeDisplay, struck: feesFullySponsored }
2149
2189
  }
2150
2190
  ),
@@ -2200,7 +2240,8 @@ function QrReviewStep({
2200
2240
  }) {
2201
2241
  const [quote, setQuote] = useState5({ state: "loading", value: null });
2202
2242
  const targetChainId = targetChainToChainId(targetChain);
2203
- const targetSymbol = getTargetTokenSymbol(targetToken, targetChainId);
2243
+ const targetSymbol = useTokenDisplay(targetChainId, targetToken).symbol;
2244
+ const sourceTrusted = useIsRecognizedToken(asset.chainId, asset.token);
2204
2245
  const boundsFor = useDepositBounds();
2205
2246
  useEffect5(() => {
2206
2247
  let cancelled = false;
@@ -2253,7 +2294,7 @@ function QrReviewStep({
2253
2294
  sourceSymbol: asset.symbol,
2254
2295
  targetSymbol,
2255
2296
  sourceAmountUsd: Number.isFinite(usdValue) && usdValue > 0 ? usdValue : void 0,
2256
- sourceTrusted: isRecognizedToken(asset.token, asset.chainId),
2297
+ sourceTrusted,
2257
2298
  prices: targetTokenPriceUsd !== null && targetTokenPriceUsd > 0 ? { [targetSymbol.toUpperCase()]: targetTokenPriceUsd } : isDisplayStablecoinSymbol(targetSymbol) ? { [targetSymbol.toUpperCase()]: 1 } : {}
2258
2299
  });
2259
2300
  return estimate ?? targetSymbol;
@@ -2275,8 +2316,10 @@ function QrReviewStep({
2275
2316
  estimatedTime,
2276
2317
  sendAmount: formattedSendAmount,
2277
2318
  sendSymbol: asset.symbol,
2319
+ sendToken: { chain: asset.chainId, address: asset.token },
2278
2320
  receiveDisplay,
2279
2321
  receiveSymbol: targetSymbol,
2322
+ receiveToken: { chain: targetChainId, address: targetToken },
2280
2323
  fee: { display: feeDisplay, struck }
2281
2324
  }
2282
2325
  ),
@@ -2311,8 +2354,7 @@ function DepositAddressSkeleton({
2311
2354
  }) {
2312
2355
  const evmChainIds = getSupportedChainIds();
2313
2356
  const defaultChainId = evmChainIds.includes(BASE_CHAIN_ID) ? BASE_CHAIN_ID : evmChainIds[0];
2314
- const tokensForChain = getTargetTokenSymbolsForChain(defaultChainId);
2315
- const defaultToken = tokensForChain.includes("USDC") ? "USDC" : tokensForChain[0] ?? "USDC";
2357
+ const defaultToken = "USDC";
2316
2358
  const chainName = getChainName(defaultChainId);
2317
2359
  const chainIcon = getChainIcon(defaultChainId);
2318
2360
  return /* @__PURE__ */ jsxs10("div", { className: "rs-screen", "aria-busy": "true", children: [
@@ -2351,10 +2393,10 @@ function DepositAddressSkeleton({
2351
2393
  ] }),
2352
2394
  /* @__PURE__ */ jsxs10("div", { className: "rs-deposit-address-dropdown-trigger", children: [
2353
2395
  /* @__PURE__ */ jsx12(
2354
- TokenIcon,
2396
+ "span",
2355
2397
  {
2356
- symbol: defaultToken,
2357
- className: "rs-deposit-address-dropdown-icon"
2398
+ className: "rs-token-icon rs-deposit-address-dropdown-icon",
2399
+ "data-loading": ""
2358
2400
  }
2359
2401
  ),
2360
2402
  /* @__PURE__ */ jsx12("span", { children: defaultToken }),
@@ -2786,18 +2828,8 @@ function asString(value) {
2786
2828
  return typeof value === "string" ? value : void 0;
2787
2829
  }
2788
2830
  function resolveSolanaTokenMeta(token) {
2789
- if (!token) return {};
2790
- const normalized = token.toLowerCase();
2791
- const matched = SOLANA_TOKENS.find(
2792
- (entry) => entry.mint.toLowerCase() === normalized
2793
- );
2794
- if (matched) {
2795
- return { sourceSymbol: matched.symbol, sourceDecimals: matched.decimals };
2796
- }
2797
- if (normalized === "native" || normalized === "11111111111111111111111111111111" || normalized === "so11111111111111111111111111111111111111112") {
2798
- return { sourceSymbol: "SOL", sourceDecimals: 9 };
2799
- }
2800
- return {};
2831
+ const matched = token ? resolveSolanaToken(token) : void 0;
2832
+ return matched ? { sourceSymbol: matched.symbol, sourceDecimals: matched.decimals } : {};
2801
2833
  }
2802
2834
  function getDepositEventDetails(event) {
2803
2835
  if (!event?.type || !isRecord(event.data)) return {};
@@ -2855,10 +2887,11 @@ function selectionAsAsset(chainId, symbol, offer, catalogChain) {
2855
2887
  decimals
2856
2888
  };
2857
2889
  }
2858
- function TokenGlyph({ symbol }) {
2890
+ function TokenGlyph({ symbol, token }) {
2859
2891
  return /* @__PURE__ */ jsx14(
2860
2892
  TokenIcon,
2861
2893
  {
2894
+ token,
2862
2895
  symbol,
2863
2896
  className: "rs-deposit-address-dropdown-icon",
2864
2897
  fallback: /* @__PURE__ */ jsx14("span", { className: "rs-deposit-address-dropdown-icon rs-deposit-address-dropdown-icon--fallback", children: symbol.slice(0, 3) })
@@ -3005,7 +3038,22 @@ function DepositAddressStep({
3005
3038
  clearInterval(timer);
3006
3039
  };
3007
3040
  }, [payment, sourceChainId, sourceTokenIdentity, smartAccount, service]);
3008
- const paymentDecimals = typeof sourceChainId === "number" && sourceTokenIdentity ? findTokenDecimals(sourceTokenIdentity, sourceChainId) : void 0;
3041
+ const tokenRefFor = (symbol) => {
3042
+ const address = resolveSourceTokenIdentity({
3043
+ chain: sourceChainId,
3044
+ symbol,
3045
+ shortlist,
3046
+ catalogTokens: offer.restricted ? void 0 : catalogFor(sourceChainId)?.supportedTokens
3047
+ });
3048
+ return address ? { chain: sourceChainId, address } : void 0;
3049
+ };
3050
+ const assetStore = useAssetStore();
3051
+ const assetStoreRef = useRef5(assetStore);
3052
+ assetStoreRef.current = assetStore;
3053
+ const paymentDecimals = useTokenDisplay(
3054
+ typeof sourceChainId === "number" ? sourceChainId : void 0,
3055
+ sourceTokenIdentity
3056
+ ).decimals;
3009
3057
  const paymentAmountUnits = payment && paymentUnits !== "loading" && paymentUnits !== "unavailable" ? paymentUnits : null;
3010
3058
  const paymentDisplay = paymentAmountUnits !== null && paymentDecimals !== void 0 ? formatUnits3(BigInt(paymentAmountUnits), paymentDecimals) : null;
3011
3059
  const qrValue = paymentAmountUnits !== null && typeof sourceChainId === "number" && sourceTokenIdentity ? paymentRequestUri({
@@ -3151,10 +3199,10 @@ function DepositAddressStep({
3151
3199
  baselineTxHashRef.current = eventTxHash;
3152
3200
  isTrackingRef.current = true;
3153
3201
  const isEvmToken = token ? /^0x[a-fA-F0-9]{40}$/.test(token) : false;
3154
- const sourceDecimals = details.sourceDecimals ?? (isEvmToken ? findTokenDecimals(
3155
- token,
3156
- typeof chainId === "number" ? chainId : void 0
3157
- ) : void 0);
3202
+ const knownChain = chainId === "unknown" ? void 0 : chainId;
3203
+ const sourceDecimals = details.sourceDecimals ?? (token && knownChain !== void 0 ? resolveCuratedToken(token, knownChain)?.decimals ?? (knownChain === "hypercore" ? void 0 : assetStoreRef.current?.peekMeta(
3204
+ assetIdFor(knownChain, token) ?? ""
3205
+ )?.decimals) : void 0);
3158
3206
  const directTransfer = typeof chainId === "number" && isEvmToken && isSameRoute(
3159
3207
  chainId,
3160
3208
  token,
@@ -3314,7 +3362,13 @@ function DepositAddressStep({
3314
3362
  setChainDropdownOpen(false);
3315
3363
  },
3316
3364
  children: [
3317
- /* @__PURE__ */ jsx14(TokenGlyph, { symbol: sourceTokenSymbol }),
3365
+ /* @__PURE__ */ jsx14(
3366
+ TokenGlyph,
3367
+ {
3368
+ symbol: sourceTokenSymbol,
3369
+ token: tokenRefFor(sourceTokenSymbol)
3370
+ }
3371
+ ),
3318
3372
  /* @__PURE__ */ jsx14("span", { children: sourceTokenSymbol }),
3319
3373
  /* @__PURE__ */ jsx14(ChevronDownIcon, { className: "rs-deposit-address-dropdown-chevron" })
3320
3374
  ]
@@ -3330,7 +3384,7 @@ function DepositAddressStep({
3330
3384
  setTokenDropdownOpen(false);
3331
3385
  },
3332
3386
  children: [
3333
- /* @__PURE__ */ jsx14(TokenGlyph, { symbol }),
3387
+ /* @__PURE__ */ jsx14(TokenGlyph, { symbol, token: tokenRefFor(symbol) }),
3334
3388
  /* @__PURE__ */ jsx14("span", { children: symbol })
3335
3389
  ]
3336
3390
  },
@@ -3611,6 +3665,10 @@ function isSwappedGoBackMessage(raw) {
3611
3665
  const obj = data;
3612
3666
  return obj.key === SWAPPED_GO_BACK_KEY || obj.type === SWAPPED_GO_BACK_KEY;
3613
3667
  }
3668
+ function assetSymbol(currencyCode) {
3669
+ const separator = currencyCode?.indexOf("_") ?? -1;
3670
+ return separator > 0 ? currencyCode.slice(0, separator) : currencyCode;
3671
+ }
3614
3672
  function parseSwappedIframeMessage(raw) {
3615
3673
  let data = raw;
3616
3674
  if (typeof data === "string") {
@@ -3632,7 +3690,9 @@ function parseSwappedIframeMessage(raw) {
3632
3690
  status: rawStatus,
3633
3691
  orderId: asString2(inner.order_id) ?? asString2(obj.orderId),
3634
3692
  externalCustomerId: asString2(inner.external_customer_id) ?? asString2(obj.external_customer_id) ?? asString2(inner.externalCustomerId) ?? asString2(obj.externalCustomerId),
3635
- orderCrypto: asString2(inner.order_crypto) ?? asString2(obj.orderCrypto),
3693
+ orderCrypto: assetSymbol(
3694
+ asString2(inner.order_crypto) ?? asString2(obj.orderCrypto)
3695
+ ),
3636
3696
  orderCryptoAmount: asString2(inner.order_crypto_amount) ?? asString2(obj.orderCryptoAmount),
3637
3697
  transactionId: asString2(inner.transaction_id) ?? asString2(obj.transactionId)
3638
3698
  };
@@ -3733,8 +3793,7 @@ function SwappedProviderStep({
3733
3793
  setWidgetUrl(res.url);
3734
3794
  expectedExternalCustomerIdRef.current = res.externalCustomerId;
3735
3795
  onAttemptConsumed?.(res.externalCustomerId);
3736
- const sep = res.externalCustomerId.indexOf(":");
3737
- expectedOrderUuidRef.current = sep >= 0 ? res.externalCustomerId.slice(sep + 1) : null;
3796
+ expectedOrderUuidRef.current = res.orderId;
3738
3797
  }).catch((err) => {
3739
3798
  if (cancelled) return;
3740
3799
  const message = err instanceof Error ? err.message : loadErrorFallback;
@@ -3797,9 +3856,10 @@ function SwappedProviderStep({
3797
3856
  async function poll() {
3798
3857
  if (cancelled) return;
3799
3858
  try {
3800
- const res = await service.fetchSwappedOrderStatus(smartAccount);
3859
+ const orderId = expectedOrderUuidRef.current;
3860
+ const res = orderId ? await service.fetchSwappedOrder(orderId) : null;
3801
3861
  if (cancelled) return;
3802
- const isCurrentOrder = res !== null && expectedOrderUuidRef.current !== null && res.orderId === expectedOrderUuidRef.current;
3862
+ const isCurrentOrder = res !== null && res.orderId === expectedOrderUuidRef.current;
3803
3863
  if (isCurrentOrder) {
3804
3864
  setOrderState(res);
3805
3865
  }
@@ -4305,9 +4365,6 @@ function ExchangeLogo({ exchange }) {
4305
4365
  }
4306
4366
  );
4307
4367
  }
4308
- function formatFeeRate(bps) {
4309
- return `${(bps / 100).toFixed(2).replace(/\.?0+$/, "")}%`;
4310
- }
4311
4368
  function ExchangeSelectStep({
4312
4369
  service,
4313
4370
  onSelectExchange,
@@ -4317,7 +4374,6 @@ function ExchangeSelectStep({
4317
4374
  const [loading, setLoading] = useState9(true);
4318
4375
  const [error, setError] = useState9(null);
4319
4376
  const [retryToken, setRetryToken] = useState9(0);
4320
- const [exchangeFeeBps, setExchangeFeeBps] = useState9(0);
4321
4377
  const [selectingConnection, setSelectingConnection] = useState9(
4322
4378
  null
4323
4379
  );
@@ -4332,12 +4388,10 @@ function ExchangeSelectStep({
4332
4388
  service.getSwappedConnectExchanges().then((res) => {
4333
4389
  if (cancelled) return;
4334
4390
  setExchanges(res.exchanges);
4335
- setExchangeFeeBps(res.exchangeFeeBps ?? 0);
4336
4391
  }).catch((err) => {
4337
4392
  if (cancelled) return;
4338
4393
  const message = err instanceof Error ? err.message : "Failed to load exchanges";
4339
4394
  setExchanges([]);
4340
- setExchangeFeeBps(0);
4341
4395
  setError(message);
4342
4396
  onError?.(message, "SWAPPED_CONNECT_EXCHANGES_FAILED");
4343
4397
  }).finally(() => {
@@ -4352,16 +4406,7 @@ function ExchangeSelectStep({
4352
4406
  setSelectingConnection(connection);
4353
4407
  setSelectionNotice(null);
4354
4408
  try {
4355
- const actualFeeBps = await onSelectExchange(
4356
- connection,
4357
- exchangeFeeBps
4358
- );
4359
- if (actualFeeBps !== exchangeFeeBps) {
4360
- setExchangeFeeBps(actualFeeBps);
4361
- setSelectionNotice(
4362
- "The Exchange Fee changed. Review the updated rate and select your exchange again."
4363
- );
4364
- }
4409
+ await onSelectExchange(connection);
4365
4410
  } catch (err) {
4366
4411
  const message = err instanceof Error ? err.message : "Failed to prepare Connect";
4367
4412
  setSelectionNotice(message);
@@ -4370,7 +4415,7 @@ function ExchangeSelectStep({
4370
4415
  setSelectingConnection(null);
4371
4416
  }
4372
4417
  },
4373
- [exchangeFeeBps, onError, onSelectExchange]
4418
+ [onError, onSelectExchange]
4374
4419
  );
4375
4420
  return /* @__PURE__ */ jsxs16("div", { className: "rs-screen rs-exchange-select", children: [
4376
4421
  /* @__PURE__ */ jsxs16("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
@@ -4434,11 +4479,6 @@ function ExchangeSelectStep({
4434
4479
  }) })
4435
4480
  ] }),
4436
4481
  /* @__PURE__ */ jsx20(PoweredBy, {}),
4437
- exchangeFeeBps > 0 && /* @__PURE__ */ jsxs16("p", { className: "rs-exchange-select-fee-note", children: [
4438
- "A ",
4439
- formatFeeRate(exchangeFeeBps),
4440
- " Exchange Fee applies to your deposit."
4441
- ] }),
4442
4482
  selectionNotice && /* @__PURE__ */ jsx20("p", { className: "rs-exchange-select-fee-note", role: "status", children: selectionNotice })
4443
4483
  ] });
4444
4484
  }
@@ -4602,6 +4642,7 @@ function SolanaTokenSelectStep({
4602
4642
  /* @__PURE__ */ jsx21("span", { className: "rs-asset-icon", children: /* @__PURE__ */ jsx21(
4603
4643
  TokenIcon,
4604
4644
  {
4645
+ token: { chain: "solana", address: entry.token.mint },
4605
4646
  symbol: entry.token.symbol,
4606
4647
  fallback: entry.token.symbol.slice(0, 4)
4607
4648
  }
@@ -4667,6 +4708,7 @@ function SolanaAmountStep({
4667
4708
  targetChain,
4668
4709
  targetChainName,
4669
4710
  targetTokenSymbol,
4711
+ targetToken,
4670
4712
  appBalanceUsd,
4671
4713
  onContinue,
4672
4714
  debug
@@ -4906,7 +4948,13 @@ function SolanaAmountStep({
4906
4948
  "Solana ",
4907
4949
  token.symbol
4908
4950
  ] }),
4909
- /* @__PURE__ */ jsx22("span", { className: "rs-amount-detail-icon", children: /* @__PURE__ */ jsx22(TokenIcon, { symbol: token.symbol }) })
4951
+ /* @__PURE__ */ jsx22("span", { className: "rs-amount-detail-icon", children: /* @__PURE__ */ jsx22(
4952
+ TokenIcon,
4953
+ {
4954
+ token: { chain: "solana", address: token.mint },
4955
+ symbol: token.symbol
4956
+ }
4957
+ ) })
4910
4958
  ] })
4911
4959
  ] }),
4912
4960
  targetChainName && targetTokenSymbol && /* @__PURE__ */ jsxs18("div", { className: "rs-amount-detail-row", children: [
@@ -4917,7 +4965,7 @@ function SolanaAmountStep({
4917
4965
  " ",
4918
4966
  targetTokenSymbol
4919
4967
  ] }),
4920
- /* @__PURE__ */ jsx22("span", { className: "rs-amount-detail-icon", children: /* @__PURE__ */ jsx22(TokenIcon, { symbol: targetTokenSymbol }) })
4968
+ /* @__PURE__ */ jsx22("span", { className: "rs-amount-detail-icon", children: /* @__PURE__ */ jsx22(TokenIcon, { token: targetToken, symbol: targetTokenSymbol }) })
4921
4969
  ] })
4922
4970
  ] }),
4923
4971
  balanceAfterUsd !== null && /* @__PURE__ */ jsxs18("div", { className: "rs-amount-detail-row", children: [
@@ -5086,7 +5134,7 @@ function SolanaConfirmStep({
5086
5134
  return () => onSubmittingChangeRef.current?.(false);
5087
5135
  }, [isSubmitting]);
5088
5136
  const targetChainId = targetChainToChainId(targetChain);
5089
- const targetSymbol = getTargetTokenSymbol(targetToken, targetChainId);
5137
+ const targetSymbol = useTokenDisplay(targetChainId, targetToken).symbol;
5090
5138
  const sourceChainName = getChainName("solana");
5091
5139
  const targetChainName = getChainName(targetChainId);
5092
5140
  const sourceChainIcon = getChainIcon("solana");
@@ -5102,7 +5150,8 @@ function SolanaConfirmStep({
5102
5150
  sourceSymbol: token.symbol,
5103
5151
  targetSymbol,
5104
5152
  sourceAmountUsd,
5105
- sourceTrusted: isRecognizedToken(token.mint, "solana"),
5153
+ // The wallet flow only offers the allowlist, so this is the check.
5154
+ sourceTrusted: resolveSolanaToken(token.mint) !== void 0,
5106
5155
  // Curated stablecoin target estimates at $1 when unquoted; never applied
5107
5156
  // to the source (a held token). See ConfirmStep for the rationale.
5108
5157
  prices: targetTokenPriceUsd !== null && targetTokenPriceUsd > 0 ? { [targetSymbol.toUpperCase()]: targetTokenPriceUsd } : isDisplayStablecoinSymbol(targetSymbol) ? { [targetSymbol.toUpperCase()]: 1 } : {}
@@ -5217,8 +5266,10 @@ function SolanaConfirmStep({
5217
5266
  estimatedTime,
5218
5267
  sendAmount: formattedAmount,
5219
5268
  sendSymbol: token.symbol,
5269
+ sendToken: { chain: "solana", address: token.mint },
5220
5270
  receiveDisplay,
5221
5271
  receiveSymbol: targetSymbol,
5272
+ receiveToken: { chain: targetChainId, address: targetToken },
5222
5273
  fee: { display: "$0.04", struck: feeSponsored, tooltip: feeTooltip }
5223
5274
  }
5224
5275
  ),
@@ -5278,6 +5329,7 @@ function DappImportAssetSelectStep({
5278
5329
  /* @__PURE__ */ jsx24("span", { className: "rs-asset-icon", children: assetIcon ? /* @__PURE__ */ jsx24(CdnIcon, { src: assetIcon, alt: asset.symbol }) : /* @__PURE__ */ jsx24(
5279
5330
  TokenIcon,
5280
5331
  {
5332
+ token: { chain: asset.chainId, address: asset.token },
5281
5333
  symbol: asset.symbol,
5282
5334
  fallback: asset.symbol.slice(0, 4)
5283
5335
  }
@@ -7399,6 +7451,10 @@ function useDepositStore(selector) {
7399
7451
 
7400
7452
  // src/DepositFlow.tsx
7401
7453
  import { Fragment as Fragment6, jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
7454
+ var BankOnrampStep = lazy2(async () => {
7455
+ const module = await import("./BankOnrampStep-JG32OCM2.mjs");
7456
+ return { default: module.BankOnrampStep };
7457
+ });
7402
7458
  function swappedWidgetPrefetchKey(method, methodSelectionSource) {
7403
7459
  return JSON.stringify([methodSelectionSource ?? null, method ?? null]);
7404
7460
  }
@@ -7669,6 +7725,9 @@ function DepositFlow({
7669
7725
  initialAssetMigration,
7670
7726
  enableWallet = true,
7671
7727
  enableFiatOnramp = false,
7728
+ bankOnramp,
7729
+ onBankJourney,
7730
+ backendUrl,
7672
7731
  enableQrTransfer = true,
7673
7732
  enableGaslessDeposit = false,
7674
7733
  fiatMethods,
@@ -7722,7 +7781,15 @@ function DepositFlow({
7722
7781
  },
7723
7782
  [debug]
7724
7783
  );
7725
- const enableSwappedPreconnect = enableFiatOnramp || enableExchangeConnect;
7784
+ const bankOnrampEnabled = Boolean(
7785
+ bankOnramp && (fiatMethods === void 0 || fiatMethods["bank-transfer"] === true)
7786
+ );
7787
+ const hasSwappedFiatMethod = Boolean(
7788
+ enableFiatOnramp && (!fiatMethods || Object.entries(fiatMethods).some(
7789
+ ([method, enabled]) => enabled && !(bankOnrampEnabled && method === "bank-transfer")
7790
+ ))
7791
+ );
7792
+ const enableSwappedPreconnect = hasSwappedFiatMethod || enableExchangeConnect;
7726
7793
  useEffect13(() => {
7727
7794
  if (!enableSwappedPreconnect) return;
7728
7795
  if (typeof document === "undefined") return;
@@ -7797,11 +7864,14 @@ function DepositFlow({
7797
7864
  walletSession?.solanaAddress,
7798
7865
  walletSession?.caipAddress
7799
7866
  ]);
7800
- const offeredFiatMethods = useMemo8(
7801
- () => fiatMethods ? FIAT_ONRAMP_METHODS.filter((m) => fiatMethods[m.method]) : FIAT_ONRAMP_METHODS,
7867
+ const configuredFiatMethods = useMemo8(
7868
+ () => fiatMethods ? FIAT_ONRAMP_METHODS.filter(
7869
+ (m) => fiatMethods[m.method]
7870
+ ) : FIAT_ONRAMP_METHODS,
7802
7871
  [fiatMethods]
7803
7872
  );
7804
- const fiatEnabled = enableFiatOnramp && offeredFiatMethods.length > 0;
7873
+ const swappedFiatEnabled = enableFiatOnramp && configuredFiatMethods.length > 0;
7874
+ const fiatEnabled = bankOnrampEnabled || swappedFiatEnabled;
7805
7875
  const enabledAssetMigrationIds = useMemo8(
7806
7876
  () => Object.entries(assetMigrations ?? {}).filter(([, on]) => on).map(([id]) => id),
7807
7877
  [assetMigrations]
@@ -7841,27 +7911,23 @@ function DepositFlow({
7841
7911
  ]);
7842
7912
  const setupChainId = typeof targetChain === "number" && !isVirtualDestination(targetChain) ? targetChain : typeof defaultSourceChain === "number" ? defaultSourceChain : DEFAULT_SETUP_CHAIN_ID;
7843
7913
  const targetChainId = targetChainToChainId(targetChain);
7844
- const targetSymbol = getTargetTokenSymbol(targetToken, targetChainId);
7914
+ const targetDisplay = useTokenDisplay(targetChainId, targetToken);
7915
+ const targetSymbol = targetDisplay.symbol;
7845
7916
  const isTargetStablecoin = isStablecoinSymbol(targetSymbol);
7917
+ const assetStore = useAssetStore();
7846
7918
  const targetMarketPriceRef = useRef9(null);
7847
7919
  useEffect13(() => {
7848
7920
  targetMarketPriceRef.current = null;
7849
- if (isTargetStablecoin || targetSymbol === "Token") {
7850
- return;
7851
- }
7921
+ if (isTargetStablecoin || !assetStore) return;
7852
7922
  let cancelled = false;
7853
- fetchTokenPriceUsd(service, {
7854
- chainId: targetChainId,
7855
- address: targetToken,
7856
- symbol: targetSymbol
7857
- }).then((price) => {
7923
+ assetStore.resolvePrice({ chain: targetChainId, address: targetToken }).then((price) => {
7858
7924
  if (cancelled) return;
7859
7925
  targetMarketPriceRef.current = price;
7860
7926
  });
7861
7927
  return () => {
7862
7928
  cancelled = true;
7863
7929
  };
7864
- }, [service, targetSymbol, isTargetStablecoin, targetChain, targetToken]);
7930
+ }, [assetStore, isTargetStablecoin, targetChainId, targetToken]);
7865
7931
  const walletSignerContext = useMemo8(() => {
7866
7932
  if (flowMode === "deposit-address") {
7867
7933
  return null;
@@ -8116,11 +8182,14 @@ function DepositFlow({
8116
8182
  useEffect13(() => {
8117
8183
  setQrSourcePrice({ resolved: false, usd: null });
8118
8184
  if (!qrSourceAsset) return;
8185
+ if (!assetStore) {
8186
+ setQrSourcePrice({ resolved: true, usd: null });
8187
+ return;
8188
+ }
8119
8189
  let cancelled = false;
8120
- fetchTokenPriceUsd(service, {
8121
- chainId: qrSourceAsset.chainId,
8122
- address: qrSourceAsset.token,
8123
- symbol: qrSourceAsset.symbol
8190
+ assetStore.resolvePrice({
8191
+ chain: qrSourceAsset.chainId,
8192
+ address: qrSourceAsset.token
8124
8193
  }).then((usd) => {
8125
8194
  if (!cancelled) setQrSourcePrice({ resolved: true, usd });
8126
8195
  }).catch(() => {
@@ -8129,7 +8198,7 @@ function DepositFlow({
8129
8198
  return () => {
8130
8199
  cancelled = true;
8131
8200
  };
8132
- }, [service, qrSourceKey]);
8201
+ }, [assetStore, qrSourceKey]);
8133
8202
  const canGoBackFromHere = effectiveStep.type === "deposit-address" || effectiveStep.type === "solana-token-select" || effectiveStep.type === "solana-amount" || effectiveStep.type === "solana-confirm" || effectiveStep.type === "amount" || effectiveStep.type === "confirm" || // Without these the QR detour has no exit but the modal's close button,
8134
8203
  // which drops the user out of the deposit entirely rather than back to
8135
8204
  // the address they came from.
@@ -8251,7 +8320,9 @@ function DepositFlow({
8251
8320
  [assetMigrationsKey, isSolanaWalletConnected]
8252
8321
  );
8253
8322
  const initialAssetMigrationProvider = useMemo8(
8254
- () => initialAssetMigration ? enabledDappImportProviders.find((p) => p.id === initialAssetMigration) ?? null : null,
8323
+ () => initialAssetMigration ? enabledDappImportProviders.find(
8324
+ (p) => p.id === initialAssetMigration
8325
+ ) ?? null : null,
8255
8326
  [initialAssetMigration, enabledDappImportProviders]
8256
8327
  );
8257
8328
  const handleSelectDappImport = useCallback7(
@@ -8499,10 +8570,7 @@ function DepositFlow({
8499
8570
  storeApi
8500
8571
  ]);
8501
8572
  const handleBootRetry = useCallback7(() => {
8502
- analytics.retry(
8503
- "migration_availability_failed",
8504
- "migration_boot_resolve"
8505
- );
8573
+ analytics.retry("migration_availability_failed", "migration_boot_resolve");
8506
8574
  const snapshot = storeApi.getState();
8507
8575
  const providerId = snapshot.dappImport.activeProviderId;
8508
8576
  if (!providerId) return;
@@ -8544,9 +8612,12 @@ function DepositFlow({
8544
8612
  storeApi.dispatch({ type: "connect/exchange-selected" });
8545
8613
  }, [analytics, storeApi]);
8546
8614
  const swappedAnalyticsCorrelatorRef = useRef9(null);
8547
- const handleSwappedAttemptConsumed = useCallback7((externalCustomerId) => {
8548
- swappedAnalyticsCorrelatorRef.current = externalCustomerId;
8549
- }, []);
8615
+ const handleSwappedAttemptConsumed = useCallback7(
8616
+ (externalCustomerId) => {
8617
+ swappedAnalyticsCorrelatorRef.current = externalCustomerId;
8618
+ },
8619
+ []
8620
+ );
8550
8621
  const handleSwappedProviderHandoff = useCallback7(() => {
8551
8622
  const externalCustomerId = swappedAnalyticsCorrelatorRef.current;
8552
8623
  if (!externalCustomerId) return;
@@ -8564,45 +8635,27 @@ function DepositFlow({
8564
8635
  swappedAnalyticsCorrelatorRef.current = null;
8565
8636
  }, [analytics, flowMode]);
8566
8637
  const swappedConnectUrlRef = useRef9(/* @__PURE__ */ new Map());
8567
- const acknowledgedConnectFeeRef = useRef9(/* @__PURE__ */ new Map());
8568
8638
  const handleSelectExchangeConnection = useCallback7(
8569
- async (connection, disclosedFeeBps) => {
8639
+ async (connection) => {
8570
8640
  if (setupSlice.status !== "ready" || !setupSlice.smartAccount) {
8571
8641
  throw new Error("Deposit account is not ready");
8572
8642
  }
8573
8643
  const smartAccount = setupSlice.smartAccount;
8574
8644
  const owner = smartAccount.toLowerCase();
8575
8645
  const key = `${owner}:${connection}`;
8576
- let entry = swappedConnectUrlRef.current.get(key);
8577
- if (!entry) {
8578
- let response;
8579
- try {
8580
- response = await service.getSwappedConnectUrl({
8581
- smartAccount,
8582
- connection,
8583
- acceptedExchangeFeeBps: disclosedFeeBps
8584
- });
8585
- } catch (error) {
8586
- if (error instanceof SwappedConnectFeeChangedError) {
8587
- return error.exchangeFeeBps;
8588
- }
8589
- throw error;
8590
- }
8591
- entry = { smartAccount: owner, response };
8592
- }
8646
+ const entry = swappedConnectUrlRef.current.get(key) ?? {
8647
+ smartAccount: owner,
8648
+ response: await service.getSwappedConnectUrl({
8649
+ smartAccount,
8650
+ connection
8651
+ })
8652
+ };
8593
8653
  const currentAccount = storeApi.getState().setup.smartAccount;
8594
8654
  if (currentAccount?.toLowerCase() !== owner) {
8595
8655
  swappedConnectUrlRef.current.delete(key);
8596
8656
  throw new Error("Deposit account changed. Select your exchange again.");
8597
8657
  }
8598
- const actualFeeBps = entry.response.exchangeFeeBps ?? 0;
8599
- if (actualFeeBps !== disclosedFeeBps) {
8600
- swappedConnectUrlRef.current.delete(key);
8601
- acknowledgedConnectFeeRef.current.delete(key);
8602
- return actualFeeBps;
8603
- }
8604
8658
  swappedConnectUrlRef.current.set(key, entry);
8605
- acknowledgedConnectFeeRef.current.set(key, actualFeeBps);
8606
8659
  analytics.selectMethod("exchange_connect", "user", {
8607
8660
  exchange: connection
8608
8661
  });
@@ -8610,7 +8663,6 @@ function DepositFlow({
8610
8663
  type: "exchange/connection-selected",
8611
8664
  connection
8612
8665
  });
8613
- return actualFeeBps;
8614
8666
  },
8615
8667
  [analytics, service, setupSlice.status, setupSlice.smartAccount, storeApi]
8616
8668
  );
@@ -8618,25 +8670,8 @@ function DepositFlow({
8618
8670
  async (smartAccount, connection) => {
8619
8671
  const key = `${smartAccount.toLowerCase()}:${connection}`;
8620
8672
  const entry = swappedConnectUrlRef.current.get(key);
8621
- const expectedFeeBps = acknowledgedConnectFeeRef.current.get(key);
8622
- if (expectedFeeBps === void 0) {
8623
- throw new Error(
8624
- "The Exchange Fee changed. Go back and select your exchange again."
8625
- );
8626
- }
8627
8673
  swappedConnectUrlRef.current.delete(key);
8628
- const response = entry?.smartAccount === smartAccount.toLowerCase() ? entry.response : await service.getSwappedConnectUrl({
8629
- smartAccount,
8630
- connection,
8631
- acceptedExchangeFeeBps: expectedFeeBps
8632
- });
8633
- const actualFeeBps = response.exchangeFeeBps ?? 0;
8634
- if (actualFeeBps !== expectedFeeBps) {
8635
- throw new Error(
8636
- "The Exchange Fee changed. Go back and select your exchange again."
8637
- );
8638
- }
8639
- return response;
8674
+ return entry?.smartAccount === smartAccount.toLowerCase() ? entry.response : service.getSwappedConnectUrl({ smartAccount, connection });
8640
8675
  },
8641
8676
  [service]
8642
8677
  );
@@ -8695,7 +8730,6 @@ function DepositFlow({
8695
8730
  useEffect13(() => {
8696
8731
  swappedUrlPrefetchRef.current.clear();
8697
8732
  swappedConnectUrlRef.current.clear();
8698
- acknowledgedConnectFeeRef.current.clear();
8699
8733
  }, [setupSlice.smartAccount]);
8700
8734
  const hasConfiguredFiatMethods = fiatMethods !== void 0;
8701
8735
  const [regionalMethods, setRegionalMethods] = useState13({
@@ -8705,7 +8739,7 @@ function DepositFlow({
8705
8739
  recommendedMethod: null
8706
8740
  });
8707
8741
  useEffect13(() => {
8708
- if (!fiatEnabled || hasConfiguredFiatMethods) return;
8742
+ if (!enableFiatOnramp || hasConfiguredFiatMethods) return;
8709
8743
  let cancelled = false;
8710
8744
  setRegionalMethods({
8711
8745
  status: "loading",
@@ -8743,25 +8777,47 @@ function DepositFlow({
8743
8777
  cancelled = true;
8744
8778
  clearTimeout(timeoutTimer);
8745
8779
  };
8746
- }, [analytics, fiatEnabled, hasConfiguredFiatMethods, service]);
8780
+ }, [analytics, enableFiatOnramp, hasConfiguredFiatMethods, service]);
8781
+ const swappedCashDisplay = useMemo8(
8782
+ () => !enableFiatOnramp ? { kind: "hidden" } : hasConfiguredFiatMethods ? {
8783
+ kind: "list",
8784
+ methods: configuredFiatMethods,
8785
+ recommendedMethod: configuredFiatMethods[0]?.method ?? "bank-transfer",
8786
+ country: null,
8787
+ source: "configured"
8788
+ } : composeFiatMethods(regionalMethods, FIAT_ONRAMP_METHODS),
8789
+ [
8790
+ configuredFiatMethods,
8791
+ enableFiatOnramp,
8792
+ hasConfiguredFiatMethods,
8793
+ regionalMethods
8794
+ ]
8795
+ );
8796
+ const swappedOffersBank = swappedCashDisplay.kind === "list" && swappedCashDisplay.methods.some(({ method }) => method === "bank-transfer");
8797
+ const [bankOnrampUnavailable, setBankOnrampUnavailable] = useState13(false);
8798
+ const bankRowOffered = bankOnrampEnabled && !bankOnrampUnavailable;
8799
+ const swappedRefusesBank = hasConfiguredFiatMethods ? !configuredFiatMethods.some(({ method }) => method === "bank-transfer") : regionalMethods.status === "ready" && regionalMethods.country !== null && !regionalMethods.methods.some(({ method }) => method === "bank-transfer");
8800
+ const handleBankOnrampUnavailable = useCallback7(() => {
8801
+ setBankOnrampUnavailable(true);
8802
+ if (swappedRefusesBank) handleProviderBack();
8803
+ }, [handleProviderBack, swappedRefusesBank]);
8747
8804
  const cashDisplay = useMemo8(() => {
8748
- if (!fiatEnabled) return { kind: "hidden" };
8749
- if (hasConfiguredFiatMethods) {
8750
- return {
8751
- kind: "list",
8752
- methods: offeredFiatMethods,
8753
- recommendedMethod: offeredFiatMethods[0].method,
8754
- country: null,
8755
- source: "configured"
8756
- };
8805
+ const swappedDisplay = swappedCashDisplay;
8806
+ if (!bankRowOffered || swappedDisplay.kind === "loading") {
8807
+ return swappedDisplay;
8757
8808
  }
8758
- return composeFiatMethods(regionalMethods, FIAT_ONRAMP_METHODS);
8759
- }, [
8760
- fiatEnabled,
8761
- hasConfiguredFiatMethods,
8762
- offeredFiatMethods,
8763
- regionalMethods
8764
- ]);
8809
+ if (swappedOffersBank) return swappedDisplay;
8810
+ const bankTransfer = FIAT_ONRAMP_METHODS.find(
8811
+ ({ method }) => method === "bank-transfer"
8812
+ );
8813
+ return {
8814
+ kind: "list",
8815
+ methods: swappedDisplay.kind === "list" ? [...swappedDisplay.methods, bankTransfer] : [bankTransfer],
8816
+ recommendedMethod: swappedDisplay.kind === "list" ? swappedDisplay.recommendedMethod : bankTransfer.method,
8817
+ country: swappedDisplay.kind === "list" ? swappedDisplay.country : null,
8818
+ source: swappedDisplay.kind === "list" ? swappedDisplay.source : "configured"
8819
+ };
8820
+ }, [bankRowOffered, swappedCashDisplay, swappedOffersBank]);
8765
8821
  useEffect13(() => {
8766
8822
  if (cashDisplay.kind === "hidden" && fiatEnabled) {
8767
8823
  analytics.friction(
@@ -8786,9 +8842,10 @@ function DepositFlow({
8786
8842
  const handlePrefetchDisplayedFiatMethod = useCallback7(
8787
8843
  (method) => {
8788
8844
  if (!displayedFiatSource) return;
8845
+ if (bankRowOffered && method === "bank-transfer") return;
8789
8846
  handlePrefetchFiatMethod(method, displayedFiatSource);
8790
8847
  },
8791
- [displayedFiatSource, handlePrefetchFiatMethod]
8848
+ [bankRowOffered, displayedFiatSource, handlePrefetchFiatMethod]
8792
8849
  );
8793
8850
  const handleNewDeposit = useCallback7(() => {
8794
8851
  analytics.completeStep();
@@ -8803,7 +8860,6 @@ function DepositFlow({
8803
8860
  stableWalletSelectionKeyRef.current = null;
8804
8861
  swappedUrlPrefetchRef.current.clear();
8805
8862
  swappedConnectUrlRef.current.clear();
8806
- acknowledgedConnectFeeRef.current.clear();
8807
8863
  lastSmartAccountLifecycleKeyRef.current = null;
8808
8864
  }, [analytics, onLifecycleRef, storeApi]);
8809
8865
  const setupInput = useMemo8(
@@ -8969,14 +9025,12 @@ function DepositFlow({
8969
9025
  );
8970
9026
  const handleSolanaAmountContinue = useCallback7(
8971
9027
  (token, sourceAmount, inputAmountUsd) => {
8972
- const targetSym = getTargetTokenSymbol(targetToken, targetChainId);
8973
- const isTargetStable = isStablecoinSymbol(targetSym);
8974
- const targetTokenPriceUsd = isTargetStable ? 1 : targetMarketPriceRef.current;
9028
+ const targetTokenPriceUsd = isTargetStablecoin ? 1 : targetMarketPriceRef.current;
8975
9029
  logFlow("solana:amount:continue", {
8976
9030
  token: token.symbol,
8977
9031
  sourceAmount,
8978
9032
  inputAmountUsd,
8979
- targetSymbol: targetSym,
9033
+ targetSymbol,
8980
9034
  targetTokenPriceUsd
8981
9035
  });
8982
9036
  storeApi.dispatch({
@@ -8987,7 +9041,7 @@ function DepositFlow({
8987
9041
  targetTokenPriceUsd
8988
9042
  });
8989
9043
  },
8990
- [targetToken, targetChain, logFlow, storeApi]
9044
+ [isTargetStablecoin, targetSymbol, logFlow, storeApi]
8991
9045
  );
8992
9046
  const handleSolanaConfirmed = useCallback7(
8993
9047
  (txHash, amountUnits, routed) => {
@@ -9045,9 +9099,7 @@ function DepositFlow({
9045
9099
  (amount, targetAmount, balance) => {
9046
9100
  const entry = storeApi.getState().setup;
9047
9101
  if (entry.status !== "ready") return;
9048
- const targetSym = getTargetTokenSymbol(targetToken, targetChainId);
9049
- const isTargetStable = isStablecoinSymbol(targetSym);
9050
- const targetTokenPriceUsd = isTargetStable ? 1 : targetMarketPriceRef.current;
9102
+ const targetTokenPriceUsd = isTargetStablecoin ? 1 : targetMarketPriceRef.current;
9051
9103
  storeApi.dispatch({
9052
9104
  type: "amount/entered",
9053
9105
  amount,
@@ -9056,7 +9108,7 @@ function DepositFlow({
9056
9108
  balance
9057
9109
  });
9058
9110
  },
9059
- [targetToken, targetChain, storeApi, activeOwner]
9111
+ [isTargetStablecoin, storeApi, activeOwner]
9060
9112
  );
9061
9113
  const handleQrReviewRequested = useCallback7(
9062
9114
  (asset) => {
@@ -9066,8 +9118,7 @@ function DepositFlow({
9066
9118
  );
9067
9119
  const handleQrAmountContinue = useCallback7(
9068
9120
  (amount, targetAmount) => {
9069
- const targetSym = getTargetTokenSymbol(targetToken, targetChainId);
9070
- const targetTokenPriceUsd = isStablecoinSymbol(targetSym) ? 1 : targetMarketPriceRef.current;
9121
+ const targetTokenPriceUsd = isTargetStablecoin ? 1 : targetMarketPriceRef.current;
9071
9122
  storeApi.dispatch({
9072
9123
  type: "qr/amount-entered",
9073
9124
  amount,
@@ -9075,7 +9126,7 @@ function DepositFlow({
9075
9126
  targetTokenPriceUsd
9076
9127
  });
9077
9128
  },
9078
- [targetToken, targetChainId, storeApi]
9129
+ [isTargetStablecoin, storeApi]
9079
9130
  );
9080
9131
  const handleDepositSubmitted = useCallback7(
9081
9132
  (txHash, chainId, amount, token, quote, routed) => {
@@ -9228,10 +9279,7 @@ function DepositFlow({
9228
9279
  if (code === "PROCESS_TIMEOUT") {
9229
9280
  analytics.friction("processor_status_poll_failed");
9230
9281
  } else {
9231
- const reason = failureReasonForCode(
9232
- code,
9233
- `${message} ${cause ?? ""}`
9234
- );
9282
+ const reason = failureReasonForCode(code, `${message} ${cause ?? ""}`);
9235
9283
  const failureStep = code === "SWAPPED_URL_FAILED" ? "fiat_provider_mint" : code === "SWAPPED_CONNECT_URL_FAILED" ? "exchange_provider_mint" : void 0;
9236
9284
  analytics.failure(
9237
9285
  reason,
@@ -9239,7 +9287,11 @@ function DepositFlow({
9239
9287
  failureStep
9240
9288
  );
9241
9289
  }
9242
- onErrorRef.current?.({ message, code, cause });
9290
+ onErrorRef.current?.({
9291
+ message,
9292
+ code,
9293
+ ...cause === void 0 ? {} : { cause }
9294
+ });
9243
9295
  },
9244
9296
  [analytics, logFlowError, onErrorRef]
9245
9297
  );
@@ -9323,6 +9375,7 @@ function DepositFlow({
9323
9375
  ),
9324
9376
  fiatPaymentMethods: cashDisplay.kind === "list" ? cashDisplay.methods : void 0,
9325
9377
  fiatLoading: cashDisplay.kind === "loading",
9378
+ fiatNotice: bankOnrampUnavailable && swappedRefusesBank ? "Bank transfer isn't available in your region." : void 0,
9326
9379
  recommendedMethod: cashDisplay.kind === "list" ? cashDisplay.recommendedMethod : void 0,
9327
9380
  onSelectFiatMethod: cashDisplay.kind === "list" ? handleSelectDisplayedFiatMethod : void 0,
9328
9381
  onPrefetchFiatMethod: cashDisplay.kind === "list" ? handlePrefetchDisplayedFiatMethod : void 0,
@@ -9365,12 +9418,7 @@ function DepositFlow({
9365
9418
  errorMessage: activeEntry.message ?? void 0,
9366
9419
  onRetry: () => handleRetrySetup()
9367
9420
  }
9368
- ) : /* @__PURE__ */ jsx28(
9369
- DepositAddressSkeleton,
9370
- {
9371
- uiConfig
9372
- }
9373
- )),
9421
+ ) : /* @__PURE__ */ jsx28(DepositAddressSkeleton, { uiConfig })),
9374
9422
  effectiveStep.type === "deposit-address" && /* @__PURE__ */ jsx28(
9375
9423
  DepositAddressStep,
9376
9424
  {
@@ -9449,6 +9497,29 @@ function DepositFlow({
9449
9497
  ] });
9450
9498
  }
9451
9499
  if (isFiatOnrampMode) {
9500
+ const swappedStep = step.type === "fiat-onramp" ? /* @__PURE__ */ jsx28(
9501
+ FiatOnrampStep,
9502
+ {
9503
+ smartAccount: step.smartAccount,
9504
+ service,
9505
+ paymentMethod: step.paymentMethod,
9506
+ methodSelectionSource: step.methodSelectionSource,
9507
+ consumePrefetchedUrl: consumeSwappedWidgetUrlPrefetch,
9508
+ onSwappedComplete: handleSwappedComplete,
9509
+ onSwappedFailed: handleDepositFailed,
9510
+ onClose: () => onClose?.(
9511
+ openExternally ? "native_dismiss_request" : "header_button"
9512
+ ),
9513
+ onGoBack: handleProviderBack,
9514
+ onError: handleError,
9515
+ onAttemptConsumed: handleSwappedAttemptConsumed,
9516
+ onProviderHandoff: handleSwappedProviderHandoff,
9517
+ onRetry: handleSwappedRetry,
9518
+ onCancelled: () => analytics.outcome("cancelled"),
9519
+ onImmersiveChange: onSwappedImmersiveChange,
9520
+ openExternally
9521
+ }
9522
+ ) : null;
9452
9523
  return /* @__PURE__ */ jsxs23(
9453
9524
  "div",
9454
9525
  {
@@ -9463,29 +9534,21 @@ function DepositFlow({
9463
9534
  onRetry: activeEntry.status === "error" ? () => handleRetrySetup() : void 0
9464
9535
  }
9465
9536
  ),
9466
- step.type === "fiat-onramp" && /* @__PURE__ */ jsx28(
9467
- FiatOnrampStep,
9537
+ step.type === "fiat-onramp" && bankRowOffered && bankOnramp && step.paymentMethod === "bank-transfer" && /* @__PURE__ */ jsx28(Suspense2, { fallback: /* @__PURE__ */ jsx28(AccountPreparingSkeleton, {}), children: /* @__PURE__ */ jsx28(
9538
+ BankOnrampStep,
9468
9539
  {
9540
+ backendUrl,
9469
9541
  smartAccount: step.smartAccount,
9470
- service,
9471
- paymentMethod: step.paymentMethod,
9472
- methodSelectionSource: step.methodSelectionSource,
9473
- consumePrefetchedUrl: consumeSwappedWidgetUrlPrefetch,
9474
- onSwappedComplete: handleSwappedComplete,
9475
- onSwappedFailed: handleDepositFailed,
9476
- onClose: () => onClose?.(
9477
- openExternally ? "native_dismiss_request" : "header_button"
9478
- ),
9542
+ bankOnramp,
9543
+ onJourney: onBankJourney,
9479
9544
  onGoBack: handleProviderBack,
9480
9545
  onError: handleError,
9481
- onAttemptConsumed: handleSwappedAttemptConsumed,
9482
- onProviderHandoff: handleSwappedProviderHandoff,
9483
- onRetry: handleSwappedRetry,
9484
- onCancelled: () => analytics.outcome("cancelled"),
9485
- onImmersiveChange: onSwappedImmersiveChange,
9486
- openExternally
9487
- }
9488
- ),
9546
+ openExternally,
9547
+ onUnavailable: handleBankOnrampUnavailable
9548
+ },
9549
+ `${backendUrl}:${step.smartAccount}`
9550
+ ) }),
9551
+ step.type === "fiat-onramp" && (!bankRowOffered || step.paymentMethod !== "bank-transfer") && swappedStep,
9489
9552
  step.type === "processing" && /* @__PURE__ */ jsx28(
9490
9553
  ProcessingStep,
9491
9554
  {
@@ -9635,7 +9698,8 @@ function DepositFlow({
9635
9698
  uiConfig,
9636
9699
  targetChain,
9637
9700
  targetChainName: getChainName(targetChainId),
9638
- targetTokenSymbol: getTargetTokenSymbol(targetToken, targetChainId),
9701
+ targetTokenSymbol: targetSymbol,
9702
+ targetToken: { chain: targetChainId, address: targetToken },
9639
9703
  appBalanceUsd,
9640
9704
  onContinue: handleSolanaAmountContinue,
9641
9705
  debug
@@ -9933,11 +9997,115 @@ function DepositFlow({
9933
9997
  ] });
9934
9998
  }
9935
9999
 
10000
+ // src/components/history/useBankHistory.ts
10001
+ import { useCallback as useCallback8, useEffect as useEffect14, useRef as useRef10, useState as useState14 } from "react";
10002
+ function useBankHistory(source, open, panelOpen) {
10003
+ const [orders, setOrders] = useState14([]);
10004
+ const [unread, setUnread] = useState14(false);
10005
+ const [loading, setLoading] = useState14(false);
10006
+ const [error, setError] = useState14(null);
10007
+ const [cursor, setCursor] = useState14(null);
10008
+ const generation = useRef10(0);
10009
+ const busy = useRef10(false);
10010
+ const seen = useRef10(/* @__PURE__ */ new Map());
10011
+ const baselined = useRef10(false);
10012
+ const paged = useRef10(false);
10013
+ const panel = useRef10(panelOpen);
10014
+ panel.current = panelOpen;
10015
+ const load = useCallback8(
10016
+ async (next) => {
10017
+ if (!source || !open || busy.current || document.visibilityState === "hidden")
10018
+ return;
10019
+ const current = generation.current;
10020
+ busy.current = true;
10021
+ setLoading(true);
10022
+ try {
10023
+ const page = await source.listOrders({
10024
+ limit: 20,
10025
+ ...next ? { cursor: next } : {}
10026
+ });
10027
+ if (current !== generation.current) return;
10028
+ const bank = page.items.filter((order) => order.provider === "noah");
10029
+ let changed = false;
10030
+ for (const order of bank) {
10031
+ const fingerprint = JSON.stringify(order.stages);
10032
+ if (!next && seen.current.get(order.id) !== fingerprint)
10033
+ changed = true;
10034
+ seen.current.set(order.id, fingerprint);
10035
+ }
10036
+ if (baselined.current && changed && !panel.current) setUnread(true);
10037
+ if (!next) baselined.current = true;
10038
+ setOrders((previous) => {
10039
+ const merged = new Map(previous.map((order) => [order.id, order]));
10040
+ for (const order of bank) merged.set(order.id, order);
10041
+ return [...merged.values()].sort(
10042
+ (a, b) => b.createdAt.localeCompare(a.createdAt)
10043
+ );
10044
+ });
10045
+ if (next) paged.current = true;
10046
+ if (next || !paged.current) setCursor(page.nextCursor);
10047
+ setError(null);
10048
+ } catch {
10049
+ if (current === generation.current)
10050
+ setError("Bank transfer history is unavailable. Try again shortly.");
10051
+ } finally {
10052
+ if (current === generation.current) {
10053
+ busy.current = false;
10054
+ setLoading(false);
10055
+ }
10056
+ }
10057
+ },
10058
+ [source, open]
10059
+ );
10060
+ useEffect14(() => {
10061
+ generation.current += 1;
10062
+ busy.current = false;
10063
+ seen.current = /* @__PURE__ */ new Map();
10064
+ baselined.current = false;
10065
+ paged.current = false;
10066
+ setOrders([]);
10067
+ setUnread(false);
10068
+ setCursor(null);
10069
+ setError(null);
10070
+ setLoading(false);
10071
+ if (!open || !source) return;
10072
+ void load();
10073
+ const refresh = () => {
10074
+ void load();
10075
+ };
10076
+ const timer = setInterval(refresh, 3e4);
10077
+ window.addEventListener("focus", refresh);
10078
+ document.addEventListener("visibilitychange", refresh);
10079
+ return () => {
10080
+ generation.current += 1;
10081
+ clearInterval(timer);
10082
+ window.removeEventListener("focus", refresh);
10083
+ document.removeEventListener("visibilitychange", refresh);
10084
+ };
10085
+ }, [source, open, load]);
10086
+ useEffect14(() => {
10087
+ if (panelOpen) {
10088
+ setUnread(false);
10089
+ void load();
10090
+ }
10091
+ }, [panelOpen, load]);
10092
+ return {
10093
+ orders,
10094
+ unread,
10095
+ loading,
10096
+ error,
10097
+ hasMore: cursor !== null,
10098
+ loadMore: () => {
10099
+ if (cursor) void load(cursor);
10100
+ }
10101
+ };
10102
+ }
10103
+
9936
10104
  // src/DepositModal.tsx
9937
10105
  import { jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
9938
- var ReownDepositInner = lazy2(async () => {
10106
+ var ReownDepositInner = lazy3(async () => {
9939
10107
  await loadReownDependencies();
9940
- const module = await import("./DepositModalReown-XBNY6QCI.mjs");
10108
+ const module = await import("./DepositModalReown-3FGTPER6.mjs");
9941
10109
  return { default: module.DepositModalReown };
9942
10110
  });
9943
10111
  function buildDepositAnalyticsSessionProperties({
@@ -9954,6 +10122,7 @@ function buildDepositAnalyticsSessionProperties({
9954
10122
  sourceChain,
9955
10123
  sourceToken,
9956
10124
  defaultAmount,
10125
+ bankOnrampEnabled = false,
9957
10126
  walletIntegration,
9958
10127
  targetChain,
9959
10128
  targetToken
@@ -9966,7 +10135,7 @@ function buildDepositAnalyticsSessionProperties({
9966
10135
  enabledFundingMethods.push("wallet");
9967
10136
  }
9968
10137
  if (enableQrTransfer) enabledFundingMethods.push("transfer");
9969
- if (enableFiatOnramp && configuredFiatIdentifiers?.length !== 0) {
10138
+ if (bankOnrampEnabled || enableFiatOnramp && configuredFiatIdentifiers?.length !== 0) {
9970
10139
  enabledFundingMethods.push("fiat_onramp");
9971
10140
  }
9972
10141
  if (enableExchangeConnect) enabledFundingMethods.push("exchange_connect");
@@ -9999,7 +10168,7 @@ function DepositModal(props) {
9999
10168
  const needsReown = !!props.reownAppId;
10000
10169
  const hasWalletClientProp = hasSuppliedWalletClient(props);
10001
10170
  if (needsReown) {
10002
- return /* @__PURE__ */ jsx29(Suspense2, { fallback: null, children: /* @__PURE__ */ jsx29(
10171
+ return /* @__PURE__ */ jsx29(Suspense3, { fallback: null, children: /* @__PURE__ */ jsx29(
10003
10172
  ReownDepositInner,
10004
10173
  {
10005
10174
  ...props,
@@ -10038,6 +10207,7 @@ function DepositModalInner({
10038
10207
  assetMigrations,
10039
10208
  initialAssetMigration,
10040
10209
  enableFiatOnramp = false,
10210
+ bankOnramp,
10041
10211
  enableQrTransfer = true,
10042
10212
  enableGaslessDeposit = false,
10043
10213
  fiatMethods,
@@ -10064,24 +10234,41 @@ function DepositModalInner({
10064
10234
  signRecovery,
10065
10235
  debug
10066
10236
  }) {
10067
- const modalRef = useRef10(null);
10068
- const analyticsControllerRef = useRef10(null);
10069
- const analyticsSessionIdRef = useRef10(null);
10070
- const previousOpenRef = useRef10(isOpen);
10237
+ const modalRef = useRef11(null);
10238
+ const analyticsControllerRef = useRef11(null);
10239
+ const analyticsSessionIdRef = useRef11(null);
10240
+ const previousOpenRef = useRef11(isOpen);
10071
10241
  const onReadyRef = useLatestRef(onReady);
10072
10242
  const onUiStateRef = useLatestRef(onUiState);
10073
- const [currentScreen, setCurrentScreen] = useState14("connect");
10074
- const [swappedImmersive, setSwappedImmersive] = useState14(false);
10075
- const [submitting, setSubmitting] = useState14(false);
10076
- const [backHandler, setBackHandler] = useState14(
10243
+ const [currentScreen, setCurrentScreen] = useState15("connect");
10244
+ const bankScope = `${backendUrl}:${recipient}:${typeof targetChainProp === "string" ? targetChainProp : getChainId(targetChainProp)}:${targetToken}`;
10245
+ const [bankSession, setBankSession] = useState15(null);
10246
+ const [bankJourneyVisible, setBankJourneyVisible] = useState15(false);
10247
+ const onBankJourney = useCallback9((journey) => {
10248
+ setBankJourneyVisible(Boolean(journey));
10249
+ if (journey)
10250
+ setBankSession(
10251
+ journey.source ? { source: journey.source, scope: bankScope } : null
10252
+ );
10253
+ }, [bankScope]);
10254
+ const bankSource = bankSession?.scope === bankScope ? bankSession.source : null;
10255
+ useEffect15(() => {
10256
+ if (!isOpen) {
10257
+ setBankSession(null);
10258
+ setBankJourneyVisible(false);
10259
+ }
10260
+ }, [isOpen]);
10261
+ const [swappedImmersive, setSwappedImmersive] = useState15(false);
10262
+ const [submitting, setSubmitting] = useState15(false);
10263
+ const [backHandler, setBackHandler] = useState15(
10077
10264
  void 0
10078
10265
  );
10079
- const [processingSettled, setProcessingSettled] = useState14(false);
10080
- const historyButtonVisible = !payment && isHistoryEntryVisible({
10266
+ const [processingSettled, setProcessingSettled] = useState15(false);
10267
+ const historyButtonVisible = !payment && (bankJourneyVisible || isHistoryEntryVisible({
10081
10268
  screen: currentScreen,
10082
10269
  submitting,
10083
10270
  settled: processingSettled
10084
- });
10271
+ }));
10085
10272
  const targetChain = typeof targetChainProp === "string" ? targetChainProp : getChainId(targetChainProp);
10086
10273
  const sourceChain = sourceChainProp ? getChainId(sourceChainProp) : void 0;
10087
10274
  const rpcUrls = useStableRpcUrls(rpcUrlsProp);
@@ -10107,15 +10294,27 @@ function DepositModalInner({
10107
10294
  canRecover: Boolean(signRecovery),
10108
10295
  analytics: historyAnalytics
10109
10296
  });
10297
+ const bankOrders = useBankHistory(bankSource, isOpen && !payment, history.isPanelOpen);
10298
+ const bankHistory = bankJourneyVisible && !bankSource ? { ...bankOrders, loading: true } : bankOrders;
10299
+ const historyDepositsRef = useLatestRef(history.deposits);
10300
+ useEffect15(() => {
10301
+ const waitingForSettlement = bankHistory.orders.some((order) => {
10302
+ if (order.stages.delivery.status !== "completed") return false;
10303
+ const { depositId } = order.stages.delivery;
10304
+ const deposit = historyDepositsRef.current.find((item) => item.id === depositId);
10305
+ return !deposit || deposit.status === "pending" || deposit.status === "processing";
10306
+ });
10307
+ if (waitingForSettlement) history.markStale();
10308
+ }, [bankHistory.orders, history.markStale, historyDepositsRef]);
10110
10309
  const {
10111
10310
  markStale: markHistoryStale,
10112
10311
  invalidate: invalidateHistory,
10113
10312
  recoverySubmitting
10114
10313
  } = history;
10115
- const [clientSetup, setClientSetup] = useState14(
10314
+ const [clientSetup, setClientSetup] = useState15(
10116
10315
  null
10117
10316
  );
10118
- useEffect14(() => {
10317
+ useEffect15(() => {
10119
10318
  if (!isOpen) return;
10120
10319
  let active = true;
10121
10320
  service.getSetup().then((config) => {
@@ -10125,7 +10324,7 @@ function DepositModalInner({
10125
10324
  active = false;
10126
10325
  };
10127
10326
  }, [isOpen, service]);
10128
- useEffect14(() => {
10327
+ useEffect15(() => {
10129
10328
  if (debug && clientSetup) {
10130
10329
  console.debug("[deposit] client setup config (not shown yet)", clientSetup);
10131
10330
  }
@@ -10135,19 +10334,19 @@ function DepositModalInner({
10135
10334
  // eslint-disable-next-line react-hooks/exhaustive-deps
10136
10335
  []
10137
10336
  );
10138
- useEffect14(() => {
10337
+ useEffect15(() => {
10139
10338
  store.dispatch({ type: "target/changed", targetChain, targetToken });
10140
10339
  }, [store, targetChain, targetToken]);
10141
- useEffect14(() => {
10340
+ useEffect15(() => {
10142
10341
  if (!isOpen || !modalRef.current) return;
10143
10342
  return applyTheme(modalRef.current, theme);
10144
10343
  }, [isOpen, theme]);
10145
- useEffect14(() => {
10344
+ useEffect15(() => {
10146
10345
  if (isOpen) {
10147
10346
  onReadyRef.current?.();
10148
10347
  }
10149
10348
  }, [isOpen, onReadyRef]);
10150
- useEffect14(() => {
10349
+ useEffect15(() => {
10151
10350
  onUiStateRef.current?.({
10152
10351
  screen: currentScreen,
10153
10352
  back: backHandler,
@@ -10162,7 +10361,7 @@ function DepositModalInner({
10162
10361
  recoverySubmitting,
10163
10362
  onUiStateRef
10164
10363
  ]);
10165
- const handleStepChange = useCallback8(
10364
+ const handleStepChange = useCallback9(
10166
10365
  (onBack, screen) => {
10167
10366
  setBackHandler(() => onBack);
10168
10367
  if (screen) setCurrentScreen(screen);
@@ -10170,7 +10369,7 @@ function DepositModalInner({
10170
10369
  []
10171
10370
  );
10172
10371
  const onLifecycleRef = useLatestRef(onLifecycle);
10173
- const handleLifecycle = useCallback8(
10372
+ const handleLifecycle = useCallback9(
10174
10373
  (event) => {
10175
10374
  onLifecycleRef.current?.(event);
10176
10375
  if (event.type === "smart-account-changed" && !event.evm && !event.solana) {
@@ -10182,7 +10381,7 @@ function DepositModalInner({
10182
10381
  },
10183
10382
  [onLifecycleRef, markHistoryStale, invalidateHistory]
10184
10383
  );
10185
- const closeWithSource = useCallback8(
10384
+ const closeWithSource = useCallback9(
10186
10385
  (source) => {
10187
10386
  if (recoverySubmitting) return;
10188
10387
  const analytics = analyticsControllerRef.current;
@@ -10192,7 +10391,7 @@ function DepositModalInner({
10192
10391
  },
10193
10392
  [onClose, recoverySubmitting]
10194
10393
  );
10195
- const handleModalDismiss = useCallback8(
10394
+ const handleModalDismiss = useCallback9(
10196
10395
  (reason) => {
10197
10396
  closeWithSource(
10198
10397
  reason === "escape" ? "escape" : reason === "overlay" ? "overlay" : "header_button"
@@ -10200,7 +10399,7 @@ function DepositModalInner({
10200
10399
  },
10201
10400
  [closeWithSource]
10202
10401
  );
10203
- useEffect14(() => {
10402
+ useEffect15(() => {
10204
10403
  if (previousOpenRef.current && !isOpen) {
10205
10404
  const analytics = analyticsControllerRef.current;
10206
10405
  analytics?.abandon("modal_close");
@@ -10208,7 +10407,7 @@ function DepositModalInner({
10208
10407
  }
10209
10408
  previousOpenRef.current = isOpen;
10210
10409
  }, [isOpen]);
10211
- useEffect14(() => {
10410
+ useEffect15(() => {
10212
10411
  if (!isOpen) {
10213
10412
  setCurrentScreen("connect");
10214
10413
  setBackHandler(void 0);
@@ -10217,7 +10416,7 @@ function DepositModalInner({
10217
10416
  setProcessingSettled(false);
10218
10417
  }
10219
10418
  }, [isOpen]);
10220
- useEffect14(() => {
10419
+ useEffect15(() => {
10221
10420
  if (!isOpen) {
10222
10421
  store.dispatch({ type: "flow/reset" });
10223
10422
  }
@@ -10237,6 +10436,9 @@ function DepositModalInner({
10237
10436
  sourceChain: sourceChainProp,
10238
10437
  sourceToken,
10239
10438
  defaultAmount,
10439
+ bankOnrampEnabled: Boolean(
10440
+ bankOnramp && (fiatMethods === void 0 || fiatMethods["bank-transfer"] === true)
10441
+ ),
10240
10442
  walletIntegration,
10241
10443
  targetChain,
10242
10444
  targetToken
@@ -10245,7 +10447,7 @@ function DepositModalInner({
10245
10447
  const canGoBack = backHandler !== void 0;
10246
10448
  const hideHeaderChrome = swappedImmersive;
10247
10449
  const modalClassName = `rs-modal${hideHeaderChrome ? " rs-modal--swapped-iframe" : ""}`;
10248
- return /* @__PURE__ */ jsx29(RpcUrlsProvider, { value: rpcUrls, children: /* @__PURE__ */ jsx29(ChainCatalogProvider, { service, rpcUrls, children: /* @__PURE__ */ jsx29(DepositStoreProvider, { store, children: /* @__PURE__ */ jsx29(
10450
+ return /* @__PURE__ */ jsx29(RpcUrlsProvider, { value: rpcUrls, children: /* @__PURE__ */ jsx29(ChainCatalogProvider, { service, rpcUrls, children: /* @__PURE__ */ jsx29(AssetMetadataProvider, { service, children: /* @__PURE__ */ jsx29(DepositStoreProvider, { store, children: /* @__PURE__ */ jsx29(
10249
10451
  Modal,
10250
10452
  {
10251
10453
  isOpen,
@@ -10284,7 +10486,8 @@ function DepositModalInner({
10284
10486
  historyButtonVisible && /* @__PURE__ */ jsx29(
10285
10487
  HistoryEntryButton,
10286
10488
  {
10287
- badge: history.badge,
10489
+ badge: bankJourneyVisible ? null : history.badge,
10490
+ unread: bankHistory.unread,
10288
10491
  onClick: history.openPanel,
10289
10492
  disabled: !recipient
10290
10493
  }
@@ -10322,6 +10525,9 @@ function DepositModalInner({
10322
10525
  assetMigrations,
10323
10526
  initialAssetMigration,
10324
10527
  enableFiatOnramp,
10528
+ bankOnramp,
10529
+ onBankJourney,
10530
+ backendUrl,
10325
10531
  enableQrTransfer,
10326
10532
  enableGaslessDeposit,
10327
10533
  fiatMethods,
@@ -10350,6 +10556,8 @@ function DepositModalInner({
10350
10556
  HistoryOverlay,
10351
10557
  {
10352
10558
  controller: history,
10559
+ bankHistory,
10560
+ bankSupportUrl: bankOnramp?.supportUrl,
10353
10561
  backLabel: "Deposit",
10354
10562
  recipient,
10355
10563
  backendUrl,
@@ -10371,7 +10579,7 @@ function DepositModalInner({
10371
10579
  }
10372
10580
  )
10373
10581
  }
10374
- ) }) }) });
10582
+ ) }) }) }) });
10375
10583
  }
10376
10584
 
10377
10585
  export {