@unifold/ui-react 0.1.61 → 0.1.62

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
@@ -5323,7 +5323,7 @@ function CashAppButton({
5323
5323
  }
5324
5324
 
5325
5325
  // src/components/deposits/buttons/BrowserWalletButton.tsx
5326
- var React24 = __toESM(require("react"));
5326
+ var React25 = __toESM(require("react"));
5327
5327
  var import_lucide_react17 = require("lucide-react");
5328
5328
  var import_core14 = require("@unifold/core");
5329
5329
 
@@ -5377,6 +5377,197 @@ function collectAllEip6963EthProviders() {
5377
5377
  return store.getProviders().map((d) => d.provider);
5378
5378
  }
5379
5379
 
5380
+ // src/components/deposits/browser-wallets/useDetectedBrowserWallet.ts
5381
+ var React12 = __toESM(require("react"));
5382
+
5383
+ // src/components/deposits/browser-wallets/detectConnectedWallet.ts
5384
+ function identifyEthWallet(provider, hint) {
5385
+ switch (hint) {
5386
+ case "metamask":
5387
+ return { type: "metamask", name: "MetaMask", icon: "metamask" };
5388
+ case "phantom":
5389
+ return { type: "phantom-ethereum", name: "Phantom", icon: "phantom" };
5390
+ case "coinbase":
5391
+ return { type: "coinbase", name: "Coinbase Wallet", icon: "coinbase" };
5392
+ case "okx":
5393
+ return { type: "okx", name: "OKX Wallet", icon: "okx" };
5394
+ case "rabby":
5395
+ return { type: "rabby", name: "Rabby", icon: "rabby" };
5396
+ case "trust":
5397
+ return { type: "trust", name: "Trust Wallet", icon: "trust" };
5398
+ case "rainbow":
5399
+ return { type: "rainbow", name: "Rainbow", icon: "rainbow" };
5400
+ }
5401
+ const anyProvider = provider;
5402
+ if (provider.isPhantom) {
5403
+ return { type: "phantom-ethereum", name: "Phantom", icon: "phantom" };
5404
+ }
5405
+ if (anyProvider.isCoinbaseWallet) {
5406
+ return { type: "coinbase", name: "Coinbase Wallet", icon: "coinbase" };
5407
+ }
5408
+ if (anyProvider.isRabby) {
5409
+ return { type: "rabby", name: "Rabby", icon: "rabby" };
5410
+ }
5411
+ if (anyProvider.isTrust) {
5412
+ return { type: "trust", name: "Trust Wallet", icon: "trust" };
5413
+ }
5414
+ if (anyProvider.isRainbow) {
5415
+ return { type: "rainbow", name: "Rainbow", icon: "rainbow" };
5416
+ }
5417
+ if (provider.isMetaMask && !provider.isPhantom) {
5418
+ return { type: "metamask", name: "MetaMask", icon: "metamask" };
5419
+ }
5420
+ return { type: "metamask", name: "Wallet", icon: "metamask" };
5421
+ }
5422
+ async function detectConnectedBrowserWallet(chainType) {
5423
+ if (typeof window === "undefined") return null;
5424
+ if (getUserDisconnectedWallet()) return null;
5425
+ try {
5426
+ const win = window;
5427
+ if (!chainType || chainType === "solana") {
5428
+ const trySilentSolana = async (provider, type, name, icon) => {
5429
+ if (!provider) return null;
5430
+ if (provider.isConnected && provider.publicKey) {
5431
+ return { type, name, address: provider.publicKey.toString(), icon };
5432
+ }
5433
+ try {
5434
+ const resp = await provider.connect({ onlyIfTrusted: true });
5435
+ if (resp.publicKey) {
5436
+ return { type, name, address: resp.publicKey.toString(), icon };
5437
+ }
5438
+ } catch {
5439
+ }
5440
+ return null;
5441
+ };
5442
+ const solanaCandidates = [
5443
+ [win.phantom?.solana, "phantom-solana", "Phantom", "phantom"],
5444
+ [win.solflare, "solflare", "Solflare", "solflare"],
5445
+ [win.backpack, "backpack", "Backpack", "backpack"],
5446
+ [win.glow, "glow", "Glow", "glow"]
5447
+ ];
5448
+ for (const [provider, type, name, icon] of solanaCandidates) {
5449
+ const found = await trySilentSolana(provider, type, name, icon);
5450
+ if (found) return found;
5451
+ }
5452
+ }
5453
+ if (!chainType || chainType === "ethereum") {
5454
+ const allProviders = [];
5455
+ const eip6963 = getEip6963Providers();
5456
+ for (const { provider, walletId } of eip6963) {
5457
+ allProviders.push({
5458
+ provider,
5459
+ walletId: walletId === "unknown" ? "default" : walletId
5460
+ });
5461
+ }
5462
+ if (allProviders.length === 0) {
5463
+ if (win.phantom?.ethereum) {
5464
+ allProviders.push({ provider: win.phantom.ethereum, walletId: "phantom" });
5465
+ }
5466
+ if (win.okxwallet) {
5467
+ allProviders.push({ provider: win.okxwallet, walletId: "okx" });
5468
+ }
5469
+ if (win.coinbaseWalletExtension) {
5470
+ allProviders.push({ provider: win.coinbaseWalletExtension, walletId: "coinbase" });
5471
+ }
5472
+ if (win.ethereum && !allProviders.some((p) => p.provider === win.ethereum)) {
5473
+ allProviders.push({ provider: win.ethereum, walletId: "default" });
5474
+ }
5475
+ }
5476
+ for (const { provider, walletId } of allProviders) {
5477
+ if (!provider) continue;
5478
+ try {
5479
+ const accounts = await provider.request({ method: "eth_accounts" });
5480
+ if (!accounts || accounts.length === 0) continue;
5481
+ const resolved = identifyEthWallet(provider, walletId);
5482
+ return { ...resolved, address: accounts[0] };
5483
+ } catch {
5484
+ }
5485
+ }
5486
+ }
5487
+ } catch (error) {
5488
+ console.error("[detectConnectedBrowserWallet] detection error:", error);
5489
+ }
5490
+ return null;
5491
+ }
5492
+
5493
+ // src/components/deposits/browser-wallets/useDetectedBrowserWallet.ts
5494
+ function useDetectedBrowserWallet(opts = {}) {
5495
+ const { chainType, enabled = true, onDisconnect } = opts;
5496
+ const [wallet, setWallet] = React12.useState(null);
5497
+ const [isLoading, setIsLoading] = React12.useState(enabled);
5498
+ const [eip6963ProviderCount, setEip6963ProviderCount] = React12.useState(0);
5499
+ const onDisconnectRef = React12.useRef(onDisconnect);
5500
+ onDisconnectRef.current = onDisconnect;
5501
+ React12.useEffect(() => {
5502
+ const store = getEip6963Store();
5503
+ if (!store) return;
5504
+ setEip6963ProviderCount(store.getProviders().length);
5505
+ return store.subscribe((providers) => setEip6963ProviderCount(providers.length));
5506
+ }, []);
5507
+ React12.useEffect(() => {
5508
+ if (!enabled) {
5509
+ setWallet(null);
5510
+ setIsLoading(false);
5511
+ return;
5512
+ }
5513
+ let mounted = true;
5514
+ const detect = async () => {
5515
+ if (!mounted) return;
5516
+ setIsLoading(true);
5517
+ const detected = await detectConnectedBrowserWallet(chainType);
5518
+ if (!mounted) return;
5519
+ setWallet(detected);
5520
+ setIsLoading(false);
5521
+ };
5522
+ detect();
5523
+ const onChange = () => detect();
5524
+ const onDisc = () => {
5525
+ onDisconnectRef.current?.();
5526
+ detect();
5527
+ };
5528
+ const onEthAccounts = (accounts) => {
5529
+ if (Array.isArray(accounts) && accounts.length === 0) onDisconnectRef.current?.();
5530
+ detect();
5531
+ };
5532
+ const win = typeof window !== "undefined" ? window : void 0;
5533
+ const solanaProvider = win?.phantom?.solana || win?.solana;
5534
+ if (solanaProvider) {
5535
+ solanaProvider.on("connect", onChange);
5536
+ solanaProvider.on("disconnect", onDisc);
5537
+ solanaProvider.on("accountChanged", onChange);
5538
+ }
5539
+ const ethProviders = [];
5540
+ for (const { provider } of getEip6963Providers()) {
5541
+ const p = provider;
5542
+ if (p && !ethProviders.includes(p)) ethProviders.push(p);
5543
+ }
5544
+ if (win?.ethereum && !ethProviders.includes(win.ethereum)) ethProviders.push(win.ethereum);
5545
+ if (win?.phantom?.ethereum && !ethProviders.includes(win.phantom.ethereum)) {
5546
+ ethProviders.push(win.phantom.ethereum);
5547
+ }
5548
+ for (const p of ethProviders) {
5549
+ p.on("accountsChanged", onEthAccounts);
5550
+ p.on("chainChanged", onChange);
5551
+ }
5552
+ return () => {
5553
+ mounted = false;
5554
+ if (solanaProvider) {
5555
+ solanaProvider.off?.("connect", onChange);
5556
+ solanaProvider.off?.("disconnect", onDisc);
5557
+ solanaProvider.off?.("accountChanged", onChange);
5558
+ }
5559
+ for (const p of ethProviders) {
5560
+ const off = p.off?.bind(p) ?? p.removeListener?.bind(p);
5561
+ if (off) {
5562
+ off("accountsChanged", onEthAccounts);
5563
+ off("chainChanged", onChange);
5564
+ }
5565
+ }
5566
+ };
5567
+ }, [chainType, eip6963ProviderCount, enabled]);
5568
+ return { wallet, isLoading, setWallet };
5569
+ }
5570
+
5380
5571
  // src/components/deposits/browser-wallets/disconnectInjectedBrowserWallet.ts
5381
5572
  var SOLANA_DISCONNECT_TYPES = [
5382
5573
  "phantom-solana",
@@ -5462,14 +5653,14 @@ async function disconnectInjectedBrowserWallet(wallet) {
5462
5653
  }
5463
5654
 
5464
5655
  // src/resources/icons/MetamaskIcon.tsx
5465
- var React12 = __toESM(require("react"));
5656
+ var React13 = __toESM(require("react"));
5466
5657
  var import_jsx_runtime23 = require("react/jsx-runtime");
5467
5658
  function MetamaskIcon({
5468
5659
  size = 24,
5469
5660
  className,
5470
5661
  variant = "color"
5471
5662
  }) {
5472
- const id = React12.useId();
5663
+ const id = React13.useId();
5473
5664
  if (variant === "light" || variant === "dark") {
5474
5665
  return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
5475
5666
  "svg",
@@ -5591,14 +5782,14 @@ function MetamaskIcon({
5591
5782
  }
5592
5783
 
5593
5784
  // src/resources/icons/PhantomIcon.tsx
5594
- var React13 = __toESM(require("react"));
5785
+ var React14 = __toESM(require("react"));
5595
5786
  var import_jsx_runtime24 = require("react/jsx-runtime");
5596
5787
  function PhantomIcon({
5597
5788
  size = 24,
5598
5789
  className,
5599
5790
  variant = "color"
5600
5791
  }) {
5601
- const id = React13.useId();
5792
+ const id = React14.useId();
5602
5793
  if (variant === "light") {
5603
5794
  return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5604
5795
  "svg",
@@ -5666,14 +5857,14 @@ function PhantomIcon({
5666
5857
  }
5667
5858
 
5668
5859
  // src/resources/icons/CoinbaseIcon.tsx
5669
- var React14 = __toESM(require("react"));
5860
+ var React15 = __toESM(require("react"));
5670
5861
  var import_jsx_runtime25 = require("react/jsx-runtime");
5671
5862
  function CoinbaseIcon({
5672
5863
  size = 24,
5673
5864
  className,
5674
5865
  variant = "color"
5675
5866
  }) {
5676
- const id = React14.useId();
5867
+ const id = React15.useId();
5677
5868
  if (variant === "light") {
5678
5869
  return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
5679
5870
  "svg",
@@ -5754,14 +5945,14 @@ function CoinbaseIcon({
5754
5945
  }
5755
5946
 
5756
5947
  // src/resources/icons/RabbyIcon.tsx
5757
- var React15 = __toESM(require("react"));
5948
+ var React16 = __toESM(require("react"));
5758
5949
  var import_jsx_runtime26 = require("react/jsx-runtime");
5759
5950
  function RabbyIcon({
5760
5951
  size = 24,
5761
5952
  className,
5762
5953
  variant = "color"
5763
5954
  }) {
5764
- const id = React15.useId();
5955
+ const id = React16.useId();
5765
5956
  if (variant === "light") {
5766
5957
  return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
5767
5958
  "svg",
@@ -6109,14 +6300,14 @@ function RabbyIcon({
6109
6300
  }
6110
6301
 
6111
6302
  // src/resources/icons/RainbowIcon.tsx
6112
- var React16 = __toESM(require("react"));
6303
+ var React17 = __toESM(require("react"));
6113
6304
  var import_jsx_runtime27 = require("react/jsx-runtime");
6114
6305
  function RainbowIcon({
6115
6306
  size = 24,
6116
6307
  className,
6117
6308
  variant = "color"
6118
6309
  }) {
6119
- const id = React16.useId();
6310
+ const id = React17.useId();
6120
6311
  if (variant === "light") {
6121
6312
  return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
6122
6313
  "svg",
@@ -6579,14 +6770,14 @@ function RainbowIcon({
6579
6770
  }
6580
6771
 
6581
6772
  // src/resources/icons/TrustIcon.tsx
6582
- var React17 = __toESM(require("react"));
6773
+ var React18 = __toESM(require("react"));
6583
6774
  var import_jsx_runtime28 = require("react/jsx-runtime");
6584
6775
  function TrustIcon({
6585
6776
  size = 24,
6586
6777
  className,
6587
6778
  variant = "color"
6588
6779
  }) {
6589
- const id = React17.useId();
6780
+ const id = React18.useId();
6590
6781
  if (variant === "light") {
6591
6782
  return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
6592
6783
  "svg",
@@ -6676,14 +6867,14 @@ function TrustIcon({
6676
6867
  }
6677
6868
 
6678
6869
  // src/resources/icons/OkxIcon.tsx
6679
- var React18 = __toESM(require("react"));
6870
+ var React19 = __toESM(require("react"));
6680
6871
  var import_jsx_runtime29 = require("react/jsx-runtime");
6681
6872
  function OkxIcon({
6682
6873
  size = 24,
6683
6874
  className,
6684
6875
  variant = "color"
6685
6876
  }) {
6686
- const id = React18.useId();
6877
+ const id = React19.useId();
6687
6878
  if (variant === "light") {
6688
6879
  return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6689
6880
  "svg",
@@ -6751,14 +6942,14 @@ function OkxIcon({
6751
6942
  }
6752
6943
 
6753
6944
  // src/resources/icons/GlowIcon.tsx
6754
- var React19 = __toESM(require("react"));
6945
+ var React20 = __toESM(require("react"));
6755
6946
  var import_jsx_runtime30 = require("react/jsx-runtime");
6756
6947
  function GlowIcon({
6757
6948
  size = 24,
6758
6949
  className,
6759
6950
  variant = "color"
6760
6951
  }) {
6761
- const id = React19.useId();
6952
+ const id = React20.useId();
6762
6953
  if (variant === "light") {
6763
6954
  return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6764
6955
  "svg",
@@ -6860,14 +7051,14 @@ function GlowIcon({
6860
7051
  }
6861
7052
 
6862
7053
  // src/resources/icons/BackpackIcon.tsx
6863
- var React20 = __toESM(require("react"));
7054
+ var React21 = __toESM(require("react"));
6864
7055
  var import_jsx_runtime31 = require("react/jsx-runtime");
6865
7056
  function BackpackIcon({
6866
7057
  size = 24,
6867
7058
  className,
6868
7059
  variant = "color"
6869
7060
  }) {
6870
- const id = React20.useId();
7061
+ const id = React21.useId();
6871
7062
  if (variant === "light") {
6872
7063
  return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
6873
7064
  "svg",
@@ -6941,14 +7132,14 @@ function BackpackIcon({
6941
7132
  }
6942
7133
 
6943
7134
  // src/resources/icons/SolflareIcon.tsx
6944
- var React21 = __toESM(require("react"));
7135
+ var React22 = __toESM(require("react"));
6945
7136
  var import_jsx_runtime32 = require("react/jsx-runtime");
6946
7137
  function SolflareIcon({
6947
7138
  size = 24,
6948
7139
  className,
6949
7140
  variant = "color"
6950
7141
  }) {
6951
- const id = React21.useId();
7142
+ const id = React22.useId();
6952
7143
  if (variant === "light") {
6953
7144
  return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6954
7145
  "svg",
@@ -7016,14 +7207,14 @@ function SolflareIcon({
7016
7207
  }
7017
7208
 
7018
7209
  // src/resources/icons/EthereumIcon.tsx
7019
- var React22 = __toESM(require("react"));
7210
+ var React23 = __toESM(require("react"));
7020
7211
  var import_jsx_runtime33 = require("react/jsx-runtime");
7021
7212
  function EthereumIcon({
7022
7213
  size = 24,
7023
7214
  className,
7024
7215
  variant = "color"
7025
7216
  }) {
7026
- const id = React22.useId();
7217
+ const id = React23.useId();
7027
7218
  if (variant === "light") {
7028
7219
  return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
7029
7220
  "svg",
@@ -7154,14 +7345,14 @@ function EthereumIcon({
7154
7345
  }
7155
7346
 
7156
7347
  // src/resources/icons/SolanaIcon.tsx
7157
- var React23 = __toESM(require("react"));
7348
+ var React24 = __toESM(require("react"));
7158
7349
  var import_jsx_runtime34 = require("react/jsx-runtime");
7159
7350
  function SolanaIcon({
7160
7351
  size = 24,
7161
7352
  className,
7162
7353
  variant = "color"
7163
7354
  }) {
7164
- const id = React23.useId();
7355
+ const id = React24.useId();
7165
7356
  if (variant === "light") {
7166
7357
  return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
7167
7358
  "svg",
@@ -7416,44 +7607,6 @@ function truncateAddress3(address) {
7416
7607
  if (address.length <= 10) return address;
7417
7608
  return `${address.slice(0, 4)}...${address.slice(-4)}`;
7418
7609
  }
7419
- function identifyEthWallet(provider, _win, hint) {
7420
- switch (hint) {
7421
- case "metamask":
7422
- return { type: "metamask", name: "MetaMask", icon: "metamask" };
7423
- case "phantom":
7424
- return { type: "phantom-ethereum", name: "Phantom", icon: "phantom" };
7425
- case "coinbase":
7426
- return { type: "coinbase", name: "Coinbase Wallet", icon: "coinbase" };
7427
- case "okx":
7428
- return { type: "okx", name: "OKX Wallet", icon: "okx" };
7429
- case "rabby":
7430
- return { type: "rabby", name: "Rabby", icon: "rabby" };
7431
- case "trust":
7432
- return { type: "trust", name: "Trust Wallet", icon: "trust" };
7433
- case "rainbow":
7434
- return { type: "rainbow", name: "Rainbow", icon: "rainbow" };
7435
- }
7436
- const anyProvider = provider;
7437
- if (provider.isPhantom) {
7438
- return { type: "phantom-ethereum", name: "Phantom", icon: "phantom" };
7439
- }
7440
- if (anyProvider.isCoinbaseWallet) {
7441
- return { type: "coinbase", name: "Coinbase Wallet", icon: "coinbase" };
7442
- }
7443
- if (anyProvider.isRabby) {
7444
- return { type: "rabby", name: "Rabby", icon: "rabby" };
7445
- }
7446
- if (anyProvider.isTrust) {
7447
- return { type: "trust", name: "Trust Wallet", icon: "trust" };
7448
- }
7449
- if (anyProvider.isRainbow) {
7450
- return { type: "rainbow", name: "Rainbow", icon: "rainbow" };
7451
- }
7452
- if (provider.isMetaMask && !provider.isPhantom) {
7453
- return { type: "metamask", name: "MetaMask", icon: "metamask" };
7454
- }
7455
- return { type: "metamask", name: "Wallet", icon: "metamask" };
7456
- }
7457
7610
  function BrowserWalletButton({
7458
7611
  onClick,
7459
7612
  onConnectClick,
@@ -7464,30 +7617,19 @@ function BrowserWalletButton({
7464
7617
  subtitle = i18n.depositModal.browserWallet.subtitle
7465
7618
  }) {
7466
7619
  const { colors: colors2, fonts, components } = useTheme();
7467
- const [isHovered, setIsHovered] = React24.useState(false);
7468
- const [isTouchDevice, setIsTouchDevice] = React24.useState(false);
7469
- const [wallet, setWallet] = React24.useState(null);
7470
- const [isLoading, setIsLoading] = React24.useState(true);
7471
- const [isConnecting, setIsConnecting] = React24.useState(false);
7472
- const [balanceText, setBalanceText] = React24.useState(null);
7473
- const [isLoadingBalance, setIsLoadingBalance] = React24.useState(false);
7474
- const [isDisconnecting, setIsDisconnecting] = React24.useState(false);
7475
- const onDisconnectRef = React24.useRef(onDisconnect);
7620
+ const [isHovered, setIsHovered] = React25.useState(false);
7621
+ const [isTouchDevice, setIsTouchDevice] = React25.useState(false);
7622
+ const { wallet, isLoading, setWallet } = useDetectedBrowserWallet({ chainType, onDisconnect });
7623
+ const [isConnecting, setIsConnecting] = React25.useState(false);
7624
+ const [balanceText, setBalanceText] = React25.useState(null);
7625
+ const [isLoadingBalance, setIsLoadingBalance] = React25.useState(false);
7626
+ const [isDisconnecting, setIsDisconnecting] = React25.useState(false);
7627
+ const onDisconnectRef = React25.useRef(onDisconnect);
7476
7628
  onDisconnectRef.current = onDisconnect;
7477
- React24.useEffect(() => {
7629
+ React25.useEffect(() => {
7478
7630
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
7479
7631
  }, []);
7480
- const [eip6963ProviderCount, setEip6963ProviderCount] = React24.useState(0);
7481
- React24.useEffect(() => {
7482
- const store = getEip6963Store();
7483
- if (!store) return;
7484
- setEip6963ProviderCount(store.getProviders().length);
7485
- const unsubscribe = store.subscribe((providers) => {
7486
- setEip6963ProviderCount(providers.length);
7487
- });
7488
- return unsubscribe;
7489
- }, []);
7490
- React24.useEffect(() => {
7632
+ React25.useEffect(() => {
7491
7633
  if (!wallet || !publishableKey) {
7492
7634
  setBalanceText(null);
7493
7635
  return;
@@ -7528,206 +7670,6 @@ function BrowserWalletButton({
7528
7670
  cancelled = true;
7529
7671
  };
7530
7672
  }, [wallet, publishableKey]);
7531
- React24.useEffect(() => {
7532
- let mounted = true;
7533
- const detectWallet = async () => {
7534
- if (!mounted) return;
7535
- setIsLoading(true);
7536
- try {
7537
- const win = typeof window !== "undefined" ? window : null;
7538
- if (!win) return;
7539
- if (getUserDisconnectedWallet()) {
7540
- if (mounted) {
7541
- setWallet(null);
7542
- setIsLoading(false);
7543
- }
7544
- return;
7545
- }
7546
- if (!chainType || chainType === "solana") {
7547
- const anyWin = win;
7548
- const trySilentSolana = async (provider, type, name, icon) => {
7549
- if (!provider) return false;
7550
- if (provider.isConnected && provider.publicKey) {
7551
- if (mounted) {
7552
- setWallet({
7553
- type,
7554
- name,
7555
- address: provider.publicKey.toString(),
7556
- icon
7557
- });
7558
- setIsLoading(false);
7559
- }
7560
- return true;
7561
- }
7562
- try {
7563
- const resp = await provider.connect({ onlyIfTrusted: true });
7564
- if (mounted && resp.publicKey) {
7565
- setWallet({
7566
- type,
7567
- name,
7568
- address: resp.publicKey.toString(),
7569
- icon
7570
- });
7571
- setIsLoading(false);
7572
- return true;
7573
- }
7574
- } catch {
7575
- }
7576
- return false;
7577
- };
7578
- if (await trySilentSolana(
7579
- win.phantom?.solana,
7580
- "phantom-solana",
7581
- "Phantom",
7582
- "phantom"
7583
- ))
7584
- return;
7585
- if (await trySilentSolana(
7586
- anyWin.solflare,
7587
- "solflare",
7588
- "Solflare",
7589
- "solflare"
7590
- ))
7591
- return;
7592
- if (await trySilentSolana(
7593
- anyWin.backpack,
7594
- "backpack",
7595
- "Backpack",
7596
- "backpack"
7597
- ))
7598
- return;
7599
- if (await trySilentSolana(
7600
- anyWin.glow,
7601
- "glow",
7602
- "Glow",
7603
- "glow"
7604
- ))
7605
- return;
7606
- }
7607
- if (!chainType || chainType === "ethereum") {
7608
- const anyWin = win;
7609
- const allProviders = [];
7610
- const eip6963 = getEip6963Providers();
7611
- for (const { provider, walletId } of eip6963) {
7612
- allProviders.push({
7613
- provider,
7614
- walletId: walletId === "unknown" ? "default" : walletId
7615
- });
7616
- }
7617
- if (allProviders.length === 0) {
7618
- if (win.phantom?.ethereum) {
7619
- allProviders.push({
7620
- provider: win.phantom.ethereum,
7621
- walletId: "phantom"
7622
- });
7623
- }
7624
- if (anyWin.okxwallet) {
7625
- allProviders.push({
7626
- provider: anyWin.okxwallet,
7627
- walletId: "okx"
7628
- });
7629
- }
7630
- if (anyWin.coinbaseWalletExtension) {
7631
- allProviders.push({
7632
- provider: anyWin.coinbaseWalletExtension,
7633
- walletId: "coinbase"
7634
- });
7635
- }
7636
- if (win.ethereum) {
7637
- const isDuplicate = allProviders.some(
7638
- (p) => p.provider === win.ethereum
7639
- );
7640
- if (!isDuplicate) {
7641
- allProviders.push({
7642
- provider: win.ethereum,
7643
- walletId: "default"
7644
- });
7645
- }
7646
- }
7647
- }
7648
- for (const { provider, walletId } of allProviders) {
7649
- if (!provider) continue;
7650
- try {
7651
- const accounts = await provider.request({
7652
- method: "eth_accounts"
7653
- });
7654
- if (!accounts || accounts.length === 0) continue;
7655
- const address = accounts[0];
7656
- const resolved = identifyEthWallet(provider, anyWin, walletId);
7657
- if (mounted) {
7658
- setWallet({ ...resolved, address });
7659
- setIsLoading(false);
7660
- }
7661
- return;
7662
- } catch {
7663
- }
7664
- }
7665
- }
7666
- if (mounted) {
7667
- setWallet(null);
7668
- setIsLoading(false);
7669
- }
7670
- } catch (error) {
7671
- console.error("[BrowserWalletButton] Error detecting wallet:", error);
7672
- if (mounted) {
7673
- setWallet(null);
7674
- setIsLoading(false);
7675
- }
7676
- }
7677
- };
7678
- detectWallet();
7679
- const handleAccountsChanged = () => {
7680
- detectWallet();
7681
- };
7682
- const handleDisconnect = () => {
7683
- onDisconnectRef.current?.();
7684
- detectWallet();
7685
- };
7686
- const handleEthAccountsChanged = (accounts) => {
7687
- if (Array.isArray(accounts) && accounts.length === 0) {
7688
- onDisconnectRef.current?.();
7689
- }
7690
- detectWallet();
7691
- };
7692
- const solanaProvider = window.phantom?.solana || window.solana;
7693
- if (solanaProvider) {
7694
- solanaProvider.on("connect", handleAccountsChanged);
7695
- solanaProvider.on("disconnect", handleDisconnect);
7696
- solanaProvider.on("accountChanged", handleAccountsChanged);
7697
- }
7698
- const ethProviders = [];
7699
- for (const { provider } of getEip6963Providers()) {
7700
- const p = provider;
7701
- if (p && !ethProviders.includes(p)) {
7702
- ethProviders.push(p);
7703
- }
7704
- }
7705
- if (window.ethereum && !ethProviders.includes(window.ethereum)) {
7706
- ethProviders.push(window.ethereum);
7707
- }
7708
- if (window.phantom?.ethereum && !ethProviders.includes(window.phantom.ethereum)) {
7709
- ethProviders.push(window.phantom.ethereum);
7710
- }
7711
- for (const provider of ethProviders) {
7712
- provider.on("accountsChanged", handleEthAccountsChanged);
7713
- provider.on("chainChanged", handleAccountsChanged);
7714
- }
7715
- return () => {
7716
- mounted = false;
7717
- if (solanaProvider) {
7718
- solanaProvider.off("connect", handleAccountsChanged);
7719
- solanaProvider.off("disconnect", handleDisconnect);
7720
- solanaProvider.off("accountChanged", handleAccountsChanged);
7721
- }
7722
- for (const provider of ethProviders) {
7723
- const off = provider.off?.bind(provider) ?? provider.removeListener?.bind(provider);
7724
- if (off) {
7725
- off("accountsChanged", handleEthAccountsChanged);
7726
- off("chainChanged", handleAccountsChanged);
7727
- }
7728
- }
7729
- };
7730
- }, [chainType, eip6963ProviderCount]);
7731
7673
  const handleConnect = async () => {
7732
7674
  if (wallet) {
7733
7675
  onClick(wallet);
@@ -7811,7 +7753,7 @@ function BrowserWalletButton({
7811
7753
  border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
7812
7754
  };
7813
7755
  const sortedWallets = featuredWallets ? [...featuredWallets].sort((a, b) => a.position - b.position) : [];
7814
- const walletIconBlock = wallet ? WALLET_ICON_COMPONENTS[wallet.icon] ? React24.createElement(WALLET_ICON_COMPONENTS[wallet.icon], {
7756
+ const walletIconBlock = wallet ? WALLET_ICON_COMPONENTS[wallet.icon] ? React25.createElement(WALLET_ICON_COMPONENTS[wallet.icon], {
7815
7757
  size: 36,
7816
7758
  className: "uf-rounded-lg",
7817
7759
  variant: "color"
@@ -8095,6 +8037,7 @@ function CoinbaseConnect({
8095
8037
  onBack: parentOnBack,
8096
8038
  onDisconnect,
8097
8039
  skipToHoldings,
8040
+ canGoBack = true,
8098
8041
  onExecutionsChange
8099
8042
  }) {
8100
8043
  const { colors: colors2, fonts, components } = useTheme();
@@ -8482,6 +8425,16 @@ function CoinbaseConnect({
8482
8425
  setIsLoading(false);
8483
8426
  }
8484
8427
  };
8428
+ const handleDisconnect = () => {
8429
+ onDisconnect?.();
8430
+ if (!canGoBack) {
8431
+ setAccessToken(null);
8432
+ setHoldings([]);
8433
+ setSelectedHolding(null);
8434
+ setSelectedAsset(null);
8435
+ transitionTo("select_exchange");
8436
+ }
8437
+ };
8485
8438
  const handleBack = () => {
8486
8439
  switch (view) {
8487
8440
  case "select_exchange":
@@ -8542,7 +8495,7 @@ function CoinbaseConnect({
8542
8495
  DepositHeader,
8543
8496
  {
8544
8497
  title: t12.title,
8545
- showBack: true,
8498
+ showBack: canGoBack,
8546
8499
  onBack: handleBack,
8547
8500
  onClose
8548
8501
  }
@@ -8555,7 +8508,7 @@ function CoinbaseConnect({
8555
8508
  DepositHeader,
8556
8509
  {
8557
8510
  title: t12.title,
8558
- showBack: true,
8511
+ showBack: canGoBack,
8559
8512
  onBack: handleBack,
8560
8513
  onClose
8561
8514
  }
@@ -9267,7 +9220,7 @@ function CoinbaseConnect({
9267
9220
  borderRadius: components.button.borderRadius,
9268
9221
  fontFamily: fonts.medium
9269
9222
  },
9270
- onClick: onDisconnect,
9223
+ onClick: handleDisconnect,
9271
9224
  children: t12.disconnect
9272
9225
  }
9273
9226
  )
@@ -10077,14 +10030,14 @@ var import_lucide_react22 = require("lucide-react");
10077
10030
  var import_react13 = require("react");
10078
10031
 
10079
10032
  // src/components/shared/ThemeStyleInjector.tsx
10080
- var React26 = __toESM(require("react"));
10033
+ var React27 = __toESM(require("react"));
10081
10034
  var import_jsx_runtime38 = require("react/jsx-runtime");
10082
10035
  function ThemeStyleInjector({
10083
10036
  children,
10084
10037
  className
10085
10038
  }) {
10086
10039
  const { colors: colors2, fonts, mode } = useTheme();
10087
- const cssVars = React26.useMemo(() => {
10040
+ const cssVars = React27.useMemo(() => {
10088
10041
  const hexToHSL = (hex) => {
10089
10042
  hex = hex.replace("#", "");
10090
10043
  const r = parseInt(hex.slice(0, 2), 16) / 255;
@@ -10144,7 +10097,7 @@ function ThemeStyleInjector({
10144
10097
  ...fonts.regular ? { "--uf-font-family": fonts.regular } : {}
10145
10098
  };
10146
10099
  }, [colors2, fonts.regular]);
10147
- React26.useEffect(() => {
10100
+ React27.useEffect(() => {
10148
10101
  if (typeof document === "undefined") return;
10149
10102
  if (fonts.regular) {
10150
10103
  document.documentElement.style.setProperty(
@@ -11132,7 +11085,7 @@ function useCopyAddress() {
11132
11085
  }
11133
11086
 
11134
11087
  // src/components/shared/tooltip.tsx
11135
- var React27 = __toESM(require("react"));
11088
+ var React28 = __toESM(require("react"));
11136
11089
  var TooltipPrimitive = __toESM(require("@radix-ui/react-tooltip"));
11137
11090
  var import_jsx_runtime44 = require("react/jsx-runtime");
11138
11091
  var TooltipProvider = TooltipPrimitive.Provider;
@@ -11140,7 +11093,7 @@ function Tooltip({
11140
11093
  children,
11141
11094
  ...props
11142
11095
  }) {
11143
- const [open, setOpen] = React27.useState(props.defaultOpen ?? false);
11096
+ const [open, setOpen] = React28.useState(props.defaultOpen ?? false);
11144
11097
  const isControlled = props.open !== void 0;
11145
11098
  const isOpen = isControlled ? props.open : open;
11146
11099
  const onOpenChange = isControlled ? props.onOpenChange : (nextOpen) => setOpen(nextOpen);
@@ -11160,14 +11113,14 @@ function Tooltip({
11160
11113
  }
11161
11114
  );
11162
11115
  }
11163
- var TooltipContext = React27.createContext({
11116
+ var TooltipContext = React28.createContext({
11164
11117
  open: false,
11165
11118
  onOpenChange: () => {
11166
11119
  }
11167
11120
  });
11168
- var TooltipTrigger = React27.forwardRef(({ onClick, ...props }, ref) => {
11169
- const { open, onOpenChange } = React27.useContext(TooltipContext);
11170
- const handleClick = React27.useCallback(
11121
+ var TooltipTrigger = React28.forwardRef(({ onClick, ...props }, ref) => {
11122
+ const { open, onOpenChange } = React28.useContext(TooltipContext);
11123
+ const handleClick = React28.useCallback(
11171
11124
  (e) => {
11172
11125
  onOpenChange(!open);
11173
11126
  onClick?.(e);
@@ -11177,7 +11130,7 @@ var TooltipTrigger = React27.forwardRef(({ onClick, ...props }, ref) => {
11177
11130
  return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(TooltipPrimitive.Trigger, { ref, onClick: handleClick, ...props });
11178
11131
  });
11179
11132
  TooltipTrigger.displayName = TooltipPrimitive.Trigger.displayName;
11180
- var TooltipContent = React27.forwardRef(({ className, sideOffset = 4, ...props }, ref) => {
11133
+ var TooltipContent = React28.forwardRef(({ className, sideOffset = 4, ...props }, ref) => {
11181
11134
  const { themeClass, colors: colors2 } = useTheme();
11182
11135
  return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(TooltipPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
11183
11136
  TooltipPrimitive.Content,
@@ -11804,14 +11757,14 @@ var import_react18 = require("react");
11804
11757
  var import_lucide_react24 = require("lucide-react");
11805
11758
 
11806
11759
  // src/components/shared/select.tsx
11807
- var React28 = __toESM(require("react"));
11760
+ var React29 = __toESM(require("react"));
11808
11761
  var SelectPrimitive = __toESM(require("@radix-ui/react-select"));
11809
11762
  var import_lucide_react23 = require("lucide-react");
11810
11763
  var import_jsx_runtime47 = require("react/jsx-runtime");
11811
11764
  var Select = SelectPrimitive.Root;
11812
11765
  var SelectGroup = SelectPrimitive.Group;
11813
11766
  var SelectValue = SelectPrimitive.Value;
11814
- var SelectTrigger = React28.forwardRef(({ className, style, children, ...props }, ref) => {
11767
+ var SelectTrigger = React29.forwardRef(({ className, style, children, ...props }, ref) => {
11815
11768
  const { components } = useTheme();
11816
11769
  return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
11817
11770
  SelectPrimitive.Trigger,
@@ -11835,7 +11788,7 @@ var SelectTrigger = React28.forwardRef(({ className, style, children, ...props }
11835
11788
  );
11836
11789
  });
11837
11790
  SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
11838
- var SelectScrollUpButton = React28.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
11791
+ var SelectScrollUpButton = React29.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
11839
11792
  SelectPrimitive.ScrollUpButton,
11840
11793
  {
11841
11794
  ref,
@@ -11848,7 +11801,7 @@ var SelectScrollUpButton = React28.forwardRef(({ className, ...props }, ref) =>
11848
11801
  }
11849
11802
  ));
11850
11803
  SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
11851
- var SelectScrollDownButton = React28.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
11804
+ var SelectScrollDownButton = React29.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
11852
11805
  SelectPrimitive.ScrollDownButton,
11853
11806
  {
11854
11807
  ref,
@@ -11861,7 +11814,7 @@ var SelectScrollDownButton = React28.forwardRef(({ className, ...props }, ref) =
11861
11814
  }
11862
11815
  ));
11863
11816
  SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
11864
- var SelectContent = React28.forwardRef(({ className, style, children, position = "popper", ...props }, ref) => {
11817
+ var SelectContent = React29.forwardRef(({ className, style, children, position = "popper", ...props }, ref) => {
11865
11818
  const { themeClass, colors: colors2, components } = useTheme();
11866
11819
  return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(SelectPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
11867
11820
  SelectPrimitive.Content,
@@ -11899,7 +11852,7 @@ var SelectContent = React28.forwardRef(({ className, style, children, position =
11899
11852
  ) });
11900
11853
  });
11901
11854
  SelectContent.displayName = SelectPrimitive.Content.displayName;
11902
- var SelectLabel = React28.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
11855
+ var SelectLabel = React29.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
11903
11856
  SelectPrimitive.Label,
11904
11857
  {
11905
11858
  ref,
@@ -11911,7 +11864,7 @@ var SelectLabel = React28.forwardRef(({ className, ...props }, ref) => /* @__PUR
11911
11864
  }
11912
11865
  ));
11913
11866
  SelectLabel.displayName = SelectPrimitive.Label.displayName;
11914
- var SelectItem = React28.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
11867
+ var SelectItem = React29.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
11915
11868
  SelectPrimitive.Item,
11916
11869
  {
11917
11870
  ref,
@@ -11927,7 +11880,7 @@ var SelectItem = React28.forwardRef(({ className, children, ...props }, ref) =>
11927
11880
  }
11928
11881
  ));
11929
11882
  SelectItem.displayName = SelectPrimitive.Item.displayName;
11930
- var SelectSeparator = React28.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
11883
+ var SelectSeparator = React29.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
11931
11884
  SelectPrimitive.Separator,
11932
11885
  {
11933
11886
  ref,
@@ -12385,7 +12338,7 @@ function TransferCryptoDoubleInput({
12385
12338
  }
12386
12339
 
12387
12340
  // src/components/deposits/WalletConnect.tsx
12388
- var React29 = __toESM(require("react"));
12341
+ var React30 = __toESM(require("react"));
12389
12342
  var import_lucide_react28 = require("lucide-react");
12390
12343
  var import_core28 = require("@unifold/core");
12391
12344
 
@@ -13628,22 +13581,27 @@ function WalletConnect({
13628
13581
  productType,
13629
13582
  onBack: parentOnBack,
13630
13583
  onClose,
13584
+ canGoBack = true,
13585
+ depositWalletsLoading = false,
13631
13586
  onExecutionsChange
13632
13587
  }) {
13633
13588
  const { colors: colors2, fonts, components } = useTheme();
13634
- const walletProvidedAtMount = React29.useRef(!!initialWalletInfo && !!initialDepositWallet);
13635
- const [activeWalletInfo, setActiveWalletInfo] = React29.useState(initialWalletInfo ?? null);
13636
- const [activeDepositWallet, setActiveDepositWallet] = React29.useState(initialDepositWallet ?? null);
13589
+ const walletProvidedAtMount = React30.useRef(!!initialWalletInfo && !!initialDepositWallet);
13590
+ const [activeWalletInfo, setActiveWalletInfo] = React30.useState(initialWalletInfo ?? null);
13591
+ const [activeDepositWallet, setActiveDepositWallet] = React30.useState(initialDepositWallet ?? null);
13637
13592
  const initialView = initialWalletInfo && initialDepositWallet ? "select_token" : "select_wallet";
13638
- const [view, setView] = React29.useState(initialView);
13639
- const [isTransitioning, setIsTransitioning] = React29.useState(false);
13640
- const viewRef = React29.useRef(initialView);
13641
- const [selectedWalletDef, setSelectedWalletDef] = React29.useState(null);
13642
- const [connectingNetwork, setConnectingNetwork] = React29.useState(null);
13643
- const [walletError, setWalletError] = React29.useState(null);
13644
- const [isWalletConnecting, setIsWalletConnecting] = React29.useState(false);
13645
- const [eip6963ProviderCount, setEip6963ProviderCount] = React29.useState(0);
13646
- React29.useEffect(() => {
13593
+ const [view, setView] = React30.useState(initialView);
13594
+ const [isTransitioning, setIsTransitioning] = React30.useState(false);
13595
+ const viewRef = React30.useRef(initialView);
13596
+ const standalone = !canGoBack && !walletProvidedAtMount.current;
13597
+ const { wallet: detectedWallet, isLoading: detectingWallet } = useDetectedBrowserWallet({ enabled: standalone });
13598
+ const [autoResolved, setAutoResolved] = React30.useState(false);
13599
+ const [selectedWalletDef, setSelectedWalletDef] = React30.useState(null);
13600
+ const [connectingNetwork, setConnectingNetwork] = React30.useState(null);
13601
+ const [walletError, setWalletError] = React30.useState(null);
13602
+ const [isWalletConnecting, setIsWalletConnecting] = React30.useState(false);
13603
+ const [eip6963ProviderCount, setEip6963ProviderCount] = React30.useState(0);
13604
+ React30.useEffect(() => {
13647
13605
  const store = getEip6963Store();
13648
13606
  if (!store) return;
13649
13607
  setEip6963ProviderCount(store.getProviders().length);
@@ -13651,20 +13609,44 @@ function WalletConnect({
13651
13609
  setEip6963ProviderCount(providers.length);
13652
13610
  });
13653
13611
  }, []);
13654
- const availableWallets = React29.useMemo(() => detectAvailableWallets(), [eip6963ProviderCount]);
13655
- const [balances, setBalances] = React29.useState([]);
13656
- const [isLoading, setIsLoading] = React29.useState(false);
13657
- const [selectedBalance, setSelectedBalance] = React29.useState(null);
13658
- const [totalBalanceUsd, setTotalBalanceUsd] = React29.useState(null);
13659
- const [error, setError] = React29.useState(null);
13660
- const [isDisconnectingWallet, setIsDisconnectingWallet] = React29.useState(false);
13661
- const [amountUsd, setAmountUsd] = React29.useState(prefillAmountUsd ?? "");
13662
- const [isConfirming, setIsConfirming] = React29.useState(false);
13663
- const [hasSignedTransaction, setHasSignedTransaction] = React29.useState(false);
13664
- const [tokenChainDetails, setTokenChainDetails] = React29.useState(null);
13665
- const [loadingTokenDetails, setLoadingTokenDetails] = React29.useState(false);
13666
- const [showTransactionDetails, setShowTransactionDetails] = React29.useState(false);
13667
- const [receivedUsdAtSubmission, setReceivedUsdAtSubmission] = React29.useState(null);
13612
+ const availableWallets = React30.useMemo(() => detectAvailableWallets(), [eip6963ProviderCount]);
13613
+ React30.useEffect(() => {
13614
+ if (!standalone || autoResolved || detectingWallet) return;
13615
+ if (!detectedWallet) {
13616
+ setAutoResolved(true);
13617
+ return;
13618
+ }
13619
+ const wct = detectedWallet.type === "phantom-solana" || detectedWallet.type === "solflare" || detectedWallet.type === "backpack" || detectedWallet.type === "glow" ? "solana" : "ethereum";
13620
+ const matching = depositWallets?.find((w) => w.chain_type === wct);
13621
+ if (!matching) {
13622
+ if (!depositWalletsLoading) setAutoResolved(true);
13623
+ return;
13624
+ }
13625
+ setActiveWalletInfo(detectedWallet);
13626
+ setActiveDepositWallet(matching);
13627
+ onWalletConnected?.(detectedWallet, matching);
13628
+ setView("select_token");
13629
+ viewRef.current = "select_token";
13630
+ setAutoResolved(true);
13631
+ }, [standalone, autoResolved, detectingWallet, detectedWallet, depositWallets, depositWalletsLoading]);
13632
+ React30.useEffect(() => {
13633
+ if (!standalone || autoResolved) return;
13634
+ const t12 = setTimeout(() => setAutoResolved(true), 5e3);
13635
+ return () => clearTimeout(t12);
13636
+ }, [standalone, autoResolved]);
13637
+ const [balances, setBalances] = React30.useState([]);
13638
+ const [isLoading, setIsLoading] = React30.useState(false);
13639
+ const [selectedBalance, setSelectedBalance] = React30.useState(null);
13640
+ const [totalBalanceUsd, setTotalBalanceUsd] = React30.useState(null);
13641
+ const [error, setError] = React30.useState(null);
13642
+ const [isDisconnectingWallet, setIsDisconnectingWallet] = React30.useState(false);
13643
+ const [amountUsd, setAmountUsd] = React30.useState(prefillAmountUsd ?? "");
13644
+ const [isConfirming, setIsConfirming] = React30.useState(false);
13645
+ const [hasSignedTransaction, setHasSignedTransaction] = React30.useState(false);
13646
+ const [tokenChainDetails, setTokenChainDetails] = React30.useState(null);
13647
+ const [loadingTokenDetails, setLoadingTokenDetails] = React30.useState(false);
13648
+ const [showTransactionDetails, setShowTransactionDetails] = React30.useState(false);
13649
+ const [receivedUsdAtSubmission, setReceivedUsdAtSubmission] = React30.useState(null);
13668
13650
  const walletInfo = activeWalletInfo;
13669
13651
  const depositWallet = activeDepositWallet;
13670
13652
  const hasWallet = !!activeWalletInfo && !!activeDepositWallet;
@@ -13672,7 +13654,7 @@ function WalletConnect({
13672
13654
  const recipientAddress = activeDepositWallet?.address ?? "";
13673
13655
  const isCheckoutMode = !!checkoutAmountUsd;
13674
13656
  const supportedChainType = chainType === "algorand" || chainType === "xrpl" ? "ethereum" : chainType;
13675
- const transitionTo = React29.useCallback((nextView) => {
13657
+ const transitionTo = React30.useCallback((nextView) => {
13676
13658
  if (nextView === viewRef.current) return;
13677
13659
  setIsTransitioning(true);
13678
13660
  setTimeout(() => {
@@ -13809,7 +13791,7 @@ function WalletConnect({
13809
13791
  }
13810
13792
  };
13811
13793
  const selectedToken = selectedBalance ? getTokenFromBalance(selectedBalance) : null;
13812
- const effectiveDestinationAmount = React29.useMemo(() => {
13794
+ const effectiveDestinationAmount = React30.useMemo(() => {
13813
13795
  if (!checkoutRemainingBaseUnits || checkoutRemainingBaseUnits === "0") return "0";
13814
13796
  if (!checkoutAmountUsd) return checkoutRemainingBaseUnits;
13815
13797
  const remaining = BigInt(checkoutRemainingBaseUnits);
@@ -13837,7 +13819,7 @@ function WalletConnect({
13837
13819
  stablecoinParity,
13838
13820
  enabled: isCheckoutMode && !!selectedToken && !!checkoutDestination && effectiveDestinationAmount !== "0"
13839
13821
  });
13840
- const activeCheckoutQuote = React29.useMemo(() => {
13822
+ const activeCheckoutQuote = React30.useMemo(() => {
13841
13823
  if (!isCheckoutMode) return null;
13842
13824
  if (walletCheckoutQuote) return { sourceAmount: walletCheckoutQuote.source_amount, sourceTokenDecimals: walletCheckoutQuote.source_token_decimals, sourceTokenSymbol: walletCheckoutQuote.source_token_symbol, sourceAmountUsd: walletCheckoutQuote.source_amount_usd, slippageBufferPercent: walletCheckoutQuote.slippage_buffer_percent ?? null };
13843
13825
  return checkoutQuote ?? null;
@@ -13851,19 +13833,19 @@ function WalletConnect({
13851
13833
  onDepositSuccess,
13852
13834
  onDepositError
13853
13835
  });
13854
- React29.useEffect(() => {
13836
+ React30.useEffect(() => {
13855
13837
  onExecutionsChange?.(depositExecutions);
13856
13838
  }, [depositExecutions, onExecutionsChange]);
13857
- React29.useEffect(() => {
13839
+ React30.useEffect(() => {
13858
13840
  if (!prefillAmountUsd || !tokenChainDetails || view !== "enter_amount") return;
13859
13841
  const minDeposit = tokenChainDetails.minimum_deposit_amount_usd || 0;
13860
13842
  const currentAmount = parseFloat(amountUsd) || 0;
13861
13843
  if (currentAmount > 0 && currentAmount < minDeposit) setAmountUsd(minDeposit.toFixed(2));
13862
13844
  }, [tokenChainDetails, view, prefillAmountUsd]);
13863
- React29.useEffect(() => {
13845
+ React30.useEffect(() => {
13864
13846
  if (view === "review") setShowTransactionDetails(false);
13865
13847
  }, [view]);
13866
- React29.useEffect(() => {
13848
+ React30.useEffect(() => {
13867
13849
  if (view !== "enter_amount" && view !== "review" || !selectedBalance || !activeDepositWallet) return;
13868
13850
  let cancelled = false;
13869
13851
  const fetchTokenDetails = async () => {
@@ -13890,7 +13872,7 @@ function WalletConnect({
13890
13872
  cancelled = true;
13891
13873
  };
13892
13874
  }, [view, selectedBalance, publishableKey, activeDepositWallet]);
13893
- React29.useEffect(() => {
13875
+ React30.useEffect(() => {
13894
13876
  if (!activeWalletInfo || !activeDepositWallet) return;
13895
13877
  let cancelled = false;
13896
13878
  setIsLoading(true);
@@ -13923,20 +13905,20 @@ function WalletConnect({
13923
13905
  cancelled = true;
13924
13906
  };
13925
13907
  }, [activeWalletInfo?.address, activeDepositWallet?.chain_type, publishableKey]);
13926
- const usdToTokenRate = React29.useMemo(() => {
13908
+ const usdToTokenRate = React30.useMemo(() => {
13927
13909
  if (!selectedBalance || !selectedBalance.amount_usd || !selectedToken) return 0;
13928
13910
  const balanceAmount = Number(selectedBalance.amount) / 10 ** selectedToken.decimals;
13929
13911
  const balanceUsd = parseFloat(selectedBalance.amount_usd);
13930
13912
  if (balanceAmount === 0 || balanceUsd === 0) return 0;
13931
13913
  return balanceAmount / balanceUsd;
13932
13914
  }, [selectedBalance, selectedToken]);
13933
- const tokenAmount = React29.useMemo(() => {
13915
+ const tokenAmount = React30.useMemo(() => {
13934
13916
  if (isCheckoutMode && activeCheckoutQuote && selectedToken) return Number(activeCheckoutQuote.sourceAmount) / 10 ** activeCheckoutQuote.sourceTokenDecimals;
13935
13917
  const usdNum = parseFloat(amountUsd) || 0;
13936
13918
  if (usdNum === 0 || usdToTokenRate === 0) return 0;
13937
13919
  return usdNum * usdToTokenRate;
13938
13920
  }, [amountUsd, usdToTokenRate, isCheckoutMode, activeCheckoutQuote, selectedToken]);
13939
- React29.useEffect(() => {
13921
+ React30.useEffect(() => {
13940
13922
  if (isCheckoutMode && activeCheckoutQuote?.sourceAmountUsd && view === "enter_amount") setAmountUsd(activeCheckoutQuote.sourceAmountUsd);
13941
13923
  }, [isCheckoutMode, activeCheckoutQuote, view]);
13942
13924
  const maxTokenAmount = selectedBalance && selectedToken ? Number(selectedBalance.amount) / 10 ** selectedToken.decimals : 0;
@@ -13944,7 +13926,7 @@ function WalletConnect({
13944
13926
  const inputUsdNum = parseFloat(amountUsd) || 0;
13945
13927
  const minDepositUsd = tokenChainDetails?.minimum_deposit_amount_usd || 0;
13946
13928
  const isValidAmount = isCheckoutMode && activeCheckoutQuote ? tokenAmount > 0 && tokenAmount <= maxTokenAmount : inputUsdNum > 0 && inputUsdNum <= maxUsdAmount && inputUsdNum >= minDepositUsd;
13947
- const formattedTokenAmount = React29.useMemo(() => {
13929
+ const formattedTokenAmount = React30.useMemo(() => {
13948
13930
  if (tokenAmount === 0 || !selectedToken) return null;
13949
13931
  return `${tokenAmount.toFixed(6)} ${selectedToken.symbol}`.replace(/\.?0+$/, "");
13950
13932
  }, [tokenAmount, selectedToken]);
@@ -13992,16 +13974,25 @@ function WalletConnect({
13992
13974
  } catch (err) {
13993
13975
  console.warn("[WalletConnect] disconnect error:", err);
13994
13976
  } finally {
13995
- setActiveWalletInfo(null);
13996
- setActiveDepositWallet(null);
13997
- setSelectedBalance(null);
13998
- setBalances([]);
13999
- setTotalBalanceUsd(null);
14000
- setAmountUsd(prefillAmountUsd ?? "");
14001
- setError(null);
14002
13977
  setIsDisconnectingWallet(false);
14003
- if (onWalletDisconnect) onWalletDisconnect();
14004
- else parentOnBack?.();
13978
+ const clearWalletState = () => {
13979
+ setActiveWalletInfo(null);
13980
+ setActiveDepositWallet(null);
13981
+ setSelectedBalance(null);
13982
+ setBalances([]);
13983
+ setTotalBalanceUsd(null);
13984
+ setAmountUsd(prefillAmountUsd ?? "");
13985
+ setError(null);
13986
+ };
13987
+ if (standalone) {
13988
+ onWalletDisconnect?.();
13989
+ transitionTo("select_wallet");
13990
+ setTimeout(clearWalletState, 160);
13991
+ } else {
13992
+ clearWalletState();
13993
+ if (onWalletDisconnect) onWalletDisconnect();
13994
+ else parentOnBack?.();
13995
+ }
14005
13996
  }
14006
13997
  };
14007
13998
  const handleReview = () => {
@@ -14127,9 +14118,15 @@ function WalletConnect({
14127
14118
  setIsConfirming(false);
14128
14119
  }
14129
14120
  };
14121
+ if (standalone && !autoResolved) {
14122
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { style: viewTransitionStyle, children: [
14123
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(DepositHeader, { title: "Connect Wallet", showBack: canGoBack, onBack: handleBack, onClose }),
14124
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-16", children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_lucide_react28.Loader2, { className: "uf-w-8 uf-h-8 uf-animate-spin", style: { color: colors2.primary } }) })
14125
+ ] });
14126
+ }
14130
14127
  if (view === "select_wallet") {
14131
14128
  return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { style: viewTransitionStyle, children: [
14132
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(DepositHeader, { title: "Connect Wallet", showBack: true, onBack: handleBack, onClose }),
14129
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(DepositHeader, { title: "Connect Wallet", showBack: canGoBack, onBack: handleBack, onClose }),
14133
14130
  /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "uf-pb-4", children: [
14134
14131
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("p", { className: "uf-text-sm uf-text-center uf-pb-4", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: "Select a wallet to connect" }),
14135
14132
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "uf-space-y-2", style: { maxHeight: 330, overflowY: "auto" }, children: availableWallets.map((wallet) => /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
@@ -14295,8 +14292,19 @@ function DepositModal({
14295
14292
  if (s === "tracker" && hideDepositTracker) return "main";
14296
14293
  if (s === "cashapp" && !enableCashApp) return "main";
14297
14294
  if (s === "card" && enableFiatOnramp === false) return "main";
14295
+ if (s === "pay_with_exchange") return enablePayWithExchange === false ? "main" : "exchange";
14296
+ if (s === "exchange_connect") return enableConnectExchange ? "coinbase_connect" : "main";
14297
+ if (s === "wallet_connect") return enableConnectWallet ? "wallet_connect" : "main";
14298
14298
  return s;
14299
- }, [initialScreen, hideDepositTracker, enableCashApp, enableFiatOnramp]);
14299
+ }, [
14300
+ initialScreen,
14301
+ hideDepositTracker,
14302
+ enableCashApp,
14303
+ enableFiatOnramp,
14304
+ enablePayWithExchange,
14305
+ enableConnectExchange,
14306
+ enableConnectWallet
14307
+ ]);
14300
14308
  const [containerEl, setContainerEl] = (0, import_react20.useState)(null);
14301
14309
  const containerCallbackRef = (0, import_react20.useCallback)((el) => {
14302
14310
  setContainerEl(el);
@@ -14420,6 +14428,12 @@ function DepositModal({
14420
14428
  setCardView("amount");
14421
14429
  }
14422
14430
  }, [view, showFiatOnramp]);
14431
+ (0, import_react20.useEffect)(() => {
14432
+ if (view === "exchange" && !showPayWithExchange) {
14433
+ setView("main");
14434
+ setExchangeView("providers");
14435
+ }
14436
+ }, [view, showPayWithExchange]);
14423
14437
  const { exchanges, isLoading: exchangesLoading } = useExchanges({
14424
14438
  publishableKey,
14425
14439
  enabled: open && showPayWithExchange
@@ -14539,7 +14553,7 @@ function DepositModal({
14539
14553
  setBrowserWalletChainType(void 0);
14540
14554
  setBrowserWalletInfo(null);
14541
14555
  setBrowserWalletModalOpen(false);
14542
- if (view === "wallet_connect") setView("main");
14556
+ if (view === "wallet_connect" && sessionOpenedFromMenu) setView("main");
14543
14557
  };
14544
14558
  const handleExchangeDisconnect = () => {
14545
14559
  const stored = getStoredIntegrationToken(import_core29.IntegrationProvider.COINBASE);
@@ -14548,7 +14562,7 @@ function DepositModal({
14548
14562
  }
14549
14563
  clearStoredIntegrationToken(import_core29.IntegrationProvider.COINBASE);
14550
14564
  setConnectedExchange(null);
14551
- if (view === "coinbase_connect") setView("main");
14565
+ if (view === "coinbase_connect" && sessionOpenedFromMenu) setView("main");
14552
14566
  };
14553
14567
  const handleClose = () => {
14554
14568
  onOpenChange(false);
@@ -14560,6 +14574,7 @@ function DepositModal({
14560
14574
  setCardView("amount");
14561
14575
  setExchangeView("providers");
14562
14576
  setBrowserWalletInfo(null);
14577
+ setCoinbaseSkipToHoldings(false);
14563
14578
  resetViewTimeoutRef.current = null;
14564
14579
  }, 200);
14565
14580
  };
@@ -14574,6 +14589,7 @@ function DepositModal({
14574
14589
  setExchangeView("providers");
14575
14590
  setBrowserWalletInfo(null);
14576
14591
  setSelectedExecution(null);
14592
+ setCoinbaseSkipToHoldings(false);
14577
14593
  }, [open, effectiveInitialScreen]);
14578
14594
  (0, import_react20.useEffect)(
14579
14595
  () => () => {
@@ -14933,7 +14949,7 @@ function DepositModal({
14933
14949
  DepositHeader,
14934
14950
  {
14935
14951
  title: payWithExchangeTitle,
14936
- showBack: true,
14952
+ showBack: exchangeView === "pending" || sessionOpenedFromMenu,
14937
14953
  onBack: handleBack,
14938
14954
  onClose: handleClose
14939
14955
  }
@@ -14987,6 +15003,7 @@ function DepositModal({
14987
15003
  onClose: handleClose,
14988
15004
  onDisconnect: handleExchangeDisconnect,
14989
15005
  skipToHoldings: coinbaseSkipToHoldings,
15006
+ canGoBack: sessionOpenedFromMenu,
14990
15007
  onExecutionsChange: setDepositExecutions
14991
15008
  }
14992
15009
  ),
@@ -15024,7 +15041,9 @@ function DepositModal({
15024
15041
  setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
15025
15042
  },
15026
15043
  onBack: handleBack,
15027
- onClose: handleClose
15044
+ onClose: handleClose,
15045
+ canGoBack: sessionOpenedFromMenu,
15046
+ depositWalletsLoading: walletsLoading
15028
15047
  }
15029
15048
  ),
15030
15049
  depositPoweredByFooter
@@ -15033,7 +15052,7 @@ function DepositModal({
15033
15052
  DepositHeader,
15034
15053
  {
15035
15054
  title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
15036
- showBack: true,
15055
+ showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
15037
15056
  onBack: handleBack,
15038
15057
  onClose: handleClose
15039
15058
  }