@rhinestone/deposit-modal 0.19.0 → 0.20.1

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 +154 -61
  2. package/dist/BankOnrampStep-3SNUX6V2.cjs +435 -0
  3. package/dist/BankOnrampStep-4D24HVHV.mjs +435 -0
  4. package/dist/{DepositModalReown-UITYXJ6W.cjs → DepositModalReown-7EHOJTFW.cjs} +21 -20
  5. package/dist/{DepositModalReown-XBNY6QCI.mjs → DepositModalReown-SYQ2SCHC.mjs} +6 -5
  6. package/dist/WithdrawModal-LLJLEYXZ.cjs +12 -0
  7. package/dist/WithdrawModal-LXDIT4UV.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-FTWKAJGN.mjs → chunk-2FOPO4N5.mjs} +1 -1
  13. package/dist/{chunk-EG4H7OMC.cjs → chunk-CIVFT5KR.cjs} +171 -130
  14. package/dist/{chunk-PYOC6K24.cjs → chunk-D3R3O4CY.cjs} +1 -1
  15. package/dist/chunk-E7IMWVMN.mjs +346 -0
  16. package/dist/chunk-EJDBIWNH.mjs +113 -0
  17. package/dist/chunk-FKJ6EJHH.cjs +346 -0
  18. package/dist/{chunk-LVCD6RHF.cjs → chunk-FVJKUTHF.cjs} +2 -2
  19. package/dist/{chunk-NITKDXHR.mjs → chunk-FW7ZMXQS.mjs} +849 -674
  20. package/dist/chunk-G264OM23.cjs +224 -0
  21. package/dist/chunk-IPHKBBUV.cjs +113 -0
  22. package/dist/{chunk-BIL4ENC3.mjs → chunk-IPKT3FU6.mjs} +73 -32
  23. package/dist/chunk-JPX4MEHV.mjs +19 -0
  24. package/dist/{chunk-HMUGY66O.cjs → chunk-KXSU24RU.cjs} +1569 -1019
  25. package/dist/{chunk-ISLVD5HQ.cjs → chunk-LVMNNMOZ.cjs} +10 -5
  26. package/dist/chunk-O5OW4S7L.cjs +19 -0
  27. package/dist/{chunk-5NWLS5BQ.mjs → chunk-OZPMRTW3.mjs} +1511 -961
  28. package/dist/{chunk-OCWSMLOP.cjs → chunk-PVFEZ3UG.cjs} +1164 -989
  29. package/dist/{chunk-ZGHVJ2XM.mjs → chunk-YQCRXJIL.mjs} +8 -3
  30. package/dist/chunk-YY4ZOAH5.mjs +224 -0
  31. package/dist/{chunk-X6N2XPTO.mjs → chunk-ZOJMB5TZ.mjs} +1 -1
  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-BOxa1DE-.d.ts → types-BEEMfNi2.d.cts} +24 -4
  64. package/dist/{types-BShYNpvO.d.cts → types-DQDUqzsZ.d.ts} +24 -4
  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,
@@ -74,22 +58,28 @@ import {
74
58
  getExchangeLogo,
75
59
  getExchangeLogoSrc,
76
60
  getPublicClient,
61
+ hasReached,
62
+ hostedOrderStateFromSwapped,
77
63
  isDepositEvent,
78
64
  isDepositPolicyRefusal,
79
65
  isDisplayStablecoinSymbol,
80
66
  isFailedEvent,
81
67
  isHistoryEntryVisible,
82
68
  isNativeAsset,
83
- isRecognizedToken,
69
+ isNativeSol,
84
70
  isSubmissionUncertain,
71
+ mergeHostedOrderState,
85
72
  portfolioToAssets,
86
73
  quoteFeeRow,
87
74
  readDedupedAccountSetupResult,
88
75
  resolveAppFeeBps,
76
+ resolveCuratedToken,
77
+ resolveSolanaToken,
89
78
  rpcUrlFor,
90
79
  runAccountSetupDeduped,
91
80
  tokenFormatter,
92
81
  txRefsMatch,
82
+ useAssetStore,
93
83
  useCatalogChain,
94
84
  useChainCatalog,
95
85
  useChainName,
@@ -100,38 +90,54 @@ import {
100
90
  useExplorerTxUrl,
101
91
  useHistoryPanel,
102
92
  useIsDepositChain,
103
- useLatestRef,
93
+ useIsRecognizedToken,
104
94
  useRestrictedListExclusion,
105
95
  useRpcUrls,
106
96
  useStableRpcUrls,
97
+ useTokenDisplay,
98
+ useTokenDisplays,
107
99
  warnRemovedProps
108
- } from "./chunk-5NWLS5BQ.mjs";
100
+ } from "./chunk-OZPMRTW3.mjs";
101
+ import {
102
+ AppleIcon,
103
+ BankIcon,
104
+ BodyHeader,
105
+ CardIcon,
106
+ CheckIcon,
107
+ ChevronDownIcon,
108
+ ChevronLeftIcon,
109
+ CloseIcon,
110
+ CopyIcon,
111
+ ExternalLinkIcon,
112
+ HandCoinsIcon,
113
+ InfoIcon,
114
+ MigrateAssetsIcon,
115
+ Spinner,
116
+ TransferCryptoIcon,
117
+ UnplugIcon,
118
+ WalletIcon,
119
+ useLatestRef
120
+ } from "./chunk-YY4ZOAH5.mjs";
109
121
  import {
110
122
  HYPERCORE_CHAIN_ID,
111
123
  HYPERCORE_MIN_DEPOSIT_USD,
112
124
  HYPERCORE_SPOT_CAIP2,
113
125
  NATIVE_TOKEN_ADDRESS,
114
126
  SOLANA_MAINNET_CAIP2,
115
- SOLANA_TOKENS,
116
127
  SUPPORTED_CHAIN_IDS,
117
128
  cdnIconUrl,
118
- findTokenDecimals,
119
129
  getChainBadge,
120
130
  getChainIcon,
121
131
  getChainId,
122
132
  getChainName,
123
- getNativeSymbol,
124
133
  getSupportedChainIds,
125
- getTargetTokenSymbol,
126
- getTargetTokenSymbolsForChain,
127
134
  isHyperCoreDestination,
128
- isNativeSol,
129
135
  isStablecoinSymbol,
130
136
  isVirtualDestination,
131
137
  parseEvmChainId,
132
138
  targetChainToChainId,
133
139
  toEvmCaip2
134
- } from "./chunk-EAGMY3QE.mjs";
140
+ } from "./chunk-E7IMWVMN.mjs";
135
141
 
136
142
  // src/core/reown-dependencies.ts
137
143
  var dependencies;
@@ -164,22 +170,23 @@ function getReownDependencies() {
164
170
  // src/DepositModal.tsx
165
171
  import {
166
172
  useMemo as useMemo9,
167
- useEffect as useEffect14,
168
- useRef as useRef10,
169
- useState as useState14,
173
+ useEffect as useEffect15,
174
+ useRef as useRef11,
175
+ useState as useState15,
170
176
  useCallback as useCallback8,
171
- lazy as lazy2,
172
- Suspense as Suspense2
177
+ lazy as lazy4,
178
+ Suspense as Suspense3
173
179
  } from "react";
174
180
 
175
181
  // src/DepositFlow.tsx
176
182
  import {
177
183
  useState as useState13,
178
- useCallback as useCallback7,
184
+ useCallback as useCallback6,
179
185
  useMemo as useMemo8,
180
186
  useEffect as useEffect13,
181
187
  useLayoutEffect as useLayoutEffect2,
182
- useRef as useRef9
188
+ useRef as useRef9,
189
+ Suspense as Suspense2
183
190
  } from "react";
184
191
 
185
192
  // src/components/steps/ConnectStep.tsx
@@ -508,10 +515,12 @@ function ConnectStep({
508
515
  transferCryptoErrorReason,
509
516
  fiatPaymentMethods,
510
517
  fiatLoading,
518
+ fiatNotice,
511
519
  onSelectFiatMethod,
512
520
  onPrefetchFiatMethod,
513
521
  recommendedMethod,
514
522
  onSelectFundFromExchange,
523
+ fundFromExchangeLoading,
515
524
  onRequestConnect,
516
525
  onConnect,
517
526
  onDisconnect,
@@ -592,7 +601,9 @@ function ConnectStep({
592
601
  title: "Connect exchange",
593
602
  subtitle: "Instant - No limit",
594
603
  meta: EXCHANGE_META,
595
- onClick: onSelectFundFromExchange
604
+ onClick: onSelectFundFromExchange,
605
+ disabled: fundFromExchangeLoading,
606
+ trailing: fundFromExchangeLoading ? SMALL_SPINNER : void 0
596
607
  },
597
608
  "connect-exchange"
598
609
  )
@@ -685,6 +696,7 @@ function ConnectStep({
685
696
  ) : void 0
686
697
  }
687
698
  ),
699
+ fiatNotice && (activeTab === "cash" || !hasCash) && /* @__PURE__ */ jsx5(Callout, { variant: "warning", children: fiatNotice }),
688
700
  /* @__PURE__ */ jsx5(
689
701
  "div",
690
702
  {
@@ -801,7 +813,7 @@ function AssetSelectStep({
801
813
  isDepositChain,
802
814
  catalog
803
815
  ]);
804
- const rows = useMemo(() => {
816
+ const filteredRows = useMemo(() => {
805
817
  return assets.filter((a) => {
806
818
  if (!isDepositChain(a.chainId)) return false;
807
819
  try {
@@ -827,6 +839,20 @@ function AssetSelectStep({
827
839
  return 0;
828
840
  });
829
841
  }, [assets, isDepositChain, isExcludedByRestrictedList]);
842
+ const displays = useTokenDisplays(
843
+ filteredRows.map((asset) => ({
844
+ chain: asset.chainId,
845
+ address: asset.token,
846
+ fallback: { symbol: asset.symbol, decimals: asset.decimals }
847
+ }))
848
+ );
849
+ const rows = useMemo(
850
+ () => filteredRows.map((asset, i) => {
851
+ const symbol = displays[i]?.symbol ?? asset.symbol;
852
+ return symbol === asset.symbol ? asset : { ...asset, symbol, name: symbol };
853
+ }),
854
+ [filteredRows, displays]
855
+ );
830
856
  useEffect2(() => {
831
857
  if (!defaultAssetId || selectedAssetId) return;
832
858
  if (rows.some((asset) => asset.id === defaultAssetId)) {
@@ -896,6 +922,7 @@ function AssetSelectStep({
896
922
  /* @__PURE__ */ jsx6("span", { className: "rs-asset-icon", children: /* @__PURE__ */ jsx6(
897
923
  TokenIcon,
898
924
  {
925
+ token: { chain: asset.chainId, address: asset.token },
899
926
  symbol: asset.symbol,
900
927
  fallback: asset.symbol.slice(0, 4)
901
928
  }
@@ -958,7 +985,7 @@ async function fetchNativeAssets(address, publicClient, existing, isDepositChain
958
985
  if (existingIds.has(id)) return [];
959
986
  try {
960
987
  const balance = await publicClient.getBalance({ address });
961
- const nativeSymbol = catalogChain?.nativeToken.symbol ?? getNativeSymbol(connectedChainId);
988
+ const nativeSymbol = catalogChain?.nativeToken.symbol ?? "Token";
962
989
  const nativeDecimals = catalogChain?.nativeToken.decimals ?? 18;
963
990
  return [
964
991
  {
@@ -1140,7 +1167,7 @@ function AmountStep({
1140
1167
  walletClient?.chain?.id && walletClient.chain.id !== asset.chainId
1141
1168
  );
1142
1169
  const targetChainId = targetChainToChainId(targetChain);
1143
- const targetSymbol = getTargetTokenSymbol(targetToken, targetChainId);
1170
+ const targetSymbol = useTokenDisplay(targetChainId, targetToken).symbol;
1144
1171
  const isSourceStablecoin = isStablecoinSymbol(asset.symbol);
1145
1172
  const derivedPriceUsd = useMemo2(() => {
1146
1173
  if (tokenPriceUsdOverride !== void 0 && tokenPriceUsdOverride > 0)
@@ -1457,7 +1484,13 @@ function AmountStep({
1457
1484
  " ",
1458
1485
  asset.symbol
1459
1486
  ] }),
1460
- /* @__PURE__ */ jsx8("span", { className: "rs-amount-detail-icon", children: /* @__PURE__ */ jsx8(TokenIcon, { symbol: asset.symbol }) })
1487
+ /* @__PURE__ */ jsx8("span", { className: "rs-amount-detail-icon", children: /* @__PURE__ */ jsx8(
1488
+ TokenIcon,
1489
+ {
1490
+ token: { chain: asset.chainId, address: asset.token },
1491
+ symbol: asset.symbol
1492
+ }
1493
+ ) })
1461
1494
  ] })
1462
1495
  ] }),
1463
1496
  /* @__PURE__ */ jsxs6("div", { className: "rs-amount-detail-row", children: [
@@ -1468,7 +1501,13 @@ function AmountStep({
1468
1501
  " ",
1469
1502
  targetSymbol
1470
1503
  ] }),
1471
- /* @__PURE__ */ jsx8("span", { className: "rs-amount-detail-icon", children: /* @__PURE__ */ jsx8(TokenIcon, { symbol: targetSymbol }) })
1504
+ /* @__PURE__ */ jsx8("span", { className: "rs-amount-detail-icon", children: /* @__PURE__ */ jsx8(
1505
+ TokenIcon,
1506
+ {
1507
+ token: { chain: targetChainId, address: targetToken },
1508
+ symbol: targetSymbol
1509
+ }
1510
+ ) })
1472
1511
  ] })
1473
1512
  ] }),
1474
1513
  balanceAfterUsd !== null && /* @__PURE__ */ jsxs6("div", { className: "rs-amount-detail-row", children: [
@@ -1517,8 +1556,10 @@ function ReviewDetails({
1517
1556
  estimatedTime,
1518
1557
  sendAmount,
1519
1558
  sendSymbol,
1559
+ sendToken,
1520
1560
  receiveDisplay,
1521
1561
  receiveSymbol,
1562
+ receiveToken,
1522
1563
  fee
1523
1564
  }) {
1524
1565
  return /* @__PURE__ */ jsxs7("div", { className: "rs-review-details", children: [
@@ -1548,14 +1589,14 @@ function ReviewDetails({
1548
1589
  " ",
1549
1590
  sendSymbol
1550
1591
  ] }),
1551
- /* @__PURE__ */ jsx9("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx9(TokenIcon, { symbol: sendSymbol }) })
1592
+ /* @__PURE__ */ jsx9("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx9(TokenIcon, { token: sendToken, symbol: sendSymbol }) })
1552
1593
  ] })
1553
1594
  ] }),
1554
1595
  /* @__PURE__ */ jsxs7("div", { className: "rs-review-detail-row", children: [
1555
1596
  /* @__PURE__ */ jsx9("span", { children: "Receive" }),
1556
1597
  /* @__PURE__ */ jsxs7("span", { className: "rs-review-detail-value", children: [
1557
1598
  /* @__PURE__ */ jsx9("span", { children: receiveDisplay }),
1558
- /* @__PURE__ */ jsx9("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx9(TokenIcon, { symbol: receiveSymbol }) })
1599
+ /* @__PURE__ */ jsx9("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx9(TokenIcon, { token: receiveToken, symbol: receiveSymbol }) })
1559
1600
  ] })
1560
1601
  ] }),
1561
1602
  /* @__PURE__ */ jsxs7("div", { className: "rs-review-detail-row", children: [
@@ -1785,7 +1826,9 @@ function ConfirmStep({
1785
1826
  ]);
1786
1827
  const quote = setupReady && quoteResult?.requestKey === quoteRequestKey ? quoteResult.quote : null;
1787
1828
  const targetChainId = targetChainToChainId(targetChain);
1788
- const targetSymbol = sameRoute ? asset.symbol : getTargetTokenSymbol(targetToken, targetChainId);
1829
+ const resolvedTargetSymbol = useTokenDisplay(targetChainId, targetToken).symbol;
1830
+ const targetSymbol = sameRoute ? asset.symbol : resolvedTargetSymbol;
1831
+ const sourceTrusted = useIsRecognizedToken(asset.chainId, asset.token);
1789
1832
  const sourceChainName = getChainName(asset.chainId);
1790
1833
  const targetChainName = getChainName(targetChainId);
1791
1834
  const sourceChainIcon = getChainIcon(asset.chainId);
@@ -1838,7 +1881,7 @@ function ConfirmStep({
1838
1881
  sourceSymbol: asset.symbol,
1839
1882
  targetSymbol,
1840
1883
  sourceAmountUsd,
1841
- sourceTrusted: isRecognizedToken(asset.token, asset.chainId),
1884
+ sourceTrusted,
1842
1885
  // The target is the curated deposit destination, so a stablecoin target
1843
1886
  // estimates at $1 when unquoted (DepositFlow skips fetching stablecoin
1844
1887
  // target prices). Not applied to the source — that can be a held token.
@@ -2143,8 +2186,10 @@ function ConfirmStep({
2143
2186
  estimatedTime: estimatedTimeDisplay,
2144
2187
  sendAmount: formattedSendAmount,
2145
2188
  sendSymbol: asset.symbol,
2189
+ sendToken: { chain: asset.chainId, address: asset.token },
2146
2190
  receiveDisplay,
2147
2191
  receiveSymbol: targetSymbol,
2192
+ receiveToken: sameRoute ? { chain: asset.chainId, address: asset.token } : { chain: targetChainId, address: targetToken },
2148
2193
  fee: { display: feeDisplay, struck: feesFullySponsored }
2149
2194
  }
2150
2195
  ),
@@ -2200,7 +2245,8 @@ function QrReviewStep({
2200
2245
  }) {
2201
2246
  const [quote, setQuote] = useState5({ state: "loading", value: null });
2202
2247
  const targetChainId = targetChainToChainId(targetChain);
2203
- const targetSymbol = getTargetTokenSymbol(targetToken, targetChainId);
2248
+ const targetSymbol = useTokenDisplay(targetChainId, targetToken).symbol;
2249
+ const sourceTrusted = useIsRecognizedToken(asset.chainId, asset.token);
2204
2250
  const boundsFor = useDepositBounds();
2205
2251
  useEffect5(() => {
2206
2252
  let cancelled = false;
@@ -2253,7 +2299,7 @@ function QrReviewStep({
2253
2299
  sourceSymbol: asset.symbol,
2254
2300
  targetSymbol,
2255
2301
  sourceAmountUsd: Number.isFinite(usdValue) && usdValue > 0 ? usdValue : void 0,
2256
- sourceTrusted: isRecognizedToken(asset.token, asset.chainId),
2302
+ sourceTrusted,
2257
2303
  prices: targetTokenPriceUsd !== null && targetTokenPriceUsd > 0 ? { [targetSymbol.toUpperCase()]: targetTokenPriceUsd } : isDisplayStablecoinSymbol(targetSymbol) ? { [targetSymbol.toUpperCase()]: 1 } : {}
2258
2304
  });
2259
2305
  return estimate ?? targetSymbol;
@@ -2275,8 +2321,10 @@ function QrReviewStep({
2275
2321
  estimatedTime,
2276
2322
  sendAmount: formattedSendAmount,
2277
2323
  sendSymbol: asset.symbol,
2324
+ sendToken: { chain: asset.chainId, address: asset.token },
2278
2325
  receiveDisplay,
2279
2326
  receiveSymbol: targetSymbol,
2327
+ receiveToken: { chain: targetChainId, address: targetToken },
2280
2328
  fee: { display: feeDisplay, struck }
2281
2329
  }
2282
2330
  ),
@@ -2311,8 +2359,7 @@ function DepositAddressSkeleton({
2311
2359
  }) {
2312
2360
  const evmChainIds = getSupportedChainIds();
2313
2361
  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";
2362
+ const defaultToken = "USDC";
2316
2363
  const chainName = getChainName(defaultChainId);
2317
2364
  const chainIcon = getChainIcon(defaultChainId);
2318
2365
  return /* @__PURE__ */ jsxs10("div", { className: "rs-screen", "aria-busy": "true", children: [
@@ -2351,10 +2398,10 @@ function DepositAddressSkeleton({
2351
2398
  ] }),
2352
2399
  /* @__PURE__ */ jsxs10("div", { className: "rs-deposit-address-dropdown-trigger", children: [
2353
2400
  /* @__PURE__ */ jsx12(
2354
- TokenIcon,
2401
+ "span",
2355
2402
  {
2356
- symbol: defaultToken,
2357
- className: "rs-deposit-address-dropdown-icon"
2403
+ className: "rs-token-icon rs-deposit-address-dropdown-icon",
2404
+ "data-loading": ""
2358
2405
  }
2359
2406
  ),
2360
2407
  /* @__PURE__ */ jsx12("span", { children: defaultToken }),
@@ -2786,18 +2833,8 @@ function asString(value) {
2786
2833
  return typeof value === "string" ? value : void 0;
2787
2834
  }
2788
2835
  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 {};
2836
+ const matched = token ? resolveSolanaToken(token) : void 0;
2837
+ return matched ? { sourceSymbol: matched.symbol, sourceDecimals: matched.decimals } : {};
2801
2838
  }
2802
2839
  function getDepositEventDetails(event) {
2803
2840
  if (!event?.type || !isRecord(event.data)) return {};
@@ -2855,10 +2892,11 @@ function selectionAsAsset(chainId, symbol, offer, catalogChain) {
2855
2892
  decimals
2856
2893
  };
2857
2894
  }
2858
- function TokenGlyph({ symbol }) {
2895
+ function TokenGlyph({ symbol, token }) {
2859
2896
  return /* @__PURE__ */ jsx14(
2860
2897
  TokenIcon,
2861
2898
  {
2899
+ token,
2862
2900
  symbol,
2863
2901
  className: "rs-deposit-address-dropdown-icon",
2864
2902
  fallback: /* @__PURE__ */ jsx14("span", { className: "rs-deposit-address-dropdown-icon rs-deposit-address-dropdown-icon--fallback", children: symbol.slice(0, 3) })
@@ -3005,7 +3043,22 @@ function DepositAddressStep({
3005
3043
  clearInterval(timer);
3006
3044
  };
3007
3045
  }, [payment, sourceChainId, sourceTokenIdentity, smartAccount, service]);
3008
- const paymentDecimals = typeof sourceChainId === "number" && sourceTokenIdentity ? findTokenDecimals(sourceTokenIdentity, sourceChainId) : void 0;
3046
+ const tokenRefFor = (symbol) => {
3047
+ const address = resolveSourceTokenIdentity({
3048
+ chain: sourceChainId,
3049
+ symbol,
3050
+ shortlist,
3051
+ catalogTokens: offer.restricted ? void 0 : catalogFor(sourceChainId)?.supportedTokens
3052
+ });
3053
+ return address ? { chain: sourceChainId, address } : void 0;
3054
+ };
3055
+ const assetStore = useAssetStore();
3056
+ const assetStoreRef = useRef5(assetStore);
3057
+ assetStoreRef.current = assetStore;
3058
+ const paymentDecimals = useTokenDisplay(
3059
+ typeof sourceChainId === "number" ? sourceChainId : void 0,
3060
+ sourceTokenIdentity
3061
+ ).decimals;
3009
3062
  const paymentAmountUnits = payment && paymentUnits !== "loading" && paymentUnits !== "unavailable" ? paymentUnits : null;
3010
3063
  const paymentDisplay = paymentAmountUnits !== null && paymentDecimals !== void 0 ? formatUnits3(BigInt(paymentAmountUnits), paymentDecimals) : null;
3011
3064
  const qrValue = paymentAmountUnits !== null && typeof sourceChainId === "number" && sourceTokenIdentity ? paymentRequestUri({
@@ -3151,10 +3204,10 @@ function DepositAddressStep({
3151
3204
  baselineTxHashRef.current = eventTxHash;
3152
3205
  isTrackingRef.current = true;
3153
3206
  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);
3207
+ const knownChain = chainId === "unknown" ? void 0 : chainId;
3208
+ const sourceDecimals = details.sourceDecimals ?? (token && knownChain !== void 0 ? resolveCuratedToken(token, knownChain)?.decimals ?? (knownChain === "hypercore" ? void 0 : assetStoreRef.current?.peekMeta(
3209
+ assetIdFor(knownChain, token) ?? ""
3210
+ )?.decimals) : void 0);
3158
3211
  const directTransfer = typeof chainId === "number" && isEvmToken && isSameRoute(
3159
3212
  chainId,
3160
3213
  token,
@@ -3314,7 +3367,13 @@ function DepositAddressStep({
3314
3367
  setChainDropdownOpen(false);
3315
3368
  },
3316
3369
  children: [
3317
- /* @__PURE__ */ jsx14(TokenGlyph, { symbol: sourceTokenSymbol }),
3370
+ /* @__PURE__ */ jsx14(
3371
+ TokenGlyph,
3372
+ {
3373
+ symbol: sourceTokenSymbol,
3374
+ token: tokenRefFor(sourceTokenSymbol)
3375
+ }
3376
+ ),
3318
3377
  /* @__PURE__ */ jsx14("span", { children: sourceTokenSymbol }),
3319
3378
  /* @__PURE__ */ jsx14(ChevronDownIcon, { className: "rs-deposit-address-dropdown-chevron" })
3320
3379
  ]
@@ -3330,7 +3389,7 @@ function DepositAddressStep({
3330
3389
  setTokenDropdownOpen(false);
3331
3390
  },
3332
3391
  children: [
3333
- /* @__PURE__ */ jsx14(TokenGlyph, { symbol }),
3392
+ /* @__PURE__ */ jsx14(TokenGlyph, { symbol, token: tokenRefFor(symbol) }),
3334
3393
  /* @__PURE__ */ jsx14("span", { children: symbol })
3335
3394
  ]
3336
3395
  },
@@ -3422,8 +3481,8 @@ function DepositAddressStep({
3422
3481
  }
3423
3482
  DepositAddressStep.displayName = "DepositAddressStep";
3424
3483
 
3425
- // src/components/steps/FiatOnrampStep.tsx
3426
- import { useCallback as useCallback3 } from "react";
3484
+ // src/components/steps/RampOrderStep.tsx
3485
+ import { lazy as lazy2, useCallback as useCallback3 } from "react";
3427
3486
 
3428
3487
  // src/core/swapped.ts
3429
3488
  var SWAPPED_ORIGINS = [
@@ -3495,7 +3554,7 @@ function SwappedOrderTracker({
3495
3554
  onRetry
3496
3555
  }) {
3497
3556
  const formattedAmount = formatTrackerAmount(amount);
3498
- const title = terminal ? terminal.kind === "cancelled" ? "Order cancelled" : "Deposit failed" : formattedAmount ? `Depositing ${formattedAmount} ${currency}` : `Depositing ${currency}`;
3557
+ const title = terminal ? terminal.title ?? (terminal.kind === "cancelled" ? "Order cancelled" : "Deposit failed") : formattedAmount ? `Depositing ${formattedAmount} ${currency}` : `Depositing ${currency}`;
3499
3558
  const labels = [
3500
3559
  STEP_LABELS[0],
3501
3560
  `${currency} received`,
@@ -3573,16 +3632,10 @@ var DEPOSIT_POLL_FAST_INTERVAL_MS = 500;
3573
3632
  var IFRAME_LOAD_TIMEOUT_MS = 15e3;
3574
3633
  var SWAPPED_SUCCESS_HANDOFF_DELAY_MS = 1400;
3575
3634
  var SWAPPED_IFRAME_ORIGINS = new Set(SWAPPED_ORIGINS);
3576
- var SWAPPED_TERMINAL_STATUSES = /* @__PURE__ */ new Set([
3577
- "order_completed",
3578
- "order_broadcasted"
3579
- ]);
3580
- var SWAPPED_STATUS_VALUES = /* @__PURE__ */ new Set([
3581
- "payment_pending",
3582
- "order_completed",
3583
- "order_broadcasted",
3584
- "order_cancelled"
3585
- ]);
3635
+ var OUTCOMES = {
3636
+ failed: { title: "Order failed", message: "Any charge will be refunded." },
3637
+ refunded: { title: "Order refunded", message: "Your payment was returned." }
3638
+ };
3586
3639
  var SWAPPED_GO_BACK_KEY = "SWAPPED_GO_BACK";
3587
3640
  var OPEN_FAILED_MESSAGE = "We could not open your browser.";
3588
3641
  var OPEN_FAILED_CODE = "SWAPPED_BROWSER_UNAVAILABLE";
@@ -3611,6 +3664,10 @@ function isSwappedGoBackMessage(raw) {
3611
3664
  const obj = data;
3612
3665
  return obj.key === SWAPPED_GO_BACK_KEY || obj.type === SWAPPED_GO_BACK_KEY;
3613
3666
  }
3667
+ function assetSymbol(currencyCode) {
3668
+ const separator = currencyCode?.indexOf("_") ?? -1;
3669
+ return separator > 0 ? currencyCode.slice(0, separator) : currencyCode;
3670
+ }
3614
3671
  function parseSwappedIframeMessage(raw) {
3615
3672
  let data = raw;
3616
3673
  if (typeof data === "string") {
@@ -3624,17 +3681,20 @@ function parseSwappedIframeMessage(raw) {
3624
3681
  const obj = data;
3625
3682
  const inner = obj.data && typeof obj.data === "object" ? obj.data : obj;
3626
3683
  const rawStatus = inner.order_status ?? inner.status ?? obj.status;
3627
- if (typeof rawStatus !== "string" || !SWAPPED_STATUS_VALUES.has(rawStatus)) {
3628
- return null;
3629
- }
3630
3684
  const asString2 = (v) => typeof v === "string" && v.length > 0 ? v : void 0;
3685
+ const state = typeof rawStatus === "string" ? hostedOrderStateFromSwapped(
3686
+ rawStatus,
3687
+ asString2(inner.transaction_id) ?? asString2(obj.transactionId)
3688
+ ) : null;
3689
+ if (!state) return null;
3631
3690
  return {
3632
- status: rawStatus,
3691
+ state,
3633
3692
  orderId: asString2(inner.order_id) ?? asString2(obj.orderId),
3634
3693
  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),
3636
- orderCryptoAmount: asString2(inner.order_crypto_amount) ?? asString2(obj.orderCryptoAmount),
3637
- transactionId: asString2(inner.transaction_id) ?? asString2(obj.transactionId)
3694
+ orderCrypto: assetSymbol(
3695
+ asString2(inner.order_crypto) ?? asString2(obj.orderCrypto)
3696
+ ),
3697
+ orderCryptoAmount: asString2(inner.order_crypto_amount) ?? asString2(obj.orderCryptoAmount)
3638
3698
  };
3639
3699
  }
3640
3700
  function SwappedProviderStep({
@@ -3645,7 +3705,7 @@ function SwappedProviderStep({
3645
3705
  iframeTitle,
3646
3706
  loadErrorCode,
3647
3707
  loadErrorFallback,
3648
- bannerForStatus,
3708
+ cancelledMessage,
3649
3709
  onSwappedComplete,
3650
3710
  onSwappedFailed,
3651
3711
  onClose,
@@ -3678,6 +3738,8 @@ function SwappedProviderStep({
3678
3738
  const expectedExternalCustomerIdRef = useRef6(null);
3679
3739
  const baselineDepositTxHashRef = useRef6(void 0);
3680
3740
  const currentDepositTxHashRef = useRef6(null);
3741
+ const deliveryTxHashRef = useRef6(null);
3742
+ deliveryTxHashRef.current = orderState?.deliveryTxHash ?? null;
3681
3743
  const fastDepositPollEnabledRef = useRef6(false);
3682
3744
  const rescheduleDepositPollRef = useRef6(
3683
3745
  null
@@ -3733,8 +3795,7 @@ function SwappedProviderStep({
3733
3795
  setWidgetUrl(res.url);
3734
3796
  expectedExternalCustomerIdRef.current = res.externalCustomerId;
3735
3797
  onAttemptConsumed?.(res.externalCustomerId);
3736
- const sep = res.externalCustomerId.indexOf(":");
3737
- expectedOrderUuidRef.current = sep >= 0 ? res.externalCustomerId.slice(sep + 1) : null;
3798
+ expectedOrderUuidRef.current = res.orderId;
3738
3799
  }).catch((err) => {
3739
3800
  if (cancelled) return;
3740
3801
  const message = err instanceof Error ? err.message : loadErrorFallback;
@@ -3797,11 +3858,15 @@ function SwappedProviderStep({
3797
3858
  async function poll() {
3798
3859
  if (cancelled) return;
3799
3860
  try {
3800
- const res = await service.fetchSwappedOrderStatus(smartAccount);
3861
+ const orderId = expectedOrderUuidRef.current;
3862
+ const res = orderId ? await service.fetchSwappedOrder(orderId) : null;
3801
3863
  if (cancelled) return;
3802
- const isCurrentOrder = res !== null && expectedOrderUuidRef.current !== null && res.orderId === expectedOrderUuidRef.current;
3864
+ const isCurrentOrder = res !== null && res.orderId === expectedOrderUuidRef.current;
3803
3865
  if (isCurrentOrder) {
3804
- setOrderState(res);
3866
+ setOrderState((prev) => ({
3867
+ ...res,
3868
+ ...mergeHostedOrderState(prev, res)
3869
+ }));
3805
3870
  }
3806
3871
  } catch {
3807
3872
  }
@@ -3838,15 +3903,29 @@ function SwappedProviderStep({
3838
3903
  async function pollDeposit() {
3839
3904
  if (cancelled) return;
3840
3905
  try {
3841
- const status = await service.fetchLatestStatus(smartAccount);
3842
- if (cancelled) return;
3843
- const event = status.lastEvent;
3844
- const eventTxHash = isDepositEvent(event) ? getEventTxHash(event) ?? null : null;
3845
- if (baselineDepositTxHashRef.current === void 0) {
3846
- baselineDepositTxHashRef.current = eventTxHash;
3847
- } else if (eventTxHash && (!baselineDepositTxHashRef.current || !txRefsMatch(eventTxHash, baselineDepositTxHashRef.current))) {
3848
- currentDepositTxHashRef.current = eventTxHash;
3849
- setLatestEvent(event ?? null);
3906
+ const deliveryTxHash = deliveryTxHashRef.current;
3907
+ if (deliveryTxHash) {
3908
+ const { lastEvent } = await service.fetchStatus(
3909
+ smartAccount,
3910
+ deliveryTxHash
3911
+ );
3912
+ if (cancelled) return;
3913
+ const txHash = isDepositEvent(lastEvent) ? getEventTxHash(lastEvent) : void 0;
3914
+ if (lastEvent && txHash && txRefsMatch(txHash, deliveryTxHash)) {
3915
+ currentDepositTxHashRef.current = txHash;
3916
+ setLatestEvent(lastEvent);
3917
+ }
3918
+ } else {
3919
+ const status = await service.fetchLatestStatus(smartAccount);
3920
+ if (cancelled) return;
3921
+ const event = status.lastEvent;
3922
+ const eventTxHash = isDepositEvent(event) ? getEventTxHash(event) ?? null : null;
3923
+ if (baselineDepositTxHashRef.current === void 0) {
3924
+ baselineDepositTxHashRef.current = eventTxHash;
3925
+ } else if (eventTxHash && (!baselineDepositTxHashRef.current || !txRefsMatch(eventTxHash, baselineDepositTxHashRef.current))) {
3926
+ currentDepositTxHashRef.current = eventTxHash;
3927
+ setLatestEvent(event ?? null);
3928
+ }
3850
3929
  }
3851
3930
  } catch {
3852
3931
  }
@@ -3869,8 +3948,7 @@ function SwappedProviderStep({
3869
3948
  }, [service, smartAccount]);
3870
3949
  useEffect8(() => {
3871
3950
  if (fastDepositPollEnabledRef.current) return;
3872
- const status = orderState?.status;
3873
- if (!status || !SWAPPED_TERMINAL_STATUSES.has(status)) return;
3951
+ if (!hasReached(orderState, "paid")) return;
3874
3952
  fastDepositPollEnabledRef.current = true;
3875
3953
  rescheduleDepositPollRef.current?.(DEPOSIT_POLL_FAST_INITIAL_DELAY_MS);
3876
3954
  }, [orderState]);
@@ -3894,10 +3972,9 @@ function SwappedProviderStep({
3894
3972
  // Normalise to the uuid the backend poll also keys on, so orderState
3895
3973
  // is consistent regardless of which path set it.
3896
3974
  orderId: expectedOrderUuidRef.current ?? prev?.orderId ?? ext,
3897
- status: parsed.status,
3975
+ ...mergeHostedOrderState(prev, parsed.state),
3898
3976
  orderCrypto: parsed.orderCrypto ?? prev?.orderCrypto ?? null,
3899
3977
  orderCryptoAmount: parsed.orderCryptoAmount ?? prev?.orderCryptoAmount ?? null,
3900
- transactionId: parsed.transactionId ?? prev?.transactionId ?? null,
3901
3978
  receivedAt: (/* @__PURE__ */ new Date()).toISOString(),
3902
3979
  paidAmountUsd: prev?.paidAmountUsd ?? null,
3903
3980
  paidAmountEur: prev?.paidAmountEur ?? null,
@@ -3909,13 +3986,13 @@ function SwappedProviderStep({
3909
3986
  return () => window.removeEventListener("message", onMessage);
3910
3987
  }, [openExternally]);
3911
3988
  useEffect8(() => {
3912
- const swappedProvesLive = orderState !== null && !(variant === "fiat" && orderState.status === "payment_pending");
3989
+ const swappedProvesLive = orderState !== null && (variant !== "fiat" || hasReached(orderState, "paying") || orderState.outcome !== null);
3913
3990
  if (phase === "provider" && (swappedProvesLive || latestEvent !== null)) {
3914
3991
  setPhase("tracker");
3915
3992
  }
3916
3993
  }, [phase, orderState, latestEvent, variant]);
3917
3994
  const stepStates = useMemo4(
3918
- () => deriveStepStates(orderState?.status ?? null, latestEvent),
3995
+ () => deriveStepStates(orderState, latestEvent),
3919
3996
  [orderState, latestEvent]
3920
3997
  );
3921
3998
  const terminalState = useMemo4(() => {
@@ -3925,15 +4002,15 @@ function SwappedProviderStep({
3925
4002
  message: failureMessageForEvent(latestEvent ?? void 0)
3926
4003
  };
3927
4004
  }
3928
- if (orderState?.status === "order_cancelled") {
3929
- const banner = bannerForStatus("order_cancelled", {});
3930
- return { kind: "cancelled", message: banner.detail ?? banner.title };
4005
+ const outcome = orderState?.outcome;
4006
+ if (outcome) {
4007
+ return outcome === "cancelled" ? { kind: "cancelled", message: cancelledMessage } : { kind: "cancelled", ...OUTCOMES[outcome] };
3931
4008
  }
3932
4009
  return null;
3933
- }, [latestEvent, orderState, bannerForStatus]);
4010
+ }, [latestEvent, orderState, cancelledMessage]);
3934
4011
  useEffect8(() => {
3935
- if (orderState?.status === "order_cancelled") onCancelled?.();
3936
- }, [onCancelled, orderState?.status]);
4012
+ if (orderState?.outcome === "cancelled") onCancelled?.();
4013
+ }, [onCancelled, orderState?.outcome]);
3937
4014
  useEffect8(() => {
3938
4015
  if (completeFiredRef.current || failedFiredRef.current) return;
3939
4016
  const t = latestEvent?.type;
@@ -4083,15 +4160,14 @@ function SwappedProviderStep({
4083
4160
  loadError && /* @__PURE__ */ jsx17(PoweredBy, {})
4084
4161
  ] });
4085
4162
  }
4086
- function deriveStepStates(swappedStatus, latestEvent) {
4163
+ function deriveStepStates(order, latestEvent) {
4087
4164
  if (isFailedEvent(latestEvent ?? void 0)) {
4088
4165
  return ["complete", "complete", "failed", "pending"];
4089
4166
  }
4090
- if (swappedStatus === "order_cancelled") {
4167
+ if (order?.outcome) {
4091
4168
  return ["failed", "pending", "pending", "pending"];
4092
4169
  }
4093
- const step1Complete = swappedStatus === "order_completed" || swappedStatus === "order_broadcasted";
4094
- const step2Complete = latestEvent !== null || swappedStatus === "order_broadcasted";
4170
+ const step2Complete = latestEvent !== null || hasReached(order, "sent");
4095
4171
  const step3Complete = latestEvent?.type === "bridge-complete";
4096
4172
  if (step3Complete) {
4097
4173
  return ["complete", "complete", "complete", "complete"];
@@ -4099,65 +4175,70 @@ function deriveStepStates(swappedStatus, latestEvent) {
4099
4175
  if (step2Complete) {
4100
4176
  return ["complete", "complete", "active", "pending"];
4101
4177
  }
4102
- if (step1Complete) {
4178
+ if (hasReached(order, "paid")) {
4103
4179
  return ["complete", "active", "pending", "pending"];
4104
4180
  }
4105
4181
  return ["active", "pending", "pending", "pending"];
4106
4182
  }
4107
4183
  SwappedProviderStep.displayName = "SwappedProviderStep";
4108
4184
 
4109
- // src/components/steps/FiatOnrampStep.tsx
4185
+ // src/components/steps/RampOrderStep.tsx
4110
4186
  import { jsx as jsx18 } from "react/jsx-runtime";
4111
- function fiatBannerForStatus(status, context) {
4112
- if (context.currencyMismatch) {
4113
- return {
4114
- level: "warning",
4115
- title: "Currency mismatch",
4116
- detail: "Funds may not bridge automatically. Contact support if your balance does not arrive."
4117
- };
4187
+ var BankOnrampStep = lazy2(async () => {
4188
+ const module = await import("./BankOnrampStep-4D24HVHV.mjs");
4189
+ return { default: module.BankOnrampStep };
4190
+ });
4191
+ var HOSTED = {
4192
+ fiat: {
4193
+ iframeTitle: "Buy crypto with Swapped",
4194
+ loadErrorCode: "SWAPPED_URL_FAILED",
4195
+ loadErrorFallback: "Failed to load on-ramp",
4196
+ cancelledMessage: "If you were charged, Swapped will refund within 5 business days."
4197
+ },
4198
+ exchange: {
4199
+ iframeTitle: "Fund from exchange via Swapped",
4200
+ loadErrorCode: "SWAPPED_CONNECT_URL_FAILED",
4201
+ loadErrorFallback: "Failed to load Connect",
4202
+ cancelledMessage: "If your exchange already debited the funds, Swapped will refund within 5 business days."
4118
4203
  }
4119
- switch (status) {
4120
- case "payment_pending":
4121
- return { level: "info", title: "Verifying payment\u2026" };
4122
- case "order_completed":
4123
- return { level: "success", title: "Payment received \u2014 sending crypto" };
4124
- case "order_broadcasted":
4125
- return {
4126
- level: "success",
4127
- title: "Crypto sent \u2014 confirming on-chain"
4128
- };
4129
- case "order_cancelled":
4130
- return {
4131
- level: "warning",
4132
- title: "Order cancelled",
4133
- detail: "If you were charged, Swapped will refund within 5 business days."
4134
- };
4204
+ };
4205
+ function RampOrderStep(props) {
4206
+ const { order, smartAccount } = props;
4207
+ if (order.flow === "funding_account") {
4208
+ return /* @__PURE__ */ jsx18(
4209
+ BankOnrampStep,
4210
+ {
4211
+ backendUrl: order.backendUrl,
4212
+ smartAccount,
4213
+ bankOnramp: order.bankOnramp,
4214
+ onJourney: order.onJourney,
4215
+ onGoBack: props.onGoBack,
4216
+ onError: props.onError,
4217
+ openExternally: props.openExternally,
4218
+ onUnavailable: order.onUnavailable
4219
+ },
4220
+ `${order.backendUrl}:${smartAccount}`
4221
+ );
4135
4222
  }
4223
+ return /* @__PURE__ */ jsx18(HostedOrder, { ...props, order });
4136
4224
  }
4137
- function FiatOnrampStep({
4225
+ function HostedOrder({
4226
+ order,
4138
4227
  smartAccount,
4139
4228
  service,
4140
- paymentMethod,
4141
- methodSelectionSource,
4142
- consumePrefetchedUrl,
4143
- onSwappedComplete,
4144
- onSwappedFailed,
4145
- onClose,
4146
- onGoBack,
4147
- onError,
4148
- onAttemptConsumed,
4149
- onProviderHandoff,
4150
- onRetry,
4151
- onCancelled,
4152
- onImmersiveChange,
4153
- openExternally
4229
+ ...callbacks
4154
4230
  }) {
4231
+ const method = order.kind === "fiat" ? order.method : void 0;
4232
+ const source = order.kind === "fiat" ? order.methodSelectionSource : void 0;
4233
+ const consumePrefetched = order.kind === "fiat" ? order.consumePrefetchedUrl : void 0;
4234
+ const connection = order.kind === "exchange" ? order.connection : void 0;
4235
+ const loadPrepared = order.kind === "exchange" ? order.loadPreparedUrl : void 0;
4155
4236
  const loadUrl = useCallback3(async () => {
4156
- const prefetched = consumePrefetchedUrl?.(
4157
- smartAccount,
4158
- paymentMethod,
4159
- methodSelectionSource
4160
- );
4237
+ if (connection !== void 0) {
4238
+ if (loadPrepared) return loadPrepared();
4239
+ return service.getSwappedConnectUrl({ smartAccount, connection });
4240
+ }
4241
+ const prefetched = consumePrefetched?.(smartAccount, method, source);
4161
4242
  if (prefetched) {
4162
4243
  try {
4163
4244
  const cached = await prefetched;
@@ -4167,136 +4248,41 @@ function FiatOnrampStep({
4167
4248
  }
4168
4249
  return service.getSwappedWidgetUrl({
4169
4250
  smartAccount,
4170
- method: paymentMethod,
4171
- methodSelectionSource
4251
+ method,
4252
+ methodSelectionSource: source
4172
4253
  });
4173
4254
  }, [
4174
4255
  service,
4175
4256
  smartAccount,
4176
- paymentMethod,
4177
- methodSelectionSource,
4178
- consumePrefetchedUrl
4257
+ method,
4258
+ source,
4259
+ consumePrefetched,
4260
+ connection,
4261
+ loadPrepared
4179
4262
  ]);
4180
4263
  return /* @__PURE__ */ jsx18(
4181
4264
  SwappedProviderStep,
4182
4265
  {
4183
4266
  smartAccount,
4184
4267
  service,
4185
- variant: "fiat",
4268
+ variant: order.kind === "fiat" ? "fiat" : "connect",
4186
4269
  loadUrl,
4187
- iframeTitle: "Buy crypto with Swapped",
4188
- loadErrorCode: "SWAPPED_URL_FAILED",
4189
- loadErrorFallback: "Failed to load on-ramp",
4190
- bannerForStatus: fiatBannerForStatus,
4191
- onSwappedComplete,
4192
- onSwappedFailed,
4193
- onClose,
4194
- onGoBack,
4195
- onError,
4196
- onAttemptConsumed,
4197
- onProviderHandoff,
4198
- onRetry,
4199
- onCancelled,
4200
- onImmersiveChange,
4201
- openExternally
4270
+ ...HOSTED[order.kind],
4271
+ ...callbacks
4202
4272
  }
4203
4273
  );
4204
4274
  }
4205
- FiatOnrampStep.displayName = "FiatOnrampStep";
4206
-
4207
- // src/components/steps/ExchangeConnectStep.tsx
4208
- import { useCallback as useCallback4 } from "react";
4209
- import { jsx as jsx19 } from "react/jsx-runtime";
4210
- function connectBannerForStatus(status, context) {
4211
- if (context.currencyMismatch) {
4212
- return {
4213
- level: "warning",
4214
- title: "Currency mismatch",
4215
- detail: "Funds may not bridge automatically. Contact support if your balance does not arrive."
4216
- };
4217
- }
4218
- switch (status) {
4219
- case "payment_pending":
4220
- return { level: "info", title: "Waiting for exchange transfer\u2026" };
4221
- case "order_completed":
4222
- return {
4223
- level: "success",
4224
- title: "Exchange transfer received \u2014 sending crypto"
4225
- };
4226
- case "order_broadcasted":
4227
- return {
4228
- level: "success",
4229
- title: "Crypto sent \u2014 confirming on-chain"
4230
- };
4231
- case "order_cancelled":
4232
- return {
4233
- level: "warning",
4234
- title: "Order cancelled",
4235
- detail: "If your exchange already debited the funds, Swapped will refund within 5 business days."
4236
- };
4237
- }
4238
- }
4239
- function ExchangeConnectStep({
4240
- smartAccount,
4241
- service,
4242
- connection,
4243
- loadUrl: loadPreparedUrl,
4244
- onSwappedComplete,
4245
- onSwappedFailed,
4246
- onClose,
4247
- onGoBack,
4248
- onError,
4249
- onAttemptConsumed,
4250
- onProviderHandoff,
4251
- onRetry,
4252
- onCancelled,
4253
- onImmersiveChange,
4254
- openExternally
4255
- }) {
4256
- const loadUrl = useCallback4(async () => {
4257
- if (loadPreparedUrl) return loadPreparedUrl();
4258
- const res = await service.getSwappedConnectUrl({
4259
- smartAccount,
4260
- connection
4261
- });
4262
- return res;
4263
- }, [loadPreparedUrl, service, smartAccount, connection]);
4264
- return /* @__PURE__ */ jsx19(
4265
- SwappedProviderStep,
4266
- {
4267
- smartAccount,
4268
- service,
4269
- variant: "connect",
4270
- loadUrl,
4271
- iframeTitle: "Fund from exchange via Swapped",
4272
- loadErrorCode: "SWAPPED_CONNECT_URL_FAILED",
4273
- loadErrorFallback: "Failed to load Connect",
4274
- bannerForStatus: connectBannerForStatus,
4275
- onSwappedComplete,
4276
- onSwappedFailed,
4277
- onClose,
4278
- onGoBack,
4279
- onError,
4280
- onAttemptConsumed,
4281
- onProviderHandoff,
4282
- onRetry,
4283
- onCancelled,
4284
- onImmersiveChange,
4285
- openExternally
4286
- }
4287
- );
4288
- }
4289
- ExchangeConnectStep.displayName = "ExchangeConnectStep";
4275
+ RampOrderStep.displayName = "RampOrderStep";
4290
4276
 
4291
4277
  // src/components/steps/ExchangeSelectStep.tsx
4292
- import { useCallback as useCallback5, useEffect as useEffect9, useState as useState9 } from "react";
4293
- import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
4278
+ import { useCallback as useCallback4, useEffect as useEffect9, useState as useState9 } from "react";
4279
+ import { jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
4294
4280
  function ExchangeLogo({ exchange }) {
4295
4281
  const [failed, setFailed] = useState9(false);
4296
4282
  if (!exchange.logoUrl || failed) {
4297
- return /* @__PURE__ */ jsx20(BankIcon, {});
4283
+ return /* @__PURE__ */ jsx19(BankIcon, {});
4298
4284
  }
4299
- return /* @__PURE__ */ jsx20(
4285
+ return /* @__PURE__ */ jsx19(
4300
4286
  "img",
4301
4287
  {
4302
4288
  src: exchange.logoUrl,
@@ -4305,9 +4291,6 @@ function ExchangeLogo({ exchange }) {
4305
4291
  }
4306
4292
  );
4307
4293
  }
4308
- function formatFeeRate(bps) {
4309
- return `${(bps / 100).toFixed(2).replace(/\.?0+$/, "")}%`;
4310
- }
4311
4294
  function ExchangeSelectStep({
4312
4295
  service,
4313
4296
  onSelectExchange,
@@ -4317,12 +4300,11 @@ function ExchangeSelectStep({
4317
4300
  const [loading, setLoading] = useState9(true);
4318
4301
  const [error, setError] = useState9(null);
4319
4302
  const [retryToken, setRetryToken] = useState9(0);
4320
- const [exchangeFeeBps, setExchangeFeeBps] = useState9(0);
4321
4303
  const [selectingConnection, setSelectingConnection] = useState9(
4322
4304
  null
4323
4305
  );
4324
4306
  const [selectionNotice, setSelectionNotice] = useState9(null);
4325
- const retry = useCallback5(() => {
4307
+ const retry = useCallback4(() => {
4326
4308
  setRetryToken((n) => n + 1);
4327
4309
  }, []);
4328
4310
  useEffect9(() => {
@@ -4332,12 +4314,10 @@ function ExchangeSelectStep({
4332
4314
  service.getSwappedConnectExchanges().then((res) => {
4333
4315
  if (cancelled) return;
4334
4316
  setExchanges(res.exchanges);
4335
- setExchangeFeeBps(res.exchangeFeeBps ?? 0);
4336
4317
  }).catch((err) => {
4337
4318
  if (cancelled) return;
4338
4319
  const message = err instanceof Error ? err.message : "Failed to load exchanges";
4339
4320
  setExchanges([]);
4340
- setExchangeFeeBps(0);
4341
4321
  setError(message);
4342
4322
  onError?.(message, "SWAPPED_CONNECT_EXCHANGES_FAILED");
4343
4323
  }).finally(() => {
@@ -4347,21 +4327,12 @@ function ExchangeSelectStep({
4347
4327
  cancelled = true;
4348
4328
  };
4349
4329
  }, [service, retryToken, onError]);
4350
- const selectExchange = useCallback5(
4330
+ const selectExchange = useCallback4(
4351
4331
  async (connection) => {
4352
4332
  setSelectingConnection(connection);
4353
4333
  setSelectionNotice(null);
4354
4334
  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
- }
4335
+ await onSelectExchange(connection);
4365
4336
  } catch (err) {
4366
4337
  const message = err instanceof Error ? err.message : "Failed to prepare Connect";
4367
4338
  setSelectionNotice(message);
@@ -4370,22 +4341,22 @@ function ExchangeSelectStep({
4370
4341
  setSelectingConnection(null);
4371
4342
  }
4372
4343
  },
4373
- [exchangeFeeBps, onError, onSelectExchange]
4344
+ [onError, onSelectExchange]
4374
4345
  );
4375
4346
  return /* @__PURE__ */ jsxs16("div", { className: "rs-screen rs-exchange-select", children: [
4376
4347
  /* @__PURE__ */ jsxs16("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
4377
- /* @__PURE__ */ jsx20(
4348
+ /* @__PURE__ */ jsx19(
4378
4349
  BodyHeader,
4379
4350
  {
4380
- icon: /* @__PURE__ */ jsx20(UnplugIcon, {}),
4351
+ icon: /* @__PURE__ */ jsx19(UnplugIcon, {}),
4381
4352
  title: "Connect exchange",
4382
4353
  subtitle: "Select an exchange to connect"
4383
4354
  }
4384
4355
  ),
4385
- loading && /* @__PURE__ */ jsx20("div", { className: "rs-exchange-select-state", "aria-live": "polite", children: /* @__PURE__ */ jsx20(Spinner, {}) }),
4356
+ loading && /* @__PURE__ */ jsx19("div", { className: "rs-exchange-select-state", "aria-live": "polite", children: /* @__PURE__ */ jsx19(Spinner, {}) }),
4386
4357
  !loading && error && /* @__PURE__ */ jsxs16("div", { className: "rs-exchange-select-state", "aria-live": "polite", children: [
4387
- /* @__PURE__ */ jsx20("div", { className: "rs-exchange-select-state-title", children: "Couldn\u2019t load exchanges" }),
4388
- /* @__PURE__ */ jsx20(
4358
+ /* @__PURE__ */ jsx19("div", { className: "rs-exchange-select-state-title", children: "Couldn\u2019t load exchanges" }),
4359
+ /* @__PURE__ */ jsx19(
4389
4360
  "button",
4390
4361
  {
4391
4362
  type: "button",
@@ -4396,8 +4367,8 @@ function ExchangeSelectStep({
4396
4367
  )
4397
4368
  ] }),
4398
4369
  !loading && !error && exchanges.length === 0 && /* @__PURE__ */ jsxs16("div", { className: "rs-exchange-select-state", "aria-live": "polite", children: [
4399
- /* @__PURE__ */ jsx20("div", { className: "rs-exchange-select-state-title", children: "No exchanges available" }),
4400
- /* @__PURE__ */ jsx20(
4370
+ /* @__PURE__ */ jsx19("div", { className: "rs-exchange-select-state-title", children: "No exchanges available" }),
4371
+ /* @__PURE__ */ jsx19(
4401
4372
  "button",
4402
4373
  {
4403
4374
  type: "button",
@@ -4407,7 +4378,7 @@ function ExchangeSelectStep({
4407
4378
  }
4408
4379
  )
4409
4380
  ] }),
4410
- !loading && !error && exchanges.length > 0 && /* @__PURE__ */ jsx20("div", { className: "rs-exchange-grid", children: exchanges.map((exchange) => {
4381
+ !loading && !error && exchanges.length > 0 && /* @__PURE__ */ jsx19("div", { className: "rs-exchange-grid", children: exchanges.map((exchange) => {
4411
4382
  const brand = getExchangeLogo(exchange.name, exchange.connection);
4412
4383
  return /* @__PURE__ */ jsxs16(
4413
4384
  "button",
@@ -4419,27 +4390,22 @@ function ExchangeSelectStep({
4419
4390
  "aria-busy": selectingConnection === exchange.connection,
4420
4391
  "aria-label": `Select ${exchange.name}`,
4421
4392
  children: [
4422
- /* @__PURE__ */ jsx20(
4393
+ /* @__PURE__ */ jsx19(
4423
4394
  "span",
4424
4395
  {
4425
4396
  className: `rs-exchange-card-logo${brand ? " rs-exchange-card-logo--brand" : ""}`,
4426
- children: brand ?? /* @__PURE__ */ jsx20(ExchangeLogo, { exchange })
4397
+ children: brand ?? /* @__PURE__ */ jsx19(ExchangeLogo, { exchange })
4427
4398
  }
4428
4399
  ),
4429
- /* @__PURE__ */ jsx20("span", { className: "rs-exchange-card-name", children: exchange.name })
4400
+ /* @__PURE__ */ jsx19("span", { className: "rs-exchange-card-name", children: exchange.name })
4430
4401
  ]
4431
4402
  },
4432
4403
  exchange.connection
4433
4404
  );
4434
4405
  }) })
4435
4406
  ] }),
4436
- /* @__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
- selectionNotice && /* @__PURE__ */ jsx20("p", { className: "rs-exchange-select-fee-note", role: "status", children: selectionNotice })
4407
+ /* @__PURE__ */ jsx19(PoweredBy, {}),
4408
+ selectionNotice && /* @__PURE__ */ jsx19("p", { className: "rs-exchange-select-fee-note", role: "status", children: selectionNotice })
4443
4409
  ] });
4444
4410
  }
4445
4411
  ExchangeSelectStep.displayName = "ExchangeSelectStep";
@@ -4447,7 +4413,7 @@ ExchangeSelectStep.displayName = "ExchangeSelectStep";
4447
4413
  // src/components/steps/SolanaTokenSelectStep.tsx
4448
4414
  import { useState as useState10, useEffect as useEffect10, useMemo as useMemo5 } from "react";
4449
4415
  import { formatUnits as formatUnits4 } from "viem";
4450
- import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
4416
+ import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
4451
4417
  function SolanaTokenSelectStep({
4452
4418
  solanaAddress,
4453
4419
  service,
@@ -4555,28 +4521,28 @@ function SolanaTokenSelectStep({
4555
4521
  const chainName = getChainName("solana");
4556
4522
  return /* @__PURE__ */ jsxs17("div", { className: "rs-screen", children: [
4557
4523
  /* @__PURE__ */ jsxs17("div", { className: "rs-screen-body", children: [
4558
- /* @__PURE__ */ jsx21(
4524
+ /* @__PURE__ */ jsx20(
4559
4525
  BodyHeader,
4560
4526
  {
4561
- icon: /* @__PURE__ */ jsx21(WalletIcon, {}),
4527
+ icon: /* @__PURE__ */ jsx20(WalletIcon, {}),
4562
4528
  title: "Your assets",
4563
4529
  subtitle: "Select source assets to transfer"
4564
4530
  }
4565
4531
  ),
4566
4532
  loading && /* @__PURE__ */ jsxs17("div", { className: "rs-loading-state", style: { padding: "40px 12px" }, children: [
4567
- /* @__PURE__ */ jsx21(Spinner, { className: "rs-text-tertiary" }),
4568
- /* @__PURE__ */ jsx21("span", { className: "rs-text-sm rs-text-tertiary", children: "Loading balances" })
4533
+ /* @__PURE__ */ jsx20(Spinner, { className: "rs-text-tertiary" }),
4534
+ /* @__PURE__ */ jsx20("span", { className: "rs-text-sm rs-text-tertiary", children: "Loading balances" })
4569
4535
  ] }),
4570
- error && /* @__PURE__ */ jsx21(Callout, { variant: "error", children: error }),
4536
+ error && /* @__PURE__ */ jsx20(Callout, { variant: "error", children: error }),
4571
4537
  !loading && !error && rows.length === 0 && /* @__PURE__ */ jsxs17("div", { className: "rs-empty-state", children: [
4572
- /* @__PURE__ */ jsx21(WalletIcon, { className: "rs-empty-icon" }),
4573
- /* @__PURE__ */ jsx21("div", { className: "rs-empty-text", children: "No funds in connected wallet" }),
4538
+ /* @__PURE__ */ jsx20(WalletIcon, { className: "rs-empty-icon" }),
4539
+ /* @__PURE__ */ jsx20("div", { className: "rs-empty-text", children: "No funds in connected wallet" }),
4574
4540
  /* @__PURE__ */ jsxs17("div", { className: "rs-empty-address", children: [
4575
4541
  solanaAddress.slice(0, 6),
4576
4542
  "...",
4577
4543
  solanaAddress.slice(-4)
4578
4544
  ] }),
4579
- onDisconnect && /* @__PURE__ */ jsx21(
4545
+ onDisconnect && /* @__PURE__ */ jsx20(
4580
4546
  "button",
4581
4547
  {
4582
4548
  type: "button",
@@ -4586,7 +4552,7 @@ function SolanaTokenSelectStep({
4586
4552
  }
4587
4553
  )
4588
4554
  ] }),
4589
- !loading && !error && rows.length > 0 && /* @__PURE__ */ jsx21("div", { className: "rs-asset-list", children: rows.map((entry) => {
4555
+ !loading && !error && rows.length > 0 && /* @__PURE__ */ jsx20("div", { className: "rs-asset-list", children: rows.map((entry) => {
4590
4556
  const isSelected = selectedSymbol === entry.token.symbol;
4591
4557
  const tokenAmount = formatBalance(entry);
4592
4558
  return /* @__PURE__ */ jsxs17(
@@ -4599,18 +4565,19 @@ function SolanaTokenSelectStep({
4599
4565
  children: [
4600
4566
  /* @__PURE__ */ jsxs17("div", { className: "rs-asset-info", children: [
4601
4567
  /* @__PURE__ */ jsxs17("div", { className: "rs-asset-icon-wrapper", children: [
4602
- /* @__PURE__ */ jsx21("span", { className: "rs-asset-icon", children: /* @__PURE__ */ jsx21(
4568
+ /* @__PURE__ */ jsx20("span", { className: "rs-asset-icon", children: /* @__PURE__ */ jsx20(
4603
4569
  TokenIcon,
4604
4570
  {
4571
+ token: { chain: "solana", address: entry.token.mint },
4605
4572
  symbol: entry.token.symbol,
4606
4573
  fallback: entry.token.symbol.slice(0, 4)
4607
4574
  }
4608
4575
  ) }),
4609
- chainIcon && /* @__PURE__ */ jsx21("span", { className: "rs-asset-chain-badge", children: /* @__PURE__ */ jsx21(CdnIcon, { src: chainIcon, alt: chainName }) })
4576
+ chainIcon && /* @__PURE__ */ jsx20("span", { className: "rs-asset-chain-badge", children: /* @__PURE__ */ jsx20(CdnIcon, { src: chainIcon, alt: chainName }) })
4610
4577
  ] }),
4611
4578
  /* @__PURE__ */ jsxs17("div", { className: "rs-asset-text", children: [
4612
4579
  /* @__PURE__ */ jsxs17("div", { className: "rs-asset-name-row", children: [
4613
- /* @__PURE__ */ jsx21("span", { className: "rs-asset-name", children: entry.token.symbol }),
4580
+ /* @__PURE__ */ jsx20("span", { className: "rs-asset-name", children: entry.token.symbol }),
4614
4581
  /* @__PURE__ */ jsxs17("span", { className: "rs-asset-chain", children: [
4615
4582
  "on ",
4616
4583
  chainName
@@ -4623,13 +4590,13 @@ function SolanaTokenSelectStep({
4623
4590
  ] })
4624
4591
  ] })
4625
4592
  ] }),
4626
- /* @__PURE__ */ jsx21("div", { className: "rs-asset-balance", children: entry.balanceUsd > 0 ? currencyFormatter.format(entry.balanceUsd) : tokenAmount !== "--" ? `${tokenAmount} ${entry.token.symbol}` : "--" })
4593
+ /* @__PURE__ */ jsx20("div", { className: "rs-asset-balance", children: entry.balanceUsd > 0 ? currencyFormatter.format(entry.balanceUsd) : tokenAmount !== "--" ? `${tokenAmount} ${entry.token.symbol}` : "--" })
4627
4594
  ]
4628
4595
  },
4629
4596
  entry.token.symbol
4630
4597
  );
4631
4598
  }) }),
4632
- /* @__PURE__ */ jsx21(
4599
+ /* @__PURE__ */ jsx20(
4633
4600
  Button,
4634
4601
  {
4635
4602
  onClick: () => selectedEntry && onContinue(
@@ -4643,14 +4610,14 @@ function SolanaTokenSelectStep({
4643
4610
  }
4644
4611
  )
4645
4612
  ] }),
4646
- /* @__PURE__ */ jsx21(PoweredBy, {})
4613
+ /* @__PURE__ */ jsx20(PoweredBy, {})
4647
4614
  ] });
4648
4615
  }
4649
4616
 
4650
4617
  // src/components/steps/SolanaAmountStep.tsx
4651
- import { useCallback as useCallback6, useEffect as useEffect11, useMemo as useMemo6, useRef as useRef7, useState as useState11 } from "react";
4618
+ import { useCallback as useCallback5, useEffect as useEffect11, useMemo as useMemo6, useRef as useRef7, useState as useState11 } from "react";
4652
4619
  import { formatUnits as formatUnits5, parseUnits as parseUnits4 } from "viem";
4653
- import { Fragment as Fragment5, jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
4620
+ import { Fragment as Fragment5, jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
4654
4621
  var SOL_FEE_RESERVE_LAMPORTS = 1000000n;
4655
4622
  var PRESETS2 = [
4656
4623
  { value: 25, label: "25%" },
@@ -4667,6 +4634,7 @@ function SolanaAmountStep({
4667
4634
  targetChain,
4668
4635
  targetChainName,
4669
4636
  targetTokenSymbol,
4637
+ targetToken,
4670
4638
  appBalanceUsd,
4671
4639
  onContinue,
4672
4640
  debug
@@ -4725,7 +4693,7 @@ function SolanaAmountStep({
4725
4693
  return null;
4726
4694
  }
4727
4695
  }, [spendableBalance, token.decimals, tokenPriceUsd]);
4728
- const computePresetAmount = useCallback6(
4696
+ const computePresetAmount = useCallback5(
4729
4697
  (percentage) => {
4730
4698
  try {
4731
4699
  const spendableUnits = Number(
@@ -4857,10 +4825,10 @@ function SolanaAmountStep({
4857
4825
  const continueDisabled = exceedsBalance || boundViolation !== null || numericAmount === 0 && !isBelowMin;
4858
4826
  return /* @__PURE__ */ jsxs18("div", { className: "rs-screen", children: [
4859
4827
  /* @__PURE__ */ jsxs18("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
4860
- /* @__PURE__ */ jsx22(BodyHeader, { icon: /* @__PURE__ */ jsx22(WalletIcon, {}), title: "Wallet deposit" }),
4828
+ /* @__PURE__ */ jsx21(BodyHeader, { icon: /* @__PURE__ */ jsx21(WalletIcon, {}), title: "Wallet deposit" }),
4861
4829
  /* @__PURE__ */ jsxs18("div", { className: "rs-amount-section", children: [
4862
4830
  /* @__PURE__ */ jsxs18("div", { className: "rs-amount-display", children: [
4863
- /* @__PURE__ */ jsx22(
4831
+ /* @__PURE__ */ jsx21(
4864
4832
  AnimatedAmountInput,
4865
4833
  {
4866
4834
  value: amount,
@@ -4887,7 +4855,7 @@ function SolanaAmountStep({
4887
4855
  ] })
4888
4856
  ] })
4889
4857
  ] }),
4890
- /* @__PURE__ */ jsx22("div", { className: "rs-amount-presets", children: PRESETS2.map((preset) => /* @__PURE__ */ jsx22(
4858
+ /* @__PURE__ */ jsx21("div", { className: "rs-amount-presets", children: PRESETS2.map((preset) => /* @__PURE__ */ jsx21(
4891
4859
  "button",
4892
4860
  {
4893
4861
  type: "button",
@@ -4900,33 +4868,39 @@ function SolanaAmountStep({
4900
4868
  ] }),
4901
4869
  /* @__PURE__ */ jsxs18("div", { className: "rs-amount-details", children: [
4902
4870
  /* @__PURE__ */ jsxs18("div", { className: "rs-amount-detail-row", children: [
4903
- /* @__PURE__ */ jsx22("span", { children: "You send" }),
4871
+ /* @__PURE__ */ jsx21("span", { children: "You send" }),
4904
4872
  /* @__PURE__ */ jsxs18("span", { className: "rs-amount-detail-value", children: [
4905
4873
  /* @__PURE__ */ jsxs18("span", { children: [
4906
4874
  "Solana ",
4907
4875
  token.symbol
4908
4876
  ] }),
4909
- /* @__PURE__ */ jsx22("span", { className: "rs-amount-detail-icon", children: /* @__PURE__ */ jsx22(TokenIcon, { symbol: token.symbol }) })
4877
+ /* @__PURE__ */ jsx21("span", { className: "rs-amount-detail-icon", children: /* @__PURE__ */ jsx21(
4878
+ TokenIcon,
4879
+ {
4880
+ token: { chain: "solana", address: token.mint },
4881
+ symbol: token.symbol
4882
+ }
4883
+ ) })
4910
4884
  ] })
4911
4885
  ] }),
4912
4886
  targetChainName && targetTokenSymbol && /* @__PURE__ */ jsxs18("div", { className: "rs-amount-detail-row", children: [
4913
- /* @__PURE__ */ jsx22("span", { children: "Receive" }),
4887
+ /* @__PURE__ */ jsx21("span", { children: "Receive" }),
4914
4888
  /* @__PURE__ */ jsxs18("span", { className: "rs-amount-detail-value", children: [
4915
4889
  /* @__PURE__ */ jsxs18("span", { children: [
4916
4890
  targetChainName,
4917
4891
  " ",
4918
4892
  targetTokenSymbol
4919
4893
  ] }),
4920
- /* @__PURE__ */ jsx22("span", { className: "rs-amount-detail-icon", children: /* @__PURE__ */ jsx22(TokenIcon, { symbol: targetTokenSymbol }) })
4894
+ /* @__PURE__ */ jsx21("span", { className: "rs-amount-detail-icon", children: /* @__PURE__ */ jsx21(TokenIcon, { token: targetToken, symbol: targetTokenSymbol }) })
4921
4895
  ] })
4922
4896
  ] }),
4923
4897
  balanceAfterUsd !== null && /* @__PURE__ */ jsxs18("div", { className: "rs-amount-detail-row", children: [
4924
- /* @__PURE__ */ jsx22("span", { children: "Balance after deposit" }),
4925
- /* @__PURE__ */ jsx22("span", { className: "rs-amount-detail-value", children: currencyFormatter.format(balanceAfterUsd) })
4898
+ /* @__PURE__ */ jsx21("span", { children: "Balance after deposit" }),
4899
+ /* @__PURE__ */ jsx21("span", { className: "rs-amount-detail-value", children: currencyFormatter.format(balanceAfterUsd) })
4926
4900
  ] })
4927
4901
  ] }),
4928
- error && /* @__PURE__ */ jsx22(Callout, { variant: "error", children: error }),
4929
- /* @__PURE__ */ jsx22(
4902
+ error && /* @__PURE__ */ jsx21(Callout, { variant: "error", children: error }),
4903
+ /* @__PURE__ */ jsx21(
4930
4904
  Button,
4931
4905
  {
4932
4906
  onClick: handleContinue,
@@ -4936,7 +4910,7 @@ function SolanaAmountStep({
4936
4910
  }
4937
4911
  )
4938
4912
  ] }),
4939
- /* @__PURE__ */ jsx22(PoweredBy, {})
4913
+ /* @__PURE__ */ jsx21(PoweredBy, {})
4940
4914
  ] });
4941
4915
  }
4942
4916
 
@@ -5054,7 +5028,7 @@ async function sendSolanaTransaction(provider, _connection, transaction) {
5054
5028
  }
5055
5029
 
5056
5030
  // src/components/steps/SolanaConfirmStep.tsx
5057
- import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
5031
+ import { jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
5058
5032
  function SolanaConfirmStep({
5059
5033
  smartAccount,
5060
5034
  solanaAddress,
@@ -5086,7 +5060,7 @@ function SolanaConfirmStep({
5086
5060
  return () => onSubmittingChangeRef.current?.(false);
5087
5061
  }, [isSubmitting]);
5088
5062
  const targetChainId = targetChainToChainId(targetChain);
5089
- const targetSymbol = getTargetTokenSymbol(targetToken, targetChainId);
5063
+ const targetSymbol = useTokenDisplay(targetChainId, targetToken).symbol;
5090
5064
  const sourceChainName = getChainName("solana");
5091
5065
  const targetChainName = getChainName(targetChainId);
5092
5066
  const sourceChainIcon = getChainIcon("solana");
@@ -5102,7 +5076,8 @@ function SolanaConfirmStep({
5102
5076
  sourceSymbol: token.symbol,
5103
5077
  targetSymbol,
5104
5078
  sourceAmountUsd,
5105
- sourceTrusted: isRecognizedToken(token.mint, "solana"),
5079
+ // The wallet flow only offers the allowlist, so this is the check.
5080
+ sourceTrusted: resolveSolanaToken(token.mint) !== void 0,
5106
5081
  // Curated stablecoin target estimates at $1 when unquoted; never applied
5107
5082
  // to the source (a held token). See ConfirmStep for the rationale.
5108
5083
  prices: targetTokenPriceUsd !== null && targetTokenPriceUsd > 0 ? { [targetSymbol.toUpperCase()]: targetTokenPriceUsd } : isDisplayStablecoinSymbol(targetSymbol) ? { [targetSymbol.toUpperCase()]: 1 } : {}
@@ -5206,8 +5181,8 @@ function SolanaConfirmStep({
5206
5181
  };
5207
5182
  return /* @__PURE__ */ jsxs19("div", { className: "rs-screen", children: [
5208
5183
  /* @__PURE__ */ jsxs19("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
5209
- /* @__PURE__ */ jsx23(BodyHeader, { icon: /* @__PURE__ */ jsx23(WalletIcon, {}), title: "Review deposit" }),
5210
- /* @__PURE__ */ jsx23(
5184
+ /* @__PURE__ */ jsx22(BodyHeader, { icon: /* @__PURE__ */ jsx22(WalletIcon, {}), title: "Review deposit" }),
5185
+ /* @__PURE__ */ jsx22(
5211
5186
  ReviewDetails,
5212
5187
  {
5213
5188
  sourceChainName,
@@ -5217,13 +5192,15 @@ function SolanaConfirmStep({
5217
5192
  estimatedTime,
5218
5193
  sendAmount: formattedAmount,
5219
5194
  sendSymbol: token.symbol,
5195
+ sendToken: { chain: "solana", address: token.mint },
5220
5196
  receiveDisplay,
5221
5197
  receiveSymbol: targetSymbol,
5198
+ receiveToken: { chain: targetChainId, address: targetToken },
5222
5199
  fee: { display: "$0.04", struck: feeSponsored, tooltip: feeTooltip }
5223
5200
  }
5224
5201
  ),
5225
- error && /* @__PURE__ */ jsx23(Callout, { variant: "error", children: error }),
5226
- /* @__PURE__ */ jsx23(
5202
+ error && /* @__PURE__ */ jsx22(Callout, { variant: "error", children: error }),
5203
+ /* @__PURE__ */ jsx22(
5227
5204
  Button,
5228
5205
  {
5229
5206
  onClick: handleConfirm,
@@ -5235,12 +5212,12 @@ function SolanaConfirmStep({
5235
5212
  }
5236
5213
  )
5237
5214
  ] }),
5238
- /* @__PURE__ */ jsx23(PoweredBy, {})
5215
+ /* @__PURE__ */ jsx22(PoweredBy, {})
5239
5216
  ] });
5240
5217
  }
5241
5218
 
5242
5219
  // src/components/steps/DappImportAssetSelectStep.tsx
5243
- import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
5220
+ import { jsx as jsx23, jsxs as jsxs20 } from "react/jsx-runtime";
5244
5221
  function DappImportAssetSelectStep({
5245
5222
  sourceLabel,
5246
5223
  assets,
@@ -5249,16 +5226,16 @@ function DappImportAssetSelectStep({
5249
5226
  }) {
5250
5227
  return /* @__PURE__ */ jsxs20("div", { className: "rs-screen", children: [
5251
5228
  /* @__PURE__ */ jsxs20("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
5252
- /* @__PURE__ */ jsx24(
5229
+ /* @__PURE__ */ jsx23(
5253
5230
  BodyHeader,
5254
5231
  {
5255
- icon: /* @__PURE__ */ jsx24(WalletIcon, {}),
5232
+ icon: /* @__PURE__ */ jsx23(WalletIcon, {}),
5256
5233
  title: `Transfer from ${sourceLabel}`,
5257
5234
  subtitle: "Pick the balance to import"
5258
5235
  }
5259
5236
  ),
5260
- incompleteSummary && /* @__PURE__ */ jsx24("div", { className: "rs-asset-notice", role: "status", children: incompleteSummary }),
5261
- /* @__PURE__ */ jsx24("div", { className: "rs-asset-list", children: assets.map((asset) => {
5237
+ incompleteSummary && /* @__PURE__ */ jsx23("div", { className: "rs-asset-notice", role: "status", children: incompleteSummary }),
5238
+ /* @__PURE__ */ jsx23("div", { className: "rs-asset-list", children: assets.map((asset) => {
5262
5239
  const tokenAmount = asset.balance ? tokenFormatter.format(
5263
5240
  Number(asset.balance) / 10 ** asset.decimals
5264
5241
  ) : "0";
@@ -5275,14 +5252,15 @@ function DappImportAssetSelectStep({
5275
5252
  children: [
5276
5253
  /* @__PURE__ */ jsxs20("div", { className: "rs-asset-info", children: [
5277
5254
  /* @__PURE__ */ jsxs20("div", { className: "rs-asset-icon-wrapper", children: [
5278
- /* @__PURE__ */ jsx24("span", { className: "rs-asset-icon", children: assetIcon ? /* @__PURE__ */ jsx24(CdnIcon, { src: assetIcon, alt: asset.symbol }) : /* @__PURE__ */ jsx24(
5255
+ /* @__PURE__ */ jsx23("span", { className: "rs-asset-icon", children: assetIcon ? /* @__PURE__ */ jsx23(CdnIcon, { src: assetIcon, alt: asset.symbol }) : /* @__PURE__ */ jsx23(
5279
5256
  TokenIcon,
5280
5257
  {
5258
+ token: { chain: asset.chainId, address: asset.token },
5281
5259
  symbol: asset.symbol,
5282
5260
  fallback: asset.symbol.slice(0, 4)
5283
5261
  }
5284
5262
  ) }),
5285
- chainIcon ? /* @__PURE__ */ jsx24("span", { className: "rs-asset-chain-badge", children: /* @__PURE__ */ jsx24(CdnIcon, { src: chainIcon, alt: getChainName(asset.chainId) }) }) : /* @__PURE__ */ jsx24(
5263
+ chainIcon ? /* @__PURE__ */ jsx23("span", { className: "rs-asset-chain-badge", children: /* @__PURE__ */ jsx23(CdnIcon, { src: chainIcon, alt: getChainName(asset.chainId) }) }) : /* @__PURE__ */ jsx23(
5286
5264
  "span",
5287
5265
  {
5288
5266
  className: "rs-asset-chain-badge",
@@ -5293,7 +5271,7 @@ function DappImportAssetSelectStep({
5293
5271
  ] }),
5294
5272
  /* @__PURE__ */ jsxs20("div", { className: "rs-asset-text", children: [
5295
5273
  /* @__PURE__ */ jsxs20("div", { className: "rs-asset-name-row", children: [
5296
- /* @__PURE__ */ jsx24("span", { className: "rs-asset-name", children: asset.symbol }),
5274
+ /* @__PURE__ */ jsx23("span", { className: "rs-asset-name", children: asset.symbol }),
5297
5275
  /* @__PURE__ */ jsxs20("span", { className: "rs-asset-chain", children: [
5298
5276
  "on ",
5299
5277
  asset.sourceLabel,
@@ -5307,20 +5285,20 @@ function DappImportAssetSelectStep({
5307
5285
  ] })
5308
5286
  ] })
5309
5287
  ] }),
5310
- /* @__PURE__ */ jsx24("div", { className: "rs-asset-balance", children: balanceUsd })
5288
+ /* @__PURE__ */ jsx23("div", { className: "rs-asset-balance", children: balanceUsd })
5311
5289
  ]
5312
5290
  },
5313
5291
  asset.id
5314
5292
  );
5315
5293
  }) })
5316
5294
  ] }),
5317
- /* @__PURE__ */ jsx24(PoweredBy, {})
5295
+ /* @__PURE__ */ jsx23(PoweredBy, {})
5318
5296
  ] });
5319
5297
  }
5320
5298
  DappImportAssetSelectStep.displayName = "DappImportAssetSelectStep";
5321
5299
 
5322
5300
  // src/components/steps/DappImportSelectStep.tsx
5323
- import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
5301
+ import { jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
5324
5302
  function describeRow(status, comingSoon) {
5325
5303
  if (comingSoon) {
5326
5304
  return { subtitle: "Coming soon", disabled: true, busy: false };
@@ -5358,28 +5336,28 @@ function DappImportSelectStep({
5358
5336
  const brands = DAPP_IMPORT_CATALOG.filter((brand) => enabled.has(brand.id));
5359
5337
  return /* @__PURE__ */ jsxs21("div", { className: "rs-screen", children: [
5360
5338
  /* @__PURE__ */ jsxs21("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
5361
- /* @__PURE__ */ jsx25(
5339
+ /* @__PURE__ */ jsx24(
5362
5340
  BodyHeader,
5363
5341
  {
5364
- icon: /* @__PURE__ */ jsx25(MigrateAssetsIcon, {}),
5342
+ icon: /* @__PURE__ */ jsx24(MigrateAssetsIcon, {}),
5365
5343
  title: "Migrate assets",
5366
5344
  subtitle: "Select a position to migrate"
5367
5345
  }
5368
5346
  ),
5369
- /* @__PURE__ */ jsx25("div", { className: "rs-list", children: brands.map((brand) => {
5347
+ /* @__PURE__ */ jsx24("div", { className: "rs-list", children: brands.map((brand) => {
5370
5348
  const status = byId.get(brand.id);
5371
5349
  const { subtitle, disabled, busy } = describeRow(
5372
5350
  status,
5373
5351
  Boolean(brand.comingSoon)
5374
5352
  );
5375
- return /* @__PURE__ */ jsx25(
5353
+ return /* @__PURE__ */ jsx24(
5376
5354
  ListRow,
5377
5355
  {
5378
5356
  leadingMedia: brand.iconUrl,
5379
5357
  title: brand.label,
5380
5358
  subtitle,
5381
5359
  disabled,
5382
- trailing: busy ? /* @__PURE__ */ jsx25(Spinner, { className: "rs-spinner--sm" }) : void 0,
5360
+ trailing: busy ? /* @__PURE__ */ jsx24(Spinner, { className: "rs-spinner--sm" }) : void 0,
5383
5361
  onClick: () => {
5384
5362
  if (status === "needs-connect") {
5385
5363
  onRequestConnect?.();
@@ -5392,13 +5370,13 @@ function DappImportSelectStep({
5392
5370
  );
5393
5371
  }) })
5394
5372
  ] }),
5395
- /* @__PURE__ */ jsx25(PoweredBy, {})
5373
+ /* @__PURE__ */ jsx24(PoweredBy, {})
5396
5374
  ] });
5397
5375
  }
5398
5376
  DappImportSelectStep.displayName = "DappImportSelectStep";
5399
5377
 
5400
5378
  // src/components/steps/DappImportAssetSelectSkeleton.tsx
5401
- import { jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
5379
+ import { jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
5402
5380
  function DappImportAssetSelectSkeleton({
5403
5381
  sourceLabel,
5404
5382
  rowCount = 3,
@@ -5406,64 +5384,64 @@ function DappImportAssetSelectSkeleton({
5406
5384
  onRetry
5407
5385
  }) {
5408
5386
  return /* @__PURE__ */ jsxs22("div", { className: "rs-screen", "aria-busy": error ? "false" : "true", children: [
5409
- /* @__PURE__ */ jsx26("span", { className: "rs-sr-only", role: "status", children: error ? "Couldn't load balances" : "Loading balances\u2026" }),
5387
+ /* @__PURE__ */ jsx25("span", { className: "rs-sr-only", role: "status", children: error ? "Couldn't load balances" : "Loading balances\u2026" }),
5410
5388
  /* @__PURE__ */ jsxs22("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
5411
- /* @__PURE__ */ jsx26(
5389
+ /* @__PURE__ */ jsx25(
5412
5390
  BodyHeader,
5413
5391
  {
5414
- icon: /* @__PURE__ */ jsx26(WalletIcon, {}),
5392
+ icon: /* @__PURE__ */ jsx25(WalletIcon, {}),
5415
5393
  title: `Transfer from ${sourceLabel}`,
5416
5394
  subtitle: "Pick the balance to import"
5417
5395
  }
5418
5396
  ),
5419
- error ? /* @__PURE__ */ jsx26("div", { className: "rs-loading-state", children: /* @__PURE__ */ jsxs22("div", { className: "rs-loading-text", children: [
5420
- /* @__PURE__ */ jsx26("div", { className: "rs-loading-title rs-text-error", children: "Couldn\u2019t load your balances" }),
5421
- /* @__PURE__ */ jsx26("div", { className: "rs-loading-subtitle", children: "Check your connection and try again." })
5422
- ] }) }) : /* @__PURE__ */ jsx26("div", { className: "rs-asset-list", "aria-hidden": "true", children: Array.from({ length: rowCount }, (_, index) => /* @__PURE__ */ jsxs22(
5397
+ error ? /* @__PURE__ */ jsx25("div", { className: "rs-loading-state", children: /* @__PURE__ */ jsxs22("div", { className: "rs-loading-text", children: [
5398
+ /* @__PURE__ */ jsx25("div", { className: "rs-loading-title rs-text-error", children: "Couldn\u2019t load your balances" }),
5399
+ /* @__PURE__ */ jsx25("div", { className: "rs-loading-subtitle", children: "Check your connection and try again." })
5400
+ ] }) }) : /* @__PURE__ */ jsx25("div", { className: "rs-asset-list", "aria-hidden": "true", children: Array.from({ length: rowCount }, (_, index) => /* @__PURE__ */ jsxs22(
5423
5401
  "div",
5424
5402
  {
5425
5403
  className: "rs-asset-row rs-asset-row--skeleton",
5426
5404
  children: [
5427
5405
  /* @__PURE__ */ jsxs22("div", { className: "rs-asset-info", children: [
5428
5406
  /* @__PURE__ */ jsxs22("div", { className: "rs-asset-icon-wrapper", children: [
5429
- /* @__PURE__ */ jsx26("span", { className: "rs-asset-icon", children: /* @__PURE__ */ jsx26("span", { className: "rs-skeleton rs-skeleton-fill" }) }),
5430
- /* @__PURE__ */ jsx26("span", { className: "rs-asset-chain-badge", children: /* @__PURE__ */ jsx26("span", { className: "rs-skeleton rs-skeleton-fill" }) })
5407
+ /* @__PURE__ */ jsx25("span", { className: "rs-asset-icon", children: /* @__PURE__ */ jsx25("span", { className: "rs-skeleton rs-skeleton-fill" }) }),
5408
+ /* @__PURE__ */ jsx25("span", { className: "rs-asset-chain-badge", children: /* @__PURE__ */ jsx25("span", { className: "rs-skeleton rs-skeleton-fill" }) })
5431
5409
  ] }),
5432
5410
  /* @__PURE__ */ jsxs22("div", { className: "rs-asset-text", children: [
5433
- /* @__PURE__ */ jsx26("div", { className: "rs-asset-name-row", children: /* @__PURE__ */ jsx26("span", { className: "rs-skeleton rs-skeleton-text rs-skeleton-text--name" }) }),
5434
- /* @__PURE__ */ jsx26("div", { className: "rs-asset-balance-small", children: /* @__PURE__ */ jsx26("span", { className: "rs-skeleton rs-skeleton-text rs-skeleton-text--balance" }) })
5411
+ /* @__PURE__ */ jsx25("div", { className: "rs-asset-name-row", children: /* @__PURE__ */ jsx25("span", { className: "rs-skeleton rs-skeleton-text rs-skeleton-text--name" }) }),
5412
+ /* @__PURE__ */ jsx25("div", { className: "rs-asset-balance-small", children: /* @__PURE__ */ jsx25("span", { className: "rs-skeleton rs-skeleton-text rs-skeleton-text--balance" }) })
5435
5413
  ] })
5436
5414
  ] }),
5437
- /* @__PURE__ */ jsx26("div", { className: "rs-asset-balance", children: /* @__PURE__ */ jsx26("span", { className: "rs-skeleton rs-skeleton-text rs-skeleton-text--usd" }) })
5415
+ /* @__PURE__ */ jsx25("div", { className: "rs-asset-balance", children: /* @__PURE__ */ jsx25("span", { className: "rs-skeleton rs-skeleton-text rs-skeleton-text--usd" }) })
5438
5416
  ]
5439
5417
  },
5440
5418
  index
5441
5419
  )) })
5442
5420
  ] }),
5443
- error && onRetry && /* @__PURE__ */ jsx26("div", { className: "rs-step-footer", children: /* @__PURE__ */ jsx26(
5421
+ error && onRetry && /* @__PURE__ */ jsx25("div", { className: "rs-step-footer", children: /* @__PURE__ */ jsx25(
5444
5422
  "button",
5445
5423
  {
5446
5424
  type: "button",
5447
5425
  className: "rs-button rs-button--default rs-button--full-width",
5448
5426
  onClick: onRetry,
5449
- children: /* @__PURE__ */ jsx26("span", { children: "Try again" })
5427
+ children: /* @__PURE__ */ jsx25("span", { children: "Try again" })
5450
5428
  }
5451
5429
  ) }),
5452
- /* @__PURE__ */ jsx26(PoweredBy, {})
5430
+ /* @__PURE__ */ jsx25(PoweredBy, {})
5453
5431
  ] });
5454
5432
  }
5455
5433
  DappImportAssetSelectSkeleton.displayName = "DappImportAssetSelectSkeleton";
5456
5434
 
5457
5435
  // src/core/fiat-methods.ts
5458
5436
  var REGIONAL_METHODS_TIMEOUT_MS = 3e3;
5459
- var BUILT_IN_ICON_METHODS = /* @__PURE__ */ new Set([
5437
+ var PRODUCT_METHODS = /* @__PURE__ */ new Set([
5460
5438
  "creditcard",
5461
5439
  "bank-transfer",
5462
5440
  "apple-pay"
5463
5441
  ]);
5464
5442
  function serverMethodToOption(m) {
5465
5443
  const icon = m.method === "bank-transfer" ? "bank" : m.method === "apple-pay" ? "apple" : "card";
5466
- const remoteIcon = BUILT_IN_ICON_METHODS.has(m.method) ? {} : {
5444
+ const remoteIcon = PRODUCT_METHODS.has(m.method) ? {} : {
5467
5445
  iconUrl: m.iconUrl ?? void 0,
5468
5446
  iconUrlLight: m.iconUrlLight ?? void 0
5469
5447
  };
@@ -5498,8 +5476,9 @@ function composeFiatMethods(regional, fallbackMethods) {
5498
5476
  source: "fallback"
5499
5477
  };
5500
5478
  }
5501
- if (regional.methods.length === 0) return { kind: "hidden" };
5502
- const methods = dedupe(regional.methods.map(serverMethodToOption));
5479
+ const methods = dedupe(
5480
+ regional.methods.filter((m) => PRODUCT_METHODS.has(m.method) || m.badge === "Popular").map(serverMethodToOption)
5481
+ );
5503
5482
  if (methods.length === 0) return { kind: "hidden" };
5504
5483
  const recommendedMethod = regional.recommendedMethod && methods.some(({ method }) => method === regional.recommendedMethod) ? regional.recommendedMethod : methods[0].method;
5505
5484
  return {
@@ -6075,7 +6054,7 @@ import {
6075
6054
  useContext,
6076
6055
  useMemo as useMemo7
6077
6056
  } from "react";
6078
- import { jsx as jsx27 } from "react/jsx-runtime";
6057
+ import { jsx as jsx26 } from "react/jsx-runtime";
6079
6058
  function fundingMethodForFlowMode(mode) {
6080
6059
  switch (mode) {
6081
6060
  case "wallet":
@@ -6136,7 +6115,15 @@ function analyticsStepForFlowStep(method, step) {
6136
6115
  return "funding_method_home";
6137
6116
  }
6138
6117
  }
6118
+ var BANK_FAILURES = {
6119
+ BANK_ONRAMP_OPTIONS_FAILED: "bank_options_failed",
6120
+ BANK_ONRAMP_SETUP_FAILED: "bank_setup_failed",
6121
+ BANK_ONRAMP_DETAILS_FAILED: "bank_details_failed",
6122
+ BANK_ONRAMP_DETAILS_PENDING: "bank_details_pending"
6123
+ };
6139
6124
  function failureReasonForCode(code, cause) {
6125
+ const bank = code ? BANK_FAILURES[code] : void 0;
6126
+ if (bank) return bank;
6140
6127
  const normalized = `${code ?? ""} ${cause ?? ""}`.toLowerCase();
6141
6128
  if (normalized.includes("uncertain")) return "submission_uncertain";
6142
6129
  if (normalized.includes("reject") && (normalized.includes("sign") || normalized.includes("permit"))) {
@@ -6371,7 +6358,7 @@ function DepositAnalyticsControllerProvider({
6371
6358
  [emit]
6372
6359
  );
6373
6360
  if (controllerRef) controllerRef.current = controller;
6374
- return /* @__PURE__ */ jsx27(DepositAnalyticsControllerContext.Provider, { value: controller, children });
6361
+ return /* @__PURE__ */ jsx26(DepositAnalyticsControllerContext.Provider, { value: controller, children });
6375
6362
  }
6376
6363
  function useDepositAnalyticsController() {
6377
6364
  return useContext(DepositAnalyticsControllerContext) ?? noopController;
@@ -6453,7 +6440,8 @@ function createInitialState(overrides) {
6453
6440
  },
6454
6441
  fiat: {
6455
6442
  selectedMethod: null,
6456
- methodSelectionSource: null
6443
+ methodSelectionSource: null,
6444
+ selectedProvider: null
6457
6445
  },
6458
6446
  exchange: {
6459
6447
  selectedConnection: null
@@ -6741,7 +6729,8 @@ function applyAction(state, action) {
6741
6729
  fiat: {
6742
6730
  ...state.fiat,
6743
6731
  selectedMethod: action.paymentMethod ?? null,
6744
- methodSelectionSource: action.methodSelectionSource ?? null
6732
+ methodSelectionSource: action.methodSelectionSource ?? null,
6733
+ selectedProvider: action.provider ?? null
6745
6734
  },
6746
6735
  // Pin on ENTRY, not on submit: a Swapped order only reports a
6747
6736
  // submission on terminal success, so between paying and that callback
@@ -7322,7 +7311,11 @@ function applyAction(state, action) {
7322
7311
  byKey: {},
7323
7312
  nextRequestId: state.portfolio.nextRequestId
7324
7313
  },
7325
- fiat: { selectedMethod: null, methodSelectionSource: null },
7314
+ fiat: {
7315
+ selectedMethod: null,
7316
+ methodSelectionSource: null,
7317
+ selectedProvider: null
7318
+ },
7326
7319
  exchange: { selectedConnection: null }
7327
7320
  };
7328
7321
  }
@@ -7398,7 +7391,7 @@ function useDepositStore(selector) {
7398
7391
  }
7399
7392
 
7400
7393
  // src/DepositFlow.tsx
7401
- import { Fragment as Fragment6, jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
7394
+ import { Fragment as Fragment6, jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
7402
7395
  function swappedWidgetPrefetchKey(method, methodSelectionSource) {
7403
7396
  return JSON.stringify([methodSelectionSource ?? null, method ?? null]);
7404
7397
  }
@@ -7407,17 +7400,17 @@ function AccountPreparingSkeleton({
7407
7400
  onRetry
7408
7401
  }) {
7409
7402
  return /* @__PURE__ */ jsxs23("div", { className: "rs-step", children: [
7410
- /* @__PURE__ */ jsx28("div", { className: "rs-step-body", style: { paddingTop: 0 }, children: /* @__PURE__ */ jsx28("div", { className: "rs-loading-state", children: /* @__PURE__ */ jsx28("div", { className: "rs-loading-text", children: errorMessage ? /* @__PURE__ */ jsxs23(Fragment6, { children: [
7411
- /* @__PURE__ */ jsx28("div", { className: "rs-loading-title rs-text-error", children: "Couldn\u2019t prepare account" }),
7412
- /* @__PURE__ */ jsx28("div", { className: "rs-loading-subtitle", children: errorMessage })
7413
- ] }) : /* @__PURE__ */ jsx28("div", { className: "rs-loading-title", children: "Preparing\u2026" }) }) }) }),
7414
- errorMessage && onRetry && /* @__PURE__ */ jsx28("div", { className: "rs-step-footer", children: /* @__PURE__ */ jsx28(
7403
+ /* @__PURE__ */ jsx27("div", { className: "rs-step-body", style: { paddingTop: 0 }, children: /* @__PURE__ */ jsx27("div", { className: "rs-loading-state", children: /* @__PURE__ */ jsx27("div", { className: "rs-loading-text", children: errorMessage ? /* @__PURE__ */ jsxs23(Fragment6, { children: [
7404
+ /* @__PURE__ */ jsx27("div", { className: "rs-loading-title rs-text-error", children: "Couldn\u2019t prepare account" }),
7405
+ /* @__PURE__ */ jsx27("div", { className: "rs-loading-subtitle", children: errorMessage })
7406
+ ] }) : /* @__PURE__ */ jsx27("div", { className: "rs-loading-title", children: "Preparing\u2026" }) }) }) }),
7407
+ errorMessage && onRetry && /* @__PURE__ */ jsx27("div", { className: "rs-step-footer", children: /* @__PURE__ */ jsx27(
7415
7408
  "button",
7416
7409
  {
7417
7410
  type: "button",
7418
7411
  className: "rs-button rs-button--default rs-button--full-width",
7419
7412
  onClick: onRetry,
7420
- children: /* @__PURE__ */ jsx28("span", { children: "Try again" })
7413
+ children: /* @__PURE__ */ jsx27("span", { children: "Try again" })
7421
7414
  }
7422
7415
  ) })
7423
7416
  ] });
@@ -7501,7 +7494,8 @@ function deriveStep(flow, d, p, activeEntry, fiat, exchange) {
7501
7494
  type: "fiat-onramp",
7502
7495
  smartAccount: committedAccount,
7503
7496
  paymentMethod: fiat.selectedMethod ?? void 0,
7504
- methodSelectionSource: fiat.methodSelectionSource ?? void 0
7497
+ methodSelectionSource: fiat.methodSelectionSource ?? void 0,
7498
+ provider: fiat.selectedProvider ?? void 0
7505
7499
  };
7506
7500
  case "exchange-select":
7507
7501
  return { type: "exchange-select" };
@@ -7669,6 +7663,9 @@ function DepositFlow({
7669
7663
  initialAssetMigration,
7670
7664
  enableWallet = true,
7671
7665
  enableFiatOnramp = false,
7666
+ bankOnramp,
7667
+ onBankJourney,
7668
+ backendUrl,
7672
7669
  enableQrTransfer = true,
7673
7670
  enableGaslessDeposit = false,
7674
7671
  fiatMethods,
@@ -7710,19 +7707,27 @@ function DepositFlow({
7710
7707
  const [totalBalanceUsd, setTotalBalanceUsd] = useState13(0);
7711
7708
  const stableWalletSignerRef = useRef9(null);
7712
7709
  const stableWalletSelectionKeyRef = useRef9(null);
7713
- const logFlow = useCallback7(
7710
+ const logFlow = useCallback6(
7714
7711
  (message, data) => {
7715
7712
  debugLog(debug, "deposit-flow", message, data);
7716
7713
  },
7717
7714
  [debug]
7718
7715
  );
7719
- const logFlowError = useCallback7(
7716
+ const logFlowError = useCallback6(
7720
7717
  (message, error, data) => {
7721
7718
  debugError(debug, "deposit-flow", message, error, data);
7722
7719
  },
7723
7720
  [debug]
7724
7721
  );
7725
- const enableSwappedPreconnect = enableFiatOnramp || enableExchangeConnect;
7722
+ const bankOnrampEnabled = Boolean(
7723
+ bankOnramp && (fiatMethods === void 0 || fiatMethods["bank-transfer"] === true)
7724
+ );
7725
+ const hasSwappedFiatMethod = Boolean(
7726
+ enableFiatOnramp && (!fiatMethods || Object.entries(fiatMethods).some(
7727
+ ([method, enabled]) => enabled && !(bankOnrampEnabled && method === "bank-transfer")
7728
+ ))
7729
+ );
7730
+ const enableSwappedPreconnect = hasSwappedFiatMethod || enableExchangeConnect;
7726
7731
  useEffect13(() => {
7727
7732
  if (!enableSwappedPreconnect) return;
7728
7733
  if (typeof document === "undefined") return;
@@ -7797,11 +7802,14 @@ function DepositFlow({
7797
7802
  walletSession?.solanaAddress,
7798
7803
  walletSession?.caipAddress
7799
7804
  ]);
7800
- const offeredFiatMethods = useMemo8(
7801
- () => fiatMethods ? FIAT_ONRAMP_METHODS.filter((m) => fiatMethods[m.method]) : FIAT_ONRAMP_METHODS,
7805
+ const configuredFiatMethods = useMemo8(
7806
+ () => fiatMethods ? FIAT_ONRAMP_METHODS.filter(
7807
+ (m) => fiatMethods[m.method]
7808
+ ) : FIAT_ONRAMP_METHODS,
7802
7809
  [fiatMethods]
7803
7810
  );
7804
- const fiatEnabled = enableFiatOnramp && offeredFiatMethods.length > 0;
7811
+ const swappedFiatEnabled = enableFiatOnramp && configuredFiatMethods.length > 0;
7812
+ const fiatEnabled = bankOnrampEnabled || swappedFiatEnabled;
7805
7813
  const enabledAssetMigrationIds = useMemo8(
7806
7814
  () => Object.entries(assetMigrations ?? {}).filter(([, on]) => on).map(([id]) => id),
7807
7815
  [assetMigrations]
@@ -7841,27 +7849,23 @@ function DepositFlow({
7841
7849
  ]);
7842
7850
  const setupChainId = typeof targetChain === "number" && !isVirtualDestination(targetChain) ? targetChain : typeof defaultSourceChain === "number" ? defaultSourceChain : DEFAULT_SETUP_CHAIN_ID;
7843
7851
  const targetChainId = targetChainToChainId(targetChain);
7844
- const targetSymbol = getTargetTokenSymbol(targetToken, targetChainId);
7852
+ const targetDisplay = useTokenDisplay(targetChainId, targetToken);
7853
+ const targetSymbol = targetDisplay.symbol;
7845
7854
  const isTargetStablecoin = isStablecoinSymbol(targetSymbol);
7855
+ const assetStore = useAssetStore();
7846
7856
  const targetMarketPriceRef = useRef9(null);
7847
7857
  useEffect13(() => {
7848
7858
  targetMarketPriceRef.current = null;
7849
- if (isTargetStablecoin || targetSymbol === "Token") {
7850
- return;
7851
- }
7859
+ if (isTargetStablecoin || !assetStore) return;
7852
7860
  let cancelled = false;
7853
- fetchTokenPriceUsd(service, {
7854
- chainId: targetChainId,
7855
- address: targetToken,
7856
- symbol: targetSymbol
7857
- }).then((price) => {
7861
+ assetStore.resolvePrice({ chain: targetChainId, address: targetToken }).then((price) => {
7858
7862
  if (cancelled) return;
7859
7863
  targetMarketPriceRef.current = price;
7860
7864
  });
7861
7865
  return () => {
7862
7866
  cancelled = true;
7863
7867
  };
7864
- }, [service, targetSymbol, isTargetStablecoin, targetChain, targetToken]);
7868
+ }, [assetStore, isTargetStablecoin, targetChainId, targetToken]);
7865
7869
  const walletSignerContext = useMemo8(() => {
7866
7870
  if (flowMode === "deposit-address") {
7867
7871
  return null;
@@ -8063,7 +8067,7 @@ function DepositFlow({
8063
8067
  ]
8064
8068
  );
8065
8069
  const step = effectiveStep;
8066
- const handleBack = useCallback7(() => {
8070
+ const handleBack = useCallback6(() => {
8067
8071
  if ([
8068
8072
  "deposit-address",
8069
8073
  "select-asset",
@@ -8091,7 +8095,7 @@ function DepositFlow({
8091
8095
  hasWalletOptions,
8092
8096
  walletSession
8093
8097
  ]);
8094
- const handleProviderBack = useCallback7(() => {
8098
+ const handleProviderBack = useCallback6(() => {
8095
8099
  analytics.abandon("provider_back");
8096
8100
  analytics.resetAttempt(
8097
8101
  flowMode === "exchange-connect" ? "exchange_connect" : null
@@ -8101,7 +8105,7 @@ function DepositFlow({
8101
8105
  hasWalletOptions: hasWalletOptions || Boolean(walletSession)
8102
8106
  });
8103
8107
  }, [analytics, flowMode, storeApi, hasWalletOptions, walletSession]);
8104
- const handleWalletDisconnect = useCallback7(() => {
8108
+ const handleWalletDisconnect = useCallback6(() => {
8105
8109
  analytics.abandon("wallet_disconnect");
8106
8110
  analytics.resetAttempt();
8107
8111
  onDisconnect?.();
@@ -8116,11 +8120,14 @@ function DepositFlow({
8116
8120
  useEffect13(() => {
8117
8121
  setQrSourcePrice({ resolved: false, usd: null });
8118
8122
  if (!qrSourceAsset) return;
8123
+ if (!assetStore) {
8124
+ setQrSourcePrice({ resolved: true, usd: null });
8125
+ return;
8126
+ }
8119
8127
  let cancelled = false;
8120
- fetchTokenPriceUsd(service, {
8121
- chainId: qrSourceAsset.chainId,
8122
- address: qrSourceAsset.token,
8123
- symbol: qrSourceAsset.symbol
8128
+ assetStore.resolvePrice({
8129
+ chain: qrSourceAsset.chainId,
8130
+ address: qrSourceAsset.token
8124
8131
  }).then((usd) => {
8125
8132
  if (!cancelled) setQrSourcePrice({ resolved: true, usd });
8126
8133
  }).catch(() => {
@@ -8129,7 +8136,7 @@ function DepositFlow({
8129
8136
  return () => {
8130
8137
  cancelled = true;
8131
8138
  };
8132
- }, [service, qrSourceKey]);
8139
+ }, [assetStore, qrSourceKey]);
8133
8140
  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
8141
  // which drops the user out of the deposit entirely rather than back to
8135
8142
  // the address they came from.
@@ -8221,11 +8228,11 @@ function DepositFlow({
8221
8228
  const isDappImportMode = flowMode === "dapp-import";
8222
8229
  const isFiatOnrampMode = flowMode === "fiat-onramp";
8223
8230
  const isExchangeConnectMode = flowMode === "exchange-connect";
8224
- const handleSelectTransferCrypto = useCallback7(() => {
8231
+ const handleSelectTransferCrypto = useCallback6(() => {
8225
8232
  analytics.selectMethod("transfer", "user");
8226
8233
  storeApi.dispatch({ type: "connect/transfer-crypto-selected" });
8227
8234
  }, [analytics, storeApi]);
8228
- const handleConfirmWallet = useCallback7(
8235
+ const handleConfirmWallet = useCallback6(
8229
8236
  (walletId) => {
8230
8237
  const selectedOption = walletOptions.find((o) => o.id === walletId);
8231
8238
  const mode = selectedOption?.kind === "solana" ? "solana-wallet" : "wallet";
@@ -8251,10 +8258,12 @@ function DepositFlow({
8251
8258
  [assetMigrationsKey, isSolanaWalletConnected]
8252
8259
  );
8253
8260
  const initialAssetMigrationProvider = useMemo8(
8254
- () => initialAssetMigration ? enabledDappImportProviders.find((p) => p.id === initialAssetMigration) ?? null : null,
8261
+ () => initialAssetMigration ? enabledDappImportProviders.find(
8262
+ (p) => p.id === initialAssetMigration
8263
+ ) ?? null : null,
8255
8264
  [initialAssetMigration, enabledDappImportProviders]
8256
8265
  );
8257
- const handleSelectDappImport = useCallback7(
8266
+ const handleSelectDappImport = useCallback6(
8258
8267
  (providerId) => {
8259
8268
  const owner = dappImportOwner;
8260
8269
  if (owner) {
@@ -8278,7 +8287,7 @@ function DepositFlow({
8278
8287
  },
8279
8288
  [analytics, storeApi, walletOptions, dappImportOwner]
8280
8289
  );
8281
- const handleDappImportAssetSelected = useCallback7(
8290
+ const handleDappImportAssetSelected = useCallback6(
8282
8291
  (asset) => {
8283
8292
  storeApi.dispatch({ type: "dapp-import/asset-selected", asset });
8284
8293
  },
@@ -8498,11 +8507,8 @@ function DepositFlow({
8498
8507
  analytics,
8499
8508
  storeApi
8500
8509
  ]);
8501
- const handleBootRetry = useCallback7(() => {
8502
- analytics.retry(
8503
- "migration_availability_failed",
8504
- "migration_boot_resolve"
8505
- );
8510
+ const handleBootRetry = useCallback6(() => {
8511
+ analytics.retry("migration_availability_failed", "migration_boot_resolve");
8506
8512
  const snapshot = storeApi.getState();
8507
8513
  const providerId = snapshot.dappImport.activeProviderId;
8508
8514
  if (!providerId) return;
@@ -8525,29 +8531,34 @@ function DepositFlow({
8525
8531
  providerId
8526
8532
  });
8527
8533
  }, [analytics, storeApi, dappImportOwner]);
8528
- const handleSelectFiatMethod = useCallback7(
8529
- (paymentMethod, methodSelectionSource) => {
8534
+ const handleSelectFiatMethod = useCallback6(
8535
+ (paymentMethod, methodSelectionSource, provider = "swapped") => {
8530
8536
  analytics.selectMethod("fiat_onramp", "user", {
8531
8537
  payment_method: paymentMethod,
8532
- source: methodSelectionSource
8538
+ source: methodSelectionSource,
8539
+ provider
8533
8540
  });
8534
8541
  storeApi.dispatch({
8535
8542
  type: "connect/fiat-onramp-selected",
8536
8543
  paymentMethod,
8537
- methodSelectionSource
8544
+ methodSelectionSource,
8545
+ provider
8538
8546
  });
8539
8547
  },
8540
8548
  [analytics, storeApi]
8541
8549
  );
8542
- const handleSelectExchange = useCallback7(() => {
8550
+ const handleSelectExchange = useCallback6(() => {
8543
8551
  analytics.selectMethod("exchange_connect", "user");
8544
8552
  storeApi.dispatch({ type: "connect/exchange-selected" });
8545
8553
  }, [analytics, storeApi]);
8546
8554
  const swappedAnalyticsCorrelatorRef = useRef9(null);
8547
- const handleSwappedAttemptConsumed = useCallback7((externalCustomerId) => {
8548
- swappedAnalyticsCorrelatorRef.current = externalCustomerId;
8549
- }, []);
8550
- const handleSwappedProviderHandoff = useCallback7(() => {
8555
+ const handleSwappedAttemptConsumed = useCallback6(
8556
+ (externalCustomerId) => {
8557
+ swappedAnalyticsCorrelatorRef.current = externalCustomerId;
8558
+ },
8559
+ []
8560
+ );
8561
+ const handleSwappedProviderHandoff = useCallback6(() => {
8551
8562
  const externalCustomerId = swappedAnalyticsCorrelatorRef.current;
8552
8563
  if (!externalCustomerId) return;
8553
8564
  analytics.handoff(
@@ -8556,7 +8567,7 @@ function DepositFlow({
8556
8567
  flowMode === "exchange-connect" ? "exchange_provider_handoff" : "fiat_provider_handoff"
8557
8568
  );
8558
8569
  }, [analytics, flowMode]);
8559
- const handleSwappedRetry = useCallback7(() => {
8570
+ const handleSwappedRetry = useCallback6(() => {
8560
8571
  analytics.retry(
8561
8572
  "swapped_mint_failed",
8562
8573
  flowMode === "exchange-connect" ? "exchange_provider_mint" : "fiat_provider_mint"
@@ -8564,45 +8575,27 @@ function DepositFlow({
8564
8575
  swappedAnalyticsCorrelatorRef.current = null;
8565
8576
  }, [analytics, flowMode]);
8566
8577
  const swappedConnectUrlRef = useRef9(/* @__PURE__ */ new Map());
8567
- const acknowledgedConnectFeeRef = useRef9(/* @__PURE__ */ new Map());
8568
- const handleSelectExchangeConnection = useCallback7(
8569
- async (connection, disclosedFeeBps) => {
8578
+ const handleSelectExchangeConnection = useCallback6(
8579
+ async (connection) => {
8570
8580
  if (setupSlice.status !== "ready" || !setupSlice.smartAccount) {
8571
8581
  throw new Error("Deposit account is not ready");
8572
8582
  }
8573
8583
  const smartAccount = setupSlice.smartAccount;
8574
8584
  const owner = smartAccount.toLowerCase();
8575
8585
  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
- }
8586
+ const entry = swappedConnectUrlRef.current.get(key) ?? {
8587
+ smartAccount: owner,
8588
+ response: await service.getSwappedConnectUrl({
8589
+ smartAccount,
8590
+ connection
8591
+ })
8592
+ };
8593
8593
  const currentAccount = storeApi.getState().setup.smartAccount;
8594
8594
  if (currentAccount?.toLowerCase() !== owner) {
8595
8595
  swappedConnectUrlRef.current.delete(key);
8596
8596
  throw new Error("Deposit account changed. Select your exchange again.");
8597
8597
  }
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
8598
  swappedConnectUrlRef.current.set(key, entry);
8605
- acknowledgedConnectFeeRef.current.set(key, actualFeeBps);
8606
8599
  analytics.selectMethod("exchange_connect", "user", {
8607
8600
  exchange: connection
8608
8601
  });
@@ -8610,38 +8603,20 @@ function DepositFlow({
8610
8603
  type: "exchange/connection-selected",
8611
8604
  connection
8612
8605
  });
8613
- return actualFeeBps;
8614
8606
  },
8615
8607
  [analytics, service, setupSlice.status, setupSlice.smartAccount, storeApi]
8616
8608
  );
8617
- const loadSwappedConnectUrl = useCallback7(
8609
+ const loadSwappedConnectUrl = useCallback6(
8618
8610
  async (smartAccount, connection) => {
8619
8611
  const key = `${smartAccount.toLowerCase()}:${connection}`;
8620
8612
  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
8613
  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;
8614
+ return entry?.smartAccount === smartAccount.toLowerCase() ? entry.response : service.getSwappedConnectUrl({ smartAccount, connection });
8640
8615
  },
8641
8616
  [service]
8642
8617
  );
8643
8618
  const swappedUrlPrefetchRef = useRef9(/* @__PURE__ */ new Map());
8644
- const prefetchSwappedWidgetUrl = useCallback7(
8619
+ const prefetchSwappedWidgetUrl = useCallback6(
8645
8620
  (smartAccount, method, methodSelectionSource) => {
8646
8621
  const cache = swappedUrlPrefetchRef.current;
8647
8622
  const key = swappedWidgetPrefetchKey(method, methodSelectionSource);
@@ -8663,7 +8638,7 @@ function DepositFlow({
8663
8638
  },
8664
8639
  [service, logFlow]
8665
8640
  );
8666
- const consumeSwappedWidgetUrlPrefetch = useCallback7(
8641
+ const consumeSwappedWidgetUrlPrefetch = useCallback6(
8667
8642
  (smartAccount, method, methodSelectionSource) => {
8668
8643
  const cache = swappedUrlPrefetchRef.current;
8669
8644
  const key = swappedWidgetPrefetchKey(method, methodSelectionSource);
@@ -8675,7 +8650,7 @@ function DepositFlow({
8675
8650
  },
8676
8651
  []
8677
8652
  );
8678
- const handlePrefetchFiatMethod = useCallback7(
8653
+ const handlePrefetchFiatMethod = useCallback6(
8679
8654
  (method, methodSelectionSource) => {
8680
8655
  if (!fiatEnabled) return;
8681
8656
  if (setupSlice.status !== "ready" || !setupSlice.smartAccount) return;
@@ -8695,9 +8670,33 @@ function DepositFlow({
8695
8670
  useEffect13(() => {
8696
8671
  swappedUrlPrefetchRef.current.clear();
8697
8672
  swappedConnectUrlRef.current.clear();
8698
- acknowledgedConnectFeeRef.current.clear();
8699
8673
  }, [setupSlice.smartAccount]);
8700
8674
  const hasConfiguredFiatMethods = fiatMethods !== void 0;
8675
+ const [providers, setProviders] = useState13("loading");
8676
+ useEffect13(() => {
8677
+ if (!enableFiatOnramp && !bankOnrampEnabled && !enableExchangeConnect) {
8678
+ return;
8679
+ }
8680
+ let settled = false;
8681
+ const settle = (list) => {
8682
+ if (settled) return;
8683
+ settled = true;
8684
+ clearTimeout(timer);
8685
+ setProviders(list);
8686
+ };
8687
+ setProviders("loading");
8688
+ const timer = setTimeout(() => settle(null), REGIONAL_METHODS_TIMEOUT_MS);
8689
+ void service.getOnrampProviders().then(settle);
8690
+ return () => {
8691
+ settled = true;
8692
+ clearTimeout(timer);
8693
+ };
8694
+ }, [bankOnrampEnabled, enableExchangeConnect, enableFiatOnramp, service]);
8695
+ const providersLoading = providers === "loading";
8696
+ const offers = (provider, kind) => providers === null || providers !== "loading" && providers.some((p) => p.provider === provider && p.kinds.includes(kind));
8697
+ const swappedFiatOffered = offers("swapped", "fiat");
8698
+ const noahOffered = offers("noah", "fiat");
8699
+ const exchangeOffered = enableExchangeConnect && offers("swapped", "exchange");
8701
8700
  const [regionalMethods, setRegionalMethods] = useState13({
8702
8701
  status: "loading",
8703
8702
  country: null,
@@ -8705,7 +8704,7 @@ function DepositFlow({
8705
8704
  recommendedMethod: null
8706
8705
  });
8707
8706
  useEffect13(() => {
8708
- if (!fiatEnabled || hasConfiguredFiatMethods) return;
8707
+ if (!enableFiatOnramp || hasConfiguredFiatMethods) return;
8709
8708
  let cancelled = false;
8710
8709
  setRegionalMethods({
8711
8710
  status: "loading",
@@ -8743,24 +8742,57 @@ function DepositFlow({
8743
8742
  cancelled = true;
8744
8743
  clearTimeout(timeoutTimer);
8745
8744
  };
8746
- }, [analytics, fiatEnabled, hasConfiguredFiatMethods, service]);
8745
+ }, [analytics, enableFiatOnramp, hasConfiguredFiatMethods, service]);
8746
+ const swappedCashDisplay = useMemo8(
8747
+ () => !enableFiatOnramp || !swappedFiatOffered ? { kind: "hidden" } : hasConfiguredFiatMethods ? {
8748
+ kind: "list",
8749
+ methods: configuredFiatMethods,
8750
+ recommendedMethod: configuredFiatMethods[0]?.method ?? "bank-transfer",
8751
+ country: null,
8752
+ source: "configured"
8753
+ } : composeFiatMethods(regionalMethods, FIAT_ONRAMP_METHODS),
8754
+ [
8755
+ configuredFiatMethods,
8756
+ enableFiatOnramp,
8757
+ hasConfiguredFiatMethods,
8758
+ regionalMethods,
8759
+ swappedFiatOffered
8760
+ ]
8761
+ );
8762
+ const swappedOffersBank = swappedCashDisplay.kind === "list" && swappedCashDisplay.methods.some(({ method }) => method === "bank-transfer");
8763
+ const [bankOnrampUnavailable, setBankOnrampUnavailable] = useState13(false);
8764
+ const bankRowOffered = bankOnrampEnabled && noahOffered && !bankOnrampUnavailable;
8765
+ const swappedRefusesBank = hasConfiguredFiatMethods ? !configuredFiatMethods.some(({ method }) => method === "bank-transfer") : regionalMethods.status === "ready" && regionalMethods.country !== null && !regionalMethods.methods.some(({ method }) => method === "bank-transfer");
8766
+ const handleBankOnrampUnavailable = useCallback6(() => {
8767
+ setBankOnrampUnavailable(true);
8768
+ if (swappedRefusesBank) handleProviderBack();
8769
+ }, [handleProviderBack, swappedRefusesBank]);
8747
8770
  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
- };
8771
+ if (providersLoading && fiatEnabled) return { kind: "loading" };
8772
+ const swappedDisplay = swappedCashDisplay;
8773
+ if (!bankRowOffered || swappedDisplay.kind === "loading") {
8774
+ return swappedDisplay;
8775
+ }
8776
+ const asNoah = (m) => m.method === "bank-transfer" ? { ...m, provider: "noah" } : m;
8777
+ if (swappedOffersBank && swappedDisplay.kind === "list") {
8778
+ return { ...swappedDisplay, methods: swappedDisplay.methods.map(asNoah) };
8757
8779
  }
8758
- return composeFiatMethods(regionalMethods, FIAT_ONRAMP_METHODS);
8780
+ const bankTransfer = asNoah(
8781
+ FIAT_ONRAMP_METHODS.find(({ method }) => method === "bank-transfer")
8782
+ );
8783
+ return {
8784
+ kind: "list",
8785
+ methods: swappedDisplay.kind === "list" ? [...swappedDisplay.methods, bankTransfer] : [bankTransfer],
8786
+ recommendedMethod: swappedDisplay.kind === "list" ? swappedDisplay.recommendedMethod : bankTransfer.method,
8787
+ country: swappedDisplay.kind === "list" ? swappedDisplay.country : null,
8788
+ source: swappedDisplay.kind === "list" ? swappedDisplay.source : "configured"
8789
+ };
8759
8790
  }, [
8791
+ bankRowOffered,
8760
8792
  fiatEnabled,
8761
- hasConfiguredFiatMethods,
8762
- offeredFiatMethods,
8763
- regionalMethods
8793
+ providersLoading,
8794
+ swappedCashDisplay,
8795
+ swappedOffersBank
8764
8796
  ]);
8765
8797
  useEffect13(() => {
8766
8798
  if (cashDisplay.kind === "hidden" && fiatEnabled) {
@@ -8776,21 +8808,25 @@ function DepositFlow({
8776
8808
  }
8777
8809
  }, [analytics, cashDisplay, fiatEnabled, hasConfiguredFiatMethods]);
8778
8810
  const displayedFiatSource = cashDisplay.kind === "list" ? cashDisplay.source : void 0;
8779
- const handleSelectDisplayedFiatMethod = useCallback7(
8811
+ const providerOf = useCallback6(
8812
+ (method) => cashDisplay.kind === "list" && cashDisplay.methods.find((m) => m.method === method)?.provider || "swapped",
8813
+ [cashDisplay]
8814
+ );
8815
+ const handleSelectDisplayedFiatMethod = useCallback6(
8780
8816
  (method) => {
8781
8817
  if (!displayedFiatSource) return;
8782
- handleSelectFiatMethod(method, displayedFiatSource);
8818
+ handleSelectFiatMethod(method, displayedFiatSource, providerOf(method));
8783
8819
  },
8784
- [displayedFiatSource, handleSelectFiatMethod]
8820
+ [displayedFiatSource, handleSelectFiatMethod, providerOf]
8785
8821
  );
8786
- const handlePrefetchDisplayedFiatMethod = useCallback7(
8822
+ const handlePrefetchDisplayedFiatMethod = useCallback6(
8787
8823
  (method) => {
8788
- if (!displayedFiatSource) return;
8824
+ if (!displayedFiatSource || providerOf(method) !== "swapped") return;
8789
8825
  handlePrefetchFiatMethod(method, displayedFiatSource);
8790
8826
  },
8791
- [displayedFiatSource, handlePrefetchFiatMethod]
8827
+ [displayedFiatSource, handlePrefetchFiatMethod, providerOf]
8792
8828
  );
8793
- const handleNewDeposit = useCallback7(() => {
8829
+ const handleNewDeposit = useCallback6(() => {
8794
8830
  analytics.completeStep();
8795
8831
  analytics.resetAttempt();
8796
8832
  onLifecycleRef.current?.({
@@ -8803,7 +8839,6 @@ function DepositFlow({
8803
8839
  stableWalletSelectionKeyRef.current = null;
8804
8840
  swappedUrlPrefetchRef.current.clear();
8805
8841
  swappedConnectUrlRef.current.clear();
8806
- acknowledgedConnectFeeRef.current.clear();
8807
8842
  lastSmartAccountLifecycleKeyRef.current = null;
8808
8843
  }, [analytics, onLifecycleRef, storeApi]);
8809
8844
  const setupInput = useMemo8(
@@ -8939,7 +8974,7 @@ function DepositFlow({
8939
8974
  })();
8940
8975
  });
8941
8976
  }, [desiredPortfolios, service, storeApi, portfolioSlice.byKey]);
8942
- const handleDepositAddressSubmitted = useCallback7(
8977
+ const handleDepositAddressSubmitted = useCallback6(
8943
8978
  (data) => {
8944
8979
  logFlow("deposit-address:detected", {
8945
8980
  txHash: data.txHash,
@@ -8954,7 +8989,7 @@ function DepositFlow({
8954
8989
  },
8955
8990
  [analytics, logFlow, onLifecycleRef]
8956
8991
  );
8957
- const handleSolanaTokenContinue = useCallback7(
8992
+ const handleSolanaTokenContinue = useCallback6(
8958
8993
  (token, balance, balanceUsd) => {
8959
8994
  logFlow("solana:token:continue", { token: token.symbol });
8960
8995
  storeApi.dispatch({
@@ -8967,16 +9002,14 @@ function DepositFlow({
8967
9002
  },
8968
9003
  [defaultAmount, logFlow, storeApi]
8969
9004
  );
8970
- const handleSolanaAmountContinue = useCallback7(
9005
+ const handleSolanaAmountContinue = useCallback6(
8971
9006
  (token, sourceAmount, inputAmountUsd) => {
8972
- const targetSym = getTargetTokenSymbol(targetToken, targetChainId);
8973
- const isTargetStable = isStablecoinSymbol(targetSym);
8974
- const targetTokenPriceUsd = isTargetStable ? 1 : targetMarketPriceRef.current;
9007
+ const targetTokenPriceUsd = isTargetStablecoin ? 1 : targetMarketPriceRef.current;
8975
9008
  logFlow("solana:amount:continue", {
8976
9009
  token: token.symbol,
8977
9010
  sourceAmount,
8978
9011
  inputAmountUsd,
8979
- targetSymbol: targetSym,
9012
+ targetSymbol,
8980
9013
  targetTokenPriceUsd
8981
9014
  });
8982
9015
  storeApi.dispatch({
@@ -8987,9 +9020,9 @@ function DepositFlow({
8987
9020
  targetTokenPriceUsd
8988
9021
  });
8989
9022
  },
8990
- [targetToken, targetChain, logFlow, storeApi]
9023
+ [isTargetStablecoin, targetSymbol, logFlow, storeApi]
8991
9024
  );
8992
- const handleSolanaConfirmed = useCallback7(
9025
+ const handleSolanaConfirmed = useCallback6(
8993
9026
  (txHash, amountUnits, routed) => {
8994
9027
  const depositAtSubmit = storeApi.getState().deposit;
8995
9028
  const tokenAtSubmit = depositAtSubmit.selectedSolanaToken;
@@ -9030,7 +9063,7 @@ function DepositFlow({
9030
9063
  },
9031
9064
  [analytics, logFlow, onLifecycleRef, storeApi]
9032
9065
  );
9033
- const handleAssetContinue = useCallback7(
9066
+ const handleAssetContinue = useCallback6(
9034
9067
  (asset) => {
9035
9068
  analytics.completeStep("wallet_source_asset");
9036
9069
  storeApi.dispatch({
@@ -9041,13 +9074,11 @@ function DepositFlow({
9041
9074
  },
9042
9075
  [analytics, defaultAmount, storeApi]
9043
9076
  );
9044
- const handleAmountContinue = useCallback7(
9077
+ const handleAmountContinue = useCallback6(
9045
9078
  (amount, targetAmount, balance) => {
9046
9079
  const entry = storeApi.getState().setup;
9047
9080
  if (entry.status !== "ready") return;
9048
- const targetSym = getTargetTokenSymbol(targetToken, targetChainId);
9049
- const isTargetStable = isStablecoinSymbol(targetSym);
9050
- const targetTokenPriceUsd = isTargetStable ? 1 : targetMarketPriceRef.current;
9081
+ const targetTokenPriceUsd = isTargetStablecoin ? 1 : targetMarketPriceRef.current;
9051
9082
  storeApi.dispatch({
9052
9083
  type: "amount/entered",
9053
9084
  amount,
@@ -9056,18 +9087,17 @@ function DepositFlow({
9056
9087
  balance
9057
9088
  });
9058
9089
  },
9059
- [targetToken, targetChain, storeApi, activeOwner]
9090
+ [isTargetStablecoin, storeApi, activeOwner]
9060
9091
  );
9061
- const handleQrReviewRequested = useCallback7(
9092
+ const handleQrReviewRequested = useCallback6(
9062
9093
  (asset) => {
9063
9094
  storeApi.dispatch({ type: "qr/review-requested", asset });
9064
9095
  },
9065
9096
  [storeApi]
9066
9097
  );
9067
- const handleQrAmountContinue = useCallback7(
9098
+ const handleQrAmountContinue = useCallback6(
9068
9099
  (amount, targetAmount) => {
9069
- const targetSym = getTargetTokenSymbol(targetToken, targetChainId);
9070
- const targetTokenPriceUsd = isStablecoinSymbol(targetSym) ? 1 : targetMarketPriceRef.current;
9100
+ const targetTokenPriceUsd = isTargetStablecoin ? 1 : targetMarketPriceRef.current;
9071
9101
  storeApi.dispatch({
9072
9102
  type: "qr/amount-entered",
9073
9103
  amount,
@@ -9075,9 +9105,9 @@ function DepositFlow({
9075
9105
  targetTokenPriceUsd
9076
9106
  });
9077
9107
  },
9078
- [targetToken, targetChainId, storeApi]
9108
+ [isTargetStablecoin, storeApi]
9079
9109
  );
9080
- const handleDepositSubmitted = useCallback7(
9110
+ const handleDepositSubmitted = useCallback6(
9081
9111
  (txHash, chainId, amount, token, quote, routed) => {
9082
9112
  logFlow("evm:submitted", {
9083
9113
  txHash,
@@ -9123,7 +9153,7 @@ function DepositFlow({
9123
9153
  },
9124
9154
  [analytics, flowMode, logFlow, storeApi]
9125
9155
  );
9126
- const handleSwappedComplete = useCallback7(
9156
+ const handleSwappedComplete = useCallback6(
9127
9157
  (info) => {
9128
9158
  logFlow("swapped:complete", {
9129
9159
  txHash: info.txHash,
@@ -9180,7 +9210,7 @@ function DepositFlow({
9180
9210
  },
9181
9211
  [logFlow, onLifecycleRef, service, storeApi]
9182
9212
  );
9183
- const handleDepositSubmittedCallback = useCallback7(
9213
+ const handleDepositSubmittedCallback = useCallback6(
9184
9214
  (txHash, sourceChain, amount) => {
9185
9215
  const depositAtSubmit = storeApi.getState().deposit;
9186
9216
  onLifecycleRef.current?.({
@@ -9194,7 +9224,7 @@ function DepositFlow({
9194
9224
  },
9195
9225
  [onLifecycleRef, storeApi]
9196
9226
  );
9197
- const handleDepositComplete = useCallback7(
9227
+ const handleDepositComplete = useCallback6(
9198
9228
  (txHash, destinationTxHash, context) => {
9199
9229
  logFlow("deposit:complete", { txHash, destinationTxHash, ...context });
9200
9230
  analytics.openStep(
@@ -9210,7 +9240,7 @@ function DepositFlow({
9210
9240
  },
9211
9241
  [analytics, analyticsMethod, logFlow, onLifecycleRef]
9212
9242
  );
9213
- const handleDepositFailed = useCallback7(
9243
+ const handleDepositFailed = useCallback6(
9214
9244
  (txHash, error) => {
9215
9245
  logFlowError("deposit:failed", error, { txHash });
9216
9246
  analytics.openStep(
@@ -9222,16 +9252,13 @@ function DepositFlow({
9222
9252
  },
9223
9253
  [analytics, analyticsMethod, logFlowError, onLifecycleRef]
9224
9254
  );
9225
- const handleError = useCallback7(
9255
+ const handleError = useCallback6(
9226
9256
  (message, code, cause) => {
9227
9257
  logFlowError("flow:error", cause ?? message, { code });
9228
9258
  if (code === "PROCESS_TIMEOUT") {
9229
9259
  analytics.friction("processor_status_poll_failed");
9230
9260
  } else {
9231
- const reason = failureReasonForCode(
9232
- code,
9233
- `${message} ${cause ?? ""}`
9234
- );
9261
+ const reason = failureReasonForCode(code, `${message} ${cause ?? ""}`);
9235
9262
  const failureStep = code === "SWAPPED_URL_FAILED" ? "fiat_provider_mint" : code === "SWAPPED_CONNECT_URL_FAILED" ? "exchange_provider_mint" : void 0;
9236
9263
  analytics.failure(
9237
9264
  reason,
@@ -9239,11 +9266,15 @@ function DepositFlow({
9239
9266
  failureStep
9240
9267
  );
9241
9268
  }
9242
- onErrorRef.current?.({ message, code, cause });
9269
+ onErrorRef.current?.({
9270
+ message,
9271
+ code,
9272
+ ...cause === void 0 ? {} : { cause }
9273
+ });
9243
9274
  },
9244
9275
  [analytics, logFlowError, onErrorRef]
9245
9276
  );
9246
- const handleTotalBalanceComputed = useCallback7((total) => {
9277
+ const handleTotalBalanceComputed = useCallback6((total) => {
9247
9278
  setTotalBalanceUsd(total);
9248
9279
  }, []);
9249
9280
  useEffect13(() => {
@@ -9296,12 +9327,12 @@ function DepositFlow({
9296
9327
  }, [enableWallet, walletOptions, setupSlice, portfolioSlice]);
9297
9328
  const transferCryptoEntry = setupSlice;
9298
9329
  const transferCryptoState = transferCryptoEntry.status === "ready" ? "ready" : transferCryptoEntry.status === "error" ? "error" : "loading";
9299
- const handleRetrySetup = useCallback7(() => {
9330
+ const handleRetrySetup = useCallback6(() => {
9300
9331
  analytics.retry("account_setup_failed", "account_setup");
9301
9332
  storeApi.dispatch({ type: "setup/retry-requested" });
9302
9333
  }, [analytics, storeApi]);
9303
9334
  if (showConnectStep) {
9304
- return /* @__PURE__ */ jsx28("div", { className: "rs-modal-body", children: /* @__PURE__ */ jsx28(
9335
+ return /* @__PURE__ */ jsx27("div", { className: "rs-modal-body", children: /* @__PURE__ */ jsx27(
9305
9336
  ConnectStep,
9306
9337
  {
9307
9338
  title: payment ? "Pay" : void 0,
@@ -9323,10 +9354,12 @@ function DepositFlow({
9323
9354
  ),
9324
9355
  fiatPaymentMethods: cashDisplay.kind === "list" ? cashDisplay.methods : void 0,
9325
9356
  fiatLoading: cashDisplay.kind === "loading",
9357
+ fiatNotice: bankOnrampUnavailable && swappedRefusesBank ? "Bank transfer isn't available in your region." : void 0,
9326
9358
  recommendedMethod: cashDisplay.kind === "list" ? cashDisplay.recommendedMethod : void 0,
9327
9359
  onSelectFiatMethod: cashDisplay.kind === "list" ? handleSelectDisplayedFiatMethod : void 0,
9328
9360
  onPrefetchFiatMethod: cashDisplay.kind === "list" ? handlePrefetchDisplayedFiatMethod : void 0,
9329
- onSelectFundFromExchange: enableExchangeConnect ? () => handleSelectExchange() : void 0,
9361
+ onSelectFundFromExchange: exchangeOffered || enableExchangeConnect && providersLoading ? () => handleSelectExchange() : void 0,
9362
+ fundFromExchangeLoading: enableExchangeConnect && providersLoading,
9330
9363
  onRequestConnect: enableWallet ? onRequestConnect : void 0,
9331
9364
  onConnect: enableWallet ? onConnect : void 0,
9332
9365
  onDisconnect,
@@ -9359,19 +9392,14 @@ function DepositFlow({
9359
9392
  }
9360
9393
  if (isDepositAddressMode) {
9361
9394
  return /* @__PURE__ */ jsxs23("div", { className: "rs-modal-body", children: [
9362
- effectiveStep.type === "setup" && (activeEntry.status === "error" ? /* @__PURE__ */ jsx28(
9395
+ effectiveStep.type === "setup" && (activeEntry.status === "error" ? /* @__PURE__ */ jsx27(
9363
9396
  AccountPreparingSkeleton,
9364
9397
  {
9365
9398
  errorMessage: activeEntry.message ?? void 0,
9366
9399
  onRetry: () => handleRetrySetup()
9367
9400
  }
9368
- ) : /* @__PURE__ */ jsx28(
9369
- DepositAddressSkeleton,
9370
- {
9371
- uiConfig
9372
- }
9373
- )),
9374
- effectiveStep.type === "deposit-address" && /* @__PURE__ */ jsx28(
9401
+ ) : /* @__PURE__ */ jsx27(DepositAddressSkeleton, { uiConfig })),
9402
+ effectiveStep.type === "deposit-address" && /* @__PURE__ */ jsx27(
9375
9403
  DepositAddressStep,
9376
9404
  {
9377
9405
  payment,
@@ -9416,7 +9444,7 @@ function DepositFlow({
9416
9444
  debug
9417
9445
  }
9418
9446
  ),
9419
- effectiveStep.type === "qr-amount" && /* @__PURE__ */ jsx28(
9447
+ effectiveStep.type === "qr-amount" && /* @__PURE__ */ jsx27(
9420
9448
  AmountStep,
9421
9449
  {
9422
9450
  asset: effectiveStep.asset,
@@ -9432,7 +9460,7 @@ function DepositFlow({
9432
9460
  onContinue: handleQrAmountContinue
9433
9461
  }
9434
9462
  ),
9435
- effectiveStep.type === "qr-review" && /* @__PURE__ */ jsx28(
9463
+ effectiveStep.type === "qr-review" && /* @__PURE__ */ jsx27(
9436
9464
  QrReviewStep,
9437
9465
  {
9438
9466
  smartAccount: effectiveStep.smartAccount,
@@ -9448,6 +9476,20 @@ function DepositFlow({
9448
9476
  )
9449
9477
  ] });
9450
9478
  }
9479
+ const rampCallbacks = {
9480
+ service,
9481
+ onSwappedComplete: handleSwappedComplete,
9482
+ onSwappedFailed: handleDepositFailed,
9483
+ onClose: () => onClose?.(openExternally ? "native_dismiss_request" : "header_button"),
9484
+ onGoBack: handleProviderBack,
9485
+ onError: handleError,
9486
+ onAttemptConsumed: handleSwappedAttemptConsumed,
9487
+ onProviderHandoff: handleSwappedProviderHandoff,
9488
+ onRetry: handleSwappedRetry,
9489
+ onCancelled: () => analytics.outcome("cancelled"),
9490
+ onImmersiveChange: onSwappedImmersiveChange,
9491
+ openExternally
9492
+ };
9451
9493
  if (isFiatOnrampMode) {
9452
9494
  return /* @__PURE__ */ jsxs23(
9453
9495
  "div",
@@ -9456,37 +9498,34 @@ function DepositFlow({
9456
9498
  "data-flow-mode": "fiat-onramp",
9457
9499
  "data-step-type": step.type,
9458
9500
  children: [
9459
- step.type === "setup" && /* @__PURE__ */ jsx28(
9501
+ step.type === "setup" && /* @__PURE__ */ jsx27(
9460
9502
  AccountPreparingSkeleton,
9461
9503
  {
9462
9504
  errorMessage: activeEntry.status === "error" ? activeEntry.message ?? void 0 : void 0,
9463
9505
  onRetry: activeEntry.status === "error" ? () => handleRetrySetup() : void 0
9464
9506
  }
9465
9507
  ),
9466
- step.type === "fiat-onramp" && /* @__PURE__ */ jsx28(
9467
- FiatOnrampStep,
9508
+ step.type === "fiat-onramp" && /* @__PURE__ */ jsx27(Suspense2, { fallback: /* @__PURE__ */ jsx27(AccountPreparingSkeleton, {}), children: /* @__PURE__ */ jsx27(
9509
+ RampOrderStep,
9468
9510
  {
9511
+ ...rampCallbacks,
9469
9512
  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
- ),
9479
- onGoBack: handleProviderBack,
9480
- onError: handleError,
9481
- onAttemptConsumed: handleSwappedAttemptConsumed,
9482
- onProviderHandoff: handleSwappedProviderHandoff,
9483
- onRetry: handleSwappedRetry,
9484
- onCancelled: () => analytics.outcome("cancelled"),
9485
- onImmersiveChange: onSwappedImmersiveChange,
9486
- openExternally
9513
+ order: step.provider === "noah" && bankRowOffered && bankOnramp ? {
9514
+ flow: "funding_account",
9515
+ backendUrl,
9516
+ bankOnramp,
9517
+ onJourney: onBankJourney,
9518
+ onUnavailable: handleBankOnrampUnavailable
9519
+ } : {
9520
+ flow: "hosted",
9521
+ kind: "fiat",
9522
+ method: step.paymentMethod,
9523
+ methodSelectionSource: step.methodSelectionSource,
9524
+ consumePrefetchedUrl: consumeSwappedWidgetUrlPrefetch
9525
+ }
9487
9526
  }
9488
- ),
9489
- step.type === "processing" && /* @__PURE__ */ jsx28(
9527
+ ) }),
9528
+ step.type === "processing" && /* @__PURE__ */ jsx27(
9490
9529
  ProcessingStep,
9491
9530
  {
9492
9531
  flowLabel: payment ? "payment" : void 0,
@@ -9530,14 +9569,14 @@ function DepositFlow({
9530
9569
  "data-flow-mode": "exchange-connect",
9531
9570
  "data-step-type": step.type,
9532
9571
  children: [
9533
- step.type === "setup" && /* @__PURE__ */ jsx28(
9572
+ step.type === "setup" && /* @__PURE__ */ jsx27(
9534
9573
  AccountPreparingSkeleton,
9535
9574
  {
9536
9575
  errorMessage: activeEntry.status === "error" ? activeEntry.message ?? void 0 : void 0,
9537
9576
  onRetry: activeEntry.status === "error" ? () => handleRetrySetup() : void 0
9538
9577
  }
9539
9578
  ),
9540
- step.type === "exchange-select" && /* @__PURE__ */ jsx28(
9579
+ step.type === "exchange-select" && /* @__PURE__ */ jsx27(
9541
9580
  ExchangeSelectStep,
9542
9581
  {
9543
9582
  service,
@@ -9545,29 +9584,20 @@ function DepositFlow({
9545
9584
  onError: handleError
9546
9585
  }
9547
9586
  ),
9548
- step.type === "exchange-connect" && /* @__PURE__ */ jsx28(
9549
- ExchangeConnectStep,
9587
+ step.type === "exchange-connect" && /* @__PURE__ */ jsx27(
9588
+ RampOrderStep,
9550
9589
  {
9590
+ ...rampCallbacks,
9551
9591
  smartAccount: step.smartAccount,
9552
- service,
9553
- connection: step.connection,
9554
- loadUrl: () => loadSwappedConnectUrl(step.smartAccount, step.connection),
9555
- onSwappedComplete: handleSwappedComplete,
9556
- onSwappedFailed: handleDepositFailed,
9557
- onClose: () => onClose?.(
9558
- openExternally ? "native_dismiss_request" : "header_button"
9559
- ),
9560
- onGoBack: handleProviderBack,
9561
- onError: handleError,
9562
- onAttemptConsumed: handleSwappedAttemptConsumed,
9563
- onProviderHandoff: handleSwappedProviderHandoff,
9564
- onRetry: handleSwappedRetry,
9565
- onCancelled: () => analytics.outcome("cancelled"),
9566
- onImmersiveChange: onSwappedImmersiveChange,
9567
- openExternally
9592
+ order: {
9593
+ flow: "hosted",
9594
+ kind: "exchange",
9595
+ connection: step.connection,
9596
+ loadPreparedUrl: () => loadSwappedConnectUrl(step.smartAccount, step.connection)
9597
+ }
9568
9598
  }
9569
9599
  ),
9570
- step.type === "processing" && /* @__PURE__ */ jsx28(
9600
+ step.type === "processing" && /* @__PURE__ */ jsx27(
9571
9601
  ProcessingStep,
9572
9602
  {
9573
9603
  flowLabel: payment ? "payment" : void 0,
@@ -9607,14 +9637,14 @@ function DepositFlow({
9607
9637
  const solanaAddr = walletSession?.solanaAddress;
9608
9638
  const solanaProvider = walletSession?.solanaProvider;
9609
9639
  return /* @__PURE__ */ jsxs23("div", { className: "rs-modal-body", children: [
9610
- effectiveStep.type === "setup" && /* @__PURE__ */ jsx28(
9640
+ effectiveStep.type === "setup" && /* @__PURE__ */ jsx27(
9611
9641
  AccountPreparingSkeleton,
9612
9642
  {
9613
9643
  errorMessage: activeEntry.status === "error" ? activeEntry.message ?? void 0 : void 0,
9614
9644
  onRetry: activeEntry.status === "error" ? () => handleRetrySetup() : void 0
9615
9645
  }
9616
9646
  ),
9617
- effectiveStep.type === "solana-token-select" && solanaAddr && /* @__PURE__ */ jsx28(
9647
+ effectiveStep.type === "solana-token-select" && solanaAddr && /* @__PURE__ */ jsx27(
9618
9648
  SolanaTokenSelectStep,
9619
9649
  {
9620
9650
  solanaAddress: solanaAddr,
@@ -9625,7 +9655,7 @@ function DepositFlow({
9625
9655
  debug
9626
9656
  }
9627
9657
  ),
9628
- effectiveStep.type === "solana-amount" && /* @__PURE__ */ jsx28(
9658
+ effectiveStep.type === "solana-amount" && /* @__PURE__ */ jsx27(
9629
9659
  SolanaAmountStep,
9630
9660
  {
9631
9661
  token: effectiveStep.token,
@@ -9635,13 +9665,14 @@ function DepositFlow({
9635
9665
  uiConfig,
9636
9666
  targetChain,
9637
9667
  targetChainName: getChainName(targetChainId),
9638
- targetTokenSymbol: getTargetTokenSymbol(targetToken, targetChainId),
9668
+ targetTokenSymbol: targetSymbol,
9669
+ targetToken: { chain: targetChainId, address: targetToken },
9639
9670
  appBalanceUsd,
9640
9671
  onContinue: handleSolanaAmountContinue,
9641
9672
  debug
9642
9673
  }
9643
9674
  ),
9644
- effectiveStep.type === "solana-confirm" && solanaAddr && solanaProvider ? /* @__PURE__ */ jsx28(
9675
+ effectiveStep.type === "solana-confirm" && solanaAddr && solanaProvider ? /* @__PURE__ */ jsx27(
9645
9676
  SolanaConfirmStep,
9646
9677
  {
9647
9678
  smartAccount: effectiveStep.smartAccount,
@@ -9665,14 +9696,14 @@ function DepositFlow({
9665
9696
  }
9666
9697
  ) : effectiveStep.type === "solana-confirm" ? /* @__PURE__ */ jsxs23("div", { className: "rs-step", children: [
9667
9698
  /* @__PURE__ */ jsxs23("div", { className: "rs-loading-state", children: [
9668
- /* @__PURE__ */ jsx28("div", { className: "rs-step-icon rs-step-icon--error", children: /* @__PURE__ */ jsx28(
9699
+ /* @__PURE__ */ jsx27("div", { className: "rs-step-icon rs-step-icon--error", children: /* @__PURE__ */ jsx27(
9669
9700
  "svg",
9670
9701
  {
9671
9702
  viewBox: "0 0 24 24",
9672
9703
  fill: "none",
9673
9704
  stroke: "currentColor",
9674
9705
  strokeWidth: "2",
9675
- children: /* @__PURE__ */ jsx28(
9706
+ children: /* @__PURE__ */ jsx27(
9676
9707
  "path",
9677
9708
  {
9678
9709
  strokeLinecap: "round",
@@ -9683,21 +9714,21 @@ function DepositFlow({
9683
9714
  }
9684
9715
  ) }),
9685
9716
  /* @__PURE__ */ jsxs23("div", { className: "rs-loading-text", children: [
9686
- /* @__PURE__ */ jsx28("div", { className: "rs-loading-title rs-text-error", children: "Wallet disconnected" }),
9687
- /* @__PURE__ */ jsx28("div", { className: "rs-loading-subtitle", children: "Please reconnect your Solana wallet to continue." })
9717
+ /* @__PURE__ */ jsx27("div", { className: "rs-loading-title rs-text-error", children: "Wallet disconnected" }),
9718
+ /* @__PURE__ */ jsx27("div", { className: "rs-loading-subtitle", children: "Please reconnect your Solana wallet to continue." })
9688
9719
  ] })
9689
9720
  ] }),
9690
- /* @__PURE__ */ jsx28("div", { className: "rs-step-footer", children: /* @__PURE__ */ jsx28(
9721
+ /* @__PURE__ */ jsx27("div", { className: "rs-step-footer", children: /* @__PURE__ */ jsx27(
9691
9722
  "button",
9692
9723
  {
9693
9724
  type: "button",
9694
9725
  className: "rs-button rs-button--default rs-button--full-width",
9695
9726
  onClick: handleBack,
9696
- children: /* @__PURE__ */ jsx28("span", { children: "Go Back" })
9727
+ children: /* @__PURE__ */ jsx27("span", { children: "Go Back" })
9697
9728
  }
9698
9729
  ) })
9699
9730
  ] }) : null,
9700
- effectiveStep.type === "processing" && /* @__PURE__ */ jsx28(
9731
+ effectiveStep.type === "processing" && /* @__PURE__ */ jsx27(
9701
9732
  ProcessingStep,
9702
9733
  {
9703
9734
  flowLabel: payment ? "payment" : void 0,
@@ -9729,13 +9760,13 @@ function DepositFlow({
9729
9760
  ] });
9730
9761
  }
9731
9762
  if (isDappImportMode && effectiveStep.type === "dapp-import-resolving") {
9732
- return /* @__PURE__ */ jsx28(
9763
+ return /* @__PURE__ */ jsx27(
9733
9764
  "div",
9734
9765
  {
9735
9766
  className: "rs-modal-body",
9736
9767
  "data-flow-mode": "dapp-import",
9737
9768
  "data-step-type": effectiveStep.type,
9738
- children: /* @__PURE__ */ jsx28(
9769
+ children: /* @__PURE__ */ jsx27(
9739
9770
  DappImportAssetSelectSkeleton,
9740
9771
  {
9741
9772
  sourceLabel: activeDappImportProvider?.sourceLabel ?? "",
@@ -9747,13 +9778,13 @@ function DepositFlow({
9747
9778
  );
9748
9779
  }
9749
9780
  if (effectiveStep.type === "dapp-import-select") {
9750
- return /* @__PURE__ */ jsx28(
9781
+ return /* @__PURE__ */ jsx27(
9751
9782
  "div",
9752
9783
  {
9753
9784
  className: "rs-modal-body",
9754
9785
  "data-flow-mode": "dapp-import",
9755
9786
  "data-step-type": effectiveStep.type,
9756
- children: /* @__PURE__ */ jsx28(
9787
+ children: /* @__PURE__ */ jsx27(
9757
9788
  DappImportSelectStep,
9758
9789
  {
9759
9790
  enabledIds: enabledAssetMigrationIds,
@@ -9780,7 +9811,7 @@ function DepositFlow({
9780
9811
  );
9781
9812
  }
9782
9813
  if (!signerContext?.walletClient || !signerContext?.publicClient) {
9783
- return /* @__PURE__ */ jsx28("div", { className: "rs-modal-body", children: /* @__PURE__ */ jsx28("div", { className: "rs-step", children: /* @__PURE__ */ jsx28("div", { className: "rs-loading-state", children: /* @__PURE__ */ jsx28("div", { className: "rs-loading-text", children: /* @__PURE__ */ jsx28("div", { className: "rs-loading-title", children: "Connecting wallet\u2026" }) }) }) }) });
9814
+ return /* @__PURE__ */ jsx27("div", { className: "rs-modal-body", children: /* @__PURE__ */ jsx27("div", { className: "rs-step", children: /* @__PURE__ */ jsx27("div", { className: "rs-loading-state", children: /* @__PURE__ */ jsx27("div", { className: "rs-loading-text", children: /* @__PURE__ */ jsx27("div", { className: "rs-loading-title", children: "Connecting wallet\u2026" }) }) }) }) });
9784
9815
  }
9785
9816
  const ownerAddress = signerContext.ownerAddress;
9786
9817
  const ownerChainId = signerContext.walletClient?.chain?.id ?? signerContext.publicClient.chain?.id ?? setupChainId;
@@ -9791,14 +9822,14 @@ function DepositFlow({
9791
9822
  return getPublicClient(chainId, rpcUrls);
9792
9823
  };
9793
9824
  return /* @__PURE__ */ jsxs23("div", { className: "rs-modal-body", children: [
9794
- effectiveStep.type === "setup" && /* @__PURE__ */ jsx28(
9825
+ effectiveStep.type === "setup" && /* @__PURE__ */ jsx27(
9795
9826
  AccountPreparingSkeleton,
9796
9827
  {
9797
9828
  errorMessage: activeEntry.status === "error" ? activeEntry.message ?? void 0 : void 0,
9798
9829
  onRetry: activeEntry.status === "error" ? () => handleRetrySetup() : void 0
9799
9830
  }
9800
9831
  ),
9801
- effectiveStep.type === "select-asset" && /* @__PURE__ */ jsx28(
9832
+ effectiveStep.type === "select-asset" && /* @__PURE__ */ jsx27(
9802
9833
  AssetSelectStep,
9803
9834
  {
9804
9835
  address: ownerAddress,
@@ -9811,7 +9842,7 @@ function DepositFlow({
9811
9842
  onDisconnect: onDisconnect ? handleWalletDisconnect : void 0
9812
9843
  }
9813
9844
  ),
9814
- effectiveStep.type === "dapp-import-asset-select" && activeDappImportProvider && activeDappImportAvailability && /* @__PURE__ */ jsx28(
9845
+ effectiveStep.type === "dapp-import-asset-select" && activeDappImportProvider && activeDappImportAvailability && /* @__PURE__ */ jsx27(
9815
9846
  DappImportAssetSelectStep,
9816
9847
  {
9817
9848
  sourceLabel: activeDappImportAvailability.assets[0]?.sourceLabel ?? activeDappImportProvider.sourceLabel,
@@ -9820,7 +9851,7 @@ function DepositFlow({
9820
9851
  onSelect: handleDappImportAssetSelected
9821
9852
  }
9822
9853
  ),
9823
- effectiveStep.type === "amount" && /* @__PURE__ */ jsx28(
9854
+ effectiveStep.type === "amount" && /* @__PURE__ */ jsx27(
9824
9855
  AmountStep,
9825
9856
  {
9826
9857
  walletClient: signerContext.walletClient,
@@ -9844,7 +9875,7 @@ function DepositFlow({
9844
9875
  }
9845
9876
  }
9846
9877
  ),
9847
- effectiveStep.type === "confirm" && /* @__PURE__ */ jsx28(
9878
+ effectiveStep.type === "confirm" && /* @__PURE__ */ jsx27(
9848
9879
  ConfirmStep,
9849
9880
  {
9850
9881
  walletClient: signerContext.walletClient,
@@ -9895,7 +9926,7 @@ function DepositFlow({
9895
9926
  onError: handleError
9896
9927
  }
9897
9928
  ),
9898
- effectiveStep.type === "processing" && /* @__PURE__ */ jsx28(
9929
+ effectiveStep.type === "processing" && /* @__PURE__ */ jsx27(
9899
9930
  ProcessingStep,
9900
9931
  {
9901
9932
  flowLabel: payment ? "payment" : void 0,
@@ -9933,11 +9964,115 @@ function DepositFlow({
9933
9964
  ] });
9934
9965
  }
9935
9966
 
9967
+ // src/components/history/useBankHistory.ts
9968
+ import { useCallback as useCallback7, useEffect as useEffect14, useRef as useRef10, useState as useState14 } from "react";
9969
+ function useBankHistory(source, open, panelOpen) {
9970
+ const [orders, setOrders] = useState14([]);
9971
+ const [unread, setUnread] = useState14(false);
9972
+ const [loading, setLoading] = useState14(false);
9973
+ const [error, setError] = useState14(null);
9974
+ const [cursor, setCursor] = useState14(null);
9975
+ const generation = useRef10(0);
9976
+ const busy = useRef10(false);
9977
+ const seen = useRef10(/* @__PURE__ */ new Map());
9978
+ const baselined = useRef10(false);
9979
+ const paged = useRef10(false);
9980
+ const panel = useRef10(panelOpen);
9981
+ panel.current = panelOpen;
9982
+ const load = useCallback7(
9983
+ async (next) => {
9984
+ if (!source || !open || busy.current || document.visibilityState === "hidden")
9985
+ return;
9986
+ const current = generation.current;
9987
+ busy.current = true;
9988
+ setLoading(true);
9989
+ try {
9990
+ const page = await source.listOrders({
9991
+ limit: 20,
9992
+ ...next ? { cursor: next } : {}
9993
+ });
9994
+ if (current !== generation.current) return;
9995
+ const bank = page.items.filter((order) => order.provider === "noah");
9996
+ let changed = false;
9997
+ for (const order of bank) {
9998
+ const fingerprint = JSON.stringify(order.stages);
9999
+ if (!next && seen.current.get(order.id) !== fingerprint)
10000
+ changed = true;
10001
+ seen.current.set(order.id, fingerprint);
10002
+ }
10003
+ if (baselined.current && changed && !panel.current) setUnread(true);
10004
+ if (!next) baselined.current = true;
10005
+ setOrders((previous) => {
10006
+ const merged = new Map(previous.map((order) => [order.id, order]));
10007
+ for (const order of bank) merged.set(order.id, order);
10008
+ return [...merged.values()].sort(
10009
+ (a, b) => b.createdAt.localeCompare(a.createdAt)
10010
+ );
10011
+ });
10012
+ if (next) paged.current = true;
10013
+ if (next || !paged.current) setCursor(page.nextCursor);
10014
+ setError(null);
10015
+ } catch {
10016
+ if (current === generation.current)
10017
+ setError("Bank transfer history is unavailable. Try again shortly.");
10018
+ } finally {
10019
+ if (current === generation.current) {
10020
+ busy.current = false;
10021
+ setLoading(false);
10022
+ }
10023
+ }
10024
+ },
10025
+ [source, open]
10026
+ );
10027
+ useEffect14(() => {
10028
+ generation.current += 1;
10029
+ busy.current = false;
10030
+ seen.current = /* @__PURE__ */ new Map();
10031
+ baselined.current = false;
10032
+ paged.current = false;
10033
+ setOrders([]);
10034
+ setUnread(false);
10035
+ setCursor(null);
10036
+ setError(null);
10037
+ setLoading(false);
10038
+ if (!open || !source) return;
10039
+ void load();
10040
+ const refresh = () => {
10041
+ void load();
10042
+ };
10043
+ const timer = setInterval(refresh, 3e4);
10044
+ window.addEventListener("focus", refresh);
10045
+ document.addEventListener("visibilitychange", refresh);
10046
+ return () => {
10047
+ generation.current += 1;
10048
+ clearInterval(timer);
10049
+ window.removeEventListener("focus", refresh);
10050
+ document.removeEventListener("visibilitychange", refresh);
10051
+ };
10052
+ }, [source, open, load]);
10053
+ useEffect14(() => {
10054
+ if (panelOpen) {
10055
+ setUnread(false);
10056
+ void load();
10057
+ }
10058
+ }, [panelOpen, load]);
10059
+ return {
10060
+ orders,
10061
+ unread,
10062
+ loading,
10063
+ error,
10064
+ hasMore: cursor !== null,
10065
+ loadMore: () => {
10066
+ if (cursor) void load(cursor);
10067
+ }
10068
+ };
10069
+ }
10070
+
9936
10071
  // src/DepositModal.tsx
9937
- import { jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
9938
- var ReownDepositInner = lazy2(async () => {
10072
+ import { jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
10073
+ var ReownDepositInner = lazy4(async () => {
9939
10074
  await loadReownDependencies();
9940
- const module = await import("./DepositModalReown-XBNY6QCI.mjs");
10075
+ const module = await import("./DepositModalReown-SYQ2SCHC.mjs");
9941
10076
  return { default: module.DepositModalReown };
9942
10077
  });
9943
10078
  function buildDepositAnalyticsSessionProperties({
@@ -9954,6 +10089,7 @@ function buildDepositAnalyticsSessionProperties({
9954
10089
  sourceChain,
9955
10090
  sourceToken,
9956
10091
  defaultAmount,
10092
+ bankOnrampEnabled = false,
9957
10093
  walletIntegration,
9958
10094
  targetChain,
9959
10095
  targetToken
@@ -9966,7 +10102,7 @@ function buildDepositAnalyticsSessionProperties({
9966
10102
  enabledFundingMethods.push("wallet");
9967
10103
  }
9968
10104
  if (enableQrTransfer) enabledFundingMethods.push("transfer");
9969
- if (enableFiatOnramp && configuredFiatIdentifiers?.length !== 0) {
10105
+ if (bankOnrampEnabled || enableFiatOnramp && configuredFiatIdentifiers?.length !== 0) {
9970
10106
  enabledFundingMethods.push("fiat_onramp");
9971
10107
  }
9972
10108
  if (enableExchangeConnect) enabledFundingMethods.push("exchange_connect");
@@ -9999,7 +10135,7 @@ function DepositModal(props) {
9999
10135
  const needsReown = !!props.reownAppId;
10000
10136
  const hasWalletClientProp = hasSuppliedWalletClient(props);
10001
10137
  if (needsReown) {
10002
- return /* @__PURE__ */ jsx29(Suspense2, { fallback: null, children: /* @__PURE__ */ jsx29(
10138
+ return /* @__PURE__ */ jsx28(Suspense3, { fallback: null, children: /* @__PURE__ */ jsx28(
10003
10139
  ReownDepositInner,
10004
10140
  {
10005
10141
  ...props,
@@ -10007,7 +10143,7 @@ function DepositModal(props) {
10007
10143
  }
10008
10144
  ) });
10009
10145
  }
10010
- return /* @__PURE__ */ jsx29(
10146
+ return /* @__PURE__ */ jsx28(
10011
10147
  DepositModalInner,
10012
10148
  {
10013
10149
  ...props,
@@ -10038,6 +10174,7 @@ function DepositModalInner({
10038
10174
  assetMigrations,
10039
10175
  initialAssetMigration,
10040
10176
  enableFiatOnramp = false,
10177
+ bankOnramp,
10041
10178
  enableQrTransfer = true,
10042
10179
  enableGaslessDeposit = false,
10043
10180
  fiatMethods,
@@ -10064,24 +10201,41 @@ function DepositModalInner({
10064
10201
  signRecovery,
10065
10202
  debug
10066
10203
  }) {
10067
- const modalRef = useRef10(null);
10068
- const analyticsControllerRef = useRef10(null);
10069
- const analyticsSessionIdRef = useRef10(null);
10070
- const previousOpenRef = useRef10(isOpen);
10204
+ const modalRef = useRef11(null);
10205
+ const analyticsControllerRef = useRef11(null);
10206
+ const analyticsSessionIdRef = useRef11(null);
10207
+ const previousOpenRef = useRef11(isOpen);
10071
10208
  const onReadyRef = useLatestRef(onReady);
10072
10209
  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(
10210
+ const [currentScreen, setCurrentScreen] = useState15("connect");
10211
+ const bankScope = `${backendUrl}:${recipient}:${typeof targetChainProp === "string" ? targetChainProp : getChainId(targetChainProp)}:${targetToken}`;
10212
+ const [bankSession, setBankSession] = useState15(null);
10213
+ const [bankJourneyVisible, setBankJourneyVisible] = useState15(false);
10214
+ const onBankJourney = useCallback8((journey) => {
10215
+ setBankJourneyVisible(Boolean(journey));
10216
+ if (journey)
10217
+ setBankSession(
10218
+ journey.source ? { source: journey.source, scope: bankScope } : null
10219
+ );
10220
+ }, [bankScope]);
10221
+ const bankSource = bankSession?.scope === bankScope ? bankSession.source : null;
10222
+ useEffect15(() => {
10223
+ if (!isOpen) {
10224
+ setBankSession(null);
10225
+ setBankJourneyVisible(false);
10226
+ }
10227
+ }, [isOpen]);
10228
+ const [swappedImmersive, setSwappedImmersive] = useState15(false);
10229
+ const [submitting, setSubmitting] = useState15(false);
10230
+ const [backHandler, setBackHandler] = useState15(
10077
10231
  void 0
10078
10232
  );
10079
- const [processingSettled, setProcessingSettled] = useState14(false);
10080
- const historyButtonVisible = !payment && isHistoryEntryVisible({
10233
+ const [processingSettled, setProcessingSettled] = useState15(false);
10234
+ const historyButtonVisible = !payment && (bankJourneyVisible || isHistoryEntryVisible({
10081
10235
  screen: currentScreen,
10082
10236
  submitting,
10083
10237
  settled: processingSettled
10084
- });
10238
+ }));
10085
10239
  const targetChain = typeof targetChainProp === "string" ? targetChainProp : getChainId(targetChainProp);
10086
10240
  const sourceChain = sourceChainProp ? getChainId(sourceChainProp) : void 0;
10087
10241
  const rpcUrls = useStableRpcUrls(rpcUrlsProp);
@@ -10107,15 +10261,27 @@ function DepositModalInner({
10107
10261
  canRecover: Boolean(signRecovery),
10108
10262
  analytics: historyAnalytics
10109
10263
  });
10264
+ const bankOrders = useBankHistory(bankSource, isOpen && !payment, history.isPanelOpen);
10265
+ const bankHistory = bankJourneyVisible && !bankSource ? { ...bankOrders, loading: true } : bankOrders;
10266
+ const historyDepositsRef = useLatestRef(history.deposits);
10267
+ useEffect15(() => {
10268
+ const waitingForSettlement = bankHistory.orders.some((order) => {
10269
+ if (order.stages.delivery.status !== "completed") return false;
10270
+ const { depositId } = order.stages.delivery;
10271
+ const deposit = historyDepositsRef.current.find((item) => item.id === depositId);
10272
+ return !deposit || deposit.status === "pending" || deposit.status === "processing";
10273
+ });
10274
+ if (waitingForSettlement) history.markStale();
10275
+ }, [bankHistory.orders, history.markStale, historyDepositsRef]);
10110
10276
  const {
10111
10277
  markStale: markHistoryStale,
10112
10278
  invalidate: invalidateHistory,
10113
10279
  recoverySubmitting
10114
10280
  } = history;
10115
- const [clientSetup, setClientSetup] = useState14(
10281
+ const [clientSetup, setClientSetup] = useState15(
10116
10282
  null
10117
10283
  );
10118
- useEffect14(() => {
10284
+ useEffect15(() => {
10119
10285
  if (!isOpen) return;
10120
10286
  let active = true;
10121
10287
  service.getSetup().then((config) => {
@@ -10125,7 +10291,7 @@ function DepositModalInner({
10125
10291
  active = false;
10126
10292
  };
10127
10293
  }, [isOpen, service]);
10128
- useEffect14(() => {
10294
+ useEffect15(() => {
10129
10295
  if (debug && clientSetup) {
10130
10296
  console.debug("[deposit] client setup config (not shown yet)", clientSetup);
10131
10297
  }
@@ -10135,19 +10301,19 @@ function DepositModalInner({
10135
10301
  // eslint-disable-next-line react-hooks/exhaustive-deps
10136
10302
  []
10137
10303
  );
10138
- useEffect14(() => {
10304
+ useEffect15(() => {
10139
10305
  store.dispatch({ type: "target/changed", targetChain, targetToken });
10140
10306
  }, [store, targetChain, targetToken]);
10141
- useEffect14(() => {
10307
+ useEffect15(() => {
10142
10308
  if (!isOpen || !modalRef.current) return;
10143
10309
  return applyTheme(modalRef.current, theme);
10144
10310
  }, [isOpen, theme]);
10145
- useEffect14(() => {
10311
+ useEffect15(() => {
10146
10312
  if (isOpen) {
10147
10313
  onReadyRef.current?.();
10148
10314
  }
10149
10315
  }, [isOpen, onReadyRef]);
10150
- useEffect14(() => {
10316
+ useEffect15(() => {
10151
10317
  onUiStateRef.current?.({
10152
10318
  screen: currentScreen,
10153
10319
  back: backHandler,
@@ -10200,7 +10366,7 @@ function DepositModalInner({
10200
10366
  },
10201
10367
  [closeWithSource]
10202
10368
  );
10203
- useEffect14(() => {
10369
+ useEffect15(() => {
10204
10370
  if (previousOpenRef.current && !isOpen) {
10205
10371
  const analytics = analyticsControllerRef.current;
10206
10372
  analytics?.abandon("modal_close");
@@ -10208,7 +10374,7 @@ function DepositModalInner({
10208
10374
  }
10209
10375
  previousOpenRef.current = isOpen;
10210
10376
  }, [isOpen]);
10211
- useEffect14(() => {
10377
+ useEffect15(() => {
10212
10378
  if (!isOpen) {
10213
10379
  setCurrentScreen("connect");
10214
10380
  setBackHandler(void 0);
@@ -10217,7 +10383,7 @@ function DepositModalInner({
10217
10383
  setProcessingSettled(false);
10218
10384
  }
10219
10385
  }, [isOpen]);
10220
- useEffect14(() => {
10386
+ useEffect15(() => {
10221
10387
  if (!isOpen) {
10222
10388
  store.dispatch({ type: "flow/reset" });
10223
10389
  }
@@ -10237,6 +10403,9 @@ function DepositModalInner({
10237
10403
  sourceChain: sourceChainProp,
10238
10404
  sourceToken,
10239
10405
  defaultAmount,
10406
+ bankOnrampEnabled: Boolean(
10407
+ bankOnramp && (fiatMethods === void 0 || fiatMethods["bank-transfer"] === true)
10408
+ ),
10240
10409
  walletIntegration,
10241
10410
  targetChain,
10242
10411
  targetToken
@@ -10245,7 +10414,7 @@ function DepositModalInner({
10245
10414
  const canGoBack = backHandler !== void 0;
10246
10415
  const hideHeaderChrome = swappedImmersive;
10247
10416
  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(
10417
+ return /* @__PURE__ */ jsx28(RpcUrlsProvider, { value: rpcUrls, children: /* @__PURE__ */ jsx28(ChainCatalogProvider, { service, rpcUrls, children: /* @__PURE__ */ jsx28(AssetMetadataProvider, { service, children: /* @__PURE__ */ jsx28(DepositStoreProvider, { store, children: /* @__PURE__ */ jsx28(
10249
10418
  Modal,
10250
10419
  {
10251
10420
  isOpen,
@@ -10254,7 +10423,7 @@ function DepositModalInner({
10254
10423
  inline,
10255
10424
  closeOnOverlayClick,
10256
10425
  ariaLabel: "Deposit",
10257
- children: /* @__PURE__ */ jsx29(
10426
+ children: /* @__PURE__ */ jsx28(
10258
10427
  AnalyticsSession,
10259
10428
  {
10260
10429
  modal: "deposit",
@@ -10264,44 +10433,45 @@ function DepositModalInner({
10264
10433
  enableIngest: enableAnalyticsIngest,
10265
10434
  ingestUrl: analyticsIngestUrl,
10266
10435
  sessionIdRef: analyticsSessionIdRef,
10267
- children: /* @__PURE__ */ jsx29(
10436
+ children: /* @__PURE__ */ jsx28(
10268
10437
  DepositAnalyticsControllerProvider,
10269
10438
  {
10270
10439
  controllerRef: analyticsControllerRef,
10271
10440
  children: /* @__PURE__ */ jsxs24("div", { ref: modalRef, className: modalClassName, children: [
10272
10441
  !hideHeaderChrome && /* @__PURE__ */ jsxs24("div", { className: "rs-modal-header--redesigned", children: [
10273
- /* @__PURE__ */ jsx29("div", { className: "rs-modal-header-nav-left", children: showBackButton && canGoBack && backHandler && /* @__PURE__ */ jsx29(
10442
+ /* @__PURE__ */ jsx28("div", { className: "rs-modal-header-nav-left", children: showBackButton && canGoBack && backHandler && /* @__PURE__ */ jsx28(
10274
10443
  "button",
10275
10444
  {
10276
10445
  type: "button",
10277
10446
  className: "rs-modal-header-back",
10278
10447
  "aria-label": "Go back",
10279
10448
  onClick: backHandler,
10280
- children: /* @__PURE__ */ jsx29(ChevronLeftIcon, {})
10449
+ children: /* @__PURE__ */ jsx28(ChevronLeftIcon, {})
10281
10450
  }
10282
10451
  ) }),
10283
10452
  /* @__PURE__ */ jsxs24("div", { className: "rs-modal-header-nav-right", children: [
10284
- historyButtonVisible && /* @__PURE__ */ jsx29(
10453
+ historyButtonVisible && /* @__PURE__ */ jsx28(
10285
10454
  HistoryEntryButton,
10286
10455
  {
10287
- badge: history.badge,
10456
+ badge: bankJourneyVisible ? null : history.badge,
10457
+ unread: bankHistory.unread,
10288
10458
  onClick: history.openPanel,
10289
10459
  disabled: !recipient
10290
10460
  }
10291
10461
  ),
10292
- /* @__PURE__ */ jsx29(
10462
+ /* @__PURE__ */ jsx28(
10293
10463
  "button",
10294
10464
  {
10295
10465
  type: "button",
10296
10466
  onClick: () => closeWithSource("header_button"),
10297
10467
  className: "rs-modal-close",
10298
10468
  "aria-label": "Close",
10299
- children: /* @__PURE__ */ jsx29(CloseIcon, {})
10469
+ children: /* @__PURE__ */ jsx28(CloseIcon, {})
10300
10470
  }
10301
10471
  )
10302
10472
  ] })
10303
10473
  ] }),
10304
- /* @__PURE__ */ jsx29(
10474
+ /* @__PURE__ */ jsx28(
10305
10475
  DepositFlow,
10306
10476
  {
10307
10477
  walletClientProp,
@@ -10322,6 +10492,9 @@ function DepositModalInner({
10322
10492
  assetMigrations,
10323
10493
  initialAssetMigration,
10324
10494
  enableFiatOnramp,
10495
+ bankOnramp,
10496
+ onBankJourney,
10497
+ backendUrl,
10325
10498
  enableQrTransfer,
10326
10499
  enableGaslessDeposit,
10327
10500
  fiatMethods,
@@ -10346,10 +10519,12 @@ function DepositModalInner({
10346
10519
  debug
10347
10520
  }
10348
10521
  ),
10349
- history.isPanelOpen && /* @__PURE__ */ jsx29(
10522
+ history.isPanelOpen && /* @__PURE__ */ jsx28(
10350
10523
  HistoryOverlay,
10351
10524
  {
10352
10525
  controller: history,
10526
+ bankHistory,
10527
+ bankSupportUrl: bankOnramp?.supportUrl,
10353
10528
  backLabel: "Deposit",
10354
10529
  recipient,
10355
10530
  backendUrl,
@@ -10371,7 +10546,7 @@ function DepositModalInner({
10371
10546
  }
10372
10547
  )
10373
10548
  }
10374
- ) }) }) });
10549
+ ) }) }) }) });
10375
10550
  }
10376
10551
 
10377
10552
  export {