@unifold/ui-web 0.1.62 → 0.1.64

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
@@ -43117,6 +43117,42 @@ var getDefaultConfig = () => {
43117
43117
  };
43118
43118
  };
43119
43119
  var twMerge = /* @__PURE__ */ createTailwindMerge(getDefaultConfig);
43120
+ function formatStablecoinAmount(baseUnits, decimals) {
43121
+ const raw = Number(baseUnits) / 10 ** decimals;
43122
+ const floored = Math.floor(raw * 100) / 100;
43123
+ const ceiled = raw > floored ? floored + 0.01 : raw;
43124
+ return ceiled.toFixed(2);
43125
+ }
43126
+ function generateKSUID() {
43127
+ const BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
43128
+ const KSUID_EPOCH = 14e8;
43129
+ const timestampSeconds = Math.floor(Date.now() / 1e3) - KSUID_EPOCH;
43130
+ const payload = new Uint8Array(20);
43131
+ payload[0] = timestampSeconds >>> 24 & 255;
43132
+ payload[1] = timestampSeconds >>> 16 & 255;
43133
+ payload[2] = timestampSeconds >>> 8 & 255;
43134
+ payload[3] = timestampSeconds & 255;
43135
+ if (typeof crypto !== "undefined" && crypto.getRandomValues) {
43136
+ crypto.getRandomValues(payload.subarray(4));
43137
+ } else {
43138
+ for (let i = 4; i < 20; i++) {
43139
+ payload[i] = Math.floor(Math.random() * 256);
43140
+ }
43141
+ }
43142
+ let value = 0n;
43143
+ for (const byte of payload) {
43144
+ value = value << 8n | BigInt(byte);
43145
+ }
43146
+ let encoded = "";
43147
+ while (value > 0n) {
43148
+ encoded = BASE62[Number(value % 62n)] + encoded;
43149
+ value = value / 62n;
43150
+ }
43151
+ return encoded.padStart(27, "0");
43152
+ }
43153
+ function generatePrefixedKSUID(prefix) {
43154
+ return `${prefix}_${generateKSUID()}`;
43155
+ }
43120
43156
  var API_BASE_URL = (() => {
43121
43157
  try {
43122
43158
  return process.env.NEXT_PUBLIC_API_BASE_URL || "https://api.unifold.io";
@@ -43419,9 +43455,7 @@ function getOnrampSessionStartUrl(request, publishableKey) {
43419
43455
  if (request.subdivision_code) {
43420
43456
  params.append("subdivision_code", request.subdivision_code);
43421
43457
  }
43422
- if (request.external_id) {
43423
- params.append("external_id", request.external_id);
43424
- }
43458
+ params.append("external_id", request.external_id ?? generatePrefixedKSUID("ors"));
43425
43459
  if (request.email) {
43426
43460
  params.append("email", request.email);
43427
43461
  }
@@ -43532,6 +43566,40 @@ async function getAddressBalances(address, chainType, publishableKey) {
43532
43566
  const data = await response.json();
43533
43567
  return data;
43534
43568
  }
43569
+ async function getExternalWallets(publishableKey) {
43570
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43571
+ validatePublishableKey(pk);
43572
+ const response = await fetch(`${API_BASE_URL}/v1/public/external_wallets`, {
43573
+ method: "GET",
43574
+ headers: {
43575
+ accept: "application/json",
43576
+ "x-publishable-key": pk
43577
+ }
43578
+ });
43579
+ if (!response.ok) {
43580
+ throw new Error(`Failed to fetch external wallets: ${response.statusText}`);
43581
+ }
43582
+ const data = await response.json();
43583
+ return data;
43584
+ }
43585
+ async function getWalletMobileDeepLink(wallet, depositAddresses, publishableKey) {
43586
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43587
+ validatePublishableKey(pk);
43588
+ const response = await fetch(`${API_BASE_URL}/v1/public/external_wallets/mobile_deeplink`, {
43589
+ method: "POST",
43590
+ headers: {
43591
+ "Content-Type": "application/json",
43592
+ accept: "application/json",
43593
+ "x-publishable-key": pk
43594
+ },
43595
+ body: JSON.stringify({ wallet, deposit_addresses: depositAddresses })
43596
+ });
43597
+ if (!response.ok) {
43598
+ throw new Error(`Failed to generate wallet deep link: ${response.statusText}`);
43599
+ }
43600
+ const data = await response.json();
43601
+ return data;
43602
+ }
43535
43603
  async function getAddressBalance(address, chainType, chainId, tokenAddress, publishableKey) {
43536
43604
  const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43537
43605
  validatePublishableKey(pk);
@@ -43636,9 +43704,7 @@ function getExchangeSessionStartUrl(request, publishableKey) {
43636
43704
  if (request.source_amount) {
43637
43705
  params.append("source_amount", request.source_amount);
43638
43706
  }
43639
- if (request.external_id) {
43640
- params.append("external_id", request.external_id);
43641
- }
43707
+ params.append("external_id", request.external_id ?? generatePrefixedKSUID("exc"));
43642
43708
  return `${API_BASE_URL}/v1/public/onramps/exchanges/sessions/start?${params.toString()}`;
43643
43709
  }
43644
43710
  async function getIntegrationExchanges(publishableKey) {
@@ -43972,40 +44038,6 @@ async function getCashAppSessionStatus(externalId, publishableKey) {
43972
44038
  }
43973
44039
  return response.json();
43974
44040
  }
43975
- function formatStablecoinAmount(baseUnits, decimals) {
43976
- const raw = Number(baseUnits) / 10 ** decimals;
43977
- const floored = Math.floor(raw * 100) / 100;
43978
- const ceiled = raw > floored ? floored + 0.01 : raw;
43979
- return ceiled.toFixed(2);
43980
- }
43981
- function generatePrefixedKSUID(prefix) {
43982
- const BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
43983
- const KSUID_EPOCH = 14e8;
43984
- const timestampSeconds = Math.floor(Date.now() / 1e3) - KSUID_EPOCH;
43985
- const payload = new Uint8Array(20);
43986
- payload[0] = timestampSeconds >>> 24 & 255;
43987
- payload[1] = timestampSeconds >>> 16 & 255;
43988
- payload[2] = timestampSeconds >>> 8 & 255;
43989
- payload[3] = timestampSeconds & 255;
43990
- if (typeof crypto !== "undefined" && crypto.getRandomValues) {
43991
- crypto.getRandomValues(payload.subarray(4));
43992
- } else {
43993
- for (let i = 4; i < 20; i++) {
43994
- payload[i] = Math.floor(Math.random() * 256);
43995
- }
43996
- }
43997
- let value = 0n;
43998
- for (const byte of payload) {
43999
- value = value << 8n | BigInt(byte);
44000
- }
44001
- let encoded = "";
44002
- while (value > 0n) {
44003
- encoded = BASE62[Number(value % 62n)] + encoded;
44004
- value = value / 62n;
44005
- }
44006
- encoded = encoded.padStart(27, "0");
44007
- return `${prefix}_${encoded}`;
44008
- }
44009
44041
  var DepositEventType = /* @__PURE__ */ ((DepositEventType2) => {
44010
44042
  DepositEventType2["ONRAMP_SESSION_CREATED"] = "onramp_session.created";
44011
44043
  return DepositEventType2;
@@ -50105,8 +50137,32 @@ var Separator = SelectSeparator;
50105
50137
  function cn(...inputs) {
50106
50138
  return twMerge(clsx(inputs));
50107
50139
  }
50108
- var WALLET_CHAIN_TYPE_STORAGE_KEY = "unifold_last_wallet_type";
50140
+ var WALLET_STATE_STORAGE_KEY = "unifold_wallet_state";
50141
+ var LEGACY_WALLET_KEYS = [
50142
+ "unifold_last_wallet_type",
50143
+ "unifold_last_connected_wallet"
50144
+ ];
50109
50145
  var WALLET_USER_DISCONNECTED_KEY = "unifold_wallet_user_disconnected";
50146
+ var SOLANA_WALLET_TYPES = /* @__PURE__ */ new Set([
50147
+ "phantom-solana",
50148
+ "solflare",
50149
+ "backpack",
50150
+ "glow"
50151
+ ]);
50152
+ var ETHEREUM_WALLET_TYPES = /* @__PURE__ */ new Set([
50153
+ "metamask",
50154
+ "phantom-ethereum",
50155
+ "coinbase",
50156
+ "trust",
50157
+ "rainbow",
50158
+ "rabby",
50159
+ "okx"
50160
+ ]);
50161
+ function walletTypeToChain(t12) {
50162
+ if (SOLANA_WALLET_TYPES.has(t12)) return "solana";
50163
+ if (ETHEREUM_WALLET_TYPES.has(t12)) return "ethereum";
50164
+ return void 0;
50165
+ }
50110
50166
  function getUserDisconnectedWallet() {
50111
50167
  if (typeof window === "undefined") return false;
50112
50168
  try {
@@ -50126,26 +50182,35 @@ function setUserDisconnectedWallet(disconnected) {
50126
50182
  } catch {
50127
50183
  }
50128
50184
  }
50129
- function getStoredWalletChainType() {
50185
+ function getStoredWalletState() {
50130
50186
  if (typeof window === "undefined") return void 0;
50131
50187
  try {
50132
- const stored = localStorage.getItem(WALLET_CHAIN_TYPE_STORAGE_KEY);
50133
- if (stored === "ethereum" || stored === "solana") return stored;
50188
+ const raw = localStorage.getItem(WALLET_STATE_STORAGE_KEY);
50189
+ if (!raw) return void 0;
50190
+ const chainType = walletTypeToChain(raw);
50191
+ if (!chainType) {
50192
+ localStorage.removeItem(WALLET_STATE_STORAGE_KEY);
50193
+ return void 0;
50194
+ }
50195
+ return { walletType: raw, chainType };
50134
50196
  } catch {
50197
+ return void 0;
50135
50198
  }
50136
- return void 0;
50137
50199
  }
50138
- function setStoredWalletChainType(chainType) {
50200
+ function setStoredWalletState(walletType) {
50139
50201
  if (typeof window === "undefined") return;
50202
+ if (!walletTypeToChain(walletType)) return;
50140
50203
  try {
50141
- localStorage.setItem(WALLET_CHAIN_TYPE_STORAGE_KEY, chainType);
50204
+ localStorage.setItem(WALLET_STATE_STORAGE_KEY, walletType);
50205
+ for (const key of LEGACY_WALLET_KEYS) localStorage.removeItem(key);
50142
50206
  } catch {
50143
50207
  }
50144
50208
  }
50145
- function clearStoredWalletChainType() {
50209
+ function clearStoredWalletState() {
50146
50210
  if (typeof window === "undefined") return;
50147
50211
  try {
50148
- localStorage.removeItem(WALLET_CHAIN_TYPE_STORAGE_KEY);
50212
+ localStorage.removeItem(WALLET_STATE_STORAGE_KEY);
50213
+ for (const key of LEGACY_WALLET_KEYS) localStorage.removeItem(key);
50149
50214
  } catch {
50150
50215
  }
50151
50216
  }
@@ -50505,6 +50570,36 @@ function ThemeProvider({
50505
50570
  );
50506
50571
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ThemeContext.Provider, { value: contextValue, children });
50507
50572
  }
50573
+ function AccentColorOverride({
50574
+ accentColor,
50575
+ accentForeground,
50576
+ children
50577
+ }) {
50578
+ const parent = useTheme();
50579
+ const value = React37.useMemo(() => {
50580
+ if (!accentColor) return parent;
50581
+ const foreground = accentForeground ?? parent.colors.primaryForeground;
50582
+ const nextColors = {
50583
+ ...parent.colors,
50584
+ primary: accentColor,
50585
+ primaryForeground: foreground
50586
+ };
50587
+ const nextComponents = {
50588
+ ...parent.components,
50589
+ button: {
50590
+ ...parent.components.button,
50591
+ primaryBackground: accentColor,
50592
+ primaryText: foreground
50593
+ },
50594
+ card: {
50595
+ ...parent.components.card,
50596
+ iconBackgroundColor: `${accentColor}26`
50597
+ }
50598
+ };
50599
+ return { ...parent, colors: nextColors, components: nextComponents };
50600
+ }, [parent, accentColor, accentForeground]);
50601
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ThemeContext.Provider, { value, children });
50602
+ }
50508
50603
  function useTheme() {
50509
50604
  const context = React37.useContext(ThemeContext);
50510
50605
  if (!context) {
@@ -50708,6 +50803,60 @@ function useDepositAddress(params) {
50708
50803
  // 1s, 2s, 4s (max 10s)
50709
50804
  });
50710
50805
  }
50806
+ var normalize = (value) => value?.toLowerCase();
50807
+ function sourceTokenMatchesDefaultSource(token, defaultSource) {
50808
+ if (!token || !defaultSource.defaultSourceChainType || !defaultSource.defaultSourceChainId) {
50809
+ return false;
50810
+ }
50811
+ if (token.chain_type !== defaultSource.defaultSourceChainType || token.chain_id !== defaultSource.defaultSourceChainId) {
50812
+ return false;
50813
+ }
50814
+ if (defaultSource.defaultSourceTokenAddress && normalize(token.token_address) === normalize(defaultSource.defaultSourceTokenAddress)) {
50815
+ return true;
50816
+ }
50817
+ if (defaultSource.defaultSourceTokenAddress) {
50818
+ return false;
50819
+ }
50820
+ return !!defaultSource.defaultSourceSymbol && normalize(token.symbol) === normalize(defaultSource.defaultSourceSymbol);
50821
+ }
50822
+ function isDefaultSourceBalance(balance, defaultSource) {
50823
+ return isBalanceEligible(balance) && sourceTokenMatchesDefaultSource(getTokenFromBalance(balance), defaultSource);
50824
+ }
50825
+ function compareBalancesWithDefaultSource(a, b, defaultSource) {
50826
+ const aDefault = isDefaultSourceBalance(a, defaultSource);
50827
+ const bDefault = isDefaultSourceBalance(b, defaultSource);
50828
+ if (aDefault && !bDefault) return -1;
50829
+ if (!aDefault && bDefault) return 1;
50830
+ const aEligible = isBalanceEligible(a);
50831
+ const bEligible = isBalanceEligible(b);
50832
+ if (aEligible && !bEligible) return -1;
50833
+ if (!aEligible && bEligible) return 1;
50834
+ return 0;
50835
+ }
50836
+ function resolveDefaultSourceSymbol(supportedTokens, defaultSource) {
50837
+ if (!supportedTokens?.length || !defaultSource.defaultSourceChainType || !defaultSource.defaultSourceChainId) {
50838
+ return null;
50839
+ }
50840
+ if (defaultSource.defaultSourceTokenAddress) {
50841
+ for (const token of supportedTokens) {
50842
+ const matchingChain = token.chains.find(
50843
+ (chain) => chain.chain_type === defaultSource.defaultSourceChainType && chain.chain_id === defaultSource.defaultSourceChainId && normalize(chain.token_address) === normalize(defaultSource.defaultSourceTokenAddress)
50844
+ );
50845
+ if (matchingChain) return token.symbol;
50846
+ }
50847
+ }
50848
+ if (!defaultSource.defaultSourceSymbol) return null;
50849
+ for (const token of supportedTokens) {
50850
+ if (normalize(token.symbol) !== normalize(defaultSource.defaultSourceSymbol)) {
50851
+ continue;
50852
+ }
50853
+ const matchingChain = token.chains.find(
50854
+ (chain) => chain.chain_type === defaultSource.defaultSourceChainType && chain.chain_id === defaultSource.defaultSourceChainId
50855
+ );
50856
+ if (matchingChain) return token.symbol;
50857
+ }
50858
+ return null;
50859
+ }
50711
50860
  function formatUsdFromBalancePercent(maxUsdAmount, percent) {
50712
50861
  if (maxUsdAmount <= 0 || percent < 0) return "";
50713
50862
  const raw = maxUsdAmount * percent / 100;
@@ -51502,6 +51651,7 @@ function useDepositPolling({
51502
51651
  clientSecret,
51503
51652
  depositConfirmationMode = "auto_ui",
51504
51653
  depositWalletId,
51654
+ depositWalletIds,
51505
51655
  enabled = true,
51506
51656
  immediateDirectPolling = false,
51507
51657
  onDepositSuccess,
@@ -51647,21 +51797,25 @@ function useDepositPolling({
51647
51797
  setIsPolling(false);
51648
51798
  };
51649
51799
  }, [userId, publishableKey, clientSecret, enabled]);
51800
+ const pollWalletIdsKey = depositWalletIds && depositWalletIds.length > 0 ? Array.from(new Set(depositWalletIds.filter(Boolean))).join(",") : depositWalletId || "";
51650
51801
  (0, import_react10.useEffect)(() => {
51651
- if (!pollingEnabled || !depositWalletId) return;
51802
+ if (!pollingEnabled || !pollWalletIdsKey) return;
51803
+ const ids = pollWalletIdsKey.split(",").filter(Boolean);
51652
51804
  const triggerPoll = async () => {
51653
- try {
51654
- await pollDirectExecutions(
51655
- { deposit_wallet_id: depositWalletId },
51656
- publishableKey
51657
- );
51658
- } catch {
51659
- }
51805
+ await Promise.all(
51806
+ ids.map(
51807
+ (id) => pollDirectExecutions(
51808
+ { deposit_wallet_id: id },
51809
+ publishableKey
51810
+ ).catch(() => {
51811
+ })
51812
+ )
51813
+ );
51660
51814
  };
51661
51815
  triggerPoll();
51662
51816
  const interval = setInterval(triggerPoll, POLL_ENDPOINT_INTERVAL_MS);
51663
51817
  return () => clearInterval(interval);
51664
- }, [pollingEnabled, depositWalletId, publishableKey]);
51818
+ }, [pollingEnabled, pollWalletIdsKey, publishableKey]);
51665
51819
  const handleIveDeposited = () => {
51666
51820
  setPollingEnabled(true);
51667
51821
  setShowWaitingUi(true);
@@ -52850,6 +53004,7 @@ function BuyWithCard({
52850
53004
  if (!selectedProvider) return "0.000000";
52851
53005
  return selectedProvider.destination_amount.toFixed(6);
52852
53006
  };
53007
+ const canOpenProviderSelector = !quotesLoading && quotes.length > 1;
52853
53008
  const selectedCurrencyData = fiatCurrencies.find(
52854
53009
  (c) => c.currency_code.toLowerCase() === currency.toLowerCase()
52855
53010
  );
@@ -53035,9 +53190,12 @@ function BuyWithCard({
53035
53190
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
53036
53191
  "button",
53037
53192
  {
53038
- onClick: () => handleViewChange("quotes"),
53193
+ onClick: () => {
53194
+ if (canOpenProviderSelector) handleViewChange("quotes");
53195
+ },
53039
53196
  disabled: quotesLoading || quotes.length === 0,
53040
- className: "uf-w-full hover:uf-bg-accent uf-transition-colors uf-p-4 uf-group disabled:uf-opacity-50 disabled:uf-cursor-not-allowed",
53197
+ "aria-disabled": !canOpenProviderSelector,
53198
+ className: `uf-w-full uf-transition-colors uf-p-4 uf-group disabled:uf-opacity-50 disabled:uf-cursor-not-allowed ${canOpenProviderSelector ? "hover:uf-bg-accent uf-cursor-pointer" : "uf-cursor-default"}`,
53041
53199
  style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
53042
53200
  children: quotesLoading ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "uf-text-left uf-w-full uf-animate-pulse", children: [
53043
53201
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
@@ -53064,7 +53222,7 @@ function BuyWithCard({
53064
53222
  )
53065
53223
  ] })
53066
53224
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "uf-w-full uf-text-left", children: [
53067
- isAutoSelected && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
53225
+ isAutoSelected && canOpenProviderSelector && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
53068
53226
  "div",
53069
53227
  {
53070
53228
  className: "uf-text-xs uf-font-normal uf-mb-2",
@@ -53100,7 +53258,7 @@ function BuyWithCard({
53100
53258
  ),
53101
53259
  selectedProvider.low_kyc === false && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "uf-flex uf-items-center uf-gap-1.5 uf-mt-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "uf-text-[10px] uf-text-muted-foreground uf-font-normal", children: "No document upload" }) })
53102
53260
  ] }),
53103
- quotes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
53261
+ canOpenProviderSelector && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
53104
53262
  ChevronRight,
53105
53263
  {
53106
53264
  className: "uf-w-4 uf-h-4 group-hover:uf-text-foreground uf-transition-colors uf-flex-shrink-0",
@@ -55221,70 +55379,106 @@ function identifyEthWallet(provider, hint) {
55221
55379
  }
55222
55380
  return { type: "metamask", name: "Wallet", icon: "metamask" };
55223
55381
  }
55382
+ var EIP6963_ID_TO_WALLET_TYPE = {
55383
+ metamask: "metamask",
55384
+ phantom: "phantom-ethereum",
55385
+ coinbase: "coinbase",
55386
+ trust: "trust",
55387
+ rainbow: "rainbow",
55388
+ rabby: "rabby",
55389
+ okx: "okx"
55390
+ };
55391
+ function inferEthWalletType(provider, walletId) {
55392
+ if (EIP6963_ID_TO_WALLET_TYPE[walletId]) return EIP6963_ID_TO_WALLET_TYPE[walletId];
55393
+ const any = provider;
55394
+ if (provider.isPhantom) return "phantom-ethereum";
55395
+ if (any.isCoinbaseWallet) return "coinbase";
55396
+ if (any.isRabby) return "rabby";
55397
+ if (any.isTrust) return "trust";
55398
+ if (any.isRainbow) return "rainbow";
55399
+ if (any.isOkxWallet) return "okx";
55400
+ if (provider.isMetaMask && !provider.isPhantom) return "metamask";
55401
+ return null;
55402
+ }
55403
+ function solanaCandidate(provider, type, name, icon) {
55404
+ return {
55405
+ walletType: type,
55406
+ detect: async () => {
55407
+ if (!provider) return null;
55408
+ if (provider.isConnected && provider.publicKey) {
55409
+ return { type, name, address: provider.publicKey.toString(), icon };
55410
+ }
55411
+ try {
55412
+ const resp = await provider.connect({ onlyIfTrusted: true });
55413
+ if (resp.publicKey) {
55414
+ return { type, name, address: resp.publicKey.toString(), icon };
55415
+ }
55416
+ } catch {
55417
+ }
55418
+ return null;
55419
+ }
55420
+ };
55421
+ }
55422
+ function ethereumCandidate(provider, walletId) {
55423
+ return {
55424
+ walletType: inferEthWalletType(provider, walletId),
55425
+ detect: async () => {
55426
+ try {
55427
+ const accounts = await provider.request({ method: "eth_accounts" });
55428
+ if (!accounts?.length) return null;
55429
+ const resolved = identifyEthWallet(provider, walletId);
55430
+ return { ...resolved, address: accounts[0] };
55431
+ } catch {
55432
+ return null;
55433
+ }
55434
+ }
55435
+ };
55436
+ }
55437
+ function buildCandidates(win, chainType) {
55438
+ const candidates = [];
55439
+ if (!chainType || chainType === "solana") {
55440
+ candidates.push(
55441
+ solanaCandidate(win.phantom?.solana, "phantom-solana", "Phantom", "phantom"),
55442
+ solanaCandidate(win.solflare, "solflare", "Solflare", "solflare"),
55443
+ solanaCandidate(win.backpack, "backpack", "Backpack", "backpack"),
55444
+ solanaCandidate(win.glow, "glow", "Glow", "glow")
55445
+ );
55446
+ }
55447
+ if (!chainType || chainType === "ethereum") {
55448
+ const seen = /* @__PURE__ */ new Set();
55449
+ const addEth = (provider, walletId) => {
55450
+ if (!provider || seen.has(provider)) return;
55451
+ seen.add(provider);
55452
+ candidates.push(ethereumCandidate(provider, walletId));
55453
+ };
55454
+ for (const { provider, walletId } of getEip6963Providers()) {
55455
+ addEth(
55456
+ provider,
55457
+ walletId === "unknown" ? "default" : walletId
55458
+ );
55459
+ }
55460
+ addEth(win.phantom?.ethereum, "phantom");
55461
+ addEth(win.coinbaseWalletExtension, "coinbase");
55462
+ addEth(win.okxwallet, "okx");
55463
+ addEth(win.trustwallet?.ethereum, "trust");
55464
+ addEth(win.ethereum, "default");
55465
+ }
55466
+ return candidates;
55467
+ }
55224
55468
  async function detectConnectedBrowserWallet(chainType) {
55225
55469
  if (typeof window === "undefined") return null;
55226
55470
  if (getUserDisconnectedWallet()) return null;
55227
55471
  try {
55228
55472
  const win = window;
55229
- if (!chainType || chainType === "solana") {
55230
- const trySilentSolana = async (provider, type, name, icon) => {
55231
- if (!provider) return null;
55232
- if (provider.isConnected && provider.publicKey) {
55233
- return { type, name, address: provider.publicKey.toString(), icon };
55234
- }
55235
- try {
55236
- const resp = await provider.connect({ onlyIfTrusted: true });
55237
- if (resp.publicKey) {
55238
- return { type, name, address: resp.publicKey.toString(), icon };
55239
- }
55240
- } catch {
55241
- }
55242
- return null;
55243
- };
55244
- const solanaCandidates = [
55245
- [win.phantom?.solana, "phantom-solana", "Phantom", "phantom"],
55246
- [win.solflare, "solflare", "Solflare", "solflare"],
55247
- [win.backpack, "backpack", "Backpack", "backpack"],
55248
- [win.glow, "glow", "Glow", "glow"]
55249
- ];
55250
- for (const [provider, type, name, icon] of solanaCandidates) {
55251
- const found = await trySilentSolana(provider, type, name, icon);
55252
- if (found) return found;
55253
- }
55254
- }
55255
- if (!chainType || chainType === "ethereum") {
55256
- const allProviders = [];
55257
- const eip6963 = getEip6963Providers();
55258
- for (const { provider, walletId } of eip6963) {
55259
- allProviders.push({
55260
- provider,
55261
- walletId: walletId === "unknown" ? "default" : walletId
55262
- });
55263
- }
55264
- if (allProviders.length === 0) {
55265
- if (win.phantom?.ethereum) {
55266
- allProviders.push({ provider: win.phantom.ethereum, walletId: "phantom" });
55267
- }
55268
- if (win.okxwallet) {
55269
- allProviders.push({ provider: win.okxwallet, walletId: "okx" });
55270
- }
55271
- if (win.coinbaseWalletExtension) {
55272
- allProviders.push({ provider: win.coinbaseWalletExtension, walletId: "coinbase" });
55273
- }
55274
- if (win.ethereum && !allProviders.some((p) => p.provider === win.ethereum)) {
55275
- allProviders.push({ provider: win.ethereum, walletId: "default" });
55276
- }
55277
- }
55278
- for (const { provider, walletId } of allProviders) {
55279
- if (!provider) continue;
55280
- try {
55281
- const accounts = await provider.request({ method: "eth_accounts" });
55282
- if (!accounts || accounts.length === 0) continue;
55283
- const resolved = identifyEthWallet(provider, walletId);
55284
- return { ...resolved, address: accounts[0] };
55285
- } catch {
55286
- }
55287
- }
55473
+ const candidates = buildCandidates(win, chainType);
55474
+ const preferred = getStoredWalletState();
55475
+ if (preferred && (!chainType || preferred.chainType === chainType)) {
55476
+ const idx = candidates.findIndex((c) => c.walletType === preferred.walletType);
55477
+ if (idx > 0) candidates.unshift(...candidates.splice(idx, 1));
55478
+ }
55479
+ for (const c of candidates) {
55480
+ const found = await c.detect();
55481
+ if (found) return found;
55288
55482
  }
55289
55483
  } catch (error) {
55290
55484
  console.error("[detectConnectedBrowserWallet] detection error:", error);
@@ -57430,6 +57624,7 @@ function BrowserWalletButton({
57430
57624
  if (solanaProvider?.isPhantom) {
57431
57625
  const { publicKey } = await solanaProvider.connect();
57432
57626
  setUserDisconnectedWallet(false);
57627
+ setStoredWalletState("phantom-solana");
57433
57628
  setWallet({
57434
57629
  type: "phantom-solana",
57435
57630
  name: "Phantom",
@@ -57449,8 +57644,10 @@ function BrowserWalletButton({
57449
57644
  if (accounts && accounts.length > 0) {
57450
57645
  setUserDisconnectedWallet(false);
57451
57646
  const isPhantom = ethProvider.isPhantom;
57647
+ const walletType = isPhantom ? "phantom-ethereum" : "metamask";
57648
+ setStoredWalletState(walletType);
57452
57649
  setWallet({
57453
- type: isPhantom ? "phantom-ethereum" : "metamask",
57650
+ type: walletType,
57454
57651
  name: isPhantom ? "Phantom" : "MetaMask",
57455
57652
  address: accounts[0],
57456
57653
  icon: isPhantom ? "phantom" : "metamask"
@@ -57760,7 +57957,11 @@ function CoinbaseConnect({
57760
57957
  onDisconnect,
57761
57958
  skipToHoldings,
57762
57959
  canGoBack = true,
57763
- onExecutionsChange
57960
+ onExecutionsChange,
57961
+ defaultSourceChainType,
57962
+ defaultSourceChainId,
57963
+ defaultSourceTokenAddress,
57964
+ defaultSourceSymbol
57764
57965
  }) {
57765
57966
  const { colors: colors2, fonts, components } = useTheme();
57766
57967
  const { projectConfig } = useProjectConfig({ publishableKey });
@@ -57825,6 +58026,21 @@ function CoinbaseConnect({
57825
58026
  params: defaultTokenParams,
57826
58027
  publishableKey
57827
58028
  });
58029
+ const defaultSourceCurrency = (0, import_react18.useMemo)(
58030
+ () => resolveDefaultSourceSymbol(supportedTokensData?.data, {
58031
+ defaultSourceChainType,
58032
+ defaultSourceChainId,
58033
+ defaultSourceTokenAddress,
58034
+ defaultSourceSymbol
58035
+ })?.toLowerCase() ?? null,
58036
+ [
58037
+ supportedTokensData,
58038
+ defaultSourceChainType,
58039
+ defaultSourceChainId,
58040
+ defaultSourceTokenAddress,
58041
+ defaultSourceSymbol
58042
+ ]
58043
+ );
57828
58044
  const sortedHoldings = (0, import_react18.useMemo)(() => {
57829
58045
  const supported = [];
57830
58046
  const unsupported = [];
@@ -57834,13 +58050,42 @@ function CoinbaseConnect({
57834
58050
  if (isSupported) supported.push(account);
57835
58051
  else unsupported.push(account);
57836
58052
  });
58053
+ if (defaultSourceCurrency) {
58054
+ const defaultIndex = supported.findIndex(
58055
+ (account) => account.currency.toLowerCase() === defaultSourceCurrency
58056
+ );
58057
+ if (defaultIndex > 0) {
58058
+ const [defaultHolding] = supported.splice(defaultIndex, 1);
58059
+ supported.unshift(defaultHolding);
58060
+ }
58061
+ }
57837
58062
  return [...supported, ...unsupported];
57838
- }, [holdings, supportedSymbols, exchangeSupportedCurrencies]);
58063
+ }, [
58064
+ holdings,
58065
+ supportedSymbols,
58066
+ exchangeSupportedCurrencies,
58067
+ defaultSourceCurrency
58068
+ ]);
57839
58069
  const selectedHoldingIsSupported = (0, import_react18.useMemo)(() => {
57840
58070
  if (!selectedHolding) return false;
57841
58071
  const currencyLower = selectedHolding.currency.toLowerCase();
57842
58072
  return (supportedSymbols.size === 0 || supportedSymbols.has(currencyLower)) && (exchangeSupportedCurrencies.size === 0 || exchangeSupportedCurrencies.has(currencyLower));
57843
58073
  }, [selectedHolding, supportedSymbols, exchangeSupportedCurrencies]);
58074
+ (0, import_react18.useEffect)(() => {
58075
+ if (!defaultSourceCurrency || selectedHolding) return;
58076
+ const defaultHolding = sortedHoldings.find((account) => {
58077
+ const currencyLower = account.currency.toLowerCase();
58078
+ return currencyLower === defaultSourceCurrency && (supportedSymbols.size === 0 || supportedSymbols.has(currencyLower)) && (exchangeSupportedCurrencies.size === 0 || exchangeSupportedCurrencies.has(currencyLower));
58079
+ });
58080
+ if (!defaultHolding) return;
58081
+ setSelectedHolding(defaultHolding);
58082
+ }, [
58083
+ defaultSourceCurrency,
58084
+ selectedHolding,
58085
+ sortedHoldings,
58086
+ supportedSymbols,
58087
+ exchangeSupportedCurrencies
58088
+ ]);
57844
58089
  const exchangeName = selectedExchange?.service_provider_display_name || "Exchange";
57845
58090
  const {
57846
58091
  executions: depositExecutions,
@@ -61989,6 +62234,60 @@ function useDepositQuote(params) {
61989
62234
  retryDelay: (attempt) => Math.min(1e3 * 2 ** attempt, 5e3)
61990
62235
  });
61991
62236
  }
62237
+ function useExternalWallets({
62238
+ publishableKey,
62239
+ enabled = true
62240
+ }) {
62241
+ const { data: wallets = [], isLoading } = useQuery({
62242
+ queryKey: ["unifold", "external-wallets", publishableKey],
62243
+ queryFn: () => getExternalWallets(publishableKey).then((res) => res.data),
62244
+ enabled: enabled && !!publishableKey,
62245
+ staleTime: 1e3 * 60 * 30,
62246
+ refetchOnMount: false,
62247
+ refetchOnWindowFocus: false
62248
+ });
62249
+ return { wallets, isLoading };
62250
+ }
62251
+ var WALLET_BRAND_COLORS = {
62252
+ phantom: "#AB9FF2",
62253
+ metamask: "#F6851B",
62254
+ coinbase: "#0052FF",
62255
+ trust: "#3375BB",
62256
+ rainbow: "#5B6CFF",
62257
+ rabby: "#7084FF",
62258
+ okx: "#000000"
62259
+ };
62260
+ function normalizeWalletId(type) {
62261
+ return type.replace(/-(ethereum|solana)$/i, "").toLowerCase();
62262
+ }
62263
+ function getWalletBrandColor(type, mode = "dark") {
62264
+ if (!type) return void 0;
62265
+ const id = normalizeWalletId(type);
62266
+ const color = WALLET_BRAND_COLORS[id];
62267
+ if (!color) return void 0;
62268
+ if (id === "okx") return mode === "dark" ? "#FFFFFF" : "#111111";
62269
+ return color;
62270
+ }
62271
+ function getContrastingTextColor(hex) {
62272
+ const c = hex.replace("#", "");
62273
+ if (c.length !== 6) return "#FFFFFF";
62274
+ const r2 = parseInt(c.slice(0, 2), 16);
62275
+ const g = parseInt(c.slice(2, 4), 16);
62276
+ const b = parseInt(c.slice(4, 6), 16);
62277
+ const luminance = (0.299 * r2 + 0.587 * g + 0.114 * b) / 255;
62278
+ return luminance > 0.6 ? "#13111C" : "#FFFFFF";
62279
+ }
62280
+ function isMobileDevice() {
62281
+ if (typeof navigator === "undefined") return false;
62282
+ return /android|iphone|ipad|ipod|mobile/i.test(navigator.userAgent);
62283
+ }
62284
+ function getMobilePlatform() {
62285
+ if (typeof navigator === "undefined") return null;
62286
+ const ua = navigator.userAgent;
62287
+ if (/iphone|ipad|ipod/i.test(ua)) return "ios";
62288
+ if (/android/i.test(ua)) return "android";
62289
+ return null;
62290
+ }
61992
62291
  var WALLET_ICONS = {
61993
62292
  metamask: MetamaskIcon,
61994
62293
  phantom: PhantomIcon,
@@ -62994,18 +63293,46 @@ var WALLET_ICONS3 = {
62994
63293
  backpack: BackpackIcon,
62995
63294
  glow: GlowIcon
62996
63295
  };
62997
- var WALLET_DEFINITIONS = [
62998
- { id: "phantom", name: "Phantom", networks: ["ethereum", "solana"], installUrl: "https://phantom.app/" },
62999
- { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum", "solana"], installUrl: "https://www.coinbase.com/wallet" },
63000
- { id: "trust", name: "Trust Wallet", networks: ["ethereum", "solana"], installUrl: "https://trustwallet.com/" },
63001
- { id: "metamask", name: "MetaMask", networks: ["ethereum"], installUrl: "https://metamask.io/download/" },
63002
- { id: "rainbow", name: "Rainbow", networks: ["ethereum"], installUrl: "https://rainbow.me/" },
63003
- { id: "rabby", name: "Rabby", networks: ["ethereum"], installUrl: "https://rabby.io/" },
63004
- { id: "okx", name: "OKX Wallet", networks: ["ethereum"], installUrl: "https://www.okx.com/web3" },
63005
- { id: "solflare", name: "Solflare", networks: ["solana"], installUrl: "https://solflare.com/" },
63006
- { id: "backpack", name: "Backpack", networks: ["solana"], installUrl: "https://backpack.app/" },
63007
- { id: "glow", name: "Glow", networks: ["solana"], installUrl: "https://glow.app/" }
63296
+ var FALLBACK_WALLET_DEFINITIONS = [
63297
+ { id: "phantom", name: "Phantom", networks: ["ethereum", "solana"], installUrl: "https://phantom.app/", supportsMobileBrowse: true },
63298
+ { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum", "solana"], installUrl: "https://www.coinbase.com/wallet", supportsMobileBrowse: true },
63299
+ { id: "trust", name: "Trust Wallet", networks: ["ethereum", "solana"], installUrl: "https://trustwallet.com/", supportsMobileBrowse: true },
63300
+ { id: "metamask", name: "MetaMask", networks: ["ethereum"], installUrl: "https://metamask.io/download/", supportsMobileBrowse: true },
63301
+ { id: "rainbow", name: "Rainbow", networks: ["ethereum"], installUrl: "https://rainbow.me/", supportsMobileBrowse: true },
63302
+ { id: "rabby", name: "Rabby", networks: ["ethereum"], installUrl: "https://apps.apple.com/app/rabby-wallet/id6450663781", supportsMobileBrowse: true },
63303
+ { id: "okx", name: "OKX Wallet", networks: ["ethereum"], installUrl: "https://www.okx.com/web3", supportsMobileBrowse: true, mobileBrowsePlatforms: ["ios"] }
63008
63304
  ];
63305
+ function getMobileInstallUrl(walletId, defaultUrl) {
63306
+ if (!isMobileDevice()) return defaultUrl;
63307
+ const ua = typeof navigator !== "undefined" ? navigator.userAgent : "";
63308
+ const isIOS = /iPhone|iPad|iPod/i.test(ua);
63309
+ const stores = {
63310
+ rabby: {
63311
+ ios: "https://apps.apple.com/app/rabby-wallet/id6450663781",
63312
+ android: "https://play.google.com/store/apps/details?id=com.debank.rabbymobile"
63313
+ },
63314
+ glow: {
63315
+ ios: "https://apps.apple.com/us/app/glow-solana-wallet/id1599584512",
63316
+ android: "https://play.google.com/store/apps/details?id=com.luma.wallet.prod"
63317
+ }
63318
+ };
63319
+ const entry = stores[walletId];
63320
+ if (!entry) return defaultUrl;
63321
+ return isIOS ? entry.ios : entry.android;
63322
+ }
63323
+ function normalizeTokenAddress(address) {
63324
+ const normalized = (address ?? "").toLowerCase();
63325
+ if (normalized === "" || normalized === "native" || normalized === "0x0000000000000000000000000000000000000000") {
63326
+ return "native";
63327
+ }
63328
+ return normalized;
63329
+ }
63330
+ function balancesRepresentSameToken(a, b) {
63331
+ const tokenA = getTokenFromBalance(a);
63332
+ const tokenB = getTokenFromBalance(b);
63333
+ if (!tokenA || !tokenB) return false;
63334
+ return tokenA.chain_type === tokenB.chain_type && tokenA.chain_id === tokenB.chain_id && normalizeTokenAddress(tokenA.token_address) === normalizeTokenAddress(tokenB.token_address);
63335
+ }
63009
63336
  function getSolanaProviders() {
63010
63337
  if (typeof window === "undefined") return {};
63011
63338
  const win = window;
@@ -63028,7 +63355,7 @@ function getLegacyEvmProviders() {
63028
63355
  okxEthereum: win.okxwallet
63029
63356
  };
63030
63357
  }
63031
- function detectAvailableWallets(filterChainType) {
63358
+ function detectAvailableWallets(definitions, filterChainType) {
63032
63359
  const solProviders = getSolanaProviders();
63033
63360
  const legacyEvm = getLegacyEvmProviders();
63034
63361
  const eip6963List = getEip6963Providers();
@@ -63054,7 +63381,7 @@ function detectAvailableWallets(filterChainType) {
63054
63381
  return false;
63055
63382
  }
63056
63383
  });
63057
- return WALLET_DEFINITIONS.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
63384
+ return definitions.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
63058
63385
  let isInstalled = false;
63059
63386
  const detectedNetworks = [];
63060
63387
  switch (wallet.id) {
@@ -63148,13 +63475,17 @@ function WalletConnect({
63148
63475
  checkoutRemainingBaseUnits,
63149
63476
  stablecoinParity = false,
63150
63477
  productType,
63478
+ defaultSourceChainType,
63479
+ defaultSourceChainId,
63480
+ defaultSourceTokenAddress,
63481
+ defaultSourceSymbol,
63151
63482
  onBack: parentOnBack,
63152
63483
  onClose,
63153
63484
  canGoBack = true,
63154
63485
  depositWalletsLoading = false,
63155
63486
  onExecutionsChange
63156
63487
  }) {
63157
- const { colors: colors2, fonts, components } = useTheme();
63488
+ const { colors: colors2, fonts, components, mode } = useTheme();
63158
63489
  const walletProvidedAtMount = React302.useRef(!!initialWalletInfo && !!initialDepositWallet);
63159
63490
  const [activeWalletInfo, setActiveWalletInfo] = React302.useState(initialWalletInfo ?? null);
63160
63491
  const [activeDepositWallet, setActiveDepositWallet] = React302.useState(initialDepositWallet ?? null);
@@ -63178,7 +63509,37 @@ function WalletConnect({
63178
63509
  setEip6963ProviderCount(providers.length);
63179
63510
  });
63180
63511
  }, []);
63181
- const availableWallets = React302.useMemo(() => detectAvailableWallets(), [eip6963ProviderCount]);
63512
+ const { wallets: backendWallets } = useExternalWallets({ publishableKey });
63513
+ const walletDefinitions = React302.useMemo(
63514
+ () => backendWallets.length > 0 ? backendWallets.map((w) => ({
63515
+ id: w.id,
63516
+ name: w.name,
63517
+ networks: w.chain_types,
63518
+ installUrl: w.install_url,
63519
+ supportsMobileBrowse: w.supports_mobile_browse,
63520
+ mobileBrowsePlatforms: w.mobile_browse_platforms ?? null
63521
+ })) : FALLBACK_WALLET_DEFINITIONS,
63522
+ [backendWallets]
63523
+ );
63524
+ const availableWallets = React302.useMemo(
63525
+ () => detectAvailableWallets(walletDefinitions),
63526
+ [walletDefinitions, eip6963ProviderCount]
63527
+ );
63528
+ const [isMobile, setIsMobile] = React302.useState(false);
63529
+ React302.useEffect(() => {
63530
+ setIsMobile(isMobileDevice());
63531
+ }, []);
63532
+ const mobileDepositAddresses = React302.useMemo(
63533
+ () => (depositWallets ?? []).map((w) => ({ chain_type: w.chain_type, address: w.address })),
63534
+ [depositWallets]
63535
+ );
63536
+ const mobileDepositWalletIds = React302.useMemo(
63537
+ () => (depositWallets ?? []).filter((w) => w.chain_type === "ethereum" || w.chain_type === "solana").map((w) => w.id),
63538
+ [depositWallets]
63539
+ );
63540
+ const [mobileRedirect, setMobileRedirect] = React302.useState(null);
63541
+ const [pendingMobileWallet, setPendingMobileWallet] = React302.useState(null);
63542
+ const [awaitingMobileDeposit, setAwaitingMobileDeposit] = React302.useState(false);
63182
63543
  React302.useEffect(() => {
63183
63544
  if (!standalone || autoResolved || detectingWallet) return;
63184
63545
  if (!detectedWallet) {
@@ -63237,10 +63598,37 @@ function WalletConnect({
63237
63598
  transform: isTransitioning ? "translateY(4px)" : "translateY(0)",
63238
63599
  transition: "opacity 150ms ease, transform 150ms ease"
63239
63600
  };
63240
- const handleWalletClick = (wallet) => {
63241
- if (!wallet.isInstalled) {
63242
- window.open(wallet.installUrl, "_blank", "noopener,noreferrer");
63243
- return;
63601
+ const openMobileWalletBrowse = async (wallet, depositAddresses) => {
63602
+ try {
63603
+ const res = await getWalletMobileDeepLink(
63604
+ wallet.id,
63605
+ depositAddresses,
63606
+ publishableKey
63607
+ );
63608
+ if (res.deeplink) {
63609
+ setMobileRedirect({ walletId: wallet.id, walletName: wallet.name, deeplink: res.deeplink });
63610
+ setAwaitingMobileDeposit(true);
63611
+ transitionTo("mobile_redirect");
63612
+ window.location.href = res.deeplink;
63613
+ return true;
63614
+ }
63615
+ } catch {
63616
+ }
63617
+ return false;
63618
+ };
63619
+ const handleWalletClick = async (wallet) => {
63620
+ if (!wallet.isInstalled) {
63621
+ const platform2 = getMobilePlatform();
63622
+ const platformAllowed = !wallet.mobileBrowsePlatforms || wallet.mobileBrowsePlatforms.includes(platform2 ?? "");
63623
+ if (isMobileDevice() && wallet.supportsMobileBrowse !== false && platformAllowed) {
63624
+ if (mobileDepositAddresses.length === 0) {
63625
+ setPendingMobileWallet(wallet);
63626
+ return;
63627
+ }
63628
+ if (await openMobileWalletBrowse(wallet, mobileDepositAddresses)) return;
63629
+ }
63630
+ window.open(getMobileInstallUrl(wallet.id, wallet.installUrl), "_blank", "noopener,noreferrer");
63631
+ return;
63244
63632
  }
63245
63633
  setSelectedWalletDef(wallet);
63246
63634
  setWalletError(null);
@@ -63255,6 +63643,27 @@ function WalletConnect({
63255
63643
  if (!selectedWalletDef) return;
63256
63644
  handleConnectWallet(selectedWalletDef, network);
63257
63645
  };
63646
+ React302.useEffect(() => {
63647
+ if (!pendingMobileWallet) return;
63648
+ if (mobileDepositAddresses.length > 0) {
63649
+ const wallet = pendingMobileWallet;
63650
+ setPendingMobileWallet(null);
63651
+ void (async () => {
63652
+ if (!await openMobileWalletBrowse(wallet, mobileDepositAddresses)) {
63653
+ window.open(getMobileInstallUrl(wallet.id, wallet.installUrl), "_blank", "noopener,noreferrer");
63654
+ }
63655
+ })();
63656
+ return;
63657
+ }
63658
+ const timeout = setTimeout(() => {
63659
+ setPendingMobileWallet((current) => {
63660
+ if (!current) return null;
63661
+ window.open(getMobileInstallUrl(current.id, current.installUrl), "_blank", "noopener,noreferrer");
63662
+ return null;
63663
+ });
63664
+ }, 8e3);
63665
+ return () => clearTimeout(timeout);
63666
+ }, [pendingMobileWallet, mobileDepositAddresses]);
63258
63667
  const handleConnectWallet = async (wallet, network) => {
63259
63668
  setConnectingNetwork(network);
63260
63669
  transitionTo("connecting");
@@ -63308,6 +63717,7 @@ function WalletConnect({
63308
63717
  metamask: "metamask"
63309
63718
  };
63310
63719
  const walletType = walletIdToType[wallet.id] || "metamask";
63720
+ setStoredWalletState(walletType);
63311
63721
  connectedInfo = { type: walletType, name: wallet.name, address: accounts[0], icon: wallet.id };
63312
63722
  } else {
63313
63723
  const solProviders = getSolanaProviders();
@@ -63336,6 +63746,7 @@ function WalletConnect({
63336
63746
  const response = await provider.connect();
63337
63747
  setUserDisconnectedWallet(false);
63338
63748
  const walletType = wallet.id === "solflare" ? "solflare" : wallet.id === "backpack" ? "backpack" : wallet.id === "glow" ? "glow" : "phantom-solana";
63749
+ setStoredWalletState(walletType);
63339
63750
  connectedInfo = { type: walletType, name: wallet.name, address: response.publicKey.toString(), icon: wallet.id };
63340
63751
  }
63341
63752
  const walletChainType = network === "solana" ? "solana" : "ethereum";
@@ -63397,14 +63808,32 @@ function WalletConnect({
63397
63808
  userId,
63398
63809
  publishableKey,
63399
63810
  clientSecret,
63811
+ // In-tab flow: poll the single connected deposit wallet.
63400
63812
  depositWalletId: activeDepositWallet?.id ?? "",
63401
- enabled: hasSignedTransaction && !!activeDepositWallet,
63813
+ // Mobile redirect flow: the deposit chain isn't known up front, so /poll every
63814
+ // chain's deposit wallet. Detection still happens via the single /query by
63815
+ // external_user_id, which already spans all chains.
63816
+ depositWalletIds: awaitingMobileDeposit ? mobileDepositWalletIds : void 0,
63817
+ enabled: hasSignedTransaction && !!activeDepositWallet || awaitingMobileDeposit,
63402
63818
  onDepositSuccess,
63403
63819
  onDepositError
63404
63820
  });
63405
63821
  React302.useEffect(() => {
63406
63822
  onExecutionsChange?.(depositExecutions);
63407
63823
  }, [depositExecutions, onExecutionsChange]);
63824
+ const latestDepositExecution = React302.useMemo(() => {
63825
+ if (depositExecutions.length === 0) return null;
63826
+ return [...depositExecutions].sort((a, b) => {
63827
+ const ta = a.created_at ? new Date(a.created_at).getTime() : 0;
63828
+ const tb = b.created_at ? new Date(b.created_at).getTime() : 0;
63829
+ return tb - ta;
63830
+ })[0];
63831
+ }, [depositExecutions]);
63832
+ React302.useEffect(() => {
63833
+ if (awaitingMobileDeposit && latestDepositExecution && (viewRef.current === "mobile_redirect" || viewRef.current === "connecting")) {
63834
+ transitionTo("mobile_deposit_status");
63835
+ }
63836
+ }, [awaitingMobileDeposit, latestDepositExecution, transitionTo]);
63408
63837
  React302.useEffect(() => {
63409
63838
  if (!prefillAmountUsd || !tokenChainDetails || view !== "enter_amount") return;
63410
63839
  const minDeposit = tokenChainDetails.minimum_deposit_amount_usd || 0;
@@ -63450,18 +63879,33 @@ function WalletConnect({
63450
63879
  getAddressBalances(activeWalletInfo.address, sct, publishableKey).then((response) => {
63451
63880
  if (cancelled) return;
63452
63881
  const nonZero = response.balances.filter((b) => b.amount !== "0");
63453
- const sorted = [...nonZero].sort((a, b) => {
63454
- const ae = isBalanceEligible(a);
63455
- const be = isBalanceEligible(b);
63456
- if (ae && !be) return -1;
63457
- if (!ae && be) return 1;
63458
- return 0;
63459
- });
63882
+ const defaultSource = {
63883
+ defaultSourceChainType,
63884
+ defaultSourceChainId,
63885
+ defaultSourceTokenAddress,
63886
+ defaultSourceSymbol
63887
+ };
63888
+ const sorted = [...nonZero].sort(
63889
+ (a, b) => compareBalancesWithDefaultSource(a, b, defaultSource)
63890
+ );
63460
63891
  setBalances(sorted);
63461
63892
  const totalUsd = nonZero.reduce((sum, b) => b.amount_usd ? sum + parseFloat(b.amount_usd) : sum, 0);
63462
63893
  if (totalUsd > 0) setTotalBalanceUsd(totalUsd.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 }));
63463
63894
  const eligible = sorted.filter(isBalanceEligible);
63464
- if (eligible.length === 1) setSelectedBalance(eligible[0]);
63895
+ const defaultBalance = sorted.find(
63896
+ (balance) => isDefaultSourceBalance(balance, defaultSource)
63897
+ );
63898
+ setSelectedBalance((current) => {
63899
+ if (current) {
63900
+ const currentInNewBalances = sorted.find(
63901
+ (balance) => balancesRepresentSameToken(balance, current)
63902
+ );
63903
+ if (currentInNewBalances) return currentInNewBalances;
63904
+ }
63905
+ if (defaultBalance) return defaultBalance;
63906
+ if (eligible.length === 1) return eligible[0];
63907
+ return null;
63908
+ });
63465
63909
  }).catch((err) => {
63466
63910
  if (!cancelled) {
63467
63911
  console.error("[WalletConnect] Error fetching balances:", err);
@@ -63473,7 +63917,15 @@ function WalletConnect({
63473
63917
  return () => {
63474
63918
  cancelled = true;
63475
63919
  };
63476
- }, [activeWalletInfo?.address, activeDepositWallet?.chain_type, publishableKey]);
63920
+ }, [
63921
+ activeWalletInfo?.address,
63922
+ activeDepositWallet?.chain_type,
63923
+ publishableKey,
63924
+ defaultSourceChainType,
63925
+ defaultSourceChainId,
63926
+ defaultSourceTokenAddress,
63927
+ defaultSourceSymbol
63928
+ ]);
63477
63929
  const usdToTokenRate = React302.useMemo(() => {
63478
63930
  if (!selectedBalance || !selectedBalance.amount_usd || !selectedToken) return 0;
63479
63931
  const balanceAmount = Number(selectedBalance.amount) / 10 ** selectedToken.decimals;
@@ -63512,6 +63964,16 @@ function WalletConnect({
63512
63964
  setSelectedWalletDef(null);
63513
63965
  setConnectingNetwork(null);
63514
63966
  break;
63967
+ case "mobile_redirect":
63968
+ transitionTo("select_wallet");
63969
+ setMobileRedirect(null);
63970
+ setAwaitingMobileDeposit(false);
63971
+ break;
63972
+ case "mobile_deposit_status":
63973
+ transitionTo("select_wallet");
63974
+ setMobileRedirect(null);
63975
+ setAwaitingMobileDeposit(false);
63976
+ break;
63515
63977
  case "select_token":
63516
63978
  if (walletProvidedAtMount.current) parentOnBack?.();
63517
63979
  else transitionTo("select_wallet");
@@ -63697,33 +64159,40 @@ function WalletConnect({
63697
64159
  return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
63698
64160
  /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(DepositHeader, { title: "Connect Wallet", showBack: canGoBack, onBack: handleBack, onClose }),
63699
64161
  /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-pb-4", children: [
63700
- /* @__PURE__ */ (0, import_jsx_runtime73.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" }),
63701
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uf-space-y-2", style: { maxHeight: 330, overflowY: "auto" }, children: availableWallets.map((wallet) => /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
63702
- "button",
63703
- {
63704
- onClick: () => handleWalletClick(wallet),
63705
- disabled: isWalletConnecting,
63706
- className: "uf-w-full uf-transition-colors uf-p-3 uf-flex uf-items-center uf-justify-between hover:uf-opacity-90 disabled:uf-opacity-50",
63707
- style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
63708
- children: [
63709
- /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
63710
- WALLET_ICONS3[wallet.id] ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(WalletIconWithNetwork, { WalletIcon: WALLET_ICONS3[wallet.id], networks: wallet.networks, size: 40, className: "uf-rounded-lg" }) : /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uf-w-10 uf-h-10 uf-rounded-lg uf-bg-gray-500" }),
63711
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uf-text-sm uf-font-medium", style: { color: components.card.titleColor, fontFamily: fonts.medium }, children: wallet.name })
63712
- ] }),
63713
- wallet.isInstalled ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "uf-text-xs uf-px-2 uf-py-1 uf-rounded-full", style: { backgroundColor: colors2.primary + "20", color: colors2.primary, fontFamily: fonts.medium }, children: "Detected" }) : /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-1", children: [
63714
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: "Install" }),
63715
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ExternalLink, { className: "uf-w-3 uf-h-3", style: { color: colors2.foregroundMuted } })
63716
- ] })
63717
- ]
63718
- },
63719
- wallet.id
63720
- )) }),
64162
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("p", { className: "uf-text-sm uf-text-center uf-pb-4", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: isMobile ? "Open this page in your wallet's app to connect" : "Select a wallet to connect" }),
64163
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uf-space-y-2", style: { maxHeight: 330, overflowY: "auto" }, children: availableWallets.map((wallet) => {
64164
+ const walletPlatformAllowed = !wallet.mobileBrowsePlatforms || wallet.mobileBrowsePlatforms.includes(getMobilePlatform() ?? "");
64165
+ const showOpenInApp = isMobile && !wallet.isInstalled && wallet.supportsMobileBrowse !== false && walletPlatformAllowed;
64166
+ const isPending = pendingMobileWallet?.id === wallet.id;
64167
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
64168
+ "button",
64169
+ {
64170
+ onClick: () => void handleWalletClick(wallet),
64171
+ disabled: isWalletConnecting || !!pendingMobileWallet,
64172
+ className: "uf-w-full uf-transition-colors uf-p-3 uf-flex uf-items-center uf-justify-between hover:uf-opacity-90 disabled:uf-opacity-50",
64173
+ style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
64174
+ children: [
64175
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
64176
+ WALLET_ICONS3[wallet.id] ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(WalletIconWithNetwork, { WalletIcon: WALLET_ICONS3[wallet.id], networks: wallet.networks, size: 40, className: "uf-rounded-lg" }) : /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uf-w-10 uf-h-10 uf-rounded-lg uf-bg-gray-500" }),
64177
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uf-text-sm uf-font-medium", style: { color: components.card.titleColor, fontFamily: fonts.medium }, children: wallet.name })
64178
+ ] }),
64179
+ isPending ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(LoaderCircle, { className: "uf-w-4 uf-h-4 uf-animate-spin", style: { color: colors2.primary } }) : wallet.isInstalled ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "uf-text-xs uf-px-2 uf-py-1 uf-rounded-full", style: { backgroundColor: colors2.primary + "20", color: colors2.primary, fontFamily: fonts.medium }, children: "Detected" }) : /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-1", children: [
64180
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: showOpenInApp ? "Open" : "Install" }),
64181
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ExternalLink, { className: "uf-w-3 uf-h-3", style: { color: colors2.foregroundMuted } })
64182
+ ] })
64183
+ ]
64184
+ },
64185
+ wallet.id
64186
+ );
64187
+ }) }),
63721
64188
  walletError && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uf-text-center uf-text-sm uf-mt-4 uf-px-4", style: { color: "#ef4444" }, children: walletError })
63722
64189
  ] })
63723
64190
  ] });
63724
64191
  }
64192
+ const preConnectAccent = selectedWalletDef ? getWalletBrandColor(selectedWalletDef.id, mode) : void 0;
64193
+ const preConnectFg = preConnectAccent ? getContrastingTextColor(preConnectAccent) : void 0;
63725
64194
  if (view === "select_network" && selectedWalletDef) {
63726
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
64195
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
63727
64196
  /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(DepositHeader, { title: "Select Network", showBack: true, onBack: handleBack, onClose }),
63728
64197
  /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-pb-4", children: [
63729
64198
  /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-pb-4", children: [
@@ -63753,10 +64222,10 @@ function WalletConnect({
63753
64222
  )) }),
63754
64223
  walletError && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uf-text-center uf-text-sm uf-mt-4 uf-px-4", style: { color: "#ef4444" }, children: walletError })
63755
64224
  ] })
63756
- ] });
64225
+ ] }) });
63757
64226
  }
63758
64227
  if (view === "connecting") {
63759
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
64228
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
63760
64229
  /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(DepositHeader, { title: "Connecting...", showBack: true, onBack: handleBack, onClose }),
63761
64230
  /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-16", children: [
63762
64231
  /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(LoaderCircle, { className: "uf-w-12 uf-h-12 uf-animate-spin uf-mb-4", style: { color: colors2.primary } }),
@@ -63767,24 +64236,132 @@ function WalletConnect({
63767
64236
  ] }),
63768
64237
  /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uf-text-sm uf-mt-2", style: { color: colors2.foregroundMuted }, children: "Please approve the connection in your wallet" })
63769
64238
  ] })
63770
- ] });
64239
+ ] }) });
64240
+ }
64241
+ if (view === "mobile_redirect" && mobileRedirect) {
64242
+ const Icon22 = WALLET_ICONS3[mobileRedirect.walletId];
64243
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
64244
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(DepositHeader, { title: mobileRedirect.walletName, showBack: true, onBack: handleBack, onClose }),
64245
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-px-6 uf-py-10", children: [
64246
+ Icon22 ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(Icon22, { size: 64, className: "uf-rounded-2xl uf-mb-5" }) : /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uf-w-16 uf-h-16 uf-rounded-2xl uf-bg-gray-500 uf-mb-5" }),
64247
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
64248
+ "div",
64249
+ {
64250
+ className: "uf-text-base uf-font-medium uf-text-center uf-mb-1",
64251
+ style: { color: colors2.foreground, fontFamily: fonts.medium },
64252
+ children: [
64253
+ "Continue in ",
64254
+ mobileRedirect.walletName
64255
+ ]
64256
+ }
64257
+ ),
64258
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
64259
+ "div",
64260
+ {
64261
+ className: "uf-text-sm uf-text-center uf-mb-6",
64262
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
64263
+ children: [
64264
+ "Complete your deposit in the ",
64265
+ mobileRedirect.walletName,
64266
+ " app"
64267
+ ]
64268
+ }
64269
+ ),
64270
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
64271
+ "button",
64272
+ {
64273
+ type: "button",
64274
+ onClick: () => {
64275
+ window.location.href = mobileRedirect.deeplink;
64276
+ },
64277
+ className: "uf-w-full uf-transition-colors uf-p-3.5 uf-flex uf-items-center uf-justify-center uf-gap-2 hover:uf-opacity-90",
64278
+ style: {
64279
+ backgroundColor: components.card.backgroundColor,
64280
+ borderRadius: components.card.borderRadius,
64281
+ border: `${components.card.borderWidth}px solid ${components.card.borderColor}`,
64282
+ color: components.card.titleColor,
64283
+ fontFamily: fonts.medium
64284
+ },
64285
+ children: [
64286
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ExternalLink, { className: "uf-w-4 uf-h-4", style: { color: components.card.iconColor } }),
64287
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("span", { className: "uf-text-sm uf-font-medium", children: [
64288
+ "Open in ",
64289
+ mobileRedirect.walletName
64290
+ ] })
64291
+ ]
64292
+ }
64293
+ ),
64294
+ awaitingMobileDeposit && /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-items-center uf-justify-center uf-gap-2 uf-mt-6", children: [
64295
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
64296
+ LoaderCircle,
64297
+ {
64298
+ className: "uf-w-4 uf-h-4 uf-animate-spin",
64299
+ style: { color: colors2.foregroundMuted }
64300
+ }
64301
+ ),
64302
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
64303
+ "span",
64304
+ {
64305
+ className: "uf-text-sm",
64306
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
64307
+ children: "Checking for deposit..."
64308
+ }
64309
+ )
64310
+ ] })
64311
+ ] })
64312
+ ] }) });
64313
+ }
64314
+ if (view === "mobile_deposit_status" && latestDepositExecution) {
64315
+ const isComplete = latestDepositExecution.status === ExecutionStatus.SUCCEEDED;
64316
+ const isFailed = latestDepositExecution.status === ExecutionStatus.FAILED;
64317
+ const title = isComplete ? "Payment Complete" : isFailed ? "Payment Failed" : "Payment Processing";
64318
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
64319
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
64320
+ DepositHeader,
64321
+ {
64322
+ title,
64323
+ showBack: false,
64324
+ onClose: isComplete && onDone ? onDone : onClose
64325
+ }
64326
+ ),
64327
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(DepositDetailContent, { execution: latestDepositExecution }),
64328
+ isComplete && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uf-flex uf-gap-2 uf-px-2 uf-pt-4 uf-pb-4", children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
64329
+ "button",
64330
+ {
64331
+ type: "button",
64332
+ onClick: onDone ? onDone : onNewDeposit ? onNewDeposit : onClose ?? (() => {
64333
+ }),
64334
+ className: "uf-flex-1 uf-py-4 uf-text-sm uf-font-medium uf-transition-opacity hover:uf-opacity-80",
64335
+ style: {
64336
+ backgroundColor: colors2.primary,
64337
+ color: colors2.primaryForeground,
64338
+ fontFamily: fonts.medium,
64339
+ borderRadius: components.button.borderRadius,
64340
+ border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
64341
+ },
64342
+ children: "Done"
64343
+ }
64344
+ ) })
64345
+ ] }) });
63771
64346
  }
63772
64347
  if (!hasWallet) return null;
64348
+ const walletAccent = getWalletBrandColor(walletInfo.type, mode);
64349
+ const walletAccentForeground = walletAccent ? getContrastingTextColor(walletAccent) : void 0;
63773
64350
  if (view === "select_token") {
63774
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(SelectTokenView, { walletInfo, projectName, assetCdnUrl, balances, isLoading, error, selectedBalance, totalBalanceUsd, onTokenSelect: handleTokenSelect, onContinue: handleContinueToAmount, onBack: handleBack, onClose: onClose ?? (() => {
63775
- }), onDisconnectWallet: onWalletDisconnect ? () => void handleDisconnect() : void 0, isDisconnectingWallet, checkoutAmountUsd, checkoutReceivedUsd }) });
64351
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(SelectTokenView, { walletInfo, projectName, assetCdnUrl, balances, isLoading, error, selectedBalance, totalBalanceUsd, onTokenSelect: handleTokenSelect, onContinue: handleContinueToAmount, onBack: handleBack, onClose: onClose ?? (() => {
64352
+ }), onDisconnectWallet: onWalletDisconnect ? () => void handleDisconnect() : void 0, isDisconnectingWallet, checkoutAmountUsd, checkoutReceivedUsd }) }) });
63776
64353
  }
63777
64354
  if (view === "enter_amount" && selectedToken && selectedBalance) {
63778
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(EnterAmountView, { walletInfo, selectedBalance, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, inputUsdNum, maxUsdAmount, isValidAmount, error, onAmountChange: setAmountUsd, onMaxClick: handleMaxClick, onReview: handleReview, onBack: handleBack, onClose: onClose ?? (() => {
63779
- }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd }) });
64355
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(EnterAmountView, { walletInfo, selectedBalance, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, inputUsdNum, maxUsdAmount, isValidAmount, error, onAmountChange: setAmountUsd, onMaxClick: handleMaxClick, onReview: handleReview, onBack: handleBack, onClose: onClose ?? (() => {
64356
+ }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd }) }) });
63780
64357
  }
63781
64358
  if (view === "review" && selectedToken) {
63782
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ReviewView, { walletInfo, recipientAddress, assetCdnUrl, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, loadingTokenDetails, showTransactionDetails, isConfirming, error, onToggleDetails: () => setShowTransactionDetails(!showTransactionDetails), onConfirm: handleConfirm, onBack: handleBack, onClose: onClose ?? (() => {
63783
- }) }) });
64359
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ReviewView, { walletInfo, recipientAddress, assetCdnUrl, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, loadingTokenDetails, showTransactionDetails, isConfirming, error, onToggleDetails: () => setShowTransactionDetails(!showTransactionDetails), onConfirm: handleConfirm, onBack: handleBack, onClose: onClose ?? (() => {
64360
+ }) }) }) });
63784
64361
  }
63785
64362
  if (view === "confirming") {
63786
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ConfirmingView, { isConfirming, onClose: onClose ?? (() => {
63787
- }), executions: depositExecutions, isPolling, onNewDeposit, onDone, paymentIntentStatus, amountReceivedUsd: checkoutReceivedUsd, amountReceivedUsdAtSubmission: receivedUsdAtSubmission }) });
64363
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ConfirmingView, { isConfirming, onClose: onClose ?? (() => {
64364
+ }), executions: depositExecutions, isPolling, onNewDeposit, onDone, paymentIntentStatus, amountReceivedUsd: checkoutReceivedUsd, amountReceivedUsdAtSubmission: receivedUsdAtSubmission }) }) });
63788
64365
  }
63789
64366
  return null;
63790
64367
  }
@@ -63828,16 +64405,17 @@ function DepositModal({
63828
64405
  defaultSourceChainId,
63829
64406
  defaultSourceTokenAddress,
63830
64407
  defaultSourceSymbol,
63831
- hideDepositTracker = false,
64408
+ hideDepositTracker,
63832
64409
  showBalanceHeader = false,
63833
64410
  transferInputVariant = "double_input",
63834
64411
  depositConfirmationMode = "auto_ui",
63835
- enableConnectWallet = false,
64412
+ enableTransferCrypto,
64413
+ enableConnectWallet,
63836
64414
  browserWalletAmountQuickSelect = "percentage",
63837
64415
  enablePayWithExchange,
63838
64416
  enableFiatOnramp,
63839
- enableConnectExchange = false,
63840
- enableCashApp = false,
64417
+ enableConnectExchange,
64418
+ enableCashApp,
63841
64419
  hideDepositFlowInfo = false,
63842
64420
  hideDisplayDescription = false,
63843
64421
  onDepositSuccess,
@@ -63855,12 +64433,13 @@ function DepositModal({
63855
64433
  const { colors: colors2, fonts, components } = useTheme();
63856
64434
  const effectiveInitialScreen = (0, import_react3.useMemo)(() => {
63857
64435
  const s = initialScreen ?? "main";
63858
- if (s === "tracker" && hideDepositTracker) return "main";
63859
- if (s === "cashapp" && !enableCashApp) return "main";
64436
+ if (s === "tracker" && hideDepositTracker === true) return "main";
64437
+ if (s === "cashapp" && enableCashApp === false) return "main";
63860
64438
  if (s === "card" && enableFiatOnramp === false) return "main";
63861
64439
  if (s === "pay_with_exchange") return enablePayWithExchange === false ? "main" : "exchange";
63862
- if (s === "exchange_connect") return enableConnectExchange ? "coinbase_connect" : "main";
63863
- if (s === "wallet_connect") return enableConnectWallet ? "wallet_connect" : "main";
64440
+ if (s === "exchange_connect")
64441
+ return enableConnectExchange === false ? "main" : "coinbase_connect";
64442
+ if (s === "wallet_connect") return enableConnectWallet === false ? "main" : "wallet_connect";
63864
64443
  return s;
63865
64444
  }, [
63866
64445
  initialScreen,
@@ -63889,26 +64468,36 @@ function DepositModal({
63889
64468
  const [browserWalletModalOpen, setBrowserWalletModalOpen] = (0, import_react3.useState)(false);
63890
64469
  const [browserWalletInfo, setBrowserWalletInfo] = (0, import_react3.useState)(null);
63891
64470
  const [walletSelectionModalOpen, setWalletSelectionModalOpen] = (0, import_react3.useState)(false);
63892
- const [browserWalletChainType, setBrowserWalletChainType] = (0, import_react3.useState)(() => getStoredWalletChainType());
64471
+ const [browserWalletChainType, setBrowserWalletChainType] = (0, import_react3.useState)(() => getStoredWalletState()?.chainType);
63893
64472
  const [quotesCount, setQuotesCount] = (0, import_react3.useState)(0);
63894
64473
  const [allExecutions, setAllExecutions] = (0, import_react3.useState)([]);
63895
64474
  const [selectedExecution, setSelectedExecution] = (0, import_react3.useState)(null);
63896
64475
  const [depositExecutions, setDepositExecutions] = (0, import_react3.useState)([]);
63897
- const isMobileView = useIsMobileViewport();
64476
+ const { projectConfig } = useProjectConfig({
64477
+ publishableKey,
64478
+ enabled: open
64479
+ });
64480
+ const showTransferCrypto = enableTransferCrypto ?? projectConfig?.transfer_crypto?.enabled ?? true;
64481
+ const showConnectWallet = enableConnectWallet ?? projectConfig?.connect_wallet?.enabled ?? true;
64482
+ const showPayWithExchange = enablePayWithExchange ?? projectConfig?.pay_with_exchange?.enabled ?? true;
64483
+ const showFiatOnramp = enableFiatOnramp ?? projectConfig?.fiat_onramp?.enabled ?? true;
64484
+ const showConnectExchange = enableConnectExchange ?? projectConfig?.connect_exchange?.enabled ?? true;
64485
+ const showCashApp = enableCashApp ?? projectConfig?.cash_app?.enabled ?? true;
64486
+ const showDepositTracker = hideDepositTracker ? false : projectConfig?.deposit_tracker?.enabled ?? true;
63898
64487
  const [integrationExchanges, setIntegrationExchanges] = (0, import_react3.useState)([]);
63899
64488
  (0, import_react3.useEffect)(() => {
63900
- if (!enableConnectExchange || !open) return;
64489
+ if (!showConnectExchange || !open) return;
63901
64490
  getIntegrationExchanges(publishableKey).then((res) => setIntegrationExchanges(res.data)).catch(() => {
63902
64491
  });
63903
- }, [enableConnectExchange, open, publishableKey]);
64492
+ }, [showConnectExchange, open, publishableKey]);
63904
64493
  const [connectedExchange, setConnectedExchange] = (0, import_react3.useState)(() => {
63905
- if (!enableConnectExchange) return null;
64494
+ if (!showConnectExchange) return null;
63906
64495
  const stored = getStoredIntegrationToken(IntegrationProvider.COINBASE);
63907
64496
  if (!stored) return null;
63908
64497
  return { name: "Coinbase", iconUrl: void 0, balanceUsd: null, isLoading: true };
63909
64498
  });
63910
64499
  (0, import_react3.useEffect)(() => {
63911
- if (!enableConnectExchange || !open || view !== "main") return;
64500
+ if (!showConnectExchange || !open || view !== "main") return;
63912
64501
  const stored = getStoredIntegrationToken(IntegrationProvider.COINBASE);
63913
64502
  if (!stored) {
63914
64503
  setConnectedExchange(null);
@@ -63943,7 +64532,7 @@ function DepositModal({
63943
64532
  setConnectedExchange(null);
63944
64533
  }
63945
64534
  });
63946
- }, [enableConnectExchange, open, view, publishableKey]);
64535
+ }, [showConnectExchange, open, view, publishableKey]);
63947
64536
  (0, import_react3.useEffect)(() => {
63948
64537
  if (!connectedExchange || integrationExchanges.length === 0) return;
63949
64538
  const cbExchange = integrationExchanges.find(
@@ -63982,18 +64571,33 @@ function DepositModal({
63982
64571
  setResolvedTheme(theme);
63983
64572
  }
63984
64573
  }, [theme]);
63985
- const { projectConfig } = useProjectConfig({
63986
- publishableKey,
63987
- enabled: open
63988
- });
63989
- const showPayWithExchange = enablePayWithExchange ?? projectConfig?.pay_with_exchange?.enabled ?? true;
63990
- const showFiatOnramp = enableFiatOnramp ?? projectConfig?.fiat_onramp?.enabled ?? true;
63991
64574
  (0, import_react3.useEffect)(() => {
63992
64575
  if (view === "card" && !showFiatOnramp) {
63993
64576
  setView("main");
63994
64577
  setCardView("amount");
64578
+ } else if (view === "transfer" && !showTransferCrypto) {
64579
+ setView("main");
64580
+ } else if (view === "exchange" && !showPayWithExchange) {
64581
+ setView("main");
64582
+ } else if (view === "cashapp" && !showCashApp) {
64583
+ setView("main");
64584
+ } else if (view === "tracker" && !showDepositTracker) {
64585
+ setView("main");
64586
+ } else if (view === "coinbase_connect" && !showConnectExchange) {
64587
+ setView("main");
64588
+ } else if (view === "wallet_connect" && !showConnectWallet) {
64589
+ setView("main");
63995
64590
  }
63996
- }, [view, showFiatOnramp]);
64591
+ }, [
64592
+ view,
64593
+ showFiatOnramp,
64594
+ showTransferCrypto,
64595
+ showPayWithExchange,
64596
+ showCashApp,
64597
+ showDepositTracker,
64598
+ showConnectExchange,
64599
+ showConnectWallet
64600
+ ]);
63997
64601
  (0, import_react3.useEffect)(() => {
63998
64602
  if (view === "exchange" && !showPayWithExchange) {
63999
64603
  setView("main");
@@ -64083,7 +64687,7 @@ function DepositModal({
64083
64687
  depositPrerequisiteBody = standaloneNeedsDepositPrereq ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(SkeletonButton, { variant: "with-icons" }) : /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64084
64688
  /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(SkeletonButton, { variant: "with-icons" }),
64085
64689
  /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(SkeletonButton, { variant: "with-icons" }),
64086
- !hideDepositTracker && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(SkeletonButton, {})
64690
+ showDepositTracker && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(SkeletonButton, {})
64087
64691
  ] });
64088
64692
  } else if (countryError) {
64089
64693
  depositPrerequisiteBody = /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-8 uf-px-4 uf-text-center", children: [
@@ -64115,7 +64719,7 @@ function DepositModal({
64115
64719
  const themeClass = resolvedTheme === "dark" ? "uf-dark" : "";
64116
64720
  const handleWalletDisconnect = () => {
64117
64721
  setUserDisconnectedWallet(true);
64118
- clearStoredWalletChainType();
64722
+ clearStoredWalletState();
64119
64723
  setBrowserWalletChainType(void 0);
64120
64724
  setBrowserWalletInfo(null);
64121
64725
  setBrowserWalletModalOpen(false);
@@ -64193,7 +64797,7 @@ function DepositModal({
64193
64797
  };
64194
64798
  const handleBrowserWalletClick = (walletInfo) => {
64195
64799
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
64196
- setStoredWalletChainType(walletChainType);
64800
+ setStoredWalletState(walletInfo.type);
64197
64801
  setBrowserWalletChainType(walletChainType);
64198
64802
  const matchingDepositWallet = wallets.find(
64199
64803
  (w) => w.chain_type === walletChainType
@@ -64224,7 +64828,7 @@ function DepositModal({
64224
64828
  };
64225
64829
  const handleWalletConnected = (walletInfo) => {
64226
64830
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
64227
- setStoredWalletChainType(walletChainType);
64831
+ setStoredWalletState(walletInfo.type);
64228
64832
  setBrowserWalletChainType(walletChainType);
64229
64833
  const matchingDepositWallet = wallets.find(
64230
64834
  (w) => w.chain_type === walletChainType
@@ -64264,7 +64868,7 @@ function DepositModal({
64264
64868
  open: hideOverlay || open,
64265
64869
  onOpenChange: hideOverlay ? void 0 : handleClose,
64266
64870
  modal: !hideOverlay,
64267
- children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64871
+ children: /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(
64268
64872
  DialogContent2,
64269
64873
  {
64270
64874
  ref: hideOverlay ? containerCallbackRef : void 0,
@@ -64273,378 +64877,389 @@ function DepositModal({
64273
64877
  style: { backgroundColor: colors2.background },
64274
64878
  onPointerDownOutside: (e) => e.preventDefault(),
64275
64879
  onInteractOutside: (e) => e.preventDefault(),
64276
- children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ThemeStyleInjector, { children: view === "main" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64277
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64278
- DepositHeader,
64279
- {
64280
- title: modalTitle || "Deposit",
64281
- showClose: !hideOverlay,
64282
- onClose: handleClose,
64283
- showBalance: showBalanceHeader,
64284
- balanceAddress: recipientAddress,
64285
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
64286
- balanceChainId: destinationChainId,
64287
- balanceTokenAddress: destinationTokenAddress,
64288
- projectName: projectConfig?.project_name,
64289
- publishableKey
64290
- }
64291
- ),
64292
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64293
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-space-y-3", children: depositPrerequisiteBody ?? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64294
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64295
- TransferCryptoButton,
64296
- {
64297
- onClick: () => setView("transfer"),
64298
- title: transferCryptoTitle,
64299
- subtitle: t7.transferCrypto.subtitle,
64300
- featuredTokens: projectConfig?.transfer_crypto.networks
64301
- }
64302
- ),
64303
- enableConnectWallet && !isMobileView && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64304
- BrowserWalletButton,
64880
+ children: [
64881
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(DialogTitle2, { className: "uf-sr-only", children: modalTitle || "Deposit" }),
64882
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ThemeStyleInjector, { children: view === "main" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64883
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64884
+ DepositHeader,
64885
+ {
64886
+ title: modalTitle || "Deposit",
64887
+ showClose: !hideOverlay,
64888
+ onClose: handleClose,
64889
+ showBalance: showBalanceHeader,
64890
+ balanceAddress: recipientAddress,
64891
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
64892
+ balanceChainId: destinationChainId,
64893
+ balanceTokenAddress: destinationTokenAddress,
64894
+ projectName: projectConfig?.project_name,
64895
+ publishableKey
64896
+ }
64897
+ ),
64898
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64899
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-space-y-3", children: depositPrerequisiteBody ?? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64900
+ showTransferCrypto && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64901
+ TransferCryptoButton,
64902
+ {
64903
+ onClick: () => setView("transfer"),
64904
+ title: transferCryptoTitle,
64905
+ subtitle: t7.transferCrypto.subtitle,
64906
+ featuredTokens: projectConfig?.transfer_crypto.networks
64907
+ }
64908
+ ),
64909
+ showConnectWallet && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64910
+ BrowserWalletButton,
64911
+ {
64912
+ onClick: handleBrowserWalletClick,
64913
+ onConnectClick: handleWalletConnectClick,
64914
+ onDisconnect: handleWalletDisconnect,
64915
+ chainType: browserWalletChainType,
64916
+ publishableKey,
64917
+ featuredWallets: projectConfig?.connect_wallet?.wallets
64918
+ }
64919
+ ),
64920
+ showFiatOnramp && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64921
+ DepositWithCardButton,
64922
+ {
64923
+ onClick: () => setView("card"),
64924
+ title: depositWithCardTitle,
64925
+ subtitle: t7.depositWithCard.subtitle,
64926
+ paymentNetworks: projectConfig?.payment_networks.networks
64927
+ }
64928
+ ),
64929
+ showPayWithExchange && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64930
+ PayWithExchangeButton,
64931
+ {
64932
+ onClick: () => setView("exchange"),
64933
+ title: payWithExchangeTitle,
64934
+ subtitle: t7.payWithExchange.subtitle,
64935
+ exchanges,
64936
+ loading: exchangesLoading
64937
+ }
64938
+ ),
64939
+ showConnectExchange && connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64940
+ ConnectExchangeButton,
64941
+ {
64942
+ onClick: () => {
64943
+ setCoinbaseSkipToHoldings(true);
64944
+ setView("coinbase_connect");
64945
+ },
64946
+ onDisconnect: handleExchangeDisconnect,
64947
+ title: i18n2.connectExchange.title,
64948
+ subtitle: i18n2.connectExchange.subtitle,
64949
+ exchanges: integrationExchanges,
64950
+ connectedExchange
64951
+ }
64952
+ ),
64953
+ showConnectExchange && !connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64954
+ ConnectExchangeButton,
64955
+ {
64956
+ onClick: () => {
64957
+ setCoinbaseSkipToHoldings(false);
64958
+ setView("coinbase_connect");
64959
+ },
64960
+ title: i18n2.connectExchange.title,
64961
+ subtitle: i18n2.connectExchange.subtitle,
64962
+ exchanges: integrationExchanges
64963
+ }
64964
+ ),
64965
+ showCashApp && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64966
+ CashAppButton,
64967
+ {
64968
+ onClick: () => setView("cashapp"),
64969
+ title: "Pay with Cash App",
64970
+ subtitle: "Deposit via Cash App",
64971
+ iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
64972
+ }
64973
+ ),
64974
+ showDepositTracker && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64975
+ DepositTrackerButton,
64976
+ {
64977
+ onClick: () => {
64978
+ setAllExecutions(depositExecutions);
64979
+ setView("tracker");
64980
+ },
64981
+ title: depositTrackerTitle,
64982
+ subtitle: depositTrackerSubTitle,
64983
+ badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
64984
+ }
64985
+ )
64986
+ ] }) }),
64987
+ depositPoweredByFooter
64988
+ ] })
64989
+ ] }) : view === "transfer" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64990
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64991
+ DepositHeader,
64992
+ {
64993
+ title: transferCryptoTitle,
64994
+ showBack: showBackTransfer,
64995
+ onBack: handleBack,
64996
+ onClose: handleClose,
64997
+ showBalance: showBalanceHeader,
64998
+ balanceAddress: recipientAddress,
64999
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
65000
+ balanceChainId: destinationChainId,
65001
+ balanceTokenAddress: destinationTokenAddress,
65002
+ projectName: projectConfig?.project_name,
65003
+ publishableKey
65004
+ }
65005
+ ),
65006
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65007
+ standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : transferInputVariant === "single_input" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65008
+ TransferCryptoSingleInput,
64305
65009
  {
64306
- onClick: handleBrowserWalletClick,
64307
- onConnectClick: handleWalletConnectClick,
64308
- onDisconnect: handleWalletDisconnect,
64309
- chainType: browserWalletChainType,
65010
+ userId,
64310
65011
  publishableKey,
64311
- featuredWallets: projectConfig?.connect_wallet?.wallets
65012
+ recipientAddress,
65013
+ destinationChainType,
65014
+ destinationChainId,
65015
+ destinationTokenAddress,
65016
+ defaultSourceChainType,
65017
+ defaultSourceChainId,
65018
+ defaultSourceTokenAddress,
65019
+ defaultSourceSymbol,
65020
+ depositConfirmationMode,
65021
+ onExecutionsChange: setDepositExecutions,
65022
+ onDepositSuccess,
65023
+ onDepositError,
65024
+ wallets
64312
65025
  }
64313
- ),
64314
- showFiatOnramp && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64315
- DepositWithCardButton,
65026
+ ) : /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65027
+ TransferCryptoDoubleInput,
64316
65028
  {
64317
- onClick: () => setView("card"),
64318
- title: depositWithCardTitle,
64319
- subtitle: t7.depositWithCard.subtitle,
64320
- paymentNetworks: projectConfig?.payment_networks.networks
65029
+ userId,
65030
+ publishableKey,
65031
+ recipientAddress,
65032
+ destinationChainType,
65033
+ destinationChainId,
65034
+ destinationTokenAddress,
65035
+ defaultSourceChainType,
65036
+ defaultSourceChainId,
65037
+ defaultSourceTokenAddress,
65038
+ defaultSourceSymbol,
65039
+ depositConfirmationMode,
65040
+ onExecutionsChange: setDepositExecutions,
65041
+ onDepositSuccess,
65042
+ onDepositError,
65043
+ wallets
64321
65044
  }
64322
65045
  ),
64323
- showPayWithExchange && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64324
- PayWithExchangeButton,
65046
+ depositPoweredByFooter
65047
+ ] })
65048
+ ] }) : view === "tracker" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
65049
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65050
+ DepositHeader,
65051
+ {
65052
+ title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
65053
+ showBack: showBackTracker,
65054
+ onBack: handleBack,
65055
+ onClose: handleClose
65056
+ }
65057
+ ),
65058
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65059
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-h-[460px] uf-overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: selectedExecution ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(DepositDetailContent, { execution: selectedExecution }) : /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-space-y-2 uf-pb-8", children: allExecutions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-py-8 uf-px-4 uf-text-center", children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65060
+ "div",
64325
65061
  {
64326
- onClick: () => setView("exchange"),
64327
- title: payWithExchangeTitle,
64328
- subtitle: t7.payWithExchange.subtitle,
64329
- exchanges,
64330
- loading: exchangesLoading
65062
+ className: "uf-text-sm",
65063
+ style: { color: components.container.subtitleColor, fontFamily: fonts.regular },
65064
+ children: "No deposits yet"
64331
65065
  }
64332
- ),
64333
- enableConnectExchange && connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64334
- ConnectExchangeButton,
65066
+ ) }) : allExecutions.map((execution) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65067
+ DepositExecutionItem,
64335
65068
  {
64336
- onClick: () => {
64337
- setCoinbaseSkipToHoldings(true);
64338
- setView("coinbase_connect");
64339
- },
64340
- onDisconnect: handleExchangeDisconnect,
64341
- title: i18n2.connectExchange.title,
64342
- subtitle: i18n2.connectExchange.subtitle,
64343
- exchanges: integrationExchanges,
64344
- connectedExchange
64345
- }
64346
- ),
64347
- enableConnectExchange && !connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64348
- ConnectExchangeButton,
65069
+ execution,
65070
+ onClick: () => setSelectedExecution(execution)
65071
+ },
65072
+ execution.id
65073
+ )) }) }),
65074
+ depositPoweredByFooter
65075
+ ] })
65076
+ ] }) : view === "card" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
65077
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65078
+ DepositHeader,
65079
+ {
65080
+ title: cardView === "quotes" ? t7.quotes : depositWithCardTitle,
65081
+ showBack: showBackCard,
65082
+ onBack: handleBack,
65083
+ onClose: handleClose,
65084
+ badge: cardView === "quotes" ? { count: quotesCount } : void 0,
65085
+ showBalance: showBalanceHeader,
65086
+ balanceAddress: recipientAddress,
65087
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
65088
+ balanceChainId: destinationChainId,
65089
+ balanceTokenAddress: destinationTokenAddress,
65090
+ projectName: projectConfig?.project_name,
65091
+ publishableKey
65092
+ }
65093
+ ),
65094
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65095
+ standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65096
+ BuyWithCard,
64349
65097
  {
64350
- onClick: () => {
64351
- setCoinbaseSkipToHoldings(false);
64352
- setView("coinbase_connect");
64353
- },
64354
- title: i18n2.connectExchange.title,
64355
- subtitle: i18n2.connectExchange.subtitle,
64356
- exchanges: integrationExchanges
65098
+ userId,
65099
+ publishableKey,
65100
+ view: cardView,
65101
+ onViewChange: handleCardViewChange,
65102
+ destinationTokenSymbol,
65103
+ recipientAddress,
65104
+ destinationChainType,
65105
+ destinationChainId,
65106
+ destinationTokenAddress,
65107
+ onDepositSuccess,
65108
+ onDepositError,
65109
+ onEvent,
65110
+ themeClass,
65111
+ wallets,
65112
+ assetCdnUrl: projectConfig?.asset_cdn_url,
65113
+ hideDepositFlowInfo,
65114
+ hideDisplayDescription
64357
65115
  }
64358
65116
  ),
64359
- enableCashApp && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64360
- CashAppButton,
65117
+ depositPoweredByFooter
65118
+ ] })
65119
+ ] }) : view === "exchange" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
65120
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65121
+ DepositHeader,
65122
+ {
65123
+ title: payWithExchangeTitle,
65124
+ showBack: exchangeView === "pending" || sessionOpenedFromMenu,
65125
+ onBack: handleBack,
65126
+ onClose: handleClose
65127
+ }
65128
+ ),
65129
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65130
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65131
+ PayWithExchange,
64361
65132
  {
64362
- onClick: () => setView("cashapp"),
64363
- title: "Pay with Cash App",
64364
- subtitle: "Deposit via Cash App",
64365
- iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
65133
+ userId,
65134
+ publishableKey,
65135
+ exchanges,
65136
+ view: exchangeView,
65137
+ onViewChange: setExchangeView,
65138
+ destinationTokenSymbol,
65139
+ recipientAddress,
65140
+ destinationChainType,
65141
+ destinationChainId,
65142
+ destinationTokenAddress,
65143
+ onDepositSuccess,
65144
+ onDepositError,
65145
+ wallets,
65146
+ defaultToken: defaultToken ?? null
64366
65147
  }
64367
65148
  ),
64368
- !hideDepositTracker && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64369
- DepositTrackerButton,
64370
- {
64371
- onClick: () => {
64372
- setAllExecutions(depositExecutions);
64373
- setView("tracker");
64374
- },
64375
- title: depositTrackerTitle,
64376
- subtitle: depositTrackerSubTitle,
64377
- badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
64378
- }
64379
- )
64380
- ] }) }),
64381
- depositPoweredByFooter
64382
- ] })
64383
- ] }) : view === "transfer" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64384
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64385
- DepositHeader,
64386
- {
64387
- title: transferCryptoTitle,
64388
- showBack: showBackTransfer,
64389
- onBack: handleBack,
64390
- onClose: handleClose,
64391
- showBalance: showBalanceHeader,
64392
- balanceAddress: recipientAddress,
64393
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
64394
- balanceChainId: destinationChainId,
64395
- balanceTokenAddress: destinationTokenAddress,
64396
- projectName: projectConfig?.project_name,
64397
- publishableKey
64398
- }
64399
- ),
64400
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64401
- standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : transferInputVariant === "single_input" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64402
- TransferCryptoSingleInput,
65149
+ depositPoweredByFooter
65150
+ ] })
65151
+ ] }) : view === "coinbase_connect" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65152
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65153
+ CoinbaseConnect,
64403
65154
  {
64404
- userId,
64405
65155
  publishableKey,
64406
- recipientAddress,
64407
- destinationChainType,
64408
- destinationChainId,
64409
- destinationTokenAddress,
64410
- defaultSourceChainType,
64411
- defaultSourceChainId,
64412
- defaultSourceTokenAddress,
64413
- defaultSourceSymbol,
64414
- depositConfirmationMode,
64415
- onExecutionsChange: setDepositExecutions,
64416
- onDepositSuccess,
64417
- onDepositError,
64418
- wallets
64419
- }
64420
- ) : /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64421
- TransferCryptoDoubleInput,
64422
- {
64423
65156
  userId,
64424
- publishableKey,
65157
+ wallets,
64425
65158
  recipientAddress,
64426
- destinationChainType,
64427
- destinationChainId,
64428
- destinationTokenAddress,
65159
+ destinationTokenAddress: destinationTokenAddress ?? "",
65160
+ destinationChainId: destinationChainId ?? "",
65161
+ destinationChainType: destinationChainType ?? "",
65162
+ onTransferSuccess: (result) => {
65163
+ onDepositSuccess?.({
65164
+ message: "Transfer completed via Coinbase Connect",
65165
+ transaction: result
65166
+ });
65167
+ },
65168
+ onTransferError: (error) => {
65169
+ onDepositError?.({
65170
+ message: error.message,
65171
+ error
65172
+ });
65173
+ },
65174
+ onBack: handleBack,
65175
+ onClose: handleClose,
65176
+ onDisconnect: handleExchangeDisconnect,
65177
+ skipToHoldings: coinbaseSkipToHoldings,
65178
+ canGoBack: sessionOpenedFromMenu,
65179
+ onExecutionsChange: setDepositExecutions,
64429
65180
  defaultSourceChainType,
64430
65181
  defaultSourceChainId,
64431
65182
  defaultSourceTokenAddress,
64432
- defaultSourceSymbol,
64433
- depositConfirmationMode,
64434
- onExecutionsChange: setDepositExecutions,
64435
- onDepositSuccess,
64436
- onDepositError,
64437
- wallets
64438
- }
64439
- ),
64440
- depositPoweredByFooter
64441
- ] })
64442
- ] }) : view === "tracker" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64443
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64444
- DepositHeader,
64445
- {
64446
- title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
64447
- showBack: showBackTracker,
64448
- onBack: handleBack,
64449
- onClose: handleClose
64450
- }
64451
- ),
64452
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64453
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-h-[460px] uf-overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: selectedExecution ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(DepositDetailContent, { execution: selectedExecution }) : /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-space-y-2 uf-pb-8", children: allExecutions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-py-8 uf-px-4 uf-text-center", children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64454
- "div",
64455
- {
64456
- className: "uf-text-sm",
64457
- style: { color: components.container.subtitleColor, fontFamily: fonts.regular },
64458
- children: "No deposits yet"
64459
- }
64460
- ) }) : allExecutions.map((execution) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64461
- DepositExecutionItem,
64462
- {
64463
- execution,
64464
- onClick: () => setSelectedExecution(execution)
64465
- },
64466
- execution.id
64467
- )) }) }),
64468
- depositPoweredByFooter
64469
- ] })
64470
- ] }) : view === "card" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64471
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64472
- DepositHeader,
64473
- {
64474
- title: cardView === "quotes" ? t7.quotes : depositWithCardTitle,
64475
- showBack: showBackCard,
64476
- onBack: handleBack,
64477
- onClose: handleClose,
64478
- badge: cardView === "quotes" ? { count: quotesCount } : void 0,
64479
- showBalance: showBalanceHeader,
64480
- balanceAddress: recipientAddress,
64481
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
64482
- balanceChainId: destinationChainId,
64483
- balanceTokenAddress: destinationTokenAddress,
64484
- projectName: projectConfig?.project_name,
64485
- publishableKey
64486
- }
64487
- ),
64488
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64489
- standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64490
- BuyWithCard,
64491
- {
64492
- userId,
64493
- publishableKey,
64494
- view: cardView,
64495
- onViewChange: handleCardViewChange,
64496
- destinationTokenSymbol,
64497
- recipientAddress,
64498
- destinationChainType,
64499
- destinationChainId,
64500
- destinationTokenAddress,
64501
- onDepositSuccess,
64502
- onDepositError,
64503
- onEvent,
64504
- themeClass,
64505
- wallets,
64506
- assetCdnUrl: projectConfig?.asset_cdn_url,
64507
- hideDepositFlowInfo,
64508
- hideDisplayDescription
65183
+ defaultSourceSymbol
64509
65184
  }
64510
65185
  ),
64511
65186
  depositPoweredByFooter
64512
- ] })
64513
- ] }) : view === "exchange" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64514
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64515
- DepositHeader,
64516
- {
64517
- title: payWithExchangeTitle,
64518
- showBack: exchangeView === "pending" || sessionOpenedFromMenu,
64519
- onBack: handleBack,
64520
- onClose: handleClose
64521
- }
64522
- ),
64523
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65187
+ ] }) : view === "wallet_connect" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64524
65188
  /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64525
- PayWithExchange,
65189
+ WalletConnect,
64526
65190
  {
65191
+ walletInfo: browserWalletInfo ?? void 0,
65192
+ depositWallet: browserWalletInfo?.depositWallet ?? void 0,
65193
+ wallets,
64527
65194
  userId,
64528
65195
  publishableKey,
64529
- exchanges,
64530
- view: exchangeView,
64531
- onViewChange: setExchangeView,
64532
- destinationTokenSymbol,
64533
- recipientAddress,
64534
- destinationChainType,
64535
- destinationChainId,
64536
- destinationTokenAddress,
65196
+ assetCdnUrl: projectConfig?.asset_cdn_url,
65197
+ projectName: projectConfig?.project_name,
65198
+ onSuccess: (txHash) => {
65199
+ onDepositSuccess?.({
65200
+ message: "Transaction sent successfully",
65201
+ transaction: { txHash }
65202
+ });
65203
+ },
65204
+ onError: (error) => {
65205
+ onDepositError?.({
65206
+ message: error.message,
65207
+ error
65208
+ });
65209
+ },
64537
65210
  onDepositSuccess,
64538
65211
  onDepositError,
64539
- wallets,
64540
- defaultToken: defaultToken ?? null
65212
+ amountQuickSelect: browserWalletAmountQuickSelect,
65213
+ onWalletDisconnect: handleWalletDisconnect,
65214
+ onWalletConnected: (info, dw) => {
65215
+ setBrowserWalletInfo({ ...info, depositWallet: dw });
65216
+ setStoredWalletState(info.type);
65217
+ setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
65218
+ },
65219
+ onBack: handleBack,
65220
+ onClose: handleClose,
65221
+ defaultSourceChainType,
65222
+ defaultSourceChainId,
65223
+ defaultSourceTokenAddress,
65224
+ defaultSourceSymbol,
65225
+ canGoBack: sessionOpenedFromMenu,
65226
+ depositWalletsLoading: walletsLoading
64541
65227
  }
64542
65228
  ),
64543
65229
  depositPoweredByFooter
64544
- ] })
64545
- ] }) : view === "coinbase_connect" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64546
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64547
- CoinbaseConnect,
64548
- {
64549
- publishableKey,
64550
- userId,
64551
- wallets,
64552
- recipientAddress,
64553
- destinationTokenAddress: destinationTokenAddress ?? "",
64554
- destinationChainId: destinationChainId ?? "",
64555
- destinationChainType: destinationChainType ?? "",
64556
- onTransferSuccess: (result) => {
64557
- onDepositSuccess?.({
64558
- message: "Transfer completed via Coinbase Connect",
64559
- transaction: result
64560
- });
64561
- },
64562
- onTransferError: (error) => {
64563
- onDepositError?.({
64564
- message: error.message,
64565
- error
64566
- });
64567
- },
64568
- onBack: handleBack,
64569
- onClose: handleClose,
64570
- onDisconnect: handleExchangeDisconnect,
64571
- skipToHoldings: coinbaseSkipToHoldings,
64572
- canGoBack: sessionOpenedFromMenu,
64573
- onExecutionsChange: setDepositExecutions
64574
- }
64575
- ),
64576
- depositPoweredByFooter
64577
- ] }) : view === "wallet_connect" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64578
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64579
- WalletConnect,
64580
- {
64581
- walletInfo: browserWalletInfo ?? void 0,
64582
- depositWallet: browserWalletInfo?.depositWallet ?? void 0,
64583
- wallets,
64584
- userId,
64585
- publishableKey,
64586
- assetCdnUrl: projectConfig?.asset_cdn_url,
64587
- projectName: projectConfig?.project_name,
64588
- onSuccess: (txHash) => {
64589
- onDepositSuccess?.({
64590
- message: "Transaction sent successfully",
64591
- transaction: { txHash }
64592
- });
64593
- },
64594
- onError: (error) => {
64595
- onDepositError?.({
64596
- message: error.message,
64597
- error
64598
- });
64599
- },
64600
- onDepositSuccess,
64601
- onDepositError,
64602
- amountQuickSelect: browserWalletAmountQuickSelect,
64603
- onWalletDisconnect: handleWalletDisconnect,
64604
- onWalletConnected: (info, dw) => {
64605
- setBrowserWalletInfo({ ...info, depositWallet: dw });
64606
- setStoredWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
64607
- setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
64608
- },
64609
- onBack: handleBack,
64610
- onClose: handleClose,
64611
- canGoBack: sessionOpenedFromMenu,
64612
- depositWalletsLoading: walletsLoading
64613
- }
64614
- ),
64615
- depositPoweredByFooter
64616
- ] }) : view === "cashapp" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64617
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64618
- DepositHeader,
64619
- {
64620
- title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
64621
- showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
64622
- onBack: handleBack,
64623
- onClose: handleClose
64624
- }
64625
- ),
64626
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65230
+ ] }) : view === "cashapp" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64627
65231
  /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64628
- PayWithCashApp,
65232
+ DepositHeader,
64629
65233
  {
64630
- userId,
64631
- publishableKey,
64632
- recipientAddress,
64633
- destinationChainType,
64634
- destinationChainId,
64635
- destinationTokenAddress,
64636
- cashAppIconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0,
64637
- view: cashAppView,
64638
- onViewChange: setCashAppView,
64639
- onAmountChange: setCashAppAmount,
64640
- onEvent,
64641
- onDepositSuccess,
64642
- onDepositError
65234
+ title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
65235
+ showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
65236
+ onBack: handleBack,
65237
+ onClose: handleClose
64643
65238
  }
64644
65239
  ),
64645
- depositPoweredByFooter
64646
- ] })
64647
- ] }) : null })
65240
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65241
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65242
+ PayWithCashApp,
65243
+ {
65244
+ userId,
65245
+ publishableKey,
65246
+ recipientAddress,
65247
+ destinationChainType,
65248
+ destinationChainId,
65249
+ destinationTokenAddress,
65250
+ cashAppIconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0,
65251
+ view: cashAppView,
65252
+ onViewChange: setCashAppView,
65253
+ onAmountChange: setCashAppAmount,
65254
+ onEvent,
65255
+ onDepositSuccess,
65256
+ onDepositError
65257
+ }
65258
+ ),
65259
+ depositPoweredByFooter
65260
+ ] })
65261
+ ] }) : null })
65262
+ ]
64648
65263
  }
64649
65264
  )
64650
65265
  }
@@ -64710,7 +65325,8 @@ function CheckoutModal({
64710
65325
  clientSecret,
64711
65326
  publishableKey,
64712
65327
  modalTitle,
64713
- enableConnectWallet = false,
65328
+ enableTransferCrypto,
65329
+ enableConnectWallet,
64714
65330
  defaultSourceChainType,
64715
65331
  defaultSourceChainId,
64716
65332
  defaultSourceTokenAddress,
@@ -64727,8 +65343,7 @@ function CheckoutModal({
64727
65343
  const [browserWalletModalOpen, setBrowserWalletModalOpen] = (0, import_react29.useState)(false);
64728
65344
  const [browserWalletInfo, setBrowserWalletInfo] = (0, import_react29.useState)(null);
64729
65345
  const [walletSelectionModalOpen, setWalletSelectionModalOpen] = (0, import_react29.useState)(false);
64730
- const [browserWalletChainType, setBrowserWalletChainType] = (0, import_react29.useState)(() => getStoredWalletChainType());
64731
- const isMobileView = useIsMobileViewport();
65346
+ const [browserWalletChainType, setBrowserWalletChainType] = (0, import_react29.useState)(() => getStoredWalletState()?.chainType);
64732
65347
  const [resolvedTheme, setResolvedTheme] = (0, import_react29.useState)(
64733
65348
  theme === "auto" ? "dark" : theme
64734
65349
  );
@@ -64760,6 +65375,15 @@ function CheckoutModal({
64760
65375
  publishableKey,
64761
65376
  enabled: open
64762
65377
  });
65378
+ const showTransferCrypto = enableTransferCrypto ?? projectConfig?.transfer_crypto?.enabled ?? true;
65379
+ const showConnectWallet = enableConnectWallet ?? projectConfig?.connect_wallet?.enabled ?? true;
65380
+ (0, import_react29.useEffect)(() => {
65381
+ if (view === "transfer" && !showTransferCrypto) {
65382
+ setView("main");
65383
+ } else if (view === "wallet_connect" && !showConnectWallet) {
65384
+ setView("main");
65385
+ }
65386
+ }, [showConnectWallet, showTransferCrypto, view]);
64763
65387
  const prevStatusRef = (0, import_react29.useRef)(null);
64764
65388
  (0, import_react29.useEffect)(() => {
64765
65389
  if (!paymentIntent) return;
@@ -64850,7 +65474,7 @@ function CheckoutModal({
64850
65474
  const handleBrowserWalletClick = (0, import_react29.useCallback)(
64851
65475
  (walletInfo) => {
64852
65476
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
64853
- setStoredWalletChainType(walletChainType);
65477
+ setStoredWalletState(walletInfo.type);
64854
65478
  setBrowserWalletChainType(walletChainType);
64855
65479
  const matchingDepositWallet = wallets.find(
64856
65480
  (w) => w.chain_type === walletChainType
@@ -64877,7 +65501,7 @@ function CheckoutModal({
64877
65501
  const handleWalletConnected = (0, import_react29.useCallback)(
64878
65502
  (walletInfo) => {
64879
65503
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
64880
- setStoredWalletChainType(walletChainType);
65504
+ setStoredWalletState(walletInfo.type);
64881
65505
  setBrowserWalletChainType(walletChainType);
64882
65506
  const matchingDepositWallet = wallets.find(
64883
65507
  (w) => w.chain_type === walletChainType
@@ -64901,7 +65525,7 @@ function CheckoutModal({
64901
65525
  );
64902
65526
  const handleWalletDisconnect = (0, import_react29.useCallback)(() => {
64903
65527
  setUserDisconnectedWallet(true);
64904
- clearStoredWalletChainType();
65528
+ clearStoredWalletState();
64905
65529
  setBrowserWalletChainType(void 0);
64906
65530
  setBrowserWalletInfo(null);
64907
65531
  setBrowserWalletModalOpen(false);
@@ -65136,7 +65760,7 @@ function CheckoutModal({
65136
65760
  ] }) : paymentIntent ? /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "uf-space-y-3", children: [
65137
65761
  progressSection,
65138
65762
  (paymentIntent.status === "requires_payment" || paymentIntent.status === "processing") && /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)(import_jsx_runtime75.Fragment, { children: [
65139
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
65763
+ showTransferCrypto && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
65140
65764
  TransferCryptoButton,
65141
65765
  {
65142
65766
  onClick: () => setView("transfer"),
@@ -65145,7 +65769,7 @@ function CheckoutModal({
65145
65769
  featuredTokens: projectConfig?.transfer_crypto.networks
65146
65770
  }
65147
65771
  ),
65148
- enableConnectWallet && !isMobileView && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
65772
+ showConnectWallet && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
65149
65773
  BrowserWalletButton,
65150
65774
  {
65151
65775
  onClick: handleBrowserWalletClick,
@@ -65286,14 +65910,18 @@ function CheckoutModal({
65286
65910
  onWalletDisconnect: handleWalletDisconnect,
65287
65911
  onWalletConnected: (info, dw) => {
65288
65912
  setBrowserWalletInfo({ ...info, depositWallet: dw });
65289
- setStoredWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
65913
+ setStoredWalletState(info.type);
65290
65914
  setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
65291
65915
  },
65292
65916
  onNewDeposit: () => setView("main"),
65293
65917
  onDone: () => setView("main"),
65294
65918
  paymentIntentStatus: paymentIntent.status,
65295
65919
  onBack: handleBack,
65296
- onClose: handleClose
65920
+ onClose: handleClose,
65921
+ defaultSourceChainType,
65922
+ defaultSourceChainId,
65923
+ defaultSourceTokenAddress,
65924
+ defaultSourceSymbol
65297
65925
  }
65298
65926
  ),
65299
65927
  poweredByFooter
@@ -67047,6 +67675,16 @@ function UnifoldProvider2({
67047
67675
  });
67048
67676
  promise.catch(() => {
67049
67677
  });
67678
+ if (!config2.recipientAddress) {
67679
+ const error = {
67680
+ message: "beginDeposit requires a `recipientAddress`.",
67681
+ code: "MISSING_RECIPIENT"
67682
+ };
67683
+ console.error(`[UnifoldProvider] ${error.message}`);
67684
+ depositPromiseRef.current.reject(error);
67685
+ depositPromiseRef.current = null;
67686
+ return promise;
67687
+ }
67050
67688
  setDepositConfig(config2);
67051
67689
  setIsOpen(true);
67052
67690
  return promise;
@@ -67256,6 +67894,7 @@ function UnifoldProvider2({
67256
67894
  onOpenChange: closeCheckout,
67257
67895
  clientSecret: checkoutConfig.clientSecret,
67258
67896
  publishableKey,
67897
+ enableTransferCrypto: config?.enableTransferCrypto,
67259
67898
  enableConnectWallet: config?.enableConnectWallet,
67260
67899
  defaultSourceChainType: checkoutConfig.defaultSourceChainType,
67261
67900
  defaultSourceChainId: checkoutConfig.defaultSourceChainId,
@@ -67312,6 +67951,7 @@ function UnifoldProvider2({
67312
67951
  hideDepositTracker: config?.hideDepositTracker,
67313
67952
  showBalanceHeader: config?.showBalanceHeader,
67314
67953
  transferInputVariant: config?.transferInputVariant,
67954
+ enableTransferCrypto: config?.enableTransferCrypto,
67315
67955
  enableConnectWallet: config?.enableConnectWallet,
67316
67956
  enablePayWithExchange: config?.enablePayWithExchange,
67317
67957
  enableFiatOnramp: config?.enableFiatOnramp,