@unifold/ui-react 0.1.58 → 0.1.60

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.
package/dist/index.mjs CHANGED
@@ -1491,7 +1491,7 @@ import {
1491
1491
  } from "@unifold/core";
1492
1492
  var DEPOSIT_CONFIRM_DELAY_MS = 5e3;
1493
1493
  var POLL_INTERVAL_MS = 2500;
1494
- var POLL_ENDPOINT_INTERVAL_MS = 3e3;
1494
+ var POLL_ENDPOINT_INTERVAL_MS = 5e3;
1495
1495
  var CUTOFF_BUFFER_MS = 6e4;
1496
1496
  function useDepositPolling({
1497
1497
  userId,
@@ -5253,6 +5253,56 @@ import * as React24 from "react";
5253
5253
  import { Wallet, ChevronRight as ChevronRight10, Loader2 as Loader23 } from "lucide-react";
5254
5254
  import { getAddressBalances } from "@unifold/core";
5255
5255
 
5256
+ // src/lib/eip6963-store.ts
5257
+ import { createStore } from "mipd";
5258
+ var _store = null;
5259
+ function getEip6963Store() {
5260
+ if (typeof window === "undefined") return null;
5261
+ if (!_store) {
5262
+ _store = createStore();
5263
+ }
5264
+ return _store;
5265
+ }
5266
+ var RDNS_TO_WALLET_ID = {
5267
+ "io.metamask": "metamask",
5268
+ "io.metamask.flask": "metamask",
5269
+ "io.metamask.mmi": "metamask",
5270
+ "app.phantom": "phantom",
5271
+ "com.coinbase.wallet": "coinbase",
5272
+ "com.okex.wallet": "okx",
5273
+ "io.rabby": "rabby",
5274
+ "com.trustwallet.app": "trust",
5275
+ "me.rainbow": "rainbow"
5276
+ };
5277
+ function rdnsToWalletId(rdns) {
5278
+ if (RDNS_TO_WALLET_ID[rdns]) return RDNS_TO_WALLET_ID[rdns];
5279
+ if (rdns.includes("metamask")) return "metamask";
5280
+ if (rdns.includes("phantom")) return "phantom";
5281
+ if (rdns.includes("coinbase")) return "coinbase";
5282
+ if (rdns.includes("okx") || rdns.includes("okex")) return "okx";
5283
+ if (rdns.includes("rabby")) return "rabby";
5284
+ if (rdns.includes("trust")) return "trust";
5285
+ if (rdns.includes("rainbow")) return "rainbow";
5286
+ return "unknown";
5287
+ }
5288
+ function getEip6963Providers() {
5289
+ const store = getEip6963Store();
5290
+ if (!store) return [];
5291
+ return store.getProviders().map((detail) => ({
5292
+ walletId: rdnsToWalletId(detail.info.rdns),
5293
+ provider: detail.provider,
5294
+ info: detail.info
5295
+ }));
5296
+ }
5297
+ function findProviderByWalletId(walletId) {
5298
+ return getEip6963Providers().find((p) => p.walletId === walletId);
5299
+ }
5300
+ function collectAllEip6963EthProviders() {
5301
+ const store = getEip6963Store();
5302
+ if (!store) return [];
5303
+ return store.getProviders().map((d) => d.provider);
5304
+ }
5305
+
5256
5306
  // src/components/deposits/browser-wallets/disconnectInjectedBrowserWallet.ts
5257
5307
  var SOLANA_DISCONNECT_TYPES = [
5258
5308
  "phantom-solana",
@@ -5293,8 +5343,9 @@ function collectEthereumProvidersForDisconnect(win) {
5293
5343
  out.push(p);
5294
5344
  }
5295
5345
  };
5296
- const list = anyWin.__eip6963Providers || [];
5297
- for (const d of list) add(d.provider);
5346
+ for (const p of collectAllEip6963EthProviders()) {
5347
+ add(p);
5348
+ }
5298
5349
  add(win.ethereum);
5299
5350
  add(
5300
5351
  win.phantom?.ethereum
@@ -7354,30 +7405,13 @@ function BrowserWalletButton({
7354
7405
  }, []);
7355
7406
  const [eip6963ProviderCount, setEip6963ProviderCount] = React24.useState(0);
7356
7407
  React24.useEffect(() => {
7357
- if (typeof window === "undefined") return;
7358
- const anyWin = window;
7359
- if (!anyWin.__eip6963Providers) {
7360
- anyWin.__eip6963Providers = [];
7361
- }
7362
- const handleAnnouncement = (event) => {
7363
- const { detail } = event;
7364
- if (!detail?.info || !detail?.provider) return;
7365
- const exists = anyWin.__eip6963Providers.some(
7366
- (p) => p.info.uuid === detail.info.uuid
7367
- );
7368
- if (!exists) {
7369
- anyWin.__eip6963Providers.push(detail);
7370
- setEip6963ProviderCount(anyWin.__eip6963Providers.length);
7371
- }
7372
- };
7373
- window.addEventListener("eip6963:announceProvider", handleAnnouncement);
7374
- window.dispatchEvent(new Event("eip6963:requestProvider"));
7375
- return () => {
7376
- window.removeEventListener(
7377
- "eip6963:announceProvider",
7378
- handleAnnouncement
7379
- );
7380
- };
7408
+ const store = getEip6963Store();
7409
+ if (!store) return;
7410
+ setEip6963ProviderCount(store.getProviders().length);
7411
+ const unsubscribe = store.subscribe((providers) => {
7412
+ setEip6963ProviderCount(providers.length);
7413
+ });
7414
+ return unsubscribe;
7381
7415
  }, []);
7382
7416
  React24.useEffect(() => {
7383
7417
  if (!wallet || !publishableKey) {
@@ -7436,7 +7470,7 @@ function BrowserWalletButton({
7436
7470
  return;
7437
7471
  }
7438
7472
  if (!chainType || chainType === "solana") {
7439
- const anyWin2 = win;
7473
+ const anyWin = win;
7440
7474
  const trySilentSolana = async (provider, type, name, icon) => {
7441
7475
  if (!provider) return false;
7442
7476
  if (provider.isConnected && provider.publicKey) {
@@ -7475,21 +7509,21 @@ function BrowserWalletButton({
7475
7509
  ))
7476
7510
  return;
7477
7511
  if (await trySilentSolana(
7478
- anyWin2.solflare,
7512
+ anyWin.solflare,
7479
7513
  "solflare",
7480
7514
  "Solflare",
7481
7515
  "solflare"
7482
7516
  ))
7483
7517
  return;
7484
7518
  if (await trySilentSolana(
7485
- anyWin2.backpack,
7519
+ anyWin.backpack,
7486
7520
  "backpack",
7487
7521
  "Backpack",
7488
7522
  "backpack"
7489
7523
  ))
7490
7524
  return;
7491
7525
  if (await trySilentSolana(
7492
- anyWin2.glow,
7526
+ anyWin.glow,
7493
7527
  "glow",
7494
7528
  "Glow",
7495
7529
  "glow"
@@ -7497,19 +7531,14 @@ function BrowserWalletButton({
7497
7531
  return;
7498
7532
  }
7499
7533
  if (!chainType || chainType === "ethereum") {
7500
- const anyWin2 = win;
7534
+ const anyWin = win;
7501
7535
  const allProviders = [];
7502
- const eip6963Providers = anyWin2.__eip6963Providers || [];
7503
- for (const { info, provider } of eip6963Providers) {
7504
- let walletId = "default";
7505
- if (info.rdns.includes("metamask")) walletId = "metamask";
7506
- else if (info.rdns.includes("phantom")) walletId = "phantom";
7507
- else if (info.rdns.includes("coinbase")) walletId = "coinbase";
7508
- else if (info.rdns.includes("okx")) walletId = "okx";
7509
- else if (info.rdns.includes("rabby")) walletId = "rabby";
7510
- else if (info.rdns.includes("trust")) walletId = "trust";
7511
- else if (info.rdns.includes("rainbow")) walletId = "rainbow";
7512
- allProviders.push({ provider, walletId });
7536
+ const eip6963 = getEip6963Providers();
7537
+ for (const { provider, walletId } of eip6963) {
7538
+ allProviders.push({
7539
+ provider,
7540
+ walletId: walletId === "unknown" ? "default" : walletId
7541
+ });
7513
7542
  }
7514
7543
  if (allProviders.length === 0) {
7515
7544
  if (win.phantom?.ethereum) {
@@ -7518,15 +7547,15 @@ function BrowserWalletButton({
7518
7547
  walletId: "phantom"
7519
7548
  });
7520
7549
  }
7521
- if (anyWin2.okxwallet) {
7550
+ if (anyWin.okxwallet) {
7522
7551
  allProviders.push({
7523
- provider: anyWin2.okxwallet,
7552
+ provider: anyWin.okxwallet,
7524
7553
  walletId: "okx"
7525
7554
  });
7526
7555
  }
7527
- if (anyWin2.coinbaseWalletExtension) {
7556
+ if (anyWin.coinbaseWalletExtension) {
7528
7557
  allProviders.push({
7529
- provider: anyWin2.coinbaseWalletExtension,
7558
+ provider: anyWin.coinbaseWalletExtension,
7530
7559
  walletId: "coinbase"
7531
7560
  });
7532
7561
  }
@@ -7550,7 +7579,7 @@ function BrowserWalletButton({
7550
7579
  });
7551
7580
  if (!accounts || accounts.length === 0) continue;
7552
7581
  const address = accounts[0];
7553
- const resolved = identifyEthWallet(provider, anyWin2, walletId);
7582
+ const resolved = identifyEthWallet(provider, anyWin, walletId);
7554
7583
  if (mounted) {
7555
7584
  setWallet({ ...resolved, address });
7556
7585
  setIsLoading(false);
@@ -7592,15 +7621,11 @@ function BrowserWalletButton({
7592
7621
  solanaProvider.on("disconnect", handleDisconnect);
7593
7622
  solanaProvider.on("accountChanged", handleAccountsChanged);
7594
7623
  }
7595
- const anyWin = window;
7596
7624
  const ethProviders = [];
7597
- if (anyWin.__eip6963Providers) {
7598
- for (const {
7599
- provider
7600
- } of anyWin.__eip6963Providers) {
7601
- if (provider && !ethProviders.includes(provider)) {
7602
- ethProviders.push(provider);
7603
- }
7625
+ for (const { provider } of getEip6963Providers()) {
7626
+ const p = provider;
7627
+ if (p && !ethProviders.includes(p)) {
7628
+ ethProviders.push(p);
7604
7629
  }
7605
7630
  }
7606
7631
  if (window.ethereum && !ethProviders.includes(window.ethereum)) {
@@ -7702,7 +7727,7 @@ function BrowserWalletButton({
7702
7727
  if (isLoading) {
7703
7728
  return null;
7704
7729
  }
7705
- const hasWalletExtension = (!chainType || chainType === "solana") && (window.phantom?.solana?.isPhantom || window.solana?.isPhantom) ? true : (!chainType || chainType === "ethereum") && (window.phantom?.ethereum || window.ethereum) ? true : false;
7730
+ const hasWalletExtension = (!chainType || chainType === "ethereum") && getEip6963Providers().length > 0 || (!chainType || chainType === "solana") && (window.phantom?.solana?.isPhantom || window.solana?.isPhantom) || (!chainType || chainType === "ethereum") && (window.phantom?.ethereum || window.ethereum);
7706
7731
  if (!onConnectClick && !wallet && !hasWalletExtension) {
7707
7732
  return null;
7708
7733
  }
@@ -10284,6 +10309,7 @@ function DepositsModal({
10284
10309
  // src/components/deposits/TokenSelectorSheet.tsx
10285
10310
  import { useState as useState23, useMemo as useMemo6, useEffect as useEffect19 } from "react";
10286
10311
  import { ArrowLeft as ArrowLeft2, X as X4 } from "lucide-react";
10312
+ import Fuse from "fuse.js";
10287
10313
  import { jsx as jsx41, jsxs as jsxs37 } from "react/jsx-runtime";
10288
10314
  var STORAGE_KEY = "unifold_recent_tokens";
10289
10315
  var MAX_RECENT_TOKENS = 5;
@@ -10389,13 +10415,25 @@ function TokenSelectorSheet({
10389
10415
  });
10390
10416
  setRecentTokens(updated);
10391
10417
  };
10418
+ const fuse = useMemo6(
10419
+ () => new Fuse(allOptions, {
10420
+ keys: [
10421
+ { name: "token.symbol", weight: 2 },
10422
+ { name: "token.name", weight: 1 },
10423
+ { name: "chain.chain_name", weight: 0.5 }
10424
+ ],
10425
+ threshold: 0.2,
10426
+ ignoreLocation: true,
10427
+ minMatchCharLength: 2
10428
+ }),
10429
+ [allOptions]
10430
+ );
10392
10431
  const filteredOptions = useMemo6(() => {
10393
10432
  if (!searchQuery.trim()) return allOptions;
10394
- const query = searchQuery.toLowerCase();
10395
- return allOptions.filter(
10396
- ({ token, chain }) => token.symbol.toLowerCase().includes(query) || token.name.toLowerCase().includes(query) || chain.chain_name.toLowerCase().includes(query)
10397
- );
10398
- }, [allOptions, searchQuery]);
10433
+ const query = searchQuery.trim();
10434
+ const results = fuse.search(query);
10435
+ return results.map((r) => r.item);
10436
+ }, [fuse, allOptions, searchQuery]);
10399
10437
  const isCommonToken = (symbol, chainType, chainId) => {
10400
10438
  return COMMON_TOKENS.some(
10401
10439
  (ct) => ct.symbol === symbol && ct.chainType === chainType && ct.chainId === chainId
@@ -13445,15 +13483,10 @@ var WALLET_DEFINITIONS = [
13445
13483
  { id: "backpack", name: "Backpack", networks: ["solana"], installUrl: "https://backpack.app/" },
13446
13484
  { id: "glow", name: "Glow", networks: ["solana"], installUrl: "https://glow.app/" }
13447
13485
  ];
13448
- function getWalletProviders() {
13486
+ function getSolanaProviders() {
13449
13487
  if (typeof window === "undefined") return {};
13450
13488
  const win = window;
13451
13489
  return {
13452
- ethereum: win.ethereum,
13453
- phantomEthereum: win.phantom?.ethereum,
13454
- coinbaseEthereum: win.coinbaseWalletExtension,
13455
- trustEthereum: win.trustwallet?.ethereum,
13456
- okxEthereum: win.okxwallet,
13457
13490
  phantomSolana: win.phantom?.solana,
13458
13491
  solflare: win.solflare,
13459
13492
  backpack: win.backpack,
@@ -13461,37 +13494,71 @@ function getWalletProviders() {
13461
13494
  coinbaseSolana: win.coinbaseSolana || win.coinbaseWalletExtension?.solana
13462
13495
  };
13463
13496
  }
13497
+ function getLegacyEvmProviders() {
13498
+ if (typeof window === "undefined") return {};
13499
+ const win = window;
13500
+ return {
13501
+ ethereum: win.ethereum,
13502
+ phantomEthereum: win.phantom?.ethereum,
13503
+ coinbaseEthereum: win.coinbaseWalletExtension,
13504
+ trustEthereum: win.trustwallet?.ethereum,
13505
+ okxEthereum: win.okxwallet
13506
+ };
13507
+ }
13464
13508
  function detectAvailableWallets(filterChainType) {
13465
- const providers = getWalletProviders();
13509
+ const solProviders = getSolanaProviders();
13510
+ const legacyEvm = getLegacyEvmProviders();
13511
+ const eip6963List = getEip6963Providers();
13466
13512
  const win = typeof window !== "undefined" ? window : null;
13513
+ const hasEip6963 = (walletId) => eip6963List.some((d) => {
13514
+ const rdns = d.info?.rdns || "";
13515
+ switch (walletId) {
13516
+ case "metamask":
13517
+ return rdns.includes("metamask");
13518
+ case "phantom":
13519
+ return rdns.includes("phantom");
13520
+ case "coinbase":
13521
+ return rdns.includes("coinbase");
13522
+ case "trust":
13523
+ return rdns.includes("trust");
13524
+ case "rainbow":
13525
+ return rdns.includes("rainbow");
13526
+ case "rabby":
13527
+ return rdns.includes("rabby");
13528
+ case "okx":
13529
+ return rdns.includes("okx") || rdns.includes("okex");
13530
+ default:
13531
+ return false;
13532
+ }
13533
+ });
13467
13534
  return WALLET_DEFINITIONS.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
13468
13535
  let isInstalled = false;
13469
13536
  const detectedNetworks = [];
13470
13537
  switch (wallet.id) {
13471
13538
  case "metamask":
13472
- isInstalled = !!(providers.ethereum?.isMetaMask && !providers.ethereum?.isPhantom && !providers.ethereum?.isRabby && !providers.ethereum?.isOkxWallet);
13539
+ isInstalled = hasEip6963("metamask") || !!(legacyEvm.ethereum?.isMetaMask && !legacyEvm.ethereum?.isPhantom && !legacyEvm.ethereum?.isRabby && !legacyEvm.ethereum?.isOkxWallet);
13473
13540
  if (isInstalled) detectedNetworks.push("ethereum");
13474
13541
  break;
13475
13542
  case "phantom":
13476
- if (providers.phantomSolana?.isPhantom) {
13543
+ if (solProviders.phantomSolana?.isPhantom) {
13477
13544
  isInstalled = true;
13478
13545
  detectedNetworks.push("solana");
13479
13546
  }
13480
- if (providers.phantomEthereum?.isPhantom) {
13547
+ if (hasEip6963("phantom") || legacyEvm.phantomEthereum?.isPhantom) {
13481
13548
  isInstalled = true;
13482
13549
  detectedNetworks.push("ethereum");
13483
13550
  }
13484
13551
  break;
13485
13552
  case "coinbase":
13486
- if (providers.coinbaseEthereum || providers.ethereum?.isCoinbaseWallet) {
13553
+ if (hasEip6963("coinbase") || legacyEvm.coinbaseEthereum || legacyEvm.ethereum?.isCoinbaseWallet) {
13487
13554
  isInstalled = true;
13488
13555
  detectedNetworks.push("ethereum");
13489
13556
  }
13490
- if (providers.coinbaseSolana || win?.coinbaseWalletExtension?.solana) detectedNetworks.push("solana");
13557
+ if (solProviders.coinbaseSolana || win?.coinbaseWalletExtension?.solana) detectedNetworks.push("solana");
13491
13558
  if (isInstalled && wallet.networks.includes("solana") && !detectedNetworks.includes("solana")) detectedNetworks.push("solana");
13492
13559
  break;
13493
13560
  case "trust":
13494
- if (providers.trustEthereum || providers.ethereum?.isTrust || win?.trustwallet) {
13561
+ if (hasEip6963("trust") || legacyEvm.trustEthereum || legacyEvm.ethereum?.isTrust || win?.trustwallet) {
13495
13562
  isInstalled = true;
13496
13563
  detectedNetworks.push("ethereum");
13497
13564
  }
@@ -13499,27 +13566,27 @@ function detectAvailableWallets(filterChainType) {
13499
13566
  if (isInstalled && wallet.networks.includes("solana") && !detectedNetworks.includes("solana")) detectedNetworks.push("solana");
13500
13567
  break;
13501
13568
  case "rainbow":
13502
- isInstalled = !!providers.ethereum?.isRainbow;
13569
+ isInstalled = hasEip6963("rainbow") || !!legacyEvm.ethereum?.isRainbow;
13503
13570
  if (isInstalled) detectedNetworks.push("ethereum");
13504
13571
  break;
13505
13572
  case "rabby":
13506
- isInstalled = !!providers.ethereum?.isRabby;
13573
+ isInstalled = hasEip6963("rabby") || !!legacyEvm.ethereum?.isRabby;
13507
13574
  if (isInstalled) detectedNetworks.push("ethereum");
13508
13575
  break;
13509
13576
  case "okx":
13510
- isInstalled = !!(providers.okxEthereum || providers.ethereum?.isOkxWallet);
13577
+ isInstalled = hasEip6963("okx") || !!(legacyEvm.okxEthereum || legacyEvm.ethereum?.isOkxWallet);
13511
13578
  if (isInstalled) detectedNetworks.push("ethereum");
13512
13579
  break;
13513
13580
  case "solflare":
13514
- isInstalled = !!providers.solflare?.isSolflare;
13581
+ isInstalled = !!solProviders.solflare?.isSolflare;
13515
13582
  if (isInstalled) detectedNetworks.push("solana");
13516
13583
  break;
13517
13584
  case "backpack":
13518
- isInstalled = !!(providers.backpack?.isBackpack || win?.backpack);
13585
+ isInstalled = !!(solProviders.backpack?.isBackpack || win?.backpack);
13519
13586
  if (isInstalled) detectedNetworks.push("solana");
13520
13587
  break;
13521
13588
  case "glow":
13522
- isInstalled = !!(providers.glow?.isGlow || win?.glow);
13589
+ isInstalled = !!(solProviders.glow?.isGlow || win?.glow);
13523
13590
  if (isInstalled) detectedNetworks.push("solana");
13524
13591
  break;
13525
13592
  }
@@ -13574,7 +13641,16 @@ function WalletConnect({
13574
13641
  const [connectingNetwork, setConnectingNetwork] = React29.useState(null);
13575
13642
  const [walletError, setWalletError] = React29.useState(null);
13576
13643
  const [isWalletConnecting, setIsWalletConnecting] = React29.useState(false);
13577
- const availableWallets = React29.useMemo(() => detectAvailableWallets(), []);
13644
+ const [eip6963ProviderCount, setEip6963ProviderCount] = React29.useState(0);
13645
+ React29.useEffect(() => {
13646
+ const store = getEip6963Store();
13647
+ if (!store) return;
13648
+ setEip6963ProviderCount(store.getProviders().length);
13649
+ return store.subscribe((providers) => {
13650
+ setEip6963ProviderCount(providers.length);
13651
+ });
13652
+ }, []);
13653
+ const availableWallets = React29.useMemo(() => detectAvailableWallets(), [eip6963ProviderCount]);
13578
13654
  const [balances, setBalances] = React29.useState([]);
13579
13655
  const [isLoading, setIsLoading] = React29.useState(false);
13580
13656
  const [selectedBalance, setSelectedBalance] = React29.useState(null);
@@ -13633,59 +13709,72 @@ function WalletConnect({
13633
13709
  setWalletError(null);
13634
13710
  setIsWalletConnecting(true);
13635
13711
  try {
13636
- const providers = getWalletProviders();
13637
13712
  const win = typeof window !== "undefined" ? window : null;
13638
13713
  let connectedInfo;
13639
13714
  if (network === "ethereum") {
13640
- let provider;
13641
- switch (wallet.id) {
13642
- case "metamask":
13643
- if (providers.ethereum?.isMetaMask && !providers.ethereum?.isPhantom) provider = providers.ethereum;
13644
- break;
13645
- case "phantom":
13646
- provider = providers.phantomEthereum;
13647
- break;
13648
- case "coinbase":
13649
- provider = providers.coinbaseEthereum || (providers.ethereum?.isCoinbaseWallet ? providers.ethereum : void 0);
13650
- break;
13651
- case "trust":
13652
- provider = providers.trustEthereum || (providers.ethereum?.isTrust ? providers.ethereum : void 0);
13653
- break;
13654
- case "rainbow":
13655
- if (providers.ethereum?.isRainbow) provider = providers.ethereum;
13656
- break;
13657
- case "rabby":
13658
- if (providers.ethereum?.isRabby) provider = providers.ethereum;
13659
- break;
13660
- case "okx":
13661
- provider = providers.okxEthereum || (providers.ethereum?.isOkxWallet ? providers.ethereum : void 0);
13662
- break;
13663
- default:
13664
- provider = providers.ethereum;
13715
+ const eip6963Match = findProviderByWalletId(wallet.id);
13716
+ let provider = eip6963Match?.provider;
13717
+ if (!provider) {
13718
+ const legacyEvm = getLegacyEvmProviders();
13719
+ switch (wallet.id) {
13720
+ case "metamask":
13721
+ if (legacyEvm.ethereum?.isMetaMask && !legacyEvm.ethereum?.isPhantom) provider = legacyEvm.ethereum;
13722
+ break;
13723
+ case "phantom":
13724
+ provider = legacyEvm.phantomEthereum;
13725
+ break;
13726
+ case "coinbase":
13727
+ provider = legacyEvm.coinbaseEthereum || (legacyEvm.ethereum?.isCoinbaseWallet ? legacyEvm.ethereum : void 0);
13728
+ break;
13729
+ case "trust":
13730
+ provider = legacyEvm.trustEthereum || (legacyEvm.ethereum?.isTrust ? legacyEvm.ethereum : void 0);
13731
+ break;
13732
+ case "rainbow":
13733
+ if (legacyEvm.ethereum?.isRainbow) provider = legacyEvm.ethereum;
13734
+ break;
13735
+ case "rabby":
13736
+ if (legacyEvm.ethereum?.isRabby) provider = legacyEvm.ethereum;
13737
+ break;
13738
+ case "okx":
13739
+ provider = legacyEvm.okxEthereum || (legacyEvm.ethereum?.isOkxWallet ? legacyEvm.ethereum : void 0);
13740
+ break;
13741
+ default:
13742
+ provider = legacyEvm.ethereum;
13743
+ }
13665
13744
  }
13666
13745
  if (!provider) throw new Error(`${wallet.name} wallet not found. Please install it.`);
13667
13746
  const accounts = await provider.request({ method: "eth_requestAccounts" });
13668
13747
  if (!accounts?.length) throw new Error("No accounts returned from wallet");
13669
13748
  setUserDisconnectedWallet(false);
13670
- const walletType = wallet.id === "phantom" ? "phantom-ethereum" : wallet.id === "coinbase" ? "coinbase" : "metamask";
13749
+ const walletIdToType = {
13750
+ phantom: "phantom-ethereum",
13751
+ coinbase: "coinbase",
13752
+ trust: "trust",
13753
+ rainbow: "rainbow",
13754
+ rabby: "rabby",
13755
+ okx: "okx",
13756
+ metamask: "metamask"
13757
+ };
13758
+ const walletType = walletIdToType[wallet.id] || "metamask";
13671
13759
  connectedInfo = { type: walletType, name: wallet.name, address: accounts[0], icon: wallet.id };
13672
13760
  } else {
13761
+ const solProviders = getSolanaProviders();
13673
13762
  let provider;
13674
13763
  switch (wallet.id) {
13675
13764
  case "phantom":
13676
- provider = providers.phantomSolana;
13765
+ provider = solProviders.phantomSolana;
13677
13766
  break;
13678
13767
  case "solflare":
13679
- provider = providers.solflare;
13768
+ provider = solProviders.solflare;
13680
13769
  break;
13681
13770
  case "backpack":
13682
- provider = providers.backpack || win?.backpack;
13771
+ provider = solProviders.backpack || win?.backpack;
13683
13772
  break;
13684
13773
  case "glow":
13685
- provider = providers.glow || win?.glow;
13774
+ provider = solProviders.glow || win?.glow;
13686
13775
  break;
13687
13776
  case "coinbase":
13688
- provider = providers.coinbaseSolana || win?.coinbaseWalletExtension?.solana;
13777
+ provider = solProviders.coinbaseSolana || win?.coinbaseWalletExtension?.solana;
13689
13778
  break;
13690
13779
  case "trust":
13691
13780
  provider = win?.trustwallet?.solana;
@@ -13931,10 +14020,15 @@ function WalletConnect({
13931
14020
  };
13932
14021
  const sendEthereumTransaction = async (token, amountStr) => {
13933
14022
  if (!recipientAddress || !/^0x[a-fA-F0-9]{40}$/.test(recipientAddress)) throw new Error(`Invalid recipient address.`);
13934
- let provider;
13935
- if (walletInfo.type === "phantom-ethereum") provider = window.phantom?.ethereum;
13936
- else if (walletInfo.type === "coinbase") provider = window.coinbaseWalletExtension || window.ethereum;
13937
- else provider = window.ethereum;
14023
+ const walletIdMap = { "phantom-ethereum": "phantom", coinbase: "coinbase", trust: "trust", okx: "okx", rainbow: "rainbow", rabby: "rabby", metamask: "metamask" };
14024
+ const lookupId = walletIdMap[walletInfo.type] || walletInfo.type;
14025
+ const eip6963Match = findProviderByWalletId(lookupId);
14026
+ let provider = eip6963Match?.provider;
14027
+ if (!provider) {
14028
+ if (walletInfo.type === "phantom-ethereum") provider = window.phantom?.ethereum;
14029
+ else if (walletInfo.type === "coinbase") provider = window.coinbaseWalletExtension || window.ethereum;
14030
+ else provider = window.ethereum;
14031
+ }
13938
14032
  if (!provider) throw new Error("Ethereum wallet not found");
13939
14033
  const currentChainIdHex = await provider.request({ method: "eth_chainId", params: [] });
13940
14034
  if (parseInt(currentChainIdHex, 16).toString() !== token.chain_id) {
@@ -14176,6 +14270,7 @@ function DepositModal({
14176
14270
  enableConnectWallet = false,
14177
14271
  browserWalletAmountQuickSelect = "percentage",
14178
14272
  enablePayWithExchange,
14273
+ enableFiatOnramp,
14179
14274
  enableConnectExchange = false,
14180
14275
  enableCashApp = false,
14181
14276
  hideDepositFlowInfo = false,
@@ -14197,8 +14292,9 @@ function DepositModal({
14197
14292
  const s = initialScreen ?? "main";
14198
14293
  if (s === "tracker" && hideDepositTracker) return "main";
14199
14294
  if (s === "cashapp" && !enableCashApp) return "main";
14295
+ if (s === "card" && enableFiatOnramp === false) return "main";
14200
14296
  return s;
14201
- }, [initialScreen, hideDepositTracker, enableCashApp]);
14297
+ }, [initialScreen, hideDepositTracker, enableCashApp, enableFiatOnramp]);
14202
14298
  const [containerEl, setContainerEl] = useState31(null);
14203
14299
  const containerCallbackRef = useCallback5((el) => {
14204
14300
  setContainerEl(el);
@@ -14314,6 +14410,13 @@ function DepositModal({
14314
14410
  enabled: open
14315
14411
  });
14316
14412
  const showPayWithExchange = enablePayWithExchange ?? projectConfig?.pay_with_exchange?.enabled ?? true;
14413
+ const showFiatOnramp = enableFiatOnramp ?? projectConfig?.fiat_onramp?.enabled ?? true;
14414
+ useEffect25(() => {
14415
+ if (view === "card" && !showFiatOnramp) {
14416
+ setView("main");
14417
+ setCardView("amount");
14418
+ }
14419
+ }, [view, showFiatOnramp]);
14317
14420
  const { exchanges, isLoading: exchangesLoading } = useExchanges({
14318
14421
  publishableKey,
14319
14422
  enabled: open && showPayWithExchange
@@ -14623,7 +14726,7 @@ function DepositModal({
14623
14726
  featuredWallets: projectConfig?.connect_wallet?.wallets
14624
14727
  }
14625
14728
  ),
14626
- /* @__PURE__ */ jsx55(
14729
+ showFiatOnramp && /* @__PURE__ */ jsx55(
14627
14730
  DepositWithCardButton,
14628
14731
  {
14629
14732
  onClick: () => setView("card"),
@@ -15819,7 +15922,7 @@ import {
15819
15922
  ActionType as ActionType5
15820
15923
  } from "@unifold/core";
15821
15924
  var POLL_INTERVAL_MS3 = 2500;
15822
- var POLL_ENDPOINT_INTERVAL_MS2 = 3e3;
15925
+ var POLL_ENDPOINT_INTERVAL_MS2 = 5e3;
15823
15926
  var CUTOFF_BUFFER_MS2 = 6e4;
15824
15927
  function useWithdrawPolling({
15825
15928
  userId,
@@ -16342,29 +16445,18 @@ async function detectBrowserWallet(chainType, senderAddress) {
16342
16445
  evmProviders.push({ provider: p, name });
16343
16446
  }
16344
16447
  };
16345
- if (!anyWin.__eip6963Providers) {
16346
- anyWin.__eip6963Providers = [];
16347
- }
16348
- const handleAnnouncement = (event) => {
16349
- const { detail } = event;
16350
- if (!detail?.info || !detail?.provider) return;
16351
- const exists = anyWin.__eip6963Providers.some((p) => p.info.uuid === detail.info.uuid);
16352
- if (!exists) anyWin.__eip6963Providers.push(detail);
16448
+ const eip6963 = getEip6963Providers();
16449
+ const walletIdToName = {
16450
+ metamask: "MetaMask",
16451
+ phantom: "Phantom",
16452
+ coinbase: "Coinbase",
16453
+ rabby: "Rabby",
16454
+ rainbow: "Rainbow",
16455
+ okx: "OKX Wallet",
16456
+ trust: "Trust Wallet"
16353
16457
  };
16354
- win.addEventListener("eip6963:announceProvider", handleAnnouncement);
16355
- win.dispatchEvent(new Event("eip6963:requestProvider"));
16356
- win.removeEventListener("eip6963:announceProvider", handleAnnouncement);
16357
- for (const detail of anyWin.__eip6963Providers) {
16358
- const rdns = detail.info?.rdns || "";
16359
- let name = detail.info?.name || "Wallet";
16360
- if (rdns.includes("metamask")) name = "MetaMask";
16361
- else if (rdns.includes("phantom")) name = "Phantom";
16362
- else if (rdns.includes("coinbase")) name = "Coinbase";
16363
- else if (rdns.includes("rabby")) name = "Rabby";
16364
- else if (rdns.includes("rainbow")) name = "Rainbow";
16365
- else if (rdns.includes("okx")) name = "OKX Wallet";
16366
- else if (rdns.includes("trust")) name = "Trust Wallet";
16367
- add(detail.provider, name);
16458
+ for (const { provider, walletId, info } of eip6963) {
16459
+ add(provider, walletIdToName[walletId] || info.name || "Wallet");
16368
16460
  }
16369
16461
  if (evmProviders.length === 0) {
16370
16462
  add(anyWin.phantom?.ethereum, "Phantom");
@@ -17655,6 +17747,7 @@ function WithdrawModal({
17655
17747
  // src/components/withdrawals/WithdrawTokenSelector.tsx
17656
17748
  import { useState as useState37, useMemo as useMemo14 } from "react";
17657
17749
  import { Search } from "lucide-react";
17750
+ import Fuse2 from "fuse.js";
17658
17751
  import { jsx as jsx62, jsxs as jsxs56 } from "react/jsx-runtime";
17659
17752
  var t11 = i18n.withdrawModal;
17660
17753
  function WithdrawTokenSelector({
@@ -17674,13 +17767,25 @@ function WithdrawTokenSelector({
17674
17767
  });
17675
17768
  return options;
17676
17769
  }, [tokens]);
17770
+ const fuse = useMemo14(
17771
+ () => new Fuse2(allOptions, {
17772
+ keys: [
17773
+ { name: "token.symbol", weight: 2 },
17774
+ { name: "token.name", weight: 1 },
17775
+ { name: "chain.chain_name", weight: 0.5 }
17776
+ ],
17777
+ threshold: 0.2,
17778
+ ignoreLocation: true,
17779
+ minMatchCharLength: 2
17780
+ }),
17781
+ [allOptions]
17782
+ );
17677
17783
  const filteredOptions = useMemo14(() => {
17678
17784
  if (!searchQuery.trim()) return allOptions;
17679
- const query = searchQuery.toLowerCase();
17680
- return allOptions.filter(
17681
- ({ token, chain }) => token.symbol.toLowerCase().includes(query) || token.name.toLowerCase().includes(query) || chain.chain_name.toLowerCase().includes(query)
17682
- );
17683
- }, [allOptions, searchQuery]);
17785
+ const query = searchQuery.trim();
17786
+ const results = fuse.search(query);
17787
+ return results.map((r) => r.item);
17788
+ }, [fuse, allOptions, searchQuery]);
17684
17789
  return /* @__PURE__ */ jsxs56(
17685
17790
  "div",
17686
17791
  {