@unifold/ui-react 0.1.62 → 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.mjs CHANGED
@@ -20,8 +20,32 @@ import { twMerge } from "tailwind-merge";
20
20
  function cn(...inputs) {
21
21
  return twMerge(clsx(inputs));
22
22
  }
23
- var WALLET_CHAIN_TYPE_STORAGE_KEY = "unifold_last_wallet_type";
23
+ var WALLET_STATE_STORAGE_KEY = "unifold_wallet_state";
24
+ var LEGACY_WALLET_KEYS = [
25
+ "unifold_last_wallet_type",
26
+ "unifold_last_connected_wallet"
27
+ ];
24
28
  var WALLET_USER_DISCONNECTED_KEY = "unifold_wallet_user_disconnected";
29
+ var SOLANA_WALLET_TYPES = /* @__PURE__ */ new Set([
30
+ "phantom-solana",
31
+ "solflare",
32
+ "backpack",
33
+ "glow"
34
+ ]);
35
+ var ETHEREUM_WALLET_TYPES = /* @__PURE__ */ new Set([
36
+ "metamask",
37
+ "phantom-ethereum",
38
+ "coinbase",
39
+ "trust",
40
+ "rainbow",
41
+ "rabby",
42
+ "okx"
43
+ ]);
44
+ function walletTypeToChain(t12) {
45
+ if (SOLANA_WALLET_TYPES.has(t12)) return "solana";
46
+ if (ETHEREUM_WALLET_TYPES.has(t12)) return "ethereum";
47
+ return void 0;
48
+ }
25
49
  function getUserDisconnectedWallet() {
26
50
  if (typeof window === "undefined") return false;
27
51
  try {
@@ -41,26 +65,35 @@ function setUserDisconnectedWallet(disconnected) {
41
65
  } catch {
42
66
  }
43
67
  }
44
- function getStoredWalletChainType() {
68
+ function getStoredWalletState() {
45
69
  if (typeof window === "undefined") return void 0;
46
70
  try {
47
- const stored = localStorage.getItem(WALLET_CHAIN_TYPE_STORAGE_KEY);
48
- if (stored === "ethereum" || stored === "solana") return stored;
71
+ const raw = localStorage.getItem(WALLET_STATE_STORAGE_KEY);
72
+ if (!raw) return void 0;
73
+ const chainType = walletTypeToChain(raw);
74
+ if (!chainType) {
75
+ localStorage.removeItem(WALLET_STATE_STORAGE_KEY);
76
+ return void 0;
77
+ }
78
+ return { walletType: raw, chainType };
49
79
  } catch {
80
+ return void 0;
50
81
  }
51
- return void 0;
52
82
  }
53
- function setStoredWalletChainType(chainType) {
83
+ function setStoredWalletState(walletType) {
54
84
  if (typeof window === "undefined") return;
85
+ if (!walletTypeToChain(walletType)) return;
55
86
  try {
56
- localStorage.setItem(WALLET_CHAIN_TYPE_STORAGE_KEY, chainType);
87
+ localStorage.setItem(WALLET_STATE_STORAGE_KEY, walletType);
88
+ for (const key of LEGACY_WALLET_KEYS) localStorage.removeItem(key);
57
89
  } catch {
58
90
  }
59
91
  }
60
- function clearStoredWalletChainType() {
92
+ function clearStoredWalletState() {
61
93
  if (typeof window === "undefined") return;
62
94
  try {
63
- localStorage.removeItem(WALLET_CHAIN_TYPE_STORAGE_KEY);
95
+ localStorage.removeItem(WALLET_STATE_STORAGE_KEY);
96
+ for (const key of LEGACY_WALLET_KEYS) localStorage.removeItem(key);
64
97
  } catch {
65
98
  }
66
99
  }
@@ -674,7 +707,63 @@ import { useEffect as useEffect2, useLayoutEffect, useState as useState2 } from
674
707
  import { getAddressBalance } from "@unifold/core";
675
708
 
676
709
  // src/components/deposits/browser-wallets/utils.ts
677
- import { IneligibilityReason } from "@unifold/core";
710
+ import {
711
+ IneligibilityReason
712
+ } from "@unifold/core";
713
+ var normalize = (value) => value?.toLowerCase();
714
+ function sourceTokenMatchesDefaultSource(token, defaultSource) {
715
+ if (!token || !defaultSource.defaultSourceChainType || !defaultSource.defaultSourceChainId) {
716
+ return false;
717
+ }
718
+ if (token.chain_type !== defaultSource.defaultSourceChainType || token.chain_id !== defaultSource.defaultSourceChainId) {
719
+ return false;
720
+ }
721
+ if (defaultSource.defaultSourceTokenAddress && normalize(token.token_address) === normalize(defaultSource.defaultSourceTokenAddress)) {
722
+ return true;
723
+ }
724
+ if (defaultSource.defaultSourceTokenAddress) {
725
+ return false;
726
+ }
727
+ return !!defaultSource.defaultSourceSymbol && normalize(token.symbol) === normalize(defaultSource.defaultSourceSymbol);
728
+ }
729
+ function isDefaultSourceBalance(balance, defaultSource) {
730
+ return isBalanceEligible(balance) && sourceTokenMatchesDefaultSource(getTokenFromBalance(balance), defaultSource);
731
+ }
732
+ function compareBalancesWithDefaultSource(a, b, defaultSource) {
733
+ const aDefault = isDefaultSourceBalance(a, defaultSource);
734
+ const bDefault = isDefaultSourceBalance(b, defaultSource);
735
+ if (aDefault && !bDefault) return -1;
736
+ if (!aDefault && bDefault) return 1;
737
+ const aEligible = isBalanceEligible(a);
738
+ const bEligible = isBalanceEligible(b);
739
+ if (aEligible && !bEligible) return -1;
740
+ if (!aEligible && bEligible) return 1;
741
+ return 0;
742
+ }
743
+ function resolveDefaultSourceSymbol(supportedTokens, defaultSource) {
744
+ if (!supportedTokens?.length || !defaultSource.defaultSourceChainType || !defaultSource.defaultSourceChainId) {
745
+ return null;
746
+ }
747
+ if (defaultSource.defaultSourceTokenAddress) {
748
+ for (const token of supportedTokens) {
749
+ const matchingChain = token.chains.find(
750
+ (chain) => chain.chain_type === defaultSource.defaultSourceChainType && chain.chain_id === defaultSource.defaultSourceChainId && normalize(chain.token_address) === normalize(defaultSource.defaultSourceTokenAddress)
751
+ );
752
+ if (matchingChain) return token.symbol;
753
+ }
754
+ }
755
+ if (!defaultSource.defaultSourceSymbol) return null;
756
+ for (const token of supportedTokens) {
757
+ if (normalize(token.symbol) !== normalize(defaultSource.defaultSourceSymbol)) {
758
+ continue;
759
+ }
760
+ const matchingChain = token.chains.find(
761
+ (chain) => chain.chain_type === defaultSource.defaultSourceChainType && chain.chain_id === defaultSource.defaultSourceChainId
762
+ );
763
+ if (matchingChain) return token.symbol;
764
+ }
765
+ return null;
766
+ }
678
767
  function formatUsdFromBalancePercent(maxUsdAmount, percent) {
679
768
  if (maxUsdAmount <= 0 || percent < 0) return "";
680
769
  const raw = maxUsdAmount * percent / 100;
@@ -5348,70 +5437,106 @@ function identifyEthWallet(provider, hint) {
5348
5437
  }
5349
5438
  return { type: "metamask", name: "Wallet", icon: "metamask" };
5350
5439
  }
5440
+ var EIP6963_ID_TO_WALLET_TYPE = {
5441
+ metamask: "metamask",
5442
+ phantom: "phantom-ethereum",
5443
+ coinbase: "coinbase",
5444
+ trust: "trust",
5445
+ rainbow: "rainbow",
5446
+ rabby: "rabby",
5447
+ okx: "okx"
5448
+ };
5449
+ function inferEthWalletType(provider, walletId) {
5450
+ if (EIP6963_ID_TO_WALLET_TYPE[walletId]) return EIP6963_ID_TO_WALLET_TYPE[walletId];
5451
+ const any = provider;
5452
+ if (provider.isPhantom) return "phantom-ethereum";
5453
+ if (any.isCoinbaseWallet) return "coinbase";
5454
+ if (any.isRabby) return "rabby";
5455
+ if (any.isTrust) return "trust";
5456
+ if (any.isRainbow) return "rainbow";
5457
+ if (any.isOkxWallet) return "okx";
5458
+ if (provider.isMetaMask && !provider.isPhantom) return "metamask";
5459
+ return null;
5460
+ }
5461
+ function solanaCandidate(provider, type, name, icon) {
5462
+ return {
5463
+ walletType: type,
5464
+ detect: async () => {
5465
+ if (!provider) return null;
5466
+ if (provider.isConnected && provider.publicKey) {
5467
+ return { type, name, address: provider.publicKey.toString(), icon };
5468
+ }
5469
+ try {
5470
+ const resp = await provider.connect({ onlyIfTrusted: true });
5471
+ if (resp.publicKey) {
5472
+ return { type, name, address: resp.publicKey.toString(), icon };
5473
+ }
5474
+ } catch {
5475
+ }
5476
+ return null;
5477
+ }
5478
+ };
5479
+ }
5480
+ function ethereumCandidate(provider, walletId) {
5481
+ return {
5482
+ walletType: inferEthWalletType(provider, walletId),
5483
+ detect: async () => {
5484
+ try {
5485
+ const accounts = await provider.request({ method: "eth_accounts" });
5486
+ if (!accounts?.length) return null;
5487
+ const resolved = identifyEthWallet(provider, walletId);
5488
+ return { ...resolved, address: accounts[0] };
5489
+ } catch {
5490
+ return null;
5491
+ }
5492
+ }
5493
+ };
5494
+ }
5495
+ function buildCandidates(win, chainType) {
5496
+ const candidates = [];
5497
+ if (!chainType || chainType === "solana") {
5498
+ candidates.push(
5499
+ solanaCandidate(win.phantom?.solana, "phantom-solana", "Phantom", "phantom"),
5500
+ solanaCandidate(win.solflare, "solflare", "Solflare", "solflare"),
5501
+ solanaCandidate(win.backpack, "backpack", "Backpack", "backpack"),
5502
+ solanaCandidate(win.glow, "glow", "Glow", "glow")
5503
+ );
5504
+ }
5505
+ if (!chainType || chainType === "ethereum") {
5506
+ const seen = /* @__PURE__ */ new Set();
5507
+ const addEth = (provider, walletId) => {
5508
+ if (!provider || seen.has(provider)) return;
5509
+ seen.add(provider);
5510
+ candidates.push(ethereumCandidate(provider, walletId));
5511
+ };
5512
+ for (const { provider, walletId } of getEip6963Providers()) {
5513
+ addEth(
5514
+ provider,
5515
+ walletId === "unknown" ? "default" : walletId
5516
+ );
5517
+ }
5518
+ addEth(win.phantom?.ethereum, "phantom");
5519
+ addEth(win.coinbaseWalletExtension, "coinbase");
5520
+ addEth(win.okxwallet, "okx");
5521
+ addEth(win.trustwallet?.ethereum, "trust");
5522
+ addEth(win.ethereum, "default");
5523
+ }
5524
+ return candidates;
5525
+ }
5351
5526
  async function detectConnectedBrowserWallet(chainType) {
5352
5527
  if (typeof window === "undefined") return null;
5353
5528
  if (getUserDisconnectedWallet()) return null;
5354
5529
  try {
5355
5530
  const win = window;
5356
- if (!chainType || chainType === "solana") {
5357
- const trySilentSolana = async (provider, type, name, icon) => {
5358
- if (!provider) return null;
5359
- if (provider.isConnected && provider.publicKey) {
5360
- return { type, name, address: provider.publicKey.toString(), icon };
5361
- }
5362
- try {
5363
- const resp = await provider.connect({ onlyIfTrusted: true });
5364
- if (resp.publicKey) {
5365
- return { type, name, address: resp.publicKey.toString(), icon };
5366
- }
5367
- } catch {
5368
- }
5369
- return null;
5370
- };
5371
- const solanaCandidates = [
5372
- [win.phantom?.solana, "phantom-solana", "Phantom", "phantom"],
5373
- [win.solflare, "solflare", "Solflare", "solflare"],
5374
- [win.backpack, "backpack", "Backpack", "backpack"],
5375
- [win.glow, "glow", "Glow", "glow"]
5376
- ];
5377
- for (const [provider, type, name, icon] of solanaCandidates) {
5378
- const found = await trySilentSolana(provider, type, name, icon);
5379
- if (found) return found;
5380
- }
5531
+ const candidates = buildCandidates(win, chainType);
5532
+ const preferred = getStoredWalletState();
5533
+ if (preferred && (!chainType || preferred.chainType === chainType)) {
5534
+ const idx = candidates.findIndex((c) => c.walletType === preferred.walletType);
5535
+ if (idx > 0) candidates.unshift(...candidates.splice(idx, 1));
5381
5536
  }
5382
- if (!chainType || chainType === "ethereum") {
5383
- const allProviders = [];
5384
- const eip6963 = getEip6963Providers();
5385
- for (const { provider, walletId } of eip6963) {
5386
- allProviders.push({
5387
- provider,
5388
- walletId: walletId === "unknown" ? "default" : walletId
5389
- });
5390
- }
5391
- if (allProviders.length === 0) {
5392
- if (win.phantom?.ethereum) {
5393
- allProviders.push({ provider: win.phantom.ethereum, walletId: "phantom" });
5394
- }
5395
- if (win.okxwallet) {
5396
- allProviders.push({ provider: win.okxwallet, walletId: "okx" });
5397
- }
5398
- if (win.coinbaseWalletExtension) {
5399
- allProviders.push({ provider: win.coinbaseWalletExtension, walletId: "coinbase" });
5400
- }
5401
- if (win.ethereum && !allProviders.some((p) => p.provider === win.ethereum)) {
5402
- allProviders.push({ provider: win.ethereum, walletId: "default" });
5403
- }
5404
- }
5405
- for (const { provider, walletId } of allProviders) {
5406
- if (!provider) continue;
5407
- try {
5408
- const accounts = await provider.request({ method: "eth_accounts" });
5409
- if (!accounts || accounts.length === 0) continue;
5410
- const resolved = identifyEthWallet(provider, walletId);
5411
- return { ...resolved, address: accounts[0] };
5412
- } catch {
5413
- }
5414
- }
5537
+ for (const c of candidates) {
5538
+ const found = await c.detect();
5539
+ if (found) return found;
5415
5540
  }
5416
5541
  } catch (error) {
5417
5542
  console.error("[detectConnectedBrowserWallet] detection error:", error);
@@ -7615,6 +7740,7 @@ function BrowserWalletButton({
7615
7740
  if (solanaProvider?.isPhantom) {
7616
7741
  const { publicKey } = await solanaProvider.connect();
7617
7742
  setUserDisconnectedWallet(false);
7743
+ setStoredWalletState("phantom-solana");
7618
7744
  setWallet({
7619
7745
  type: "phantom-solana",
7620
7746
  name: "Phantom",
@@ -7634,8 +7760,10 @@ function BrowserWalletButton({
7634
7760
  if (accounts && accounts.length > 0) {
7635
7761
  setUserDisconnectedWallet(false);
7636
7762
  const isPhantom = ethProvider.isPhantom;
7763
+ const walletType = isPhantom ? "phantom-ethereum" : "metamask";
7764
+ setStoredWalletState(walletType);
7637
7765
  setWallet({
7638
- type: isPhantom ? "phantom-ethereum" : "metamask",
7766
+ type: walletType,
7639
7767
  name: isPhantom ? "Phantom" : "MetaMask",
7640
7768
  address: accounts[0],
7641
7769
  icon: isPhantom ? "phantom" : "metamask"
@@ -7989,7 +8117,11 @@ function CoinbaseConnect({
7989
8117
  onDisconnect,
7990
8118
  skipToHoldings,
7991
8119
  canGoBack = true,
7992
- onExecutionsChange
8120
+ onExecutionsChange,
8121
+ defaultSourceChainType,
8122
+ defaultSourceChainId,
8123
+ defaultSourceTokenAddress,
8124
+ defaultSourceSymbol
7993
8125
  }) {
7994
8126
  const { colors: colors2, fonts, components } = useTheme();
7995
8127
  const { projectConfig } = useProjectConfig({ publishableKey });
@@ -8054,6 +8186,21 @@ function CoinbaseConnect({
8054
8186
  params: defaultTokenParams,
8055
8187
  publishableKey
8056
8188
  });
8189
+ const defaultSourceCurrency = useMemo4(
8190
+ () => resolveDefaultSourceSymbol(supportedTokensData?.data, {
8191
+ defaultSourceChainType,
8192
+ defaultSourceChainId,
8193
+ defaultSourceTokenAddress,
8194
+ defaultSourceSymbol
8195
+ })?.toLowerCase() ?? null,
8196
+ [
8197
+ supportedTokensData,
8198
+ defaultSourceChainType,
8199
+ defaultSourceChainId,
8200
+ defaultSourceTokenAddress,
8201
+ defaultSourceSymbol
8202
+ ]
8203
+ );
8057
8204
  const sortedHoldings = useMemo4(() => {
8058
8205
  const supported = [];
8059
8206
  const unsupported = [];
@@ -8063,13 +8210,42 @@ function CoinbaseConnect({
8063
8210
  if (isSupported) supported.push(account);
8064
8211
  else unsupported.push(account);
8065
8212
  });
8213
+ if (defaultSourceCurrency) {
8214
+ const defaultIndex = supported.findIndex(
8215
+ (account) => account.currency.toLowerCase() === defaultSourceCurrency
8216
+ );
8217
+ if (defaultIndex > 0) {
8218
+ const [defaultHolding] = supported.splice(defaultIndex, 1);
8219
+ supported.unshift(defaultHolding);
8220
+ }
8221
+ }
8066
8222
  return [...supported, ...unsupported];
8067
- }, [holdings, supportedSymbols, exchangeSupportedCurrencies]);
8223
+ }, [
8224
+ holdings,
8225
+ supportedSymbols,
8226
+ exchangeSupportedCurrencies,
8227
+ defaultSourceCurrency
8228
+ ]);
8068
8229
  const selectedHoldingIsSupported = useMemo4(() => {
8069
8230
  if (!selectedHolding) return false;
8070
8231
  const currencyLower = selectedHolding.currency.toLowerCase();
8071
8232
  return (supportedSymbols.size === 0 || supportedSymbols.has(currencyLower)) && (exchangeSupportedCurrencies.size === 0 || exchangeSupportedCurrencies.has(currencyLower));
8072
8233
  }, [selectedHolding, supportedSymbols, exchangeSupportedCurrencies]);
8234
+ useEffect17(() => {
8235
+ if (!defaultSourceCurrency || selectedHolding) return;
8236
+ const defaultHolding = sortedHoldings.find((account) => {
8237
+ const currencyLower = account.currency.toLowerCase();
8238
+ return currencyLower === defaultSourceCurrency && (supportedSymbols.size === 0 || supportedSymbols.has(currencyLower)) && (exchangeSupportedCurrencies.size === 0 || exchangeSupportedCurrencies.has(currencyLower));
8239
+ });
8240
+ if (!defaultHolding) return;
8241
+ setSelectedHolding(defaultHolding);
8242
+ }, [
8243
+ defaultSourceCurrency,
8244
+ selectedHolding,
8245
+ sortedHoldings,
8246
+ supportedSymbols,
8247
+ exchangeSupportedCurrencies
8248
+ ]);
8073
8249
  const exchangeName = selectedExchange?.service_provider_display_name || "Exchange";
8074
8250
  const {
8075
8251
  executions: depositExecutions,
@@ -13439,6 +13615,19 @@ var WALLET_DEFINITIONS = [
13439
13615
  { id: "backpack", name: "Backpack", networks: ["solana"], installUrl: "https://backpack.app/" },
13440
13616
  { id: "glow", name: "Glow", networks: ["solana"], installUrl: "https://glow.app/" }
13441
13617
  ];
13618
+ function normalizeTokenAddress(address) {
13619
+ const normalized = (address ?? "").toLowerCase();
13620
+ if (normalized === "" || normalized === "native" || normalized === "0x0000000000000000000000000000000000000000") {
13621
+ return "native";
13622
+ }
13623
+ return normalized;
13624
+ }
13625
+ function balancesRepresentSameToken(a, b) {
13626
+ const tokenA = getTokenFromBalance(a);
13627
+ const tokenB = getTokenFromBalance(b);
13628
+ if (!tokenA || !tokenB) return false;
13629
+ return tokenA.chain_type === tokenB.chain_type && tokenA.chain_id === tokenB.chain_id && normalizeTokenAddress(tokenA.token_address) === normalizeTokenAddress(tokenB.token_address);
13630
+ }
13442
13631
  function getSolanaProviders() {
13443
13632
  if (typeof window === "undefined") return {};
13444
13633
  const win = window;
@@ -13581,6 +13770,10 @@ function WalletConnect({
13581
13770
  checkoutRemainingBaseUnits,
13582
13771
  stablecoinParity = false,
13583
13772
  productType,
13773
+ defaultSourceChainType,
13774
+ defaultSourceChainId,
13775
+ defaultSourceTokenAddress,
13776
+ defaultSourceSymbol,
13584
13777
  onBack: parentOnBack,
13585
13778
  onClose,
13586
13779
  canGoBack = true,
@@ -13741,6 +13934,7 @@ function WalletConnect({
13741
13934
  metamask: "metamask"
13742
13935
  };
13743
13936
  const walletType = walletIdToType[wallet.id] || "metamask";
13937
+ setStoredWalletState(walletType);
13744
13938
  connectedInfo = { type: walletType, name: wallet.name, address: accounts[0], icon: wallet.id };
13745
13939
  } else {
13746
13940
  const solProviders = getSolanaProviders();
@@ -13769,6 +13963,7 @@ function WalletConnect({
13769
13963
  const response = await provider.connect();
13770
13964
  setUserDisconnectedWallet(false);
13771
13965
  const walletType = wallet.id === "solflare" ? "solflare" : wallet.id === "backpack" ? "backpack" : wallet.id === "glow" ? "glow" : "phantom-solana";
13966
+ setStoredWalletState(walletType);
13772
13967
  connectedInfo = { type: walletType, name: wallet.name, address: response.publicKey.toString(), icon: wallet.id };
13773
13968
  }
13774
13969
  const walletChainType = network === "solana" ? "solana" : "ethereum";
@@ -13883,18 +14078,33 @@ function WalletConnect({
13883
14078
  getAddressBalances2(activeWalletInfo.address, sct, publishableKey).then((response) => {
13884
14079
  if (cancelled) return;
13885
14080
  const nonZero = response.balances.filter((b) => b.amount !== "0");
13886
- const sorted = [...nonZero].sort((a, b) => {
13887
- const ae = isBalanceEligible(a);
13888
- const be = isBalanceEligible(b);
13889
- if (ae && !be) return -1;
13890
- if (!ae && be) return 1;
13891
- return 0;
13892
- });
14081
+ const defaultSource = {
14082
+ defaultSourceChainType,
14083
+ defaultSourceChainId,
14084
+ defaultSourceTokenAddress,
14085
+ defaultSourceSymbol
14086
+ };
14087
+ const sorted = [...nonZero].sort(
14088
+ (a, b) => compareBalancesWithDefaultSource(a, b, defaultSource)
14089
+ );
13893
14090
  setBalances(sorted);
13894
14091
  const totalUsd = nonZero.reduce((sum, b) => b.amount_usd ? sum + parseFloat(b.amount_usd) : sum, 0);
13895
14092
  if (totalUsd > 0) setTotalBalanceUsd(totalUsd.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 }));
13896
14093
  const eligible = sorted.filter(isBalanceEligible);
13897
- if (eligible.length === 1) setSelectedBalance(eligible[0]);
14094
+ const defaultBalance = sorted.find(
14095
+ (balance) => isDefaultSourceBalance(balance, defaultSource)
14096
+ );
14097
+ setSelectedBalance((current) => {
14098
+ if (current) {
14099
+ const currentInNewBalances = sorted.find(
14100
+ (balance) => balancesRepresentSameToken(balance, current)
14101
+ );
14102
+ if (currentInNewBalances) return currentInNewBalances;
14103
+ }
14104
+ if (defaultBalance) return defaultBalance;
14105
+ if (eligible.length === 1) return eligible[0];
14106
+ return null;
14107
+ });
13898
14108
  }).catch((err) => {
13899
14109
  if (!cancelled) {
13900
14110
  console.error("[WalletConnect] Error fetching balances:", err);
@@ -13906,7 +14116,15 @@ function WalletConnect({
13906
14116
  return () => {
13907
14117
  cancelled = true;
13908
14118
  };
13909
- }, [activeWalletInfo?.address, activeDepositWallet?.chain_type, publishableKey]);
14119
+ }, [
14120
+ activeWalletInfo?.address,
14121
+ activeDepositWallet?.chain_type,
14122
+ publishableKey,
14123
+ defaultSourceChainType,
14124
+ defaultSourceChainId,
14125
+ defaultSourceTokenAddress,
14126
+ defaultSourceSymbol
14127
+ ]);
13910
14128
  const usdToTokenRate = React30.useMemo(() => {
13911
14129
  if (!selectedBalance || !selectedBalance.amount_usd || !selectedToken) return 0;
13912
14130
  const balanceAmount = Number(selectedBalance.amount) / 10 ** selectedToken.decimals;
@@ -14264,16 +14482,17 @@ function DepositModal({
14264
14482
  defaultSourceChainId,
14265
14483
  defaultSourceTokenAddress,
14266
14484
  defaultSourceSymbol,
14267
- hideDepositTracker = false,
14485
+ hideDepositTracker,
14268
14486
  showBalanceHeader = false,
14269
14487
  transferInputVariant = "double_input",
14270
14488
  depositConfirmationMode = "auto_ui",
14271
- enableConnectWallet = false,
14489
+ enableTransferCrypto,
14490
+ enableConnectWallet,
14272
14491
  browserWalletAmountQuickSelect = "percentage",
14273
14492
  enablePayWithExchange,
14274
14493
  enableFiatOnramp,
14275
- enableConnectExchange = false,
14276
- enableCashApp = false,
14494
+ enableConnectExchange,
14495
+ enableCashApp,
14277
14496
  hideDepositFlowInfo = false,
14278
14497
  hideDisplayDescription = false,
14279
14498
  onDepositSuccess,
@@ -14291,12 +14510,13 @@ function DepositModal({
14291
14510
  const { colors: colors2, fonts, components } = useTheme();
14292
14511
  const effectiveInitialScreen = useMemo10(() => {
14293
14512
  const s = initialScreen ?? "main";
14294
- if (s === "tracker" && hideDepositTracker) return "main";
14295
- if (s === "cashapp" && !enableCashApp) return "main";
14513
+ if (s === "tracker" && hideDepositTracker === true) return "main";
14514
+ if (s === "cashapp" && enableCashApp === false) return "main";
14296
14515
  if (s === "card" && enableFiatOnramp === false) return "main";
14297
14516
  if (s === "pay_with_exchange") return enablePayWithExchange === false ? "main" : "exchange";
14298
- if (s === "exchange_connect") return enableConnectExchange ? "coinbase_connect" : "main";
14299
- if (s === "wallet_connect") return enableConnectWallet ? "wallet_connect" : "main";
14517
+ if (s === "exchange_connect")
14518
+ return enableConnectExchange === false ? "main" : "coinbase_connect";
14519
+ if (s === "wallet_connect") return enableConnectWallet === false ? "main" : "wallet_connect";
14300
14520
  return s;
14301
14521
  }, [
14302
14522
  initialScreen,
@@ -14325,26 +14545,37 @@ function DepositModal({
14325
14545
  const [browserWalletModalOpen, setBrowserWalletModalOpen] = useState32(false);
14326
14546
  const [browserWalletInfo, setBrowserWalletInfo] = useState32(null);
14327
14547
  const [walletSelectionModalOpen, setWalletSelectionModalOpen] = useState32(false);
14328
- const [browserWalletChainType, setBrowserWalletChainType] = useState32(() => getStoredWalletChainType());
14548
+ const [browserWalletChainType, setBrowserWalletChainType] = useState32(() => getStoredWalletState()?.chainType);
14329
14549
  const [quotesCount, setQuotesCount] = useState32(0);
14330
14550
  const [allExecutions, setAllExecutions] = useState32([]);
14331
14551
  const [selectedExecution, setSelectedExecution] = useState32(null);
14332
14552
  const [depositExecutions, setDepositExecutions] = useState32([]);
14333
14553
  const isMobileView = useIsMobileViewport();
14554
+ const { projectConfig } = useProjectConfig({
14555
+ publishableKey,
14556
+ enabled: open
14557
+ });
14558
+ const showTransferCrypto = enableTransferCrypto ?? projectConfig?.transfer_crypto?.enabled ?? true;
14559
+ const showConnectWallet = enableConnectWallet ?? projectConfig?.connect_wallet?.enabled ?? true;
14560
+ const showPayWithExchange = enablePayWithExchange ?? projectConfig?.pay_with_exchange?.enabled ?? true;
14561
+ const showFiatOnramp = enableFiatOnramp ?? projectConfig?.fiat_onramp?.enabled ?? true;
14562
+ const showConnectExchange = enableConnectExchange ?? projectConfig?.connect_exchange?.enabled ?? true;
14563
+ const showCashApp = enableCashApp ?? projectConfig?.cash_app?.enabled ?? true;
14564
+ const showDepositTracker = hideDepositTracker ? false : projectConfig?.deposit_tracker?.enabled ?? true;
14334
14565
  const [integrationExchanges, setIntegrationExchanges] = useState32([]);
14335
14566
  useEffect26(() => {
14336
- if (!enableConnectExchange || !open) return;
14567
+ if (!showConnectExchange || !open) return;
14337
14568
  getIntegrationExchanges2(publishableKey).then((res) => setIntegrationExchanges(res.data)).catch(() => {
14338
14569
  });
14339
- }, [enableConnectExchange, open, publishableKey]);
14570
+ }, [showConnectExchange, open, publishableKey]);
14340
14571
  const [connectedExchange, setConnectedExchange] = useState32(() => {
14341
- if (!enableConnectExchange) return null;
14572
+ if (!showConnectExchange) return null;
14342
14573
  const stored = getStoredIntegrationToken(IntegrationProvider2.COINBASE);
14343
14574
  if (!stored) return null;
14344
14575
  return { name: "Coinbase", iconUrl: void 0, balanceUsd: null, isLoading: true };
14345
14576
  });
14346
14577
  useEffect26(() => {
14347
- if (!enableConnectExchange || !open || view !== "main") return;
14578
+ if (!showConnectExchange || !open || view !== "main") return;
14348
14579
  const stored = getStoredIntegrationToken(IntegrationProvider2.COINBASE);
14349
14580
  if (!stored) {
14350
14581
  setConnectedExchange(null);
@@ -14379,7 +14610,7 @@ function DepositModal({
14379
14610
  setConnectedExchange(null);
14380
14611
  }
14381
14612
  });
14382
- }, [enableConnectExchange, open, view, publishableKey]);
14613
+ }, [showConnectExchange, open, view, publishableKey]);
14383
14614
  useEffect26(() => {
14384
14615
  if (!connectedExchange || integrationExchanges.length === 0) return;
14385
14616
  const cbExchange = integrationExchanges.find(
@@ -14418,18 +14649,33 @@ function DepositModal({
14418
14649
  setResolvedTheme(theme);
14419
14650
  }
14420
14651
  }, [theme]);
14421
- const { projectConfig } = useProjectConfig({
14422
- publishableKey,
14423
- enabled: open
14424
- });
14425
- const showPayWithExchange = enablePayWithExchange ?? projectConfig?.pay_with_exchange?.enabled ?? true;
14426
- const showFiatOnramp = enableFiatOnramp ?? projectConfig?.fiat_onramp?.enabled ?? true;
14427
14652
  useEffect26(() => {
14428
14653
  if (view === "card" && !showFiatOnramp) {
14429
14654
  setView("main");
14430
14655
  setCardView("amount");
14656
+ } else if (view === "transfer" && !showTransferCrypto) {
14657
+ setView("main");
14658
+ } else if (view === "exchange" && !showPayWithExchange) {
14659
+ setView("main");
14660
+ } else if (view === "cashapp" && !showCashApp) {
14661
+ setView("main");
14662
+ } else if (view === "tracker" && !showDepositTracker) {
14663
+ setView("main");
14664
+ } else if (view === "coinbase_connect" && !showConnectExchange) {
14665
+ setView("main");
14666
+ } else if (view === "wallet_connect" && !showConnectWallet) {
14667
+ setView("main");
14431
14668
  }
14432
- }, [view, showFiatOnramp]);
14669
+ }, [
14670
+ view,
14671
+ showFiatOnramp,
14672
+ showTransferCrypto,
14673
+ showPayWithExchange,
14674
+ showCashApp,
14675
+ showDepositTracker,
14676
+ showConnectExchange,
14677
+ showConnectWallet
14678
+ ]);
14433
14679
  useEffect26(() => {
14434
14680
  if (view === "exchange" && !showPayWithExchange) {
14435
14681
  setView("main");
@@ -14519,7 +14765,7 @@ function DepositModal({
14519
14765
  depositPrerequisiteBody = standaloneNeedsDepositPrereq ? /* @__PURE__ */ jsx55(SkeletonButton, { variant: "with-icons" }) : /* @__PURE__ */ jsxs49(Fragment11, { children: [
14520
14766
  /* @__PURE__ */ jsx55(SkeletonButton, { variant: "with-icons" }),
14521
14767
  /* @__PURE__ */ jsx55(SkeletonButton, { variant: "with-icons" }),
14522
- !hideDepositTracker && /* @__PURE__ */ jsx55(SkeletonButton, {})
14768
+ showDepositTracker && /* @__PURE__ */ jsx55(SkeletonButton, {})
14523
14769
  ] });
14524
14770
  } else if (countryError) {
14525
14771
  depositPrerequisiteBody = /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-8 uf-px-4 uf-text-center", children: [
@@ -14551,7 +14797,7 @@ function DepositModal({
14551
14797
  const themeClass = resolvedTheme === "dark" ? "uf-dark" : "";
14552
14798
  const handleWalletDisconnect = () => {
14553
14799
  setUserDisconnectedWallet(true);
14554
- clearStoredWalletChainType();
14800
+ clearStoredWalletState();
14555
14801
  setBrowserWalletChainType(void 0);
14556
14802
  setBrowserWalletInfo(null);
14557
14803
  setBrowserWalletModalOpen(false);
@@ -14629,7 +14875,7 @@ function DepositModal({
14629
14875
  };
14630
14876
  const handleBrowserWalletClick = (walletInfo) => {
14631
14877
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
14632
- setStoredWalletChainType(walletChainType);
14878
+ setStoredWalletState(walletInfo.type);
14633
14879
  setBrowserWalletChainType(walletChainType);
14634
14880
  const matchingDepositWallet = wallets.find(
14635
14881
  (w) => w.chain_type === walletChainType
@@ -14660,7 +14906,7 @@ function DepositModal({
14660
14906
  };
14661
14907
  const handleWalletConnected = (walletInfo) => {
14662
14908
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
14663
- setStoredWalletChainType(walletChainType);
14909
+ setStoredWalletState(walletInfo.type);
14664
14910
  setBrowserWalletChainType(walletChainType);
14665
14911
  const matchingDepositWallet = wallets.find(
14666
14912
  (w) => w.chain_type === walletChainType
@@ -14727,7 +14973,7 @@ function DepositModal({
14727
14973
  ),
14728
14974
  /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
14729
14975
  /* @__PURE__ */ jsx55("div", { className: "uf-space-y-3", children: depositPrerequisiteBody ?? /* @__PURE__ */ jsxs49(Fragment11, { children: [
14730
- /* @__PURE__ */ jsx55(
14976
+ showTransferCrypto && /* @__PURE__ */ jsx55(
14731
14977
  TransferCryptoButton,
14732
14978
  {
14733
14979
  onClick: () => setView("transfer"),
@@ -14736,7 +14982,7 @@ function DepositModal({
14736
14982
  featuredTokens: projectConfig?.transfer_crypto.networks
14737
14983
  }
14738
14984
  ),
14739
- enableConnectWallet && !isMobileView && /* @__PURE__ */ jsx55(
14985
+ showConnectWallet && !isMobileView && /* @__PURE__ */ jsx55(
14740
14986
  BrowserWalletButton,
14741
14987
  {
14742
14988
  onClick: handleBrowserWalletClick,
@@ -14766,7 +15012,7 @@ function DepositModal({
14766
15012
  loading: exchangesLoading
14767
15013
  }
14768
15014
  ),
14769
- enableConnectExchange && connectedExchange && /* @__PURE__ */ jsx55(
15015
+ showConnectExchange && connectedExchange && /* @__PURE__ */ jsx55(
14770
15016
  ConnectExchangeButton,
14771
15017
  {
14772
15018
  onClick: () => {
@@ -14780,7 +15026,7 @@ function DepositModal({
14780
15026
  connectedExchange
14781
15027
  }
14782
15028
  ),
14783
- enableConnectExchange && !connectedExchange && /* @__PURE__ */ jsx55(
15029
+ showConnectExchange && !connectedExchange && /* @__PURE__ */ jsx55(
14784
15030
  ConnectExchangeButton,
14785
15031
  {
14786
15032
  onClick: () => {
@@ -14792,7 +15038,7 @@ function DepositModal({
14792
15038
  exchanges: integrationExchanges
14793
15039
  }
14794
15040
  ),
14795
- enableCashApp && /* @__PURE__ */ jsx55(
15041
+ showCashApp && /* @__PURE__ */ jsx55(
14796
15042
  CashAppButton,
14797
15043
  {
14798
15044
  onClick: () => setView("cashapp"),
@@ -14801,7 +15047,7 @@ function DepositModal({
14801
15047
  iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
14802
15048
  }
14803
15049
  ),
14804
- !hideDepositTracker && /* @__PURE__ */ jsx55(
15050
+ showDepositTracker && /* @__PURE__ */ jsx55(
14805
15051
  DepositTrackerButton,
14806
15052
  {
14807
15053
  onClick: () => {
@@ -15006,7 +15252,11 @@ function DepositModal({
15006
15252
  onDisconnect: handleExchangeDisconnect,
15007
15253
  skipToHoldings: coinbaseSkipToHoldings,
15008
15254
  canGoBack: sessionOpenedFromMenu,
15009
- onExecutionsChange: setDepositExecutions
15255
+ onExecutionsChange: setDepositExecutions,
15256
+ defaultSourceChainType,
15257
+ defaultSourceChainId,
15258
+ defaultSourceTokenAddress,
15259
+ defaultSourceSymbol
15010
15260
  }
15011
15261
  ),
15012
15262
  depositPoweredByFooter
@@ -15039,11 +15289,15 @@ function DepositModal({
15039
15289
  onWalletDisconnect: handleWalletDisconnect,
15040
15290
  onWalletConnected: (info, dw) => {
15041
15291
  setBrowserWalletInfo({ ...info, depositWallet: dw });
15042
- setStoredWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
15292
+ setStoredWalletState(info.type);
15043
15293
  setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
15044
15294
  },
15045
15295
  onBack: handleBack,
15046
15296
  onClose: handleClose,
15297
+ defaultSourceChainType,
15298
+ defaultSourceChainId,
15299
+ defaultSourceTokenAddress,
15300
+ defaultSourceSymbol,
15047
15301
  canGoBack: sessionOpenedFromMenu,
15048
15302
  depositWalletsLoading: walletsLoading
15049
15303
  }
@@ -15164,7 +15418,8 @@ function CheckoutModal({
15164
15418
  clientSecret,
15165
15419
  publishableKey,
15166
15420
  modalTitle,
15167
- enableConnectWallet = false,
15421
+ enableTransferCrypto,
15422
+ enableConnectWallet,
15168
15423
  defaultSourceChainType,
15169
15424
  defaultSourceChainId,
15170
15425
  defaultSourceTokenAddress,
@@ -15181,7 +15436,7 @@ function CheckoutModal({
15181
15436
  const [browserWalletModalOpen, setBrowserWalletModalOpen] = useState33(false);
15182
15437
  const [browserWalletInfo, setBrowserWalletInfo] = useState33(null);
15183
15438
  const [walletSelectionModalOpen, setWalletSelectionModalOpen] = useState33(false);
15184
- const [browserWalletChainType, setBrowserWalletChainType] = useState33(() => getStoredWalletChainType());
15439
+ const [browserWalletChainType, setBrowserWalletChainType] = useState33(() => getStoredWalletState()?.chainType);
15185
15440
  const isMobileView = useIsMobileViewport();
15186
15441
  const [resolvedTheme, setResolvedTheme] = useState33(
15187
15442
  theme === "auto" ? "dark" : theme
@@ -15214,6 +15469,15 @@ function CheckoutModal({
15214
15469
  publishableKey,
15215
15470
  enabled: open
15216
15471
  });
15472
+ const showTransferCrypto = enableTransferCrypto ?? projectConfig?.transfer_crypto?.enabled ?? true;
15473
+ const showConnectWallet = enableConnectWallet ?? projectConfig?.connect_wallet?.enabled ?? true;
15474
+ useEffect27(() => {
15475
+ if (view === "transfer" && !showTransferCrypto) {
15476
+ setView("main");
15477
+ } else if (view === "wallet_connect" && !showConnectWallet) {
15478
+ setView("main");
15479
+ }
15480
+ }, [showConnectWallet, showTransferCrypto, view]);
15217
15481
  const prevStatusRef = useRef10(null);
15218
15482
  useEffect27(() => {
15219
15483
  if (!paymentIntent) return;
@@ -15304,7 +15568,7 @@ function CheckoutModal({
15304
15568
  const handleBrowserWalletClick = useCallback6(
15305
15569
  (walletInfo) => {
15306
15570
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
15307
- setStoredWalletChainType(walletChainType);
15571
+ setStoredWalletState(walletInfo.type);
15308
15572
  setBrowserWalletChainType(walletChainType);
15309
15573
  const matchingDepositWallet = wallets.find(
15310
15574
  (w) => w.chain_type === walletChainType
@@ -15331,7 +15595,7 @@ function CheckoutModal({
15331
15595
  const handleWalletConnected = useCallback6(
15332
15596
  (walletInfo) => {
15333
15597
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
15334
- setStoredWalletChainType(walletChainType);
15598
+ setStoredWalletState(walletInfo.type);
15335
15599
  setBrowserWalletChainType(walletChainType);
15336
15600
  const matchingDepositWallet = wallets.find(
15337
15601
  (w) => w.chain_type === walletChainType
@@ -15355,7 +15619,7 @@ function CheckoutModal({
15355
15619
  );
15356
15620
  const handleWalletDisconnect = useCallback6(() => {
15357
15621
  setUserDisconnectedWallet(true);
15358
- clearStoredWalletChainType();
15622
+ clearStoredWalletState();
15359
15623
  setBrowserWalletChainType(void 0);
15360
15624
  setBrowserWalletInfo(null);
15361
15625
  setBrowserWalletModalOpen(false);
@@ -15590,7 +15854,7 @@ function CheckoutModal({
15590
15854
  ] }) : paymentIntent ? /* @__PURE__ */ jsxs50("div", { className: "uf-space-y-3", children: [
15591
15855
  progressSection,
15592
15856
  (paymentIntent.status === "requires_payment" || paymentIntent.status === "processing") && /* @__PURE__ */ jsxs50(Fragment12, { children: [
15593
- /* @__PURE__ */ jsx56(
15857
+ showTransferCrypto && /* @__PURE__ */ jsx56(
15594
15858
  TransferCryptoButton,
15595
15859
  {
15596
15860
  onClick: () => setView("transfer"),
@@ -15599,7 +15863,7 @@ function CheckoutModal({
15599
15863
  featuredTokens: projectConfig?.transfer_crypto.networks
15600
15864
  }
15601
15865
  ),
15602
- enableConnectWallet && !isMobileView && /* @__PURE__ */ jsx56(
15866
+ showConnectWallet && !isMobileView && /* @__PURE__ */ jsx56(
15603
15867
  BrowserWalletButton,
15604
15868
  {
15605
15869
  onClick: handleBrowserWalletClick,
@@ -15740,14 +16004,18 @@ function CheckoutModal({
15740
16004
  onWalletDisconnect: handleWalletDisconnect,
15741
16005
  onWalletConnected: (info, dw) => {
15742
16006
  setBrowserWalletInfo({ ...info, depositWallet: dw });
15743
- setStoredWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
16007
+ setStoredWalletState(info.type);
15744
16008
  setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
15745
16009
  },
15746
16010
  onNewDeposit: () => setView("main"),
15747
16011
  onDone: () => setView("main"),
15748
16012
  paymentIntentStatus: paymentIntent.status,
15749
16013
  onBack: handleBack,
15750
- onClose: handleClose
16014
+ onClose: handleClose,
16015
+ defaultSourceChainType,
16016
+ defaultSourceChainId,
16017
+ defaultSourceTokenAddress,
16018
+ defaultSourceSymbol
15751
16019
  }
15752
16020
  ),
15753
16021
  poweredByFooter