@rhinestone/deposit-modal 0.18.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +179 -48
  2. package/dist/BankOnrampStep-JG32OCM2.mjs +435 -0
  3. package/dist/BankOnrampStep-NPGXAA7U.cjs +435 -0
  4. package/dist/{DepositModalReown-VCY65DJX.mjs → DepositModalReown-3FGTPER6.mjs} +6 -5
  5. package/dist/{DepositModalReown-TVO3ZQQK.cjs → DepositModalReown-ALVWADG7.cjs} +21 -20
  6. package/dist/WithdrawModal-5YWFJSYY.cjs +12 -0
  7. package/dist/WithdrawModal-LL4Z5WZP.mjs +12 -0
  8. package/dist/{bearer-transport-CVHNBgoV.d.cts → bearer-transport-DZyeDG64.d.cts} +5 -1
  9. package/dist/{bearer-transport-CVHNBgoV.d.ts → bearer-transport-DZyeDG64.d.ts} +5 -1
  10. package/dist/{caip-BMi-9t09.d.cts → caip-nwFFL46o.d.cts} +2 -2
  11. package/dist/{caip-BMi-9t09.d.ts → caip-nwFFL46o.d.ts} +2 -2
  12. package/dist/{chunk-EKC2IRQG.mjs → chunk-247GJH57.mjs} +687 -299
  13. package/dist/{chunk-FTWKAJGN.mjs → chunk-2FOPO4N5.mjs} +1 -1
  14. package/dist/{chunk-AIZKGFVA.mjs → chunk-32ERBFMO.mjs} +1499 -978
  15. package/dist/chunk-5QUWEFD4.mjs +19 -0
  16. package/dist/chunk-6CTJFR3T.mjs +113 -0
  17. package/dist/{chunk-3TEVMP76.mjs → chunk-B2LZQIGB.mjs} +1 -1
  18. package/dist/{chunk-34JVJZEZ.cjs → chunk-BTEG2VNZ.cjs} +171 -130
  19. package/dist/{chunk-N3AAT6BS.cjs → chunk-CXRH5MKO.cjs} +1556 -1035
  20. package/dist/chunk-E7IMWVMN.mjs +346 -0
  21. package/dist/{chunk-N6JJG57R.cjs → chunk-EKFXUF5A.cjs} +1 -1
  22. package/dist/chunk-FKJ6EJHH.cjs +346 -0
  23. package/dist/chunk-FMUSY563.cjs +19 -0
  24. package/dist/{chunk-LVCD6RHF.cjs → chunk-FVJKUTHF.cjs} +2 -2
  25. package/dist/chunk-G264OM23.cjs +224 -0
  26. package/dist/{chunk-R2B6VD4E.mjs → chunk-HP7S7AD6.mjs} +73 -32
  27. package/dist/{chunk-O4JZKKCZ.cjs → chunk-OPT5EW6L.cjs} +10 -5
  28. package/dist/chunk-PYRXOP2Y.cjs +113 -0
  29. package/dist/{chunk-X4EUXBHJ.mjs → chunk-XBJCZYBX.mjs} +8 -3
  30. package/dist/chunk-YY4ZOAH5.mjs +224 -0
  31. package/dist/{chunk-JV5OGG53.cjs → chunk-Z4RBTNKX.cjs} +1202 -814
  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 -20
  55. package/dist/onramp.d.cts +59 -23
  56. package/dist/onramp.d.ts +59 -23
  57. package/dist/onramp.mjs +5 -21
  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 +280 -0
  63. package/dist/{types-CbUs4boj.d.cts → types-BxSrazbq.d.ts} +56 -3
  64. package/dist/{types-CZYypODQ.d.ts → types-CixUBhrM.d.cts} +56 -3
  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-GR3HLYXU.cjs +0 -11
  71. package/dist/WithdrawModal-RMCYJJ4S.mjs +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
@@ -1,3 +1,22 @@
1
+ import {
2
+ AlertTriangleIcon,
3
+ ArrowUpRightIcon,
4
+ BankIcon,
5
+ BodyHeader,
6
+ CheckIcon,
7
+ ChevronDownIcon,
8
+ ChevronLeftIcon,
9
+ ChevronRightIcon,
10
+ CloseIcon,
11
+ CoinsIcon,
12
+ ExternalLinkIcon,
13
+ HandCoinsIcon,
14
+ HistoryIcon,
15
+ InfoIcon,
16
+ Spinner,
17
+ WalletIcon,
18
+ useLatestRef
19
+ } from "./chunk-YY4ZOAH5.mjs";
1
20
  import {
2
21
  CHAIN_DISPLAY_ORDER,
3
22
  HYPERCORE_CHAIN_ID,
@@ -6,36 +25,27 @@ import {
6
25
  ICON_CDN,
7
26
  NATIVE_TOKEN_ADDRESS,
8
27
  SOLANA_MAINNET_CAIP2,
9
- SOLANA_TOKENS,
10
28
  STELLAR_PUBNET_CAIP2,
11
29
  TRON_MAINNET_CAIP2,
12
30
  cdnIconUrl,
13
31
  displayChainIdForCaip2,
14
- findTokenDecimals,
15
32
  getChainIcon,
16
33
  getChainName,
17
34
  getExplorerTxUrl,
18
- getRuntimeTokenByAddress,
19
- getSolanaTokenByMint,
20
- getTokenAddress,
21
- getTokenDecimalsByAddress,
22
- getTokenSymbol,
35
+ getRuntimeNativeDecimals,
36
+ getRuntimeNativeSymbol,
23
37
  isHyperCoreCaip2,
24
- isRegistryTokenOnChain,
25
38
  isSolanaCaip2,
26
39
  parseEvmChainId,
27
- publishShortlistTokens,
28
40
  setRuntimeChainMeta,
29
- setRuntimeTokens,
30
41
  targetChainToCaip2,
31
42
  targetChainToChainId,
32
- toEvmCaip2,
33
- tokenIconUrl
34
- } from "./chunk-EAGMY3QE.mjs";
43
+ toEvmCaip2
44
+ } from "./chunk-E7IMWVMN.mjs";
35
45
  import {
36
46
  MODAL_VERSION,
37
47
  serviceHeaders
38
- } from "./chunk-3TEVMP76.mjs";
48
+ } from "./chunk-B2LZQIGB.mjs";
39
49
 
40
50
  // src/components/ui/Modal.tsx
41
51
  import {
@@ -164,139 +174,72 @@ function Modal({
164
174
  }
165
175
  Modal.displayName = "Modal";
166
176
 
167
- // src/components/ui/Icons.tsx
168
- import {
169
- Wallet,
170
- ExternalLink,
171
- Coins,
172
- Check,
173
- ChevronRight,
174
- ChevronLeft,
175
- ChevronDown,
176
- X,
177
- HandCoins,
178
- History,
179
- Info,
180
- Copy,
181
- ArrowRight,
182
- ArrowUpRight,
183
- AlertTriangle,
184
- CircleArrowOutUpLeft,
185
- CreditCard,
186
- Landmark,
187
- Unplug
188
- } from "lucide-react";
189
- import { jsx as jsx2, jsxs } from "react/jsx-runtime";
190
- var WalletIcon = Wallet;
191
- var ExternalLinkIcon = ExternalLink;
192
- var CheckIcon = Check;
193
- function TransferCryptoIcon() {
194
- return /* @__PURE__ */ jsx2(
195
- "svg",
196
- {
197
- width: "24",
198
- height: "24",
199
- viewBox: "8 8 24 24",
200
- fill: "none",
201
- xmlns: "http://www.w3.org/2000/svg",
202
- "aria-hidden": "true",
203
- children: /* @__PURE__ */ jsx2(
204
- "path",
205
- {
206
- d: "M26.08 18.37C27.03 18.72 27.87 19.30 28.53 20.07C29.19 20.83 29.65 21.75 29.86 22.73C30.07 23.72 30.03 24.74 29.74 25.71C29.45 26.68 28.92 27.55 28.20 28.26C27.48 28.97 26.59 29.49 25.62 29.76C24.65 30.04 23.63 30.06 22.64 29.83C21.66 29.61 20.75 29.14 20.00 28.47C19.24 27.80 18.67 26.95 18.33 26.00M15 14H16V18M24.70 21.87L25.40 22.58L22.58 25.40M22 16C22 19.31 19.31 22 16 22C12.68 22 10 19.31 10 16C10 12.68 12.68 10 16 10C19.31 10 22 12.68 22 16Z",
207
- stroke: "currentColor",
208
- strokeWidth: "2",
209
- strokeLinecap: "round",
210
- strokeLinejoin: "round"
211
- }
212
- )
213
- }
214
- );
177
+ // src/core/deposit-service.ts
178
+ import { getAddress } from "viem";
179
+
180
+ // src/core/runtime-token-meta.ts
181
+ var bySymbol = /* @__PURE__ */ new Map();
182
+ var byAddress = /* @__PURE__ */ new Map();
183
+ function symbolKey(chainId, symbol) {
184
+ return `${chainId}:${symbol.trim().toUpperCase()}`;
185
+ }
186
+ function addressKey(chainId, address) {
187
+ const key = address.startsWith("0x") ? address.toLowerCase() : address;
188
+ return `${chainId}:${key}`;
189
+ }
190
+ var version = 0;
191
+ var listeners = /* @__PURE__ */ new Set();
192
+ function subscribeToRuntimeTokens(listener) {
193
+ listeners.add(listener);
194
+ return () => {
195
+ listeners.delete(listener);
196
+ };
215
197
  }
216
- var ChevronRightIcon = ChevronRight;
217
- var ChevronLeftIcon = ChevronLeft;
218
- var ChevronDownIcon = ChevronDown;
219
- var CloseIcon = X;
220
- var HandCoinsIcon = HandCoins;
221
- var CoinsIcon = Coins;
222
- var HistoryIcon = History;
223
- var InfoIcon = Info;
224
- var CopyIcon = Copy;
225
- var ArrowUpRightIcon = ArrowUpRight;
226
- var AlertTriangleIcon = AlertTriangle;
227
- var CircleArrowOutUpLeftIcon = CircleArrowOutUpLeft;
228
- var CardIcon = CreditCard;
229
- var BankIcon = Landmark;
230
- var UnplugIcon = Unplug;
231
- function MigrateAssetsIcon() {
232
- return /* @__PURE__ */ jsx2(
233
- "svg",
234
- {
235
- width: "24",
236
- height: "24",
237
- viewBox: "0 0 24 24",
238
- fill: "none",
239
- xmlns: "http://www.w3.org/2000/svg",
240
- "aria-hidden": "true",
241
- children: /* @__PURE__ */ jsxs(
242
- "g",
243
- {
244
- stroke: "currentColor",
245
- strokeWidth: "2",
246
- strokeLinecap: "round",
247
- strokeLinejoin: "round",
248
- children: [
249
- /* @__PURE__ */ jsx2(
250
- "path",
251
- {
252
- d: "M19 4.344V3C19 2.46957 18.7893 1.96086 18.4142 1.58579C18.0391 1.21071 17.5304 1 17 1H3C2.46957 1 1.96086 1.21071 1.58579 1.58579C1.21071 1.96086 1 2.46957 1 3V17C1 17.5304 1.21071 18.0391 1.58579 18.4142C1.96086 18.7893 2.46957 19 3 19H17C17.5304 19 18.0391 18.7893 18.4142 18.4142C18.7893 18.0391 19 17.5304 19 17V15.656",
253
- transform: "translate(2 2)"
254
- }
255
- ),
256
- /* @__PURE__ */ jsx2("path", { d: "M1 1H12", transform: "translate(9 11)" }),
257
- /* @__PURE__ */ jsx2("path", { d: "M1 9L5 5L1 1", transform: "translate(16 7)" })
258
- ]
259
- }
260
- )
198
+ function getRuntimeTokensVersion() {
199
+ return version;
200
+ }
201
+ function setRuntimeTokens(tokens) {
202
+ let changed = false;
203
+ for (const token of tokens) {
204
+ const sKey = symbolKey(token.chainId, token.symbol);
205
+ if (!bySymbol.has(sKey)) {
206
+ bySymbol.set(sKey, token);
207
+ changed = true;
261
208
  }
262
- );
209
+ const aKey = addressKey(token.chainId, token.address);
210
+ const previous = byAddress.get(aKey);
211
+ if (previous?.symbol !== token.symbol || previous.decimals !== token.decimals) {
212
+ changed = true;
213
+ }
214
+ byAddress.set(aKey, token);
215
+ }
216
+ if (!changed) return;
217
+ version += 1;
218
+ for (const listener of [...listeners]) listener();
263
219
  }
264
- function AppleIcon() {
265
- return /* @__PURE__ */ jsxs(
266
- "svg",
267
- {
268
- width: "24",
269
- height: "24",
270
- viewBox: "0 0 24 24",
271
- fill: "none",
272
- xmlns: "http://www.w3.org/2000/svg",
273
- "aria-hidden": "true",
274
- children: [
275
- /* @__PURE__ */ jsx2(
276
- "path",
277
- {
278
- d: "M16.36 1.43c0 1.14-.49 2.27-1.18 3.08-.74.9-1.99 1.57-2.98 1.57-.12 0-.23-.02-.3-.03-.01-.06-.04-.22-.04-.39 0-1.15.57-2.27 1.2-2.98.8-.94 2.15-1.64 3.25-1.68.03.13.05.28.05.43z",
279
- stroke: "currentColor",
280
- strokeWidth: "1.6",
281
- strokeLinejoin: "round"
282
- }
283
- ),
284
- /* @__PURE__ */ jsx2(
285
- "path",
286
- {
287
- d: "M20.93 17.14c-.03.07-.46 1.58-1.52 3.12-.94 1.34-1.94 2.71-3.43 2.71-1.51 0-1.9-.88-3.63-.88-1.7 0-2.3.91-3.67.91-1.38 0-2.33-1.26-3.43-2.8-1.29-1.82-2.32-4.63-2.32-7.28 0-4.28 2.8-6.55 5.55-6.55 1.45 0 2.68.95 3.6.95.86 0 2.22-1.01 3.9-1.01.61 0 2.89.06 4.37 2.19-.13.09-2.38 1.37-2.38 4.19 0 3.26 2.85 4.42 2.96 4.45z",
288
- stroke: "currentColor",
289
- strokeWidth: "1.6",
290
- strokeLinejoin: "round"
291
- }
292
- )
293
- ]
220
+ function publishShortlistTokens(shortlist) {
221
+ const tokens = [];
222
+ for (const [chainKey, entries] of Object.entries(shortlist)) {
223
+ const chainId = Number(chainKey);
224
+ if (!Number.isInteger(chainId)) continue;
225
+ for (const entry of entries) {
226
+ if (!/^0x[a-fA-F0-9]{40}$/.test(entry.address)) continue;
227
+ tokens.push({
228
+ chainId,
229
+ symbol: entry.symbol,
230
+ address: entry.address,
231
+ decimals: entry.decimals
232
+ });
294
233
  }
295
- );
234
+ }
235
+ setRuntimeTokens(tokens);
236
+ }
237
+ function getRuntimeToken(chainId, symbol) {
238
+ return bySymbol.get(symbolKey(chainId, symbol));
239
+ }
240
+ function getRuntimeTokenByAddress(chainId, address) {
241
+ return byAddress.get(addressKey(chainId, address));
296
242
  }
297
-
298
- // src/core/deposit-service.ts
299
- import { getAddress } from "viem";
300
243
 
301
244
  // src/core/debug.ts
302
245
  function truncateString(value, max = 240) {
@@ -351,6 +294,32 @@ function debugError(enabled, scope, message, error, data) {
351
294
  console.error(`[deposit-modal:${scope}] ${message}`, payload);
352
295
  }
353
296
 
297
+ // src/core/solana-tokens.ts
298
+ var SOLANA_TOKENS = [
299
+ { symbol: "SOL", mint: "native", decimals: 9 },
300
+ {
301
+ symbol: "USDC",
302
+ mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
303
+ decimals: 6
304
+ },
305
+ {
306
+ symbol: "USDT",
307
+ mint: "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB",
308
+ decimals: 6
309
+ }
310
+ ];
311
+ var SOLANA_SYSTEM_PROGRAM = "11111111111111111111111111111111";
312
+ function resolveSolanaToken(mint) {
313
+ if (mint === "native" || mint === SOLANA_SYSTEM_PROGRAM) {
314
+ return { symbol: "SOL", decimals: 9 };
315
+ }
316
+ const token = SOLANA_TOKENS.find((t) => t.mint === mint);
317
+ return token ? { symbol: token.symbol, decimals: token.decimals } : void 0;
318
+ }
319
+ function isNativeSol(token) {
320
+ return token.mint === "native";
321
+ }
322
+
354
323
  // src/core/chain-catalog.ts
355
324
  function parseToken(value) {
356
325
  if (typeof value !== "object" || value === null) return null;
@@ -625,6 +594,8 @@ function parseQuotePreview(raw) {
625
594
  }
626
595
  const output = parseQuoteOutput(obj.output);
627
596
  if (!output) return null;
597
+ const input = obj.input === void 0 ? void 0 : parseQuoteOutput(obj.input);
598
+ if (obj.input !== void 0 && !input) return null;
628
599
  const fees = obj.fees;
629
600
  if (typeof fees !== "object" || fees === null) return null;
630
601
  const total = fees.total;
@@ -657,6 +628,7 @@ function parseQuotePreview(raw) {
657
628
  estimatedFillTimeSeconds: obj.estimatedFillTimeSeconds,
658
629
  fees: { total: { usd: totalUsd }, breakdown },
659
630
  output,
631
+ ...input ? { input } : {},
660
632
  ...timing ? { timing } : {}
661
633
  };
662
634
  }
@@ -716,16 +688,6 @@ function parseFeeLine(raw) {
716
688
  ...line.internal !== void 0 && { internal: line.internal }
717
689
  };
718
690
  }
719
- var SwappedConnectFeeChangedError = class extends Error {
720
- constructor(exchangeFeeBps, message = "The Exchange Fee changed") {
721
- super(message);
722
- this.exchangeFeeBps = exchangeFeeBps;
723
- this.name = "SwappedConnectFeeChangedError";
724
- }
725
- };
726
- function parseExchangeFeeBps(value) {
727
- return typeof value === "number" && Number.isInteger(value) && value >= 0 && value <= 1e4 ? value : void 0;
728
- }
729
691
  var UNSUPPORTED_CONNECT_EXCHANGES = /* @__PURE__ */ new Set(["kraken", "htx"]);
730
692
  var SUPPORTED_CONNECT_EXCHANGE_COUNT = 7;
731
693
  function isSupportedConnectExchange(exchange) {
@@ -747,6 +709,10 @@ var DEPOSIT_POLICY_REFUSAL_CODES = [
747
709
  "BALANCE-3",
748
710
  "BALANCE-4"
749
711
  ];
712
+ var ASSET_LOOKUP_MAX_IDS = 100;
713
+ var ASSET_LOOKUP_MAX_URL_LENGTH = 2e3;
714
+ var ASSET_LOOKUP_TIMEOUT_MS = 8e3;
715
+ var ASSET_LOGO_PREFIX = "https://s3.rhinestone.dev/";
750
716
  var DEPOSIT_PREFLIGHT_TIMEOUT_MS = 1e4;
751
717
  async function readPolicyRefusal(response) {
752
718
  if (response.status !== 422) return null;
@@ -787,16 +753,14 @@ function createDepositService(baseUrl, options) {
787
753
  if (value.length <= 20) return value;
788
754
  return `${value.slice(0, 10)}...${value.slice(-8)}`;
789
755
  }
790
- function withPreflightTimeout(label, fallback, run) {
756
+ function withPreflightTimeout(label, fallback, run, timeoutMs = DEPOSIT_PREFLIGHT_TIMEOUT_MS) {
791
757
  const controller = new AbortController();
792
758
  return new Promise((resolve) => {
793
759
  const timer = setTimeout(() => {
794
- debugLog(debug, scope, `${label}:timeout`, {
795
- timeoutMs: DEPOSIT_PREFLIGHT_TIMEOUT_MS
796
- });
760
+ debugLog(debug, scope, `${label}:timeout`, { timeoutMs });
797
761
  controller.abort();
798
762
  resolve(fallback);
799
- }, DEPOSIT_PREFLIGHT_TIMEOUT_MS);
763
+ }, timeoutMs);
800
764
  run(controller.signal).then(
801
765
  (value) => {
802
766
  clearTimeout(timer);
@@ -811,6 +775,85 @@ function createDepositService(baseUrl, options) {
811
775
  }
812
776
  const PORTFOLIO_CACHE_TTL_MS = 3e4;
813
777
  const portfolioCache = /* @__PURE__ */ new Map();
778
+ let assetsRouteMissing = false;
779
+ let assetsQueryUnsupported = false;
780
+ function assetsGetUrl(ids, fields) {
781
+ return apiUrl(
782
+ `/assets?${new URLSearchParams({
783
+ ids: ids.join(","),
784
+ fields: fields.join(",")
785
+ }).toString()}`
786
+ );
787
+ }
788
+ function requestAssets(method, ids, fields) {
789
+ const failed = { ok: false, status: null };
790
+ return withPreflightTimeout(
791
+ `lookupAssets:${method}`,
792
+ failed,
793
+ async (signal) => {
794
+ const response = await fetch(
795
+ method === "GET" ? assetsGetUrl(ids, fields) : apiUrl("/assets"),
796
+ {
797
+ method,
798
+ headers: serviceHeaders(),
799
+ body: method === "QUERY" ? JSON.stringify({ ids, fields }) : void 0,
800
+ cache: "no-store",
801
+ signal
802
+ }
803
+ );
804
+ if (response.status !== 200) {
805
+ debugError(debug, scope, "lookupAssets:failed", {
806
+ method,
807
+ status: response.status
808
+ });
809
+ return { ok: false, status: response.status };
810
+ }
811
+ const body = await response.json().catch(() => null);
812
+ const data = body?.data;
813
+ if (!data || typeof data !== "object" || Array.isArray(data)) {
814
+ debugError(debug, scope, "lookupAssets:malformed", { method });
815
+ return failed;
816
+ }
817
+ return { ok: true, data };
818
+ },
819
+ ASSET_LOOKUP_TIMEOUT_MS
820
+ );
821
+ }
822
+ function chunkForGet(ids, fields) {
823
+ const chunks = [];
824
+ let current = [];
825
+ for (const id of ids) {
826
+ const next = [...current, id];
827
+ if (current.length > 0 && assetsGetUrl(next, fields).length > ASSET_LOOKUP_MAX_URL_LENGTH) {
828
+ chunks.push(current);
829
+ current = [id];
830
+ } else {
831
+ current = next;
832
+ }
833
+ }
834
+ if (current.length > 0) chunks.push(current);
835
+ return chunks;
836
+ }
837
+ async function lookupAssetsViaGet(ids, fields) {
838
+ const data = {};
839
+ for (const chunk of chunkForGet(ids, fields)) {
840
+ const outcome = await requestAssets("GET", chunk, fields);
841
+ if (!outcome.ok) return outcome;
842
+ Object.assign(data, outcome.data);
843
+ }
844
+ return { ok: true, data };
845
+ }
846
+ async function lookupAssetsBatch(ids, fields) {
847
+ const fitsGet = assetsGetUrl(ids, fields).length <= ASSET_LOOKUP_MAX_URL_LENGTH;
848
+ if (fitsGet || assetsQueryUnsupported) {
849
+ return lookupAssetsViaGet(ids, fields);
850
+ }
851
+ const viaQuery = await requestAssets("QUERY", ids, fields);
852
+ if (viaQuery.ok) return viaQuery;
853
+ const viaGet = await lookupAssetsViaGet(ids, fields);
854
+ if (viaGet.ok) assetsQueryUnsupported = true;
855
+ return viaGet;
856
+ }
814
857
  let topTokensPromise = null;
815
858
  let chainsPromise = null;
816
859
  function parseDepositOptions(value) {
@@ -915,6 +958,39 @@ function createDepositService(baseUrl, options) {
915
958
  });
916
959
  return promise;
917
960
  }
961
+ async function startSwappedCheckout(kind, account, fields) {
962
+ const label = kind === "fiat" ? "Swapped widget URL" : "Swapped Connect URL";
963
+ const response = await fetch(apiUrl("/onramp/orders"), {
964
+ method: "POST",
965
+ headers: serviceHeaders(),
966
+ body: JSON.stringify({
967
+ provider: "swapped",
968
+ kind,
969
+ account,
970
+ ...fields
971
+ })
972
+ });
973
+ if (!response.ok) {
974
+ const error = await response.json().catch(() => ({ error: "Unknown error" }));
975
+ debugError(debug, scope, "startSwappedCheckout:failed", error, {
976
+ status: response.status,
977
+ kind
978
+ });
979
+ throw new Error(
980
+ typeof error.error === "string" && error.error || `${label} failed: ${response.status}`
981
+ );
982
+ }
983
+ const body = await response.json().catch(() => null);
984
+ if (typeof body?.orderId !== "string" || body.nextAction?.type !== "hosted" || typeof body.nextAction.url !== "string") {
985
+ throw new Error(`${label}: malformed response`);
986
+ }
987
+ return {
988
+ orderId: body.orderId,
989
+ url: body.nextAction.url,
990
+ externalCustomerId: `${account.toLowerCase()}:${body.orderId}`,
991
+ expiresAt: typeof body.expiresAt === "string" ? body.expiresAt : void 0
992
+ };
993
+ }
918
994
  return {
919
995
  async registerManagedAccount(params) {
920
996
  const url = apiUrl("/register-managed");
@@ -1289,7 +1365,7 @@ function createDepositService(baseUrl, options) {
1289
1365
  },
1290
1366
  async checkLiquidity(params) {
1291
1367
  if (isSolanaCaip2(params.destinationChainId) || params.destinationChainId === "solana") {
1292
- const token = getSolanaTokenByMint(params.destinationToken);
1368
+ const token = resolveSolanaToken(params.destinationToken);
1293
1369
  return {
1294
1370
  hasLiquidity: true,
1295
1371
  symbol: token?.symbol ?? "Token",
@@ -1351,13 +1427,18 @@ function createDepositService(baseUrl, options) {
1351
1427
  // chain, and a HyperCore source token is a 16-byte Core spot tokenId.
1352
1428
  sourceChainId: params.sourceChainId === "hypercore" ? HYPERCORE_SPOT_CAIP2 : `eip155:${params.sourceChainId}`,
1353
1429
  sourceToken: params.sourceToken,
1354
- amount: params.amount
1430
+ // Each direction carries its own amount field and omits the other, which
1431
+ // is what the processor's "exactly one of" refinement checks. Sending
1432
+ // both is a 400, so spread rather than always emitting `amount`.
1433
+ ...params.direction === "exactOut" ? { direction: "exactOut", amountOut: params.amountOut } : { amount: params.amount }
1355
1434
  };
1356
1435
  debugLog(debug, scope, "getQuotePreview:request", {
1357
1436
  url,
1358
1437
  sourceChainId: body.sourceChainId,
1359
1438
  sourceToken: params.sourceToken,
1360
- amount: params.amount
1439
+ direction: params.direction ?? "exactIn",
1440
+ amount: params.amount,
1441
+ amountOut: params.amountOut
1361
1442
  });
1362
1443
  return withPreflightTimeout("getQuotePreview", null, async (signal) => {
1363
1444
  try {
@@ -1558,138 +1639,45 @@ function createDepositService(baseUrl, options) {
1558
1639
  status: result.status ?? "processing"
1559
1640
  };
1560
1641
  },
1561
- async fetchPrices(symbols) {
1562
- const list = symbols.filter((s) => s.length > 0);
1563
- if (list.length === 0) return {};
1564
- const url = apiUrl(
1565
- `/prices?${new URLSearchParams({ symbols: list.join(",") }).toString()}`
1566
- );
1567
- try {
1568
- const response = await fetch(url, {
1569
- method: "GET",
1570
- headers: serviceHeaders(),
1571
- cache: "no-store"
1572
- });
1573
- if (!response.ok) {
1574
- debugError(debug, scope, "fetchPrices:failed", {
1575
- status: response.status
1576
- });
1577
- return {};
1642
+ async lookupAssets(ids, fields) {
1643
+ const unique = [...new Set(ids.filter((id) => id.length > 0))];
1644
+ if (unique.length === 0) return { ok: true, items: {} };
1645
+ if (assetsRouteMissing) return { ok: false, routeMissing: true };
1646
+ const items = {};
1647
+ for (let i = 0; i < unique.length; i += ASSET_LOOKUP_MAX_IDS) {
1648
+ const batch = unique.slice(i, i + ASSET_LOOKUP_MAX_IDS);
1649
+ const outcome = await lookupAssetsBatch(batch, fields);
1650
+ if (!outcome.ok) {
1651
+ const routeMissing = outcome.status === 404 || outcome.status === 405;
1652
+ if (routeMissing) assetsRouteMissing = true;
1653
+ return { ok: false, routeMissing };
1578
1654
  }
1579
- const data = await response.json();
1580
- return Object.fromEntries(
1581
- Object.entries(data.prices ?? {}).map(([symbol, price]) => [
1582
- symbol.toUpperCase(),
1583
- price
1584
- ])
1585
- );
1586
- } catch (err) {
1587
- debugError(debug, scope, "fetchPrices:error", err);
1588
- return {};
1589
- }
1590
- },
1591
- async fetchPricesByAddress(caip2Ids) {
1592
- const list = caip2Ids.filter((id) => id.length > 0);
1593
- if (list.length === 0) return {};
1594
- const url = apiUrl(
1595
- `/prices?${new URLSearchParams({
1596
- addresses: list.join(",")
1597
- }).toString()}`
1598
- );
1599
- try {
1600
- const response = await fetch(url, {
1601
- method: "GET",
1602
- headers: serviceHeaders(),
1603
- cache: "no-store"
1604
- });
1605
- if (!response.ok) {
1606
- debugError(debug, scope, "fetchPricesByAddress:failed", {
1607
- status: response.status
1608
- });
1609
- return {};
1655
+ for (const id of batch) {
1656
+ const item = parseAssetItem(outcome.data[id], fields);
1657
+ if (item) items[id] = item;
1610
1658
  }
1611
- const data = await response.json();
1612
- return data.prices ?? {};
1613
- } catch (err) {
1614
- debugError(debug, scope, "fetchPricesByAddress:error", err);
1615
- return {};
1616
1659
  }
1660
+ return { ok: true, items };
1617
1661
  },
1618
1662
  async getSwappedWidgetUrl(params) {
1619
- const url = apiUrl("/onramp/swapped/widget-url");
1663
+ const { smartAccount, ...fields } = params;
1620
1664
  debugLog(debug, scope, "getSwappedWidgetUrl:request", {
1621
- smartAccount: shortRef(params.smartAccount),
1665
+ smartAccount: shortRef(smartAccount),
1622
1666
  method: params.method,
1623
1667
  methodSelectionSource: params.methodSelectionSource
1624
1668
  });
1625
- const response = await fetch(url, {
1626
- method: "POST",
1627
- headers: serviceHeaders(),
1628
- body: JSON.stringify(params)
1629
- });
1630
- if (!response.ok) {
1631
- const error = await response.json().catch(() => ({ error: "Unknown error" }));
1632
- debugError(debug, scope, "getSwappedWidgetUrl:failed", error, {
1633
- status: response.status
1634
- });
1635
- throw new Error(
1636
- error.error || `Swapped widget URL failed: ${response.status}`
1637
- );
1638
- }
1639
- const body = await response.json();
1640
- if (typeof body.url !== "string" || typeof body.currencyCode !== "string" || typeof body.externalCustomerId !== "string") {
1641
- throw new Error("Swapped widget URL: malformed response");
1642
- }
1643
- return {
1644
- url: body.url,
1645
- currencyCode: body.currencyCode,
1646
- sandbox: body.sandbox === true,
1647
- externalCustomerId: body.externalCustomerId,
1648
- expiresAt: body.expiresAt
1649
- };
1669
+ return startSwappedCheckout("fiat", smartAccount, fields);
1650
1670
  },
1651
1671
  async getSwappedConnectUrl(params) {
1652
- const url = apiUrl("/onramp/swapped/connect-url");
1672
+ const { smartAccount, ...fields } = params;
1653
1673
  debugLog(debug, scope, "getSwappedConnectUrl:request", {
1654
- smartAccount: shortRef(params.smartAccount),
1674
+ smartAccount: shortRef(smartAccount),
1655
1675
  connection: params.connection
1656
1676
  });
1657
- const response = await fetch(url, {
1658
- method: "POST",
1659
- headers: serviceHeaders(),
1660
- body: JSON.stringify(params)
1661
- });
1662
- if (!response.ok) {
1663
- const error = await response.json().catch(() => ({ error: "Unknown error" }));
1664
- debugError(debug, scope, "getSwappedConnectUrl:failed", error, {
1665
- status: response.status
1666
- });
1667
- const currentFeeBps = parseExchangeFeeBps(error.exchangeFeeBps);
1668
- if (response.status === 409 && currentFeeBps !== void 0) {
1669
- throw new SwappedConnectFeeChangedError(
1670
- currentFeeBps,
1671
- typeof error.error === "string" ? error.error : void 0
1672
- );
1673
- }
1674
- throw new Error(
1675
- typeof error.error === "string" && error.error || `Swapped Connect URL failed: ${response.status}`
1676
- );
1677
- }
1678
- const body = await response.json();
1679
- if (typeof body.url !== "string" || typeof body.currencyCode !== "string" || typeof body.externalCustomerId !== "string") {
1680
- throw new Error("Swapped Connect URL: malformed response");
1681
- }
1682
- return {
1683
- url: body.url,
1684
- currencyCode: body.currencyCode,
1685
- sandbox: body.sandbox === true,
1686
- externalCustomerId: body.externalCustomerId,
1687
- expiresAt: body.expiresAt,
1688
- exchangeFeeBps: parseExchangeFeeBps(body.exchangeFeeBps)
1689
- };
1677
+ return startSwappedCheckout("exchange", smartAccount, fields);
1690
1678
  },
1691
1679
  async getSwappedConnectExchanges() {
1692
- const url = apiUrl("/onramp/swapped/connect-exchanges");
1680
+ const url = apiUrl("/onramp/options?provider=swapped&kind=exchange");
1693
1681
  debugLog(debug, scope, "getSwappedConnectExchanges:request");
1694
1682
  const response = await fetch(url, {
1695
1683
  method: "GET",
@@ -1706,7 +1694,7 @@ function createDepositService(baseUrl, options) {
1706
1694
  );
1707
1695
  }
1708
1696
  const body = await response.json();
1709
- const rawExchanges = Array.isArray(body.exchanges) ? body.exchanges : null;
1697
+ const rawExchanges = Array.isArray(body.connections) ? body.connections : null;
1710
1698
  const exchanges = [];
1711
1699
  let hasMalformedExchange = rawExchanges === null;
1712
1700
  for (const exchange of rawExchanges ?? []) {
@@ -1724,16 +1712,10 @@ function createDepositService(baseUrl, options) {
1724
1712
  }
1725
1713
  exchanges.push({ connection, name, logoUrl });
1726
1714
  }
1727
- if (hasMalformedExchange || typeof body.fetchedAt !== "string" || typeof body.expiresAt !== "string") {
1715
+ if (hasMalformedExchange) {
1728
1716
  throw new Error("Swapped Connect exchanges: malformed response");
1729
1717
  }
1730
- return {
1731
- exchanges: exchanges.filter(isSupportedConnectExchange),
1732
- fetchedAt: body.fetchedAt,
1733
- expiresAt: body.expiresAt,
1734
- stale: body.stale === true ? true : void 0,
1735
- exchangeFeeBps: parseExchangeFeeBps(body.exchangeFeeBps)
1736
- };
1718
+ return { exchanges: exchanges.filter(isSupportedConnectExchange) };
1737
1719
  },
1738
1720
  async getSwappedPaymentMethods() {
1739
1721
  const empty = {
@@ -1741,7 +1723,7 @@ function createDepositService(baseUrl, options) {
1741
1723
  methods: [],
1742
1724
  recommendedMethod: null
1743
1725
  };
1744
- const url = apiUrl("/onramp/swapped/payment-methods");
1726
+ const url = apiUrl("/onramp/options?provider=swapped&kind=fiat");
1745
1727
  debugLog(debug, scope, "getSwappedPaymentMethods:request");
1746
1728
  try {
1747
1729
  const response = await fetch(url, {
@@ -1855,51 +1837,87 @@ function createDepositService(baseUrl, options) {
1855
1837
  return null;
1856
1838
  }
1857
1839
  },
1858
- async fetchSwappedOrderStatus(smartAccount) {
1859
- const url = apiUrl(
1860
- `/onramp/swapped/status/${encodeURIComponent(smartAccount)}`
1861
- );
1840
+ async fetchSwappedOrder(orderId) {
1841
+ const url = apiUrl(`/onramp/orders/${encodeURIComponent(orderId)}`);
1862
1842
  const response = await fetch(url, {
1863
1843
  method: "GET",
1864
1844
  headers: serviceHeaders(),
1865
1845
  cache: "no-store"
1866
1846
  });
1867
1847
  if (!response.ok) return null;
1868
- let body = null;
1848
+ let body;
1869
1849
  try {
1870
1850
  body = await response.json();
1871
1851
  } catch {
1872
1852
  return null;
1873
1853
  }
1874
- if (!body || body.ok !== true) return null;
1875
- const status = typeof body.status === "string" ? body.status : null;
1876
- const orderId = typeof body.orderId === "string" ? body.orderId : null;
1877
- if (!status || !orderId) return null;
1878
- const numericOrNull = (v) => {
1879
- if (typeof v === "number") {
1880
- return Number.isFinite(v) ? v : null;
1881
- }
1882
- if (typeof v === "string" && v.trim().length > 0) {
1883
- const parsed = Number(v);
1884
- return Number.isFinite(parsed) ? parsed : null;
1885
- }
1886
- return null;
1887
- };
1888
- return {
1889
- orderId,
1890
- status,
1891
- orderCrypto: typeof body.orderCrypto === "string" ? body.orderCrypto : null,
1892
- orderCryptoAmount: typeof body.orderCryptoAmount === "string" ? body.orderCryptoAmount : null,
1893
- transactionId: typeof body.transactionId === "string" ? body.transactionId : null,
1894
- receivedAt: typeof body.receivedAt === "string" ? body.receivedAt : null,
1895
- paidAmountUsd: numericOrNull(body.paidAmountUsd),
1896
- paidAmountEur: numericOrNull(body.paidAmountEur),
1897
- onrampFeeUsd: numericOrNull(body.onrampFeeUsd),
1898
- paymentMethod: typeof body.paymentMethod === "string" ? body.paymentMethod : null
1899
- };
1854
+ return swappedOrderFromView(orderId, body);
1900
1855
  }
1901
1856
  };
1902
1857
  }
1858
+ var SWAPPED_ORDER_STATUSES = /* @__PURE__ */ new Set([
1859
+ "payment_pending",
1860
+ "order_completed",
1861
+ "order_broadcasted",
1862
+ "order_cancelled"
1863
+ ]);
1864
+ function swappedOrderFromView(orderId, raw) {
1865
+ if (!raw || typeof raw !== "object") return null;
1866
+ const view = raw;
1867
+ if (view.provider !== "swapped") return null;
1868
+ const status = view.providerStatus;
1869
+ if (typeof status !== "string" || !SWAPPED_ORDER_STATUSES.has(status)) {
1870
+ return null;
1871
+ }
1872
+ const number = (v) => {
1873
+ const n = typeof v === "string" && v.trim() ? Number(v) : v;
1874
+ return typeof n === "number" && Number.isFinite(n) ? n : null;
1875
+ };
1876
+ const text = (v) => typeof v === "string" && v.length > 0 ? v : null;
1877
+ const railName = (v) => {
1878
+ const name = text(v);
1879
+ return name === "provider_selected" || name === "unknown" ? null : name;
1880
+ };
1881
+ const usdTotal = number(view.fiat?.usd?.total);
1882
+ const usdNet = number(view.fiat?.usd?.net);
1883
+ return {
1884
+ orderId,
1885
+ status,
1886
+ orderCrypto: text(view.crypto?.asset),
1887
+ orderCryptoAmount: text(view.crypto?.amount),
1888
+ transactionId: text(view.stages?.delivery?.txHash),
1889
+ receivedAt: text(view.updatedAt),
1890
+ paidAmountUsd: usdTotal ?? usdNet,
1891
+ paidAmountEur: number(view.fiat?.eur?.total) ?? number(view.fiat?.eur?.net),
1892
+ onrampFeeUsd: usdTotal !== null && usdNet !== null && usdTotal > usdNet ? Number((usdTotal - usdNet).toFixed(2)) : null,
1893
+ paymentMethod: railName(view.rail?.method ?? view.rail?.connection)
1894
+ };
1895
+ }
1896
+ function parseAssetItem(raw, fields) {
1897
+ if (!raw || typeof raw !== "object") return void 0;
1898
+ const record = raw;
1899
+ const item = {};
1900
+ if (fields.includes("symbol")) {
1901
+ const symbol = record.symbol;
1902
+ item.symbol = typeof symbol === "string" && symbol.trim().length > 0 ? symbol.trim() : null;
1903
+ }
1904
+ if (fields.includes("decimals")) {
1905
+ const decimals = record.decimals;
1906
+ item.decimals = typeof decimals === "number" && Number.isInteger(decimals) && decimals >= 0 && decimals <= 255 ? decimals : null;
1907
+ }
1908
+ if (fields.includes("logo")) {
1909
+ const logo = record.logo;
1910
+ item.logo = typeof logo === "string" && logo.startsWith(ASSET_LOGO_PREFIX) ? logo : null;
1911
+ }
1912
+ if (fields.includes("price")) {
1913
+ const price = record.price;
1914
+ const usd = price && typeof price === "object" ? typeof price.usd === "string" && price.usd.trim() !== "" ? Number(price.usd) : typeof price.usd === "number" ? price.usd : Number.NaN : Number.NaN;
1915
+ item.priceUsd = Number.isFinite(usd) && usd > 0 ? usd : null;
1916
+ }
1917
+ const error = record.error;
1918
+ item.error = error && typeof error === "object" && typeof error.code === "string" ? { code: error.code } : null;
1919
+ return item;
1920
+ }
1903
1921
  function normalizeDirectPortfolio(data) {
1904
1922
  const rawTokens = extractArray(data, "tokens") ?? extractArray(
1905
1923
  data?.data,
@@ -1925,20 +1943,13 @@ function normalizeOrchestratorPortfolio(data) {
1925
1943
  const unlocked = chainBalance.balance?.unlocked ?? "0";
1926
1944
  const normalizedName = tokenData.tokenName.trim();
1927
1945
  const isNativeSymbol = normalizedName.toUpperCase() === "ETH" || normalizedName.toUpperCase() === "ETHER";
1928
- const tokenAddress = chainBalance.tokenAddress ?? extractTokenAddress(tokenData, chainBalance.chainId) ?? getTokenAddress(tokenData.tokenName, chainBalance.chainId);
1946
+ const tokenAddress = chainBalance.tokenAddress ?? extractTokenAddress(tokenData, chainBalance.chainId) ?? runtimeEvmAddress(chainBalance.chainId, normalizedName);
1929
1947
  const resolvedTokenAddress = isNativeSymbol ? NATIVE_TOKEN_ADDRESS : tokenAddress;
1930
1948
  if (!resolvedTokenAddress) {
1931
1949
  continue;
1932
1950
  }
1933
- const registrySymbol = getTokenSymbol(
1934
- resolvedTokenAddress,
1935
- chainBalance.chainId
1936
- );
1937
- const symbol = registrySymbol !== "Token" ? registrySymbol : normalizedName || "Token";
1938
- const decimals = registrySymbol !== "Token" ? getTokenDecimalsByAddress(
1939
- resolvedTokenAddress,
1940
- chainBalance.chainId
1941
- ) : tokenData.tokenDecimals ?? 18;
1951
+ const symbol = normalizedName || "Token";
1952
+ const decimals = tokenData.tokenDecimals ?? 18;
1942
1953
  tokens.push({
1943
1954
  chainId: chainBalance.chainId,
1944
1955
  address: resolvedTokenAddress,
@@ -1964,7 +1975,6 @@ function normalizeDirectToken(token) {
1964
1975
  isHyperCoreCaip2(rawChainString) || rawChainString.toLowerCase() === "hypercore" ? "hypercore" : parseEvmChainId(rawChainString)
1965
1976
  ) : null);
1966
1977
  if (chainId === null) return null;
1967
- const registryChainId = typeof chainId === "number" ? chainId : chainId === "hypercore" ? HYPERCORE_CHAIN_ID : void 0;
1968
1978
  const symbol = extractString(token, "symbol") ?? extractString(token, "tokenSymbol") ?? extractString(token, "tokenName") ?? extractString(token, "name");
1969
1979
  if (!symbol) return null;
1970
1980
  const balanceValue = extractString(token, "balance") ?? extractString(token, "amount") ?? extractString(token, "value") ?? extractString(token, "rawBalance") ?? extractNumber(token, "balance")?.toString() ?? extractNumber(token, "amount")?.toString() ?? extractNumber(token, "value")?.toString() ?? extractNumber(token, "rawBalance")?.toString();
@@ -1972,14 +1982,13 @@ function normalizeDirectToken(token) {
1972
1982
  const address = extractString(token, "address") ?? extractString(token, "tokenAddress") ?? extractString(
1973
1983
  token.token,
1974
1984
  "address"
1975
- ) ?? (registryChainId !== void 0 ? getTokenAddress(symbol, registryChainId) : void 0);
1985
+ ) ?? (chainId === "hypercore" ? hyperCoreSourceToken(void 0, symbol)?.address : typeof chainId === "number" ? runtimeEvmAddress(chainId, symbol) : void 0);
1976
1986
  if (!address) return null;
1977
1987
  const balanceUsd = extractNumber(token, "balanceUsd") ?? extractNumber(token, "usdValue") ?? extractNumber(token, "valueUsd") ?? extractNumericString(token, "balanceUsd") ?? extractNumericString(token, "usdValue") ?? extractNumericString(token, "valueUsd") ?? 0;
1978
- const isSolanaToken = chainId === "solana";
1979
- const registrySymbol = isSolanaToken ? "Token" : getTokenSymbol(address, registryChainId);
1980
- const resolvedSymbol = isSolanaToken ? symbol : registrySymbol !== "Token" ? registrySymbol : symbol;
1981
1988
  const backendDecimals = extractNumber(token, "decimals") ?? extractNumber(token, "tokenDecimals");
1982
- const resolvedDecimals = !isSolanaToken && registrySymbol !== "Token" ? getTokenDecimalsByAddress(address, registryChainId) : backendDecimals ?? 18;
1989
+ const hyperCore = chainId === "hypercore" ? hyperCoreSourceToken(address, symbol) : void 0;
1990
+ const resolvedSymbol = hyperCore?.symbol ?? symbol;
1991
+ const resolvedDecimals = hyperCore?.decimals ?? backendDecimals ?? 18;
1983
1992
  return {
1984
1993
  chainId,
1985
1994
  address,
@@ -1990,6 +1999,15 @@ function normalizeDirectToken(token) {
1990
1999
  balanceUsd
1991
2000
  };
1992
2001
  }
2002
+ function runtimeEvmAddress(chainId, symbol) {
2003
+ const token = getRuntimeToken(chainId, symbol);
2004
+ return token && /^0x[a-fA-F0-9]{40}$/.test(token.address) ? token.address : void 0;
2005
+ }
2006
+ function hyperCoreSourceToken(address, symbol) {
2007
+ return HYPERCORE_SOURCE_TOKENS.find(
2008
+ (t) => address ? t.address.toLowerCase() === address.toLowerCase() : t.symbol.toUpperCase() === symbol.trim().toUpperCase()
2009
+ );
2010
+ }
1993
2011
  function extractTokenAddress(tokenData, chainId) {
1994
2012
  const token = tokenData;
1995
2013
  return token.tokenAddress ?? token.address ?? token.addresses?.[chainId] ?? token.token?.address ?? token.token?.addresses?.[chainId];
@@ -2261,7 +2279,7 @@ function needsViemChains(catalog, overrides) {
2261
2279
  }
2262
2280
 
2263
2281
  // src/core/chain-catalog-context.tsx
2264
- import { jsx as jsx3 } from "react/jsx-runtime";
2282
+ import { jsx as jsx2 } from "react/jsx-runtime";
2265
2283
  var EMPTY = {
2266
2284
  catalog: null,
2267
2285
  viemChains: null,
@@ -2335,6 +2353,7 @@ function publishRuntimeChainMeta(catalog) {
2335
2353
  name: chain.name,
2336
2354
  iconUrl: chain.iconUrl ?? void 0,
2337
2355
  nativeSymbol: chain.nativeToken.symbol,
2356
+ nativeDecimals: chain.nativeToken.decimals,
2338
2357
  explorerUrl: chain.explorer?.url,
2339
2358
  explorerTxPath: chain.explorer?.txPath,
2340
2359
  explorerAddressPath: chain.explorer?.addressPath
@@ -2496,10 +2515,10 @@ function useRuntimeChainsVersion() {
2496
2515
  );
2497
2516
  }
2498
2517
  function useReadClient(chainId, rpcUrls) {
2499
- const version = useRuntimeChainsVersion();
2518
+ const version2 = useRuntimeChainsVersion();
2500
2519
  return useMemo2(
2501
2520
  () => getPublicClient(chainId, rpcUrls),
2502
- [chainId, rpcUrls, version]
2521
+ [chainId, rpcUrls, version2]
2503
2522
  );
2504
2523
  }
2505
2524
  function useExplorerTxUrl() {
@@ -2617,27 +2636,303 @@ function ChainCatalogProvider({
2617
2636
  clientCapableChainIds
2618
2637
  ]
2619
2638
  );
2620
- return /* @__PURE__ */ jsx3(ChainCatalogContext.Provider, { value, children });
2639
+ return /* @__PURE__ */ jsx2(ChainCatalogContext.Provider, { value, children });
2640
+ }
2641
+
2642
+ // src/core/asset-metadata.tsx
2643
+ import {
2644
+ createContext as createContext3,
2645
+ useContext as useContext3,
2646
+ useEffect as useEffect3,
2647
+ useMemo as useMemo3,
2648
+ useSyncExternalStore as useSyncExternalStore2
2649
+ } from "react";
2650
+
2651
+ // src/core/asset-id.ts
2652
+ var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
2653
+ var EVM_ADDRESS_RE = /^0x[a-fA-F0-9]{40}$/;
2654
+ var BASE58_RE = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;
2655
+ var SOLANA_SYSTEM_PROGRAM2 = "11111111111111111111111111111111";
2656
+ function isNativeSpelling(chain, address) {
2657
+ if (chain === "solana") {
2658
+ return address === "native" || address === SOLANA_SYSTEM_PROGRAM2;
2659
+ }
2660
+ if (chain === "stellar") return address === "native";
2661
+ if (chain === "tron") return address === "native" || address === ZERO_ADDRESS;
2662
+ return address.toLowerCase() === ZERO_ADDRESS;
2663
+ }
2664
+ function assetIdFor(chain, address) {
2665
+ if (chain === void 0 || !address) return void 0;
2666
+ const native = isNativeSpelling(chain, address);
2667
+ if (chain === "hypercore" || chain === HYPERCORE_CHAIN_ID) {
2668
+ if (!EVM_ADDRESS_RE.test(address)) return void 0;
2669
+ return `${HYPERCORE_SPOT_CAIP2}:${native ? "native" : address.toLowerCase()}`;
2670
+ }
2671
+ if (typeof chain === "number") {
2672
+ if (!EVM_ADDRESS_RE.test(address)) return void 0;
2673
+ return `${toEvmCaip2(chain)}:${native ? "native" : address.toLowerCase()}`;
2674
+ }
2675
+ if (chain === "solana") {
2676
+ if (native) return `${SOLANA_MAINNET_CAIP2}:native`;
2677
+ return BASE58_RE.test(address) ? `${SOLANA_MAINNET_CAIP2}:${address}` : void 0;
2678
+ }
2679
+ const caip2 = chain === "tron" ? TRON_MAINNET_CAIP2 : STELLAR_PUBNET_CAIP2;
2680
+ return `${caip2}:${native ? "native" : address}`;
2681
+ }
2682
+ function assetIdForRef(ref) {
2683
+ return ref ? assetIdFor(ref.chain, ref.address) : void 0;
2621
2684
  }
2622
2685
 
2623
- // src/core/useLatestRef.ts
2624
- import { useEffect as useEffect3, useRef as useRef2 } from "react";
2625
- function useLatestRef(value) {
2626
- const ref = useRef2(value);
2686
+ // src/core/asset-metadata.tsx
2687
+ import { jsx as jsx3 } from "react/jsx-runtime";
2688
+ var ASSET_RETRY_MS = 6e4;
2689
+ var ASSET_PRICE_TTL_MS = 6e4;
2690
+ var META_FIELDS = ["symbol", "decimals", "logo"];
2691
+ var PRICE_FIELDS = ["price"];
2692
+ var TERMINAL_ITEM_ERRORS = /* @__PURE__ */ new Set([
2693
+ "not_found",
2694
+ "unsupported_chain",
2695
+ "invalid_id"
2696
+ ]);
2697
+ function createAssetStore(service, now = Date.now) {
2698
+ const meta = /* @__PURE__ */ new Map();
2699
+ const prices = /* @__PURE__ */ new Map();
2700
+ const metaInFlight = /* @__PURE__ */ new Set();
2701
+ const priceInFlight = /* @__PURE__ */ new Set();
2702
+ let metaQueue = /* @__PURE__ */ new Set();
2703
+ let priceQueue = /* @__PURE__ */ new Set();
2704
+ let flushScheduled = false;
2705
+ let routeMissing = false;
2706
+ let version2 = 0;
2707
+ const listeners2 = /* @__PURE__ */ new Set();
2708
+ function notify() {
2709
+ version2 += 1;
2710
+ for (const listener of [...listeners2]) listener();
2711
+ }
2712
+ function idsFor(refs) {
2713
+ const ids = [];
2714
+ for (const ref of refs) {
2715
+ const id = assetIdForRef(ref);
2716
+ if (!id) continue;
2717
+ ids.push(id);
2718
+ }
2719
+ return ids;
2720
+ }
2721
+ function scheduleFlush() {
2722
+ if (flushScheduled) return;
2723
+ flushScheduled = true;
2724
+ queueMicrotask(() => {
2725
+ flushScheduled = false;
2726
+ const metaIds = [...metaQueue];
2727
+ const priceIds = [...priceQueue];
2728
+ metaQueue = /* @__PURE__ */ new Set();
2729
+ priceQueue = /* @__PURE__ */ new Set();
2730
+ if (metaIds.length > 0) void flushMeta(metaIds);
2731
+ if (priceIds.length > 0) void flushPrices(priceIds);
2732
+ });
2733
+ }
2734
+ function needsMeta(id) {
2735
+ if (metaInFlight.has(id) || metaQueue.has(id)) return false;
2736
+ const entry = meta.get(id);
2737
+ if (!entry) return true;
2738
+ if (entry.status === "missing" || entry.status === "pending") return false;
2739
+ if (entry.status === "failed" && routeMissing) return false;
2740
+ return entry.retryAt !== void 0 && now() >= entry.retryAt;
2741
+ }
2742
+ function needsPrice(id) {
2743
+ if (priceInFlight.has(id) || priceQueue.has(id)) return false;
2744
+ const entry = prices.get(id);
2745
+ return !entry || now() - entry.at >= ASSET_PRICE_TTL_MS;
2746
+ }
2747
+ async function lookup2(ids, fields) {
2748
+ try {
2749
+ return await service.lookupAssets(ids, fields);
2750
+ } catch {
2751
+ return { ok: false, routeMissing: false };
2752
+ }
2753
+ }
2754
+ async function flushMeta(ids) {
2755
+ for (const id of ids) metaInFlight.add(id);
2756
+ const result = await lookup2(ids, META_FIELDS);
2757
+ const at = now();
2758
+ for (const id of ids) {
2759
+ metaInFlight.delete(id);
2760
+ const previous = meta.get(id);
2761
+ if (!result.ok) {
2762
+ if (result.routeMissing) routeMissing = true;
2763
+ meta.set(id, {
2764
+ ...previous,
2765
+ status: previous?.status === "ready" ? "ready" : "failed",
2766
+ retryAt: at + ASSET_RETRY_MS
2767
+ });
2768
+ continue;
2769
+ }
2770
+ const item = result.items[id];
2771
+ const code = item?.error?.code;
2772
+ if (!item || code && TERMINAL_ITEM_ERRORS.has(code)) {
2773
+ meta.set(id, { status: "missing" });
2774
+ continue;
2775
+ }
2776
+ meta.set(id, {
2777
+ status: "ready",
2778
+ symbol: item.symbol ?? previous?.symbol,
2779
+ decimals: item.decimals ?? previous?.decimals,
2780
+ logo: item.logo ?? previous?.logo,
2781
+ retryAt: code ? at + ASSET_RETRY_MS : void 0
2782
+ });
2783
+ }
2784
+ notify();
2785
+ }
2786
+ async function flushPrices(ids) {
2787
+ for (const id of ids) priceInFlight.add(id);
2788
+ const result = await lookup2(ids, PRICE_FIELDS);
2789
+ const at = now();
2790
+ for (const id of ids) {
2791
+ priceInFlight.delete(id);
2792
+ prices.set(id, {
2793
+ usd: result.ok ? result.items[id]?.priceUsd ?? null : null,
2794
+ at
2795
+ });
2796
+ }
2797
+ notify();
2798
+ }
2799
+ function requestMeta(refs) {
2800
+ let queued = false;
2801
+ for (const id of idsFor(refs)) {
2802
+ if (!needsMeta(id)) continue;
2803
+ metaQueue.add(id);
2804
+ queued = true;
2805
+ }
2806
+ if (queued) scheduleFlush();
2807
+ }
2808
+ function requestPrices(refs) {
2809
+ let queued = false;
2810
+ for (const id of idsFor(refs)) {
2811
+ if (!needsPrice(id)) continue;
2812
+ priceQueue.add(id);
2813
+ queued = true;
2814
+ }
2815
+ if (queued) scheduleFlush();
2816
+ }
2817
+ function settled(test) {
2818
+ if (test()) return Promise.resolve();
2819
+ return new Promise((resolve) => {
2820
+ const unsubscribe = subscribe(() => {
2821
+ if (!test()) return;
2822
+ unsubscribe();
2823
+ resolve();
2824
+ });
2825
+ });
2826
+ }
2827
+ function subscribe(listener) {
2828
+ listeners2.add(listener);
2829
+ return () => {
2830
+ listeners2.delete(listener);
2831
+ };
2832
+ }
2833
+ function peekMeta(id) {
2834
+ const entry = meta.get(id);
2835
+ if (!entry) {
2836
+ return metaInFlight.has(id) || metaQueue.has(id) ? { status: "pending" } : void 0;
2837
+ }
2838
+ const { retryAt: _retryAt, ...rest } = entry;
2839
+ return rest;
2840
+ }
2841
+ return {
2842
+ subscribe,
2843
+ getVersion: () => version2,
2844
+ requestMeta,
2845
+ requestPrices,
2846
+ peekMeta,
2847
+ peekPrice: (id) => prices.get(id)?.usd,
2848
+ async resolveMeta(refs) {
2849
+ const ids = idsFor(refs);
2850
+ requestMeta(refs);
2851
+ await settled(
2852
+ () => ids.every((id) => !metaInFlight.has(id) && !metaQueue.has(id))
2853
+ );
2854
+ return Object.fromEntries(
2855
+ ids.map((id) => [id, peekMeta(id) ?? { status: "missing" }])
2856
+ );
2857
+ },
2858
+ async resolvePrice(ref) {
2859
+ const [id] = idsFor([ref]);
2860
+ if (!id) return null;
2861
+ requestPrices([ref]);
2862
+ await settled(() => !priceInFlight.has(id) && !priceQueue.has(id));
2863
+ return prices.get(id)?.usd ?? null;
2864
+ }
2865
+ };
2866
+ }
2867
+ var AssetStoreContext = createContext3(null);
2868
+ function AssetMetadataProvider({
2869
+ service,
2870
+ children
2871
+ }) {
2872
+ const store = useMemo3(() => createAssetStore(service), [service]);
2873
+ return /* @__PURE__ */ jsx3(AssetStoreContext.Provider, { value: store, children });
2874
+ }
2875
+ function useAssetStore() {
2876
+ return useContext3(AssetStoreContext);
2877
+ }
2878
+ var noopSubscribe = () => () => {
2879
+ };
2880
+ var zero = () => 0;
2881
+ function useStoreVersion(store) {
2882
+ return useSyncExternalStore2(
2883
+ store ? store.subscribe : noopSubscribe,
2884
+ store ? store.getVersion : zero,
2885
+ store ? store.getVersion : zero
2886
+ );
2887
+ }
2888
+ function refsKey(refs) {
2889
+ return refs.map((ref) => assetIdForRef(ref) ?? "").filter(Boolean).join("|");
2890
+ }
2891
+ function definedRefs(refs) {
2892
+ return refs.filter((ref) => Boolean(ref));
2893
+ }
2894
+ function useAssetMetadata(refs) {
2895
+ const store = useAssetStore();
2896
+ const version2 = useStoreVersion(store);
2897
+ const key = refsKey(refs);
2898
+ useEffect3(() => {
2899
+ if (store && key) store.requestMeta(definedRefs(refs));
2900
+ }, [store, key]);
2901
+ return useMemo3(() => {
2902
+ const out = {};
2903
+ if (!store || !key) return out;
2904
+ for (const id of key.split("|")) {
2905
+ out[id] = store.peekMeta(id) ?? { status: "pending" };
2906
+ }
2907
+ return out;
2908
+ }, [store, key, version2]);
2909
+ }
2910
+ function useAssetPrices(refs) {
2911
+ const store = useAssetStore();
2912
+ const version2 = useStoreVersion(store);
2913
+ const key = refsKey(refs);
2627
2914
  useEffect3(() => {
2628
- ref.current = value;
2629
- }, [value]);
2630
- return ref;
2915
+ if (store && key) store.requestPrices(definedRefs(refs));
2916
+ }, [store, key]);
2917
+ return useMemo3(() => {
2918
+ const out = {};
2919
+ if (!store || !key) return out;
2920
+ for (const id of key.split("|")) {
2921
+ const usd = store.peekPrice(id);
2922
+ if (typeof usd === "number") out[id] = usd;
2923
+ }
2924
+ return out;
2925
+ }, [store, key, version2]);
2631
2926
  }
2632
2927
 
2633
2928
  // src/core/analytics.tsx
2634
2929
  import {
2635
- createContext as createContext3,
2930
+ createContext as createContext4,
2636
2931
  useCallback as useCallback3,
2637
- useContext as useContext3,
2932
+ useContext as useContext4,
2638
2933
  useEffect as useEffect4,
2639
- useMemo as useMemo3,
2640
- useRef as useRef3
2934
+ useMemo as useMemo4,
2935
+ useRef as useRef2
2641
2936
  } from "react";
2642
2937
 
2643
2938
  // src/core/analytics-ingest.ts
@@ -2986,7 +3281,7 @@ function resolveProxyOrigin(backendUrl) {
2986
3281
 
2987
3282
  // src/core/analytics.tsx
2988
3283
  import { jsx as jsx4 } from "react/jsx-runtime";
2989
- var AnalyticsContext = createContext3(null);
3284
+ var AnalyticsContext = createContext4(null);
2990
3285
  var noopDepositEmitter = () => {
2991
3286
  };
2992
3287
  var noopWithdrawEmitter = () => {
@@ -3006,21 +3301,21 @@ function cloneAndFreeze(value) {
3006
3301
  return value;
3007
3302
  }
3008
3303
  function AnalyticsSession(props) {
3009
- const sessionIdRef = useRef3(void 0);
3304
+ const sessionIdRef = useRef2(void 0);
3010
3305
  if (sessionIdRef.current === void 0) {
3011
3306
  sessionIdRef.current = (props.createSessionId ?? randomUuid)();
3012
3307
  }
3013
- const sessionPropertiesRef = useRef3(void 0);
3308
+ const sessionPropertiesRef = useRef2(void 0);
3014
3309
  if (sessionPropertiesRef.current === void 0) {
3015
3310
  sessionPropertiesRef.current = cloneAndFreeze(props.sessionProperties);
3016
3311
  }
3017
3312
  if (props.sessionIdRef) props.sessionIdRef.current = sessionIdRef.current;
3018
- const onEventRef = useRef3(props.onEvent);
3313
+ const onEventRef = useRef2(props.onEvent);
3019
3314
  onEventRef.current = props.onEvent;
3020
- const nowRef = useRef3(props.now ?? (() => /* @__PURE__ */ new Date()));
3315
+ const nowRef = useRef2(props.now ?? (() => /* @__PURE__ */ new Date()));
3021
3316
  nowRef.current = props.now ?? (() => /* @__PURE__ */ new Date());
3022
3317
  const modal = props.modal;
3023
- const reportedFailuresRef = useRef3(/* @__PURE__ */ new Set());
3318
+ const reportedFailuresRef = useRef2(/* @__PURE__ */ new Set());
3024
3319
  const emitFailure = useCallback3(
3025
3320
  ({ reason, status, droppedEvents }) => {
3026
3321
  if (reportedFailuresRef.current.has(reason)) return;
@@ -3066,11 +3361,11 @@ function AnalyticsSession(props) {
3066
3361
  initialFailure: null
3067
3362
  };
3068
3363
  }
3069
- const ingestRef = useRef3(void 0);
3364
+ const ingestRef = useRef2(void 0);
3070
3365
  if (ingestRef.current === void 0) {
3071
3366
  ingestRef.current = createIngest();
3072
3367
  }
3073
- const pendingDisposalRef = useRef3(null);
3368
+ const pendingDisposalRef = useRef2(null);
3074
3369
  const enqueue = useCallback3(
3075
3370
  (event) => {
3076
3371
  try {
@@ -3157,24 +3452,24 @@ function AnalyticsSession(props) {
3157
3452
  },
3158
3453
  [enqueue, modal, nowRef, onEventRef]
3159
3454
  );
3160
- const context = useMemo3(
3455
+ const context = useMemo4(
3161
3456
  () => modal === "deposit" ? { modal, emit: emitDeposit } : modal === "withdraw" ? { modal, emit: emitWithdraw } : { modal, emit: emitClaim },
3162
3457
  [modal, emitDeposit, emitWithdraw, emitClaim]
3163
3458
  );
3164
3459
  return /* @__PURE__ */ jsx4(AnalyticsContext.Provider, { value: context, children: props.children });
3165
3460
  }
3166
3461
  function useDepositAnalyticsEmitter() {
3167
- const context = useContext3(AnalyticsContext);
3462
+ const context = useContext4(AnalyticsContext);
3168
3463
  if (!context || context.modal !== "deposit") return noopDepositEmitter;
3169
3464
  return context.emit;
3170
3465
  }
3171
3466
  function useWithdrawAnalyticsEmitter() {
3172
- const context = useContext3(AnalyticsContext);
3467
+ const context = useContext4(AnalyticsContext);
3173
3468
  if (!context || context.modal !== "withdraw") return noopWithdrawEmitter;
3174
3469
  return context.emit;
3175
3470
  }
3176
3471
  function useClaimAnalyticsEmitter() {
3177
- const context = useContext3(AnalyticsContext);
3472
+ const context = useContext4(AnalyticsContext);
3178
3473
  if (!context || context.modal !== "claim") return noopClaimEmitter;
3179
3474
  return context.emit;
3180
3475
  }
@@ -3202,7 +3497,7 @@ function toRecoverableDeposit(row, options = {}) {
3202
3497
  return {
3203
3498
  depositId: row.id,
3204
3499
  signer,
3205
- destinationPrefill: signer,
3500
+ depositAddress: row.depositAddress,
3206
3501
  sourceChainId,
3207
3502
  targetChainId,
3208
3503
  token: row.token,
@@ -3210,6 +3505,12 @@ function toRecoverableDeposit(row, options = {}) {
3210
3505
  sourceTxHash: sourceDepositTxHash(row)
3211
3506
  };
3212
3507
  }
3508
+ function isDepositSelfDestination(row, destination) {
3509
+ const depositAddress = row.depositAddress?.trim();
3510
+ const candidate = destination.trim();
3511
+ if (!depositAddress || !candidate) return false;
3512
+ return depositAddress.toLowerCase() === candidate.toLowerCase();
3513
+ }
3213
3514
  function recoveryFailureCause(sourceChainName) {
3214
3515
  return sourceChainName ? `This deposit couldn't be completed. Your funds are still on ${sourceChainName}.` : "This deposit couldn't be completed and your funds were not moved.";
3215
3516
  }
@@ -3307,26 +3608,27 @@ function historyBadgeAriaLabel(badge) {
3307
3608
  }
3308
3609
 
3309
3610
  // src/components/history/HistoryEntryButton.tsx
3310
- import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
3611
+ import { jsx as jsx5, jsxs } from "react/jsx-runtime";
3311
3612
  function HistoryEntryButton({
3312
3613
  badge,
3313
3614
  onClick,
3314
- disabled
3615
+ disabled,
3616
+ unread = false
3315
3617
  }) {
3316
- return /* @__PURE__ */ jsxs2(
3618
+ return /* @__PURE__ */ jsxs(
3317
3619
  "button",
3318
3620
  {
3319
3621
  type: "button",
3320
3622
  className: "rs-modal-header-history",
3321
- "aria-label": historyBadgeAriaLabel(badge),
3623
+ "aria-label": unread ? "Deposit history \u2014 new bank transfer activity" : historyBadgeAriaLabel(badge),
3322
3624
  onClick,
3323
3625
  disabled,
3324
3626
  children: [
3325
3627
  /* @__PURE__ */ jsx5(HistoryIcon, {}),
3326
- badge && /* @__PURE__ */ jsx5(
3628
+ (badge || unread) && /* @__PURE__ */ jsx5(
3327
3629
  "span",
3328
3630
  {
3329
- className: `rs-history-dot rs-history-dot--${badge.state}`,
3631
+ className: `rs-history-dot rs-history-dot--${badge?.state ?? "progress"}`,
3330
3632
  "aria-hidden": "true"
3331
3633
  }
3332
3634
  )
@@ -3336,16 +3638,16 @@ function HistoryEntryButton({
3336
3638
  }
3337
3639
 
3338
3640
  // src/components/history/HistoryOverlay.tsx
3339
- import { useCallback as useCallback7, useEffect as useEffect10, useMemo as useMemo6, useRef as useRef7, useState as useState8 } from "react";
3641
+ import { useCallback as useCallback7, useEffect as useEffect10, useMemo as useMemo8, useRef as useRef6, useState as useState9 } from "react";
3340
3642
 
3341
3643
  // src/components/history/DepositHistoryPanel.tsx
3342
3644
  import {
3343
3645
  useCallback as useCallback4,
3344
3646
  useEffect as useEffect5,
3345
- useId,
3346
- useMemo as useMemo4,
3347
- useRef as useRef4,
3348
- useState as useState3
3647
+ useId as useId2,
3648
+ useMemo as useMemo6,
3649
+ useRef as useRef3,
3650
+ useState as useState4
3349
3651
  } from "react";
3350
3652
 
3351
3653
  // src/components/ui/CdnIcon.tsx
@@ -3396,65 +3698,8 @@ function CdnIcon({
3396
3698
  }
3397
3699
  CdnIcon.displayName = "CdnIcon";
3398
3700
 
3399
- // src/components/ui/BodyHeader.tsx
3400
- import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
3401
- function BodyHeader({
3402
- icon,
3403
- title,
3404
- subtitle,
3405
- variant = "default",
3406
- aside
3407
- }) {
3408
- const iconClasses = [
3409
- "rs-body-header-icon",
3410
- variant === "success" ? "rs-body-header-icon--success" : "",
3411
- variant === "error" ? "rs-body-header-icon--error" : ""
3412
- ].filter(Boolean).join(" ");
3413
- return /* @__PURE__ */ jsxs3("div", { className: "rs-body-header", children: [
3414
- /* @__PURE__ */ jsx7("div", { className: iconClasses, children: icon }),
3415
- /* @__PURE__ */ jsxs3("div", { className: "rs-body-header-main", children: [
3416
- /* @__PURE__ */ jsxs3("div", { className: "rs-body-header-text", children: [
3417
- /* @__PURE__ */ jsx7("h2", { className: "rs-body-header-title", children: title }),
3418
- subtitle && /* @__PURE__ */ jsx7("p", { className: "rs-body-header-subtitle", children: subtitle })
3419
- ] }),
3420
- aside && /* @__PURE__ */ jsx7("div", { className: "rs-body-header-aside", children: aside })
3421
- ] })
3422
- ] });
3423
- }
3424
- BodyHeader.displayName = "BodyHeader";
3425
-
3426
- // src/components/ui/Spinner.tsx
3427
- import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
3428
- function Spinner({ className }) {
3429
- return /* @__PURE__ */ jsxs4(
3430
- "svg",
3431
- {
3432
- className: `rs-spinner ${className || ""}`,
3433
- fill: "none",
3434
- viewBox: "0 0 20 21",
3435
- children: [
3436
- /* @__PURE__ */ jsx8(
3437
- "path",
3438
- {
3439
- d: "M10 0.5C8.02 0.5 6.08 1.08 4.44 2.18C2.79 3.28 1.51 4.84 0.76 6.67C0.00 8.50 -0.19 10.51 0.19 12.45C0.57 14.39 1.53 16.17 2.92 17.57C4.32 18.96 6.10 19.92 8.04 20.30C9.98 20.69 11.99 20.49 13.82 19.73C15.65 18.98 17.21 17.70 18.31 16.05C19.41 14.41 20 12.47 20 10.5C20 7.84 18.94 5.30 17.07 3.42C15.19 1.55 12.65 0.5 10 0.5ZM10 17.77C8.56 17.77 7.15 17.34 5.95 16.54C4.76 15.74 3.83 14.61 3.28 13.28C2.73 11.95 2.58 10.49 2.86 9.08C3.14 7.67 3.84 6.37 4.85 5.35C5.87 4.34 7.17 3.64 8.58 3.36C9.99 3.08 11.45 3.23 12.78 3.78C14.11 4.33 15.24 5.26 16.04 6.45C16.84 7.65 17.27 9.06 17.27 10.5C17.27 12.42 16.50 14.27 15.14 15.64C13.77 17.00 11.92 17.77 10 17.77Z",
3440
- fill: "currentColor",
3441
- opacity: 0.3
3442
- }
3443
- ),
3444
- /* @__PURE__ */ jsx8(
3445
- "path",
3446
- {
3447
- d: "M10 3.22C11.74 3.22 13.42 3.84 14.75 4.95C16.08 6.07 16.96 7.61 17.25 9.31C17.30 9.64 17.46 9.94 17.71 10.15C17.96 10.37 18.28 10.49 18.62 10.5C18.82 10.50 19.01 10.45 19.20 10.37C19.38 10.29 19.54 10.16 19.67 10.01C19.80 9.86 19.89 9.68 19.95 9.49C20.00 9.30 20.01 9.10 19.98 8.90C19.59 6.56 18.38 4.42 16.55 2.88C14.72 1.34 12.40 0.5 10 0.5C7.59 0.5 5.27 1.34 3.44 2.88C1.61 4.42 0.40 6.56 0.01 8.90C-0.01 9.10 -0.00 9.30 0.04 9.49C0.10 9.68 0.19 9.86 0.32 10.01C0.45 10.16 0.61 10.29 0.79 10.37C0.98 10.45 1.17 10.50 1.37 10.5C1.71 10.49 2.03 10.37 2.28 10.15C2.53 9.94 2.69 9.64 2.74 9.31C3.03 7.61 3.91 6.07 5.24 4.95C6.57 3.84 8.25 3.22 10 3.22Z",
3448
- fill: "currentColor"
3449
- }
3450
- )
3451
- ]
3452
- }
3453
- );
3454
- }
3455
-
3456
3701
  // src/components/ui/Button.tsx
3457
- import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
3702
+ import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
3458
3703
  function Button({
3459
3704
  children,
3460
3705
  variant = "accent",
@@ -3474,19 +3719,19 @@ function Button({
3474
3719
  className
3475
3720
  ].filter(Boolean).join(" ");
3476
3721
  const showInlineLoadingText = loading && loadingText !== void 0;
3477
- return /* @__PURE__ */ jsx9(
3722
+ return /* @__PURE__ */ jsx7(
3478
3723
  "button",
3479
3724
  {
3480
3725
  className: classes,
3481
3726
  disabled: disabled || loading,
3482
3727
  "aria-busy": loading || void 0,
3483
3728
  ...props,
3484
- children: showInlineLoadingText ? /* @__PURE__ */ jsxs5("span", { className: "rs-button__loading-row", children: [
3485
- /* @__PURE__ */ jsx9(Spinner, { className: "rs-spinner--sm" }),
3486
- /* @__PURE__ */ jsx9("span", { children: loadingText })
3487
- ] }) : /* @__PURE__ */ jsxs5(Fragment2, { children: [
3488
- /* @__PURE__ */ jsx9("span", { className: loading ? "rs-button__content--hidden" : "", children }),
3489
- loading && /* @__PURE__ */ jsx9("span", { className: "rs-button__spinner", children: /* @__PURE__ */ jsx9(Spinner, { className: "rs-spinner--sm" }) })
3729
+ children: showInlineLoadingText ? /* @__PURE__ */ jsxs2("span", { className: "rs-button__loading-row", children: [
3730
+ /* @__PURE__ */ jsx7(Spinner, { className: "rs-spinner--sm" }),
3731
+ /* @__PURE__ */ jsx7("span", { children: loadingText })
3732
+ ] }) : /* @__PURE__ */ jsxs2(Fragment2, { children: [
3733
+ /* @__PURE__ */ jsx7("span", { className: loading ? "rs-button__content--hidden" : "", children }),
3734
+ loading && /* @__PURE__ */ jsx7("span", { className: "rs-button__spinner", children: /* @__PURE__ */ jsx7(Spinner, { className: "rs-spinner--sm" }) })
3490
3735
  ] })
3491
3736
  }
3492
3737
  );
@@ -3494,9 +3739,9 @@ function Button({
3494
3739
  Button.displayName = "Button";
3495
3740
 
3496
3741
  // src/components/ui/Callout.tsx
3497
- import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
3742
+ import { jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
3498
3743
  function CircleAlertIcon() {
3499
- return /* @__PURE__ */ jsx10(
3744
+ return /* @__PURE__ */ jsx8(
3500
3745
  "svg",
3501
3746
  {
3502
3747
  width: "16",
@@ -3505,7 +3750,7 @@ function CircleAlertIcon() {
3505
3750
  fill: "none",
3506
3751
  xmlns: "http://www.w3.org/2000/svg",
3507
3752
  "aria-hidden": "true",
3508
- children: /* @__PURE__ */ jsx10(
3753
+ children: /* @__PURE__ */ jsx8(
3509
3754
  "path",
3510
3755
  {
3511
3756
  d: "M10 5.99L6 9.99M6 5.99L10 9.99M14.66 7.99C14.66 11.68 11.68 14.66 8 14.66C4.31 14.66 1.33 11.68 1.33 7.99C1.33 4.31 4.31 1.33 8 1.33C11.68 1.33 14.66 4.31 14.66 7.99Z",
@@ -3519,14 +3764,14 @@ function CircleAlertIcon() {
3519
3764
  );
3520
3765
  }
3521
3766
  function Callout({ variant = "error", children, role }) {
3522
- return /* @__PURE__ */ jsxs6(
3767
+ return /* @__PURE__ */ jsxs3(
3523
3768
  "div",
3524
3769
  {
3525
3770
  className: `rs-callout rs-callout--${variant}`,
3526
3771
  role: role ?? (variant === "error" ? "alert" : "status"),
3527
3772
  children: [
3528
- /* @__PURE__ */ jsx10("span", { className: "rs-callout-icon", children: variant === "error" ? /* @__PURE__ */ jsx10(CircleAlertIcon, {}) : /* @__PURE__ */ jsx10(AlertTriangleIcon, {}) }),
3529
- /* @__PURE__ */ jsx10("span", { className: "rs-callout-text", children })
3773
+ /* @__PURE__ */ jsx8("span", { className: "rs-callout-icon", children: variant === "error" ? /* @__PURE__ */ jsx8(CircleAlertIcon, {}) : /* @__PURE__ */ jsx8(AlertTriangleIcon, {}) }),
3774
+ /* @__PURE__ */ jsx8("span", { className: "rs-callout-text", children })
3530
3775
  ]
3531
3776
  }
3532
3777
  );
@@ -3534,8 +3779,8 @@ function Callout({ variant = "error", children, role }) {
3534
3779
  Callout.displayName = "Callout";
3535
3780
 
3536
3781
  // src/components/ui/PoweredBy.tsx
3537
- import { jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
3538
- var rhinestoneLogo = /* @__PURE__ */ jsxs7(
3782
+ import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
3783
+ var rhinestoneLogo = /* @__PURE__ */ jsxs4(
3539
3784
  "svg",
3540
3785
  {
3541
3786
  className: "rs-powered-by-logo",
@@ -3544,8 +3789,8 @@ var rhinestoneLogo = /* @__PURE__ */ jsxs7(
3544
3789
  xmlns: "http://www.w3.org/2000/svg",
3545
3790
  "aria-hidden": "true",
3546
3791
  children: [
3547
- /* @__PURE__ */ jsxs7("g", { fill: "currentColor", clipPath: "url(#rs-pb-clip)", children: [
3548
- /* @__PURE__ */ jsx11(
3792
+ /* @__PURE__ */ jsxs4("g", { fill: "currentColor", clipPath: "url(#rs-pb-clip)", children: [
3793
+ /* @__PURE__ */ jsx9(
3549
3794
  "path",
3550
3795
  {
3551
3796
  opacity: "0.5",
@@ -3554,8 +3799,8 @@ var rhinestoneLogo = /* @__PURE__ */ jsxs7(
3554
3799
  d: "M10.48 14.82a4.3 4.3 0 0 1-2.9 1 4.3 4.3 0 0 1-2.4-1 25 25 0 0 1-2.08-1.95l-.13-.13c-.78-.78-1.46-1.46-1.94-2.08a4.3 4.3 0 0 1-1-2.9c.05-.96.48-1.72 1-2.4a25 25 0 0 1 1.94-2.08l.07-.06.06-.07a25 25 0 0 1 2.08-1.94 4.3 4.3 0 0 1 2.9-1c.96.05 1.73.48 2.4 1 .62.49 1.3 1.17 2.08 1.94l.13.13c.77.78 1.46 1.46 1.94 2.09a4.3 4.3 0 0 1 1 2.9 4.3 4.3 0 0 1-1 2.39c-.48.62-1.17 1.3-1.94 2.08l-.07.07-.06.06c-.78.78-1.46 1.46-2.08 1.94m-8.9-6.63c.07 1.02.9 1.86 2.56 3.52s2.5 2.5 3.53 2.56h.32c1.03-.06 1.86-.9 3.53-2.56s2.5-2.5 2.56-3.52v-.33c-.07-1.03-.9-1.86-2.56-3.52-1.67-1.67-2.5-2.5-3.53-2.56h-.32c-1.03.06-1.86.89-3.53 2.56-1.66 1.66-2.5 2.5-2.56 3.52z"
3555
3800
  }
3556
3801
  ),
3557
- /* @__PURE__ */ jsx11("path", { d: "M3.66 8.01q.02-.27.28-.35a4.6 4.6 0 0 0 2.53-1.48q.72-.8 1-2.05a.4.4 0 0 1 .36-.29c.17 0 .32.12.36.29a4.6 4.6 0 0 0 1.47 2.52c.55.49 1.21.8 2.06 1a.4.4 0 0 1 .28.36.4.4 0 0 1-.28.36 4.6 4.6 0 0 0-2.53 1.47 4.6 4.6 0 0 0-1 2.06.4.4 0 0 1-.36.28.4.4 0 0 1-.36-.28A4.6 4.6 0 0 0 6 9.38a4.6 4.6 0 0 0-2.06-1.01.4.4 0 0 1-.28-.36m26.46-3.44c0 .51.38.87.96.87s.95-.36.95-.87c0-.52-.37-.86-.95-.86s-.96.34-.96.86m.2 1.44v5.33h1.53V6.01zm-4.4 5.33h-1.55V3.88h1.54v2.98c.25-.5.8-1.01 1.6-1.01 1.29 0 1.87.83 1.87 2.28v3.21h-1.54V8.3c0-.77-.34-1.16-.92-1.16-.67 0-1 .53-1 1.3zm-4.45 0h-1.54V6.01h1.54l-.27 1.22a.1.1 0 0 0 .02.1.1.1 0 0 0 .1.04q.09 0 .1-.09c.24-.84.93-1.36 1.64-1.36q.4.01.57.05v1.42l-.67-.04c-.67 0-1.5.31-1.5 2zm13 0h-1.55V6.01h1.54l-.02.9a1.8 1.8 0 0 1 1.61-1.06c1.3 0 1.88.83 1.88 2.28v3.21H36.4V8.3c0-.77-.35-1.16-.93-1.16-.67 0-1 .53-1 1.3z" }),
3558
- /* @__PURE__ */ jsx11(
3802
+ /* @__PURE__ */ jsx9("path", { d: "M3.66 8.01q.02-.27.28-.35a4.6 4.6 0 0 0 2.53-1.48q.72-.8 1-2.05a.4.4 0 0 1 .36-.29c.17 0 .32.12.36.29a4.6 4.6 0 0 0 1.47 2.52c.55.49 1.21.8 2.06 1a.4.4 0 0 1 .28.36.4.4 0 0 1-.28.36 4.6 4.6 0 0 0-2.53 1.47 4.6 4.6 0 0 0-1 2.06.4.4 0 0 1-.36.28.4.4 0 0 1-.36-.28A4.6 4.6 0 0 0 6 9.38a4.6 4.6 0 0 0-2.06-1.01.4.4 0 0 1-.28-.36m26.46-3.44c0 .51.38.87.96.87s.95-.36.95-.87c0-.52-.37-.86-.95-.86s-.96.34-.96.86m.2 1.44v5.33h1.53V6.01zm-4.4 5.33h-1.55V3.88h1.54v2.98c.25-.5.8-1.01 1.6-1.01 1.29 0 1.87.83 1.87 2.28v3.21h-1.54V8.3c0-.77-.34-1.16-.92-1.16-.67 0-1 .53-1 1.3zm-4.45 0h-1.54V6.01h1.54l-.27 1.22a.1.1 0 0 0 .02.1.1.1 0 0 0 .1.04q.09 0 .1-.09c.24-.84.93-1.36 1.64-1.36q.4.01.57.05v1.42l-.67-.04c-.67 0-1.5.31-1.5 2zm13 0h-1.55V6.01h1.54l-.02.9a1.8 1.8 0 0 1 1.61-1.06c1.3 0 1.88.83 1.88 2.28v3.21H36.4V8.3c0-.77-.35-1.16-.93-1.16-.67 0-1 .53-1 1.3z" }),
3803
+ /* @__PURE__ */ jsx9(
3559
3804
  "path",
3560
3805
  {
3561
3806
  fillRule: "evenodd",
@@ -3563,8 +3808,8 @@ var rhinestoneLogo = /* @__PURE__ */ jsxs7(
3563
3808
  d: "M38.74 8.69c0 1.63 1.01 2.82 2.7 2.82 1.51 0 2.32-.82 2.55-1.73l-1.43-.26c-.1.37-.47.82-1.12.82-.67 0-1.23-.6-1.24-1.31H44q.05-.19.06-.56a2.55 2.55 0 0 0-2.6-2.63c-1.5 0-2.72 1.2-2.72 2.85m3.82-.58h-2.3a1.2 1.2 0 0 1 1.18-1.13c.6 0 1.14.45 1.12 1.13"
3564
3809
  }
3565
3810
  ),
3566
- /* @__PURE__ */ jsx11("path", { d: "M47.1 11.51c-1.2 0-2.33-.41-2.55-1.65l1.43-.21q.27.8 1.1.79c.5 0 .77-.24.77-.55 0-.27-.2-.45-.75-.55l-.5-.1c-1.1-.24-1.77-.74-1.77-1.63 0-1.06.91-1.78 2.25-1.78 1.26 0 2.2.59 2.32 1.68l-1.41.22c-.07-.52-.43-.82-.91-.82-.5 0-.75.26-.75.57 0 .25.17.42.63.51l.5.1c1.28.26 1.94.77 1.94 1.75 0 1.01-1.03 1.66-2.3 1.66" }),
3567
- /* @__PURE__ */ jsx11(
3811
+ /* @__PURE__ */ jsx9("path", { d: "M47.1 11.51c-1.2 0-2.33-.41-2.55-1.65l1.43-.21q.27.8 1.1.79c.5 0 .77-.24.77-.55 0-.27-.2-.45-.75-.55l-.5-.1c-1.1-.24-1.77-.74-1.77-1.63 0-1.06.91-1.78 2.25-1.78 1.26 0 2.2.59 2.32 1.68l-1.41.22c-.07-.52-.43-.82-.91-.82-.5 0-.75.26-.75.57 0 .25.17.42.63.51l.5.1c1.28.26 1.94.77 1.94 1.75 0 1.01-1.03 1.66-2.3 1.66" }),
3812
+ /* @__PURE__ */ jsx9(
3568
3813
  "path",
3569
3814
  {
3570
3815
  fillRule: "evenodd",
@@ -3572,8 +3817,8 @@ var rhinestoneLogo = /* @__PURE__ */ jsxs7(
3572
3817
  d: "M54.44 8.68c0 1.53 1.08 2.83 2.78 2.83s2.79-1.3 2.79-2.83c0-1.55-1.1-2.84-2.79-2.84-1.7 0-2.78 1.29-2.78 2.84m4.02 0c0 .98-.59 1.45-1.24 1.45-.64 0-1.23-.47-1.23-1.45 0-.97.59-1.47 1.23-1.47.65 0 1.24.48 1.24 1.47"
3573
3818
  }
3574
3819
  ),
3575
- /* @__PURE__ */ jsx11("path", { d: "M62.4 11.34h-1.53V6.01h1.54l-.02.9a1.8 1.8 0 0 1 1.6-1.06c1.3 0 1.89.83 1.89 2.28v3.21h-1.54V8.3c0-.77-.34-1.16-.93-1.16-.66 0-1 .53-1 1.3z" }),
3576
- /* @__PURE__ */ jsx11(
3820
+ /* @__PURE__ */ jsx9("path", { d: "M62.4 11.34h-1.53V6.01h1.54l-.02.9a1.8 1.8 0 0 1 1.6-1.06c1.3 0 1.89.83 1.89 2.28v3.21h-1.54V8.3c0-.77-.34-1.16-.93-1.16-.66 0-1 .53-1 1.3z" }),
3821
+ /* @__PURE__ */ jsx9(
3577
3822
  "path",
3578
3823
  {
3579
3824
  fillRule: "evenodd",
@@ -3581,38 +3826,280 @@ var rhinestoneLogo = /* @__PURE__ */ jsxs7(
3581
3826
  d: "M66.68 8.69c0 1.63 1.02 2.82 2.71 2.82 1.51 0 2.31-.82 2.55-1.73l-1.44-.26c-.1.37-.47.82-1.12.82-.67 0-1.23-.6-1.24-1.31h3.8q.06-.19.06-.56a2.55 2.55 0 0 0-2.6-2.63c-1.5 0-2.72 1.2-2.72 2.85m3.82-.58h-2.3a1.2 1.2 0 0 1 1.18-1.13c.6 0 1.15.45 1.12 1.13"
3582
3827
  }
3583
3828
  ),
3584
- /* @__PURE__ */ jsx11("path", { d: "M52.44 9.05V7.26h1.53V6h-1.53V4.42h-1.53V6h-1.1v1.26h1.1v1.85l.02.49a1.9 1.9 0 0 0 1.67 1.67c.22.03.47.03.62.03h.65V9.87h-.61c-.4 0-.59 0-.7-.12-.12-.11-.12-.3-.12-.64z" })
3829
+ /* @__PURE__ */ jsx9("path", { d: "M52.44 9.05V7.26h1.53V6h-1.53V4.42h-1.53V6h-1.1v1.26h1.1v1.85l.02.49a1.9 1.9 0 0 0 1.67 1.67c.22.03.47.03.62.03h.65V9.87h-.61c-.4 0-.59 0-.7-.12-.12-.11-.12-.3-.12-.64z" })
3585
3830
  ] }),
3586
- /* @__PURE__ */ jsx11("defs", { children: /* @__PURE__ */ jsx11("clipPath", { id: "rs-pb-clip", children: /* @__PURE__ */ jsx11("path", { fill: "#fff", d: "M0 0h72v16H0z" }) }) })
3831
+ /* @__PURE__ */ jsx9("defs", { children: /* @__PURE__ */ jsx9("clipPath", { id: "rs-pb-clip", children: /* @__PURE__ */ jsx9("path", { fill: "#fff", d: "M0 0h72v16H0z" }) }) })
3587
3832
  ]
3588
3833
  }
3589
3834
  );
3590
3835
  function PoweredBy() {
3591
- return /* @__PURE__ */ jsxs7("div", { className: "rs-powered-by", "aria-label": "Powered by Rhinestone", children: [
3592
- /* @__PURE__ */ jsx11("span", { children: "Powered by" }),
3593
- /* @__PURE__ */ jsx11(
3836
+ return /* @__PURE__ */ jsxs4("div", { className: "rs-powered-by", "aria-label": "Powered by Rhinestone", children: [
3837
+ /* @__PURE__ */ jsx9("span", { children: "Powered by" }),
3838
+ /* @__PURE__ */ jsx9(
3839
+ "a",
3840
+ {
3841
+ className: "rs-powered-by-link",
3842
+ href: "https://www.rhinestone.dev",
3843
+ target: "_blank",
3844
+ rel: "noopener noreferrer",
3845
+ children: rhinestoneLogo
3846
+ }
3847
+ )
3848
+ ] });
3849
+ }
3850
+ PoweredBy.displayName = "PoweredBy";
3851
+
3852
+ // src/components/history/BankOrderCard.tsx
3853
+ import { useId, useState as useState3 } from "react";
3854
+
3855
+ // src/components/history/HistoryTransactionLink.tsx
3856
+ import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
3857
+ function resolveHistoryChainId(value) {
3858
+ if (value === void 0 || value === null) return null;
3859
+ if (typeof value === "number") return value;
3860
+ const display = displayChainIdForCaip2(value);
3861
+ if (display !== null) return display;
3862
+ if (value === "solana" || value === "hypercore") return value;
3863
+ const number = Number(value);
3864
+ return Number.isFinite(number) ? number : null;
3865
+ }
3866
+ function HistoryTransactionLink({
3867
+ chainId,
3868
+ txHash,
3869
+ label = "Transaction details"
3870
+ }) {
3871
+ const explorerTxUrl = useExplorerTxUrl();
3872
+ const chain = resolveHistoryChainId(chainId);
3873
+ const url = chain !== null && txHash ? explorerTxUrl(chain, txHash) : void 0;
3874
+ if (!url || !txHash) return null;
3875
+ const text = txHash.length > 14 ? `${txHash.slice(0, 6)}\u2026${txHash.slice(-4)}` : txHash;
3876
+ return /* @__PURE__ */ jsxs5("div", { className: "rs-amount-detail-row", children: [
3877
+ /* @__PURE__ */ jsx10("span", { children: label }),
3878
+ /* @__PURE__ */ jsxs5(
3594
3879
  "a",
3595
3880
  {
3596
- className: "rs-powered-by-link",
3597
- href: "https://www.rhinestone.dev",
3881
+ href: url,
3598
3882
  target: "_blank",
3599
3883
  rel: "noopener noreferrer",
3600
- children: rhinestoneLogo
3884
+ className: "rs-history-card-link",
3885
+ "aria-label": `${label}: ${txHash}`,
3886
+ children: [
3887
+ /* @__PURE__ */ jsx10("span", { children: text }),
3888
+ /* @__PURE__ */ jsx10(ArrowUpRightIcon, {})
3889
+ ]
3601
3890
  }
3602
3891
  )
3603
3892
  ] });
3604
3893
  }
3605
- PoweredBy.displayName = "PoweredBy";
3894
+
3895
+ // src/core/bank-onramp-progress.ts
3896
+ function toPaymentProgress(order) {
3897
+ const { receipt, conversion, delivery } = order.stages;
3898
+ const stages = [receipt.status, conversion.status, delivery.status];
3899
+ if (stages.includes("on_hold")) return "on_hold";
3900
+ if (order.stages.return.status !== "none") return "returned";
3901
+ if (stages.includes("failed")) return "failed";
3902
+ if (delivery.status === "completed") return "delivered";
3903
+ if (delivery.status !== "not_started") return "sending";
3904
+ if (conversion.status === "completed") return "sending";
3905
+ if (conversion.status !== "not_started") return "converting";
3906
+ if (receipt.status === "completed") return "received";
3907
+ return "awaiting_transfer";
3908
+ }
3909
+ var TERMINAL = /* @__PURE__ */ new Set([
3910
+ "delivered",
3911
+ "returned",
3912
+ "failed"
3913
+ ]);
3914
+ function toPaymentView(order) {
3915
+ const progress = toPaymentProgress(order);
3916
+ return {
3917
+ id: order.id,
3918
+ amount: order.fiat.charged?.total ?? "",
3919
+ currency: order.fiat.charged?.currency ?? "",
3920
+ progress,
3921
+ terminal: TERMINAL.has(progress)
3922
+ };
3923
+ }
3924
+ var BANK_ONRAMP_COPY = {
3925
+ awaiting_transfer: {
3926
+ title: "Waiting for your transfer",
3927
+ subtitle: "Send the transfer from your bank using the details above."
3928
+ },
3929
+ received: {
3930
+ title: "Transfer received",
3931
+ subtitle: "Your bank transfer has arrived and is being processed."
3932
+ },
3933
+ converting: {
3934
+ title: "Converting",
3935
+ subtitle: "Your money is being converted to crypto."
3936
+ },
3937
+ sending: {
3938
+ title: "Sending to your account",
3939
+ subtitle: "The crypto is on its way. This usually takes a few minutes."
3940
+ },
3941
+ delivered: {
3942
+ title: "Funds delivered",
3943
+ subtitle: "The crypto has arrived in your account."
3944
+ },
3945
+ on_hold: {
3946
+ title: "Under review",
3947
+ subtitle: "Your provider is reviewing this transfer and may contact you for more information."
3948
+ },
3949
+ returned: {
3950
+ title: "Transfer returned",
3951
+ subtitle: "This transfer was returned. Contact support if unexpected."
3952
+ },
3953
+ failed: {
3954
+ title: "Transfer failed",
3955
+ subtitle: "This transfer could not be completed. Contact support."
3956
+ }
3957
+ };
3958
+
3959
+ // src/components/history/BankOrderCard.tsx
3960
+ import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
3961
+ function bankSupportHref(value) {
3962
+ if (!value) return void 0;
3963
+ try {
3964
+ const url = new URL(value);
3965
+ return ["https:", "mailto:"].includes(url.protocol) ? url.href : void 0;
3966
+ } catch {
3967
+ return void 0;
3968
+ }
3969
+ }
3970
+ function BankOrderCard({
3971
+ order,
3972
+ supportUrl,
3973
+ children,
3974
+ deposit
3975
+ }) {
3976
+ const [expanded, setExpanded] = useState3(false);
3977
+ const panelId = useId();
3978
+ const view = toPaymentView(order);
3979
+ const subFee = [order.stages.conversion, order.stages.delivery].some(
3980
+ (stage) => stage.status === "failed" && stage.reason === "sub_fee"
3981
+ );
3982
+ const support = bankSupportHref(supportUrl);
3983
+ const { delivery } = order.stages;
3984
+ const deliveryTxHash = "txHash" in delivery ? delivery.txHash : void 0;
3985
+ const needsHelp = ["failed", "returned", "on_hold"].includes(view.progress);
3986
+ const settlement = deposit ? normalizeStatus(deposit.status, deposit.isSpam) : null;
3987
+ let status = "pending";
3988
+ let label = "Detected";
3989
+ if (view.progress === "failed" || settlement === "failed" || settlement === "spam") {
3990
+ status = "failed";
3991
+ label = "Failed";
3992
+ } else if (view.progress === "returned" || settlement === "refunded") {
3993
+ status = "refunded";
3994
+ label = "Returned";
3995
+ } else if (settlement === "completed") {
3996
+ status = "completed";
3997
+ label = "Completed";
3998
+ } else if (view.progress === "on_hold") {
3999
+ status = "processing";
4000
+ label = "Under review";
4001
+ } else if (view.progress === "delivered") {
4002
+ status = "processing";
4003
+ label = "Settled";
4004
+ } else if (view.progress !== "awaiting_transfer" && view.progress !== "received") {
4005
+ status = "processing";
4006
+ label = "Settling";
4007
+ }
4008
+ const amount = view.amount && Number.isFinite(Number(view.amount)) ? `${Number(view.amount).toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} ${view.currency}` : "\u2014";
4009
+ const date = new Date(order.createdAt).toLocaleDateString(void 0, {
4010
+ day: "numeric",
4011
+ month: "short",
4012
+ year: "numeric"
4013
+ });
4014
+ const description = subFee ? "The transfer was consumed by the provider\u2019s fees. No crypto was delivered." : label === "Failed" && deposit ? "Crypto arrived, but settlement to your destination could not be completed." : label === "Completed" ? "Your bank transfer has completed and the crypto reached its destination." : label === "Settled" ? "Your bank transfer has settled into crypto. Final delivery is being confirmed." : label === "Settling" ? "Your bank transfer is being settled into crypto." : label === "Detected" ? "Your bank transfer was detected and is awaiting settlement." : BANK_ONRAMP_COPY[view.progress].subtitle;
4015
+ return /* @__PURE__ */ jsxs6(
4016
+ "div",
4017
+ {
4018
+ className: `rs-history-card${expanded ? " rs-history-card--expanded" : ""}`,
4019
+ children: [
4020
+ /* @__PURE__ */ jsx11(
4021
+ "button",
4022
+ {
4023
+ type: "button",
4024
+ className: "rs-history-card-trigger",
4025
+ onClick: () => setExpanded(!expanded),
4026
+ "aria-expanded": expanded,
4027
+ "aria-controls": panelId,
4028
+ children: /* @__PURE__ */ jsxs6("div", { className: "rs-history-card-row", children: [
4029
+ /* @__PURE__ */ jsx11("div", { className: "rs-history-card-icons", children: /* @__PURE__ */ jsx11("span", { className: "rs-history-card-token", children: /* @__PURE__ */ jsx11(BankIcon, {}) }) }),
4030
+ /* @__PURE__ */ jsxs6("div", { className: "rs-history-card-text", children: [
4031
+ /* @__PURE__ */ jsx11("span", { className: "rs-history-card-title", children: "Bank transfer" }),
4032
+ /* @__PURE__ */ jsx11("time", { className: "rs-history-card-date", dateTime: order.createdAt, children: date })
4033
+ ] }),
4034
+ /* @__PURE__ */ jsxs6("div", { className: "rs-history-card-side", children: [
4035
+ /* @__PURE__ */ jsx11("span", { className: "rs-history-card-amount", children: amount }),
4036
+ /* @__PURE__ */ jsx11("span", { className: `rs-history-badge rs-history-badge--${status}`, children: label })
4037
+ ] })
4038
+ ] })
4039
+ }
4040
+ ),
4041
+ /* @__PURE__ */ jsx11("div", { className: "rs-history-card-panel", id: panelId, children: /* @__PURE__ */ jsx11("div", { className: "rs-history-card-panel-inner", children: /* @__PURE__ */ jsxs6("div", { className: "rs-history-card-details", children: [
4042
+ subFee || status === "failed" ? /* @__PURE__ */ jsx11(Callout, { variant: "error", children: description }) : /* @__PURE__ */ jsx11("p", { className: "rs-history-empty-hint", children: description }),
4043
+ order.crypto && /* @__PURE__ */ jsxs6("div", { className: "rs-amount-detail-row", children: [
4044
+ /* @__PURE__ */ jsx11("span", { children: "Converted amount" }),
4045
+ /* @__PURE__ */ jsxs6("span", { className: "rs-amount-detail-value", children: [
4046
+ order.crypto.amount,
4047
+ " ",
4048
+ order.crypto.asset
4049
+ ] })
4050
+ ] }),
4051
+ /* @__PURE__ */ jsx11(
4052
+ HistoryTransactionLink,
4053
+ {
4054
+ chainId: deposit?.chain ?? order.deliveryChain,
4055
+ txHash: deposit?.txHash ?? deliveryTxHash,
4056
+ label: "Crypto deposit"
4057
+ }
4058
+ ),
4059
+ deposit?.destinationTxHash !== deposit?.txHash && /* @__PURE__ */ jsx11(HistoryTransactionLink, { chainId: deposit?.targetChain, txHash: deposit?.destinationTxHash, label: "Final settlement" }),
4060
+ (needsHelp || status === "failed") && support && /* @__PURE__ */ jsxs6(
4061
+ "a",
4062
+ {
4063
+ className: "rs-history-card-link",
4064
+ href: support,
4065
+ target: "_blank",
4066
+ rel: "noopener noreferrer",
4067
+ children: [
4068
+ "Contact support ",
4069
+ /* @__PURE__ */ jsx11(ArrowUpRightIcon, {})
4070
+ ]
4071
+ }
4072
+ ),
4073
+ children
4074
+ ] }) }) })
4075
+ ]
4076
+ }
4077
+ );
4078
+ }
3606
4079
 
3607
4080
  // src/components/ui/TokenIcon.tsx
3608
4081
  import { jsx as jsx12 } from "react/jsx-runtime";
3609
- function TokenIcon({ symbol, className, fallback }) {
4082
+ function TokenIcon({ token, symbol, className, fallback }) {
4083
+ const id = assetIdForRef(token);
4084
+ const entry = useAssetMetadata([token])[id ?? ""];
4085
+ const classes = `rs-token-icon ${className ?? ""}`.trimEnd();
4086
+ const badge = fallback ?? /* @__PURE__ */ jsx12("span", { className: "rs-token-initials", "aria-hidden": "true", children: (symbol ?? "").trim().slice(0, 1).toUpperCase() });
4087
+ if (entry?.status === "pending") {
4088
+ return /* @__PURE__ */ jsx12(
4089
+ "span",
4090
+ {
4091
+ className: `${classes} rs-token-icon--pending`,
4092
+ "data-loading": "",
4093
+ "aria-hidden": "true"
4094
+ }
4095
+ );
4096
+ }
3610
4097
  return /* @__PURE__ */ jsx12(
3611
4098
  CdnIcon,
3612
4099
  {
3613
- src: tokenIconUrl(symbol),
3614
- className: `rs-token-icon ${className ?? ""}`.trimEnd(),
3615
- fallback
4100
+ src: entry?.status === "ready" ? entry.logo : void 0,
4101
+ className: classes,
4102
+ fallback: badge
3616
4103
  }
3617
4104
  );
3618
4105
  }
@@ -3692,8 +4179,84 @@ function resolveHistoryTiming({
3692
4179
  };
3693
4180
  }
3694
4181
 
4182
+ // src/core/token-display.ts
4183
+ import { useMemo as useMemo5, useSyncExternalStore as useSyncExternalStore3 } from "react";
4184
+ function isHyperCore(chain) {
4185
+ return chain === "hypercore" || chain === HYPERCORE_CHAIN_ID;
4186
+ }
4187
+ function resolveCuratedToken(token, chain) {
4188
+ if (isHyperCore(chain)) {
4189
+ const listed = HYPERCORE_SOURCE_TOKENS.find(
4190
+ (t) => t.address.toLowerCase() === token.toLowerCase()
4191
+ );
4192
+ return listed ? { symbol: listed.symbol, decimals: listed.decimals } : void 0;
4193
+ }
4194
+ const published = getRuntimeTokenByAddress(chain, token);
4195
+ if (published) {
4196
+ return { symbol: published.symbol, decimals: published.decimals };
4197
+ }
4198
+ if (chain === "solana") return resolveSolanaToken(token);
4199
+ if (isNativeSpelling(chain, token)) {
4200
+ const symbol = getRuntimeNativeSymbol(chain);
4201
+ const decimals = getRuntimeNativeDecimals(chain) ?? (typeof chain === "number" ? 18 : void 0);
4202
+ return symbol ? { symbol, decimals } : void 0;
4203
+ }
4204
+ return void 0;
4205
+ }
4206
+ function resolveTokenDisplay(token, chain, asset, fallback) {
4207
+ const pending = asset?.status === "pending";
4208
+ const curated = token !== void 0 && chain !== void 0 ? resolveCuratedToken(token, chain) : void 0;
4209
+ const fromAsset = asset?.status === "ready" ? asset : void 0;
4210
+ const hyperCore = chain !== void 0 && isHyperCore(chain);
4211
+ const native = token !== void 0 && chain !== void 0 && isNativeSpelling(chain, token);
4212
+ const curatedSymbol = native ? curated?.symbol ?? fromAsset?.symbol : fromAsset?.symbol ?? curated?.symbol;
4213
+ const decimals = fallback?.decimals ?? curated?.decimals ?? (hyperCore ? void 0 : fromAsset?.decimals);
4214
+ return {
4215
+ symbol: curatedSymbol ?? fallback?.symbol ?? "Token",
4216
+ decimals,
4217
+ logo: fromAsset?.logo,
4218
+ curated: curatedSymbol !== void 0,
4219
+ pending
4220
+ };
4221
+ }
4222
+ function toAssetRef(ref) {
4223
+ return ref?.chain !== void 0 && ref.address ? { chain: ref.chain, address: ref.address } : void 0;
4224
+ }
4225
+ function useTokenDisplays(refs) {
4226
+ const { catalog } = useChainCatalog();
4227
+ const tokensVersion = useSyncExternalStore3(
4228
+ subscribeToRuntimeTokens,
4229
+ getRuntimeTokensVersion,
4230
+ getRuntimeTokensVersion
4231
+ );
4232
+ const assets = useAssetMetadata(refs.map(toAssetRef));
4233
+ const key = refs.map(
4234
+ (ref) => `${String(ref?.chain)}:${ref?.address ?? ""}:${ref?.fallback?.symbol ?? ""}:${ref?.fallback?.decimals ?? ""}`
4235
+ ).join("|");
4236
+ return useMemo5(
4237
+ () => refs.map((ref) => {
4238
+ const id = assetIdFor(ref?.chain, ref?.address);
4239
+ return resolveTokenDisplay(
4240
+ ref?.address,
4241
+ ref?.chain,
4242
+ id ? assets[id] : void 0,
4243
+ ref?.fallback
4244
+ );
4245
+ }),
4246
+ // `refs` enters through `key`.
4247
+ // eslint-disable-next-line react-hooks/exhaustive-deps
4248
+ [key, assets, catalog, tokensVersion]
4249
+ );
4250
+ }
4251
+ function useTokenDisplay(chain, address, fallback) {
4252
+ return useTokenDisplays([{ chain, address, fallback }])[0];
4253
+ }
4254
+ function useIsRecognizedToken(chain, address) {
4255
+ return useTokenDisplay(chain, address).curated;
4256
+ }
4257
+
3695
4258
  // src/components/history/DepositHistoryPanel.tsx
3696
- import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
4259
+ import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
3697
4260
  var MAX_TIMER_DELAY_MS = 2147e6;
3698
4261
  function shortenHash(hash) {
3699
4262
  if (hash.length <= 14) return hash;
@@ -3712,60 +4275,8 @@ function formatDate(iso) {
3712
4275
  return iso;
3713
4276
  }
3714
4277
  }
3715
- function resolveChainId(value) {
3716
- if (value === void 0 || value === null) return null;
3717
- if (typeof value === "number") return value;
3718
- const display = displayChainIdForCaip2(value);
3719
- if (display !== null) return display;
3720
- if (value === "solana" || value === "hypercore") return value;
3721
- const num = Number(value);
3722
- return Number.isFinite(num) ? num : null;
3723
- }
3724
- function resolveTokenSymbol(token, chainId) {
3725
- if (!token) return "";
3726
- if (chainId === "solana") {
3727
- const normalized = token.toLowerCase();
3728
- const matched = SOLANA_TOKENS.find(
3729
- (entry) => entry.mint.toLowerCase() === normalized
3730
- );
3731
- if (matched) return matched.symbol;
3732
- if (normalized === "native" || normalized === "11111111111111111111111111111111" || normalized === "so11111111111111111111111111111111111111112") {
3733
- return "SOL";
3734
- }
3735
- }
3736
- if (chainId !== null && chainId !== void 0 && chainId !== "solana" && // Both callers pass the SOURCE chain, and `/chains` reports
3737
- // `deposit: false` for Tron and Stellar — so neither can appear here, and
3738
- // neither has an EVM token table to look one up in if it did.
3739
- chainId !== "tron" && chainId !== "stellar" && /^0x[a-fA-F0-9]{40}$/.test(token)) {
3740
- const evmChainId = chainId === "hypercore" ? HYPERCORE_CHAIN_ID : chainId;
3741
- const sym = getTokenSymbol(token, evmChainId);
3742
- if (sym !== "Token") return sym;
3743
- }
3744
- return shortenHash(token);
3745
- }
3746
- function formatAmount(rawAmount, token, chainId) {
3747
- if (!rawAmount) return "";
3748
- let decimals = 18;
3749
- if (token && chainId !== null && chainId !== void 0) {
3750
- if (chainId === "solana") {
3751
- const normalized = token.toLowerCase();
3752
- const matched = SOLANA_TOKENS.find(
3753
- (entry) => entry.mint.toLowerCase() === normalized
3754
- );
3755
- if (matched) {
3756
- decimals = matched.decimals;
3757
- } else if (normalized === "native" || normalized === "11111111111111111111111111111111" || normalized === "so11111111111111111111111111111111111111112") {
3758
- decimals = 9;
3759
- }
3760
- } else if (
3761
- // See `resolveTokenSymbol`: this reads the source chain, which Tron and
3762
- // Stellar cannot be.
3763
- chainId !== "tron" && chainId !== "stellar" && /^0x[a-fA-F0-9]{40}$/.test(token)
3764
- ) {
3765
- const evmChainId = chainId === "hypercore" ? HYPERCORE_CHAIN_ID : chainId;
3766
- decimals = getTokenDecimalsByAddress(token, evmChainId);
3767
- }
3768
- }
4278
+ function formatAmount(rawAmount, decimals) {
4279
+ if (!rawAmount || decimals === void 0) return null;
3769
4280
  try {
3770
4281
  const raw = BigInt(rawAmount);
3771
4282
  const divisor = 10n ** BigInt(decimals);
@@ -3780,6 +4291,8 @@ function formatAmount(rawAmount, token, chainId) {
3780
4291
  }
3781
4292
  }
3782
4293
  function DepositHistoryPanel({
4294
+ bankHistory,
4295
+ bankSupportUrl,
3783
4296
  deposits,
3784
4297
  isLoading,
3785
4298
  error,
@@ -3796,7 +4309,7 @@ function DepositHistoryPanel({
3796
4309
  onRowView,
3797
4310
  obscured
3798
4311
  }) {
3799
- const rootRef = useRef4(null);
4312
+ const rootRef = useRef3(null);
3800
4313
  useEffect5(() => {
3801
4314
  rootRef.current?.toggleAttribute("inert", Boolean(obscured));
3802
4315
  }, [obscured]);
@@ -3810,12 +4323,12 @@ function DepositHistoryPanel({
3810
4323
  },
3811
4324
  [onClose, obscured]
3812
4325
  );
3813
- const visibleDeposits = useMemo4(
4326
+ const visibleDeposits = useMemo6(
3814
4327
  () => filterVisibleDeposits(deposits),
3815
4328
  [deposits]
3816
4329
  );
3817
- const [nowMs, setNowMs] = useState3(() => Date.now());
3818
- const timingPresentations = useMemo4(
4330
+ const [nowMs, setNowMs] = useState4(() => Date.now());
4331
+ const timingPresentations = useMemo6(
3819
4332
  () => visibleDeposits.map(
3820
4333
  (deposit) => resolveHistoryTiming({
3821
4334
  status: deposit.status,
@@ -3856,7 +4369,7 @@ function DepositHistoryPanel({
3856
4369
  if (timeout !== void 0) clearTimeout(timeout);
3857
4370
  };
3858
4371
  }, [timingPresentations]);
3859
- return /* @__PURE__ */ jsxs8(
4372
+ return /* @__PURE__ */ jsxs7(
3860
4373
  "div",
3861
4374
  {
3862
4375
  ref: rootRef,
@@ -3866,8 +4379,8 @@ function DepositHistoryPanel({
3866
4379
  "aria-hidden": obscured || void 0,
3867
4380
  onKeyDown: handleKeyDown,
3868
4381
  children: [
3869
- /* @__PURE__ */ jsxs8("div", { className: "rs-modal-header--redesigned", children: [
3870
- /* @__PURE__ */ jsx13("div", { className: "rs-modal-header-nav-left", children: /* @__PURE__ */ jsxs8(
4382
+ /* @__PURE__ */ jsxs7("div", { className: "rs-modal-header--redesigned", children: [
4383
+ /* @__PURE__ */ jsx13("div", { className: "rs-modal-header-nav-left", children: /* @__PURE__ */ jsxs7(
3871
4384
  "button",
3872
4385
  {
3873
4386
  type: "button",
@@ -3891,10 +4404,10 @@ function DepositHistoryPanel({
3891
4404
  }
3892
4405
  ) })
3893
4406
  ] }),
3894
- /* @__PURE__ */ jsxs8("div", { className: "rs-history-screen", children: [
3895
- /* @__PURE__ */ jsxs8("div", { className: "rs-history-screen-body", children: [
4407
+ /* @__PURE__ */ jsxs7("div", { className: "rs-history-screen", children: [
4408
+ /* @__PURE__ */ jsxs7("div", { className: "rs-history-screen-body", children: [
3896
4409
  /* @__PURE__ */ jsx13(BodyHeader, { icon: /* @__PURE__ */ jsx13(HistoryIcon, {}), title }),
3897
- onFindByTxHash && /* @__PURE__ */ jsxs8(
4410
+ onFindByTxHash && /* @__PURE__ */ jsxs7(
3898
4411
  "button",
3899
4412
  {
3900
4413
  type: "button",
@@ -3906,40 +4419,82 @@ function DepositHistoryPanel({
3906
4419
  ]
3907
4420
  }
3908
4421
  ),
3909
- isLoading && deposits.length === 0 && /* @__PURE__ */ jsxs8("div", { className: "rs-history-empty", children: [
4422
+ (isLoading || bankHistory?.loading) && deposits.length === 0 && !bankHistory?.orders.length && /* @__PURE__ */ jsxs7("div", { className: "rs-history-empty", children: [
3910
4423
  /* @__PURE__ */ jsx13("span", { className: "rs-history-empty-glyph", "aria-hidden": "true", children: /* @__PURE__ */ jsx13(HistoryIcon, {}) }),
3911
- /* @__PURE__ */ jsxs8("div", { className: "rs-history-empty-text", children: [
4424
+ /* @__PURE__ */ jsxs7("div", { className: "rs-history-empty-text", children: [
3912
4425
  /* @__PURE__ */ jsx13(Spinner, { className: "rs-spinner--sm" }),
3913
4426
  /* @__PURE__ */ jsx13("span", { className: "rs-history-empty-hint", children: "Loading history\u2026" })
3914
4427
  ] })
3915
4428
  ] }),
3916
- error && !isLoading && /* @__PURE__ */ jsxs8("div", { className: "rs-history-empty", children: [
4429
+ error && !isLoading && /* @__PURE__ */ jsxs7("div", { className: "rs-history-empty", children: [
3917
4430
  /* @__PURE__ */ jsx13("span", { className: "rs-history-empty-glyph", "aria-hidden": "true", children: /* @__PURE__ */ jsx13(AlertTriangleIcon, {}) }),
3918
- /* @__PURE__ */ jsxs8("div", { className: "rs-history-empty-text", children: [
4431
+ /* @__PURE__ */ jsxs7("div", { className: "rs-history-empty-text", children: [
3919
4432
  /* @__PURE__ */ jsx13("span", { className: "rs-history-empty-title", children: "Couldn't load history" }),
3920
4433
  /* @__PURE__ */ jsx13("span", { className: "rs-history-empty-hint", children: error })
3921
4434
  ] })
3922
4435
  ] }),
3923
- !isLoading && !error && visibleDeposits.length === 0 && /* @__PURE__ */ jsxs8("div", { className: "rs-history-empty", children: [
4436
+ bankHistory?.error && /* @__PURE__ */ jsx13("p", { role: "status", children: bankHistory.error }),
4437
+ !isLoading && !error && !bankHistory?.loading && !bankHistory?.error && !bankHistory?.orders.length && visibleDeposits.length === 0 && /* @__PURE__ */ jsxs7("div", { className: "rs-history-empty", children: [
3924
4438
  /* @__PURE__ */ jsx13("span", { className: "rs-history-empty-glyph", "aria-hidden": "true", children: /* @__PURE__ */ jsx13(HistoryIcon, {}) }),
3925
- /* @__PURE__ */ jsxs8("div", { className: "rs-history-empty-text", children: [
4439
+ /* @__PURE__ */ jsxs7("div", { className: "rs-history-empty-text", children: [
3926
4440
  /* @__PURE__ */ jsx13("span", { className: "rs-history-empty-title", children: "No deposits yet" }),
3927
4441
  /* @__PURE__ */ jsx13("span", { className: "rs-history-empty-hint", children: "Your deposit history will appear here" })
3928
4442
  ] })
3929
4443
  ] }),
3930
- visibleDeposits.length > 0 && /* @__PURE__ */ jsxs8("div", { className: "rs-history-list", children: [
3931
- visibleDeposits.map((deposit, i) => /* @__PURE__ */ jsx13(
3932
- HistoryCard,
4444
+ (visibleDeposits.length > 0 || Boolean(bankHistory?.orders.length)) && /* @__PURE__ */ jsxs7("div", { className: "rs-history-list", children: [
4445
+ [
4446
+ ...visibleDeposits.filter(
4447
+ (deposit) => !bankHistory?.orders.some(
4448
+ (order) => order.stages.delivery.status === "completed" && order.stages.delivery.depositId === deposit.id
4449
+ )
4450
+ ).map((deposit, i) => ({
4451
+ id: `deposit:${deposit.id ?? deposit.txHash}`,
4452
+ createdAt: deposit.createdAt ?? "",
4453
+ content: /* @__PURE__ */ jsx13(
4454
+ HistoryCard,
4455
+ {
4456
+ deposit,
4457
+ timing: timingPresentations[visibleDeposits.indexOf(deposit)],
4458
+ position: i,
4459
+ recipient,
4460
+ onRecover,
4461
+ onRowView
4462
+ },
4463
+ deposit.txHash || i
4464
+ )
4465
+ })),
4466
+ ...(bankHistory?.orders ?? []).map((order) => {
4467
+ const delivery = order.stages.delivery;
4468
+ const linked = delivery.status === "completed" ? visibleDeposits.find(
4469
+ (deposit) => deposit.id === delivery.depositId
4470
+ ) : void 0;
4471
+ return {
4472
+ id: `bank:${order.id}`,
4473
+ createdAt: order.createdAt,
4474
+ content: /* @__PURE__ */ jsx13(BankOrderCard, { order, deposit: linked, supportUrl: bankSupportUrl, children: linked && normalizeStatus(linked.status) === "failed" && /* @__PURE__ */ jsx13(
4475
+ HistoryCard,
4476
+ {
4477
+ deposit: linked,
4478
+ position: visibleDeposits.indexOf(linked),
4479
+ recipient,
4480
+ onRecover,
4481
+ onRowView,
4482
+ timing: timingPresentations[visibleDeposits.indexOf(linked)]
4483
+ }
4484
+ ) })
4485
+ };
4486
+ })
4487
+ ].sort((a, b) => b.createdAt.localeCompare(a.createdAt)).map((entry) => /* @__PURE__ */ jsx13("div", { children: entry.content }, entry.id)),
4488
+ bankHistory?.hasMore && /* @__PURE__ */ jsx13(
4489
+ "button",
3933
4490
  {
3934
- deposit,
3935
- timing: timingPresentations[i],
3936
- position: i,
3937
- recipient,
3938
- onRecover,
3939
- onRowView
3940
- },
3941
- deposit.txHash || i
3942
- )),
4491
+ type: "button",
4492
+ className: "rs-history-load-more",
4493
+ disabled: bankHistory.loading,
4494
+ onClick: bankHistory.loadMore,
4495
+ children: "Load older bank transfers"
4496
+ }
4497
+ ),
3943
4498
  hasMore && /* @__PURE__ */ jsx13(
3944
4499
  "button",
3945
4500
  {
@@ -3966,27 +4521,27 @@ function HistoryCard({
3966
4521
  onRecover,
3967
4522
  onRowView
3968
4523
  }) {
3969
- const explorerTxUrl = useExplorerTxUrl();
3970
- const [expanded, setExpanded] = useState3(false);
3971
- const panelId = useId();
4524
+ const [expanded, setExpanded] = useState4(false);
4525
+ const panelId = useId2();
3972
4526
  const status = normalizeStatus(deposit.status, deposit.isSpam);
3973
- const sourceChainId = resolveChainId(deposit.chain);
3974
- const targetChainId = resolveChainId(deposit.targetChain);
4527
+ const sourceChainId = resolveHistoryChainId(deposit.chain);
4528
+ const targetChainId = resolveHistoryChainId(deposit.targetChain);
3975
4529
  const sourceChainName = sourceChainId ? getChainName(sourceChainId) : null;
3976
4530
  const targetChainName = targetChainId ? getChainName(targetChainId) : null;
3977
4531
  const sourceChainIcon = sourceChainId ? getChainIcon(sourceChainId) : void 0;
3978
4532
  const targetChainIcon = targetChainId ? getChainIcon(targetChainId) : void 0;
3979
- const sourceSymbol = resolveTokenSymbol(deposit.token, sourceChainId);
4533
+ const sourceToken = deposit.token ?? void 0;
4534
+ const tokenDisplay = useTokenDisplay(sourceChainId ?? void 0, sourceToken);
4535
+ const sourceSymbol = !sourceToken ? "" : tokenDisplay.curated ? tokenDisplay.symbol : shortenHash(sourceToken);
3980
4536
  const rawAmount = deposit.sourceAmount && deposit.sourceAmount !== "0" ? deposit.sourceAmount : deposit.amount;
3981
- const formattedAmount = rawAmount ? formatAmount(rawAmount, deposit.token, sourceChainId) : null;
4537
+ const formattedAmount = rawAmount ? formatAmount(rawAmount, tokenDisplay.decimals) : null;
3982
4538
  const displayAmount = formattedAmount ? sourceSymbol && /^USD/.test(sourceSymbol) ? `$${Number(formattedAmount).toLocaleString("en-US", {
3983
4539
  minimumFractionDigits: 2,
3984
4540
  maximumFractionDigits: 2
3985
- })}` : `${formattedAmount} ${sourceSymbol}` : "\u2014";
4541
+ })}` : `${formattedAmount} ${sourceSymbol}` : rawAmount && tokenDisplay.pending ? "\u2026" : "\u2014";
3986
4542
  const date = deposit.createdAt ? formatDate(deposit.createdAt) : null;
3987
4543
  const txTypeLabel = `Deposit${sourceSymbol ? ` ${sourceSymbol}` : ""}`;
3988
4544
  const srcTxHash = sourceChainId === "hypercore" ? deposit.txHash : deposit.sourceTxHash;
3989
- const srcTxUrl = srcTxHash && sourceChainId ? explorerTxUrl(sourceChainId, srcTxHash) : null;
3990
4545
  const eligible = toRecoverableDeposit(deposit, { recipient });
3991
4546
  const recoverable = onRecover ? eligible : null;
3992
4547
  const toggleExpanded = () => {
@@ -4001,7 +4556,7 @@ function HistoryCard({
4001
4556
  position
4002
4557
  });
4003
4558
  };
4004
- return /* @__PURE__ */ jsxs8(
4559
+ return /* @__PURE__ */ jsxs7(
4005
4560
  "div",
4006
4561
  {
4007
4562
  className: `rs-history-card ${expanded ? "rs-history-card--expanded" : ""}`,
@@ -4014,60 +4569,46 @@ function HistoryCard({
4014
4569
  onClick: toggleExpanded,
4015
4570
  "aria-expanded": expanded,
4016
4571
  "aria-controls": panelId,
4017
- children: /* @__PURE__ */ jsxs8("div", { className: "rs-history-card-row", children: [
4018
- /* @__PURE__ */ jsxs8("div", { className: "rs-history-card-icons", children: [
4572
+ children: /* @__PURE__ */ jsxs7("div", { className: "rs-history-card-row", children: [
4573
+ /* @__PURE__ */ jsxs7("div", { className: "rs-history-card-icons", children: [
4019
4574
  /* @__PURE__ */ jsx13("span", { className: "rs-history-card-token", children: /* @__PURE__ */ jsx13(
4020
4575
  TokenIcon,
4021
4576
  {
4577
+ token: sourceChainId !== null && sourceToken ? { chain: sourceChainId, address: sourceToken } : void 0,
4022
4578
  symbol: sourceSymbol,
4023
4579
  fallback: sourceSymbol.slice(0, 2)
4024
4580
  }
4025
4581
  ) }),
4026
4582
  sourceChainIcon && /* @__PURE__ */ jsx13("span", { className: "rs-history-card-chain", children: /* @__PURE__ */ jsx13(CdnIcon, { src: sourceChainIcon }) })
4027
4583
  ] }),
4028
- /* @__PURE__ */ jsxs8("div", { className: "rs-history-card-text", children: [
4584
+ /* @__PURE__ */ jsxs7("div", { className: "rs-history-card-text", children: [
4029
4585
  /* @__PURE__ */ jsx13("span", { className: "rs-history-card-title", children: txTypeLabel }),
4030
4586
  date && /* @__PURE__ */ jsx13("span", { className: "rs-history-card-date", children: date })
4031
4587
  ] }),
4032
- /* @__PURE__ */ jsxs8("div", { className: "rs-history-card-side", children: [
4588
+ /* @__PURE__ */ jsxs7("div", { className: "rs-history-card-side", children: [
4033
4589
  /* @__PURE__ */ jsx13("span", { className: "rs-history-card-amount", children: displayAmount }),
4034
4590
  /* @__PURE__ */ jsx13("span", { className: `rs-history-badge rs-history-badge--${status}`, children: STATUS_LABEL[status] })
4035
4591
  ] })
4036
4592
  ] })
4037
4593
  }
4038
4594
  ),
4039
- /* @__PURE__ */ jsx13("div", { className: "rs-history-card-panel", id: panelId, children: /* @__PURE__ */ jsx13("div", { className: "rs-history-card-panel-inner", children: /* @__PURE__ */ jsxs8("div", { className: "rs-history-card-details", children: [
4595
+ /* @__PURE__ */ jsx13("div", { className: "rs-history-card-panel", id: panelId, children: /* @__PURE__ */ jsx13("div", { className: "rs-history-card-panel-inner", children: /* @__PURE__ */ jsxs7("div", { className: "rs-history-card-details", children: [
4040
4596
  (status === "failed" || recoverable) && /* @__PURE__ */ jsx13(Callout, { variant: "error", children: recoveryFailureCause(sourceChainName) }),
4041
- sourceChainName && /* @__PURE__ */ jsxs8("div", { className: "rs-amount-detail-row", children: [
4597
+ sourceChainName && /* @__PURE__ */ jsxs7("div", { className: "rs-amount-detail-row", children: [
4042
4598
  /* @__PURE__ */ jsx13("span", { children: "Source chain" }),
4043
- /* @__PURE__ */ jsxs8("span", { className: "rs-amount-detail-value", children: [
4599
+ /* @__PURE__ */ jsxs7("span", { className: "rs-amount-detail-value", children: [
4044
4600
  /* @__PURE__ */ jsx13("span", { children: sourceChainName }),
4045
4601
  sourceChainIcon && /* @__PURE__ */ jsx13("span", { className: "rs-amount-detail-icon", children: /* @__PURE__ */ jsx13(CdnIcon, { src: sourceChainIcon }) })
4046
4602
  ] })
4047
4603
  ] }),
4048
- targetChainName && /* @__PURE__ */ jsxs8("div", { className: "rs-amount-detail-row", children: [
4604
+ targetChainName && /* @__PURE__ */ jsxs7("div", { className: "rs-amount-detail-row", children: [
4049
4605
  /* @__PURE__ */ jsx13("span", { children: "Destination chain" }),
4050
- /* @__PURE__ */ jsxs8("span", { className: "rs-amount-detail-value", children: [
4606
+ /* @__PURE__ */ jsxs7("span", { className: "rs-amount-detail-value", children: [
4051
4607
  /* @__PURE__ */ jsx13("span", { children: targetChainName }),
4052
4608
  targetChainIcon && /* @__PURE__ */ jsx13("span", { className: "rs-amount-detail-icon", children: /* @__PURE__ */ jsx13(CdnIcon, { src: targetChainIcon }) })
4053
4609
  ] })
4054
4610
  ] }),
4055
- srcTxUrl && srcTxHash && /* @__PURE__ */ jsxs8("div", { className: "rs-amount-detail-row", children: [
4056
- /* @__PURE__ */ jsx13("span", { children: "Transaction details" }),
4057
- /* @__PURE__ */ jsxs8(
4058
- "a",
4059
- {
4060
- href: srcTxUrl,
4061
- target: "_blank",
4062
- rel: "noopener noreferrer",
4063
- className: "rs-history-card-link",
4064
- children: [
4065
- /* @__PURE__ */ jsx13("span", { children: shortenHash(srcTxHash) }),
4066
- /* @__PURE__ */ jsx13(ArrowUpRightIcon, {})
4067
- ]
4068
- }
4069
- )
4070
- ] }),
4611
+ /* @__PURE__ */ jsx13(HistoryTransactionLink, { chainId: sourceChainId, txHash: srcTxHash }),
4071
4612
  timing && /* @__PURE__ */ jsx13(
4072
4613
  "span",
4073
4614
  {
@@ -4078,14 +4619,14 @@ function HistoryCard({
4078
4619
  children: timing.state === "expected" ? `Usually arrives in ${timing.expectedDuration}` : timing.state === "soft" ? "Taking longer than usual" : "Taking much longer than usual"
4079
4620
  }
4080
4621
  ),
4081
- recoverable && /* @__PURE__ */ jsxs8(
4622
+ recoverable && /* @__PURE__ */ jsxs7(
4082
4623
  Button,
4083
4624
  {
4084
4625
  onClick: () => onRecover?.(recoverable),
4085
4626
  fullWidth: true,
4086
4627
  className: "rs-history-card-recover",
4087
4628
  children: [
4088
- /* @__PURE__ */ jsxs8("span", { children: [
4629
+ /* @__PURE__ */ jsxs7("span", { children: [
4089
4630
  "Recover ",
4090
4631
  displayAmount
4091
4632
  ] }),
@@ -4101,10 +4642,10 @@ function HistoryCard({
4101
4642
  DepositHistoryPanel.displayName = "DepositHistoryPanel";
4102
4643
 
4103
4644
  // src/components/history/HistoryFallbackFlow.tsx
4104
- import { useCallback as useCallback5, useEffect as useEffect7, useRef as useRef5, useState as useState5 } from "react";
4645
+ import { useCallback as useCallback5, useEffect as useEffect7, useRef as useRef4, useState as useState6 } from "react";
4105
4646
 
4106
4647
  // src/components/ui/ListRow.tsx
4107
- import { Fragment as Fragment3, jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
4648
+ import { Fragment as Fragment3, jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
4108
4649
  function ListRow({
4109
4650
  leading,
4110
4651
  leadingMedia,
@@ -4118,10 +4659,10 @@ function ListRow({
4118
4659
  disabled,
4119
4660
  ...props
4120
4661
  }) {
4121
- const inner = /* @__PURE__ */ jsxs9(Fragment3, { children: [
4662
+ const inner = /* @__PURE__ */ jsxs8(Fragment3, { children: [
4122
4663
  leadingMedia ? /* @__PURE__ */ jsx14("span", { className: "rs-list-row-leading rs-list-row-leading--media", children: /* @__PURE__ */ jsx14(CdnIcon, { src: leadingMedia }) }) : leading ? /* @__PURE__ */ jsx14("span", { className: "rs-list-row-leading", children: leading }) : null,
4123
- /* @__PURE__ */ jsxs9("div", { className: "rs-list-row-body", children: [
4124
- /* @__PURE__ */ jsxs9("div", { className: "rs-list-row-text", children: [
4664
+ /* @__PURE__ */ jsxs8("div", { className: "rs-list-row-body", children: [
4665
+ /* @__PURE__ */ jsxs8("div", { className: "rs-list-row-text", children: [
4125
4666
  /* @__PURE__ */ jsx14("span", { className: "rs-list-row-title", children: title }),
4126
4667
  subtitle && /* @__PURE__ */ jsx14("span", { className: "rs-list-row-subtitle", children: subtitle })
4127
4668
  ] }),
@@ -4177,15 +4718,15 @@ function ListRow({
4177
4718
  ListRow.displayName = "ListRow";
4178
4719
 
4179
4720
  // src/components/recovery/RecoveryLookupScreen.tsx
4180
- import { useEffect as useEffect6, useState as useState4 } from "react";
4721
+ import { useEffect as useEffect6, useState as useState5 } from "react";
4181
4722
 
4182
4723
  // src/components/ui/Input.tsx
4183
4724
  import { forwardRef } from "react";
4184
- import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
4725
+ import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
4185
4726
  var Input = forwardRef(
4186
4727
  ({ label, error, hint, variant, className = "", ...props }, ref) => {
4187
4728
  const inputVariant = error ? "error" : variant || "default";
4188
- return /* @__PURE__ */ jsxs10("div", { className: "rs-input-wrapper", children: [
4729
+ return /* @__PURE__ */ jsxs9("div", { className: "rs-input-wrapper", children: [
4189
4730
  label && /* @__PURE__ */ jsx15("label", { className: "rs-input-label", children: label }),
4190
4731
  /* @__PURE__ */ jsx15(
4191
4732
  "input",
@@ -4195,7 +4736,7 @@ var Input = forwardRef(
4195
4736
  ...props
4196
4737
  }
4197
4738
  ),
4198
- error ? /* @__PURE__ */ jsxs10("p", { className: "rs-input-error", children: [
4739
+ error ? /* @__PURE__ */ jsxs9("p", { className: "rs-input-error", children: [
4199
4740
  /* @__PURE__ */ jsx15(AlertTriangleIcon, { className: "rs-input-error-icon" }),
4200
4741
  error
4201
4742
  ] }) : hint && /* @__PURE__ */ jsx15("p", { className: "rs-input-hint", children: hint })
@@ -4225,7 +4766,7 @@ function classifyRecoveryLookup(rows, options = {}) {
4225
4766
  }
4226
4767
 
4227
4768
  // src/components/recovery/RecoveryLookupScreen.tsx
4228
- import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
4769
+ import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
4229
4770
  function RecoveryLookupScreen({
4230
4771
  title,
4231
4772
  subtitle,
@@ -4236,7 +4777,7 @@ function RecoveryLookupScreen({
4236
4777
  onSubmit,
4237
4778
  onInvalid
4238
4779
  }) {
4239
- const [txHash, setTxHash] = useState4("");
4780
+ const [txHash, setTxHash] = useState5("");
4240
4781
  const onInvalidRef = useLatestRef(onInvalid);
4241
4782
  const trimmed = txHash.trim();
4242
4783
  const valid = isRecoveryTxHash(trimmed);
@@ -4245,8 +4786,8 @@ function RecoveryLookupScreen({
4245
4786
  onInvalidRef.current?.();
4246
4787
  }
4247
4788
  }, [trimmed, valid, onInvalidRef]);
4248
- return /* @__PURE__ */ jsxs11("div", { className: "rs-screen", children: [
4249
- /* @__PURE__ */ jsxs11("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
4789
+ return /* @__PURE__ */ jsxs10("div", { className: "rs-screen", children: [
4790
+ /* @__PURE__ */ jsxs10("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
4250
4791
  /* @__PURE__ */ jsx16(
4251
4792
  BodyHeader,
4252
4793
  {
@@ -4304,43 +4845,12 @@ var STABLECOIN_SYMBOLS = /* @__PURE__ */ new Set([
4304
4845
  "BUSD",
4305
4846
  "USDE"
4306
4847
  ]);
4307
- var EVM_ADDRESS_RE = /^0x[a-fA-F0-9]{40}$/;
4308
- function resolveTokenDisplay(token, chain, fallback) {
4309
- if (token !== void 0) {
4310
- if (chain === "solana") {
4311
- const solanaToken = getSolanaTokenByMint(token);
4312
- if (solanaToken) {
4313
- return { symbol: solanaToken.symbol, decimals: solanaToken.decimals };
4314
- }
4315
- } else if (chain === "hypercore") {
4316
- const t = HYPERCORE_SOURCE_TOKENS.find(
4317
- (x) => x.address.toLowerCase() === token.toLowerCase()
4318
- );
4319
- if (t) return { symbol: t.symbol, decimals: t.decimals };
4320
- } else if (chain === "tron" || chain === "stellar") {
4321
- const published = getRuntimeTokenByAddress(chain, token);
4322
- if (published) {
4323
- return { symbol: published.symbol, decimals: published.decimals };
4324
- }
4325
- } else if (EVM_ADDRESS_RE.test(token)) {
4326
- const symbol = getTokenSymbol(token, chain);
4327
- const decimals = findTokenDecimals(token, chain);
4328
- if (symbol !== "Token" || decimals !== void 0) {
4329
- return {
4330
- symbol: symbol !== "Token" ? symbol : fallback?.symbol ?? symbol,
4331
- decimals: decimals ?? fallback?.decimals
4332
- };
4333
- }
4334
- }
4335
- }
4336
- return {
4337
- symbol: fallback?.symbol ?? "Token",
4338
- decimals: fallback?.decimals
4339
- };
4848
+ function normalizeStableSymbol(symbol) {
4849
+ return symbol.trim().toUpperCase().replace(/₮/g, "T").replace(/\.E$/, "");
4340
4850
  }
4341
4851
  function maxFractionDigitsFor(symbol) {
4342
4852
  if (!symbol) return 6;
4343
- return STABLECOIN_SYMBOLS.has(symbol.toUpperCase()) ? 3 : 6;
4853
+ return STABLECOIN_SYMBOLS.has(normalizeStableSymbol(symbol)) ? 3 : 6;
4344
4854
  }
4345
4855
  function formatTokenAmount(amount, symbol) {
4346
4856
  if (!Number.isFinite(amount)) return void 0;
@@ -4364,26 +4874,13 @@ function formatRawTokenAmount(rawAmount, token) {
4364
4874
  return formatTokenAmount(value, token.symbol);
4365
4875
  }
4366
4876
  function isDisplayStablecoinSymbol(symbol) {
4367
- return symbol !== void 0 && STABLECOIN_SYMBOLS.has(symbol.toUpperCase());
4877
+ return symbol !== void 0 && STABLECOIN_SYMBOLS.has(normalizeStableSymbol(symbol));
4368
4878
  }
4369
4879
  function priceUsdFor(symbol, prices) {
4370
4880
  if (!symbol) return void 0;
4371
4881
  const quoted = prices[symbol.toUpperCase()];
4372
4882
  return typeof quoted === "number" && quoted > 0 ? quoted : void 0;
4373
4883
  }
4374
- function isRecognizedToken(address, chain) {
4375
- if (address === void 0 || chain === void 0) return false;
4376
- if (chain === "solana") return getSolanaTokenByMint(address) !== void 0;
4377
- if (chain === "hypercore") {
4378
- return HYPERCORE_SOURCE_TOKENS.some(
4379
- (t) => t.address.toLowerCase() === address.toLowerCase()
4380
- );
4381
- }
4382
- if (chain === "tron" || chain === "stellar") {
4383
- return getRuntimeTokenByAddress(chain, address) !== void 0;
4384
- }
4385
- return EVM_ADDRESS_RE.test(address) && isRegistryTokenOnChain(address, chain);
4386
- }
4387
4884
  function estimateReceiveAmount(params) {
4388
4885
  const {
4389
4886
  sourceAmount,
@@ -4435,20 +4932,14 @@ function formatReceiveEstimate(params) {
4435
4932
 
4436
4933
  // src/components/recovery/recovery-display.ts
4437
4934
  function describeRecoveryDeposit(params) {
4438
- const token = params.token ?? "0x";
4439
- const decimals = getTokenDecimalsByAddress(token, params.chainId);
4440
- const symbol = getTokenSymbol(token, params.chainId);
4441
- const raw = toBigInt(params.amountRaw);
4442
- const human = Number(formatUnits3(raw, decimals));
4443
4935
  return {
4444
- symbol,
4445
- decimals,
4446
- amount: formatTokenAmount(human, symbol) ?? formatUnits3(raw, decimals),
4936
+ amount: formatRecoveryAmount(params.amountRaw, params.decimals, params.symbol),
4447
4937
  chainName: getChainName(params.chainId),
4448
4938
  chainIcon: getChainIcon(params.chainId)
4449
4939
  };
4450
4940
  }
4451
4941
  function formatRecoveryAmount(amountRaw, decimals, symbol) {
4942
+ if (decimals === void 0) return "\u2014";
4452
4943
  const raw = toBigInt(amountRaw);
4453
4944
  return formatTokenAmount(Number(formatUnits3(raw, decimals)), symbol) ?? formatUnits3(raw, decimals);
4454
4945
  }
@@ -4468,9 +4959,9 @@ function shortenAddress(addr) {
4468
4959
 
4469
4960
  // src/core/claim-analytics.tsx
4470
4961
  import {
4471
- createContext as createContext4,
4472
- useContext as useContext4,
4473
- useMemo as useMemo5
4962
+ createContext as createContext5,
4963
+ useContext as useContext5,
4964
+ useMemo as useMemo7
4474
4965
  } from "react";
4475
4966
 
4476
4967
  // src/core/recovery.ts
@@ -4789,7 +5280,7 @@ function createClaimAnalyticsController(emit, correlation) {
4789
5280
  };
4790
5281
  return controller;
4791
5282
  }
4792
- var ClaimAnalyticsControllerContext = createContext4(null);
5283
+ var ClaimAnalyticsControllerContext = createContext5(null);
4793
5284
  var noopController = createClaimAnalyticsController(() => {
4794
5285
  });
4795
5286
  function ClaimAnalyticsControllerProvider({
@@ -4798,7 +5289,7 @@ function ClaimAnalyticsControllerProvider({
4798
5289
  correlation
4799
5290
  }) {
4800
5291
  const emit = useClaimAnalyticsEmitter();
4801
- const controller = useMemo5(
5292
+ const controller = useMemo7(
4802
5293
  () => createClaimAnalyticsController(emit, correlation),
4803
5294
  [emit, correlation]
4804
5295
  );
@@ -4806,7 +5297,7 @@ function ClaimAnalyticsControllerProvider({
4806
5297
  return /* @__PURE__ */ jsx17(ClaimAnalyticsControllerContext.Provider, { value: controller, children });
4807
5298
  }
4808
5299
  function useClaimAnalyticsController() {
4809
- return useContext4(ClaimAnalyticsControllerContext) ?? noopController;
5300
+ return useContext5(ClaimAnalyticsControllerContext) ?? noopController;
4810
5301
  }
4811
5302
 
4812
5303
  // src/core/formatters.ts
@@ -4914,7 +5405,7 @@ function formatUserError(raw) {
4914
5405
  }
4915
5406
 
4916
5407
  // src/components/history/HistoryFallbackFlow.tsx
4917
- import { jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
5408
+ import { jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
4918
5409
  function HistoryFallbackFlow({
4919
5410
  service,
4920
5411
  recipient,
@@ -4923,13 +5414,13 @@ function HistoryFallbackFlow({
4923
5414
  onFound
4924
5415
  }) {
4925
5416
  const analytics = useClaimAnalyticsController();
4926
- const [loading, setLoading] = useState5(false);
4927
- const [error, setError] = useState5(null);
4928
- const [matches, setMatches] = useState5(null);
5417
+ const [loading, setLoading] = useState6(false);
5418
+ const [error, setError] = useState6(null);
5419
+ const [matches, setMatches] = useState6(null);
4929
5420
  useEffect7(() => {
4930
5421
  analytics.openStep("lookup");
4931
5422
  }, [analytics]);
4932
- const epochRef = useRef5(0);
5423
+ const epochRef = useRef4(0);
4933
5424
  useEffect7(() => {
4934
5425
  setMatches(null);
4935
5426
  setError(null);
@@ -5008,7 +5499,13 @@ function HistoryFallbackFlow({
5008
5499
  },
5009
5500
  [onBack]
5010
5501
  );
5011
- return /* @__PURE__ */ jsxs12(
5502
+ const matchDisplays = useTokenDisplays(
5503
+ (matches ?? []).map((match) => ({
5504
+ chain: match.sourceChainId,
5505
+ address: match.token
5506
+ }))
5507
+ );
5508
+ return /* @__PURE__ */ jsxs11(
5012
5509
  "div",
5013
5510
  {
5014
5511
  className: "rs-history-lookup",
@@ -5016,8 +5513,8 @@ function HistoryFallbackFlow({
5016
5513
  "aria-label": "Find a deposit",
5017
5514
  onKeyDown: handleKeyDown,
5018
5515
  children: [
5019
- /* @__PURE__ */ jsxs12("div", { className: "rs-modal-header--redesigned", children: [
5020
- /* @__PURE__ */ jsx18("div", { className: "rs-modal-header-nav-left", children: /* @__PURE__ */ jsxs12(
5516
+ /* @__PURE__ */ jsxs11("div", { className: "rs-modal-header--redesigned", children: [
5517
+ /* @__PURE__ */ jsx18("div", { className: "rs-modal-header-nav-left", children: /* @__PURE__ */ jsxs11(
5021
5518
  "button",
5022
5519
  {
5023
5520
  type: "button",
@@ -5041,8 +5538,8 @@ function HistoryFallbackFlow({
5041
5538
  }
5042
5539
  ) })
5043
5540
  ] }),
5044
- matches ? /* @__PURE__ */ jsxs12("div", { className: "rs-screen", children: [
5045
- /* @__PURE__ */ jsxs12("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
5541
+ matches ? /* @__PURE__ */ jsxs11("div", { className: "rs-screen", children: [
5542
+ /* @__PURE__ */ jsxs11("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
5046
5543
  /* @__PURE__ */ jsx18(
5047
5544
  BodyHeader,
5048
5545
  {
@@ -5051,16 +5548,19 @@ function HistoryFallbackFlow({
5051
5548
  subtitle: "This transaction produced multiple deposits. Choose the one to recover."
5052
5549
  }
5053
5550
  ),
5054
- /* @__PURE__ */ jsx18("div", { className: "rs-list", children: matches.map((match) => {
5055
- const { symbol, amount, chainName } = describeRecoveryDeposit({
5551
+ /* @__PURE__ */ jsx18("div", { className: "rs-list", children: matches.map((match, i) => {
5552
+ const display = matchDisplays[i];
5553
+ const symbol = display?.symbol ?? "Token";
5554
+ const { amount, chainName } = describeRecoveryDeposit({
5056
5555
  chainId: match.sourceChainId,
5057
- token: match.token,
5058
- amountRaw: match.amountRaw
5556
+ amountRaw: match.amountRaw,
5557
+ symbol,
5558
+ decimals: display?.decimals
5059
5559
  });
5060
5560
  return /* @__PURE__ */ jsx18(
5061
5561
  ListRow,
5062
5562
  {
5063
- leadingMedia: tokenIconUrl(symbol),
5563
+ leadingMedia: display?.logo,
5064
5564
  title: `${amount} ${symbol}`,
5065
5565
  subtitle: chainName,
5066
5566
  onClick: () => selectMatch(match)
@@ -5094,10 +5594,10 @@ function newestFirst(rows) {
5094
5594
  HistoryFallbackFlow.displayName = "HistoryFallbackFlow";
5095
5595
 
5096
5596
  // src/components/history/HistoryRecoveryFlow.tsx
5097
- import { useCallback as useCallback6, useEffect as useEffect9, useRef as useRef6, useState as useState7 } from "react";
5597
+ import { useCallback as useCallback6, useEffect as useEffect9, useRef as useRef5, useState as useState8 } from "react";
5098
5598
 
5099
5599
  // src/components/recovery/RecoveryOutcomeScreen.tsx
5100
- import { jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
5600
+ import { jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
5101
5601
  function RecoveryOutcomeScreen({
5102
5602
  result,
5103
5603
  error,
@@ -5106,8 +5606,8 @@ function RecoveryOutcomeScreen({
5106
5606
  const success = !!result;
5107
5607
  const explorerTxUrl = useExplorerTxUrl();
5108
5608
  const txUrl = result ? explorerTxUrl(result.chainId, result.txHash) : null;
5109
- return /* @__PURE__ */ jsxs13("div", { className: "rs-screen", children: [
5110
- /* @__PURE__ */ jsxs13("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
5609
+ return /* @__PURE__ */ jsxs12("div", { className: "rs-screen", children: [
5610
+ /* @__PURE__ */ jsxs12("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
5111
5611
  /* @__PURE__ */ jsx19(
5112
5612
  BodyHeader,
5113
5613
  {
@@ -5117,25 +5617,31 @@ function RecoveryOutcomeScreen({
5117
5617
  subtitle: success ? "Your funds are being returned on the source chain." : void 0
5118
5618
  }
5119
5619
  ),
5120
- result ? /* @__PURE__ */ jsxs13("div", { className: "rs-review-details", children: [
5121
- /* @__PURE__ */ jsxs13("div", { className: "rs-review-detail-row", children: [
5620
+ result ? /* @__PURE__ */ jsxs12("div", { className: "rs-review-details", children: [
5621
+ /* @__PURE__ */ jsxs12("div", { className: "rs-review-detail-row", children: [
5122
5622
  /* @__PURE__ */ jsx19("span", { children: "Amount" }),
5123
- /* @__PURE__ */ jsxs13("span", { className: "rs-review-detail-value", children: [
5124
- /* @__PURE__ */ jsxs13("span", { children: [
5623
+ /* @__PURE__ */ jsxs12("span", { className: "rs-review-detail-value", children: [
5624
+ /* @__PURE__ */ jsxs12("span", { children: [
5125
5625
  result.amountDisplay,
5126
5626
  " ",
5127
5627
  result.symbol
5128
5628
  ] }),
5129
- /* @__PURE__ */ jsx19("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx19(TokenIcon, { symbol: result.symbol }) })
5629
+ /* @__PURE__ */ jsx19("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx19(
5630
+ TokenIcon,
5631
+ {
5632
+ token: result.token ? { chain: result.chainId, address: result.token } : void 0,
5633
+ symbol: result.symbol
5634
+ }
5635
+ ) })
5130
5636
  ] })
5131
5637
  ] }),
5132
- /* @__PURE__ */ jsxs13("div", { className: "rs-review-detail-row", children: [
5638
+ /* @__PURE__ */ jsxs12("div", { className: "rs-review-detail-row", children: [
5133
5639
  /* @__PURE__ */ jsx19("span", { children: "Sent to" }),
5134
5640
  /* @__PURE__ */ jsx19("span", { className: "rs-review-detail-value", children: shortenAddress(result.destination) })
5135
5641
  ] }),
5136
- /* @__PURE__ */ jsxs13("div", { className: "rs-review-detail-row", children: [
5642
+ /* @__PURE__ */ jsxs12("div", { className: "rs-review-detail-row", children: [
5137
5643
  /* @__PURE__ */ jsx19("span", { children: "Refund transaction" }),
5138
- txUrl ? /* @__PURE__ */ jsxs13(
5644
+ txUrl ? /* @__PURE__ */ jsxs12(
5139
5645
  "a",
5140
5646
  {
5141
5647
  className: "rs-review-detail-value rs-link",
@@ -5158,40 +5664,58 @@ function RecoveryOutcomeScreen({
5158
5664
  RecoveryOutcomeScreen.displayName = "RecoveryOutcomeScreen";
5159
5665
 
5160
5666
  // src/components/recovery/RecoveryReviewScreen.tsx
5161
- import { useEffect as useEffect8, useState as useState6 } from "react";
5667
+ import { useEffect as useEffect8, useState as useState7 } from "react";
5162
5668
  import { isAddress as isAddress2 } from "viem";
5163
- import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
5669
+ import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
5164
5670
  function RecoveryReviewScreen({
5165
5671
  chainId,
5166
5672
  token,
5167
5673
  amountRaw,
5168
5674
  txHash,
5169
5675
  defaultDestination,
5170
- destinationHint,
5676
+ depositAddress,
5171
5677
  submitting,
5172
5678
  onSubmit,
5173
- onDestinationInvalid
5679
+ onDestinationInvalid,
5680
+ onDestinationIsDepositAddress
5174
5681
  }) {
5175
- const { symbol, amount, chainName, chainIcon } = describeRecoveryDeposit({
5682
+ const { symbol, decimals } = useTokenDisplay(chainId, token);
5683
+ const { amount, chainName, chainIcon } = describeRecoveryDeposit({
5176
5684
  chainId,
5177
- token,
5178
- amountRaw
5685
+ amountRaw,
5686
+ symbol,
5687
+ decimals
5179
5688
  });
5180
5689
  const explorerTxUrl = useExplorerTxUrl();
5181
- const [destination, setDestination] = useState6(
5182
- defaultDestination ?? ""
5690
+ const [destination, setDestination] = useState7(defaultDestination ?? "");
5691
+ const isSelfDestination = isDepositSelfDestination(
5692
+ { depositAddress },
5693
+ destination
5183
5694
  );
5184
- const destinationValid = isAddress2(destination);
5695
+ const destinationValid = isAddress2(destination) && !isSelfDestination;
5185
5696
  const onDestinationInvalidRef = useLatestRef(onDestinationInvalid);
5697
+ const onDestinationIsDepositAddressRef = useLatestRef(
5698
+ onDestinationIsDepositAddress
5699
+ );
5186
5700
  useEffect8(() => {
5187
- if (destination.length > 0 && !destinationValid) {
5701
+ if (destination.length === 0) return;
5702
+ if (isSelfDestination) {
5703
+ onDestinationIsDepositAddressRef.current?.();
5704
+ } else if (!destinationValid) {
5188
5705
  onDestinationInvalidRef.current?.();
5189
5706
  }
5190
- }, [destination, destinationValid, onDestinationInvalidRef]);
5707
+ }, [
5708
+ destination,
5709
+ destinationValid,
5710
+ isSelfDestination,
5711
+ onDestinationInvalidRef,
5712
+ onDestinationIsDepositAddressRef
5713
+ ]);
5714
+ const selfDestinationError = `${shortenAddress(destination)} is this deposit's own address. Enter a different address.`;
5191
5715
  const txUrl = txHash ? explorerTxUrl(chainId, txHash) : null;
5192
5716
  const txShort = txHash ? shortenHash2(txHash) : "\u2014";
5193
- return /* @__PURE__ */ jsxs14("div", { className: "rs-screen", children: [
5194
- /* @__PURE__ */ jsxs14("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
5717
+ return /* @__PURE__ */ jsxs13("div", { className: "rs-screen", children: [
5718
+ /* @__PURE__ */ jsxs13("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
5195
5719
  /* @__PURE__ */ jsx20(
5196
5720
  BodyHeader,
5197
5721
  {
@@ -5200,28 +5724,34 @@ function RecoveryReviewScreen({
5200
5724
  subtitle: "This returns the funds on the source chain. It does not retry the original deposit."
5201
5725
  }
5202
5726
  ),
5203
- /* @__PURE__ */ jsxs14("div", { className: "rs-review-details", children: [
5204
- /* @__PURE__ */ jsxs14("div", { className: "rs-review-detail-row", children: [
5727
+ /* @__PURE__ */ jsxs13("div", { className: "rs-review-details", children: [
5728
+ /* @__PURE__ */ jsxs13("div", { className: "rs-review-detail-row", children: [
5205
5729
  /* @__PURE__ */ jsx20("span", { children: "Amount" }),
5206
- /* @__PURE__ */ jsxs14("span", { className: "rs-review-detail-value", children: [
5207
- /* @__PURE__ */ jsxs14("span", { children: [
5730
+ /* @__PURE__ */ jsxs13("span", { className: "rs-review-detail-value", children: [
5731
+ /* @__PURE__ */ jsxs13("span", { children: [
5208
5732
  amount,
5209
5733
  " ",
5210
5734
  symbol
5211
5735
  ] }),
5212
- /* @__PURE__ */ jsx20("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx20(TokenIcon, { symbol }) })
5736
+ /* @__PURE__ */ jsx20("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx20(
5737
+ TokenIcon,
5738
+ {
5739
+ token: token ? { chain: chainId, address: token } : void 0,
5740
+ symbol
5741
+ }
5742
+ ) })
5213
5743
  ] })
5214
5744
  ] }),
5215
- /* @__PURE__ */ jsxs14("div", { className: "rs-review-detail-row", children: [
5745
+ /* @__PURE__ */ jsxs13("div", { className: "rs-review-detail-row", children: [
5216
5746
  /* @__PURE__ */ jsx20("span", { children: "Source chain" }),
5217
- /* @__PURE__ */ jsxs14("span", { className: "rs-review-detail-value", children: [
5747
+ /* @__PURE__ */ jsxs13("span", { className: "rs-review-detail-value", children: [
5218
5748
  /* @__PURE__ */ jsx20("span", { children: chainName }),
5219
5749
  chainIcon && /* @__PURE__ */ jsx20("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx20(CdnIcon, { src: chainIcon }) })
5220
5750
  ] })
5221
5751
  ] }),
5222
- /* @__PURE__ */ jsxs14("div", { className: "rs-review-detail-row", children: [
5752
+ /* @__PURE__ */ jsxs13("div", { className: "rs-review-detail-row", children: [
5223
5753
  /* @__PURE__ */ jsx20("span", { children: "Deposit transaction" }),
5224
- txUrl ? /* @__PURE__ */ jsxs14(
5754
+ txUrl ? /* @__PURE__ */ jsxs13(
5225
5755
  "a",
5226
5756
  {
5227
5757
  className: "rs-review-detail-value rs-link",
@@ -5243,8 +5773,8 @@ function RecoveryReviewScreen({
5243
5773
  placeholder: "0x\u2026",
5244
5774
  value: destination,
5245
5775
  onChange: (e) => setDestination(e.target.value),
5246
- hint: destinationHint,
5247
- error: destination.length > 0 && !destinationValid ? "Enter a valid address" : void 0
5776
+ hint: `An address you control on ${chainName}.`,
5777
+ error: isSelfDestination ? selfDestinationError : destination.length > 0 && !destinationValid ? "Enter a valid address" : void 0
5248
5778
  }
5249
5779
  ),
5250
5780
  /* @__PURE__ */ jsx20(
@@ -5265,7 +5795,7 @@ function RecoveryReviewScreen({
5265
5795
  RecoveryReviewScreen.displayName = "RecoveryReviewScreen";
5266
5796
 
5267
5797
  // src/components/history/HistoryRecoveryFlow.tsx
5268
- import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
5798
+ import { jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
5269
5799
  function HistoryRecoveryFlow({
5270
5800
  deposit,
5271
5801
  entrySource,
@@ -5278,11 +5808,12 @@ function HistoryRecoveryFlow({
5278
5808
  onRecovered
5279
5809
  }) {
5280
5810
  const analytics = useClaimAnalyticsController();
5281
- const [phase, setPhase] = useState7("review");
5282
- const [outcome, setOutcome] = useState7(null);
5283
- const [error, setError] = useState7(null);
5284
- const [retryable, setRetryable] = useState7(false);
5285
- const lastFailureRef = useRef6(null);
5811
+ const [phase, setPhase] = useState8("review");
5812
+ const [outcome, setOutcome] = useState8(null);
5813
+ const [error, setError] = useState8(null);
5814
+ const [retryable, setRetryable] = useState8(false);
5815
+ const [destination, setDestination] = useState8();
5816
+ const lastFailureRef = useRef5(null);
5286
5817
  useEffect9(() => {
5287
5818
  if (entrySource === "history_row") {
5288
5819
  analytics.selectDeposit({
@@ -5293,13 +5824,13 @@ function HistoryRecoveryFlow({
5293
5824
  }
5294
5825
  analytics.openStep("review");
5295
5826
  }, [analytics, deposit, entrySource]);
5296
- const { symbol, decimals } = describeRecoveryDeposit({
5297
- chainId: deposit.sourceChainId,
5298
- token: deposit.token,
5299
- amountRaw: deposit.amountRaw
5300
- });
5827
+ const { symbol, decimals } = useTokenDisplay(
5828
+ deposit.sourceChainId,
5829
+ deposit.token
5830
+ );
5301
5831
  const submit = useCallback6(
5302
- async (destination) => {
5832
+ async (destination2) => {
5833
+ setDestination(destination2);
5303
5834
  setPhase("submitting");
5304
5835
  onSubmittingChange(true);
5305
5836
  analytics.completeStep("review");
@@ -5312,14 +5843,14 @@ function HistoryRecoveryFlow({
5312
5843
  chainId: deposit.targetChainId,
5313
5844
  depositId: deposit.depositId,
5314
5845
  signer: deposit.signer,
5315
- destination,
5846
+ destination: destination2,
5316
5847
  signRecovery,
5317
5848
  debug
5318
5849
  });
5319
5850
  setOutcome({
5320
5851
  // No destination to reconcile: it is inside the signed struct, so the
5321
5852
  // processor cannot have paid anywhere else.
5322
- destination,
5853
+ destination: destination2,
5323
5854
  txHash: result.transactionHash,
5324
5855
  symbol,
5325
5856
  amountDisplay: formatRecoveryAmount(
@@ -5380,15 +5911,15 @@ function HistoryRecoveryFlow({
5380
5911
  setPhase("review");
5381
5912
  }, [analytics]);
5382
5913
  const submitting = phase === "submitting";
5383
- return /* @__PURE__ */ jsxs15(
5914
+ return /* @__PURE__ */ jsxs14(
5384
5915
  "div",
5385
5916
  {
5386
5917
  className: "rs-history-recovery",
5387
5918
  role: "dialog",
5388
5919
  "aria-label": "Recover deposit",
5389
5920
  children: [
5390
- /* @__PURE__ */ jsxs15("div", { className: "rs-modal-header--redesigned", children: [
5391
- /* @__PURE__ */ jsx21("div", { className: "rs-modal-header-nav-left", children: !submitting && /* @__PURE__ */ jsxs15(
5921
+ /* @__PURE__ */ jsxs14("div", { className: "rs-modal-header--redesigned", children: [
5922
+ /* @__PURE__ */ jsx21("div", { className: "rs-modal-header-nav-left", children: !submitting && /* @__PURE__ */ jsxs14(
5392
5923
  "button",
5393
5924
  {
5394
5925
  type: "button",
@@ -5420,21 +5951,29 @@ function HistoryRecoveryFlow({
5420
5951
  token: deposit.token,
5421
5952
  amountRaw: deposit.amountRaw,
5422
5953
  txHash: deposit.sourceTxHash,
5423
- defaultDestination: deposit.destinationPrefill,
5424
- destinationHint: "Prefilled with the account this deposit was for. Editable.",
5954
+ defaultDestination: destination,
5955
+ depositAddress: deposit.depositAddress,
5425
5956
  submitting,
5426
5957
  onSubmit: submit,
5427
- onDestinationInvalid: () => analytics.friction("refund_destination_invalid", "review")
5958
+ onDestinationInvalid: () => analytics.friction("refund_destination_invalid", "review"),
5959
+ onDestinationIsDepositAddress: () => analytics.friction(
5960
+ "refund_destination_is_deposit_address",
5961
+ "review"
5962
+ )
5428
5963
  }
5429
5964
  ),
5430
5965
  phase === "success" && outcome && /* @__PURE__ */ jsx21(
5431
5966
  RecoveryOutcomeScreen,
5432
5967
  {
5433
- result: { ...outcome, chainId: deposit.sourceChainId },
5968
+ result: {
5969
+ ...outcome,
5970
+ chainId: deposit.sourceChainId,
5971
+ token: deposit.token
5972
+ },
5434
5973
  children: /* @__PURE__ */ jsx21(Button, { variant: "outline", onClick: onBack, fullWidth: true, children: "Back to history" })
5435
5974
  }
5436
5975
  ),
5437
- phase === "failed" && /* @__PURE__ */ jsxs15(RecoveryOutcomeScreen, { error, children: [
5976
+ phase === "failed" && /* @__PURE__ */ jsxs14(RecoveryOutcomeScreen, { error, children: [
5438
5977
  /* @__PURE__ */ jsx21(Button, { variant: "outline", onClick: onBack, fullWidth: true, children: "Back to history" }),
5439
5978
  retryable && /* @__PURE__ */ jsx21(Button, { onClick: retry, fullWidth: true, children: "Try again" })
5440
5979
  ] })
@@ -5445,9 +5984,11 @@ function HistoryRecoveryFlow({
5445
5984
  HistoryRecoveryFlow.displayName = "HistoryRecoveryFlow";
5446
5985
 
5447
5986
  // src/components/history/HistoryOverlay.tsx
5448
- import { Fragment as Fragment4, jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
5987
+ import { Fragment as Fragment4, jsx as jsx22, jsxs as jsxs15 } from "react/jsx-runtime";
5449
5988
  function HistoryOverlay({
5450
5989
  controller,
5990
+ bankHistory,
5991
+ bankSupportUrl,
5451
5992
  backLabel,
5452
5993
  title,
5453
5994
  recipient,
@@ -5464,9 +6005,9 @@ function HistoryOverlay({
5464
6005
  onEvent
5465
6006
  }) {
5466
6007
  const recovering = signRecovery ? controller.recovering : null;
5467
- const [fallbackOpen, setFallbackOpen] = useState8(false);
5468
- const [attempt, setAttempt] = useState8(null);
5469
- const claimControllerRef = useRef7(null);
6008
+ const [fallbackOpen, setFallbackOpen] = useState9(false);
6009
+ const [attempt, setAttempt] = useState9(null);
6010
+ const claimControllerRef = useRef6(null);
5470
6011
  const beginAttempt = useCallback7(
5471
6012
  (entrySource) => {
5472
6013
  const id = randomUuid();
@@ -5551,15 +6092,15 @@ function HistoryOverlay({
5551
6092
  claim?.close("host_controlled");
5552
6093
  };
5553
6094
  }, [attempt]);
5554
- const claimSessionProperties = useMemo6(
6095
+ const claimSessionProperties = useMemo8(
5555
6096
  () => ({
5556
6097
  presentation: inline ? "inline" : "overlay",
5557
6098
  overlay_close_enabled: !inline && Boolean(closeOnOverlayClick),
5558
- prefills: { transaction_hash: false, refund_destination: true }
6099
+ prefills: { transaction_hash: false, refund_destination: false }
5559
6100
  }),
5560
6101
  [inline, closeOnOverlayClick]
5561
6102
  );
5562
- const layers = /* @__PURE__ */ jsxs16(Fragment4, { children: [
6103
+ const layers = /* @__PURE__ */ jsxs15(Fragment4, { children: [
5563
6104
  fallbackOpen && recipient && !recovering && /* @__PURE__ */ jsx22(
5564
6105
  HistoryFallbackFlow,
5565
6106
  {
@@ -5585,10 +6126,12 @@ function HistoryOverlay({
5585
6126
  }
5586
6127
  )
5587
6128
  ] });
5588
- return /* @__PURE__ */ jsxs16(Fragment4, { children: [
6129
+ return /* @__PURE__ */ jsxs15(Fragment4, { children: [
5589
6130
  /* @__PURE__ */ jsx22(
5590
6131
  DepositHistoryPanel,
5591
6132
  {
6133
+ bankHistory,
6134
+ bankSupportUrl,
5592
6135
  deposits: controller.deposits,
5593
6136
  isLoading: controller.isLoading,
5594
6137
  error: controller.error,
@@ -5630,7 +6173,7 @@ function HistoryOverlay({
5630
6173
  }
5631
6174
 
5632
6175
  // src/components/history/useHistoryPanel.ts
5633
- import { useCallback as useCallback8, useEffect as useEffect11, useMemo as useMemo7, useRef as useRef8, useState as useState9 } from "react";
6176
+ import { useCallback as useCallback8, useEffect as useEffect11, useMemo as useMemo9, useRef as useRef7, useState as useState10 } from "react";
5634
6177
  var MAX_TIMEOUT_MS = 2147483647;
5635
6178
  function sortByCreatedAtDesc(items) {
5636
6179
  return [...items].sort((a, b) => {
@@ -5646,19 +6189,19 @@ function useHistoryPanel({
5646
6189
  canRecover,
5647
6190
  analytics
5648
6191
  }) {
5649
- const [isPanelOpen, setIsPanelOpen] = useState9(false);
5650
- const [deposits, setDeposits] = useState9([]);
5651
- const [hasMore, setHasMore] = useState9(false);
5652
- const [isLoading, setIsLoading] = useState9(false);
5653
- const [isLoadingMore, setIsLoadingMore] = useState9(false);
5654
- const [error, setError] = useState9(null);
5655
- const cursorRef = useRef8(null);
5656
- const staleRef = useRef8(false);
5657
- const loadedRef = useRef8(false);
5658
- const recipientRef = useRef8(recipient);
5659
- const requestRef = useRef8(0);
5660
- const [recovering, setRecovering] = useState9(null);
5661
- const [recoverySubmitting, setRecoverySubmitting] = useState9(false);
6192
+ const [isPanelOpen, setIsPanelOpen] = useState10(false);
6193
+ const [deposits, setDeposits] = useState10([]);
6194
+ const [hasMore, setHasMore] = useState10(false);
6195
+ const [isLoading, setIsLoading] = useState10(false);
6196
+ const [isLoadingMore, setIsLoadingMore] = useState10(false);
6197
+ const [error, setError] = useState10(null);
6198
+ const cursorRef = useRef7(null);
6199
+ const staleRef = useRef7(false);
6200
+ const loadedRef = useRef7(false);
6201
+ const recipientRef = useRef7(recipient);
6202
+ const requestRef = useRef7(0);
6203
+ const [recovering, setRecovering] = useState10(null);
6204
+ const [recoverySubmitting, setRecoverySubmitting] = useState10(false);
5662
6205
  const fetchHistory = useCallback8(
5663
6206
  async (mode = "initial") => {
5664
6207
  if (!recipient) return;
@@ -5782,7 +6325,7 @@ function useHistoryPanel({
5782
6325
  staleRef.current = true;
5783
6326
  }, []);
5784
6327
  const cancelRecovery = useCallback8(() => setRecovering(null), []);
5785
- return useMemo7(
6328
+ return useMemo9(
5786
6329
  () => ({
5787
6330
  deposits,
5788
6331
  isLoading,
@@ -6029,6 +6572,9 @@ var REMOVED_UI_CONFIG_KEYS = {
6029
6572
  checkLiquidity: "removed \u2014 the modal no longer surfaces a liquidity cap. Route capacity is enforced when the deposit is processed.",
6030
6573
  showHistoryButton: "removed \u2014 deposit history is always offered, from the modal's home screen. There is no way to hide it."
6031
6574
  };
6575
+ var REMOVED_BANK_ONRAMP_KEYS = {
6576
+ currency: "removed \u2014 the currency follows the residence the customer declares at verification: EUR inside SEPA, USD elsewhere."
6577
+ };
6032
6578
  var warned = /* @__PURE__ */ new Set();
6033
6579
  function warnOnce(component, key, replacement) {
6034
6580
  const id = `${component}.${key}`;
@@ -6046,6 +6592,18 @@ function warnRemovedProps(component, props) {
6046
6592
  warnOnce(component, key, table[key]);
6047
6593
  }
6048
6594
  }
6595
+ const bankOnramp = props.bankOnramp;
6596
+ if (bankOnramp && typeof bankOnramp === "object") {
6597
+ for (const key of Object.keys(REMOVED_BANK_ONRAMP_KEYS)) {
6598
+ if (Object.prototype.hasOwnProperty.call(bankOnramp, key)) {
6599
+ warnOnce(
6600
+ component,
6601
+ `bankOnramp.${key}`,
6602
+ REMOVED_BANK_ONRAMP_KEYS[key]
6603
+ );
6604
+ }
6605
+ }
6606
+ }
6049
6607
  const uiConfig = props.uiConfig;
6050
6608
  if (uiConfig && typeof uiConfig === "object") {
6051
6609
  for (const key of Object.keys(REMOVED_UI_CONFIG_KEYS)) {
@@ -6215,22 +6773,22 @@ function isSubmissionUncertain(error) {
6215
6773
  }
6216
6774
 
6217
6775
  // src/components/steps/ProcessingStep.tsx
6218
- import { useCallback as useCallback10, useEffect as useEffect14, useRef as useRef10, useState as useState13 } from "react";
6776
+ import { useCallback as useCallback10, useEffect as useEffect13, useRef as useRef9, useState as useState13 } from "react";
6219
6777
 
6220
6778
  // src/components/ui/Tooltip.tsx
6221
6779
  import {
6222
- useState as useState10,
6223
- useRef as useRef9,
6780
+ useState as useState11,
6781
+ useRef as useRef8,
6224
6782
  useEffect as useEffect12,
6225
6783
  useCallback as useCallback9
6226
6784
  } from "react";
6227
6785
  import { createPortal as createPortal2 } from "react-dom";
6228
- import { jsx as jsx23, jsxs as jsxs17 } from "react/jsx-runtime";
6786
+ import { jsx as jsx23, jsxs as jsxs16 } from "react/jsx-runtime";
6229
6787
  function Tooltip({ content, children, className }) {
6230
- const [open, setOpen] = useState10(false);
6231
- const [position, setPosition] = useState10(null);
6232
- const triggerRef = useRef9(null);
6233
- const bubbleRef = useRef9(null);
6788
+ const [open, setOpen] = useState11(false);
6789
+ const [position, setPosition] = useState11(null);
6790
+ const triggerRef = useRef8(null);
6791
+ const bubbleRef = useRef8(null);
6234
6792
  const updatePosition = useCallback9(() => {
6235
6793
  const trigger = triggerRef.current;
6236
6794
  if (!trigger) return;
@@ -6266,7 +6824,7 @@ function Tooltip({ content, children, className }) {
6266
6824
  window.removeEventListener("resize", updatePosition);
6267
6825
  };
6268
6826
  }, [open, updatePosition]);
6269
- return /* @__PURE__ */ jsxs17(
6827
+ return /* @__PURE__ */ jsxs16(
6270
6828
  "span",
6271
6829
  {
6272
6830
  ref: triggerRef,
@@ -6315,18 +6873,18 @@ function Tooltip({ content, children, className }) {
6315
6873
  Tooltip.displayName = "Tooltip";
6316
6874
 
6317
6875
  // src/components/ui/FeesAccordion.tsx
6318
- import { useState as useState11 } from "react";
6319
- import { jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
6876
+ import { useState as useState12 } from "react";
6877
+ import { jsx as jsx24, jsxs as jsxs17 } from "react/jsx-runtime";
6320
6878
  function FeesAccordion({ total, rows, tooltip }) {
6321
- const [open, setOpen] = useState11(false);
6879
+ const [open, setOpen] = useState12(false);
6322
6880
  const expandable = rows.length > 0;
6323
- return /* @__PURE__ */ jsxs18("div", { className: "rs-fees-accordion", children: [
6324
- /* @__PURE__ */ jsxs18("div", { className: "rs-fees-accordion-summary", children: [
6325
- /* @__PURE__ */ jsxs18("span", { className: "rs-fees-accordion-label", children: [
6881
+ return /* @__PURE__ */ jsxs17("div", { className: "rs-fees-accordion", children: [
6882
+ /* @__PURE__ */ jsxs17("div", { className: "rs-fees-accordion-summary", children: [
6883
+ /* @__PURE__ */ jsxs17("span", { className: "rs-fees-accordion-label", children: [
6326
6884
  /* @__PURE__ */ jsx24("span", { children: "Fees" }),
6327
6885
  tooltip && /* @__PURE__ */ jsx24(Tooltip, { content: tooltip, children: /* @__PURE__ */ jsx24("span", { className: "rs-review-detail-info", "aria-label": "Fees info", children: /* @__PURE__ */ jsx24(InfoIcon, {}) }) })
6328
6886
  ] }),
6329
- /* @__PURE__ */ jsxs18(
6887
+ /* @__PURE__ */ jsxs17(
6330
6888
  "button",
6331
6889
  {
6332
6890
  type: "button",
@@ -6349,9 +6907,9 @@ function FeesAccordion({ total, rows, tooltip }) {
6349
6907
  }
6350
6908
  )
6351
6909
  ] }),
6352
- expandable && open && /* @__PURE__ */ jsx24("div", { className: "rs-fees-accordion-rows", children: rows.map((row, i) => /* @__PURE__ */ jsxs18("div", { className: "rs-fees-accordion-row", children: [
6910
+ expandable && open && /* @__PURE__ */ jsx24("div", { className: "rs-fees-accordion-rows", children: rows.map((row, i) => /* @__PURE__ */ jsxs17("div", { className: "rs-fees-accordion-row", children: [
6353
6911
  /* @__PURE__ */ jsx24("span", { children: row.label }),
6354
- /* @__PURE__ */ jsxs18("span", { className: "rs-review-detail-value", children: [
6912
+ /* @__PURE__ */ jsxs17("span", { className: "rs-review-detail-value", children: [
6355
6913
  /* @__PURE__ */ jsx24(
6356
6914
  "span",
6357
6915
  {
@@ -6374,13 +6932,14 @@ function FeesAccordion({ total, rows, tooltip }) {
6374
6932
  FeesAccordion.displayName = "FeesAccordion";
6375
6933
 
6376
6934
  // src/components/steps/SwappedReceipt.tsx
6377
- import { jsx as jsx25, jsxs as jsxs19 } from "react/jsx-runtime";
6935
+ import { jsx as jsx25, jsxs as jsxs18 } from "react/jsx-runtime";
6378
6936
  function SwappedReceipt({
6379
6937
  onrampMethod,
6380
6938
  onrampMethodIcon,
6381
6939
  amountPaid,
6382
6940
  depositedAmount,
6383
6941
  depositedSymbol,
6942
+ depositedToken,
6384
6943
  feesTotal,
6385
6944
  feeRows,
6386
6945
  feesTooltip,
@@ -6388,26 +6947,26 @@ function SwappedReceipt({
6388
6947
  onNewDeposit,
6389
6948
  onClose
6390
6949
  }) {
6391
- return /* @__PURE__ */ jsxs19("div", { className: "rs-screen", children: [
6392
- /* @__PURE__ */ jsxs19("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
6950
+ return /* @__PURE__ */ jsxs18("div", { className: "rs-screen", children: [
6951
+ /* @__PURE__ */ jsxs18("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
6393
6952
  /* @__PURE__ */ jsx25(BodyHeader, { icon: /* @__PURE__ */ jsx25(CheckIcon, {}), title: "Deposit successful" }),
6394
- /* @__PURE__ */ jsxs19("div", { className: "rs-review-details", children: [
6395
- onrampMethod && /* @__PURE__ */ jsxs19("div", { className: "rs-review-detail-row", children: [
6953
+ /* @__PURE__ */ jsxs18("div", { className: "rs-review-details", children: [
6954
+ onrampMethod && /* @__PURE__ */ jsxs18("div", { className: "rs-review-detail-row", children: [
6396
6955
  /* @__PURE__ */ jsx25("span", { children: "Onramp method" }),
6397
- /* @__PURE__ */ jsxs19("span", { className: "rs-review-detail-value", children: [
6956
+ /* @__PURE__ */ jsxs18("span", { className: "rs-review-detail-value", children: [
6398
6957
  /* @__PURE__ */ jsx25("span", { children: onrampMethod }),
6399
6958
  onrampMethodIcon && /* @__PURE__ */ jsx25("span", { className: "rs-review-detail-icon rs-review-detail-icon--square", children: /* @__PURE__ */ jsx25(CdnIcon, { src: onrampMethodIcon }) })
6400
6959
  ] })
6401
6960
  ] }),
6402
- amountPaid && /* @__PURE__ */ jsxs19("div", { className: "rs-review-detail-row", children: [
6961
+ amountPaid && /* @__PURE__ */ jsxs18("div", { className: "rs-review-detail-row", children: [
6403
6962
  /* @__PURE__ */ jsx25("span", { children: "Amount paid" }),
6404
6963
  /* @__PURE__ */ jsx25("span", { className: "rs-review-detail-value", children: amountPaid })
6405
6964
  ] }),
6406
- /* @__PURE__ */ jsxs19("div", { className: "rs-review-detail-row", children: [
6965
+ /* @__PURE__ */ jsxs18("div", { className: "rs-review-detail-row", children: [
6407
6966
  /* @__PURE__ */ jsx25("span", { children: "Deposited amount" }),
6408
- /* @__PURE__ */ jsxs19("span", { className: "rs-review-detail-value", children: [
6967
+ /* @__PURE__ */ jsxs18("span", { className: "rs-review-detail-value", children: [
6409
6968
  /* @__PURE__ */ jsx25("span", { children: depositedAmount }),
6410
- depositedSymbol && /* @__PURE__ */ jsx25("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx25(TokenIcon, { symbol: depositedSymbol }) })
6969
+ depositedSymbol && /* @__PURE__ */ jsx25("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx25(TokenIcon, { token: depositedToken, symbol: depositedSymbol }) })
6411
6970
  ] })
6412
6971
  ] }),
6413
6972
  feesTotal != null && /* @__PURE__ */ jsx25(
@@ -6419,7 +6978,7 @@ function SwappedReceipt({
6419
6978
  }
6420
6979
  )
6421
6980
  ] }),
6422
- /* @__PURE__ */ jsxs19("div", { className: "rs-screen-button-row", children: [
6981
+ /* @__PURE__ */ jsxs18("div", { className: "rs-screen-button-row", children: [
6423
6982
  onNewDeposit && /* @__PURE__ */ jsx25(Button, { variant: "outline", onClick: onNewDeposit, fullWidth: true, children: newLabel }),
6424
6983
  onClose && /* @__PURE__ */ jsx25(Button, { onClick: onClose, fullWidth: true, children: "Done" })
6425
6984
  ] })
@@ -6605,73 +7164,35 @@ function failureMessageForEvent(event) {
6605
7164
  }
6606
7165
 
6607
7166
  // src/core/useTokenPrices.ts
6608
- import { useEffect as useEffect13, useState as useState12 } from "react";
6609
- var PRICE_SERVICE_NATIVE = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
6610
- var WRAPPED_SOL_MINT = "So11111111111111111111111111111111111111112";
6611
- var SOL_SYSTEM_PROGRAM = "11111111111111111111111111111111";
6612
- function isSolanaNativeAddress(address) {
6613
- if (!address) return true;
6614
- const lower = address.toLowerCase();
6615
- return lower === "native" || lower === SOL_SYSTEM_PROGRAM;
6616
- }
6617
- function isNativeAddress(address) {
6618
- if (!address) return true;
6619
- return address.toLowerCase() === NATIVE_TOKEN_ADDRESS.toLowerCase();
6620
- }
6621
- function caip2For(token) {
6622
- if (token.chainId === "solana") {
6623
- const mint = isSolanaNativeAddress(token.address) ? WRAPPED_SOL_MINT : token.address;
6624
- return mint ? `${SOLANA_MAINNET_CAIP2}:${mint}` : void 0;
6625
- }
6626
- if (typeof token.chainId !== "number") return void 0;
6627
- const address = isNativeAddress(token.address) ? PRICE_SERVICE_NATIVE : token.address;
6628
- return `${toEvmCaip2(token.chainId)}:${address.toLowerCase()}`;
6629
- }
6630
- async function fetchTokenPriceUsd(service, token) {
6631
- const caip2 = caip2For(token);
6632
- if (!caip2) return null;
6633
- const prices = await service.fetchPricesByAddress([caip2]);
6634
- const price = prices[caip2];
6635
- return typeof price === "number" && price > 0 ? price : null;
6636
- }
6637
- function useTokenPrices(service, tokens) {
6638
- const [prices, setPrices] = useState12({});
7167
+ import { useMemo as useMemo10 } from "react";
7168
+ var ZERO_ADDRESS2 = "0x0000000000000000000000000000000000000000";
7169
+ function addressFor(token) {
7170
+ if (token.address) return token.address;
7171
+ return token.chainId === "solana" ? "native" : ZERO_ADDRESS2;
7172
+ }
7173
+ function useTokenPrices(tokens) {
6639
7174
  const defined = tokens.filter((t) => Boolean(t?.symbol));
6640
- const entries = [
6641
- ...new Map(
6642
- defined.flatMap((token) => {
6643
- const caip2 = caip2For(token);
6644
- return caip2 ? [{ symbol: token.symbol.toUpperCase(), caip2 }] : [];
6645
- }).map((entry) => [entry.caip2, entry])
6646
- ).values()
6647
- ].sort((a, b) => a.caip2.localeCompare(b.caip2));
6648
- const key = JSON.stringify(entries);
6649
- useEffect13(() => {
6650
- if (key === "[]") return;
6651
- let cancelled = false;
6652
- const parsed = JSON.parse(key);
6653
- const caip2Ids = [...new Set(parsed.map((e) => e.caip2))];
6654
- service.fetchPricesByAddress(caip2Ids).then((byAddress) => {
6655
- if (cancelled) return;
6656
- const merged = {};
6657
- for (const entry of parsed) {
6658
- const price = byAddress[entry.caip2];
6659
- if (typeof price === "number") merged[entry.symbol] = price;
6660
- }
6661
- setPrices(merged);
6662
- }).catch(() => {
6663
- });
6664
- return () => {
6665
- cancelled = true;
6666
- };
6667
- }, [service, key]);
6668
- return prices;
7175
+ const refs = defined.map((token) => ({
7176
+ chain: token.chainId,
7177
+ address: addressFor(token)
7178
+ }));
7179
+ const byId = useAssetPrices(refs);
7180
+ const key = defined.map((t) => `${String(t.chainId)}:${addressFor(t)}:${t.symbol}`).join("|");
7181
+ return useMemo10(() => {
7182
+ const out = {};
7183
+ for (const token of defined) {
7184
+ const id = assetIdFor(token.chainId, addressFor(token));
7185
+ const usd = id ? byId[id] : void 0;
7186
+ if (typeof usd === "number") out[token.symbol.toUpperCase()] = usd;
7187
+ }
7188
+ return out;
7189
+ }, [key, byId]);
6669
7190
  }
6670
7191
 
6671
7192
  // src/components/steps/ProcessingStep.tsx
6672
- import { Fragment as Fragment5, jsx as jsx27, jsxs as jsxs20 } from "react/jsx-runtime";
7193
+ import { Fragment as Fragment5, jsx as jsx27, jsxs as jsxs19 } from "react/jsx-runtime";
6673
7194
  function SuccessBadge() {
6674
- return /* @__PURE__ */ jsxs20(
7195
+ return /* @__PURE__ */ jsxs19(
6675
7196
  "svg",
6676
7197
  {
6677
7198
  width: "40",
@@ -6705,7 +7226,7 @@ function SuccessBadge() {
6705
7226
  );
6706
7227
  }
6707
7228
  function FailedBadge() {
6708
- return /* @__PURE__ */ jsxs20(
7229
+ return /* @__PURE__ */ jsxs19(
6709
7230
  "svg",
6710
7231
  {
6711
7232
  width: "40",
@@ -6847,7 +7368,7 @@ function TickerChar({ value }) {
6847
7368
  const [current, setCurrent] = useState13(value);
6848
7369
  const [previous, setPrevious] = useState13(null);
6849
7370
  const [animKey, setAnimKey] = useState13(0);
6850
- useEffect14(() => {
7371
+ useEffect13(() => {
6851
7372
  if (value === current) return;
6852
7373
  setPrevious(current);
6853
7374
  setCurrent(value);
@@ -6855,7 +7376,7 @@ function TickerChar({ value }) {
6855
7376
  const timeout = setTimeout(() => setPrevious(null), 360);
6856
7377
  return () => clearTimeout(timeout);
6857
7378
  }, [value, current]);
6858
- return /* @__PURE__ */ jsxs20("span", { className: "rs-ticker-slot", children: [
7379
+ return /* @__PURE__ */ jsxs19("span", { className: "rs-ticker-slot", children: [
6859
7380
  previous !== null && /* @__PURE__ */ jsx27("span", { className: "rs-ticker-out", children: previous }, `out-${animKey}`),
6860
7381
  /* @__PURE__ */ jsx27("span", { className: "rs-ticker-in", children: current }, `in-${animKey}`)
6861
7382
  ] });
@@ -6891,6 +7412,10 @@ function getCurrentPhaseId(state, phaseTimings) {
6891
7412
  if (state.lastEvent?.type === "deposit-received") return "received";
6892
7413
  return "confirming";
6893
7414
  }
7415
+ function getCompletionDestinationAmount(event) {
7416
+ const amount = event?.data?.destination?.amount;
7417
+ return typeof amount === "string" ? amount : void 0;
7418
+ }
6894
7419
  function getCompletionDestinationTxHash(event) {
6895
7420
  const eventData = event?.data;
6896
7421
  const swapTxHash = eventData?.swap?.transactionHash;
@@ -6901,7 +7426,8 @@ function getTerminalProcessingOutcome(event) {
6901
7426
  if (event?.type === "post-bridge-swap-complete") {
6902
7427
  return {
6903
7428
  type: "complete",
6904
- destinationTxHash: getCompletionDestinationTxHash(event)
7429
+ destinationTxHash: getCompletionDestinationTxHash(event),
7430
+ destinationAmount: getCompletionDestinationAmount(event)
6905
7431
  };
6906
7432
  }
6907
7433
  if (event?.type === "post-bridge-swap-failed") {
@@ -6913,7 +7439,8 @@ function getTerminalProcessingOutcome(event) {
6913
7439
  if (event?.type === "bridge-complete") {
6914
7440
  return {
6915
7441
  type: "complete",
6916
- destinationTxHash: getCompletionDestinationTxHash(event)
7442
+ destinationTxHash: getCompletionDestinationTxHash(event),
7443
+ destinationAmount: getCompletionDestinationAmount(event)
6917
7444
  };
6918
7445
  }
6919
7446
  if (event?.type === "bridge-failed") {
@@ -6981,10 +7508,10 @@ function ProcessingStep({
6981
7508
  onSettledChange,
6982
7509
  onError
6983
7510
  }) {
6984
- const startTimeRef = useRef10(Date.now());
6985
- const pollIntervalRef = useRef10(INITIAL_POLL_INTERVAL);
6986
- const pollTimeoutRef = useRef10(null);
6987
- const escalatedDelayRef = useRef10(false);
7511
+ const startTimeRef = useRef9(Date.now());
7512
+ const pollIntervalRef = useRef9(INITIAL_POLL_INTERVAL);
7513
+ const pollTimeoutRef = useRef9(null);
7514
+ const escalatedDelayRef = useRef9(false);
6988
7515
  const processingContextRef = useLatestRef({
6989
7516
  amount,
6990
7517
  sourceChain,
@@ -6998,8 +7525,8 @@ function ProcessingStep({
6998
7525
  const onDepositFailedRef = useLatestRef(onDepositFailed);
6999
7526
  const onErrorRef = useLatestRef(onError);
7000
7527
  const explorerTxUrl = useExplorerTxUrl();
7001
- const initialTerminalEventRef = useRef10(null);
7002
- const completedDirectTransferTxHashRef = useRef10(null);
7528
+ const initialTerminalEventRef = useRef9(null);
7529
+ const completedDirectTransferTxHashRef = useRef9(null);
7003
7530
  const [state, setState] = useState13(() => {
7004
7531
  if (directTransfer) return { type: "complete" };
7005
7532
  const initial = getInitialProcessingState(
@@ -7029,8 +7556,8 @@ function ProcessingStep({
7029
7556
  if (latchedTiming === void 0 && quote?.timing !== void 0) {
7030
7557
  setLatchedTiming(quote.timing);
7031
7558
  }
7032
- const timingStateRef = useRef10("expected");
7033
- const servedTimingLatchRef = useRef10(false);
7559
+ const timingStateRef = useRef9("expected");
7560
+ const servedTimingLatchRef = useRef9(false);
7034
7561
  const updatePhaseTimings = useCallback10(
7035
7562
  (updater) => {
7036
7563
  setPhaseTimings((previous) => {
@@ -7041,7 +7568,7 @@ function ProcessingStep({
7041
7568
  },
7042
7569
  [txHash]
7043
7570
  );
7044
- useEffect14(() => {
7571
+ useEffect13(() => {
7045
7572
  if (!directTransfer || completedDirectTransferTxHashRef.current === txHash) {
7046
7573
  return;
7047
7574
  }
@@ -7075,7 +7602,7 @@ function ProcessingStep({
7075
7602
  txHash,
7076
7603
  updatePhaseTimings
7077
7604
  ]);
7078
- useEffect14(() => {
7605
+ useEffect13(() => {
7079
7606
  const event = initialTerminalEventRef.current;
7080
7607
  if (!event) return;
7081
7608
  initialTerminalEventRef.current = null;
@@ -7100,7 +7627,8 @@ function ProcessingStep({
7100
7627
  sourceDecimals: context.sourceDecimals,
7101
7628
  amountUsd: context.amountUsd,
7102
7629
  targetChain: context.targetChain,
7103
- targetToken: context.targetToken
7630
+ targetToken: context.targetToken,
7631
+ destinationAmount: outcome.destinationAmount
7104
7632
  }
7105
7633
  );
7106
7634
  return;
@@ -7118,13 +7646,13 @@ function ProcessingStep({
7118
7646
  processingContextRef,
7119
7647
  txHash
7120
7648
  ]);
7121
- const onSettledChangeRef = useRef10(onSettledChange);
7649
+ const onSettledChangeRef = useRef9(onSettledChange);
7122
7650
  onSettledChangeRef.current = onSettledChange;
7123
- useEffect14(() => {
7651
+ useEffect13(() => {
7124
7652
  onSettledChangeRef.current?.(state.type !== "processing");
7125
7653
  return () => onSettledChangeRef.current?.(false);
7126
7654
  }, [state.type]);
7127
- useEffect14(() => {
7655
+ useEffect13(() => {
7128
7656
  if (directTransfer || state.type !== "processing") return;
7129
7657
  const updateElapsed = () => {
7130
7658
  setElapsedSeconds(
@@ -7135,7 +7663,7 @@ function ProcessingStep({
7135
7663
  const intervalId = setInterval(updateElapsed, 1e3);
7136
7664
  return () => clearInterval(intervalId);
7137
7665
  }, [directTransfer, state.type]);
7138
- useEffect14(() => {
7666
+ useEffect13(() => {
7139
7667
  if (state.type === "processing") return;
7140
7668
  const endedAt = state.type === "complete" ? phaseTimings.completedAt ?? Date.now() : Date.now();
7141
7669
  setElapsedSeconds(Math.floor((endedAt - startTimeRef.current) / 1e3));
@@ -7143,31 +7671,26 @@ function ProcessingStep({
7143
7671
  (previous) => previous.endedAt !== void 0 ? previous : { ...previous, endedAt }
7144
7672
  );
7145
7673
  }, [phaseTimings.completedAt, state.type, updatePhaseTimings]);
7146
- useEffect14(() => {
7674
+ useEffect13(() => {
7147
7675
  if (!state.lastEvent) return;
7148
7676
  updatePhaseTimings(
7149
7677
  (previous) => syncPhaseTimings(previous, state.lastEvent)
7150
7678
  );
7151
7679
  }, [state.lastEvent?.time, state.lastEvent?.type, updatePhaseTimings]);
7152
7680
  const [swappedFiatContext, setSwappedFiatContext] = useState13(null);
7153
- useEffect14(() => {
7681
+ useEffect13(() => {
7154
7682
  let cancelled = false;
7155
7683
  let timeoutId;
7156
7684
  const isFiatSwappedOrder = isSwappedOrder && swappedContext?.variant === "fiat";
7157
7685
  const expectedOrderUuid = swappedContext?.expectedOrderUuid ?? null;
7158
7686
  setSwappedFiatContext(null);
7159
- if (isFiatSwappedOrder && !expectedOrderUuid) {
7687
+ if (!isSwappedOrder || !expectedOrderUuid) {
7160
7688
  return () => {
7161
7689
  cancelled = true;
7162
7690
  };
7163
7691
  }
7692
+ const orderId = expectedOrderUuid;
7164
7693
  let attempts = 0;
7165
- const matchesCurrentDeposit = (res) => {
7166
- if (isFiatSwappedOrder) {
7167
- return res.orderId === expectedOrderUuid;
7168
- }
7169
- return res.transactionId != null && res.transactionId.toLowerCase() === txHash.toLowerCase();
7170
- };
7171
7694
  const scheduleRetry = () => {
7172
7695
  if (cancelled || !isFiatSwappedOrder || attempts >= SWAPPED_FIAT_STATUS_MAX_ATTEMPTS) {
7173
7696
  return;
@@ -7180,9 +7703,9 @@ function ProcessingStep({
7180
7703
  async function fetchContext() {
7181
7704
  attempts += 1;
7182
7705
  try {
7183
- const res = await service.fetchSwappedOrderStatus(smartAccount);
7706
+ const res = await service.fetchSwappedOrder(orderId);
7184
7707
  if (cancelled) return;
7185
- if (!res || !matchesCurrentDeposit(res)) {
7708
+ if (!res || res.orderId !== orderId) {
7186
7709
  scheduleRetry();
7187
7710
  return;
7188
7711
  }
@@ -7201,13 +7724,11 @@ function ProcessingStep({
7201
7724
  };
7202
7725
  }, [
7203
7726
  service,
7204
- smartAccount,
7205
- txHash,
7206
7727
  isSwappedOrder,
7207
7728
  swappedContext?.variant,
7208
7729
  swappedContext?.expectedOrderUuid
7209
7730
  ]);
7210
- useEffect14(() => {
7731
+ useEffect13(() => {
7211
7732
  if (directTransfer) return;
7212
7733
  if (state.type !== "processing") {
7213
7734
  pollIntervalRef.current = INITIAL_POLL_INTERVAL;
@@ -7241,7 +7762,8 @@ function ProcessingStep({
7241
7762
  eventForCurrentTx,
7242
7763
  txHash
7243
7764
  );
7244
- const destinationTxHash2 = eventForCurrentTx.data?.destination?.transactionHash;
7765
+ const destination = eventForCurrentTx.data?.destination;
7766
+ const destinationTxHash2 = destination?.transactionHash;
7245
7767
  debugLog(debug, "processing", "state:complete", {
7246
7768
  txHash,
7247
7769
  sourceTxHash: sourceTxHash2,
@@ -7256,7 +7778,8 @@ function ProcessingStep({
7256
7778
  sourceDecimals: context.sourceDecimals,
7257
7779
  amountUsd: context.amountUsd,
7258
7780
  targetChain: context.targetChain,
7259
- targetToken: context.targetToken
7781
+ targetToken: context.targetToken,
7782
+ destinationAmount: typeof destination?.amount === "string" ? destination.amount : void 0
7260
7783
  });
7261
7784
  return;
7262
7785
  }
@@ -7342,8 +7865,8 @@ function ProcessingStep({
7342
7865
  const lastEvent = state.lastEvent;
7343
7866
  const failureMessage = state.type === "failed" ? state.message : void 0;
7344
7867
  const timelineNowMs = phaseTimings.endedAt ?? Date.now();
7345
- const flowNoun = flowLabel === "withdraw" ? "withdrawal" : "deposit";
7346
- const flowCapitalized = flowLabel === "withdraw" ? "Withdrawal" : "Deposit";
7868
+ const flowNoun = flowLabel === "withdraw" ? "withdrawal" : flowLabel === "payment" ? "payment" : "deposit";
7869
+ const flowCapitalized = flowLabel === "withdraw" ? "Withdrawal" : flowLabel === "payment" ? "Payment" : "Deposit";
7347
7870
  const destinationTxHash = lastEvent?.data?.destination?.transactionHash || null;
7348
7871
  const sourceTxHash = getSettledSourceTxHash(lastEvent, txHash);
7349
7872
  const sourceDetails = getEventSourceDetails(lastEvent);
@@ -7353,46 +7876,53 @@ function ProcessingStep({
7353
7876
  const targetChainId = targetChainToChainId(targetChain);
7354
7877
  const settledSourceTxHash = lastEvent?.data?.source?.transactionHash;
7355
7878
  const sourceExplorerHash = settledSourceTxHash ?? (sourceTxHashPending ? null : sourceTxHash);
7356
- useEffect14(() => {
7879
+ useEffect13(() => {
7357
7880
  if (sourceTxHashPending && settledSourceTxHash) {
7358
7881
  onSourceTransactionObserved?.(settledSourceTxHash);
7359
7882
  }
7360
7883
  }, [onSourceTransactionObserved, settledSourceTxHash, sourceTxHashPending]);
7361
7884
  const sourceExplorerUrl = sourceExplorerHash ? explorerTxUrl(displaySourceChain, sourceExplorerHash) : null;
7362
7885
  const destExplorerUrl = destinationTxHash ? explorerTxUrl(targetChainId, destinationTxHash) : null;
7363
- const sourceDisplay = (() => {
7364
- const resolved = resolveTokenDisplay(displaySourceToken, displaySourceChain, {
7365
- symbol: providedSourceSymbol ?? (displaySourceChain === "solana" ? "SOL" : "Token"),
7366
- decimals: providedSourceDecimals
7367
- });
7368
- return {
7369
- symbol: resolved.symbol,
7370
- decimals: resolved.decimals ?? (displaySourceChain === "solana" ? 9 : 18)
7371
- };
7372
- })();
7373
- const sourceSymbol = sourceDisplay.symbol;
7374
- const formattedSentAmount = formatRawTokenAmount(displayAmount, sourceDisplay) ?? // Not raw base units (e.g. a decimal string) — render the number as-is.
7375
- formatTokenAmount(Number(displayAmount), sourceDisplay.symbol) ?? displayAmount;
7376
7886
  const eventDestination = getEventDestinationDetails(lastEvent);
7377
- const targetDisplay = resolveTokenDisplay(
7378
- eventDestination.token ?? targetToken,
7379
- eventDestination.chainId ?? targetChainId,
7380
- // Dapp deposits default to USDC targets; mirror the source symbol last so
7381
- // unresolvable same-token routes still label sensibly.
7382
- { symbol: providedSourceSymbol ?? "USDC" }
7383
- );
7887
+ const displayTargetChain = eventDestination.chainId ?? targetChainId;
7888
+ const displayTargetToken = eventDestination.token ?? targetToken;
7889
+ const [sourceDisplay, targetDisplay] = useTokenDisplays([
7890
+ {
7891
+ chain: displaySourceChain,
7892
+ address: displaySourceToken,
7893
+ fallback: {
7894
+ symbol: providedSourceSymbol ?? (displaySourceChain === "solana" ? "SOL" : "Token"),
7895
+ decimals: providedSourceDecimals
7896
+ }
7897
+ },
7898
+ {
7899
+ chain: displayTargetChain,
7900
+ address: displayTargetToken,
7901
+ // Dapp deposits default to USDC targets; mirror the source symbol last
7902
+ // so unresolvable same-token routes still label sensibly.
7903
+ fallback: { symbol: providedSourceSymbol ?? "USDC" }
7904
+ }
7905
+ ]);
7906
+ const sourceSymbol = sourceDisplay.symbol;
7384
7907
  const targetSymbol = targetDisplay.symbol;
7908
+ const formattedSentAmount = formatRawTokenAmount(displayAmount, sourceDisplay) ?? // Unknown decimals: no figure rather than a guess off by 10^12.
7909
+ (sourceDisplay.decimals === void 0 ? "\u2014" : (
7910
+ // Not raw base units (e.g. a decimal string) — render the number as-is.
7911
+ formatTokenAmount(Number(displayAmount), sourceDisplay.symbol) ?? displayAmount
7912
+ ));
7913
+ const sourceTokenRef = displaySourceToken ? { chain: displaySourceChain, address: displaySourceToken } : void 0;
7914
+ const targetTokenRef = displayTargetToken ? { chain: displayTargetChain, address: displayTargetToken } : void 0;
7385
7915
  const formattedDestinationAmount = eventDestination.amount !== void 0 ? formatRawTokenAmount(eventDestination.amount, targetDisplay) : void 0;
7386
7916
  const amountUsdNumber = amountUsd !== void 0 && Number(amountUsd) > 0 ? Number(amountUsd) : void 0;
7387
- const prices = useTokenPrices(service, [
7917
+ const prices = useTokenPrices([
7388
7918
  {
7389
7919
  chainId: displaySourceChain,
7390
7920
  address: displaySourceToken,
7391
7921
  symbol: sourceDisplay.symbol
7392
7922
  },
7393
7923
  {
7394
- chainId: eventDestination.chainId ?? targetChainId,
7395
- address: eventDestination.token ?? targetToken,
7924
+ chainId: displayTargetChain,
7925
+ address: displayTargetToken,
7396
7926
  symbol: targetDisplay.symbol
7397
7927
  }
7398
7928
  ]);
@@ -7402,7 +7932,7 @@ function ProcessingStep({
7402
7932
  sourceSymbol: sourceDisplay.symbol,
7403
7933
  targetSymbol: targetDisplay.symbol,
7404
7934
  sourceAmountUsd: amountUsdNumber,
7405
- sourceTrusted: isRecognizedToken(displaySourceToken, displaySourceChain),
7935
+ sourceTrusted: sourceDisplay.curated,
7406
7936
  prices
7407
7937
  });
7408
7938
  return estimate !== void 0 ? formatTokenAmount(estimate, targetDisplay.symbol) : void 0;
@@ -7450,7 +7980,7 @@ function ProcessingStep({
7450
7980
  ) : timingStateRef.current;
7451
7981
  timingStateRef.current = timingState;
7452
7982
  const expectedDuration = latchedTiming && timingState === "expected" ? formatExpectedDuration(latchedTiming.expectedSeconds) : void 0;
7453
- useEffect14(() => {
7983
+ useEffect13(() => {
7454
7984
  if (directTransfer || !isProcessing || timingState !== "escalated") return;
7455
7985
  if (escalatedDelayRef.current) return;
7456
7986
  escalatedDelayRef.current = true;
@@ -7481,10 +8011,10 @@ function ProcessingStep({
7481
8011
  const feeTooltip = uiConfig?.feeTooltip ?? (feeSponsored ? "Network fees are sponsored for this deposit." : "Network fees apply.");
7482
8012
  const stateTitle = isComplete ? `${flowCapitalized} successful` : isFailed ? `${flowCapitalized} failed` : "Processing...";
7483
8013
  const handleRetry = onRetry ?? onNewDeposit;
7484
- const headerContent = isComplete ? /* @__PURE__ */ jsxs20("div", { className: "rs-body-header", children: [
8014
+ const headerContent = isComplete ? /* @__PURE__ */ jsxs19("div", { className: "rs-body-header", children: [
7485
8015
  /* @__PURE__ */ jsx27(SuccessBadge, {}),
7486
8016
  /* @__PURE__ */ jsx27("div", { className: "rs-body-header-text", children: /* @__PURE__ */ jsx27("h2", { className: "rs-body-header-title", children: stateTitle }) })
7487
- ] }) : isFailed ? /* @__PURE__ */ jsxs20("div", { className: "rs-body-header", children: [
8017
+ ] }) : isFailed ? /* @__PURE__ */ jsxs19("div", { className: "rs-body-header", children: [
7488
8018
  /* @__PURE__ */ jsx27(FailedBadge, {}),
7489
8019
  /* @__PURE__ */ jsx27("div", { className: "rs-body-header-text", children: /* @__PURE__ */ jsx27("h2", { className: "rs-body-header-title", children: stateTitle }) })
7490
8020
  ] }) : /* @__PURE__ */ jsx27(BodyHeader, { icon: /* @__PURE__ */ jsx27(WalletIcon, {}), title: stateTitle });
@@ -7535,6 +8065,7 @@ function ProcessingStep({
7535
8065
  amountPaid,
7536
8066
  depositedAmount,
7537
8067
  depositedSymbol: targetSymbol,
8068
+ depositedToken: targetTokenRef,
7538
8069
  feesTotal,
7539
8070
  feeRows,
7540
8071
  feesTooltip,
@@ -7544,13 +8075,13 @@ function ProcessingStep({
7544
8075
  }
7545
8076
  );
7546
8077
  }
7547
- return /* @__PURE__ */ jsxs20("div", { className: "rs-screen", children: [
7548
- /* @__PURE__ */ jsxs20("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
8078
+ return /* @__PURE__ */ jsxs19("div", { className: "rs-screen", children: [
8079
+ /* @__PURE__ */ jsxs19("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
7549
8080
  headerContent,
7550
- /* @__PURE__ */ jsxs20("div", { className: "rs-review-details", children: [
7551
- /* @__PURE__ */ jsxs20("div", { className: "rs-review-detail-row", children: [
8081
+ /* @__PURE__ */ jsxs19("div", { className: "rs-review-details", children: [
8082
+ /* @__PURE__ */ jsxs19("div", { className: "rs-review-detail-row", children: [
7552
8083
  /* @__PURE__ */ jsx27("span", { children: "Source chain" }),
7553
- /* @__PURE__ */ jsxs20("span", { className: "rs-review-detail-value", children: [
8084
+ /* @__PURE__ */ jsxs19("span", { className: "rs-review-detail-value", children: [
7554
8085
  /* @__PURE__ */ jsx27("span", { children: sourceChainName }),
7555
8086
  sourceChainIcon && /* @__PURE__ */ jsx27("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx27(CdnIcon, { src: sourceChainIcon }) }),
7556
8087
  sourceExplorerUrl && /* @__PURE__ */ jsx27(
@@ -7566,9 +8097,9 @@ function ProcessingStep({
7566
8097
  )
7567
8098
  ] })
7568
8099
  ] }),
7569
- /* @__PURE__ */ jsxs20("div", { className: "rs-review-detail-row", children: [
8100
+ /* @__PURE__ */ jsxs19("div", { className: "rs-review-detail-row", children: [
7570
8101
  /* @__PURE__ */ jsx27("span", { children: "Destination chain" }),
7571
- /* @__PURE__ */ jsxs20("span", { className: "rs-review-detail-value", children: [
8102
+ /* @__PURE__ */ jsxs19("span", { className: "rs-review-detail-value", children: [
7572
8103
  /* @__PURE__ */ jsx27("span", { children: targetChainName }),
7573
8104
  targetChainIcon && /* @__PURE__ */ jsx27("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx27(CdnIcon, { src: targetChainIcon }) }),
7574
8105
  destExplorerUrl && /* @__PURE__ */ jsx27(
@@ -7584,70 +8115,70 @@ function ProcessingStep({
7584
8115
  )
7585
8116
  ] })
7586
8117
  ] }),
7587
- /* @__PURE__ */ jsxs20("div", { className: "rs-review-detail-row", children: [
8118
+ /* @__PURE__ */ jsxs19("div", { className: "rs-review-detail-row", children: [
7588
8119
  /* @__PURE__ */ jsx27("span", { children: isProcessing ? "Time elapsed" : "Total time" }),
7589
8120
  /* @__PURE__ */ jsx27("span", { className: "rs-review-detail-value", children: /* @__PURE__ */ jsx27(Ticker, { value: timerText }) })
7590
8121
  ] }),
7591
- isSwappedOrder ? /* @__PURE__ */ jsxs20(Fragment5, { children: [
7592
- swappedFiatContext?.paidAmountUsd != null && /* @__PURE__ */ jsxs20("div", { className: "rs-review-detail-row", children: [
8122
+ isSwappedOrder ? /* @__PURE__ */ jsxs19(Fragment5, { children: [
8123
+ swappedFiatContext?.paidAmountUsd != null && /* @__PURE__ */ jsxs19("div", { className: "rs-review-detail-row", children: [
7593
8124
  /* @__PURE__ */ jsx27("span", { children: "You pay" }),
7594
- /* @__PURE__ */ jsxs20("span", { className: "rs-review-detail-value", children: [
8125
+ /* @__PURE__ */ jsxs19("span", { className: "rs-review-detail-value", children: [
7595
8126
  "$",
7596
8127
  swappedFiatContext.paidAmountUsd.toFixed(2),
7597
- swappedFiatContext.paymentMethod && /* @__PURE__ */ jsxs20("span", { style: { color: "#71717b", marginLeft: 6 }, children: [
8128
+ swappedFiatContext.paymentMethod && /* @__PURE__ */ jsxs19("span", { style: { color: "#71717b", marginLeft: 6 }, children: [
7598
8129
  "via",
7599
8130
  " ",
7600
8131
  formatPaymentMethod(swappedFiatContext.paymentMethod)
7601
8132
  ] })
7602
8133
  ] })
7603
8134
  ] }),
7604
- swappedFiatContext?.onrampFeeUsd != null && /* @__PURE__ */ jsxs20("div", { className: "rs-review-detail-row", children: [
8135
+ swappedFiatContext?.onrampFeeUsd != null && /* @__PURE__ */ jsxs19("div", { className: "rs-review-detail-row", children: [
7605
8136
  /* @__PURE__ */ jsx27("span", { children: "On-ramp fee" }),
7606
- /* @__PURE__ */ jsxs20("span", { className: "rs-review-detail-value", children: [
8137
+ /* @__PURE__ */ jsxs19("span", { className: "rs-review-detail-value", children: [
7607
8138
  "$",
7608
8139
  swappedFiatContext.onrampFeeUsd.toFixed(2)
7609
8140
  ] })
7610
8141
  ] }),
7611
- formattedBridgingCost && /* @__PURE__ */ jsxs20("div", { className: "rs-review-detail-row", children: [
8142
+ formattedBridgingCost && /* @__PURE__ */ jsxs19("div", { className: "rs-review-detail-row", children: [
7612
8143
  /* @__PURE__ */ jsx27("span", { children: "Bridging cost" }),
7613
- /* @__PURE__ */ jsxs20("span", { className: "rs-review-detail-value", children: [
7614
- /* @__PURE__ */ jsxs20("span", { children: [
8144
+ /* @__PURE__ */ jsxs19("span", { className: "rs-review-detail-value", children: [
8145
+ /* @__PURE__ */ jsxs19("span", { children: [
7615
8146
  formattedBridgingCost,
7616
8147
  " ",
7617
8148
  sourceSymbol
7618
8149
  ] }),
7619
- /* @__PURE__ */ jsx27("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx27(TokenIcon, { symbol: sourceSymbol }) })
8150
+ /* @__PURE__ */ jsx27("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx27(TokenIcon, { token: sourceTokenRef, symbol: sourceSymbol }) })
7620
8151
  ] })
7621
8152
  ] })
7622
- ] }) : /* @__PURE__ */ jsxs20("div", { className: "rs-review-detail-row", children: [
8153
+ ] }) : /* @__PURE__ */ jsxs19("div", { className: "rs-review-detail-row", children: [
7623
8154
  /* @__PURE__ */ jsx27("span", { children: isProcessing ? "You send" : "You sent" }),
7624
- /* @__PURE__ */ jsxs20("span", { className: "rs-review-detail-value", children: [
7625
- /* @__PURE__ */ jsxs20("span", { children: [
8155
+ /* @__PURE__ */ jsxs19("span", { className: "rs-review-detail-value", children: [
8156
+ /* @__PURE__ */ jsxs19("span", { children: [
7626
8157
  formattedSentAmount,
7627
8158
  " ",
7628
8159
  sourceSymbol
7629
8160
  ] }),
7630
- /* @__PURE__ */ jsx27("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx27(TokenIcon, { symbol: sourceSymbol }) })
8161
+ /* @__PURE__ */ jsx27("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx27(TokenIcon, { token: sourceTokenRef, symbol: sourceSymbol }) })
7631
8162
  ] })
7632
8163
  ] }),
7633
- /* @__PURE__ */ jsxs20("div", { className: "rs-review-detail-row", children: [
8164
+ /* @__PURE__ */ jsxs19("div", { className: "rs-review-detail-row", children: [
7634
8165
  /* @__PURE__ */ jsx27("span", { children: isProcessing ? "Receive" : "Received" }),
7635
- /* @__PURE__ */ jsxs20("span", { className: "rs-review-detail-value", children: [
8166
+ /* @__PURE__ */ jsxs19("span", { className: "rs-review-detail-value", children: [
7636
8167
  /* @__PURE__ */ jsx27("span", { children: receiveDisplay }),
7637
- /* @__PURE__ */ jsx27("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx27(TokenIcon, { symbol: targetSymbol }) })
8168
+ /* @__PURE__ */ jsx27("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx27(TokenIcon, { token: targetTokenRef, symbol: targetSymbol }) })
7638
8169
  ] })
7639
8170
  ] }),
7640
- isFailed && balanceAfterUsd !== void 0 && /* @__PURE__ */ jsxs20("div", { className: "rs-review-detail-row", children: [
8171
+ isFailed && balanceAfterUsd !== void 0 && /* @__PURE__ */ jsxs19("div", { className: "rs-review-detail-row", children: [
7641
8172
  /* @__PURE__ */ jsx27("span", { children: "Balance" }),
7642
- /* @__PURE__ */ jsxs20("span", { className: "rs-review-detail-value", children: [
8173
+ /* @__PURE__ */ jsxs19("span", { className: "rs-review-detail-value", children: [
7643
8174
  "$",
7644
8175
  balanceAfterUsd.toFixed(2)
7645
8176
  ] })
7646
8177
  ] }),
7647
- isSwappedOrder ? quotedFeeAmount !== void 0 && /* @__PURE__ */ jsxs20("div", { className: "rs-review-detail-row", children: [
8178
+ isSwappedOrder ? quotedFeeAmount !== void 0 && /* @__PURE__ */ jsxs19("div", { className: "rs-review-detail-row", children: [
7648
8179
  /* @__PURE__ */ jsx27("span", { children: "Fees" }),
7649
- /* @__PURE__ */ jsxs20("span", { className: "rs-review-detail-value", children: [
7650
- /* @__PURE__ */ jsxs20(
8180
+ /* @__PURE__ */ jsxs19("span", { className: "rs-review-detail-value", children: [
8181
+ /* @__PURE__ */ jsxs19(
7651
8182
  "span",
7652
8183
  {
7653
8184
  style: feeSponsored ? { textDecoration: "line-through" } : void 0,
@@ -7670,7 +8201,7 @@ function ProcessingStep({
7670
8201
  ] }) : (() => {
7671
8202
  const { display, struck } = quoteFeeRow(quote?.fees);
7672
8203
  if (display !== null) {
7673
- return /* @__PURE__ */ jsxs20("div", { className: "rs-review-detail-row", children: [
8204
+ return /* @__PURE__ */ jsxs19("div", { className: "rs-review-detail-row", children: [
7674
8205
  /* @__PURE__ */ jsx27("span", { children: "Fees" }),
7675
8206
  /* @__PURE__ */ jsx27("span", { className: "rs-review-detail-value", children: /* @__PURE__ */ jsx27(
7676
8207
  "span",
@@ -7683,9 +8214,9 @@ function ProcessingStep({
7683
8214
  }
7684
8215
  const feeValue = quotedFeeAmount ?? formattedBridgingCost;
7685
8216
  if (feeValue === void 0) return null;
7686
- return /* @__PURE__ */ jsxs20("div", { className: "rs-review-detail-row", children: [
8217
+ return /* @__PURE__ */ jsxs19("div", { className: "rs-review-detail-row", children: [
7687
8218
  /* @__PURE__ */ jsx27("span", { children: "Fees" }),
7688
- /* @__PURE__ */ jsx27("span", { className: "rs-review-detail-value", children: /* @__PURE__ */ jsxs20(
8219
+ /* @__PURE__ */ jsx27("span", { className: "rs-review-detail-value", children: /* @__PURE__ */ jsxs19(
7689
8220
  "span",
7690
8221
  {
7691
8222
  style: feeSponsored ? { textDecoration: "line-through" } : void 0,
@@ -7700,7 +8231,7 @@ function ProcessingStep({
7700
8231
  })()
7701
8232
  ] }),
7702
8233
  isFailed && failureMessage && /* @__PURE__ */ jsx27(Callout, { variant: "error", children: failureMessage }),
7703
- isProcessing && expectedDuration !== void 0 && /* @__PURE__ */ jsxs20("p", { className: "rs-pending-expectation", children: [
8234
+ isProcessing && expectedDuration !== void 0 && /* @__PURE__ */ jsxs19("p", { className: "rs-pending-expectation", children: [
7704
8235
  "Usually arrives in ",
7705
8236
  expectedDuration
7706
8237
  ] }),
@@ -7715,14 +8246,14 @@ function ProcessingStep({
7715
8246
  children: "Submitting transaction\u2026"
7716
8247
  }
7717
8248
  ),
7718
- isComplete && /* @__PURE__ */ jsxs20("div", { className: "rs-screen-button-row", children: [
7719
- onNewDeposit && /* @__PURE__ */ jsxs20(Button, { variant: "outline", onClick: onNewDeposit, fullWidth: true, children: [
8249
+ isComplete && /* @__PURE__ */ jsxs19("div", { className: "rs-screen-button-row", children: [
8250
+ onNewDeposit && /* @__PURE__ */ jsxs19(Button, { variant: "outline", onClick: onNewDeposit, fullWidth: true, children: [
7720
8251
  "New ",
7721
8252
  flowNoun
7722
8253
  ] }),
7723
8254
  onClose && /* @__PURE__ */ jsx27(Button, { onClick: () => onClose("success_done"), fullWidth: true, children: "Done" })
7724
8255
  ] }),
7725
- isFailed && /* @__PURE__ */ jsxs20("div", { className: "rs-screen-button-row", children: [
8256
+ isFailed && /* @__PURE__ */ jsxs19("div", { className: "rs-screen-button-row", children: [
7726
8257
  onClose && /* @__PURE__ */ jsx27(
7727
8258
  Button,
7728
8259
  {
@@ -7797,7 +8328,8 @@ function computeRequestKey(input) {
7797
8328
  recipient: normalizeKeyToken(input.recipient),
7798
8329
  outputTokenRules: input.outputTokenRules ?? null,
7799
8330
  rejectUnmapped: input.rejectUnmapped ?? null,
7800
- forceRegister: input.forceRegister ?? false
8331
+ forceRegister: input.forceRegister ?? false,
8332
+ salt: input.salt ?? null
7801
8333
  });
7802
8334
  }
7803
8335
  function computeCacheKey(input) {
@@ -7806,7 +8338,8 @@ function computeCacheKey(input) {
7806
8338
  targetToken: normalizeKeyToken(input.targetToken),
7807
8339
  recipient: normalizeKeyToken(input.recipient),
7808
8340
  outputTokenRules: input.outputTokenRules ?? null,
7809
- rejectUnmapped: input.rejectUnmapped ?? null
8341
+ rejectUnmapped: input.rejectUnmapped ?? null,
8342
+ salt: input.salt ?? null
7810
8343
  });
7811
8344
  }
7812
8345
  function computeIsCacheable(input) {
@@ -7838,7 +8371,7 @@ async function runAccountSetup(input, deps) {
7838
8371
  );
7839
8372
  }
7840
8373
  try {
7841
- const salt = deriveAccountSalt(input);
8374
+ const salt = input.salt ?? deriveAccountSalt(input);
7842
8375
  debugLog(debug, "account-setup", "setup:start", {
7843
8376
  salt,
7844
8377
  recipient: input.recipient,
@@ -7932,36 +8465,21 @@ function mapError(error) {
7932
8465
 
7933
8466
  export {
7934
8467
  Modal,
7935
- WalletIcon,
7936
- ExternalLinkIcon,
7937
- CheckIcon,
7938
- TransferCryptoIcon,
7939
- ChevronLeftIcon,
7940
- ChevronDownIcon,
7941
- CloseIcon,
7942
- HandCoinsIcon,
7943
- InfoIcon,
7944
- CopyIcon,
7945
- CircleArrowOutUpLeftIcon,
7946
- CardIcon,
7947
- BankIcon,
7948
- UnplugIcon,
7949
- MigrateAssetsIcon,
7950
- AppleIcon,
7951
- BodyHeader,
8468
+ Callout,
7952
8469
  CdnIcon,
7953
8470
  ListRow,
7954
8471
  PoweredBy,
7955
- Spinner,
7956
8472
  catalogKeyForChain,
7957
8473
  debugLog,
7958
8474
  debugError,
8475
+ SOLANA_TOKENS,
8476
+ resolveSolanaToken,
8477
+ isNativeSol,
7959
8478
  getAssetId,
7960
8479
  chainIdsByValue,
7961
8480
  portfolioToAssets,
7962
8481
  isNativeAsset,
7963
8482
  quoteFeeRow,
7964
- SwappedConnectFeeChangedError,
7965
8483
  SUPPORTED_CONNECT_EXCHANGE_COUNT,
7966
8484
  resolveAppFeeBps,
7967
8485
  isDepositPolicyRefusal,
@@ -7991,10 +8509,15 @@ export {
7991
8509
  ChainCatalogProvider,
7992
8510
  getExchangeLogoSrc,
7993
8511
  getExchangeLogo,
7994
- useLatestRef,
7995
8512
  Button,
7996
- Callout,
8513
+ assetIdFor,
8514
+ AssetMetadataProvider,
8515
+ useAssetStore,
7997
8516
  TokenIcon,
8517
+ resolveCuratedToken,
8518
+ useTokenDisplays,
8519
+ useTokenDisplay,
8520
+ useIsRecognizedToken,
7998
8521
  currencyFormatter,
7999
8522
  tokenFormatter,
8000
8523
  isUnsupportedChainSwitchError,
@@ -8005,7 +8528,6 @@ export {
8005
8528
  isSubmissionUncertain,
8006
8529
  formatTokenAmount,
8007
8530
  isDisplayStablecoinSymbol,
8008
- isRecognizedToken,
8009
8531
  formatQuotedReceive,
8010
8532
  formatReceiveEstimate,
8011
8533
  getEventTxHash,
@@ -8014,7 +8536,6 @@ export {
8014
8536
  isFailedEvent,
8015
8537
  txRefsMatch,
8016
8538
  failureMessageForEvent,
8017
- fetchTokenPriceUsd,
8018
8539
  useTokenPrices,
8019
8540
  ProcessingStep,
8020
8541
  AnalyticsSession,