@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.js CHANGED
@@ -1580,7 +1580,7 @@ var import_react3 = require("react");
1580
1580
  var import_core6 = require("@unifold/core");
1581
1581
  var DEPOSIT_CONFIRM_DELAY_MS = 5e3;
1582
1582
  var POLL_INTERVAL_MS = 2500;
1583
- var POLL_ENDPOINT_INTERVAL_MS = 3e3;
1583
+ var POLL_ENDPOINT_INTERVAL_MS = 5e3;
1584
1584
  var CUTOFF_BUFFER_MS = 6e4;
1585
1585
  function useDepositPolling({
1586
1586
  userId,
@@ -5324,6 +5324,56 @@ var React24 = __toESM(require("react"));
5324
5324
  var import_lucide_react17 = require("lucide-react");
5325
5325
  var import_core14 = require("@unifold/core");
5326
5326
 
5327
+ // src/lib/eip6963-store.ts
5328
+ var import_mipd = require("mipd");
5329
+ var _store = null;
5330
+ function getEip6963Store() {
5331
+ if (typeof window === "undefined") return null;
5332
+ if (!_store) {
5333
+ _store = (0, import_mipd.createStore)();
5334
+ }
5335
+ return _store;
5336
+ }
5337
+ var RDNS_TO_WALLET_ID = {
5338
+ "io.metamask": "metamask",
5339
+ "io.metamask.flask": "metamask",
5340
+ "io.metamask.mmi": "metamask",
5341
+ "app.phantom": "phantom",
5342
+ "com.coinbase.wallet": "coinbase",
5343
+ "com.okex.wallet": "okx",
5344
+ "io.rabby": "rabby",
5345
+ "com.trustwallet.app": "trust",
5346
+ "me.rainbow": "rainbow"
5347
+ };
5348
+ function rdnsToWalletId(rdns) {
5349
+ if (RDNS_TO_WALLET_ID[rdns]) return RDNS_TO_WALLET_ID[rdns];
5350
+ if (rdns.includes("metamask")) return "metamask";
5351
+ if (rdns.includes("phantom")) return "phantom";
5352
+ if (rdns.includes("coinbase")) return "coinbase";
5353
+ if (rdns.includes("okx") || rdns.includes("okex")) return "okx";
5354
+ if (rdns.includes("rabby")) return "rabby";
5355
+ if (rdns.includes("trust")) return "trust";
5356
+ if (rdns.includes("rainbow")) return "rainbow";
5357
+ return "unknown";
5358
+ }
5359
+ function getEip6963Providers() {
5360
+ const store = getEip6963Store();
5361
+ if (!store) return [];
5362
+ return store.getProviders().map((detail) => ({
5363
+ walletId: rdnsToWalletId(detail.info.rdns),
5364
+ provider: detail.provider,
5365
+ info: detail.info
5366
+ }));
5367
+ }
5368
+ function findProviderByWalletId(walletId) {
5369
+ return getEip6963Providers().find((p) => p.walletId === walletId);
5370
+ }
5371
+ function collectAllEip6963EthProviders() {
5372
+ const store = getEip6963Store();
5373
+ if (!store) return [];
5374
+ return store.getProviders().map((d) => d.provider);
5375
+ }
5376
+
5327
5377
  // src/components/deposits/browser-wallets/disconnectInjectedBrowserWallet.ts
5328
5378
  var SOLANA_DISCONNECT_TYPES = [
5329
5379
  "phantom-solana",
@@ -5364,8 +5414,9 @@ function collectEthereumProvidersForDisconnect(win) {
5364
5414
  out.push(p);
5365
5415
  }
5366
5416
  };
5367
- const list = anyWin.__eip6963Providers || [];
5368
- for (const d of list) add(d.provider);
5417
+ for (const p of collectAllEip6963EthProviders()) {
5418
+ add(p);
5419
+ }
5369
5420
  add(win.ethereum);
5370
5421
  add(
5371
5422
  win.phantom?.ethereum
@@ -7425,30 +7476,13 @@ function BrowserWalletButton({
7425
7476
  }, []);
7426
7477
  const [eip6963ProviderCount, setEip6963ProviderCount] = React24.useState(0);
7427
7478
  React24.useEffect(() => {
7428
- if (typeof window === "undefined") return;
7429
- const anyWin = window;
7430
- if (!anyWin.__eip6963Providers) {
7431
- anyWin.__eip6963Providers = [];
7432
- }
7433
- const handleAnnouncement = (event) => {
7434
- const { detail } = event;
7435
- if (!detail?.info || !detail?.provider) return;
7436
- const exists = anyWin.__eip6963Providers.some(
7437
- (p) => p.info.uuid === detail.info.uuid
7438
- );
7439
- if (!exists) {
7440
- anyWin.__eip6963Providers.push(detail);
7441
- setEip6963ProviderCount(anyWin.__eip6963Providers.length);
7442
- }
7443
- };
7444
- window.addEventListener("eip6963:announceProvider", handleAnnouncement);
7445
- window.dispatchEvent(new Event("eip6963:requestProvider"));
7446
- return () => {
7447
- window.removeEventListener(
7448
- "eip6963:announceProvider",
7449
- handleAnnouncement
7450
- );
7451
- };
7479
+ const store = getEip6963Store();
7480
+ if (!store) return;
7481
+ setEip6963ProviderCount(store.getProviders().length);
7482
+ const unsubscribe = store.subscribe((providers) => {
7483
+ setEip6963ProviderCount(providers.length);
7484
+ });
7485
+ return unsubscribe;
7452
7486
  }, []);
7453
7487
  React24.useEffect(() => {
7454
7488
  if (!wallet || !publishableKey) {
@@ -7507,7 +7541,7 @@ function BrowserWalletButton({
7507
7541
  return;
7508
7542
  }
7509
7543
  if (!chainType || chainType === "solana") {
7510
- const anyWin2 = win;
7544
+ const anyWin = win;
7511
7545
  const trySilentSolana = async (provider, type, name, icon) => {
7512
7546
  if (!provider) return false;
7513
7547
  if (provider.isConnected && provider.publicKey) {
@@ -7546,21 +7580,21 @@ function BrowserWalletButton({
7546
7580
  ))
7547
7581
  return;
7548
7582
  if (await trySilentSolana(
7549
- anyWin2.solflare,
7583
+ anyWin.solflare,
7550
7584
  "solflare",
7551
7585
  "Solflare",
7552
7586
  "solflare"
7553
7587
  ))
7554
7588
  return;
7555
7589
  if (await trySilentSolana(
7556
- anyWin2.backpack,
7590
+ anyWin.backpack,
7557
7591
  "backpack",
7558
7592
  "Backpack",
7559
7593
  "backpack"
7560
7594
  ))
7561
7595
  return;
7562
7596
  if (await trySilentSolana(
7563
- anyWin2.glow,
7597
+ anyWin.glow,
7564
7598
  "glow",
7565
7599
  "Glow",
7566
7600
  "glow"
@@ -7568,19 +7602,14 @@ function BrowserWalletButton({
7568
7602
  return;
7569
7603
  }
7570
7604
  if (!chainType || chainType === "ethereum") {
7571
- const anyWin2 = win;
7605
+ const anyWin = win;
7572
7606
  const allProviders = [];
7573
- const eip6963Providers = anyWin2.__eip6963Providers || [];
7574
- for (const { info, provider } of eip6963Providers) {
7575
- let walletId = "default";
7576
- if (info.rdns.includes("metamask")) walletId = "metamask";
7577
- else if (info.rdns.includes("phantom")) walletId = "phantom";
7578
- else if (info.rdns.includes("coinbase")) walletId = "coinbase";
7579
- else if (info.rdns.includes("okx")) walletId = "okx";
7580
- else if (info.rdns.includes("rabby")) walletId = "rabby";
7581
- else if (info.rdns.includes("trust")) walletId = "trust";
7582
- else if (info.rdns.includes("rainbow")) walletId = "rainbow";
7583
- allProviders.push({ provider, walletId });
7607
+ const eip6963 = getEip6963Providers();
7608
+ for (const { provider, walletId } of eip6963) {
7609
+ allProviders.push({
7610
+ provider,
7611
+ walletId: walletId === "unknown" ? "default" : walletId
7612
+ });
7584
7613
  }
7585
7614
  if (allProviders.length === 0) {
7586
7615
  if (win.phantom?.ethereum) {
@@ -7589,15 +7618,15 @@ function BrowserWalletButton({
7589
7618
  walletId: "phantom"
7590
7619
  });
7591
7620
  }
7592
- if (anyWin2.okxwallet) {
7621
+ if (anyWin.okxwallet) {
7593
7622
  allProviders.push({
7594
- provider: anyWin2.okxwallet,
7623
+ provider: anyWin.okxwallet,
7595
7624
  walletId: "okx"
7596
7625
  });
7597
7626
  }
7598
- if (anyWin2.coinbaseWalletExtension) {
7627
+ if (anyWin.coinbaseWalletExtension) {
7599
7628
  allProviders.push({
7600
- provider: anyWin2.coinbaseWalletExtension,
7629
+ provider: anyWin.coinbaseWalletExtension,
7601
7630
  walletId: "coinbase"
7602
7631
  });
7603
7632
  }
@@ -7621,7 +7650,7 @@ function BrowserWalletButton({
7621
7650
  });
7622
7651
  if (!accounts || accounts.length === 0) continue;
7623
7652
  const address = accounts[0];
7624
- const resolved = identifyEthWallet(provider, anyWin2, walletId);
7653
+ const resolved = identifyEthWallet(provider, anyWin, walletId);
7625
7654
  if (mounted) {
7626
7655
  setWallet({ ...resolved, address });
7627
7656
  setIsLoading(false);
@@ -7663,15 +7692,11 @@ function BrowserWalletButton({
7663
7692
  solanaProvider.on("disconnect", handleDisconnect);
7664
7693
  solanaProvider.on("accountChanged", handleAccountsChanged);
7665
7694
  }
7666
- const anyWin = window;
7667
7695
  const ethProviders = [];
7668
- if (anyWin.__eip6963Providers) {
7669
- for (const {
7670
- provider
7671
- } of anyWin.__eip6963Providers) {
7672
- if (provider && !ethProviders.includes(provider)) {
7673
- ethProviders.push(provider);
7674
- }
7696
+ for (const { provider } of getEip6963Providers()) {
7697
+ const p = provider;
7698
+ if (p && !ethProviders.includes(p)) {
7699
+ ethProviders.push(p);
7675
7700
  }
7676
7701
  }
7677
7702
  if (window.ethereum && !ethProviders.includes(window.ethereum)) {
@@ -7773,7 +7798,7 @@ function BrowserWalletButton({
7773
7798
  if (isLoading) {
7774
7799
  return null;
7775
7800
  }
7776
- const hasWalletExtension = (!chainType || chainType === "solana") && (window.phantom?.solana?.isPhantom || window.solana?.isPhantom) ? true : (!chainType || chainType === "ethereum") && (window.phantom?.ethereum || window.ethereum) ? true : false;
7801
+ 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);
7777
7802
  if (!onConnectClick && !wallet && !hasWalletExtension) {
7778
7803
  return null;
7779
7804
  }
@@ -10307,6 +10332,7 @@ function DepositsModal({
10307
10332
  // src/components/deposits/TokenSelectorSheet.tsx
10308
10333
  var import_react14 = require("react");
10309
10334
  var import_lucide_react19 = require("lucide-react");
10335
+ var import_fuse = __toESM(require("fuse.js"));
10310
10336
  var import_jsx_runtime41 = require("react/jsx-runtime");
10311
10337
  var STORAGE_KEY = "unifold_recent_tokens";
10312
10338
  var MAX_RECENT_TOKENS = 5;
@@ -10412,13 +10438,25 @@ function TokenSelectorSheet({
10412
10438
  });
10413
10439
  setRecentTokens(updated);
10414
10440
  };
10441
+ const fuse = (0, import_react14.useMemo)(
10442
+ () => new import_fuse.default(allOptions, {
10443
+ keys: [
10444
+ { name: "token.symbol", weight: 2 },
10445
+ { name: "token.name", weight: 1 },
10446
+ { name: "chain.chain_name", weight: 0.5 }
10447
+ ],
10448
+ threshold: 0.2,
10449
+ ignoreLocation: true,
10450
+ minMatchCharLength: 2
10451
+ }),
10452
+ [allOptions]
10453
+ );
10415
10454
  const filteredOptions = (0, import_react14.useMemo)(() => {
10416
10455
  if (!searchQuery.trim()) return allOptions;
10417
- const query = searchQuery.toLowerCase();
10418
- return allOptions.filter(
10419
- ({ token, chain }) => token.symbol.toLowerCase().includes(query) || token.name.toLowerCase().includes(query) || chain.chain_name.toLowerCase().includes(query)
10420
- );
10421
- }, [allOptions, searchQuery]);
10456
+ const query = searchQuery.trim();
10457
+ const results = fuse.search(query);
10458
+ return results.map((r) => r.item);
10459
+ }, [fuse, allOptions, searchQuery]);
10422
10460
  const isCommonToken = (symbol, chainType, chainId) => {
10423
10461
  return COMMON_TOKENS.some(
10424
10462
  (ct) => ct.symbol === symbol && ct.chainType === chainType && ct.chainId === chainId
@@ -13443,15 +13481,10 @@ var WALLET_DEFINITIONS = [
13443
13481
  { id: "backpack", name: "Backpack", networks: ["solana"], installUrl: "https://backpack.app/" },
13444
13482
  { id: "glow", name: "Glow", networks: ["solana"], installUrl: "https://glow.app/" }
13445
13483
  ];
13446
- function getWalletProviders() {
13484
+ function getSolanaProviders() {
13447
13485
  if (typeof window === "undefined") return {};
13448
13486
  const win = window;
13449
13487
  return {
13450
- ethereum: win.ethereum,
13451
- phantomEthereum: win.phantom?.ethereum,
13452
- coinbaseEthereum: win.coinbaseWalletExtension,
13453
- trustEthereum: win.trustwallet?.ethereum,
13454
- okxEthereum: win.okxwallet,
13455
13488
  phantomSolana: win.phantom?.solana,
13456
13489
  solflare: win.solflare,
13457
13490
  backpack: win.backpack,
@@ -13459,37 +13492,71 @@ function getWalletProviders() {
13459
13492
  coinbaseSolana: win.coinbaseSolana || win.coinbaseWalletExtension?.solana
13460
13493
  };
13461
13494
  }
13495
+ function getLegacyEvmProviders() {
13496
+ if (typeof window === "undefined") return {};
13497
+ const win = window;
13498
+ return {
13499
+ ethereum: win.ethereum,
13500
+ phantomEthereum: win.phantom?.ethereum,
13501
+ coinbaseEthereum: win.coinbaseWalletExtension,
13502
+ trustEthereum: win.trustwallet?.ethereum,
13503
+ okxEthereum: win.okxwallet
13504
+ };
13505
+ }
13462
13506
  function detectAvailableWallets(filterChainType) {
13463
- const providers = getWalletProviders();
13507
+ const solProviders = getSolanaProviders();
13508
+ const legacyEvm = getLegacyEvmProviders();
13509
+ const eip6963List = getEip6963Providers();
13464
13510
  const win = typeof window !== "undefined" ? window : null;
13511
+ const hasEip6963 = (walletId) => eip6963List.some((d) => {
13512
+ const rdns = d.info?.rdns || "";
13513
+ switch (walletId) {
13514
+ case "metamask":
13515
+ return rdns.includes("metamask");
13516
+ case "phantom":
13517
+ return rdns.includes("phantom");
13518
+ case "coinbase":
13519
+ return rdns.includes("coinbase");
13520
+ case "trust":
13521
+ return rdns.includes("trust");
13522
+ case "rainbow":
13523
+ return rdns.includes("rainbow");
13524
+ case "rabby":
13525
+ return rdns.includes("rabby");
13526
+ case "okx":
13527
+ return rdns.includes("okx") || rdns.includes("okex");
13528
+ default:
13529
+ return false;
13530
+ }
13531
+ });
13465
13532
  return WALLET_DEFINITIONS.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
13466
13533
  let isInstalled = false;
13467
13534
  const detectedNetworks = [];
13468
13535
  switch (wallet.id) {
13469
13536
  case "metamask":
13470
- isInstalled = !!(providers.ethereum?.isMetaMask && !providers.ethereum?.isPhantom && !providers.ethereum?.isRabby && !providers.ethereum?.isOkxWallet);
13537
+ isInstalled = hasEip6963("metamask") || !!(legacyEvm.ethereum?.isMetaMask && !legacyEvm.ethereum?.isPhantom && !legacyEvm.ethereum?.isRabby && !legacyEvm.ethereum?.isOkxWallet);
13471
13538
  if (isInstalled) detectedNetworks.push("ethereum");
13472
13539
  break;
13473
13540
  case "phantom":
13474
- if (providers.phantomSolana?.isPhantom) {
13541
+ if (solProviders.phantomSolana?.isPhantom) {
13475
13542
  isInstalled = true;
13476
13543
  detectedNetworks.push("solana");
13477
13544
  }
13478
- if (providers.phantomEthereum?.isPhantom) {
13545
+ if (hasEip6963("phantom") || legacyEvm.phantomEthereum?.isPhantom) {
13479
13546
  isInstalled = true;
13480
13547
  detectedNetworks.push("ethereum");
13481
13548
  }
13482
13549
  break;
13483
13550
  case "coinbase":
13484
- if (providers.coinbaseEthereum || providers.ethereum?.isCoinbaseWallet) {
13551
+ if (hasEip6963("coinbase") || legacyEvm.coinbaseEthereum || legacyEvm.ethereum?.isCoinbaseWallet) {
13485
13552
  isInstalled = true;
13486
13553
  detectedNetworks.push("ethereum");
13487
13554
  }
13488
- if (providers.coinbaseSolana || win?.coinbaseWalletExtension?.solana) detectedNetworks.push("solana");
13555
+ if (solProviders.coinbaseSolana || win?.coinbaseWalletExtension?.solana) detectedNetworks.push("solana");
13489
13556
  if (isInstalled && wallet.networks.includes("solana") && !detectedNetworks.includes("solana")) detectedNetworks.push("solana");
13490
13557
  break;
13491
13558
  case "trust":
13492
- if (providers.trustEthereum || providers.ethereum?.isTrust || win?.trustwallet) {
13559
+ if (hasEip6963("trust") || legacyEvm.trustEthereum || legacyEvm.ethereum?.isTrust || win?.trustwallet) {
13493
13560
  isInstalled = true;
13494
13561
  detectedNetworks.push("ethereum");
13495
13562
  }
@@ -13497,27 +13564,27 @@ function detectAvailableWallets(filterChainType) {
13497
13564
  if (isInstalled && wallet.networks.includes("solana") && !detectedNetworks.includes("solana")) detectedNetworks.push("solana");
13498
13565
  break;
13499
13566
  case "rainbow":
13500
- isInstalled = !!providers.ethereum?.isRainbow;
13567
+ isInstalled = hasEip6963("rainbow") || !!legacyEvm.ethereum?.isRainbow;
13501
13568
  if (isInstalled) detectedNetworks.push("ethereum");
13502
13569
  break;
13503
13570
  case "rabby":
13504
- isInstalled = !!providers.ethereum?.isRabby;
13571
+ isInstalled = hasEip6963("rabby") || !!legacyEvm.ethereum?.isRabby;
13505
13572
  if (isInstalled) detectedNetworks.push("ethereum");
13506
13573
  break;
13507
13574
  case "okx":
13508
- isInstalled = !!(providers.okxEthereum || providers.ethereum?.isOkxWallet);
13575
+ isInstalled = hasEip6963("okx") || !!(legacyEvm.okxEthereum || legacyEvm.ethereum?.isOkxWallet);
13509
13576
  if (isInstalled) detectedNetworks.push("ethereum");
13510
13577
  break;
13511
13578
  case "solflare":
13512
- isInstalled = !!providers.solflare?.isSolflare;
13579
+ isInstalled = !!solProviders.solflare?.isSolflare;
13513
13580
  if (isInstalled) detectedNetworks.push("solana");
13514
13581
  break;
13515
13582
  case "backpack":
13516
- isInstalled = !!(providers.backpack?.isBackpack || win?.backpack);
13583
+ isInstalled = !!(solProviders.backpack?.isBackpack || win?.backpack);
13517
13584
  if (isInstalled) detectedNetworks.push("solana");
13518
13585
  break;
13519
13586
  case "glow":
13520
- isInstalled = !!(providers.glow?.isGlow || win?.glow);
13587
+ isInstalled = !!(solProviders.glow?.isGlow || win?.glow);
13521
13588
  if (isInstalled) detectedNetworks.push("solana");
13522
13589
  break;
13523
13590
  }
@@ -13572,7 +13639,16 @@ function WalletConnect({
13572
13639
  const [connectingNetwork, setConnectingNetwork] = React29.useState(null);
13573
13640
  const [walletError, setWalletError] = React29.useState(null);
13574
13641
  const [isWalletConnecting, setIsWalletConnecting] = React29.useState(false);
13575
- const availableWallets = React29.useMemo(() => detectAvailableWallets(), []);
13642
+ const [eip6963ProviderCount, setEip6963ProviderCount] = React29.useState(0);
13643
+ React29.useEffect(() => {
13644
+ const store = getEip6963Store();
13645
+ if (!store) return;
13646
+ setEip6963ProviderCount(store.getProviders().length);
13647
+ return store.subscribe((providers) => {
13648
+ setEip6963ProviderCount(providers.length);
13649
+ });
13650
+ }, []);
13651
+ const availableWallets = React29.useMemo(() => detectAvailableWallets(), [eip6963ProviderCount]);
13576
13652
  const [balances, setBalances] = React29.useState([]);
13577
13653
  const [isLoading, setIsLoading] = React29.useState(false);
13578
13654
  const [selectedBalance, setSelectedBalance] = React29.useState(null);
@@ -13631,59 +13707,72 @@ function WalletConnect({
13631
13707
  setWalletError(null);
13632
13708
  setIsWalletConnecting(true);
13633
13709
  try {
13634
- const providers = getWalletProviders();
13635
13710
  const win = typeof window !== "undefined" ? window : null;
13636
13711
  let connectedInfo;
13637
13712
  if (network === "ethereum") {
13638
- let provider;
13639
- switch (wallet.id) {
13640
- case "metamask":
13641
- if (providers.ethereum?.isMetaMask && !providers.ethereum?.isPhantom) provider = providers.ethereum;
13642
- break;
13643
- case "phantom":
13644
- provider = providers.phantomEthereum;
13645
- break;
13646
- case "coinbase":
13647
- provider = providers.coinbaseEthereum || (providers.ethereum?.isCoinbaseWallet ? providers.ethereum : void 0);
13648
- break;
13649
- case "trust":
13650
- provider = providers.trustEthereum || (providers.ethereum?.isTrust ? providers.ethereum : void 0);
13651
- break;
13652
- case "rainbow":
13653
- if (providers.ethereum?.isRainbow) provider = providers.ethereum;
13654
- break;
13655
- case "rabby":
13656
- if (providers.ethereum?.isRabby) provider = providers.ethereum;
13657
- break;
13658
- case "okx":
13659
- provider = providers.okxEthereum || (providers.ethereum?.isOkxWallet ? providers.ethereum : void 0);
13660
- break;
13661
- default:
13662
- provider = providers.ethereum;
13713
+ const eip6963Match = findProviderByWalletId(wallet.id);
13714
+ let provider = eip6963Match?.provider;
13715
+ if (!provider) {
13716
+ const legacyEvm = getLegacyEvmProviders();
13717
+ switch (wallet.id) {
13718
+ case "metamask":
13719
+ if (legacyEvm.ethereum?.isMetaMask && !legacyEvm.ethereum?.isPhantom) provider = legacyEvm.ethereum;
13720
+ break;
13721
+ case "phantom":
13722
+ provider = legacyEvm.phantomEthereum;
13723
+ break;
13724
+ case "coinbase":
13725
+ provider = legacyEvm.coinbaseEthereum || (legacyEvm.ethereum?.isCoinbaseWallet ? legacyEvm.ethereum : void 0);
13726
+ break;
13727
+ case "trust":
13728
+ provider = legacyEvm.trustEthereum || (legacyEvm.ethereum?.isTrust ? legacyEvm.ethereum : void 0);
13729
+ break;
13730
+ case "rainbow":
13731
+ if (legacyEvm.ethereum?.isRainbow) provider = legacyEvm.ethereum;
13732
+ break;
13733
+ case "rabby":
13734
+ if (legacyEvm.ethereum?.isRabby) provider = legacyEvm.ethereum;
13735
+ break;
13736
+ case "okx":
13737
+ provider = legacyEvm.okxEthereum || (legacyEvm.ethereum?.isOkxWallet ? legacyEvm.ethereum : void 0);
13738
+ break;
13739
+ default:
13740
+ provider = legacyEvm.ethereum;
13741
+ }
13663
13742
  }
13664
13743
  if (!provider) throw new Error(`${wallet.name} wallet not found. Please install it.`);
13665
13744
  const accounts = await provider.request({ method: "eth_requestAccounts" });
13666
13745
  if (!accounts?.length) throw new Error("No accounts returned from wallet");
13667
13746
  setUserDisconnectedWallet(false);
13668
- const walletType = wallet.id === "phantom" ? "phantom-ethereum" : wallet.id === "coinbase" ? "coinbase" : "metamask";
13747
+ const walletIdToType = {
13748
+ phantom: "phantom-ethereum",
13749
+ coinbase: "coinbase",
13750
+ trust: "trust",
13751
+ rainbow: "rainbow",
13752
+ rabby: "rabby",
13753
+ okx: "okx",
13754
+ metamask: "metamask"
13755
+ };
13756
+ const walletType = walletIdToType[wallet.id] || "metamask";
13669
13757
  connectedInfo = { type: walletType, name: wallet.name, address: accounts[0], icon: wallet.id };
13670
13758
  } else {
13759
+ const solProviders = getSolanaProviders();
13671
13760
  let provider;
13672
13761
  switch (wallet.id) {
13673
13762
  case "phantom":
13674
- provider = providers.phantomSolana;
13763
+ provider = solProviders.phantomSolana;
13675
13764
  break;
13676
13765
  case "solflare":
13677
- provider = providers.solflare;
13766
+ provider = solProviders.solflare;
13678
13767
  break;
13679
13768
  case "backpack":
13680
- provider = providers.backpack || win?.backpack;
13769
+ provider = solProviders.backpack || win?.backpack;
13681
13770
  break;
13682
13771
  case "glow":
13683
- provider = providers.glow || win?.glow;
13772
+ provider = solProviders.glow || win?.glow;
13684
13773
  break;
13685
13774
  case "coinbase":
13686
- provider = providers.coinbaseSolana || win?.coinbaseWalletExtension?.solana;
13775
+ provider = solProviders.coinbaseSolana || win?.coinbaseWalletExtension?.solana;
13687
13776
  break;
13688
13777
  case "trust":
13689
13778
  provider = win?.trustwallet?.solana;
@@ -13929,10 +14018,15 @@ function WalletConnect({
13929
14018
  };
13930
14019
  const sendEthereumTransaction = async (token, amountStr) => {
13931
14020
  if (!recipientAddress || !/^0x[a-fA-F0-9]{40}$/.test(recipientAddress)) throw new Error(`Invalid recipient address.`);
13932
- let provider;
13933
- if (walletInfo.type === "phantom-ethereum") provider = window.phantom?.ethereum;
13934
- else if (walletInfo.type === "coinbase") provider = window.coinbaseWalletExtension || window.ethereum;
13935
- else provider = window.ethereum;
14021
+ const walletIdMap = { "phantom-ethereum": "phantom", coinbase: "coinbase", trust: "trust", okx: "okx", rainbow: "rainbow", rabby: "rabby", metamask: "metamask" };
14022
+ const lookupId = walletIdMap[walletInfo.type] || walletInfo.type;
14023
+ const eip6963Match = findProviderByWalletId(lookupId);
14024
+ let provider = eip6963Match?.provider;
14025
+ if (!provider) {
14026
+ if (walletInfo.type === "phantom-ethereum") provider = window.phantom?.ethereum;
14027
+ else if (walletInfo.type === "coinbase") provider = window.coinbaseWalletExtension || window.ethereum;
14028
+ else provider = window.ethereum;
14029
+ }
13936
14030
  if (!provider) throw new Error("Ethereum wallet not found");
13937
14031
  const currentChainIdHex = await provider.request({ method: "eth_chainId", params: [] });
13938
14032
  if (parseInt(currentChainIdHex, 16).toString() !== token.chain_id) {
@@ -14174,6 +14268,7 @@ function DepositModal({
14174
14268
  enableConnectWallet = false,
14175
14269
  browserWalletAmountQuickSelect = "percentage",
14176
14270
  enablePayWithExchange,
14271
+ enableFiatOnramp,
14177
14272
  enableConnectExchange = false,
14178
14273
  enableCashApp = false,
14179
14274
  hideDepositFlowInfo = false,
@@ -14195,8 +14290,9 @@ function DepositModal({
14195
14290
  const s = initialScreen ?? "main";
14196
14291
  if (s === "tracker" && hideDepositTracker) return "main";
14197
14292
  if (s === "cashapp" && !enableCashApp) return "main";
14293
+ if (s === "card" && enableFiatOnramp === false) return "main";
14198
14294
  return s;
14199
- }, [initialScreen, hideDepositTracker, enableCashApp]);
14295
+ }, [initialScreen, hideDepositTracker, enableCashApp, enableFiatOnramp]);
14200
14296
  const [containerEl, setContainerEl] = (0, import_react20.useState)(null);
14201
14297
  const containerCallbackRef = (0, import_react20.useCallback)((el) => {
14202
14298
  setContainerEl(el);
@@ -14312,6 +14408,13 @@ function DepositModal({
14312
14408
  enabled: open
14313
14409
  });
14314
14410
  const showPayWithExchange = enablePayWithExchange ?? projectConfig?.pay_with_exchange?.enabled ?? true;
14411
+ const showFiatOnramp = enableFiatOnramp ?? projectConfig?.fiat_onramp?.enabled ?? true;
14412
+ (0, import_react20.useEffect)(() => {
14413
+ if (view === "card" && !showFiatOnramp) {
14414
+ setView("main");
14415
+ setCardView("amount");
14416
+ }
14417
+ }, [view, showFiatOnramp]);
14315
14418
  const { exchanges, isLoading: exchangesLoading } = useExchanges({
14316
14419
  publishableKey,
14317
14420
  enabled: open && showPayWithExchange
@@ -14621,7 +14724,7 @@ function DepositModal({
14621
14724
  featuredWallets: projectConfig?.connect_wallet?.wallets
14622
14725
  }
14623
14726
  ),
14624
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
14727
+ showFiatOnramp && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
14625
14728
  DepositWithCardButton,
14626
14729
  {
14627
14730
  onClick: () => setView("card"),
@@ -15797,7 +15900,7 @@ function useExecutions(userId, publishableKey, options) {
15797
15900
  var import_react22 = require("react");
15798
15901
  var import_core35 = require("@unifold/core");
15799
15902
  var POLL_INTERVAL_MS3 = 2500;
15800
- var POLL_ENDPOINT_INTERVAL_MS2 = 3e3;
15903
+ var POLL_ENDPOINT_INTERVAL_MS2 = 5e3;
15801
15904
  var CUTOFF_BUFFER_MS2 = 6e4;
15802
15905
  function useWithdrawPolling({
15803
15906
  userId,
@@ -16302,29 +16405,18 @@ async function detectBrowserWallet(chainType, senderAddress) {
16302
16405
  evmProviders.push({ provider: p, name });
16303
16406
  }
16304
16407
  };
16305
- if (!anyWin.__eip6963Providers) {
16306
- anyWin.__eip6963Providers = [];
16307
- }
16308
- const handleAnnouncement = (event) => {
16309
- const { detail } = event;
16310
- if (!detail?.info || !detail?.provider) return;
16311
- const exists = anyWin.__eip6963Providers.some((p) => p.info.uuid === detail.info.uuid);
16312
- if (!exists) anyWin.__eip6963Providers.push(detail);
16408
+ const eip6963 = getEip6963Providers();
16409
+ const walletIdToName = {
16410
+ metamask: "MetaMask",
16411
+ phantom: "Phantom",
16412
+ coinbase: "Coinbase",
16413
+ rabby: "Rabby",
16414
+ rainbow: "Rainbow",
16415
+ okx: "OKX Wallet",
16416
+ trust: "Trust Wallet"
16313
16417
  };
16314
- win.addEventListener("eip6963:announceProvider", handleAnnouncement);
16315
- win.dispatchEvent(new Event("eip6963:requestProvider"));
16316
- win.removeEventListener("eip6963:announceProvider", handleAnnouncement);
16317
- for (const detail of anyWin.__eip6963Providers) {
16318
- const rdns = detail.info?.rdns || "";
16319
- let name = detail.info?.name || "Wallet";
16320
- if (rdns.includes("metamask")) name = "MetaMask";
16321
- else if (rdns.includes("phantom")) name = "Phantom";
16322
- else if (rdns.includes("coinbase")) name = "Coinbase";
16323
- else if (rdns.includes("rabby")) name = "Rabby";
16324
- else if (rdns.includes("rainbow")) name = "Rainbow";
16325
- else if (rdns.includes("okx")) name = "OKX Wallet";
16326
- else if (rdns.includes("trust")) name = "Trust Wallet";
16327
- add(detail.provider, name);
16418
+ for (const { provider, walletId, info } of eip6963) {
16419
+ add(provider, walletIdToName[walletId] || info.name || "Wallet");
16328
16420
  }
16329
16421
  if (evmProviders.length === 0) {
16330
16422
  add(anyWin.phantom?.ethereum, "Phantom");
@@ -17606,6 +17698,7 @@ function WithdrawModal({
17606
17698
  // src/components/withdrawals/WithdrawTokenSelector.tsx
17607
17699
  var import_react27 = require("react");
17608
17700
  var import_lucide_react34 = require("lucide-react");
17701
+ var import_fuse2 = __toESM(require("fuse.js"));
17609
17702
  var import_jsx_runtime62 = require("react/jsx-runtime");
17610
17703
  var t11 = i18n.withdrawModal;
17611
17704
  function WithdrawTokenSelector({
@@ -17625,13 +17718,25 @@ function WithdrawTokenSelector({
17625
17718
  });
17626
17719
  return options;
17627
17720
  }, [tokens]);
17721
+ const fuse = (0, import_react27.useMemo)(
17722
+ () => new import_fuse2.default(allOptions, {
17723
+ keys: [
17724
+ { name: "token.symbol", weight: 2 },
17725
+ { name: "token.name", weight: 1 },
17726
+ { name: "chain.chain_name", weight: 0.5 }
17727
+ ],
17728
+ threshold: 0.2,
17729
+ ignoreLocation: true,
17730
+ minMatchCharLength: 2
17731
+ }),
17732
+ [allOptions]
17733
+ );
17628
17734
  const filteredOptions = (0, import_react27.useMemo)(() => {
17629
17735
  if (!searchQuery.trim()) return allOptions;
17630
- const query = searchQuery.toLowerCase();
17631
- return allOptions.filter(
17632
- ({ token, chain }) => token.symbol.toLowerCase().includes(query) || token.name.toLowerCase().includes(query) || chain.chain_name.toLowerCase().includes(query)
17633
- );
17634
- }, [allOptions, searchQuery]);
17736
+ const query = searchQuery.trim();
17737
+ const results = fuse.search(query);
17738
+ return results.map((r) => r.item);
17739
+ }, [fuse, allOptions, searchQuery]);
17635
17740
  return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(
17636
17741
  "div",
17637
17742
  {