@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.js CHANGED
@@ -43130,6 +43130,42 @@ var getDefaultConfig = () => {
43130
43130
  };
43131
43131
  };
43132
43132
  var twMerge = /* @__PURE__ */ createTailwindMerge(getDefaultConfig);
43133
+ function formatStablecoinAmount(baseUnits, decimals) {
43134
+ const raw = Number(baseUnits) / 10 ** decimals;
43135
+ const floored = Math.floor(raw * 100) / 100;
43136
+ const ceiled = raw > floored ? floored + 0.01 : raw;
43137
+ return ceiled.toFixed(2);
43138
+ }
43139
+ function generateKSUID() {
43140
+ const BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
43141
+ const KSUID_EPOCH = 14e8;
43142
+ const timestampSeconds = Math.floor(Date.now() / 1e3) - KSUID_EPOCH;
43143
+ const payload = new Uint8Array(20);
43144
+ payload[0] = timestampSeconds >>> 24 & 255;
43145
+ payload[1] = timestampSeconds >>> 16 & 255;
43146
+ payload[2] = timestampSeconds >>> 8 & 255;
43147
+ payload[3] = timestampSeconds & 255;
43148
+ if (typeof crypto !== "undefined" && crypto.getRandomValues) {
43149
+ crypto.getRandomValues(payload.subarray(4));
43150
+ } else {
43151
+ for (let i = 4; i < 20; i++) {
43152
+ payload[i] = Math.floor(Math.random() * 256);
43153
+ }
43154
+ }
43155
+ let value = 0n;
43156
+ for (const byte of payload) {
43157
+ value = value << 8n | BigInt(byte);
43158
+ }
43159
+ let encoded = "";
43160
+ while (value > 0n) {
43161
+ encoded = BASE62[Number(value % 62n)] + encoded;
43162
+ value = value / 62n;
43163
+ }
43164
+ return encoded.padStart(27, "0");
43165
+ }
43166
+ function generatePrefixedKSUID(prefix) {
43167
+ return `${prefix}_${generateKSUID()}`;
43168
+ }
43133
43169
  var API_BASE_URL = (() => {
43134
43170
  try {
43135
43171
  return process.env.NEXT_PUBLIC_API_BASE_URL || "https://api.unifold.io";
@@ -43432,9 +43468,7 @@ function getOnrampSessionStartUrl(request, publishableKey) {
43432
43468
  if (request.subdivision_code) {
43433
43469
  params.append("subdivision_code", request.subdivision_code);
43434
43470
  }
43435
- if (request.external_id) {
43436
- params.append("external_id", request.external_id);
43437
- }
43471
+ params.append("external_id", request.external_id ?? generatePrefixedKSUID("ors"));
43438
43472
  if (request.email) {
43439
43473
  params.append("email", request.email);
43440
43474
  }
@@ -43545,6 +43579,40 @@ async function getAddressBalances(address, chainType, publishableKey) {
43545
43579
  const data = await response.json();
43546
43580
  return data;
43547
43581
  }
43582
+ async function getExternalWallets(publishableKey) {
43583
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43584
+ validatePublishableKey(pk);
43585
+ const response = await fetch(`${API_BASE_URL}/v1/public/external_wallets`, {
43586
+ method: "GET",
43587
+ headers: {
43588
+ accept: "application/json",
43589
+ "x-publishable-key": pk
43590
+ }
43591
+ });
43592
+ if (!response.ok) {
43593
+ throw new Error(`Failed to fetch external wallets: ${response.statusText}`);
43594
+ }
43595
+ const data = await response.json();
43596
+ return data;
43597
+ }
43598
+ async function getWalletMobileDeepLink(wallet, depositAddresses, publishableKey) {
43599
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43600
+ validatePublishableKey(pk);
43601
+ const response = await fetch(`${API_BASE_URL}/v1/public/external_wallets/mobile_deeplink`, {
43602
+ method: "POST",
43603
+ headers: {
43604
+ "Content-Type": "application/json",
43605
+ accept: "application/json",
43606
+ "x-publishable-key": pk
43607
+ },
43608
+ body: JSON.stringify({ wallet, deposit_addresses: depositAddresses })
43609
+ });
43610
+ if (!response.ok) {
43611
+ throw new Error(`Failed to generate wallet deep link: ${response.statusText}`);
43612
+ }
43613
+ const data = await response.json();
43614
+ return data;
43615
+ }
43548
43616
  async function getAddressBalance(address, chainType, chainId, tokenAddress, publishableKey) {
43549
43617
  const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43550
43618
  validatePublishableKey(pk);
@@ -43649,9 +43717,7 @@ function getExchangeSessionStartUrl(request, publishableKey) {
43649
43717
  if (request.source_amount) {
43650
43718
  params.append("source_amount", request.source_amount);
43651
43719
  }
43652
- if (request.external_id) {
43653
- params.append("external_id", request.external_id);
43654
- }
43720
+ params.append("external_id", request.external_id ?? generatePrefixedKSUID("exc"));
43655
43721
  return `${API_BASE_URL}/v1/public/onramps/exchanges/sessions/start?${params.toString()}`;
43656
43722
  }
43657
43723
  async function getIntegrationExchanges(publishableKey) {
@@ -43985,40 +44051,6 @@ async function getCashAppSessionStatus(externalId, publishableKey) {
43985
44051
  }
43986
44052
  return response.json();
43987
44053
  }
43988
- function formatStablecoinAmount(baseUnits, decimals) {
43989
- const raw = Number(baseUnits) / 10 ** decimals;
43990
- const floored = Math.floor(raw * 100) / 100;
43991
- const ceiled = raw > floored ? floored + 0.01 : raw;
43992
- return ceiled.toFixed(2);
43993
- }
43994
- function generatePrefixedKSUID(prefix) {
43995
- const BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
43996
- const KSUID_EPOCH = 14e8;
43997
- const timestampSeconds = Math.floor(Date.now() / 1e3) - KSUID_EPOCH;
43998
- const payload = new Uint8Array(20);
43999
- payload[0] = timestampSeconds >>> 24 & 255;
44000
- payload[1] = timestampSeconds >>> 16 & 255;
44001
- payload[2] = timestampSeconds >>> 8 & 255;
44002
- payload[3] = timestampSeconds & 255;
44003
- if (typeof crypto !== "undefined" && crypto.getRandomValues) {
44004
- crypto.getRandomValues(payload.subarray(4));
44005
- } else {
44006
- for (let i = 4; i < 20; i++) {
44007
- payload[i] = Math.floor(Math.random() * 256);
44008
- }
44009
- }
44010
- let value = 0n;
44011
- for (const byte of payload) {
44012
- value = value << 8n | BigInt(byte);
44013
- }
44014
- let encoded = "";
44015
- while (value > 0n) {
44016
- encoded = BASE62[Number(value % 62n)] + encoded;
44017
- value = value / 62n;
44018
- }
44019
- encoded = encoded.padStart(27, "0");
44020
- return `${prefix}_${encoded}`;
44021
- }
44022
44054
  var DepositEventType = /* @__PURE__ */ ((DepositEventType2) => {
44023
44055
  DepositEventType2["ONRAMP_SESSION_CREATED"] = "onramp_session.created";
44024
44056
  return DepositEventType2;
@@ -50118,8 +50150,32 @@ var Separator = SelectSeparator;
50118
50150
  function cn(...inputs) {
50119
50151
  return twMerge(clsx(inputs));
50120
50152
  }
50121
- var WALLET_CHAIN_TYPE_STORAGE_KEY = "unifold_last_wallet_type";
50153
+ var WALLET_STATE_STORAGE_KEY = "unifold_wallet_state";
50154
+ var LEGACY_WALLET_KEYS = [
50155
+ "unifold_last_wallet_type",
50156
+ "unifold_last_connected_wallet"
50157
+ ];
50122
50158
  var WALLET_USER_DISCONNECTED_KEY = "unifold_wallet_user_disconnected";
50159
+ var SOLANA_WALLET_TYPES = /* @__PURE__ */ new Set([
50160
+ "phantom-solana",
50161
+ "solflare",
50162
+ "backpack",
50163
+ "glow"
50164
+ ]);
50165
+ var ETHEREUM_WALLET_TYPES = /* @__PURE__ */ new Set([
50166
+ "metamask",
50167
+ "phantom-ethereum",
50168
+ "coinbase",
50169
+ "trust",
50170
+ "rainbow",
50171
+ "rabby",
50172
+ "okx"
50173
+ ]);
50174
+ function walletTypeToChain(t12) {
50175
+ if (SOLANA_WALLET_TYPES.has(t12)) return "solana";
50176
+ if (ETHEREUM_WALLET_TYPES.has(t12)) return "ethereum";
50177
+ return void 0;
50178
+ }
50123
50179
  function getUserDisconnectedWallet() {
50124
50180
  if (typeof window === "undefined") return false;
50125
50181
  try {
@@ -50139,26 +50195,35 @@ function setUserDisconnectedWallet(disconnected) {
50139
50195
  } catch {
50140
50196
  }
50141
50197
  }
50142
- function getStoredWalletChainType() {
50198
+ function getStoredWalletState() {
50143
50199
  if (typeof window === "undefined") return void 0;
50144
50200
  try {
50145
- const stored = localStorage.getItem(WALLET_CHAIN_TYPE_STORAGE_KEY);
50146
- if (stored === "ethereum" || stored === "solana") return stored;
50201
+ const raw = localStorage.getItem(WALLET_STATE_STORAGE_KEY);
50202
+ if (!raw) return void 0;
50203
+ const chainType = walletTypeToChain(raw);
50204
+ if (!chainType) {
50205
+ localStorage.removeItem(WALLET_STATE_STORAGE_KEY);
50206
+ return void 0;
50207
+ }
50208
+ return { walletType: raw, chainType };
50147
50209
  } catch {
50210
+ return void 0;
50148
50211
  }
50149
- return void 0;
50150
50212
  }
50151
- function setStoredWalletChainType(chainType) {
50213
+ function setStoredWalletState(walletType) {
50152
50214
  if (typeof window === "undefined") return;
50215
+ if (!walletTypeToChain(walletType)) return;
50153
50216
  try {
50154
- localStorage.setItem(WALLET_CHAIN_TYPE_STORAGE_KEY, chainType);
50217
+ localStorage.setItem(WALLET_STATE_STORAGE_KEY, walletType);
50218
+ for (const key of LEGACY_WALLET_KEYS) localStorage.removeItem(key);
50155
50219
  } catch {
50156
50220
  }
50157
50221
  }
50158
- function clearStoredWalletChainType() {
50222
+ function clearStoredWalletState() {
50159
50223
  if (typeof window === "undefined") return;
50160
50224
  try {
50161
- localStorage.removeItem(WALLET_CHAIN_TYPE_STORAGE_KEY);
50225
+ localStorage.removeItem(WALLET_STATE_STORAGE_KEY);
50226
+ for (const key of LEGACY_WALLET_KEYS) localStorage.removeItem(key);
50162
50227
  } catch {
50163
50228
  }
50164
50229
  }
@@ -50518,6 +50583,36 @@ function ThemeProvider({
50518
50583
  );
50519
50584
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ThemeContext.Provider, { value: contextValue, children });
50520
50585
  }
50586
+ function AccentColorOverride({
50587
+ accentColor,
50588
+ accentForeground,
50589
+ children
50590
+ }) {
50591
+ const parent = useTheme();
50592
+ const value = React37.useMemo(() => {
50593
+ if (!accentColor) return parent;
50594
+ const foreground = accentForeground ?? parent.colors.primaryForeground;
50595
+ const nextColors = {
50596
+ ...parent.colors,
50597
+ primary: accentColor,
50598
+ primaryForeground: foreground
50599
+ };
50600
+ const nextComponents = {
50601
+ ...parent.components,
50602
+ button: {
50603
+ ...parent.components.button,
50604
+ primaryBackground: accentColor,
50605
+ primaryText: foreground
50606
+ },
50607
+ card: {
50608
+ ...parent.components.card,
50609
+ iconBackgroundColor: `${accentColor}26`
50610
+ }
50611
+ };
50612
+ return { ...parent, colors: nextColors, components: nextComponents };
50613
+ }, [parent, accentColor, accentForeground]);
50614
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ThemeContext.Provider, { value, children });
50615
+ }
50521
50616
  function useTheme() {
50522
50617
  const context = React37.useContext(ThemeContext);
50523
50618
  if (!context) {
@@ -50721,6 +50816,60 @@ function useDepositAddress(params) {
50721
50816
  // 1s, 2s, 4s (max 10s)
50722
50817
  });
50723
50818
  }
50819
+ var normalize = (value) => value?.toLowerCase();
50820
+ function sourceTokenMatchesDefaultSource(token, defaultSource) {
50821
+ if (!token || !defaultSource.defaultSourceChainType || !defaultSource.defaultSourceChainId) {
50822
+ return false;
50823
+ }
50824
+ if (token.chain_type !== defaultSource.defaultSourceChainType || token.chain_id !== defaultSource.defaultSourceChainId) {
50825
+ return false;
50826
+ }
50827
+ if (defaultSource.defaultSourceTokenAddress && normalize(token.token_address) === normalize(defaultSource.defaultSourceTokenAddress)) {
50828
+ return true;
50829
+ }
50830
+ if (defaultSource.defaultSourceTokenAddress) {
50831
+ return false;
50832
+ }
50833
+ return !!defaultSource.defaultSourceSymbol && normalize(token.symbol) === normalize(defaultSource.defaultSourceSymbol);
50834
+ }
50835
+ function isDefaultSourceBalance(balance, defaultSource) {
50836
+ return isBalanceEligible(balance) && sourceTokenMatchesDefaultSource(getTokenFromBalance(balance), defaultSource);
50837
+ }
50838
+ function compareBalancesWithDefaultSource(a, b, defaultSource) {
50839
+ const aDefault = isDefaultSourceBalance(a, defaultSource);
50840
+ const bDefault = isDefaultSourceBalance(b, defaultSource);
50841
+ if (aDefault && !bDefault) return -1;
50842
+ if (!aDefault && bDefault) return 1;
50843
+ const aEligible = isBalanceEligible(a);
50844
+ const bEligible = isBalanceEligible(b);
50845
+ if (aEligible && !bEligible) return -1;
50846
+ if (!aEligible && bEligible) return 1;
50847
+ return 0;
50848
+ }
50849
+ function resolveDefaultSourceSymbol(supportedTokens, defaultSource) {
50850
+ if (!supportedTokens?.length || !defaultSource.defaultSourceChainType || !defaultSource.defaultSourceChainId) {
50851
+ return null;
50852
+ }
50853
+ if (defaultSource.defaultSourceTokenAddress) {
50854
+ for (const token of supportedTokens) {
50855
+ const matchingChain = token.chains.find(
50856
+ (chain) => chain.chain_type === defaultSource.defaultSourceChainType && chain.chain_id === defaultSource.defaultSourceChainId && normalize(chain.token_address) === normalize(defaultSource.defaultSourceTokenAddress)
50857
+ );
50858
+ if (matchingChain) return token.symbol;
50859
+ }
50860
+ }
50861
+ if (!defaultSource.defaultSourceSymbol) return null;
50862
+ for (const token of supportedTokens) {
50863
+ if (normalize(token.symbol) !== normalize(defaultSource.defaultSourceSymbol)) {
50864
+ continue;
50865
+ }
50866
+ const matchingChain = token.chains.find(
50867
+ (chain) => chain.chain_type === defaultSource.defaultSourceChainType && chain.chain_id === defaultSource.defaultSourceChainId
50868
+ );
50869
+ if (matchingChain) return token.symbol;
50870
+ }
50871
+ return null;
50872
+ }
50724
50873
  function formatUsdFromBalancePercent(maxUsdAmount, percent) {
50725
50874
  if (maxUsdAmount <= 0 || percent < 0) return "";
50726
50875
  const raw = maxUsdAmount * percent / 100;
@@ -51515,6 +51664,7 @@ function useDepositPolling({
51515
51664
  clientSecret,
51516
51665
  depositConfirmationMode = "auto_ui",
51517
51666
  depositWalletId,
51667
+ depositWalletIds,
51518
51668
  enabled = true,
51519
51669
  immediateDirectPolling = false,
51520
51670
  onDepositSuccess,
@@ -51660,21 +51810,25 @@ function useDepositPolling({
51660
51810
  setIsPolling(false);
51661
51811
  };
51662
51812
  }, [userId, publishableKey, clientSecret, enabled]);
51813
+ const pollWalletIdsKey = depositWalletIds && depositWalletIds.length > 0 ? Array.from(new Set(depositWalletIds.filter(Boolean))).join(",") : depositWalletId || "";
51663
51814
  (0, import_react10.useEffect)(() => {
51664
- if (!pollingEnabled || !depositWalletId) return;
51815
+ if (!pollingEnabled || !pollWalletIdsKey) return;
51816
+ const ids = pollWalletIdsKey.split(",").filter(Boolean);
51665
51817
  const triggerPoll = async () => {
51666
- try {
51667
- await pollDirectExecutions(
51668
- { deposit_wallet_id: depositWalletId },
51669
- publishableKey
51670
- );
51671
- } catch {
51672
- }
51818
+ await Promise.all(
51819
+ ids.map(
51820
+ (id) => pollDirectExecutions(
51821
+ { deposit_wallet_id: id },
51822
+ publishableKey
51823
+ ).catch(() => {
51824
+ })
51825
+ )
51826
+ );
51673
51827
  };
51674
51828
  triggerPoll();
51675
51829
  const interval = setInterval(triggerPoll, POLL_ENDPOINT_INTERVAL_MS);
51676
51830
  return () => clearInterval(interval);
51677
- }, [pollingEnabled, depositWalletId, publishableKey]);
51831
+ }, [pollingEnabled, pollWalletIdsKey, publishableKey]);
51678
51832
  const handleIveDeposited = () => {
51679
51833
  setPollingEnabled(true);
51680
51834
  setShowWaitingUi(true);
@@ -52863,6 +53017,7 @@ function BuyWithCard({
52863
53017
  if (!selectedProvider) return "0.000000";
52864
53018
  return selectedProvider.destination_amount.toFixed(6);
52865
53019
  };
53020
+ const canOpenProviderSelector = !quotesLoading && quotes.length > 1;
52866
53021
  const selectedCurrencyData = fiatCurrencies.find(
52867
53022
  (c) => c.currency_code.toLowerCase() === currency.toLowerCase()
52868
53023
  );
@@ -53048,9 +53203,12 @@ function BuyWithCard({
53048
53203
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
53049
53204
  "button",
53050
53205
  {
53051
- onClick: () => handleViewChange("quotes"),
53206
+ onClick: () => {
53207
+ if (canOpenProviderSelector) handleViewChange("quotes");
53208
+ },
53052
53209
  disabled: quotesLoading || quotes.length === 0,
53053
- 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",
53210
+ "aria-disabled": !canOpenProviderSelector,
53211
+ 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"}`,
53054
53212
  style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
53055
53213
  children: quotesLoading ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "uf-text-left uf-w-full uf-animate-pulse", children: [
53056
53214
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
@@ -53077,7 +53235,7 @@ function BuyWithCard({
53077
53235
  )
53078
53236
  ] })
53079
53237
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "uf-w-full uf-text-left", children: [
53080
- isAutoSelected && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
53238
+ isAutoSelected && canOpenProviderSelector && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
53081
53239
  "div",
53082
53240
  {
53083
53241
  className: "uf-text-xs uf-font-normal uf-mb-2",
@@ -53113,7 +53271,7 @@ function BuyWithCard({
53113
53271
  ),
53114
53272
  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" }) })
53115
53273
  ] }),
53116
- quotes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
53274
+ canOpenProviderSelector && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
53117
53275
  ChevronRight,
53118
53276
  {
53119
53277
  className: "uf-w-4 uf-h-4 group-hover:uf-text-foreground uf-transition-colors uf-flex-shrink-0",
@@ -55234,70 +55392,106 @@ function identifyEthWallet(provider, hint) {
55234
55392
  }
55235
55393
  return { type: "metamask", name: "Wallet", icon: "metamask" };
55236
55394
  }
55395
+ var EIP6963_ID_TO_WALLET_TYPE = {
55396
+ metamask: "metamask",
55397
+ phantom: "phantom-ethereum",
55398
+ coinbase: "coinbase",
55399
+ trust: "trust",
55400
+ rainbow: "rainbow",
55401
+ rabby: "rabby",
55402
+ okx: "okx"
55403
+ };
55404
+ function inferEthWalletType(provider, walletId) {
55405
+ if (EIP6963_ID_TO_WALLET_TYPE[walletId]) return EIP6963_ID_TO_WALLET_TYPE[walletId];
55406
+ const any = provider;
55407
+ if (provider.isPhantom) return "phantom-ethereum";
55408
+ if (any.isCoinbaseWallet) return "coinbase";
55409
+ if (any.isRabby) return "rabby";
55410
+ if (any.isTrust) return "trust";
55411
+ if (any.isRainbow) return "rainbow";
55412
+ if (any.isOkxWallet) return "okx";
55413
+ if (provider.isMetaMask && !provider.isPhantom) return "metamask";
55414
+ return null;
55415
+ }
55416
+ function solanaCandidate(provider, type, name, icon) {
55417
+ return {
55418
+ walletType: type,
55419
+ detect: async () => {
55420
+ if (!provider) return null;
55421
+ if (provider.isConnected && provider.publicKey) {
55422
+ return { type, name, address: provider.publicKey.toString(), icon };
55423
+ }
55424
+ try {
55425
+ const resp = await provider.connect({ onlyIfTrusted: true });
55426
+ if (resp.publicKey) {
55427
+ return { type, name, address: resp.publicKey.toString(), icon };
55428
+ }
55429
+ } catch {
55430
+ }
55431
+ return null;
55432
+ }
55433
+ };
55434
+ }
55435
+ function ethereumCandidate(provider, walletId) {
55436
+ return {
55437
+ walletType: inferEthWalletType(provider, walletId),
55438
+ detect: async () => {
55439
+ try {
55440
+ const accounts = await provider.request({ method: "eth_accounts" });
55441
+ if (!accounts?.length) return null;
55442
+ const resolved = identifyEthWallet(provider, walletId);
55443
+ return { ...resolved, address: accounts[0] };
55444
+ } catch {
55445
+ return null;
55446
+ }
55447
+ }
55448
+ };
55449
+ }
55450
+ function buildCandidates(win, chainType) {
55451
+ const candidates = [];
55452
+ if (!chainType || chainType === "solana") {
55453
+ candidates.push(
55454
+ solanaCandidate(win.phantom?.solana, "phantom-solana", "Phantom", "phantom"),
55455
+ solanaCandidate(win.solflare, "solflare", "Solflare", "solflare"),
55456
+ solanaCandidate(win.backpack, "backpack", "Backpack", "backpack"),
55457
+ solanaCandidate(win.glow, "glow", "Glow", "glow")
55458
+ );
55459
+ }
55460
+ if (!chainType || chainType === "ethereum") {
55461
+ const seen = /* @__PURE__ */ new Set();
55462
+ const addEth = (provider, walletId) => {
55463
+ if (!provider || seen.has(provider)) return;
55464
+ seen.add(provider);
55465
+ candidates.push(ethereumCandidate(provider, walletId));
55466
+ };
55467
+ for (const { provider, walletId } of getEip6963Providers()) {
55468
+ addEth(
55469
+ provider,
55470
+ walletId === "unknown" ? "default" : walletId
55471
+ );
55472
+ }
55473
+ addEth(win.phantom?.ethereum, "phantom");
55474
+ addEth(win.coinbaseWalletExtension, "coinbase");
55475
+ addEth(win.okxwallet, "okx");
55476
+ addEth(win.trustwallet?.ethereum, "trust");
55477
+ addEth(win.ethereum, "default");
55478
+ }
55479
+ return candidates;
55480
+ }
55237
55481
  async function detectConnectedBrowserWallet(chainType) {
55238
55482
  if (typeof window === "undefined") return null;
55239
55483
  if (getUserDisconnectedWallet()) return null;
55240
55484
  try {
55241
55485
  const win = window;
55242
- if (!chainType || chainType === "solana") {
55243
- const trySilentSolana = async (provider, type, name, icon) => {
55244
- if (!provider) return null;
55245
- if (provider.isConnected && provider.publicKey) {
55246
- return { type, name, address: provider.publicKey.toString(), icon };
55247
- }
55248
- try {
55249
- const resp = await provider.connect({ onlyIfTrusted: true });
55250
- if (resp.publicKey) {
55251
- return { type, name, address: resp.publicKey.toString(), icon };
55252
- }
55253
- } catch {
55254
- }
55255
- return null;
55256
- };
55257
- const solanaCandidates = [
55258
- [win.phantom?.solana, "phantom-solana", "Phantom", "phantom"],
55259
- [win.solflare, "solflare", "Solflare", "solflare"],
55260
- [win.backpack, "backpack", "Backpack", "backpack"],
55261
- [win.glow, "glow", "Glow", "glow"]
55262
- ];
55263
- for (const [provider, type, name, icon] of solanaCandidates) {
55264
- const found = await trySilentSolana(provider, type, name, icon);
55265
- if (found) return found;
55266
- }
55267
- }
55268
- if (!chainType || chainType === "ethereum") {
55269
- const allProviders = [];
55270
- const eip6963 = getEip6963Providers();
55271
- for (const { provider, walletId } of eip6963) {
55272
- allProviders.push({
55273
- provider,
55274
- walletId: walletId === "unknown" ? "default" : walletId
55275
- });
55276
- }
55277
- if (allProviders.length === 0) {
55278
- if (win.phantom?.ethereum) {
55279
- allProviders.push({ provider: win.phantom.ethereum, walletId: "phantom" });
55280
- }
55281
- if (win.okxwallet) {
55282
- allProviders.push({ provider: win.okxwallet, walletId: "okx" });
55283
- }
55284
- if (win.coinbaseWalletExtension) {
55285
- allProviders.push({ provider: win.coinbaseWalletExtension, walletId: "coinbase" });
55286
- }
55287
- if (win.ethereum && !allProviders.some((p) => p.provider === win.ethereum)) {
55288
- allProviders.push({ provider: win.ethereum, walletId: "default" });
55289
- }
55290
- }
55291
- for (const { provider, walletId } of allProviders) {
55292
- if (!provider) continue;
55293
- try {
55294
- const accounts = await provider.request({ method: "eth_accounts" });
55295
- if (!accounts || accounts.length === 0) continue;
55296
- const resolved = identifyEthWallet(provider, walletId);
55297
- return { ...resolved, address: accounts[0] };
55298
- } catch {
55299
- }
55300
- }
55486
+ const candidates = buildCandidates(win, chainType);
55487
+ const preferred = getStoredWalletState();
55488
+ if (preferred && (!chainType || preferred.chainType === chainType)) {
55489
+ const idx = candidates.findIndex((c) => c.walletType === preferred.walletType);
55490
+ if (idx > 0) candidates.unshift(...candidates.splice(idx, 1));
55491
+ }
55492
+ for (const c of candidates) {
55493
+ const found = await c.detect();
55494
+ if (found) return found;
55301
55495
  }
55302
55496
  } catch (error) {
55303
55497
  console.error("[detectConnectedBrowserWallet] detection error:", error);
@@ -57443,6 +57637,7 @@ function BrowserWalletButton({
57443
57637
  if (solanaProvider?.isPhantom) {
57444
57638
  const { publicKey } = await solanaProvider.connect();
57445
57639
  setUserDisconnectedWallet(false);
57640
+ setStoredWalletState("phantom-solana");
57446
57641
  setWallet({
57447
57642
  type: "phantom-solana",
57448
57643
  name: "Phantom",
@@ -57462,8 +57657,10 @@ function BrowserWalletButton({
57462
57657
  if (accounts && accounts.length > 0) {
57463
57658
  setUserDisconnectedWallet(false);
57464
57659
  const isPhantom = ethProvider.isPhantom;
57660
+ const walletType = isPhantom ? "phantom-ethereum" : "metamask";
57661
+ setStoredWalletState(walletType);
57465
57662
  setWallet({
57466
- type: isPhantom ? "phantom-ethereum" : "metamask",
57663
+ type: walletType,
57467
57664
  name: isPhantom ? "Phantom" : "MetaMask",
57468
57665
  address: accounts[0],
57469
57666
  icon: isPhantom ? "phantom" : "metamask"
@@ -57773,7 +57970,11 @@ function CoinbaseConnect({
57773
57970
  onDisconnect,
57774
57971
  skipToHoldings,
57775
57972
  canGoBack = true,
57776
- onExecutionsChange
57973
+ onExecutionsChange,
57974
+ defaultSourceChainType,
57975
+ defaultSourceChainId,
57976
+ defaultSourceTokenAddress,
57977
+ defaultSourceSymbol
57777
57978
  }) {
57778
57979
  const { colors: colors2, fonts, components } = useTheme();
57779
57980
  const { projectConfig } = useProjectConfig({ publishableKey });
@@ -57838,6 +58039,21 @@ function CoinbaseConnect({
57838
58039
  params: defaultTokenParams,
57839
58040
  publishableKey
57840
58041
  });
58042
+ const defaultSourceCurrency = (0, import_react18.useMemo)(
58043
+ () => resolveDefaultSourceSymbol(supportedTokensData?.data, {
58044
+ defaultSourceChainType,
58045
+ defaultSourceChainId,
58046
+ defaultSourceTokenAddress,
58047
+ defaultSourceSymbol
58048
+ })?.toLowerCase() ?? null,
58049
+ [
58050
+ supportedTokensData,
58051
+ defaultSourceChainType,
58052
+ defaultSourceChainId,
58053
+ defaultSourceTokenAddress,
58054
+ defaultSourceSymbol
58055
+ ]
58056
+ );
57841
58057
  const sortedHoldings = (0, import_react18.useMemo)(() => {
57842
58058
  const supported = [];
57843
58059
  const unsupported = [];
@@ -57847,13 +58063,42 @@ function CoinbaseConnect({
57847
58063
  if (isSupported) supported.push(account);
57848
58064
  else unsupported.push(account);
57849
58065
  });
58066
+ if (defaultSourceCurrency) {
58067
+ const defaultIndex = supported.findIndex(
58068
+ (account) => account.currency.toLowerCase() === defaultSourceCurrency
58069
+ );
58070
+ if (defaultIndex > 0) {
58071
+ const [defaultHolding] = supported.splice(defaultIndex, 1);
58072
+ supported.unshift(defaultHolding);
58073
+ }
58074
+ }
57850
58075
  return [...supported, ...unsupported];
57851
- }, [holdings, supportedSymbols, exchangeSupportedCurrencies]);
58076
+ }, [
58077
+ holdings,
58078
+ supportedSymbols,
58079
+ exchangeSupportedCurrencies,
58080
+ defaultSourceCurrency
58081
+ ]);
57852
58082
  const selectedHoldingIsSupported = (0, import_react18.useMemo)(() => {
57853
58083
  if (!selectedHolding) return false;
57854
58084
  const currencyLower = selectedHolding.currency.toLowerCase();
57855
58085
  return (supportedSymbols.size === 0 || supportedSymbols.has(currencyLower)) && (exchangeSupportedCurrencies.size === 0 || exchangeSupportedCurrencies.has(currencyLower));
57856
58086
  }, [selectedHolding, supportedSymbols, exchangeSupportedCurrencies]);
58087
+ (0, import_react18.useEffect)(() => {
58088
+ if (!defaultSourceCurrency || selectedHolding) return;
58089
+ const defaultHolding = sortedHoldings.find((account) => {
58090
+ const currencyLower = account.currency.toLowerCase();
58091
+ return currencyLower === defaultSourceCurrency && (supportedSymbols.size === 0 || supportedSymbols.has(currencyLower)) && (exchangeSupportedCurrencies.size === 0 || exchangeSupportedCurrencies.has(currencyLower));
58092
+ });
58093
+ if (!defaultHolding) return;
58094
+ setSelectedHolding(defaultHolding);
58095
+ }, [
58096
+ defaultSourceCurrency,
58097
+ selectedHolding,
58098
+ sortedHoldings,
58099
+ supportedSymbols,
58100
+ exchangeSupportedCurrencies
58101
+ ]);
57857
58102
  const exchangeName = selectedExchange?.service_provider_display_name || "Exchange";
57858
58103
  const {
57859
58104
  executions: depositExecutions,
@@ -62002,6 +62247,60 @@ function useDepositQuote(params) {
62002
62247
  retryDelay: (attempt) => Math.min(1e3 * 2 ** attempt, 5e3)
62003
62248
  });
62004
62249
  }
62250
+ function useExternalWallets({
62251
+ publishableKey,
62252
+ enabled = true
62253
+ }) {
62254
+ const { data: wallets = [], isLoading } = useQuery({
62255
+ queryKey: ["unifold", "external-wallets", publishableKey],
62256
+ queryFn: () => getExternalWallets(publishableKey).then((res) => res.data),
62257
+ enabled: enabled && !!publishableKey,
62258
+ staleTime: 1e3 * 60 * 30,
62259
+ refetchOnMount: false,
62260
+ refetchOnWindowFocus: false
62261
+ });
62262
+ return { wallets, isLoading };
62263
+ }
62264
+ var WALLET_BRAND_COLORS = {
62265
+ phantom: "#AB9FF2",
62266
+ metamask: "#F6851B",
62267
+ coinbase: "#0052FF",
62268
+ trust: "#3375BB",
62269
+ rainbow: "#5B6CFF",
62270
+ rabby: "#7084FF",
62271
+ okx: "#000000"
62272
+ };
62273
+ function normalizeWalletId(type) {
62274
+ return type.replace(/-(ethereum|solana)$/i, "").toLowerCase();
62275
+ }
62276
+ function getWalletBrandColor(type, mode = "dark") {
62277
+ if (!type) return void 0;
62278
+ const id = normalizeWalletId(type);
62279
+ const color = WALLET_BRAND_COLORS[id];
62280
+ if (!color) return void 0;
62281
+ if (id === "okx") return mode === "dark" ? "#FFFFFF" : "#111111";
62282
+ return color;
62283
+ }
62284
+ function getContrastingTextColor(hex) {
62285
+ const c = hex.replace("#", "");
62286
+ if (c.length !== 6) return "#FFFFFF";
62287
+ const r2 = parseInt(c.slice(0, 2), 16);
62288
+ const g = parseInt(c.slice(2, 4), 16);
62289
+ const b = parseInt(c.slice(4, 6), 16);
62290
+ const luminance = (0.299 * r2 + 0.587 * g + 0.114 * b) / 255;
62291
+ return luminance > 0.6 ? "#13111C" : "#FFFFFF";
62292
+ }
62293
+ function isMobileDevice() {
62294
+ if (typeof navigator === "undefined") return false;
62295
+ return /android|iphone|ipad|ipod|mobile/i.test(navigator.userAgent);
62296
+ }
62297
+ function getMobilePlatform() {
62298
+ if (typeof navigator === "undefined") return null;
62299
+ const ua = navigator.userAgent;
62300
+ if (/iphone|ipad|ipod/i.test(ua)) return "ios";
62301
+ if (/android/i.test(ua)) return "android";
62302
+ return null;
62303
+ }
62005
62304
  var WALLET_ICONS = {
62006
62305
  metamask: MetamaskIcon,
62007
62306
  phantom: PhantomIcon,
@@ -63007,18 +63306,46 @@ var WALLET_ICONS3 = {
63007
63306
  backpack: BackpackIcon,
63008
63307
  glow: GlowIcon
63009
63308
  };
63010
- var WALLET_DEFINITIONS = [
63011
- { id: "phantom", name: "Phantom", networks: ["ethereum", "solana"], installUrl: "https://phantom.app/" },
63012
- { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum", "solana"], installUrl: "https://www.coinbase.com/wallet" },
63013
- { id: "trust", name: "Trust Wallet", networks: ["ethereum", "solana"], installUrl: "https://trustwallet.com/" },
63014
- { id: "metamask", name: "MetaMask", networks: ["ethereum"], installUrl: "https://metamask.io/download/" },
63015
- { id: "rainbow", name: "Rainbow", networks: ["ethereum"], installUrl: "https://rainbow.me/" },
63016
- { id: "rabby", name: "Rabby", networks: ["ethereum"], installUrl: "https://rabby.io/" },
63017
- { id: "okx", name: "OKX Wallet", networks: ["ethereum"], installUrl: "https://www.okx.com/web3" },
63018
- { id: "solflare", name: "Solflare", networks: ["solana"], installUrl: "https://solflare.com/" },
63019
- { id: "backpack", name: "Backpack", networks: ["solana"], installUrl: "https://backpack.app/" },
63020
- { id: "glow", name: "Glow", networks: ["solana"], installUrl: "https://glow.app/" }
63309
+ var FALLBACK_WALLET_DEFINITIONS = [
63310
+ { id: "phantom", name: "Phantom", networks: ["ethereum", "solana"], installUrl: "https://phantom.app/", supportsMobileBrowse: true },
63311
+ { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum", "solana"], installUrl: "https://www.coinbase.com/wallet", supportsMobileBrowse: true },
63312
+ { id: "trust", name: "Trust Wallet", networks: ["ethereum", "solana"], installUrl: "https://trustwallet.com/", supportsMobileBrowse: true },
63313
+ { id: "metamask", name: "MetaMask", networks: ["ethereum"], installUrl: "https://metamask.io/download/", supportsMobileBrowse: true },
63314
+ { id: "rainbow", name: "Rainbow", networks: ["ethereum"], installUrl: "https://rainbow.me/", supportsMobileBrowse: true },
63315
+ { id: "rabby", name: "Rabby", networks: ["ethereum"], installUrl: "https://apps.apple.com/app/rabby-wallet/id6450663781", supportsMobileBrowse: true },
63316
+ { id: "okx", name: "OKX Wallet", networks: ["ethereum"], installUrl: "https://www.okx.com/web3", supportsMobileBrowse: true, mobileBrowsePlatforms: ["ios"] }
63021
63317
  ];
63318
+ function getMobileInstallUrl(walletId, defaultUrl) {
63319
+ if (!isMobileDevice()) return defaultUrl;
63320
+ const ua = typeof navigator !== "undefined" ? navigator.userAgent : "";
63321
+ const isIOS = /iPhone|iPad|iPod/i.test(ua);
63322
+ const stores = {
63323
+ rabby: {
63324
+ ios: "https://apps.apple.com/app/rabby-wallet/id6450663781",
63325
+ android: "https://play.google.com/store/apps/details?id=com.debank.rabbymobile"
63326
+ },
63327
+ glow: {
63328
+ ios: "https://apps.apple.com/us/app/glow-solana-wallet/id1599584512",
63329
+ android: "https://play.google.com/store/apps/details?id=com.luma.wallet.prod"
63330
+ }
63331
+ };
63332
+ const entry = stores[walletId];
63333
+ if (!entry) return defaultUrl;
63334
+ return isIOS ? entry.ios : entry.android;
63335
+ }
63336
+ function normalizeTokenAddress(address) {
63337
+ const normalized = (address ?? "").toLowerCase();
63338
+ if (normalized === "" || normalized === "native" || normalized === "0x0000000000000000000000000000000000000000") {
63339
+ return "native";
63340
+ }
63341
+ return normalized;
63342
+ }
63343
+ function balancesRepresentSameToken(a, b) {
63344
+ const tokenA = getTokenFromBalance(a);
63345
+ const tokenB = getTokenFromBalance(b);
63346
+ if (!tokenA || !tokenB) return false;
63347
+ return tokenA.chain_type === tokenB.chain_type && tokenA.chain_id === tokenB.chain_id && normalizeTokenAddress(tokenA.token_address) === normalizeTokenAddress(tokenB.token_address);
63348
+ }
63022
63349
  function getSolanaProviders() {
63023
63350
  if (typeof window === "undefined") return {};
63024
63351
  const win = window;
@@ -63041,7 +63368,7 @@ function getLegacyEvmProviders() {
63041
63368
  okxEthereum: win.okxwallet
63042
63369
  };
63043
63370
  }
63044
- function detectAvailableWallets(filterChainType) {
63371
+ function detectAvailableWallets(definitions, filterChainType) {
63045
63372
  const solProviders = getSolanaProviders();
63046
63373
  const legacyEvm = getLegacyEvmProviders();
63047
63374
  const eip6963List = getEip6963Providers();
@@ -63067,7 +63394,7 @@ function detectAvailableWallets(filterChainType) {
63067
63394
  return false;
63068
63395
  }
63069
63396
  });
63070
- return WALLET_DEFINITIONS.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
63397
+ return definitions.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
63071
63398
  let isInstalled = false;
63072
63399
  const detectedNetworks = [];
63073
63400
  switch (wallet.id) {
@@ -63161,13 +63488,17 @@ function WalletConnect({
63161
63488
  checkoutRemainingBaseUnits,
63162
63489
  stablecoinParity = false,
63163
63490
  productType,
63491
+ defaultSourceChainType,
63492
+ defaultSourceChainId,
63493
+ defaultSourceTokenAddress,
63494
+ defaultSourceSymbol,
63164
63495
  onBack: parentOnBack,
63165
63496
  onClose,
63166
63497
  canGoBack = true,
63167
63498
  depositWalletsLoading = false,
63168
63499
  onExecutionsChange
63169
63500
  }) {
63170
- const { colors: colors2, fonts, components } = useTheme();
63501
+ const { colors: colors2, fonts, components, mode } = useTheme();
63171
63502
  const walletProvidedAtMount = React302.useRef(!!initialWalletInfo && !!initialDepositWallet);
63172
63503
  const [activeWalletInfo, setActiveWalletInfo] = React302.useState(initialWalletInfo ?? null);
63173
63504
  const [activeDepositWallet, setActiveDepositWallet] = React302.useState(initialDepositWallet ?? null);
@@ -63191,7 +63522,37 @@ function WalletConnect({
63191
63522
  setEip6963ProviderCount(providers.length);
63192
63523
  });
63193
63524
  }, []);
63194
- const availableWallets = React302.useMemo(() => detectAvailableWallets(), [eip6963ProviderCount]);
63525
+ const { wallets: backendWallets } = useExternalWallets({ publishableKey });
63526
+ const walletDefinitions = React302.useMemo(
63527
+ () => backendWallets.length > 0 ? backendWallets.map((w) => ({
63528
+ id: w.id,
63529
+ name: w.name,
63530
+ networks: w.chain_types,
63531
+ installUrl: w.install_url,
63532
+ supportsMobileBrowse: w.supports_mobile_browse,
63533
+ mobileBrowsePlatforms: w.mobile_browse_platforms ?? null
63534
+ })) : FALLBACK_WALLET_DEFINITIONS,
63535
+ [backendWallets]
63536
+ );
63537
+ const availableWallets = React302.useMemo(
63538
+ () => detectAvailableWallets(walletDefinitions),
63539
+ [walletDefinitions, eip6963ProviderCount]
63540
+ );
63541
+ const [isMobile, setIsMobile] = React302.useState(false);
63542
+ React302.useEffect(() => {
63543
+ setIsMobile(isMobileDevice());
63544
+ }, []);
63545
+ const mobileDepositAddresses = React302.useMemo(
63546
+ () => (depositWallets ?? []).map((w) => ({ chain_type: w.chain_type, address: w.address })),
63547
+ [depositWallets]
63548
+ );
63549
+ const mobileDepositWalletIds = React302.useMemo(
63550
+ () => (depositWallets ?? []).filter((w) => w.chain_type === "ethereum" || w.chain_type === "solana").map((w) => w.id),
63551
+ [depositWallets]
63552
+ );
63553
+ const [mobileRedirect, setMobileRedirect] = React302.useState(null);
63554
+ const [pendingMobileWallet, setPendingMobileWallet] = React302.useState(null);
63555
+ const [awaitingMobileDeposit, setAwaitingMobileDeposit] = React302.useState(false);
63195
63556
  React302.useEffect(() => {
63196
63557
  if (!standalone || autoResolved || detectingWallet) return;
63197
63558
  if (!detectedWallet) {
@@ -63250,10 +63611,37 @@ function WalletConnect({
63250
63611
  transform: isTransitioning ? "translateY(4px)" : "translateY(0)",
63251
63612
  transition: "opacity 150ms ease, transform 150ms ease"
63252
63613
  };
63253
- const handleWalletClick = (wallet) => {
63254
- if (!wallet.isInstalled) {
63255
- window.open(wallet.installUrl, "_blank", "noopener,noreferrer");
63256
- return;
63614
+ const openMobileWalletBrowse = async (wallet, depositAddresses) => {
63615
+ try {
63616
+ const res = await getWalletMobileDeepLink(
63617
+ wallet.id,
63618
+ depositAddresses,
63619
+ publishableKey
63620
+ );
63621
+ if (res.deeplink) {
63622
+ setMobileRedirect({ walletId: wallet.id, walletName: wallet.name, deeplink: res.deeplink });
63623
+ setAwaitingMobileDeposit(true);
63624
+ transitionTo("mobile_redirect");
63625
+ window.location.href = res.deeplink;
63626
+ return true;
63627
+ }
63628
+ } catch {
63629
+ }
63630
+ return false;
63631
+ };
63632
+ const handleWalletClick = async (wallet) => {
63633
+ if (!wallet.isInstalled) {
63634
+ const platform2 = getMobilePlatform();
63635
+ const platformAllowed = !wallet.mobileBrowsePlatforms || wallet.mobileBrowsePlatforms.includes(platform2 ?? "");
63636
+ if (isMobileDevice() && wallet.supportsMobileBrowse !== false && platformAllowed) {
63637
+ if (mobileDepositAddresses.length === 0) {
63638
+ setPendingMobileWallet(wallet);
63639
+ return;
63640
+ }
63641
+ if (await openMobileWalletBrowse(wallet, mobileDepositAddresses)) return;
63642
+ }
63643
+ window.open(getMobileInstallUrl(wallet.id, wallet.installUrl), "_blank", "noopener,noreferrer");
63644
+ return;
63257
63645
  }
63258
63646
  setSelectedWalletDef(wallet);
63259
63647
  setWalletError(null);
@@ -63268,6 +63656,27 @@ function WalletConnect({
63268
63656
  if (!selectedWalletDef) return;
63269
63657
  handleConnectWallet(selectedWalletDef, network);
63270
63658
  };
63659
+ React302.useEffect(() => {
63660
+ if (!pendingMobileWallet) return;
63661
+ if (mobileDepositAddresses.length > 0) {
63662
+ const wallet = pendingMobileWallet;
63663
+ setPendingMobileWallet(null);
63664
+ void (async () => {
63665
+ if (!await openMobileWalletBrowse(wallet, mobileDepositAddresses)) {
63666
+ window.open(getMobileInstallUrl(wallet.id, wallet.installUrl), "_blank", "noopener,noreferrer");
63667
+ }
63668
+ })();
63669
+ return;
63670
+ }
63671
+ const timeout = setTimeout(() => {
63672
+ setPendingMobileWallet((current) => {
63673
+ if (!current) return null;
63674
+ window.open(getMobileInstallUrl(current.id, current.installUrl), "_blank", "noopener,noreferrer");
63675
+ return null;
63676
+ });
63677
+ }, 8e3);
63678
+ return () => clearTimeout(timeout);
63679
+ }, [pendingMobileWallet, mobileDepositAddresses]);
63271
63680
  const handleConnectWallet = async (wallet, network) => {
63272
63681
  setConnectingNetwork(network);
63273
63682
  transitionTo("connecting");
@@ -63321,6 +63730,7 @@ function WalletConnect({
63321
63730
  metamask: "metamask"
63322
63731
  };
63323
63732
  const walletType = walletIdToType[wallet.id] || "metamask";
63733
+ setStoredWalletState(walletType);
63324
63734
  connectedInfo = { type: walletType, name: wallet.name, address: accounts[0], icon: wallet.id };
63325
63735
  } else {
63326
63736
  const solProviders = getSolanaProviders();
@@ -63349,6 +63759,7 @@ function WalletConnect({
63349
63759
  const response = await provider.connect();
63350
63760
  setUserDisconnectedWallet(false);
63351
63761
  const walletType = wallet.id === "solflare" ? "solflare" : wallet.id === "backpack" ? "backpack" : wallet.id === "glow" ? "glow" : "phantom-solana";
63762
+ setStoredWalletState(walletType);
63352
63763
  connectedInfo = { type: walletType, name: wallet.name, address: response.publicKey.toString(), icon: wallet.id };
63353
63764
  }
63354
63765
  const walletChainType = network === "solana" ? "solana" : "ethereum";
@@ -63410,14 +63821,32 @@ function WalletConnect({
63410
63821
  userId,
63411
63822
  publishableKey,
63412
63823
  clientSecret,
63824
+ // In-tab flow: poll the single connected deposit wallet.
63413
63825
  depositWalletId: activeDepositWallet?.id ?? "",
63414
- enabled: hasSignedTransaction && !!activeDepositWallet,
63826
+ // Mobile redirect flow: the deposit chain isn't known up front, so /poll every
63827
+ // chain's deposit wallet. Detection still happens via the single /query by
63828
+ // external_user_id, which already spans all chains.
63829
+ depositWalletIds: awaitingMobileDeposit ? mobileDepositWalletIds : void 0,
63830
+ enabled: hasSignedTransaction && !!activeDepositWallet || awaitingMobileDeposit,
63415
63831
  onDepositSuccess,
63416
63832
  onDepositError
63417
63833
  });
63418
63834
  React302.useEffect(() => {
63419
63835
  onExecutionsChange?.(depositExecutions);
63420
63836
  }, [depositExecutions, onExecutionsChange]);
63837
+ const latestDepositExecution = React302.useMemo(() => {
63838
+ if (depositExecutions.length === 0) return null;
63839
+ return [...depositExecutions].sort((a, b) => {
63840
+ const ta = a.created_at ? new Date(a.created_at).getTime() : 0;
63841
+ const tb = b.created_at ? new Date(b.created_at).getTime() : 0;
63842
+ return tb - ta;
63843
+ })[0];
63844
+ }, [depositExecutions]);
63845
+ React302.useEffect(() => {
63846
+ if (awaitingMobileDeposit && latestDepositExecution && (viewRef.current === "mobile_redirect" || viewRef.current === "connecting")) {
63847
+ transitionTo("mobile_deposit_status");
63848
+ }
63849
+ }, [awaitingMobileDeposit, latestDepositExecution, transitionTo]);
63421
63850
  React302.useEffect(() => {
63422
63851
  if (!prefillAmountUsd || !tokenChainDetails || view !== "enter_amount") return;
63423
63852
  const minDeposit = tokenChainDetails.minimum_deposit_amount_usd || 0;
@@ -63463,18 +63892,33 @@ function WalletConnect({
63463
63892
  getAddressBalances(activeWalletInfo.address, sct, publishableKey).then((response) => {
63464
63893
  if (cancelled) return;
63465
63894
  const nonZero = response.balances.filter((b) => b.amount !== "0");
63466
- const sorted = [...nonZero].sort((a, b) => {
63467
- const ae = isBalanceEligible(a);
63468
- const be = isBalanceEligible(b);
63469
- if (ae && !be) return -1;
63470
- if (!ae && be) return 1;
63471
- return 0;
63472
- });
63895
+ const defaultSource = {
63896
+ defaultSourceChainType,
63897
+ defaultSourceChainId,
63898
+ defaultSourceTokenAddress,
63899
+ defaultSourceSymbol
63900
+ };
63901
+ const sorted = [...nonZero].sort(
63902
+ (a, b) => compareBalancesWithDefaultSource(a, b, defaultSource)
63903
+ );
63473
63904
  setBalances(sorted);
63474
63905
  const totalUsd = nonZero.reduce((sum, b) => b.amount_usd ? sum + parseFloat(b.amount_usd) : sum, 0);
63475
63906
  if (totalUsd > 0) setTotalBalanceUsd(totalUsd.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 }));
63476
63907
  const eligible = sorted.filter(isBalanceEligible);
63477
- if (eligible.length === 1) setSelectedBalance(eligible[0]);
63908
+ const defaultBalance = sorted.find(
63909
+ (balance) => isDefaultSourceBalance(balance, defaultSource)
63910
+ );
63911
+ setSelectedBalance((current) => {
63912
+ if (current) {
63913
+ const currentInNewBalances = sorted.find(
63914
+ (balance) => balancesRepresentSameToken(balance, current)
63915
+ );
63916
+ if (currentInNewBalances) return currentInNewBalances;
63917
+ }
63918
+ if (defaultBalance) return defaultBalance;
63919
+ if (eligible.length === 1) return eligible[0];
63920
+ return null;
63921
+ });
63478
63922
  }).catch((err) => {
63479
63923
  if (!cancelled) {
63480
63924
  console.error("[WalletConnect] Error fetching balances:", err);
@@ -63486,7 +63930,15 @@ function WalletConnect({
63486
63930
  return () => {
63487
63931
  cancelled = true;
63488
63932
  };
63489
- }, [activeWalletInfo?.address, activeDepositWallet?.chain_type, publishableKey]);
63933
+ }, [
63934
+ activeWalletInfo?.address,
63935
+ activeDepositWallet?.chain_type,
63936
+ publishableKey,
63937
+ defaultSourceChainType,
63938
+ defaultSourceChainId,
63939
+ defaultSourceTokenAddress,
63940
+ defaultSourceSymbol
63941
+ ]);
63490
63942
  const usdToTokenRate = React302.useMemo(() => {
63491
63943
  if (!selectedBalance || !selectedBalance.amount_usd || !selectedToken) return 0;
63492
63944
  const balanceAmount = Number(selectedBalance.amount) / 10 ** selectedToken.decimals;
@@ -63525,6 +63977,16 @@ function WalletConnect({
63525
63977
  setSelectedWalletDef(null);
63526
63978
  setConnectingNetwork(null);
63527
63979
  break;
63980
+ case "mobile_redirect":
63981
+ transitionTo("select_wallet");
63982
+ setMobileRedirect(null);
63983
+ setAwaitingMobileDeposit(false);
63984
+ break;
63985
+ case "mobile_deposit_status":
63986
+ transitionTo("select_wallet");
63987
+ setMobileRedirect(null);
63988
+ setAwaitingMobileDeposit(false);
63989
+ break;
63528
63990
  case "select_token":
63529
63991
  if (walletProvidedAtMount.current) parentOnBack?.();
63530
63992
  else transitionTo("select_wallet");
@@ -63710,33 +64172,40 @@ function WalletConnect({
63710
64172
  return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
63711
64173
  /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(DepositHeader, { title: "Connect Wallet", showBack: canGoBack, onBack: handleBack, onClose }),
63712
64174
  /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-pb-4", children: [
63713
- /* @__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" }),
63714
- /* @__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)(
63715
- "button",
63716
- {
63717
- onClick: () => handleWalletClick(wallet),
63718
- disabled: isWalletConnecting,
63719
- 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",
63720
- style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
63721
- children: [
63722
- /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
63723
- 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" }),
63724
- /* @__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 })
63725
- ] }),
63726
- 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: [
63727
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: "Install" }),
63728
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ExternalLink, { className: "uf-w-3 uf-h-3", style: { color: colors2.foregroundMuted } })
63729
- ] })
63730
- ]
63731
- },
63732
- wallet.id
63733
- )) }),
64175
+ /* @__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" }),
64176
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uf-space-y-2", style: { maxHeight: 330, overflowY: "auto" }, children: availableWallets.map((wallet) => {
64177
+ const walletPlatformAllowed = !wallet.mobileBrowsePlatforms || wallet.mobileBrowsePlatforms.includes(getMobilePlatform() ?? "");
64178
+ const showOpenInApp = isMobile && !wallet.isInstalled && wallet.supportsMobileBrowse !== false && walletPlatformAllowed;
64179
+ const isPending = pendingMobileWallet?.id === wallet.id;
64180
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
64181
+ "button",
64182
+ {
64183
+ onClick: () => void handleWalletClick(wallet),
64184
+ disabled: isWalletConnecting || !!pendingMobileWallet,
64185
+ 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",
64186
+ style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
64187
+ children: [
64188
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
64189
+ 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" }),
64190
+ /* @__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 })
64191
+ ] }),
64192
+ 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: [
64193
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: showOpenInApp ? "Open" : "Install" }),
64194
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ExternalLink, { className: "uf-w-3 uf-h-3", style: { color: colors2.foregroundMuted } })
64195
+ ] })
64196
+ ]
64197
+ },
64198
+ wallet.id
64199
+ );
64200
+ }) }),
63734
64201
  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 })
63735
64202
  ] })
63736
64203
  ] });
63737
64204
  }
64205
+ const preConnectAccent = selectedWalletDef ? getWalletBrandColor(selectedWalletDef.id, mode) : void 0;
64206
+ const preConnectFg = preConnectAccent ? getContrastingTextColor(preConnectAccent) : void 0;
63738
64207
  if (view === "select_network" && selectedWalletDef) {
63739
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
64208
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
63740
64209
  /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(DepositHeader, { title: "Select Network", showBack: true, onBack: handleBack, onClose }),
63741
64210
  /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-pb-4", children: [
63742
64211
  /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-pb-4", children: [
@@ -63766,10 +64235,10 @@ function WalletConnect({
63766
64235
  )) }),
63767
64236
  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 })
63768
64237
  ] })
63769
- ] });
64238
+ ] }) });
63770
64239
  }
63771
64240
  if (view === "connecting") {
63772
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
64241
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
63773
64242
  /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(DepositHeader, { title: "Connecting...", showBack: true, onBack: handleBack, onClose }),
63774
64243
  /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-16", children: [
63775
64244
  /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(LoaderCircle, { className: "uf-w-12 uf-h-12 uf-animate-spin uf-mb-4", style: { color: colors2.primary } }),
@@ -63780,24 +64249,132 @@ function WalletConnect({
63780
64249
  ] }),
63781
64250
  /* @__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" })
63782
64251
  ] })
63783
- ] });
64252
+ ] }) });
64253
+ }
64254
+ if (view === "mobile_redirect" && mobileRedirect) {
64255
+ const Icon22 = WALLET_ICONS3[mobileRedirect.walletId];
64256
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
64257
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(DepositHeader, { title: mobileRedirect.walletName, showBack: true, onBack: handleBack, onClose }),
64258
+ /* @__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: [
64259
+ 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" }),
64260
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
64261
+ "div",
64262
+ {
64263
+ className: "uf-text-base uf-font-medium uf-text-center uf-mb-1",
64264
+ style: { color: colors2.foreground, fontFamily: fonts.medium },
64265
+ children: [
64266
+ "Continue in ",
64267
+ mobileRedirect.walletName
64268
+ ]
64269
+ }
64270
+ ),
64271
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
64272
+ "div",
64273
+ {
64274
+ className: "uf-text-sm uf-text-center uf-mb-6",
64275
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
64276
+ children: [
64277
+ "Complete your deposit in the ",
64278
+ mobileRedirect.walletName,
64279
+ " app"
64280
+ ]
64281
+ }
64282
+ ),
64283
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
64284
+ "button",
64285
+ {
64286
+ type: "button",
64287
+ onClick: () => {
64288
+ window.location.href = mobileRedirect.deeplink;
64289
+ },
64290
+ 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",
64291
+ style: {
64292
+ backgroundColor: components.card.backgroundColor,
64293
+ borderRadius: components.card.borderRadius,
64294
+ border: `${components.card.borderWidth}px solid ${components.card.borderColor}`,
64295
+ color: components.card.titleColor,
64296
+ fontFamily: fonts.medium
64297
+ },
64298
+ children: [
64299
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ExternalLink, { className: "uf-w-4 uf-h-4", style: { color: components.card.iconColor } }),
64300
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("span", { className: "uf-text-sm uf-font-medium", children: [
64301
+ "Open in ",
64302
+ mobileRedirect.walletName
64303
+ ] })
64304
+ ]
64305
+ }
64306
+ ),
64307
+ awaitingMobileDeposit && /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uf-flex uf-items-center uf-justify-center uf-gap-2 uf-mt-6", children: [
64308
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
64309
+ LoaderCircle,
64310
+ {
64311
+ className: "uf-w-4 uf-h-4 uf-animate-spin",
64312
+ style: { color: colors2.foregroundMuted }
64313
+ }
64314
+ ),
64315
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
64316
+ "span",
64317
+ {
64318
+ className: "uf-text-sm",
64319
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
64320
+ children: "Checking for deposit..."
64321
+ }
64322
+ )
64323
+ ] })
64324
+ ] })
64325
+ ] }) });
64326
+ }
64327
+ if (view === "mobile_deposit_status" && latestDepositExecution) {
64328
+ const isComplete = latestDepositExecution.status === ExecutionStatus.SUCCEEDED;
64329
+ const isFailed = latestDepositExecution.status === ExecutionStatus.FAILED;
64330
+ const title = isComplete ? "Payment Complete" : isFailed ? "Payment Failed" : "Payment Processing";
64331
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { style: viewTransitionStyle, children: [
64332
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
64333
+ DepositHeader,
64334
+ {
64335
+ title,
64336
+ showBack: false,
64337
+ onClose: isComplete && onDone ? onDone : onClose
64338
+ }
64339
+ ),
64340
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(DepositDetailContent, { execution: latestDepositExecution }),
64341
+ 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)(
64342
+ "button",
64343
+ {
64344
+ type: "button",
64345
+ onClick: onDone ? onDone : onNewDeposit ? onNewDeposit : onClose ?? (() => {
64346
+ }),
64347
+ className: "uf-flex-1 uf-py-4 uf-text-sm uf-font-medium uf-transition-opacity hover:uf-opacity-80",
64348
+ style: {
64349
+ backgroundColor: colors2.primary,
64350
+ color: colors2.primaryForeground,
64351
+ fontFamily: fonts.medium,
64352
+ borderRadius: components.button.borderRadius,
64353
+ border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
64354
+ },
64355
+ children: "Done"
64356
+ }
64357
+ ) })
64358
+ ] }) });
63784
64359
  }
63785
64360
  if (!hasWallet) return null;
64361
+ const walletAccent = getWalletBrandColor(walletInfo.type, mode);
64362
+ const walletAccentForeground = walletAccent ? getContrastingTextColor(walletAccent) : void 0;
63786
64363
  if (view === "select_token") {
63787
- 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 ?? (() => {
63788
- }), onDisconnectWallet: onWalletDisconnect ? () => void handleDisconnect() : void 0, isDisconnectingWallet, checkoutAmountUsd, checkoutReceivedUsd }) });
64364
+ 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 ?? (() => {
64365
+ }), onDisconnectWallet: onWalletDisconnect ? () => void handleDisconnect() : void 0, isDisconnectingWallet, checkoutAmountUsd, checkoutReceivedUsd }) }) });
63789
64366
  }
63790
64367
  if (view === "enter_amount" && selectedToken && selectedBalance) {
63791
- 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 ?? (() => {
63792
- }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd }) });
64368
+ 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 ?? (() => {
64369
+ }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd }) }) });
63793
64370
  }
63794
64371
  if (view === "review" && selectedToken) {
63795
- 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 ?? (() => {
63796
- }) }) });
64372
+ 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 ?? (() => {
64373
+ }) }) }) });
63797
64374
  }
63798
64375
  if (view === "confirming") {
63799
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { style: viewTransitionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ConfirmingView, { isConfirming, onClose: onClose ?? (() => {
63800
- }), executions: depositExecutions, isPolling, onNewDeposit, onDone, paymentIntentStatus, amountReceivedUsd: checkoutReceivedUsd, amountReceivedUsdAtSubmission: receivedUsdAtSubmission }) });
64376
+ 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 ?? (() => {
64377
+ }), executions: depositExecutions, isPolling, onNewDeposit, onDone, paymentIntentStatus, amountReceivedUsd: checkoutReceivedUsd, amountReceivedUsdAtSubmission: receivedUsdAtSubmission }) }) });
63801
64378
  }
63802
64379
  return null;
63803
64380
  }
@@ -63841,16 +64418,17 @@ function DepositModal({
63841
64418
  defaultSourceChainId,
63842
64419
  defaultSourceTokenAddress,
63843
64420
  defaultSourceSymbol,
63844
- hideDepositTracker = false,
64421
+ hideDepositTracker,
63845
64422
  showBalanceHeader = false,
63846
64423
  transferInputVariant = "double_input",
63847
64424
  depositConfirmationMode = "auto_ui",
63848
- enableConnectWallet = false,
64425
+ enableTransferCrypto,
64426
+ enableConnectWallet,
63849
64427
  browserWalletAmountQuickSelect = "percentage",
63850
64428
  enablePayWithExchange,
63851
64429
  enableFiatOnramp,
63852
- enableConnectExchange = false,
63853
- enableCashApp = false,
64430
+ enableConnectExchange,
64431
+ enableCashApp,
63854
64432
  hideDepositFlowInfo = false,
63855
64433
  hideDisplayDescription = false,
63856
64434
  onDepositSuccess,
@@ -63868,12 +64446,13 @@ function DepositModal({
63868
64446
  const { colors: colors2, fonts, components } = useTheme();
63869
64447
  const effectiveInitialScreen = (0, import_react3.useMemo)(() => {
63870
64448
  const s = initialScreen ?? "main";
63871
- if (s === "tracker" && hideDepositTracker) return "main";
63872
- if (s === "cashapp" && !enableCashApp) return "main";
64449
+ if (s === "tracker" && hideDepositTracker === true) return "main";
64450
+ if (s === "cashapp" && enableCashApp === false) return "main";
63873
64451
  if (s === "card" && enableFiatOnramp === false) return "main";
63874
64452
  if (s === "pay_with_exchange") return enablePayWithExchange === false ? "main" : "exchange";
63875
- if (s === "exchange_connect") return enableConnectExchange ? "coinbase_connect" : "main";
63876
- if (s === "wallet_connect") return enableConnectWallet ? "wallet_connect" : "main";
64453
+ if (s === "exchange_connect")
64454
+ return enableConnectExchange === false ? "main" : "coinbase_connect";
64455
+ if (s === "wallet_connect") return enableConnectWallet === false ? "main" : "wallet_connect";
63877
64456
  return s;
63878
64457
  }, [
63879
64458
  initialScreen,
@@ -63902,26 +64481,36 @@ function DepositModal({
63902
64481
  const [browserWalletModalOpen, setBrowserWalletModalOpen] = (0, import_react3.useState)(false);
63903
64482
  const [browserWalletInfo, setBrowserWalletInfo] = (0, import_react3.useState)(null);
63904
64483
  const [walletSelectionModalOpen, setWalletSelectionModalOpen] = (0, import_react3.useState)(false);
63905
- const [browserWalletChainType, setBrowserWalletChainType] = (0, import_react3.useState)(() => getStoredWalletChainType());
64484
+ const [browserWalletChainType, setBrowserWalletChainType] = (0, import_react3.useState)(() => getStoredWalletState()?.chainType);
63906
64485
  const [quotesCount, setQuotesCount] = (0, import_react3.useState)(0);
63907
64486
  const [allExecutions, setAllExecutions] = (0, import_react3.useState)([]);
63908
64487
  const [selectedExecution, setSelectedExecution] = (0, import_react3.useState)(null);
63909
64488
  const [depositExecutions, setDepositExecutions] = (0, import_react3.useState)([]);
63910
- const isMobileView = useIsMobileViewport();
64489
+ const { projectConfig } = useProjectConfig({
64490
+ publishableKey,
64491
+ enabled: open
64492
+ });
64493
+ const showTransferCrypto = enableTransferCrypto ?? projectConfig?.transfer_crypto?.enabled ?? true;
64494
+ const showConnectWallet = enableConnectWallet ?? projectConfig?.connect_wallet?.enabled ?? true;
64495
+ const showPayWithExchange = enablePayWithExchange ?? projectConfig?.pay_with_exchange?.enabled ?? true;
64496
+ const showFiatOnramp = enableFiatOnramp ?? projectConfig?.fiat_onramp?.enabled ?? true;
64497
+ const showConnectExchange = enableConnectExchange ?? projectConfig?.connect_exchange?.enabled ?? true;
64498
+ const showCashApp = enableCashApp ?? projectConfig?.cash_app?.enabled ?? true;
64499
+ const showDepositTracker = hideDepositTracker ? false : projectConfig?.deposit_tracker?.enabled ?? true;
63911
64500
  const [integrationExchanges, setIntegrationExchanges] = (0, import_react3.useState)([]);
63912
64501
  (0, import_react3.useEffect)(() => {
63913
- if (!enableConnectExchange || !open) return;
64502
+ if (!showConnectExchange || !open) return;
63914
64503
  getIntegrationExchanges(publishableKey).then((res) => setIntegrationExchanges(res.data)).catch(() => {
63915
64504
  });
63916
- }, [enableConnectExchange, open, publishableKey]);
64505
+ }, [showConnectExchange, open, publishableKey]);
63917
64506
  const [connectedExchange, setConnectedExchange] = (0, import_react3.useState)(() => {
63918
- if (!enableConnectExchange) return null;
64507
+ if (!showConnectExchange) return null;
63919
64508
  const stored = getStoredIntegrationToken(IntegrationProvider.COINBASE);
63920
64509
  if (!stored) return null;
63921
64510
  return { name: "Coinbase", iconUrl: void 0, balanceUsd: null, isLoading: true };
63922
64511
  });
63923
64512
  (0, import_react3.useEffect)(() => {
63924
- if (!enableConnectExchange || !open || view !== "main") return;
64513
+ if (!showConnectExchange || !open || view !== "main") return;
63925
64514
  const stored = getStoredIntegrationToken(IntegrationProvider.COINBASE);
63926
64515
  if (!stored) {
63927
64516
  setConnectedExchange(null);
@@ -63956,7 +64545,7 @@ function DepositModal({
63956
64545
  setConnectedExchange(null);
63957
64546
  }
63958
64547
  });
63959
- }, [enableConnectExchange, open, view, publishableKey]);
64548
+ }, [showConnectExchange, open, view, publishableKey]);
63960
64549
  (0, import_react3.useEffect)(() => {
63961
64550
  if (!connectedExchange || integrationExchanges.length === 0) return;
63962
64551
  const cbExchange = integrationExchanges.find(
@@ -63995,18 +64584,33 @@ function DepositModal({
63995
64584
  setResolvedTheme(theme);
63996
64585
  }
63997
64586
  }, [theme]);
63998
- const { projectConfig } = useProjectConfig({
63999
- publishableKey,
64000
- enabled: open
64001
- });
64002
- const showPayWithExchange = enablePayWithExchange ?? projectConfig?.pay_with_exchange?.enabled ?? true;
64003
- const showFiatOnramp = enableFiatOnramp ?? projectConfig?.fiat_onramp?.enabled ?? true;
64004
64587
  (0, import_react3.useEffect)(() => {
64005
64588
  if (view === "card" && !showFiatOnramp) {
64006
64589
  setView("main");
64007
64590
  setCardView("amount");
64591
+ } else if (view === "transfer" && !showTransferCrypto) {
64592
+ setView("main");
64593
+ } else if (view === "exchange" && !showPayWithExchange) {
64594
+ setView("main");
64595
+ } else if (view === "cashapp" && !showCashApp) {
64596
+ setView("main");
64597
+ } else if (view === "tracker" && !showDepositTracker) {
64598
+ setView("main");
64599
+ } else if (view === "coinbase_connect" && !showConnectExchange) {
64600
+ setView("main");
64601
+ } else if (view === "wallet_connect" && !showConnectWallet) {
64602
+ setView("main");
64008
64603
  }
64009
- }, [view, showFiatOnramp]);
64604
+ }, [
64605
+ view,
64606
+ showFiatOnramp,
64607
+ showTransferCrypto,
64608
+ showPayWithExchange,
64609
+ showCashApp,
64610
+ showDepositTracker,
64611
+ showConnectExchange,
64612
+ showConnectWallet
64613
+ ]);
64010
64614
  (0, import_react3.useEffect)(() => {
64011
64615
  if (view === "exchange" && !showPayWithExchange) {
64012
64616
  setView("main");
@@ -64096,7 +64700,7 @@ function DepositModal({
64096
64700
  depositPrerequisiteBody = standaloneNeedsDepositPrereq ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(SkeletonButton, { variant: "with-icons" }) : /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64097
64701
  /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(SkeletonButton, { variant: "with-icons" }),
64098
64702
  /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(SkeletonButton, { variant: "with-icons" }),
64099
- !hideDepositTracker && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(SkeletonButton, {})
64703
+ showDepositTracker && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(SkeletonButton, {})
64100
64704
  ] });
64101
64705
  } else if (countryError) {
64102
64706
  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: [
@@ -64128,7 +64732,7 @@ function DepositModal({
64128
64732
  const themeClass = resolvedTheme === "dark" ? "uf-dark" : "";
64129
64733
  const handleWalletDisconnect = () => {
64130
64734
  setUserDisconnectedWallet(true);
64131
- clearStoredWalletChainType();
64735
+ clearStoredWalletState();
64132
64736
  setBrowserWalletChainType(void 0);
64133
64737
  setBrowserWalletInfo(null);
64134
64738
  setBrowserWalletModalOpen(false);
@@ -64206,7 +64810,7 @@ function DepositModal({
64206
64810
  };
64207
64811
  const handleBrowserWalletClick = (walletInfo) => {
64208
64812
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
64209
- setStoredWalletChainType(walletChainType);
64813
+ setStoredWalletState(walletInfo.type);
64210
64814
  setBrowserWalletChainType(walletChainType);
64211
64815
  const matchingDepositWallet = wallets.find(
64212
64816
  (w) => w.chain_type === walletChainType
@@ -64237,7 +64841,7 @@ function DepositModal({
64237
64841
  };
64238
64842
  const handleWalletConnected = (walletInfo) => {
64239
64843
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
64240
- setStoredWalletChainType(walletChainType);
64844
+ setStoredWalletState(walletInfo.type);
64241
64845
  setBrowserWalletChainType(walletChainType);
64242
64846
  const matchingDepositWallet = wallets.find(
64243
64847
  (w) => w.chain_type === walletChainType
@@ -64277,7 +64881,7 @@ function DepositModal({
64277
64881
  open: hideOverlay || open,
64278
64882
  onOpenChange: hideOverlay ? void 0 : handleClose,
64279
64883
  modal: !hideOverlay,
64280
- children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64884
+ children: /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(
64281
64885
  DialogContent2,
64282
64886
  {
64283
64887
  ref: hideOverlay ? containerCallbackRef : void 0,
@@ -64286,378 +64890,389 @@ function DepositModal({
64286
64890
  style: { backgroundColor: colors2.background },
64287
64891
  onPointerDownOutside: (e) => e.preventDefault(),
64288
64892
  onInteractOutside: (e) => e.preventDefault(),
64289
- children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ThemeStyleInjector, { children: view === "main" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64290
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64291
- DepositHeader,
64292
- {
64293
- title: modalTitle || "Deposit",
64294
- showClose: !hideOverlay,
64295
- onClose: handleClose,
64296
- showBalance: showBalanceHeader,
64297
- balanceAddress: recipientAddress,
64298
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
64299
- balanceChainId: destinationChainId,
64300
- balanceTokenAddress: destinationTokenAddress,
64301
- projectName: projectConfig?.project_name,
64302
- publishableKey
64303
- }
64304
- ),
64305
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64306
- /* @__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: [
64307
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64308
- TransferCryptoButton,
64309
- {
64310
- onClick: () => setView("transfer"),
64311
- title: transferCryptoTitle,
64312
- subtitle: t7.transferCrypto.subtitle,
64313
- featuredTokens: projectConfig?.transfer_crypto.networks
64314
- }
64315
- ),
64316
- enableConnectWallet && !isMobileView && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64317
- BrowserWalletButton,
64893
+ children: [
64894
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(DialogTitle2, { className: "uf-sr-only", children: modalTitle || "Deposit" }),
64895
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(ThemeStyleInjector, { children: view === "main" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64896
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64897
+ DepositHeader,
64898
+ {
64899
+ title: modalTitle || "Deposit",
64900
+ showClose: !hideOverlay,
64901
+ onClose: handleClose,
64902
+ showBalance: showBalanceHeader,
64903
+ balanceAddress: recipientAddress,
64904
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
64905
+ balanceChainId: destinationChainId,
64906
+ balanceTokenAddress: destinationTokenAddress,
64907
+ projectName: projectConfig?.project_name,
64908
+ publishableKey
64909
+ }
64910
+ ),
64911
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64912
+ /* @__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: [
64913
+ showTransferCrypto && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64914
+ TransferCryptoButton,
64915
+ {
64916
+ onClick: () => setView("transfer"),
64917
+ title: transferCryptoTitle,
64918
+ subtitle: t7.transferCrypto.subtitle,
64919
+ featuredTokens: projectConfig?.transfer_crypto.networks
64920
+ }
64921
+ ),
64922
+ showConnectWallet && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64923
+ BrowserWalletButton,
64924
+ {
64925
+ onClick: handleBrowserWalletClick,
64926
+ onConnectClick: handleWalletConnectClick,
64927
+ onDisconnect: handleWalletDisconnect,
64928
+ chainType: browserWalletChainType,
64929
+ publishableKey,
64930
+ featuredWallets: projectConfig?.connect_wallet?.wallets
64931
+ }
64932
+ ),
64933
+ showFiatOnramp && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64934
+ DepositWithCardButton,
64935
+ {
64936
+ onClick: () => setView("card"),
64937
+ title: depositWithCardTitle,
64938
+ subtitle: t7.depositWithCard.subtitle,
64939
+ paymentNetworks: projectConfig?.payment_networks.networks
64940
+ }
64941
+ ),
64942
+ showPayWithExchange && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64943
+ PayWithExchangeButton,
64944
+ {
64945
+ onClick: () => setView("exchange"),
64946
+ title: payWithExchangeTitle,
64947
+ subtitle: t7.payWithExchange.subtitle,
64948
+ exchanges,
64949
+ loading: exchangesLoading
64950
+ }
64951
+ ),
64952
+ showConnectExchange && connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64953
+ ConnectExchangeButton,
64954
+ {
64955
+ onClick: () => {
64956
+ setCoinbaseSkipToHoldings(true);
64957
+ setView("coinbase_connect");
64958
+ },
64959
+ onDisconnect: handleExchangeDisconnect,
64960
+ title: i18n2.connectExchange.title,
64961
+ subtitle: i18n2.connectExchange.subtitle,
64962
+ exchanges: integrationExchanges,
64963
+ connectedExchange
64964
+ }
64965
+ ),
64966
+ showConnectExchange && !connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64967
+ ConnectExchangeButton,
64968
+ {
64969
+ onClick: () => {
64970
+ setCoinbaseSkipToHoldings(false);
64971
+ setView("coinbase_connect");
64972
+ },
64973
+ title: i18n2.connectExchange.title,
64974
+ subtitle: i18n2.connectExchange.subtitle,
64975
+ exchanges: integrationExchanges
64976
+ }
64977
+ ),
64978
+ showCashApp && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64979
+ CashAppButton,
64980
+ {
64981
+ onClick: () => setView("cashapp"),
64982
+ title: "Pay with Cash App",
64983
+ subtitle: "Deposit via Cash App",
64984
+ iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
64985
+ }
64986
+ ),
64987
+ showDepositTracker && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64988
+ DepositTrackerButton,
64989
+ {
64990
+ onClick: () => {
64991
+ setAllExecutions(depositExecutions);
64992
+ setView("tracker");
64993
+ },
64994
+ title: depositTrackerTitle,
64995
+ subtitle: depositTrackerSubTitle,
64996
+ badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
64997
+ }
64998
+ )
64999
+ ] }) }),
65000
+ depositPoweredByFooter
65001
+ ] })
65002
+ ] }) : view === "transfer" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
65003
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65004
+ DepositHeader,
65005
+ {
65006
+ title: transferCryptoTitle,
65007
+ showBack: showBackTransfer,
65008
+ onBack: handleBack,
65009
+ onClose: handleClose,
65010
+ showBalance: showBalanceHeader,
65011
+ balanceAddress: recipientAddress,
65012
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
65013
+ balanceChainId: destinationChainId,
65014
+ balanceTokenAddress: destinationTokenAddress,
65015
+ projectName: projectConfig?.project_name,
65016
+ publishableKey
65017
+ }
65018
+ ),
65019
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65020
+ 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)(
65021
+ TransferCryptoSingleInput,
64318
65022
  {
64319
- onClick: handleBrowserWalletClick,
64320
- onConnectClick: handleWalletConnectClick,
64321
- onDisconnect: handleWalletDisconnect,
64322
- chainType: browserWalletChainType,
65023
+ userId,
64323
65024
  publishableKey,
64324
- featuredWallets: projectConfig?.connect_wallet?.wallets
65025
+ recipientAddress,
65026
+ destinationChainType,
65027
+ destinationChainId,
65028
+ destinationTokenAddress,
65029
+ defaultSourceChainType,
65030
+ defaultSourceChainId,
65031
+ defaultSourceTokenAddress,
65032
+ defaultSourceSymbol,
65033
+ depositConfirmationMode,
65034
+ onExecutionsChange: setDepositExecutions,
65035
+ onDepositSuccess,
65036
+ onDepositError,
65037
+ wallets
64325
65038
  }
64326
- ),
64327
- showFiatOnramp && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64328
- DepositWithCardButton,
65039
+ ) : /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65040
+ TransferCryptoDoubleInput,
64329
65041
  {
64330
- onClick: () => setView("card"),
64331
- title: depositWithCardTitle,
64332
- subtitle: t7.depositWithCard.subtitle,
64333
- paymentNetworks: projectConfig?.payment_networks.networks
65042
+ userId,
65043
+ publishableKey,
65044
+ recipientAddress,
65045
+ destinationChainType,
65046
+ destinationChainId,
65047
+ destinationTokenAddress,
65048
+ defaultSourceChainType,
65049
+ defaultSourceChainId,
65050
+ defaultSourceTokenAddress,
65051
+ defaultSourceSymbol,
65052
+ depositConfirmationMode,
65053
+ onExecutionsChange: setDepositExecutions,
65054
+ onDepositSuccess,
65055
+ onDepositError,
65056
+ wallets
64334
65057
  }
64335
65058
  ),
64336
- showPayWithExchange && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64337
- PayWithExchangeButton,
65059
+ depositPoweredByFooter
65060
+ ] })
65061
+ ] }) : view === "tracker" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
65062
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65063
+ DepositHeader,
65064
+ {
65065
+ title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
65066
+ showBack: showBackTracker,
65067
+ onBack: handleBack,
65068
+ onClose: handleClose
65069
+ }
65070
+ ),
65071
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65072
+ /* @__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)(
65073
+ "div",
64338
65074
  {
64339
- onClick: () => setView("exchange"),
64340
- title: payWithExchangeTitle,
64341
- subtitle: t7.payWithExchange.subtitle,
64342
- exchanges,
64343
- loading: exchangesLoading
65075
+ className: "uf-text-sm",
65076
+ style: { color: components.container.subtitleColor, fontFamily: fonts.regular },
65077
+ children: "No deposits yet"
64344
65078
  }
64345
- ),
64346
- enableConnectExchange && connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64347
- ConnectExchangeButton,
65079
+ ) }) : allExecutions.map((execution) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65080
+ DepositExecutionItem,
64348
65081
  {
64349
- onClick: () => {
64350
- setCoinbaseSkipToHoldings(true);
64351
- setView("coinbase_connect");
64352
- },
64353
- onDisconnect: handleExchangeDisconnect,
64354
- title: i18n2.connectExchange.title,
64355
- subtitle: i18n2.connectExchange.subtitle,
64356
- exchanges: integrationExchanges,
64357
- connectedExchange
64358
- }
64359
- ),
64360
- enableConnectExchange && !connectedExchange && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64361
- ConnectExchangeButton,
65082
+ execution,
65083
+ onClick: () => setSelectedExecution(execution)
65084
+ },
65085
+ execution.id
65086
+ )) }) }),
65087
+ depositPoweredByFooter
65088
+ ] })
65089
+ ] }) : view === "card" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
65090
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65091
+ DepositHeader,
65092
+ {
65093
+ title: cardView === "quotes" ? t7.quotes : depositWithCardTitle,
65094
+ showBack: showBackCard,
65095
+ onBack: handleBack,
65096
+ onClose: handleClose,
65097
+ badge: cardView === "quotes" ? { count: quotesCount } : void 0,
65098
+ showBalance: showBalanceHeader,
65099
+ balanceAddress: recipientAddress,
65100
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
65101
+ balanceChainId: destinationChainId,
65102
+ balanceTokenAddress: destinationTokenAddress,
65103
+ projectName: projectConfig?.project_name,
65104
+ publishableKey
65105
+ }
65106
+ ),
65107
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65108
+ 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)(
65109
+ BuyWithCard,
64362
65110
  {
64363
- onClick: () => {
64364
- setCoinbaseSkipToHoldings(false);
64365
- setView("coinbase_connect");
64366
- },
64367
- title: i18n2.connectExchange.title,
64368
- subtitle: i18n2.connectExchange.subtitle,
64369
- exchanges: integrationExchanges
65111
+ userId,
65112
+ publishableKey,
65113
+ view: cardView,
65114
+ onViewChange: handleCardViewChange,
65115
+ destinationTokenSymbol,
65116
+ recipientAddress,
65117
+ destinationChainType,
65118
+ destinationChainId,
65119
+ destinationTokenAddress,
65120
+ onDepositSuccess,
65121
+ onDepositError,
65122
+ onEvent,
65123
+ themeClass,
65124
+ wallets,
65125
+ assetCdnUrl: projectConfig?.asset_cdn_url,
65126
+ hideDepositFlowInfo,
65127
+ hideDisplayDescription
64370
65128
  }
64371
65129
  ),
64372
- enableCashApp && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64373
- CashAppButton,
65130
+ depositPoweredByFooter
65131
+ ] })
65132
+ ] }) : view === "exchange" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
65133
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65134
+ DepositHeader,
65135
+ {
65136
+ title: payWithExchangeTitle,
65137
+ showBack: exchangeView === "pending" || sessionOpenedFromMenu,
65138
+ onBack: handleBack,
65139
+ onClose: handleClose
65140
+ }
65141
+ ),
65142
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65143
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65144
+ PayWithExchange,
64374
65145
  {
64375
- onClick: () => setView("cashapp"),
64376
- title: "Pay with Cash App",
64377
- subtitle: "Deposit via Cash App",
64378
- iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
65146
+ userId,
65147
+ publishableKey,
65148
+ exchanges,
65149
+ view: exchangeView,
65150
+ onViewChange: setExchangeView,
65151
+ destinationTokenSymbol,
65152
+ recipientAddress,
65153
+ destinationChainType,
65154
+ destinationChainId,
65155
+ destinationTokenAddress,
65156
+ onDepositSuccess,
65157
+ onDepositError,
65158
+ wallets,
65159
+ defaultToken: defaultToken ?? null
64379
65160
  }
64380
65161
  ),
64381
- !hideDepositTracker && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64382
- DepositTrackerButton,
64383
- {
64384
- onClick: () => {
64385
- setAllExecutions(depositExecutions);
64386
- setView("tracker");
64387
- },
64388
- title: depositTrackerTitle,
64389
- subtitle: depositTrackerSubTitle,
64390
- badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
64391
- }
64392
- )
64393
- ] }) }),
64394
- depositPoweredByFooter
64395
- ] })
64396
- ] }) : view === "transfer" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64397
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64398
- DepositHeader,
64399
- {
64400
- title: transferCryptoTitle,
64401
- showBack: showBackTransfer,
64402
- onBack: handleBack,
64403
- onClose: handleClose,
64404
- showBalance: showBalanceHeader,
64405
- balanceAddress: recipientAddress,
64406
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
64407
- balanceChainId: destinationChainId,
64408
- balanceTokenAddress: destinationTokenAddress,
64409
- projectName: projectConfig?.project_name,
64410
- publishableKey
64411
- }
64412
- ),
64413
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64414
- 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)(
64415
- TransferCryptoSingleInput,
65162
+ depositPoweredByFooter
65163
+ ] })
65164
+ ] }) : view === "coinbase_connect" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65165
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65166
+ CoinbaseConnect,
64416
65167
  {
64417
- userId,
64418
65168
  publishableKey,
64419
- recipientAddress,
64420
- destinationChainType,
64421
- destinationChainId,
64422
- destinationTokenAddress,
64423
- defaultSourceChainType,
64424
- defaultSourceChainId,
64425
- defaultSourceTokenAddress,
64426
- defaultSourceSymbol,
64427
- depositConfirmationMode,
64428
- onExecutionsChange: setDepositExecutions,
64429
- onDepositSuccess,
64430
- onDepositError,
64431
- wallets
64432
- }
64433
- ) : /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64434
- TransferCryptoDoubleInput,
64435
- {
64436
65169
  userId,
64437
- publishableKey,
65170
+ wallets,
64438
65171
  recipientAddress,
64439
- destinationChainType,
64440
- destinationChainId,
64441
- destinationTokenAddress,
65172
+ destinationTokenAddress: destinationTokenAddress ?? "",
65173
+ destinationChainId: destinationChainId ?? "",
65174
+ destinationChainType: destinationChainType ?? "",
65175
+ onTransferSuccess: (result) => {
65176
+ onDepositSuccess?.({
65177
+ message: "Transfer completed via Coinbase Connect",
65178
+ transaction: result
65179
+ });
65180
+ },
65181
+ onTransferError: (error) => {
65182
+ onDepositError?.({
65183
+ message: error.message,
65184
+ error
65185
+ });
65186
+ },
65187
+ onBack: handleBack,
65188
+ onClose: handleClose,
65189
+ onDisconnect: handleExchangeDisconnect,
65190
+ skipToHoldings: coinbaseSkipToHoldings,
65191
+ canGoBack: sessionOpenedFromMenu,
65192
+ onExecutionsChange: setDepositExecutions,
64442
65193
  defaultSourceChainType,
64443
65194
  defaultSourceChainId,
64444
65195
  defaultSourceTokenAddress,
64445
- defaultSourceSymbol,
64446
- depositConfirmationMode,
64447
- onExecutionsChange: setDepositExecutions,
64448
- onDepositSuccess,
64449
- onDepositError,
64450
- wallets
64451
- }
64452
- ),
64453
- depositPoweredByFooter
64454
- ] })
64455
- ] }) : view === "tracker" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64456
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64457
- DepositHeader,
64458
- {
64459
- title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
64460
- showBack: showBackTracker,
64461
- onBack: handleBack,
64462
- onClose: handleClose
64463
- }
64464
- ),
64465
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64466
- /* @__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)(
64467
- "div",
64468
- {
64469
- className: "uf-text-sm",
64470
- style: { color: components.container.subtitleColor, fontFamily: fonts.regular },
64471
- children: "No deposits yet"
64472
- }
64473
- ) }) : allExecutions.map((execution) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64474
- DepositExecutionItem,
64475
- {
64476
- execution,
64477
- onClick: () => setSelectedExecution(execution)
64478
- },
64479
- execution.id
64480
- )) }) }),
64481
- depositPoweredByFooter
64482
- ] })
64483
- ] }) : view === "card" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64484
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64485
- DepositHeader,
64486
- {
64487
- title: cardView === "quotes" ? t7.quotes : depositWithCardTitle,
64488
- showBack: showBackCard,
64489
- onBack: handleBack,
64490
- onClose: handleClose,
64491
- badge: cardView === "quotes" ? { count: quotesCount } : void 0,
64492
- showBalance: showBalanceHeader,
64493
- balanceAddress: recipientAddress,
64494
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
64495
- balanceChainId: destinationChainId,
64496
- balanceTokenAddress: destinationTokenAddress,
64497
- projectName: projectConfig?.project_name,
64498
- publishableKey
64499
- }
64500
- ),
64501
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64502
- 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)(
64503
- BuyWithCard,
64504
- {
64505
- userId,
64506
- publishableKey,
64507
- view: cardView,
64508
- onViewChange: handleCardViewChange,
64509
- destinationTokenSymbol,
64510
- recipientAddress,
64511
- destinationChainType,
64512
- destinationChainId,
64513
- destinationTokenAddress,
64514
- onDepositSuccess,
64515
- onDepositError,
64516
- onEvent,
64517
- themeClass,
64518
- wallets,
64519
- assetCdnUrl: projectConfig?.asset_cdn_url,
64520
- hideDepositFlowInfo,
64521
- hideDisplayDescription
65196
+ defaultSourceSymbol
64522
65197
  }
64523
65198
  ),
64524
65199
  depositPoweredByFooter
64525
- ] })
64526
- ] }) : view === "exchange" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64527
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64528
- DepositHeader,
64529
- {
64530
- title: payWithExchangeTitle,
64531
- showBack: exchangeView === "pending" || sessionOpenedFromMenu,
64532
- onBack: handleBack,
64533
- onClose: handleClose
64534
- }
64535
- ),
64536
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65200
+ ] }) : view === "wallet_connect" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64537
65201
  /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64538
- PayWithExchange,
65202
+ WalletConnect,
64539
65203
  {
65204
+ walletInfo: browserWalletInfo ?? void 0,
65205
+ depositWallet: browserWalletInfo?.depositWallet ?? void 0,
65206
+ wallets,
64540
65207
  userId,
64541
65208
  publishableKey,
64542
- exchanges,
64543
- view: exchangeView,
64544
- onViewChange: setExchangeView,
64545
- destinationTokenSymbol,
64546
- recipientAddress,
64547
- destinationChainType,
64548
- destinationChainId,
64549
- destinationTokenAddress,
65209
+ assetCdnUrl: projectConfig?.asset_cdn_url,
65210
+ projectName: projectConfig?.project_name,
65211
+ onSuccess: (txHash) => {
65212
+ onDepositSuccess?.({
65213
+ message: "Transaction sent successfully",
65214
+ transaction: { txHash }
65215
+ });
65216
+ },
65217
+ onError: (error) => {
65218
+ onDepositError?.({
65219
+ message: error.message,
65220
+ error
65221
+ });
65222
+ },
64550
65223
  onDepositSuccess,
64551
65224
  onDepositError,
64552
- wallets,
64553
- defaultToken: defaultToken ?? null
65225
+ amountQuickSelect: browserWalletAmountQuickSelect,
65226
+ onWalletDisconnect: handleWalletDisconnect,
65227
+ onWalletConnected: (info, dw) => {
65228
+ setBrowserWalletInfo({ ...info, depositWallet: dw });
65229
+ setStoredWalletState(info.type);
65230
+ setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
65231
+ },
65232
+ onBack: handleBack,
65233
+ onClose: handleClose,
65234
+ defaultSourceChainType,
65235
+ defaultSourceChainId,
65236
+ defaultSourceTokenAddress,
65237
+ defaultSourceSymbol,
65238
+ canGoBack: sessionOpenedFromMenu,
65239
+ depositWalletsLoading: walletsLoading
64554
65240
  }
64555
65241
  ),
64556
65242
  depositPoweredByFooter
64557
- ] })
64558
- ] }) : view === "coinbase_connect" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64559
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64560
- CoinbaseConnect,
64561
- {
64562
- publishableKey,
64563
- userId,
64564
- wallets,
64565
- recipientAddress,
64566
- destinationTokenAddress: destinationTokenAddress ?? "",
64567
- destinationChainId: destinationChainId ?? "",
64568
- destinationChainType: destinationChainType ?? "",
64569
- onTransferSuccess: (result) => {
64570
- onDepositSuccess?.({
64571
- message: "Transfer completed via Coinbase Connect",
64572
- transaction: result
64573
- });
64574
- },
64575
- onTransferError: (error) => {
64576
- onDepositError?.({
64577
- message: error.message,
64578
- error
64579
- });
64580
- },
64581
- onBack: handleBack,
64582
- onClose: handleClose,
64583
- onDisconnect: handleExchangeDisconnect,
64584
- skipToHoldings: coinbaseSkipToHoldings,
64585
- canGoBack: sessionOpenedFromMenu,
64586
- onExecutionsChange: setDepositExecutions
64587
- }
64588
- ),
64589
- depositPoweredByFooter
64590
- ] }) : view === "wallet_connect" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
64591
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64592
- WalletConnect,
64593
- {
64594
- walletInfo: browserWalletInfo ?? void 0,
64595
- depositWallet: browserWalletInfo?.depositWallet ?? void 0,
64596
- wallets,
64597
- userId,
64598
- publishableKey,
64599
- assetCdnUrl: projectConfig?.asset_cdn_url,
64600
- projectName: projectConfig?.project_name,
64601
- onSuccess: (txHash) => {
64602
- onDepositSuccess?.({
64603
- message: "Transaction sent successfully",
64604
- transaction: { txHash }
64605
- });
64606
- },
64607
- onError: (error) => {
64608
- onDepositError?.({
64609
- message: error.message,
64610
- error
64611
- });
64612
- },
64613
- onDepositSuccess,
64614
- onDepositError,
64615
- amountQuickSelect: browserWalletAmountQuickSelect,
64616
- onWalletDisconnect: handleWalletDisconnect,
64617
- onWalletConnected: (info, dw) => {
64618
- setBrowserWalletInfo({ ...info, depositWallet: dw });
64619
- setStoredWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
64620
- setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
64621
- },
64622
- onBack: handleBack,
64623
- onClose: handleClose,
64624
- canGoBack: sessionOpenedFromMenu,
64625
- depositWalletsLoading: walletsLoading
64626
- }
64627
- ),
64628
- depositPoweredByFooter
64629
- ] }) : view === "cashapp" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64630
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64631
- DepositHeader,
64632
- {
64633
- title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
64634
- showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
64635
- onBack: handleBack,
64636
- onClose: handleClose
64637
- }
64638
- ),
64639
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65243
+ ] }) : view === "cashapp" ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
64640
65244
  /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
64641
- PayWithCashApp,
65245
+ DepositHeader,
64642
65246
  {
64643
- userId,
64644
- publishableKey,
64645
- recipientAddress,
64646
- destinationChainType,
64647
- destinationChainId,
64648
- destinationTokenAddress,
64649
- cashAppIconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0,
64650
- view: cashAppView,
64651
- onViewChange: setCashAppView,
64652
- onAmountChange: setCashAppAmount,
64653
- onEvent,
64654
- onDepositSuccess,
64655
- onDepositError
65247
+ title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
65248
+ showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
65249
+ onBack: handleBack,
65250
+ onClose: handleClose
64656
65251
  }
64657
65252
  ),
64658
- depositPoweredByFooter
64659
- ] })
64660
- ] }) : null })
65253
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
65254
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
65255
+ PayWithCashApp,
65256
+ {
65257
+ userId,
65258
+ publishableKey,
65259
+ recipientAddress,
65260
+ destinationChainType,
65261
+ destinationChainId,
65262
+ destinationTokenAddress,
65263
+ cashAppIconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0,
65264
+ view: cashAppView,
65265
+ onViewChange: setCashAppView,
65266
+ onAmountChange: setCashAppAmount,
65267
+ onEvent,
65268
+ onDepositSuccess,
65269
+ onDepositError
65270
+ }
65271
+ ),
65272
+ depositPoweredByFooter
65273
+ ] })
65274
+ ] }) : null })
65275
+ ]
64661
65276
  }
64662
65277
  )
64663
65278
  }
@@ -64723,7 +65338,8 @@ function CheckoutModal({
64723
65338
  clientSecret,
64724
65339
  publishableKey,
64725
65340
  modalTitle,
64726
- enableConnectWallet = false,
65341
+ enableTransferCrypto,
65342
+ enableConnectWallet,
64727
65343
  defaultSourceChainType,
64728
65344
  defaultSourceChainId,
64729
65345
  defaultSourceTokenAddress,
@@ -64740,8 +65356,7 @@ function CheckoutModal({
64740
65356
  const [browserWalletModalOpen, setBrowserWalletModalOpen] = (0, import_react29.useState)(false);
64741
65357
  const [browserWalletInfo, setBrowserWalletInfo] = (0, import_react29.useState)(null);
64742
65358
  const [walletSelectionModalOpen, setWalletSelectionModalOpen] = (0, import_react29.useState)(false);
64743
- const [browserWalletChainType, setBrowserWalletChainType] = (0, import_react29.useState)(() => getStoredWalletChainType());
64744
- const isMobileView = useIsMobileViewport();
65359
+ const [browserWalletChainType, setBrowserWalletChainType] = (0, import_react29.useState)(() => getStoredWalletState()?.chainType);
64745
65360
  const [resolvedTheme, setResolvedTheme] = (0, import_react29.useState)(
64746
65361
  theme === "auto" ? "dark" : theme
64747
65362
  );
@@ -64773,6 +65388,15 @@ function CheckoutModal({
64773
65388
  publishableKey,
64774
65389
  enabled: open
64775
65390
  });
65391
+ const showTransferCrypto = enableTransferCrypto ?? projectConfig?.transfer_crypto?.enabled ?? true;
65392
+ const showConnectWallet = enableConnectWallet ?? projectConfig?.connect_wallet?.enabled ?? true;
65393
+ (0, import_react29.useEffect)(() => {
65394
+ if (view === "transfer" && !showTransferCrypto) {
65395
+ setView("main");
65396
+ } else if (view === "wallet_connect" && !showConnectWallet) {
65397
+ setView("main");
65398
+ }
65399
+ }, [showConnectWallet, showTransferCrypto, view]);
64776
65400
  const prevStatusRef = (0, import_react29.useRef)(null);
64777
65401
  (0, import_react29.useEffect)(() => {
64778
65402
  if (!paymentIntent) return;
@@ -64863,7 +65487,7 @@ function CheckoutModal({
64863
65487
  const handleBrowserWalletClick = (0, import_react29.useCallback)(
64864
65488
  (walletInfo) => {
64865
65489
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
64866
- setStoredWalletChainType(walletChainType);
65490
+ setStoredWalletState(walletInfo.type);
64867
65491
  setBrowserWalletChainType(walletChainType);
64868
65492
  const matchingDepositWallet = wallets.find(
64869
65493
  (w) => w.chain_type === walletChainType
@@ -64890,7 +65514,7 @@ function CheckoutModal({
64890
65514
  const handleWalletConnected = (0, import_react29.useCallback)(
64891
65515
  (walletInfo) => {
64892
65516
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
64893
- setStoredWalletChainType(walletChainType);
65517
+ setStoredWalletState(walletInfo.type);
64894
65518
  setBrowserWalletChainType(walletChainType);
64895
65519
  const matchingDepositWallet = wallets.find(
64896
65520
  (w) => w.chain_type === walletChainType
@@ -64914,7 +65538,7 @@ function CheckoutModal({
64914
65538
  );
64915
65539
  const handleWalletDisconnect = (0, import_react29.useCallback)(() => {
64916
65540
  setUserDisconnectedWallet(true);
64917
- clearStoredWalletChainType();
65541
+ clearStoredWalletState();
64918
65542
  setBrowserWalletChainType(void 0);
64919
65543
  setBrowserWalletInfo(null);
64920
65544
  setBrowserWalletModalOpen(false);
@@ -65149,7 +65773,7 @@ function CheckoutModal({
65149
65773
  ] }) : paymentIntent ? /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "uf-space-y-3", children: [
65150
65774
  progressSection,
65151
65775
  (paymentIntent.status === "requires_payment" || paymentIntent.status === "processing") && /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)(import_jsx_runtime75.Fragment, { children: [
65152
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
65776
+ showTransferCrypto && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
65153
65777
  TransferCryptoButton,
65154
65778
  {
65155
65779
  onClick: () => setView("transfer"),
@@ -65158,7 +65782,7 @@ function CheckoutModal({
65158
65782
  featuredTokens: projectConfig?.transfer_crypto.networks
65159
65783
  }
65160
65784
  ),
65161
- enableConnectWallet && !isMobileView && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
65785
+ showConnectWallet && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
65162
65786
  BrowserWalletButton,
65163
65787
  {
65164
65788
  onClick: handleBrowserWalletClick,
@@ -65299,14 +65923,18 @@ function CheckoutModal({
65299
65923
  onWalletDisconnect: handleWalletDisconnect,
65300
65924
  onWalletConnected: (info, dw) => {
65301
65925
  setBrowserWalletInfo({ ...info, depositWallet: dw });
65302
- setStoredWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
65926
+ setStoredWalletState(info.type);
65303
65927
  setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
65304
65928
  },
65305
65929
  onNewDeposit: () => setView("main"),
65306
65930
  onDone: () => setView("main"),
65307
65931
  paymentIntentStatus: paymentIntent.status,
65308
65932
  onBack: handleBack,
65309
- onClose: handleClose
65933
+ onClose: handleClose,
65934
+ defaultSourceChainType,
65935
+ defaultSourceChainId,
65936
+ defaultSourceTokenAddress,
65937
+ defaultSourceSymbol
65310
65938
  }
65311
65939
  ),
65312
65940
  poweredByFooter
@@ -67060,6 +67688,16 @@ function UnifoldProvider2({
67060
67688
  });
67061
67689
  promise.catch(() => {
67062
67690
  });
67691
+ if (!config2.recipientAddress) {
67692
+ const error = {
67693
+ message: "beginDeposit requires a `recipientAddress`.",
67694
+ code: "MISSING_RECIPIENT"
67695
+ };
67696
+ console.error(`[UnifoldProvider] ${error.message}`);
67697
+ depositPromiseRef.current.reject(error);
67698
+ depositPromiseRef.current = null;
67699
+ return promise;
67700
+ }
67063
67701
  setDepositConfig(config2);
67064
67702
  setIsOpen(true);
67065
67703
  return promise;
@@ -67269,6 +67907,7 @@ function UnifoldProvider2({
67269
67907
  onOpenChange: closeCheckout,
67270
67908
  clientSecret: checkoutConfig.clientSecret,
67271
67909
  publishableKey,
67910
+ enableTransferCrypto: config?.enableTransferCrypto,
67272
67911
  enableConnectWallet: config?.enableConnectWallet,
67273
67912
  defaultSourceChainType: checkoutConfig.defaultSourceChainType,
67274
67913
  defaultSourceChainId: checkoutConfig.defaultSourceChainId,
@@ -67325,6 +67964,7 @@ function UnifoldProvider2({
67325
67964
  hideDepositTracker: config?.hideDepositTracker,
67326
67965
  showBalanceHeader: config?.showBalanceHeader,
67327
67966
  transferInputVariant: config?.transferInputVariant,
67967
+ enableTransferCrypto: config?.enableTransferCrypto,
67328
67968
  enableConnectWallet: config?.enableConnectWallet,
67329
67969
  enablePayWithExchange: config?.enablePayWithExchange,
67330
67970
  enableFiatOnramp: config?.enableFiatOnramp,