@unifold/ui-react 0.1.61 → 0.1.63

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
@@ -128,8 +128,32 @@ var import_tailwind_merge = require("tailwind-merge");
128
128
  function cn(...inputs) {
129
129
  return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
130
130
  }
131
- var WALLET_CHAIN_TYPE_STORAGE_KEY = "unifold_last_wallet_type";
131
+ var WALLET_STATE_STORAGE_KEY = "unifold_wallet_state";
132
+ var LEGACY_WALLET_KEYS = [
133
+ "unifold_last_wallet_type",
134
+ "unifold_last_connected_wallet"
135
+ ];
132
136
  var WALLET_USER_DISCONNECTED_KEY = "unifold_wallet_user_disconnected";
137
+ var SOLANA_WALLET_TYPES = /* @__PURE__ */ new Set([
138
+ "phantom-solana",
139
+ "solflare",
140
+ "backpack",
141
+ "glow"
142
+ ]);
143
+ var ETHEREUM_WALLET_TYPES = /* @__PURE__ */ new Set([
144
+ "metamask",
145
+ "phantom-ethereum",
146
+ "coinbase",
147
+ "trust",
148
+ "rainbow",
149
+ "rabby",
150
+ "okx"
151
+ ]);
152
+ function walletTypeToChain(t12) {
153
+ if (SOLANA_WALLET_TYPES.has(t12)) return "solana";
154
+ if (ETHEREUM_WALLET_TYPES.has(t12)) return "ethereum";
155
+ return void 0;
156
+ }
133
157
  function getUserDisconnectedWallet() {
134
158
  if (typeof window === "undefined") return false;
135
159
  try {
@@ -149,26 +173,35 @@ function setUserDisconnectedWallet(disconnected) {
149
173
  } catch {
150
174
  }
151
175
  }
152
- function getStoredWalletChainType() {
176
+ function getStoredWalletState() {
153
177
  if (typeof window === "undefined") return void 0;
154
178
  try {
155
- const stored = localStorage.getItem(WALLET_CHAIN_TYPE_STORAGE_KEY);
156
- if (stored === "ethereum" || stored === "solana") return stored;
179
+ const raw = localStorage.getItem(WALLET_STATE_STORAGE_KEY);
180
+ if (!raw) return void 0;
181
+ const chainType = walletTypeToChain(raw);
182
+ if (!chainType) {
183
+ localStorage.removeItem(WALLET_STATE_STORAGE_KEY);
184
+ return void 0;
185
+ }
186
+ return { walletType: raw, chainType };
157
187
  } catch {
188
+ return void 0;
158
189
  }
159
- return void 0;
160
190
  }
161
- function setStoredWalletChainType(chainType) {
191
+ function setStoredWalletState(walletType) {
162
192
  if (typeof window === "undefined") return;
193
+ if (!walletTypeToChain(walletType)) return;
163
194
  try {
164
- localStorage.setItem(WALLET_CHAIN_TYPE_STORAGE_KEY, chainType);
195
+ localStorage.setItem(WALLET_STATE_STORAGE_KEY, walletType);
196
+ for (const key of LEGACY_WALLET_KEYS) localStorage.removeItem(key);
165
197
  } catch {
166
198
  }
167
199
  }
168
- function clearStoredWalletChainType() {
200
+ function clearStoredWalletState() {
169
201
  if (typeof window === "undefined") return;
170
202
  try {
171
- localStorage.removeItem(WALLET_CHAIN_TYPE_STORAGE_KEY);
203
+ localStorage.removeItem(WALLET_STATE_STORAGE_KEY);
204
+ for (const key of LEGACY_WALLET_KEYS) localStorage.removeItem(key);
172
205
  } catch {
173
206
  }
174
207
  }
@@ -770,6 +803,60 @@ var import_core3 = require("@unifold/core");
770
803
 
771
804
  // src/components/deposits/browser-wallets/utils.ts
772
805
  var import_core2 = require("@unifold/core");
806
+ var normalize = (value) => value?.toLowerCase();
807
+ function sourceTokenMatchesDefaultSource(token, defaultSource) {
808
+ if (!token || !defaultSource.defaultSourceChainType || !defaultSource.defaultSourceChainId) {
809
+ return false;
810
+ }
811
+ if (token.chain_type !== defaultSource.defaultSourceChainType || token.chain_id !== defaultSource.defaultSourceChainId) {
812
+ return false;
813
+ }
814
+ if (defaultSource.defaultSourceTokenAddress && normalize(token.token_address) === normalize(defaultSource.defaultSourceTokenAddress)) {
815
+ return true;
816
+ }
817
+ if (defaultSource.defaultSourceTokenAddress) {
818
+ return false;
819
+ }
820
+ return !!defaultSource.defaultSourceSymbol && normalize(token.symbol) === normalize(defaultSource.defaultSourceSymbol);
821
+ }
822
+ function isDefaultSourceBalance(balance, defaultSource) {
823
+ return isBalanceEligible(balance) && sourceTokenMatchesDefaultSource(getTokenFromBalance(balance), defaultSource);
824
+ }
825
+ function compareBalancesWithDefaultSource(a, b, defaultSource) {
826
+ const aDefault = isDefaultSourceBalance(a, defaultSource);
827
+ const bDefault = isDefaultSourceBalance(b, defaultSource);
828
+ if (aDefault && !bDefault) return -1;
829
+ if (!aDefault && bDefault) return 1;
830
+ const aEligible = isBalanceEligible(a);
831
+ const bEligible = isBalanceEligible(b);
832
+ if (aEligible && !bEligible) return -1;
833
+ if (!aEligible && bEligible) return 1;
834
+ return 0;
835
+ }
836
+ function resolveDefaultSourceSymbol(supportedTokens, defaultSource) {
837
+ if (!supportedTokens?.length || !defaultSource.defaultSourceChainType || !defaultSource.defaultSourceChainId) {
838
+ return null;
839
+ }
840
+ if (defaultSource.defaultSourceTokenAddress) {
841
+ for (const token of supportedTokens) {
842
+ const matchingChain = token.chains.find(
843
+ (chain) => chain.chain_type === defaultSource.defaultSourceChainType && chain.chain_id === defaultSource.defaultSourceChainId && normalize(chain.token_address) === normalize(defaultSource.defaultSourceTokenAddress)
844
+ );
845
+ if (matchingChain) return token.symbol;
846
+ }
847
+ }
848
+ if (!defaultSource.defaultSourceSymbol) return null;
849
+ for (const token of supportedTokens) {
850
+ if (normalize(token.symbol) !== normalize(defaultSource.defaultSourceSymbol)) {
851
+ continue;
852
+ }
853
+ const matchingChain = token.chains.find(
854
+ (chain) => chain.chain_type === defaultSource.defaultSourceChainType && chain.chain_id === defaultSource.defaultSourceChainId
855
+ );
856
+ if (matchingChain) return token.symbol;
857
+ }
858
+ return null;
859
+ }
773
860
  function formatUsdFromBalancePercent(maxUsdAmount, percent) {
774
861
  if (maxUsdAmount <= 0 || percent < 0) return "";
775
862
  const raw = maxUsdAmount * percent / 100;
@@ -5323,7 +5410,7 @@ function CashAppButton({
5323
5410
  }
5324
5411
 
5325
5412
  // src/components/deposits/buttons/BrowserWalletButton.tsx
5326
- var React24 = __toESM(require("react"));
5413
+ var React25 = __toESM(require("react"));
5327
5414
  var import_lucide_react17 = require("lucide-react");
5328
5415
  var import_core14 = require("@unifold/core");
5329
5416
 
@@ -5377,6 +5464,233 @@ function collectAllEip6963EthProviders() {
5377
5464
  return store.getProviders().map((d) => d.provider);
5378
5465
  }
5379
5466
 
5467
+ // src/components/deposits/browser-wallets/useDetectedBrowserWallet.ts
5468
+ var React12 = __toESM(require("react"));
5469
+
5470
+ // src/components/deposits/browser-wallets/detectConnectedWallet.ts
5471
+ function identifyEthWallet(provider, hint) {
5472
+ switch (hint) {
5473
+ case "metamask":
5474
+ return { type: "metamask", name: "MetaMask", icon: "metamask" };
5475
+ case "phantom":
5476
+ return { type: "phantom-ethereum", name: "Phantom", icon: "phantom" };
5477
+ case "coinbase":
5478
+ return { type: "coinbase", name: "Coinbase Wallet", icon: "coinbase" };
5479
+ case "okx":
5480
+ return { type: "okx", name: "OKX Wallet", icon: "okx" };
5481
+ case "rabby":
5482
+ return { type: "rabby", name: "Rabby", icon: "rabby" };
5483
+ case "trust":
5484
+ return { type: "trust", name: "Trust Wallet", icon: "trust" };
5485
+ case "rainbow":
5486
+ return { type: "rainbow", name: "Rainbow", icon: "rainbow" };
5487
+ }
5488
+ const anyProvider = provider;
5489
+ if (provider.isPhantom) {
5490
+ return { type: "phantom-ethereum", name: "Phantom", icon: "phantom" };
5491
+ }
5492
+ if (anyProvider.isCoinbaseWallet) {
5493
+ return { type: "coinbase", name: "Coinbase Wallet", icon: "coinbase" };
5494
+ }
5495
+ if (anyProvider.isRabby) {
5496
+ return { type: "rabby", name: "Rabby", icon: "rabby" };
5497
+ }
5498
+ if (anyProvider.isTrust) {
5499
+ return { type: "trust", name: "Trust Wallet", icon: "trust" };
5500
+ }
5501
+ if (anyProvider.isRainbow) {
5502
+ return { type: "rainbow", name: "Rainbow", icon: "rainbow" };
5503
+ }
5504
+ if (provider.isMetaMask && !provider.isPhantom) {
5505
+ return { type: "metamask", name: "MetaMask", icon: "metamask" };
5506
+ }
5507
+ return { type: "metamask", name: "Wallet", icon: "metamask" };
5508
+ }
5509
+ var EIP6963_ID_TO_WALLET_TYPE = {
5510
+ metamask: "metamask",
5511
+ phantom: "phantom-ethereum",
5512
+ coinbase: "coinbase",
5513
+ trust: "trust",
5514
+ rainbow: "rainbow",
5515
+ rabby: "rabby",
5516
+ okx: "okx"
5517
+ };
5518
+ function inferEthWalletType(provider, walletId) {
5519
+ if (EIP6963_ID_TO_WALLET_TYPE[walletId]) return EIP6963_ID_TO_WALLET_TYPE[walletId];
5520
+ const any = provider;
5521
+ if (provider.isPhantom) return "phantom-ethereum";
5522
+ if (any.isCoinbaseWallet) return "coinbase";
5523
+ if (any.isRabby) return "rabby";
5524
+ if (any.isTrust) return "trust";
5525
+ if (any.isRainbow) return "rainbow";
5526
+ if (any.isOkxWallet) return "okx";
5527
+ if (provider.isMetaMask && !provider.isPhantom) return "metamask";
5528
+ return null;
5529
+ }
5530
+ function solanaCandidate(provider, type, name, icon) {
5531
+ return {
5532
+ walletType: type,
5533
+ detect: async () => {
5534
+ if (!provider) return null;
5535
+ if (provider.isConnected && provider.publicKey) {
5536
+ return { type, name, address: provider.publicKey.toString(), icon };
5537
+ }
5538
+ try {
5539
+ const resp = await provider.connect({ onlyIfTrusted: true });
5540
+ if (resp.publicKey) {
5541
+ return { type, name, address: resp.publicKey.toString(), icon };
5542
+ }
5543
+ } catch {
5544
+ }
5545
+ return null;
5546
+ }
5547
+ };
5548
+ }
5549
+ function ethereumCandidate(provider, walletId) {
5550
+ return {
5551
+ walletType: inferEthWalletType(provider, walletId),
5552
+ detect: async () => {
5553
+ try {
5554
+ const accounts = await provider.request({ method: "eth_accounts" });
5555
+ if (!accounts?.length) return null;
5556
+ const resolved = identifyEthWallet(provider, walletId);
5557
+ return { ...resolved, address: accounts[0] };
5558
+ } catch {
5559
+ return null;
5560
+ }
5561
+ }
5562
+ };
5563
+ }
5564
+ function buildCandidates(win, chainType) {
5565
+ const candidates = [];
5566
+ if (!chainType || chainType === "solana") {
5567
+ candidates.push(
5568
+ solanaCandidate(win.phantom?.solana, "phantom-solana", "Phantom", "phantom"),
5569
+ solanaCandidate(win.solflare, "solflare", "Solflare", "solflare"),
5570
+ solanaCandidate(win.backpack, "backpack", "Backpack", "backpack"),
5571
+ solanaCandidate(win.glow, "glow", "Glow", "glow")
5572
+ );
5573
+ }
5574
+ if (!chainType || chainType === "ethereum") {
5575
+ const seen = /* @__PURE__ */ new Set();
5576
+ const addEth = (provider, walletId) => {
5577
+ if (!provider || seen.has(provider)) return;
5578
+ seen.add(provider);
5579
+ candidates.push(ethereumCandidate(provider, walletId));
5580
+ };
5581
+ for (const { provider, walletId } of getEip6963Providers()) {
5582
+ addEth(
5583
+ provider,
5584
+ walletId === "unknown" ? "default" : walletId
5585
+ );
5586
+ }
5587
+ addEth(win.phantom?.ethereum, "phantom");
5588
+ addEth(win.coinbaseWalletExtension, "coinbase");
5589
+ addEth(win.okxwallet, "okx");
5590
+ addEth(win.trustwallet?.ethereum, "trust");
5591
+ addEth(win.ethereum, "default");
5592
+ }
5593
+ return candidates;
5594
+ }
5595
+ async function detectConnectedBrowserWallet(chainType) {
5596
+ if (typeof window === "undefined") return null;
5597
+ if (getUserDisconnectedWallet()) return null;
5598
+ try {
5599
+ const win = window;
5600
+ const candidates = buildCandidates(win, chainType);
5601
+ const preferred = getStoredWalletState();
5602
+ if (preferred && (!chainType || preferred.chainType === chainType)) {
5603
+ const idx = candidates.findIndex((c) => c.walletType === preferred.walletType);
5604
+ if (idx > 0) candidates.unshift(...candidates.splice(idx, 1));
5605
+ }
5606
+ for (const c of candidates) {
5607
+ const found = await c.detect();
5608
+ if (found) return found;
5609
+ }
5610
+ } catch (error) {
5611
+ console.error("[detectConnectedBrowserWallet] detection error:", error);
5612
+ }
5613
+ return null;
5614
+ }
5615
+
5616
+ // src/components/deposits/browser-wallets/useDetectedBrowserWallet.ts
5617
+ function useDetectedBrowserWallet(opts = {}) {
5618
+ const { chainType, enabled = true, onDisconnect } = opts;
5619
+ const [wallet, setWallet] = React12.useState(null);
5620
+ const [isLoading, setIsLoading] = React12.useState(enabled);
5621
+ const [eip6963ProviderCount, setEip6963ProviderCount] = React12.useState(0);
5622
+ const onDisconnectRef = React12.useRef(onDisconnect);
5623
+ onDisconnectRef.current = onDisconnect;
5624
+ React12.useEffect(() => {
5625
+ const store = getEip6963Store();
5626
+ if (!store) return;
5627
+ setEip6963ProviderCount(store.getProviders().length);
5628
+ return store.subscribe((providers) => setEip6963ProviderCount(providers.length));
5629
+ }, []);
5630
+ React12.useEffect(() => {
5631
+ if (!enabled) {
5632
+ setWallet(null);
5633
+ setIsLoading(false);
5634
+ return;
5635
+ }
5636
+ let mounted = true;
5637
+ const detect = async () => {
5638
+ if (!mounted) return;
5639
+ setIsLoading(true);
5640
+ const detected = await detectConnectedBrowserWallet(chainType);
5641
+ if (!mounted) return;
5642
+ setWallet(detected);
5643
+ setIsLoading(false);
5644
+ };
5645
+ detect();
5646
+ const onChange = () => detect();
5647
+ const onDisc = () => {
5648
+ onDisconnectRef.current?.();
5649
+ detect();
5650
+ };
5651
+ const onEthAccounts = (accounts) => {
5652
+ if (Array.isArray(accounts) && accounts.length === 0) onDisconnectRef.current?.();
5653
+ detect();
5654
+ };
5655
+ const win = typeof window !== "undefined" ? window : void 0;
5656
+ const solanaProvider = win?.phantom?.solana || win?.solana;
5657
+ if (solanaProvider) {
5658
+ solanaProvider.on("connect", onChange);
5659
+ solanaProvider.on("disconnect", onDisc);
5660
+ solanaProvider.on("accountChanged", onChange);
5661
+ }
5662
+ const ethProviders = [];
5663
+ for (const { provider } of getEip6963Providers()) {
5664
+ const p = provider;
5665
+ if (p && !ethProviders.includes(p)) ethProviders.push(p);
5666
+ }
5667
+ if (win?.ethereum && !ethProviders.includes(win.ethereum)) ethProviders.push(win.ethereum);
5668
+ if (win?.phantom?.ethereum && !ethProviders.includes(win.phantom.ethereum)) {
5669
+ ethProviders.push(win.phantom.ethereum);
5670
+ }
5671
+ for (const p of ethProviders) {
5672
+ p.on("accountsChanged", onEthAccounts);
5673
+ p.on("chainChanged", onChange);
5674
+ }
5675
+ return () => {
5676
+ mounted = false;
5677
+ if (solanaProvider) {
5678
+ solanaProvider.off?.("connect", onChange);
5679
+ solanaProvider.off?.("disconnect", onDisc);
5680
+ solanaProvider.off?.("accountChanged", onChange);
5681
+ }
5682
+ for (const p of ethProviders) {
5683
+ const off = p.off?.bind(p) ?? p.removeListener?.bind(p);
5684
+ if (off) {
5685
+ off("accountsChanged", onEthAccounts);
5686
+ off("chainChanged", onChange);
5687
+ }
5688
+ }
5689
+ };
5690
+ }, [chainType, eip6963ProviderCount, enabled]);
5691
+ return { wallet, isLoading, setWallet };
5692
+ }
5693
+
5380
5694
  // src/components/deposits/browser-wallets/disconnectInjectedBrowserWallet.ts
5381
5695
  var SOLANA_DISCONNECT_TYPES = [
5382
5696
  "phantom-solana",
@@ -5462,14 +5776,14 @@ async function disconnectInjectedBrowserWallet(wallet) {
5462
5776
  }
5463
5777
 
5464
5778
  // src/resources/icons/MetamaskIcon.tsx
5465
- var React12 = __toESM(require("react"));
5779
+ var React13 = __toESM(require("react"));
5466
5780
  var import_jsx_runtime23 = require("react/jsx-runtime");
5467
5781
  function MetamaskIcon({
5468
5782
  size = 24,
5469
5783
  className,
5470
5784
  variant = "color"
5471
5785
  }) {
5472
- const id = React12.useId();
5786
+ const id = React13.useId();
5473
5787
  if (variant === "light" || variant === "dark") {
5474
5788
  return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
5475
5789
  "svg",
@@ -5591,14 +5905,14 @@ function MetamaskIcon({
5591
5905
  }
5592
5906
 
5593
5907
  // src/resources/icons/PhantomIcon.tsx
5594
- var React13 = __toESM(require("react"));
5908
+ var React14 = __toESM(require("react"));
5595
5909
  var import_jsx_runtime24 = require("react/jsx-runtime");
5596
5910
  function PhantomIcon({
5597
5911
  size = 24,
5598
5912
  className,
5599
5913
  variant = "color"
5600
5914
  }) {
5601
- const id = React13.useId();
5915
+ const id = React14.useId();
5602
5916
  if (variant === "light") {
5603
5917
  return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5604
5918
  "svg",
@@ -5666,14 +5980,14 @@ function PhantomIcon({
5666
5980
  }
5667
5981
 
5668
5982
  // src/resources/icons/CoinbaseIcon.tsx
5669
- var React14 = __toESM(require("react"));
5983
+ var React15 = __toESM(require("react"));
5670
5984
  var import_jsx_runtime25 = require("react/jsx-runtime");
5671
5985
  function CoinbaseIcon({
5672
5986
  size = 24,
5673
5987
  className,
5674
5988
  variant = "color"
5675
5989
  }) {
5676
- const id = React14.useId();
5990
+ const id = React15.useId();
5677
5991
  if (variant === "light") {
5678
5992
  return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
5679
5993
  "svg",
@@ -5754,14 +6068,14 @@ function CoinbaseIcon({
5754
6068
  }
5755
6069
 
5756
6070
  // src/resources/icons/RabbyIcon.tsx
5757
- var React15 = __toESM(require("react"));
6071
+ var React16 = __toESM(require("react"));
5758
6072
  var import_jsx_runtime26 = require("react/jsx-runtime");
5759
6073
  function RabbyIcon({
5760
6074
  size = 24,
5761
6075
  className,
5762
6076
  variant = "color"
5763
6077
  }) {
5764
- const id = React15.useId();
6078
+ const id = React16.useId();
5765
6079
  if (variant === "light") {
5766
6080
  return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
5767
6081
  "svg",
@@ -6109,14 +6423,14 @@ function RabbyIcon({
6109
6423
  }
6110
6424
 
6111
6425
  // src/resources/icons/RainbowIcon.tsx
6112
- var React16 = __toESM(require("react"));
6426
+ var React17 = __toESM(require("react"));
6113
6427
  var import_jsx_runtime27 = require("react/jsx-runtime");
6114
6428
  function RainbowIcon({
6115
6429
  size = 24,
6116
6430
  className,
6117
6431
  variant = "color"
6118
6432
  }) {
6119
- const id = React16.useId();
6433
+ const id = React17.useId();
6120
6434
  if (variant === "light") {
6121
6435
  return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
6122
6436
  "svg",
@@ -6579,14 +6893,14 @@ function RainbowIcon({
6579
6893
  }
6580
6894
 
6581
6895
  // src/resources/icons/TrustIcon.tsx
6582
- var React17 = __toESM(require("react"));
6896
+ var React18 = __toESM(require("react"));
6583
6897
  var import_jsx_runtime28 = require("react/jsx-runtime");
6584
6898
  function TrustIcon({
6585
6899
  size = 24,
6586
6900
  className,
6587
6901
  variant = "color"
6588
6902
  }) {
6589
- const id = React17.useId();
6903
+ const id = React18.useId();
6590
6904
  if (variant === "light") {
6591
6905
  return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
6592
6906
  "svg",
@@ -6676,14 +6990,14 @@ function TrustIcon({
6676
6990
  }
6677
6991
 
6678
6992
  // src/resources/icons/OkxIcon.tsx
6679
- var React18 = __toESM(require("react"));
6993
+ var React19 = __toESM(require("react"));
6680
6994
  var import_jsx_runtime29 = require("react/jsx-runtime");
6681
6995
  function OkxIcon({
6682
6996
  size = 24,
6683
6997
  className,
6684
6998
  variant = "color"
6685
6999
  }) {
6686
- const id = React18.useId();
7000
+ const id = React19.useId();
6687
7001
  if (variant === "light") {
6688
7002
  return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6689
7003
  "svg",
@@ -6751,14 +7065,14 @@ function OkxIcon({
6751
7065
  }
6752
7066
 
6753
7067
  // src/resources/icons/GlowIcon.tsx
6754
- var React19 = __toESM(require("react"));
7068
+ var React20 = __toESM(require("react"));
6755
7069
  var import_jsx_runtime30 = require("react/jsx-runtime");
6756
7070
  function GlowIcon({
6757
7071
  size = 24,
6758
7072
  className,
6759
7073
  variant = "color"
6760
7074
  }) {
6761
- const id = React19.useId();
7075
+ const id = React20.useId();
6762
7076
  if (variant === "light") {
6763
7077
  return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6764
7078
  "svg",
@@ -6860,14 +7174,14 @@ function GlowIcon({
6860
7174
  }
6861
7175
 
6862
7176
  // src/resources/icons/BackpackIcon.tsx
6863
- var React20 = __toESM(require("react"));
7177
+ var React21 = __toESM(require("react"));
6864
7178
  var import_jsx_runtime31 = require("react/jsx-runtime");
6865
7179
  function BackpackIcon({
6866
7180
  size = 24,
6867
7181
  className,
6868
7182
  variant = "color"
6869
7183
  }) {
6870
- const id = React20.useId();
7184
+ const id = React21.useId();
6871
7185
  if (variant === "light") {
6872
7186
  return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
6873
7187
  "svg",
@@ -6941,14 +7255,14 @@ function BackpackIcon({
6941
7255
  }
6942
7256
 
6943
7257
  // src/resources/icons/SolflareIcon.tsx
6944
- var React21 = __toESM(require("react"));
7258
+ var React22 = __toESM(require("react"));
6945
7259
  var import_jsx_runtime32 = require("react/jsx-runtime");
6946
7260
  function SolflareIcon({
6947
7261
  size = 24,
6948
7262
  className,
6949
7263
  variant = "color"
6950
7264
  }) {
6951
- const id = React21.useId();
7265
+ const id = React22.useId();
6952
7266
  if (variant === "light") {
6953
7267
  return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6954
7268
  "svg",
@@ -7016,14 +7330,14 @@ function SolflareIcon({
7016
7330
  }
7017
7331
 
7018
7332
  // src/resources/icons/EthereumIcon.tsx
7019
- var React22 = __toESM(require("react"));
7333
+ var React23 = __toESM(require("react"));
7020
7334
  var import_jsx_runtime33 = require("react/jsx-runtime");
7021
7335
  function EthereumIcon({
7022
7336
  size = 24,
7023
7337
  className,
7024
7338
  variant = "color"
7025
7339
  }) {
7026
- const id = React22.useId();
7340
+ const id = React23.useId();
7027
7341
  if (variant === "light") {
7028
7342
  return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
7029
7343
  "svg",
@@ -7154,14 +7468,14 @@ function EthereumIcon({
7154
7468
  }
7155
7469
 
7156
7470
  // src/resources/icons/SolanaIcon.tsx
7157
- var React23 = __toESM(require("react"));
7471
+ var React24 = __toESM(require("react"));
7158
7472
  var import_jsx_runtime34 = require("react/jsx-runtime");
7159
7473
  function SolanaIcon({
7160
7474
  size = 24,
7161
7475
  className,
7162
7476
  variant = "color"
7163
7477
  }) {
7164
- const id = React23.useId();
7478
+ const id = React24.useId();
7165
7479
  if (variant === "light") {
7166
7480
  return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
7167
7481
  "svg",
@@ -7416,44 +7730,6 @@ function truncateAddress3(address) {
7416
7730
  if (address.length <= 10) return address;
7417
7731
  return `${address.slice(0, 4)}...${address.slice(-4)}`;
7418
7732
  }
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
7733
  function BrowserWalletButton({
7458
7734
  onClick,
7459
7735
  onConnectClick,
@@ -7464,30 +7740,19 @@ function BrowserWalletButton({
7464
7740
  subtitle = i18n.depositModal.browserWallet.subtitle
7465
7741
  }) {
7466
7742
  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);
7743
+ const [isHovered, setIsHovered] = React25.useState(false);
7744
+ const [isTouchDevice, setIsTouchDevice] = React25.useState(false);
7745
+ const { wallet, isLoading, setWallet } = useDetectedBrowserWallet({ chainType, onDisconnect });
7746
+ const [isConnecting, setIsConnecting] = React25.useState(false);
7747
+ const [balanceText, setBalanceText] = React25.useState(null);
7748
+ const [isLoadingBalance, setIsLoadingBalance] = React25.useState(false);
7749
+ const [isDisconnecting, setIsDisconnecting] = React25.useState(false);
7750
+ const onDisconnectRef = React25.useRef(onDisconnect);
7476
7751
  onDisconnectRef.current = onDisconnect;
7477
- React24.useEffect(() => {
7752
+ React25.useEffect(() => {
7478
7753
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
7479
7754
  }, []);
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(() => {
7755
+ React25.useEffect(() => {
7491
7756
  if (!wallet || !publishableKey) {
7492
7757
  setBalanceText(null);
7493
7758
  return;
@@ -7528,206 +7793,6 @@ function BrowserWalletButton({
7528
7793
  cancelled = true;
7529
7794
  };
7530
7795
  }, [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
7796
  const handleConnect = async () => {
7732
7797
  if (wallet) {
7733
7798
  onClick(wallet);
@@ -7744,6 +7809,7 @@ function BrowserWalletButton({
7744
7809
  if (solanaProvider?.isPhantom) {
7745
7810
  const { publicKey } = await solanaProvider.connect();
7746
7811
  setUserDisconnectedWallet(false);
7812
+ setStoredWalletState("phantom-solana");
7747
7813
  setWallet({
7748
7814
  type: "phantom-solana",
7749
7815
  name: "Phantom",
@@ -7763,8 +7829,10 @@ function BrowserWalletButton({
7763
7829
  if (accounts && accounts.length > 0) {
7764
7830
  setUserDisconnectedWallet(false);
7765
7831
  const isPhantom = ethProvider.isPhantom;
7832
+ const walletType = isPhantom ? "phantom-ethereum" : "metamask";
7833
+ setStoredWalletState(walletType);
7766
7834
  setWallet({
7767
- type: isPhantom ? "phantom-ethereum" : "metamask",
7835
+ type: walletType,
7768
7836
  name: isPhantom ? "Phantom" : "MetaMask",
7769
7837
  address: accounts[0],
7770
7838
  icon: isPhantom ? "phantom" : "metamask"
@@ -7811,7 +7879,7 @@ function BrowserWalletButton({
7811
7879
  border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
7812
7880
  };
7813
7881
  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], {
7882
+ const walletIconBlock = wallet ? WALLET_ICON_COMPONENTS[wallet.icon] ? React25.createElement(WALLET_ICON_COMPONENTS[wallet.icon], {
7815
7883
  size: 36,
7816
7884
  className: "uf-rounded-lg",
7817
7885
  variant: "color"
@@ -8095,7 +8163,12 @@ function CoinbaseConnect({
8095
8163
  onBack: parentOnBack,
8096
8164
  onDisconnect,
8097
8165
  skipToHoldings,
8098
- onExecutionsChange
8166
+ canGoBack = true,
8167
+ onExecutionsChange,
8168
+ defaultSourceChainType,
8169
+ defaultSourceChainId,
8170
+ defaultSourceTokenAddress,
8171
+ defaultSourceSymbol
8099
8172
  }) {
8100
8173
  const { colors: colors2, fonts, components } = useTheme();
8101
8174
  const { projectConfig } = useProjectConfig({ publishableKey });
@@ -8160,6 +8233,21 @@ function CoinbaseConnect({
8160
8233
  params: defaultTokenParams,
8161
8234
  publishableKey
8162
8235
  });
8236
+ const defaultSourceCurrency = (0, import_react12.useMemo)(
8237
+ () => resolveDefaultSourceSymbol(supportedTokensData?.data, {
8238
+ defaultSourceChainType,
8239
+ defaultSourceChainId,
8240
+ defaultSourceTokenAddress,
8241
+ defaultSourceSymbol
8242
+ })?.toLowerCase() ?? null,
8243
+ [
8244
+ supportedTokensData,
8245
+ defaultSourceChainType,
8246
+ defaultSourceChainId,
8247
+ defaultSourceTokenAddress,
8248
+ defaultSourceSymbol
8249
+ ]
8250
+ );
8163
8251
  const sortedHoldings = (0, import_react12.useMemo)(() => {
8164
8252
  const supported = [];
8165
8253
  const unsupported = [];
@@ -8169,13 +8257,42 @@ function CoinbaseConnect({
8169
8257
  if (isSupported) supported.push(account);
8170
8258
  else unsupported.push(account);
8171
8259
  });
8260
+ if (defaultSourceCurrency) {
8261
+ const defaultIndex = supported.findIndex(
8262
+ (account) => account.currency.toLowerCase() === defaultSourceCurrency
8263
+ );
8264
+ if (defaultIndex > 0) {
8265
+ const [defaultHolding] = supported.splice(defaultIndex, 1);
8266
+ supported.unshift(defaultHolding);
8267
+ }
8268
+ }
8172
8269
  return [...supported, ...unsupported];
8173
- }, [holdings, supportedSymbols, exchangeSupportedCurrencies]);
8270
+ }, [
8271
+ holdings,
8272
+ supportedSymbols,
8273
+ exchangeSupportedCurrencies,
8274
+ defaultSourceCurrency
8275
+ ]);
8174
8276
  const selectedHoldingIsSupported = (0, import_react12.useMemo)(() => {
8175
8277
  if (!selectedHolding) return false;
8176
8278
  const currencyLower = selectedHolding.currency.toLowerCase();
8177
8279
  return (supportedSymbols.size === 0 || supportedSymbols.has(currencyLower)) && (exchangeSupportedCurrencies.size === 0 || exchangeSupportedCurrencies.has(currencyLower));
8178
8280
  }, [selectedHolding, supportedSymbols, exchangeSupportedCurrencies]);
8281
+ (0, import_react12.useEffect)(() => {
8282
+ if (!defaultSourceCurrency || selectedHolding) return;
8283
+ const defaultHolding = sortedHoldings.find((account) => {
8284
+ const currencyLower = account.currency.toLowerCase();
8285
+ return currencyLower === defaultSourceCurrency && (supportedSymbols.size === 0 || supportedSymbols.has(currencyLower)) && (exchangeSupportedCurrencies.size === 0 || exchangeSupportedCurrencies.has(currencyLower));
8286
+ });
8287
+ if (!defaultHolding) return;
8288
+ setSelectedHolding(defaultHolding);
8289
+ }, [
8290
+ defaultSourceCurrency,
8291
+ selectedHolding,
8292
+ sortedHoldings,
8293
+ supportedSymbols,
8294
+ exchangeSupportedCurrencies
8295
+ ]);
8179
8296
  const exchangeName = selectedExchange?.service_provider_display_name || "Exchange";
8180
8297
  const {
8181
8298
  executions: depositExecutions,
@@ -8482,6 +8599,16 @@ function CoinbaseConnect({
8482
8599
  setIsLoading(false);
8483
8600
  }
8484
8601
  };
8602
+ const handleDisconnect = () => {
8603
+ onDisconnect?.();
8604
+ if (!canGoBack) {
8605
+ setAccessToken(null);
8606
+ setHoldings([]);
8607
+ setSelectedHolding(null);
8608
+ setSelectedAsset(null);
8609
+ transitionTo("select_exchange");
8610
+ }
8611
+ };
8485
8612
  const handleBack = () => {
8486
8613
  switch (view) {
8487
8614
  case "select_exchange":
@@ -8542,7 +8669,7 @@ function CoinbaseConnect({
8542
8669
  DepositHeader,
8543
8670
  {
8544
8671
  title: t12.title,
8545
- showBack: true,
8672
+ showBack: canGoBack,
8546
8673
  onBack: handleBack,
8547
8674
  onClose
8548
8675
  }
@@ -8555,7 +8682,7 @@ function CoinbaseConnect({
8555
8682
  DepositHeader,
8556
8683
  {
8557
8684
  title: t12.title,
8558
- showBack: true,
8685
+ showBack: canGoBack,
8559
8686
  onBack: handleBack,
8560
8687
  onClose
8561
8688
  }
@@ -9267,7 +9394,7 @@ function CoinbaseConnect({
9267
9394
  borderRadius: components.button.borderRadius,
9268
9395
  fontFamily: fonts.medium
9269
9396
  },
9270
- onClick: onDisconnect,
9397
+ onClick: handleDisconnect,
9271
9398
  children: t12.disconnect
9272
9399
  }
9273
9400
  )
@@ -10077,14 +10204,14 @@ var import_lucide_react22 = require("lucide-react");
10077
10204
  var import_react13 = require("react");
10078
10205
 
10079
10206
  // src/components/shared/ThemeStyleInjector.tsx
10080
- var React26 = __toESM(require("react"));
10207
+ var React27 = __toESM(require("react"));
10081
10208
  var import_jsx_runtime38 = require("react/jsx-runtime");
10082
10209
  function ThemeStyleInjector({
10083
10210
  children,
10084
10211
  className
10085
10212
  }) {
10086
10213
  const { colors: colors2, fonts, mode } = useTheme();
10087
- const cssVars = React26.useMemo(() => {
10214
+ const cssVars = React27.useMemo(() => {
10088
10215
  const hexToHSL = (hex) => {
10089
10216
  hex = hex.replace("#", "");
10090
10217
  const r = parseInt(hex.slice(0, 2), 16) / 255;
@@ -10144,7 +10271,7 @@ function ThemeStyleInjector({
10144
10271
  ...fonts.regular ? { "--uf-font-family": fonts.regular } : {}
10145
10272
  };
10146
10273
  }, [colors2, fonts.regular]);
10147
- React26.useEffect(() => {
10274
+ React27.useEffect(() => {
10148
10275
  if (typeof document === "undefined") return;
10149
10276
  if (fonts.regular) {
10150
10277
  document.documentElement.style.setProperty(
@@ -11132,7 +11259,7 @@ function useCopyAddress() {
11132
11259
  }
11133
11260
 
11134
11261
  // src/components/shared/tooltip.tsx
11135
- var React27 = __toESM(require("react"));
11262
+ var React28 = __toESM(require("react"));
11136
11263
  var TooltipPrimitive = __toESM(require("@radix-ui/react-tooltip"));
11137
11264
  var import_jsx_runtime44 = require("react/jsx-runtime");
11138
11265
  var TooltipProvider = TooltipPrimitive.Provider;
@@ -11140,7 +11267,7 @@ function Tooltip({
11140
11267
  children,
11141
11268
  ...props
11142
11269
  }) {
11143
- const [open, setOpen] = React27.useState(props.defaultOpen ?? false);
11270
+ const [open, setOpen] = React28.useState(props.defaultOpen ?? false);
11144
11271
  const isControlled = props.open !== void 0;
11145
11272
  const isOpen = isControlled ? props.open : open;
11146
11273
  const onOpenChange = isControlled ? props.onOpenChange : (nextOpen) => setOpen(nextOpen);
@@ -11160,14 +11287,14 @@ function Tooltip({
11160
11287
  }
11161
11288
  );
11162
11289
  }
11163
- var TooltipContext = React27.createContext({
11290
+ var TooltipContext = React28.createContext({
11164
11291
  open: false,
11165
11292
  onOpenChange: () => {
11166
11293
  }
11167
11294
  });
11168
- var TooltipTrigger = React27.forwardRef(({ onClick, ...props }, ref) => {
11169
- const { open, onOpenChange } = React27.useContext(TooltipContext);
11170
- const handleClick = React27.useCallback(
11295
+ var TooltipTrigger = React28.forwardRef(({ onClick, ...props }, ref) => {
11296
+ const { open, onOpenChange } = React28.useContext(TooltipContext);
11297
+ const handleClick = React28.useCallback(
11171
11298
  (e) => {
11172
11299
  onOpenChange(!open);
11173
11300
  onClick?.(e);
@@ -11177,7 +11304,7 @@ var TooltipTrigger = React27.forwardRef(({ onClick, ...props }, ref) => {
11177
11304
  return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(TooltipPrimitive.Trigger, { ref, onClick: handleClick, ...props });
11178
11305
  });
11179
11306
  TooltipTrigger.displayName = TooltipPrimitive.Trigger.displayName;
11180
- var TooltipContent = React27.forwardRef(({ className, sideOffset = 4, ...props }, ref) => {
11307
+ var TooltipContent = React28.forwardRef(({ className, sideOffset = 4, ...props }, ref) => {
11181
11308
  const { themeClass, colors: colors2 } = useTheme();
11182
11309
  return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(TooltipPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
11183
11310
  TooltipPrimitive.Content,
@@ -11804,14 +11931,14 @@ var import_react18 = require("react");
11804
11931
  var import_lucide_react24 = require("lucide-react");
11805
11932
 
11806
11933
  // src/components/shared/select.tsx
11807
- var React28 = __toESM(require("react"));
11934
+ var React29 = __toESM(require("react"));
11808
11935
  var SelectPrimitive = __toESM(require("@radix-ui/react-select"));
11809
11936
  var import_lucide_react23 = require("lucide-react");
11810
11937
  var import_jsx_runtime47 = require("react/jsx-runtime");
11811
11938
  var Select = SelectPrimitive.Root;
11812
11939
  var SelectGroup = SelectPrimitive.Group;
11813
11940
  var SelectValue = SelectPrimitive.Value;
11814
- var SelectTrigger = React28.forwardRef(({ className, style, children, ...props }, ref) => {
11941
+ var SelectTrigger = React29.forwardRef(({ className, style, children, ...props }, ref) => {
11815
11942
  const { components } = useTheme();
11816
11943
  return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
11817
11944
  SelectPrimitive.Trigger,
@@ -11835,7 +11962,7 @@ var SelectTrigger = React28.forwardRef(({ className, style, children, ...props }
11835
11962
  );
11836
11963
  });
11837
11964
  SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
11838
- var SelectScrollUpButton = React28.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
11965
+ var SelectScrollUpButton = React29.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
11839
11966
  SelectPrimitive.ScrollUpButton,
11840
11967
  {
11841
11968
  ref,
@@ -11848,7 +11975,7 @@ var SelectScrollUpButton = React28.forwardRef(({ className, ...props }, ref) =>
11848
11975
  }
11849
11976
  ));
11850
11977
  SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
11851
- var SelectScrollDownButton = React28.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
11978
+ var SelectScrollDownButton = React29.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
11852
11979
  SelectPrimitive.ScrollDownButton,
11853
11980
  {
11854
11981
  ref,
@@ -11861,7 +11988,7 @@ var SelectScrollDownButton = React28.forwardRef(({ className, ...props }, ref) =
11861
11988
  }
11862
11989
  ));
11863
11990
  SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
11864
- var SelectContent = React28.forwardRef(({ className, style, children, position = "popper", ...props }, ref) => {
11991
+ var SelectContent = React29.forwardRef(({ className, style, children, position = "popper", ...props }, ref) => {
11865
11992
  const { themeClass, colors: colors2, components } = useTheme();
11866
11993
  return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(SelectPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
11867
11994
  SelectPrimitive.Content,
@@ -11899,7 +12026,7 @@ var SelectContent = React28.forwardRef(({ className, style, children, position =
11899
12026
  ) });
11900
12027
  });
11901
12028
  SelectContent.displayName = SelectPrimitive.Content.displayName;
11902
- var SelectLabel = React28.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
12029
+ var SelectLabel = React29.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
11903
12030
  SelectPrimitive.Label,
11904
12031
  {
11905
12032
  ref,
@@ -11911,7 +12038,7 @@ var SelectLabel = React28.forwardRef(({ className, ...props }, ref) => /* @__PUR
11911
12038
  }
11912
12039
  ));
11913
12040
  SelectLabel.displayName = SelectPrimitive.Label.displayName;
11914
- var SelectItem = React28.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
12041
+ var SelectItem = React29.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
11915
12042
  SelectPrimitive.Item,
11916
12043
  {
11917
12044
  ref,
@@ -11927,7 +12054,7 @@ var SelectItem = React28.forwardRef(({ className, children, ...props }, ref) =>
11927
12054
  }
11928
12055
  ));
11929
12056
  SelectItem.displayName = SelectPrimitive.Item.displayName;
11930
- var SelectSeparator = React28.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
12057
+ var SelectSeparator = React29.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
11931
12058
  SelectPrimitive.Separator,
11932
12059
  {
11933
12060
  ref,
@@ -12385,7 +12512,7 @@ function TransferCryptoDoubleInput({
12385
12512
  }
12386
12513
 
12387
12514
  // src/components/deposits/WalletConnect.tsx
12388
- var React29 = __toESM(require("react"));
12515
+ var React30 = __toESM(require("react"));
12389
12516
  var import_lucide_react28 = require("lucide-react");
12390
12517
  var import_core28 = require("@unifold/core");
12391
12518
 
@@ -13484,6 +13611,19 @@ var WALLET_DEFINITIONS = [
13484
13611
  { id: "backpack", name: "Backpack", networks: ["solana"], installUrl: "https://backpack.app/" },
13485
13612
  { id: "glow", name: "Glow", networks: ["solana"], installUrl: "https://glow.app/" }
13486
13613
  ];
13614
+ function normalizeTokenAddress(address) {
13615
+ const normalized = (address ?? "").toLowerCase();
13616
+ if (normalized === "" || normalized === "native" || normalized === "0x0000000000000000000000000000000000000000") {
13617
+ return "native";
13618
+ }
13619
+ return normalized;
13620
+ }
13621
+ function balancesRepresentSameToken(a, b) {
13622
+ const tokenA = getTokenFromBalance(a);
13623
+ const tokenB = getTokenFromBalance(b);
13624
+ if (!tokenA || !tokenB) return false;
13625
+ return tokenA.chain_type === tokenB.chain_type && tokenA.chain_id === tokenB.chain_id && normalizeTokenAddress(tokenA.token_address) === normalizeTokenAddress(tokenB.token_address);
13626
+ }
13487
13627
  function getSolanaProviders() {
13488
13628
  if (typeof window === "undefined") return {};
13489
13629
  const win = window;
@@ -13626,24 +13766,33 @@ function WalletConnect({
13626
13766
  checkoutRemainingBaseUnits,
13627
13767
  stablecoinParity = false,
13628
13768
  productType,
13769
+ defaultSourceChainType,
13770
+ defaultSourceChainId,
13771
+ defaultSourceTokenAddress,
13772
+ defaultSourceSymbol,
13629
13773
  onBack: parentOnBack,
13630
13774
  onClose,
13775
+ canGoBack = true,
13776
+ depositWalletsLoading = false,
13631
13777
  onExecutionsChange
13632
13778
  }) {
13633
13779
  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);
13780
+ const walletProvidedAtMount = React30.useRef(!!initialWalletInfo && !!initialDepositWallet);
13781
+ const [activeWalletInfo, setActiveWalletInfo] = React30.useState(initialWalletInfo ?? null);
13782
+ const [activeDepositWallet, setActiveDepositWallet] = React30.useState(initialDepositWallet ?? null);
13637
13783
  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(() => {
13784
+ const [view, setView] = React30.useState(initialView);
13785
+ const [isTransitioning, setIsTransitioning] = React30.useState(false);
13786
+ const viewRef = React30.useRef(initialView);
13787
+ const standalone = !canGoBack && !walletProvidedAtMount.current;
13788
+ const { wallet: detectedWallet, isLoading: detectingWallet } = useDetectedBrowserWallet({ enabled: standalone });
13789
+ const [autoResolved, setAutoResolved] = React30.useState(false);
13790
+ const [selectedWalletDef, setSelectedWalletDef] = React30.useState(null);
13791
+ const [connectingNetwork, setConnectingNetwork] = React30.useState(null);
13792
+ const [walletError, setWalletError] = React30.useState(null);
13793
+ const [isWalletConnecting, setIsWalletConnecting] = React30.useState(false);
13794
+ const [eip6963ProviderCount, setEip6963ProviderCount] = React30.useState(0);
13795
+ React30.useEffect(() => {
13647
13796
  const store = getEip6963Store();
13648
13797
  if (!store) return;
13649
13798
  setEip6963ProviderCount(store.getProviders().length);
@@ -13651,20 +13800,44 @@ function WalletConnect({
13651
13800
  setEip6963ProviderCount(providers.length);
13652
13801
  });
13653
13802
  }, []);
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);
13803
+ const availableWallets = React30.useMemo(() => detectAvailableWallets(), [eip6963ProviderCount]);
13804
+ React30.useEffect(() => {
13805
+ if (!standalone || autoResolved || detectingWallet) return;
13806
+ if (!detectedWallet) {
13807
+ setAutoResolved(true);
13808
+ return;
13809
+ }
13810
+ const wct = detectedWallet.type === "phantom-solana" || detectedWallet.type === "solflare" || detectedWallet.type === "backpack" || detectedWallet.type === "glow" ? "solana" : "ethereum";
13811
+ const matching = depositWallets?.find((w) => w.chain_type === wct);
13812
+ if (!matching) {
13813
+ if (!depositWalletsLoading) setAutoResolved(true);
13814
+ return;
13815
+ }
13816
+ setActiveWalletInfo(detectedWallet);
13817
+ setActiveDepositWallet(matching);
13818
+ onWalletConnected?.(detectedWallet, matching);
13819
+ setView("select_token");
13820
+ viewRef.current = "select_token";
13821
+ setAutoResolved(true);
13822
+ }, [standalone, autoResolved, detectingWallet, detectedWallet, depositWallets, depositWalletsLoading]);
13823
+ React30.useEffect(() => {
13824
+ if (!standalone || autoResolved) return;
13825
+ const t12 = setTimeout(() => setAutoResolved(true), 5e3);
13826
+ return () => clearTimeout(t12);
13827
+ }, [standalone, autoResolved]);
13828
+ const [balances, setBalances] = React30.useState([]);
13829
+ const [isLoading, setIsLoading] = React30.useState(false);
13830
+ const [selectedBalance, setSelectedBalance] = React30.useState(null);
13831
+ const [totalBalanceUsd, setTotalBalanceUsd] = React30.useState(null);
13832
+ const [error, setError] = React30.useState(null);
13833
+ const [isDisconnectingWallet, setIsDisconnectingWallet] = React30.useState(false);
13834
+ const [amountUsd, setAmountUsd] = React30.useState(prefillAmountUsd ?? "");
13835
+ const [isConfirming, setIsConfirming] = React30.useState(false);
13836
+ const [hasSignedTransaction, setHasSignedTransaction] = React30.useState(false);
13837
+ const [tokenChainDetails, setTokenChainDetails] = React30.useState(null);
13838
+ const [loadingTokenDetails, setLoadingTokenDetails] = React30.useState(false);
13839
+ const [showTransactionDetails, setShowTransactionDetails] = React30.useState(false);
13840
+ const [receivedUsdAtSubmission, setReceivedUsdAtSubmission] = React30.useState(null);
13668
13841
  const walletInfo = activeWalletInfo;
13669
13842
  const depositWallet = activeDepositWallet;
13670
13843
  const hasWallet = !!activeWalletInfo && !!activeDepositWallet;
@@ -13672,7 +13845,7 @@ function WalletConnect({
13672
13845
  const recipientAddress = activeDepositWallet?.address ?? "";
13673
13846
  const isCheckoutMode = !!checkoutAmountUsd;
13674
13847
  const supportedChainType = chainType === "algorand" || chainType === "xrpl" ? "ethereum" : chainType;
13675
- const transitionTo = React29.useCallback((nextView) => {
13848
+ const transitionTo = React30.useCallback((nextView) => {
13676
13849
  if (nextView === viewRef.current) return;
13677
13850
  setIsTransitioning(true);
13678
13851
  setTimeout(() => {
@@ -13757,6 +13930,7 @@ function WalletConnect({
13757
13930
  metamask: "metamask"
13758
13931
  };
13759
13932
  const walletType = walletIdToType[wallet.id] || "metamask";
13933
+ setStoredWalletState(walletType);
13760
13934
  connectedInfo = { type: walletType, name: wallet.name, address: accounts[0], icon: wallet.id };
13761
13935
  } else {
13762
13936
  const solProviders = getSolanaProviders();
@@ -13785,6 +13959,7 @@ function WalletConnect({
13785
13959
  const response = await provider.connect();
13786
13960
  setUserDisconnectedWallet(false);
13787
13961
  const walletType = wallet.id === "solflare" ? "solflare" : wallet.id === "backpack" ? "backpack" : wallet.id === "glow" ? "glow" : "phantom-solana";
13962
+ setStoredWalletState(walletType);
13788
13963
  connectedInfo = { type: walletType, name: wallet.name, address: response.publicKey.toString(), icon: wallet.id };
13789
13964
  }
13790
13965
  const walletChainType = network === "solana" ? "solana" : "ethereum";
@@ -13809,7 +13984,7 @@ function WalletConnect({
13809
13984
  }
13810
13985
  };
13811
13986
  const selectedToken = selectedBalance ? getTokenFromBalance(selectedBalance) : null;
13812
- const effectiveDestinationAmount = React29.useMemo(() => {
13987
+ const effectiveDestinationAmount = React30.useMemo(() => {
13813
13988
  if (!checkoutRemainingBaseUnits || checkoutRemainingBaseUnits === "0") return "0";
13814
13989
  if (!checkoutAmountUsd) return checkoutRemainingBaseUnits;
13815
13990
  const remaining = BigInt(checkoutRemainingBaseUnits);
@@ -13837,7 +14012,7 @@ function WalletConnect({
13837
14012
  stablecoinParity,
13838
14013
  enabled: isCheckoutMode && !!selectedToken && !!checkoutDestination && effectiveDestinationAmount !== "0"
13839
14014
  });
13840
- const activeCheckoutQuote = React29.useMemo(() => {
14015
+ const activeCheckoutQuote = React30.useMemo(() => {
13841
14016
  if (!isCheckoutMode) return null;
13842
14017
  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
14018
  return checkoutQuote ?? null;
@@ -13851,19 +14026,19 @@ function WalletConnect({
13851
14026
  onDepositSuccess,
13852
14027
  onDepositError
13853
14028
  });
13854
- React29.useEffect(() => {
14029
+ React30.useEffect(() => {
13855
14030
  onExecutionsChange?.(depositExecutions);
13856
14031
  }, [depositExecutions, onExecutionsChange]);
13857
- React29.useEffect(() => {
14032
+ React30.useEffect(() => {
13858
14033
  if (!prefillAmountUsd || !tokenChainDetails || view !== "enter_amount") return;
13859
14034
  const minDeposit = tokenChainDetails.minimum_deposit_amount_usd || 0;
13860
14035
  const currentAmount = parseFloat(amountUsd) || 0;
13861
14036
  if (currentAmount > 0 && currentAmount < minDeposit) setAmountUsd(minDeposit.toFixed(2));
13862
14037
  }, [tokenChainDetails, view, prefillAmountUsd]);
13863
- React29.useEffect(() => {
14038
+ React30.useEffect(() => {
13864
14039
  if (view === "review") setShowTransactionDetails(false);
13865
14040
  }, [view]);
13866
- React29.useEffect(() => {
14041
+ React30.useEffect(() => {
13867
14042
  if (view !== "enter_amount" && view !== "review" || !selectedBalance || !activeDepositWallet) return;
13868
14043
  let cancelled = false;
13869
14044
  const fetchTokenDetails = async () => {
@@ -13890,7 +14065,7 @@ function WalletConnect({
13890
14065
  cancelled = true;
13891
14066
  };
13892
14067
  }, [view, selectedBalance, publishableKey, activeDepositWallet]);
13893
- React29.useEffect(() => {
14068
+ React30.useEffect(() => {
13894
14069
  if (!activeWalletInfo || !activeDepositWallet) return;
13895
14070
  let cancelled = false;
13896
14071
  setIsLoading(true);
@@ -13899,18 +14074,33 @@ function WalletConnect({
13899
14074
  (0, import_core28.getAddressBalances)(activeWalletInfo.address, sct, publishableKey).then((response) => {
13900
14075
  if (cancelled) return;
13901
14076
  const nonZero = response.balances.filter((b) => b.amount !== "0");
13902
- const sorted = [...nonZero].sort((a, b) => {
13903
- const ae = isBalanceEligible(a);
13904
- const be = isBalanceEligible(b);
13905
- if (ae && !be) return -1;
13906
- if (!ae && be) return 1;
13907
- return 0;
13908
- });
14077
+ const defaultSource = {
14078
+ defaultSourceChainType,
14079
+ defaultSourceChainId,
14080
+ defaultSourceTokenAddress,
14081
+ defaultSourceSymbol
14082
+ };
14083
+ const sorted = [...nonZero].sort(
14084
+ (a, b) => compareBalancesWithDefaultSource(a, b, defaultSource)
14085
+ );
13909
14086
  setBalances(sorted);
13910
14087
  const totalUsd = nonZero.reduce((sum, b) => b.amount_usd ? sum + parseFloat(b.amount_usd) : sum, 0);
13911
14088
  if (totalUsd > 0) setTotalBalanceUsd(totalUsd.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 }));
13912
14089
  const eligible = sorted.filter(isBalanceEligible);
13913
- if (eligible.length === 1) setSelectedBalance(eligible[0]);
14090
+ const defaultBalance = sorted.find(
14091
+ (balance) => isDefaultSourceBalance(balance, defaultSource)
14092
+ );
14093
+ setSelectedBalance((current) => {
14094
+ if (current) {
14095
+ const currentInNewBalances = sorted.find(
14096
+ (balance) => balancesRepresentSameToken(balance, current)
14097
+ );
14098
+ if (currentInNewBalances) return currentInNewBalances;
14099
+ }
14100
+ if (defaultBalance) return defaultBalance;
14101
+ if (eligible.length === 1) return eligible[0];
14102
+ return null;
14103
+ });
13914
14104
  }).catch((err) => {
13915
14105
  if (!cancelled) {
13916
14106
  console.error("[WalletConnect] Error fetching balances:", err);
@@ -13922,21 +14112,29 @@ function WalletConnect({
13922
14112
  return () => {
13923
14113
  cancelled = true;
13924
14114
  };
13925
- }, [activeWalletInfo?.address, activeDepositWallet?.chain_type, publishableKey]);
13926
- const usdToTokenRate = React29.useMemo(() => {
14115
+ }, [
14116
+ activeWalletInfo?.address,
14117
+ activeDepositWallet?.chain_type,
14118
+ publishableKey,
14119
+ defaultSourceChainType,
14120
+ defaultSourceChainId,
14121
+ defaultSourceTokenAddress,
14122
+ defaultSourceSymbol
14123
+ ]);
14124
+ const usdToTokenRate = React30.useMemo(() => {
13927
14125
  if (!selectedBalance || !selectedBalance.amount_usd || !selectedToken) return 0;
13928
14126
  const balanceAmount = Number(selectedBalance.amount) / 10 ** selectedToken.decimals;
13929
14127
  const balanceUsd = parseFloat(selectedBalance.amount_usd);
13930
14128
  if (balanceAmount === 0 || balanceUsd === 0) return 0;
13931
14129
  return balanceAmount / balanceUsd;
13932
14130
  }, [selectedBalance, selectedToken]);
13933
- const tokenAmount = React29.useMemo(() => {
14131
+ const tokenAmount = React30.useMemo(() => {
13934
14132
  if (isCheckoutMode && activeCheckoutQuote && selectedToken) return Number(activeCheckoutQuote.sourceAmount) / 10 ** activeCheckoutQuote.sourceTokenDecimals;
13935
14133
  const usdNum = parseFloat(amountUsd) || 0;
13936
14134
  if (usdNum === 0 || usdToTokenRate === 0) return 0;
13937
14135
  return usdNum * usdToTokenRate;
13938
14136
  }, [amountUsd, usdToTokenRate, isCheckoutMode, activeCheckoutQuote, selectedToken]);
13939
- React29.useEffect(() => {
14137
+ React30.useEffect(() => {
13940
14138
  if (isCheckoutMode && activeCheckoutQuote?.sourceAmountUsd && view === "enter_amount") setAmountUsd(activeCheckoutQuote.sourceAmountUsd);
13941
14139
  }, [isCheckoutMode, activeCheckoutQuote, view]);
13942
14140
  const maxTokenAmount = selectedBalance && selectedToken ? Number(selectedBalance.amount) / 10 ** selectedToken.decimals : 0;
@@ -13944,7 +14142,7 @@ function WalletConnect({
13944
14142
  const inputUsdNum = parseFloat(amountUsd) || 0;
13945
14143
  const minDepositUsd = tokenChainDetails?.minimum_deposit_amount_usd || 0;
13946
14144
  const isValidAmount = isCheckoutMode && activeCheckoutQuote ? tokenAmount > 0 && tokenAmount <= maxTokenAmount : inputUsdNum > 0 && inputUsdNum <= maxUsdAmount && inputUsdNum >= minDepositUsd;
13947
- const formattedTokenAmount = React29.useMemo(() => {
14145
+ const formattedTokenAmount = React30.useMemo(() => {
13948
14146
  if (tokenAmount === 0 || !selectedToken) return null;
13949
14147
  return `${tokenAmount.toFixed(6)} ${selectedToken.symbol}`.replace(/\.?0+$/, "");
13950
14148
  }, [tokenAmount, selectedToken]);
@@ -13992,16 +14190,25 @@ function WalletConnect({
13992
14190
  } catch (err) {
13993
14191
  console.warn("[WalletConnect] disconnect error:", err);
13994
14192
  } finally {
13995
- setActiveWalletInfo(null);
13996
- setActiveDepositWallet(null);
13997
- setSelectedBalance(null);
13998
- setBalances([]);
13999
- setTotalBalanceUsd(null);
14000
- setAmountUsd(prefillAmountUsd ?? "");
14001
- setError(null);
14002
14193
  setIsDisconnectingWallet(false);
14003
- if (onWalletDisconnect) onWalletDisconnect();
14004
- else parentOnBack?.();
14194
+ const clearWalletState = () => {
14195
+ setActiveWalletInfo(null);
14196
+ setActiveDepositWallet(null);
14197
+ setSelectedBalance(null);
14198
+ setBalances([]);
14199
+ setTotalBalanceUsd(null);
14200
+ setAmountUsd(prefillAmountUsd ?? "");
14201
+ setError(null);
14202
+ };
14203
+ if (standalone) {
14204
+ onWalletDisconnect?.();
14205
+ transitionTo("select_wallet");
14206
+ setTimeout(clearWalletState, 160);
14207
+ } else {
14208
+ clearWalletState();
14209
+ if (onWalletDisconnect) onWalletDisconnect();
14210
+ else parentOnBack?.();
14211
+ }
14005
14212
  }
14006
14213
  };
14007
14214
  const handleReview = () => {
@@ -14127,9 +14334,15 @@ function WalletConnect({
14127
14334
  setIsConfirming(false);
14128
14335
  }
14129
14336
  };
14337
+ if (standalone && !autoResolved) {
14338
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { style: viewTransitionStyle, children: [
14339
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(DepositHeader, { title: "Connect Wallet", showBack: canGoBack, onBack: handleBack, onClose }),
14340
+ /* @__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 } }) })
14341
+ ] });
14342
+ }
14130
14343
  if (view === "select_wallet") {
14131
14344
  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 }),
14345
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(DepositHeader, { title: "Connect Wallet", showBack: canGoBack, onBack: handleBack, onClose }),
14133
14346
  /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "uf-pb-4", children: [
14134
14347
  /* @__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
14348
  /* @__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)(
@@ -14265,16 +14478,17 @@ function DepositModal({
14265
14478
  defaultSourceChainId,
14266
14479
  defaultSourceTokenAddress,
14267
14480
  defaultSourceSymbol,
14268
- hideDepositTracker = false,
14481
+ hideDepositTracker,
14269
14482
  showBalanceHeader = false,
14270
14483
  transferInputVariant = "double_input",
14271
14484
  depositConfirmationMode = "auto_ui",
14272
- enableConnectWallet = false,
14485
+ enableTransferCrypto,
14486
+ enableConnectWallet,
14273
14487
  browserWalletAmountQuickSelect = "percentage",
14274
14488
  enablePayWithExchange,
14275
14489
  enableFiatOnramp,
14276
- enableConnectExchange = false,
14277
- enableCashApp = false,
14490
+ enableConnectExchange,
14491
+ enableCashApp,
14278
14492
  hideDepositFlowInfo = false,
14279
14493
  hideDisplayDescription = false,
14280
14494
  onDepositSuccess,
@@ -14292,11 +14506,23 @@ function DepositModal({
14292
14506
  const { colors: colors2, fonts, components } = useTheme();
14293
14507
  const effectiveInitialScreen = (0, import_react20.useMemo)(() => {
14294
14508
  const s = initialScreen ?? "main";
14295
- if (s === "tracker" && hideDepositTracker) return "main";
14296
- if (s === "cashapp" && !enableCashApp) return "main";
14509
+ if (s === "tracker" && hideDepositTracker === true) return "main";
14510
+ if (s === "cashapp" && enableCashApp === false) return "main";
14297
14511
  if (s === "card" && enableFiatOnramp === false) return "main";
14512
+ if (s === "pay_with_exchange") return enablePayWithExchange === false ? "main" : "exchange";
14513
+ if (s === "exchange_connect")
14514
+ return enableConnectExchange === false ? "main" : "coinbase_connect";
14515
+ if (s === "wallet_connect") return enableConnectWallet === false ? "main" : "wallet_connect";
14298
14516
  return s;
14299
- }, [initialScreen, hideDepositTracker, enableCashApp, enableFiatOnramp]);
14517
+ }, [
14518
+ initialScreen,
14519
+ hideDepositTracker,
14520
+ enableCashApp,
14521
+ enableFiatOnramp,
14522
+ enablePayWithExchange,
14523
+ enableConnectExchange,
14524
+ enableConnectWallet
14525
+ ]);
14300
14526
  const [containerEl, setContainerEl] = (0, import_react20.useState)(null);
14301
14527
  const containerCallbackRef = (0, import_react20.useCallback)((el) => {
14302
14528
  setContainerEl(el);
@@ -14315,26 +14541,37 @@ function DepositModal({
14315
14541
  const [browserWalletModalOpen, setBrowserWalletModalOpen] = (0, import_react20.useState)(false);
14316
14542
  const [browserWalletInfo, setBrowserWalletInfo] = (0, import_react20.useState)(null);
14317
14543
  const [walletSelectionModalOpen, setWalletSelectionModalOpen] = (0, import_react20.useState)(false);
14318
- const [browserWalletChainType, setBrowserWalletChainType] = (0, import_react20.useState)(() => getStoredWalletChainType());
14544
+ const [browserWalletChainType, setBrowserWalletChainType] = (0, import_react20.useState)(() => getStoredWalletState()?.chainType);
14319
14545
  const [quotesCount, setQuotesCount] = (0, import_react20.useState)(0);
14320
14546
  const [allExecutions, setAllExecutions] = (0, import_react20.useState)([]);
14321
14547
  const [selectedExecution, setSelectedExecution] = (0, import_react20.useState)(null);
14322
14548
  const [depositExecutions, setDepositExecutions] = (0, import_react20.useState)([]);
14323
14549
  const isMobileView = useIsMobileViewport();
14550
+ const { projectConfig } = useProjectConfig({
14551
+ publishableKey,
14552
+ enabled: open
14553
+ });
14554
+ const showTransferCrypto = enableTransferCrypto ?? projectConfig?.transfer_crypto?.enabled ?? true;
14555
+ const showConnectWallet = enableConnectWallet ?? projectConfig?.connect_wallet?.enabled ?? true;
14556
+ const showPayWithExchange = enablePayWithExchange ?? projectConfig?.pay_with_exchange?.enabled ?? true;
14557
+ const showFiatOnramp = enableFiatOnramp ?? projectConfig?.fiat_onramp?.enabled ?? true;
14558
+ const showConnectExchange = enableConnectExchange ?? projectConfig?.connect_exchange?.enabled ?? true;
14559
+ const showCashApp = enableCashApp ?? projectConfig?.cash_app?.enabled ?? true;
14560
+ const showDepositTracker = hideDepositTracker ? false : projectConfig?.deposit_tracker?.enabled ?? true;
14324
14561
  const [integrationExchanges, setIntegrationExchanges] = (0, import_react20.useState)([]);
14325
14562
  (0, import_react20.useEffect)(() => {
14326
- if (!enableConnectExchange || !open) return;
14563
+ if (!showConnectExchange || !open) return;
14327
14564
  (0, import_core29.getIntegrationExchanges)(publishableKey).then((res) => setIntegrationExchanges(res.data)).catch(() => {
14328
14565
  });
14329
- }, [enableConnectExchange, open, publishableKey]);
14566
+ }, [showConnectExchange, open, publishableKey]);
14330
14567
  const [connectedExchange, setConnectedExchange] = (0, import_react20.useState)(() => {
14331
- if (!enableConnectExchange) return null;
14568
+ if (!showConnectExchange) return null;
14332
14569
  const stored = getStoredIntegrationToken(import_core29.IntegrationProvider.COINBASE);
14333
14570
  if (!stored) return null;
14334
14571
  return { name: "Coinbase", iconUrl: void 0, balanceUsd: null, isLoading: true };
14335
14572
  });
14336
14573
  (0, import_react20.useEffect)(() => {
14337
- if (!enableConnectExchange || !open || view !== "main") return;
14574
+ if (!showConnectExchange || !open || view !== "main") return;
14338
14575
  const stored = getStoredIntegrationToken(import_core29.IntegrationProvider.COINBASE);
14339
14576
  if (!stored) {
14340
14577
  setConnectedExchange(null);
@@ -14369,7 +14606,7 @@ function DepositModal({
14369
14606
  setConnectedExchange(null);
14370
14607
  }
14371
14608
  });
14372
- }, [enableConnectExchange, open, view, publishableKey]);
14609
+ }, [showConnectExchange, open, view, publishableKey]);
14373
14610
  (0, import_react20.useEffect)(() => {
14374
14611
  if (!connectedExchange || integrationExchanges.length === 0) return;
14375
14612
  const cbExchange = integrationExchanges.find(
@@ -14408,18 +14645,39 @@ function DepositModal({
14408
14645
  setResolvedTheme(theme);
14409
14646
  }
14410
14647
  }, [theme]);
14411
- const { projectConfig } = useProjectConfig({
14412
- publishableKey,
14413
- enabled: open
14414
- });
14415
- const showPayWithExchange = enablePayWithExchange ?? projectConfig?.pay_with_exchange?.enabled ?? true;
14416
- const showFiatOnramp = enableFiatOnramp ?? projectConfig?.fiat_onramp?.enabled ?? true;
14417
14648
  (0, import_react20.useEffect)(() => {
14418
14649
  if (view === "card" && !showFiatOnramp) {
14419
14650
  setView("main");
14420
14651
  setCardView("amount");
14652
+ } else if (view === "transfer" && !showTransferCrypto) {
14653
+ setView("main");
14654
+ } else if (view === "exchange" && !showPayWithExchange) {
14655
+ setView("main");
14656
+ } else if (view === "cashapp" && !showCashApp) {
14657
+ setView("main");
14658
+ } else if (view === "tracker" && !showDepositTracker) {
14659
+ setView("main");
14660
+ } else if (view === "coinbase_connect" && !showConnectExchange) {
14661
+ setView("main");
14662
+ } else if (view === "wallet_connect" && !showConnectWallet) {
14663
+ setView("main");
14421
14664
  }
14422
- }, [view, showFiatOnramp]);
14665
+ }, [
14666
+ view,
14667
+ showFiatOnramp,
14668
+ showTransferCrypto,
14669
+ showPayWithExchange,
14670
+ showCashApp,
14671
+ showDepositTracker,
14672
+ showConnectExchange,
14673
+ showConnectWallet
14674
+ ]);
14675
+ (0, import_react20.useEffect)(() => {
14676
+ if (view === "exchange" && !showPayWithExchange) {
14677
+ setView("main");
14678
+ setExchangeView("providers");
14679
+ }
14680
+ }, [view, showPayWithExchange]);
14423
14681
  const { exchanges, isLoading: exchangesLoading } = useExchanges({
14424
14682
  publishableKey,
14425
14683
  enabled: open && showPayWithExchange
@@ -14503,7 +14761,7 @@ function DepositModal({
14503
14761
  depositPrerequisiteBody = standaloneNeedsDepositPrereq ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(SkeletonButton, { variant: "with-icons" }) : /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
14504
14762
  /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(SkeletonButton, { variant: "with-icons" }),
14505
14763
  /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(SkeletonButton, { variant: "with-icons" }),
14506
- !hideDepositTracker && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(SkeletonButton, {})
14764
+ showDepositTracker && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(SkeletonButton, {})
14507
14765
  ] });
14508
14766
  } else if (countryError) {
14509
14767
  depositPrerequisiteBody = /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-8 uf-px-4 uf-text-center", children: [
@@ -14535,11 +14793,11 @@ function DepositModal({
14535
14793
  const themeClass = resolvedTheme === "dark" ? "uf-dark" : "";
14536
14794
  const handleWalletDisconnect = () => {
14537
14795
  setUserDisconnectedWallet(true);
14538
- clearStoredWalletChainType();
14796
+ clearStoredWalletState();
14539
14797
  setBrowserWalletChainType(void 0);
14540
14798
  setBrowserWalletInfo(null);
14541
14799
  setBrowserWalletModalOpen(false);
14542
- if (view === "wallet_connect") setView("main");
14800
+ if (view === "wallet_connect" && sessionOpenedFromMenu) setView("main");
14543
14801
  };
14544
14802
  const handleExchangeDisconnect = () => {
14545
14803
  const stored = getStoredIntegrationToken(import_core29.IntegrationProvider.COINBASE);
@@ -14548,7 +14806,7 @@ function DepositModal({
14548
14806
  }
14549
14807
  clearStoredIntegrationToken(import_core29.IntegrationProvider.COINBASE);
14550
14808
  setConnectedExchange(null);
14551
- if (view === "coinbase_connect") setView("main");
14809
+ if (view === "coinbase_connect" && sessionOpenedFromMenu) setView("main");
14552
14810
  };
14553
14811
  const handleClose = () => {
14554
14812
  onOpenChange(false);
@@ -14560,6 +14818,7 @@ function DepositModal({
14560
14818
  setCardView("amount");
14561
14819
  setExchangeView("providers");
14562
14820
  setBrowserWalletInfo(null);
14821
+ setCoinbaseSkipToHoldings(false);
14563
14822
  resetViewTimeoutRef.current = null;
14564
14823
  }, 200);
14565
14824
  };
@@ -14574,6 +14833,7 @@ function DepositModal({
14574
14833
  setExchangeView("providers");
14575
14834
  setBrowserWalletInfo(null);
14576
14835
  setSelectedExecution(null);
14836
+ setCoinbaseSkipToHoldings(false);
14577
14837
  }, [open, effectiveInitialScreen]);
14578
14838
  (0, import_react20.useEffect)(
14579
14839
  () => () => {
@@ -14611,7 +14871,7 @@ function DepositModal({
14611
14871
  };
14612
14872
  const handleBrowserWalletClick = (walletInfo) => {
14613
14873
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
14614
- setStoredWalletChainType(walletChainType);
14874
+ setStoredWalletState(walletInfo.type);
14615
14875
  setBrowserWalletChainType(walletChainType);
14616
14876
  const matchingDepositWallet = wallets.find(
14617
14877
  (w) => w.chain_type === walletChainType
@@ -14642,7 +14902,7 @@ function DepositModal({
14642
14902
  };
14643
14903
  const handleWalletConnected = (walletInfo) => {
14644
14904
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
14645
- setStoredWalletChainType(walletChainType);
14905
+ setStoredWalletState(walletInfo.type);
14646
14906
  setBrowserWalletChainType(walletChainType);
14647
14907
  const matchingDepositWallet = wallets.find(
14648
14908
  (w) => w.chain_type === walletChainType
@@ -14709,7 +14969,7 @@ function DepositModal({
14709
14969
  ),
14710
14970
  /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
14711
14971
  /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "uf-space-y-3", children: depositPrerequisiteBody ?? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
14712
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
14972
+ showTransferCrypto && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
14713
14973
  TransferCryptoButton,
14714
14974
  {
14715
14975
  onClick: () => setView("transfer"),
@@ -14718,7 +14978,7 @@ function DepositModal({
14718
14978
  featuredTokens: projectConfig?.transfer_crypto.networks
14719
14979
  }
14720
14980
  ),
14721
- enableConnectWallet && !isMobileView && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
14981
+ showConnectWallet && !isMobileView && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
14722
14982
  BrowserWalletButton,
14723
14983
  {
14724
14984
  onClick: handleBrowserWalletClick,
@@ -14748,7 +15008,7 @@ function DepositModal({
14748
15008
  loading: exchangesLoading
14749
15009
  }
14750
15010
  ),
14751
- enableConnectExchange && connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15011
+ showConnectExchange && connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
14752
15012
  ConnectExchangeButton,
14753
15013
  {
14754
15014
  onClick: () => {
@@ -14762,7 +15022,7 @@ function DepositModal({
14762
15022
  connectedExchange
14763
15023
  }
14764
15024
  ),
14765
- enableConnectExchange && !connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15025
+ showConnectExchange && !connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
14766
15026
  ConnectExchangeButton,
14767
15027
  {
14768
15028
  onClick: () => {
@@ -14774,7 +15034,7 @@ function DepositModal({
14774
15034
  exchanges: integrationExchanges
14775
15035
  }
14776
15036
  ),
14777
- enableCashApp && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15037
+ showCashApp && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
14778
15038
  CashAppButton,
14779
15039
  {
14780
15040
  onClick: () => setView("cashapp"),
@@ -14783,7 +15043,7 @@ function DepositModal({
14783
15043
  iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
14784
15044
  }
14785
15045
  ),
14786
- !hideDepositTracker && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
15046
+ showDepositTracker && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
14787
15047
  DepositTrackerButton,
14788
15048
  {
14789
15049
  onClick: () => {
@@ -14933,7 +15193,7 @@ function DepositModal({
14933
15193
  DepositHeader,
14934
15194
  {
14935
15195
  title: payWithExchangeTitle,
14936
- showBack: true,
15196
+ showBack: exchangeView === "pending" || sessionOpenedFromMenu,
14937
15197
  onBack: handleBack,
14938
15198
  onClose: handleClose
14939
15199
  }
@@ -14987,7 +15247,12 @@ function DepositModal({
14987
15247
  onClose: handleClose,
14988
15248
  onDisconnect: handleExchangeDisconnect,
14989
15249
  skipToHoldings: coinbaseSkipToHoldings,
14990
- onExecutionsChange: setDepositExecutions
15250
+ canGoBack: sessionOpenedFromMenu,
15251
+ onExecutionsChange: setDepositExecutions,
15252
+ defaultSourceChainType,
15253
+ defaultSourceChainId,
15254
+ defaultSourceTokenAddress,
15255
+ defaultSourceSymbol
14991
15256
  }
14992
15257
  ),
14993
15258
  depositPoweredByFooter
@@ -15020,11 +15285,17 @@ function DepositModal({
15020
15285
  onWalletDisconnect: handleWalletDisconnect,
15021
15286
  onWalletConnected: (info, dw) => {
15022
15287
  setBrowserWalletInfo({ ...info, depositWallet: dw });
15023
- setStoredWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
15288
+ setStoredWalletState(info.type);
15024
15289
  setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
15025
15290
  },
15026
15291
  onBack: handleBack,
15027
- onClose: handleClose
15292
+ onClose: handleClose,
15293
+ defaultSourceChainType,
15294
+ defaultSourceChainId,
15295
+ defaultSourceTokenAddress,
15296
+ defaultSourceSymbol,
15297
+ canGoBack: sessionOpenedFromMenu,
15298
+ depositWalletsLoading: walletsLoading
15028
15299
  }
15029
15300
  ),
15030
15301
  depositPoweredByFooter
@@ -15033,7 +15304,7 @@ function DepositModal({
15033
15304
  DepositHeader,
15034
15305
  {
15035
15306
  title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
15036
- showBack: true,
15307
+ showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
15037
15308
  onBack: handleBack,
15038
15309
  onClose: handleClose
15039
15310
  }
@@ -15136,7 +15407,8 @@ function CheckoutModal({
15136
15407
  clientSecret,
15137
15408
  publishableKey,
15138
15409
  modalTitle,
15139
- enableConnectWallet = false,
15410
+ enableTransferCrypto,
15411
+ enableConnectWallet,
15140
15412
  defaultSourceChainType,
15141
15413
  defaultSourceChainId,
15142
15414
  defaultSourceTokenAddress,
@@ -15153,7 +15425,7 @@ function CheckoutModal({
15153
15425
  const [browserWalletModalOpen, setBrowserWalletModalOpen] = (0, import_react21.useState)(false);
15154
15426
  const [browserWalletInfo, setBrowserWalletInfo] = (0, import_react21.useState)(null);
15155
15427
  const [walletSelectionModalOpen, setWalletSelectionModalOpen] = (0, import_react21.useState)(false);
15156
- const [browserWalletChainType, setBrowserWalletChainType] = (0, import_react21.useState)(() => getStoredWalletChainType());
15428
+ const [browserWalletChainType, setBrowserWalletChainType] = (0, import_react21.useState)(() => getStoredWalletState()?.chainType);
15157
15429
  const isMobileView = useIsMobileViewport();
15158
15430
  const [resolvedTheme, setResolvedTheme] = (0, import_react21.useState)(
15159
15431
  theme === "auto" ? "dark" : theme
@@ -15186,6 +15458,15 @@ function CheckoutModal({
15186
15458
  publishableKey,
15187
15459
  enabled: open
15188
15460
  });
15461
+ const showTransferCrypto = enableTransferCrypto ?? projectConfig?.transfer_crypto?.enabled ?? true;
15462
+ const showConnectWallet = enableConnectWallet ?? projectConfig?.connect_wallet?.enabled ?? true;
15463
+ (0, import_react21.useEffect)(() => {
15464
+ if (view === "transfer" && !showTransferCrypto) {
15465
+ setView("main");
15466
+ } else if (view === "wallet_connect" && !showConnectWallet) {
15467
+ setView("main");
15468
+ }
15469
+ }, [showConnectWallet, showTransferCrypto, view]);
15189
15470
  const prevStatusRef = (0, import_react21.useRef)(null);
15190
15471
  (0, import_react21.useEffect)(() => {
15191
15472
  if (!paymentIntent) return;
@@ -15276,7 +15557,7 @@ function CheckoutModal({
15276
15557
  const handleBrowserWalletClick = (0, import_react21.useCallback)(
15277
15558
  (walletInfo) => {
15278
15559
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
15279
- setStoredWalletChainType(walletChainType);
15560
+ setStoredWalletState(walletInfo.type);
15280
15561
  setBrowserWalletChainType(walletChainType);
15281
15562
  const matchingDepositWallet = wallets.find(
15282
15563
  (w) => w.chain_type === walletChainType
@@ -15303,7 +15584,7 @@ function CheckoutModal({
15303
15584
  const handleWalletConnected = (0, import_react21.useCallback)(
15304
15585
  (walletInfo) => {
15305
15586
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
15306
- setStoredWalletChainType(walletChainType);
15587
+ setStoredWalletState(walletInfo.type);
15307
15588
  setBrowserWalletChainType(walletChainType);
15308
15589
  const matchingDepositWallet = wallets.find(
15309
15590
  (w) => w.chain_type === walletChainType
@@ -15327,7 +15608,7 @@ function CheckoutModal({
15327
15608
  );
15328
15609
  const handleWalletDisconnect = (0, import_react21.useCallback)(() => {
15329
15610
  setUserDisconnectedWallet(true);
15330
- clearStoredWalletChainType();
15611
+ clearStoredWalletState();
15331
15612
  setBrowserWalletChainType(void 0);
15332
15613
  setBrowserWalletInfo(null);
15333
15614
  setBrowserWalletModalOpen(false);
@@ -15562,7 +15843,7 @@ function CheckoutModal({
15562
15843
  ] }) : paymentIntent ? /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "uf-space-y-3", children: [
15563
15844
  progressSection,
15564
15845
  (paymentIntent.status === "requires_payment" || paymentIntent.status === "processing") && /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_jsx_runtime56.Fragment, { children: [
15565
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
15846
+ showTransferCrypto && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
15566
15847
  TransferCryptoButton,
15567
15848
  {
15568
15849
  onClick: () => setView("transfer"),
@@ -15571,7 +15852,7 @@ function CheckoutModal({
15571
15852
  featuredTokens: projectConfig?.transfer_crypto.networks
15572
15853
  }
15573
15854
  ),
15574
- enableConnectWallet && !isMobileView && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
15855
+ showConnectWallet && !isMobileView && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
15575
15856
  BrowserWalletButton,
15576
15857
  {
15577
15858
  onClick: handleBrowserWalletClick,
@@ -15712,14 +15993,18 @@ function CheckoutModal({
15712
15993
  onWalletDisconnect: handleWalletDisconnect,
15713
15994
  onWalletConnected: (info, dw) => {
15714
15995
  setBrowserWalletInfo({ ...info, depositWallet: dw });
15715
- setStoredWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
15996
+ setStoredWalletState(info.type);
15716
15997
  setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
15717
15998
  },
15718
15999
  onNewDeposit: () => setView("main"),
15719
16000
  onDone: () => setView("main"),
15720
16001
  paymentIntentStatus: paymentIntent.status,
15721
16002
  onBack: handleBack,
15722
- onClose: handleClose
16003
+ onClose: handleClose,
16004
+ defaultSourceChainType,
16005
+ defaultSourceChainId,
16006
+ defaultSourceTokenAddress,
16007
+ defaultSourceSymbol
15723
16008
  }
15724
16009
  ),
15725
16010
  poweredByFooter