@unifold/connect-react 0.1.62 → 0.1.64

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -6124,6 +6124,42 @@ import { useState as useState92, useEffect as useEffect52, useRef as useRef22 }
6124
6124
 
6125
6125
  // ../core/dist/index.mjs
6126
6126
  import { useQuery } from "@tanstack/react-query";
6127
+ function formatStablecoinAmount(baseUnits, decimals) {
6128
+ const raw = Number(baseUnits) / 10 ** decimals;
6129
+ const floored = Math.floor(raw * 100) / 100;
6130
+ const ceiled = raw > floored ? floored + 0.01 : raw;
6131
+ return ceiled.toFixed(2);
6132
+ }
6133
+ function generateKSUID() {
6134
+ const BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
6135
+ const KSUID_EPOCH = 14e8;
6136
+ const timestampSeconds = Math.floor(Date.now() / 1e3) - KSUID_EPOCH;
6137
+ const payload = new Uint8Array(20);
6138
+ payload[0] = timestampSeconds >>> 24 & 255;
6139
+ payload[1] = timestampSeconds >>> 16 & 255;
6140
+ payload[2] = timestampSeconds >>> 8 & 255;
6141
+ payload[3] = timestampSeconds & 255;
6142
+ if (typeof crypto !== "undefined" && crypto.getRandomValues) {
6143
+ crypto.getRandomValues(payload.subarray(4));
6144
+ } else {
6145
+ for (let i = 4; i < 20; i++) {
6146
+ payload[i] = Math.floor(Math.random() * 256);
6147
+ }
6148
+ }
6149
+ let value = 0n;
6150
+ for (const byte of payload) {
6151
+ value = value << 8n | BigInt(byte);
6152
+ }
6153
+ let encoded = "";
6154
+ while (value > 0n) {
6155
+ encoded = BASE62[Number(value % 62n)] + encoded;
6156
+ value = value / 62n;
6157
+ }
6158
+ return encoded.padStart(27, "0");
6159
+ }
6160
+ function generatePrefixedKSUID(prefix) {
6161
+ return `${prefix}_${generateKSUID()}`;
6162
+ }
6127
6163
  var API_BASE_URL = (() => {
6128
6164
  try {
6129
6165
  return process.env.NEXT_PUBLIC_API_BASE_URL || "https://api.unifold.io";
@@ -6450,9 +6486,7 @@ function getOnrampSessionStartUrl(request, publishableKey) {
6450
6486
  if (request.subdivision_code) {
6451
6487
  params.append("subdivision_code", request.subdivision_code);
6452
6488
  }
6453
- if (request.external_id) {
6454
- params.append("external_id", request.external_id);
6455
- }
6489
+ params.append("external_id", request.external_id ?? generatePrefixedKSUID("ors"));
6456
6490
  if (request.email) {
6457
6491
  params.append("email", request.email);
6458
6492
  }
@@ -6563,6 +6597,40 @@ async function getAddressBalances(address, chainType, publishableKey) {
6563
6597
  const data = await response.json();
6564
6598
  return data;
6565
6599
  }
6600
+ async function getExternalWallets(publishableKey) {
6601
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
6602
+ validatePublishableKey(pk);
6603
+ const response = await fetch(`${API_BASE_URL}/v1/public/external_wallets`, {
6604
+ method: "GET",
6605
+ headers: {
6606
+ accept: "application/json",
6607
+ "x-publishable-key": pk
6608
+ }
6609
+ });
6610
+ if (!response.ok) {
6611
+ throw new Error(`Failed to fetch external wallets: ${response.statusText}`);
6612
+ }
6613
+ const data = await response.json();
6614
+ return data;
6615
+ }
6616
+ async function getWalletMobileDeepLink(wallet, depositAddresses, publishableKey) {
6617
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
6618
+ validatePublishableKey(pk);
6619
+ const response = await fetch(`${API_BASE_URL}/v1/public/external_wallets/mobile_deeplink`, {
6620
+ method: "POST",
6621
+ headers: {
6622
+ "Content-Type": "application/json",
6623
+ accept: "application/json",
6624
+ "x-publishable-key": pk
6625
+ },
6626
+ body: JSON.stringify({ wallet, deposit_addresses: depositAddresses })
6627
+ });
6628
+ if (!response.ok) {
6629
+ throw new Error(`Failed to generate wallet deep link: ${response.statusText}`);
6630
+ }
6631
+ const data = await response.json();
6632
+ return data;
6633
+ }
6566
6634
  async function getAddressBalance(address, chainType, chainId, tokenAddress, publishableKey) {
6567
6635
  const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
6568
6636
  validatePublishableKey(pk);
@@ -6667,9 +6735,7 @@ function getExchangeSessionStartUrl(request, publishableKey) {
6667
6735
  if (request.source_amount) {
6668
6736
  params.append("source_amount", request.source_amount);
6669
6737
  }
6670
- if (request.external_id) {
6671
- params.append("external_id", request.external_id);
6672
- }
6738
+ params.append("external_id", request.external_id ?? generatePrefixedKSUID("exc"));
6673
6739
  return `${API_BASE_URL}/v1/public/onramps/exchanges/sessions/start?${params.toString()}`;
6674
6740
  }
6675
6741
  async function getIntegrationExchanges(publishableKey) {
@@ -7003,40 +7069,6 @@ async function getCashAppSessionStatus(externalId, publishableKey) {
7003
7069
  }
7004
7070
  return response.json();
7005
7071
  }
7006
- function formatStablecoinAmount(baseUnits, decimals) {
7007
- const raw = Number(baseUnits) / 10 ** decimals;
7008
- const floored = Math.floor(raw * 100) / 100;
7009
- const ceiled = raw > floored ? floored + 0.01 : raw;
7010
- return ceiled.toFixed(2);
7011
- }
7012
- function generatePrefixedKSUID(prefix) {
7013
- const BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
7014
- const KSUID_EPOCH = 14e8;
7015
- const timestampSeconds = Math.floor(Date.now() / 1e3) - KSUID_EPOCH;
7016
- const payload = new Uint8Array(20);
7017
- payload[0] = timestampSeconds >>> 24 & 255;
7018
- payload[1] = timestampSeconds >>> 16 & 255;
7019
- payload[2] = timestampSeconds >>> 8 & 255;
7020
- payload[3] = timestampSeconds & 255;
7021
- if (typeof crypto !== "undefined" && crypto.getRandomValues) {
7022
- crypto.getRandomValues(payload.subarray(4));
7023
- } else {
7024
- for (let i = 4; i < 20; i++) {
7025
- payload[i] = Math.floor(Math.random() * 256);
7026
- }
7027
- }
7028
- let value = 0n;
7029
- for (const byte of payload) {
7030
- value = value << 8n | BigInt(byte);
7031
- }
7032
- let encoded = "";
7033
- while (value > 0n) {
7034
- encoded = BASE62[Number(value % 62n)] + encoded;
7035
- value = value / 62n;
7036
- }
7037
- encoded = encoded.padStart(27, "0");
7038
- return `${prefix}_${encoded}`;
7039
- }
7040
7072
  var DepositEventType = /* @__PURE__ */ ((DepositEventType2) => {
7041
7073
  DepositEventType2["ONRAMP_SESSION_CREATED"] = "onramp_session.created";
7042
7074
  return DepositEventType2;
@@ -13441,6 +13473,7 @@ import { jsx as jsx47, jsxs as jsxs422 } from "react/jsx-runtime";
13441
13473
  import { jsx as jsx48, jsxs as jsxs43 } from "react/jsx-runtime";
13442
13474
  import * as React302 from "react";
13443
13475
  import { useQuery as useQuery12 } from "@tanstack/react-query";
13476
+ import { useQuery as useQuery13 } from "@tanstack/react-query";
13444
13477
  import { jsx as jsx49 } from "react/jsx-runtime";
13445
13478
  import { jsx as jsx50, jsxs as jsxs44 } from "react/jsx-runtime";
13446
13479
  import { Fragment as Fragment82, jsx as jsx51, jsxs as jsxs45 } from "react/jsx-runtime";
@@ -13457,7 +13490,7 @@ import {
13457
13490
  useRef as useRef102,
13458
13491
  useMemo as useMemo112
13459
13492
  } from "react";
13460
- import { useQuery as useQuery13 } from "@tanstack/react-query";
13493
+ import { useQuery as useQuery14 } from "@tanstack/react-query";
13461
13494
  import { Fragment as Fragment12, jsx as jsx56, jsxs as jsxs50 } from "react/jsx-runtime";
13462
13495
  import {
13463
13496
  useState as useState37,
@@ -13466,16 +13499,16 @@ import {
13466
13499
  useCallback as useCallback82,
13467
13500
  useRef as useRef122
13468
13501
  } from "react";
13469
- import { useQuery as useQuery14 } from "@tanstack/react-query";
13470
13502
  import { useQuery as useQuery15 } from "@tanstack/react-query";
13471
13503
  import { useQuery as useQuery16 } from "@tanstack/react-query";
13472
13504
  import { useQuery as useQuery17 } from "@tanstack/react-query";
13505
+ import { useQuery as useQuery18 } from "@tanstack/react-query";
13473
13506
  import { useState as useState34, useEffect as useEffect282, useRef as useRef112 } from "react";
13474
13507
  import { jsx as jsx57, jsxs as jsxs51 } from "react/jsx-runtime";
13475
13508
  import { useState as useState35, useCallback as useCallback72, useMemo as useMemo132, useEffect as useEffect292 } from "react";
13476
- import { useQuery as useQuery18 } from "@tanstack/react-query";
13477
- import { useMemo as useMemo122 } from "react";
13478
13509
  import { useQuery as useQuery19 } from "@tanstack/react-query";
13510
+ import { useMemo as useMemo122 } from "react";
13511
+ import { useQuery as useQuery20 } from "@tanstack/react-query";
13479
13512
  import { Fragment as Fragment13, jsx as jsx58, jsxs as jsxs52 } from "react/jsx-runtime";
13480
13513
  import { jsx as jsx59, jsxs as jsxs53 } from "react/jsx-runtime";
13481
13514
  import { useState as useState36, useEffect as useEffect302 } from "react";
@@ -13486,8 +13519,32 @@ import { jsx as jsx622, jsxs as jsxs56 } from "react/jsx-runtime";
13486
13519
  function cn(...inputs) {
13487
13520
  return twMerge(clsx(inputs));
13488
13521
  }
13489
- var WALLET_CHAIN_TYPE_STORAGE_KEY = "unifold_last_wallet_type";
13522
+ var WALLET_STATE_STORAGE_KEY = "unifold_wallet_state";
13523
+ var LEGACY_WALLET_KEYS = [
13524
+ "unifold_last_wallet_type",
13525
+ "unifold_last_connected_wallet"
13526
+ ];
13490
13527
  var WALLET_USER_DISCONNECTED_KEY = "unifold_wallet_user_disconnected";
13528
+ var SOLANA_WALLET_TYPES = /* @__PURE__ */ new Set([
13529
+ "phantom-solana",
13530
+ "solflare",
13531
+ "backpack",
13532
+ "glow"
13533
+ ]);
13534
+ var ETHEREUM_WALLET_TYPES = /* @__PURE__ */ new Set([
13535
+ "metamask",
13536
+ "phantom-ethereum",
13537
+ "coinbase",
13538
+ "trust",
13539
+ "rainbow",
13540
+ "rabby",
13541
+ "okx"
13542
+ ]);
13543
+ function walletTypeToChain(t12) {
13544
+ if (SOLANA_WALLET_TYPES.has(t12)) return "solana";
13545
+ if (ETHEREUM_WALLET_TYPES.has(t12)) return "ethereum";
13546
+ return void 0;
13547
+ }
13491
13548
  function getUserDisconnectedWallet() {
13492
13549
  if (typeof window === "undefined") return false;
13493
13550
  try {
@@ -13507,26 +13564,35 @@ function setUserDisconnectedWallet(disconnected) {
13507
13564
  } catch {
13508
13565
  }
13509
13566
  }
13510
- function getStoredWalletChainType() {
13567
+ function getStoredWalletState() {
13511
13568
  if (typeof window === "undefined") return void 0;
13512
13569
  try {
13513
- const stored = localStorage.getItem(WALLET_CHAIN_TYPE_STORAGE_KEY);
13514
- if (stored === "ethereum" || stored === "solana") return stored;
13570
+ const raw = localStorage.getItem(WALLET_STATE_STORAGE_KEY);
13571
+ if (!raw) return void 0;
13572
+ const chainType = walletTypeToChain(raw);
13573
+ if (!chainType) {
13574
+ localStorage.removeItem(WALLET_STATE_STORAGE_KEY);
13575
+ return void 0;
13576
+ }
13577
+ return { walletType: raw, chainType };
13515
13578
  } catch {
13579
+ return void 0;
13516
13580
  }
13517
- return void 0;
13518
13581
  }
13519
- function setStoredWalletChainType(chainType) {
13582
+ function setStoredWalletState(walletType) {
13520
13583
  if (typeof window === "undefined") return;
13584
+ if (!walletTypeToChain(walletType)) return;
13521
13585
  try {
13522
- localStorage.setItem(WALLET_CHAIN_TYPE_STORAGE_KEY, chainType);
13586
+ localStorage.setItem(WALLET_STATE_STORAGE_KEY, walletType);
13587
+ for (const key of LEGACY_WALLET_KEYS) localStorage.removeItem(key);
13523
13588
  } catch {
13524
13589
  }
13525
13590
  }
13526
- function clearStoredWalletChainType() {
13591
+ function clearStoredWalletState() {
13527
13592
  if (typeof window === "undefined") return;
13528
13593
  try {
13529
- localStorage.removeItem(WALLET_CHAIN_TYPE_STORAGE_KEY);
13594
+ localStorage.removeItem(WALLET_STATE_STORAGE_KEY);
13595
+ for (const key of LEGACY_WALLET_KEYS) localStorage.removeItem(key);
13530
13596
  } catch {
13531
13597
  }
13532
13598
  }
@@ -13886,6 +13952,36 @@ function ThemeProvider({
13886
13952
  );
13887
13953
  return /* @__PURE__ */ jsx17(ThemeContext.Provider, { value: contextValue, children });
13888
13954
  }
13955
+ function AccentColorOverride({
13956
+ accentColor,
13957
+ accentForeground,
13958
+ children
13959
+ }) {
13960
+ const parent = useTheme();
13961
+ const value = React37.useMemo(() => {
13962
+ if (!accentColor) return parent;
13963
+ const foreground = accentForeground ?? parent.colors.primaryForeground;
13964
+ const nextColors = {
13965
+ ...parent.colors,
13966
+ primary: accentColor,
13967
+ primaryForeground: foreground
13968
+ };
13969
+ const nextComponents = {
13970
+ ...parent.components,
13971
+ button: {
13972
+ ...parent.components.button,
13973
+ primaryBackground: accentColor,
13974
+ primaryText: foreground
13975
+ },
13976
+ card: {
13977
+ ...parent.components.card,
13978
+ iconBackgroundColor: `${accentColor}26`
13979
+ }
13980
+ };
13981
+ return { ...parent, colors: nextColors, components: nextComponents };
13982
+ }, [parent, accentColor, accentForeground]);
13983
+ return /* @__PURE__ */ jsx17(ThemeContext.Provider, { value, children });
13984
+ }
13889
13985
  function useTheme() {
13890
13986
  const context = React37.useContext(ThemeContext);
13891
13987
  if (!context) {
@@ -14089,6 +14185,60 @@ function useDepositAddress(params) {
14089
14185
  // 1s, 2s, 4s (max 10s)
14090
14186
  });
14091
14187
  }
14188
+ var normalize = (value) => value?.toLowerCase();
14189
+ function sourceTokenMatchesDefaultSource(token, defaultSource) {
14190
+ if (!token || !defaultSource.defaultSourceChainType || !defaultSource.defaultSourceChainId) {
14191
+ return false;
14192
+ }
14193
+ if (token.chain_type !== defaultSource.defaultSourceChainType || token.chain_id !== defaultSource.defaultSourceChainId) {
14194
+ return false;
14195
+ }
14196
+ if (defaultSource.defaultSourceTokenAddress && normalize(token.token_address) === normalize(defaultSource.defaultSourceTokenAddress)) {
14197
+ return true;
14198
+ }
14199
+ if (defaultSource.defaultSourceTokenAddress) {
14200
+ return false;
14201
+ }
14202
+ return !!defaultSource.defaultSourceSymbol && normalize(token.symbol) === normalize(defaultSource.defaultSourceSymbol);
14203
+ }
14204
+ function isDefaultSourceBalance(balance, defaultSource) {
14205
+ return isBalanceEligible(balance) && sourceTokenMatchesDefaultSource(getTokenFromBalance(balance), defaultSource);
14206
+ }
14207
+ function compareBalancesWithDefaultSource(a, b, defaultSource) {
14208
+ const aDefault = isDefaultSourceBalance(a, defaultSource);
14209
+ const bDefault = isDefaultSourceBalance(b, defaultSource);
14210
+ if (aDefault && !bDefault) return -1;
14211
+ if (!aDefault && bDefault) return 1;
14212
+ const aEligible = isBalanceEligible(a);
14213
+ const bEligible = isBalanceEligible(b);
14214
+ if (aEligible && !bEligible) return -1;
14215
+ if (!aEligible && bEligible) return 1;
14216
+ return 0;
14217
+ }
14218
+ function resolveDefaultSourceSymbol(supportedTokens, defaultSource) {
14219
+ if (!supportedTokens?.length || !defaultSource.defaultSourceChainType || !defaultSource.defaultSourceChainId) {
14220
+ return null;
14221
+ }
14222
+ if (defaultSource.defaultSourceTokenAddress) {
14223
+ for (const token of supportedTokens) {
14224
+ const matchingChain = token.chains.find(
14225
+ (chain) => chain.chain_type === defaultSource.defaultSourceChainType && chain.chain_id === defaultSource.defaultSourceChainId && normalize(chain.token_address) === normalize(defaultSource.defaultSourceTokenAddress)
14226
+ );
14227
+ if (matchingChain) return token.symbol;
14228
+ }
14229
+ }
14230
+ if (!defaultSource.defaultSourceSymbol) return null;
14231
+ for (const token of supportedTokens) {
14232
+ if (normalize(token.symbol) !== normalize(defaultSource.defaultSourceSymbol)) {
14233
+ continue;
14234
+ }
14235
+ const matchingChain = token.chains.find(
14236
+ (chain) => chain.chain_type === defaultSource.defaultSourceChainType && chain.chain_id === defaultSource.defaultSourceChainId
14237
+ );
14238
+ if (matchingChain) return token.symbol;
14239
+ }
14240
+ return null;
14241
+ }
14092
14242
  function formatUsdFromBalancePercent(maxUsdAmount, percent) {
14093
14243
  if (maxUsdAmount <= 0 || percent < 0) return "";
14094
14244
  const raw = maxUsdAmount * percent / 100;
@@ -14883,6 +15033,7 @@ function useDepositPolling({
14883
15033
  clientSecret,
14884
15034
  depositConfirmationMode = "auto_ui",
14885
15035
  depositWalletId,
15036
+ depositWalletIds,
14886
15037
  enabled = true,
14887
15038
  immediateDirectPolling = false,
14888
15039
  onDepositSuccess,
@@ -15028,21 +15179,25 @@ function useDepositPolling({
15028
15179
  setIsPolling(false);
15029
15180
  };
15030
15181
  }, [userId, publishableKey, clientSecret, enabled]);
15182
+ const pollWalletIdsKey = depositWalletIds && depositWalletIds.length > 0 ? Array.from(new Set(depositWalletIds.filter(Boolean))).join(",") : depositWalletId || "";
15031
15183
  useEffect32(() => {
15032
- if (!pollingEnabled || !depositWalletId) return;
15184
+ if (!pollingEnabled || !pollWalletIdsKey) return;
15185
+ const ids = pollWalletIdsKey.split(",").filter(Boolean);
15033
15186
  const triggerPoll = async () => {
15034
- try {
15035
- await pollDirectExecutions(
15036
- { deposit_wallet_id: depositWalletId },
15037
- publishableKey
15038
- );
15039
- } catch {
15040
- }
15187
+ await Promise.all(
15188
+ ids.map(
15189
+ (id) => pollDirectExecutions(
15190
+ { deposit_wallet_id: id },
15191
+ publishableKey
15192
+ ).catch(() => {
15193
+ })
15194
+ )
15195
+ );
15041
15196
  };
15042
15197
  triggerPoll();
15043
15198
  const interval = setInterval(triggerPoll, POLL_ENDPOINT_INTERVAL_MS);
15044
15199
  return () => clearInterval(interval);
15045
- }, [pollingEnabled, depositWalletId, publishableKey]);
15200
+ }, [pollingEnabled, pollWalletIdsKey, publishableKey]);
15046
15201
  const handleIveDeposited = () => {
15047
15202
  setPollingEnabled(true);
15048
15203
  setShowWaitingUi(true);
@@ -16231,6 +16386,7 @@ function BuyWithCard({
16231
16386
  if (!selectedProvider) return "0.000000";
16232
16387
  return selectedProvider.destination_amount.toFixed(6);
16233
16388
  };
16389
+ const canOpenProviderSelector = !quotesLoading && quotes.length > 1;
16234
16390
  const selectedCurrencyData = fiatCurrencies.find(
16235
16391
  (c) => c.currency_code.toLowerCase() === currency.toLowerCase()
16236
16392
  );
@@ -16416,9 +16572,12 @@ function BuyWithCard({
16416
16572
  /* @__PURE__ */ jsx112(
16417
16573
  "button",
16418
16574
  {
16419
- onClick: () => handleViewChange("quotes"),
16575
+ onClick: () => {
16576
+ if (canOpenProviderSelector) handleViewChange("quotes");
16577
+ },
16420
16578
  disabled: quotesLoading || quotes.length === 0,
16421
- 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",
16579
+ "aria-disabled": !canOpenProviderSelector,
16580
+ 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"}`,
16422
16581
  style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
16423
16582
  children: quotesLoading ? /* @__PURE__ */ jsxs9("div", { className: "uf-text-left uf-w-full uf-animate-pulse", children: [
16424
16583
  /* @__PURE__ */ jsx112(
@@ -16445,7 +16604,7 @@ function BuyWithCard({
16445
16604
  )
16446
16605
  ] })
16447
16606
  ] }) : /* @__PURE__ */ jsxs9("div", { className: "uf-w-full uf-text-left", children: [
16448
- isAutoSelected && /* @__PURE__ */ jsx112(
16607
+ isAutoSelected && canOpenProviderSelector && /* @__PURE__ */ jsx112(
16449
16608
  "div",
16450
16609
  {
16451
16610
  className: "uf-text-xs uf-font-normal uf-mb-2",
@@ -16481,7 +16640,7 @@ function BuyWithCard({
16481
16640
  ),
16482
16641
  selectedProvider.low_kyc === false && /* @__PURE__ */ jsx112("div", { className: "uf-flex uf-items-center uf-gap-1.5 uf-mt-0.5", children: /* @__PURE__ */ jsx112("span", { className: "uf-text-[10px] uf-text-muted-foreground uf-font-normal", children: "No document upload" }) })
16483
16642
  ] }),
16484
- quotes.length > 0 && /* @__PURE__ */ jsx112(
16643
+ canOpenProviderSelector && /* @__PURE__ */ jsx112(
16485
16644
  ChevronRight,
16486
16645
  {
16487
16646
  className: "uf-w-4 uf-h-4 group-hover:uf-text-foreground uf-transition-colors uf-flex-shrink-0",
@@ -18602,70 +18761,106 @@ function identifyEthWallet(provider, hint) {
18602
18761
  }
18603
18762
  return { type: "metamask", name: "Wallet", icon: "metamask" };
18604
18763
  }
18764
+ var EIP6963_ID_TO_WALLET_TYPE = {
18765
+ metamask: "metamask",
18766
+ phantom: "phantom-ethereum",
18767
+ coinbase: "coinbase",
18768
+ trust: "trust",
18769
+ rainbow: "rainbow",
18770
+ rabby: "rabby",
18771
+ okx: "okx"
18772
+ };
18773
+ function inferEthWalletType(provider, walletId) {
18774
+ if (EIP6963_ID_TO_WALLET_TYPE[walletId]) return EIP6963_ID_TO_WALLET_TYPE[walletId];
18775
+ const any = provider;
18776
+ if (provider.isPhantom) return "phantom-ethereum";
18777
+ if (any.isCoinbaseWallet) return "coinbase";
18778
+ if (any.isRabby) return "rabby";
18779
+ if (any.isTrust) return "trust";
18780
+ if (any.isRainbow) return "rainbow";
18781
+ if (any.isOkxWallet) return "okx";
18782
+ if (provider.isMetaMask && !provider.isPhantom) return "metamask";
18783
+ return null;
18784
+ }
18785
+ function solanaCandidate(provider, type, name, icon) {
18786
+ return {
18787
+ walletType: type,
18788
+ detect: async () => {
18789
+ if (!provider) return null;
18790
+ if (provider.isConnected && provider.publicKey) {
18791
+ return { type, name, address: provider.publicKey.toString(), icon };
18792
+ }
18793
+ try {
18794
+ const resp = await provider.connect({ onlyIfTrusted: true });
18795
+ if (resp.publicKey) {
18796
+ return { type, name, address: resp.publicKey.toString(), icon };
18797
+ }
18798
+ } catch {
18799
+ }
18800
+ return null;
18801
+ }
18802
+ };
18803
+ }
18804
+ function ethereumCandidate(provider, walletId) {
18805
+ return {
18806
+ walletType: inferEthWalletType(provider, walletId),
18807
+ detect: async () => {
18808
+ try {
18809
+ const accounts = await provider.request({ method: "eth_accounts" });
18810
+ if (!accounts?.length) return null;
18811
+ const resolved = identifyEthWallet(provider, walletId);
18812
+ return { ...resolved, address: accounts[0] };
18813
+ } catch {
18814
+ return null;
18815
+ }
18816
+ }
18817
+ };
18818
+ }
18819
+ function buildCandidates(win, chainType) {
18820
+ const candidates = [];
18821
+ if (!chainType || chainType === "solana") {
18822
+ candidates.push(
18823
+ solanaCandidate(win.phantom?.solana, "phantom-solana", "Phantom", "phantom"),
18824
+ solanaCandidate(win.solflare, "solflare", "Solflare", "solflare"),
18825
+ solanaCandidate(win.backpack, "backpack", "Backpack", "backpack"),
18826
+ solanaCandidate(win.glow, "glow", "Glow", "glow")
18827
+ );
18828
+ }
18829
+ if (!chainType || chainType === "ethereum") {
18830
+ const seen = /* @__PURE__ */ new Set();
18831
+ const addEth = (provider, walletId) => {
18832
+ if (!provider || seen.has(provider)) return;
18833
+ seen.add(provider);
18834
+ candidates.push(ethereumCandidate(provider, walletId));
18835
+ };
18836
+ for (const { provider, walletId } of getEip6963Providers()) {
18837
+ addEth(
18838
+ provider,
18839
+ walletId === "unknown" ? "default" : walletId
18840
+ );
18841
+ }
18842
+ addEth(win.phantom?.ethereum, "phantom");
18843
+ addEth(win.coinbaseWalletExtension, "coinbase");
18844
+ addEth(win.okxwallet, "okx");
18845
+ addEth(win.trustwallet?.ethereum, "trust");
18846
+ addEth(win.ethereum, "default");
18847
+ }
18848
+ return candidates;
18849
+ }
18605
18850
  async function detectConnectedBrowserWallet(chainType) {
18606
18851
  if (typeof window === "undefined") return null;
18607
18852
  if (getUserDisconnectedWallet()) return null;
18608
18853
  try {
18609
18854
  const win = window;
18610
- if (!chainType || chainType === "solana") {
18611
- const trySilentSolana = async (provider, type, name, icon) => {
18612
- if (!provider) return null;
18613
- if (provider.isConnected && provider.publicKey) {
18614
- return { type, name, address: provider.publicKey.toString(), icon };
18615
- }
18616
- try {
18617
- const resp = await provider.connect({ onlyIfTrusted: true });
18618
- if (resp.publicKey) {
18619
- return { type, name, address: resp.publicKey.toString(), icon };
18620
- }
18621
- } catch {
18622
- }
18623
- return null;
18624
- };
18625
- const solanaCandidates = [
18626
- [win.phantom?.solana, "phantom-solana", "Phantom", "phantom"],
18627
- [win.solflare, "solflare", "Solflare", "solflare"],
18628
- [win.backpack, "backpack", "Backpack", "backpack"],
18629
- [win.glow, "glow", "Glow", "glow"]
18630
- ];
18631
- for (const [provider, type, name, icon] of solanaCandidates) {
18632
- const found = await trySilentSolana(provider, type, name, icon);
18633
- if (found) return found;
18634
- }
18635
- }
18636
- if (!chainType || chainType === "ethereum") {
18637
- const allProviders = [];
18638
- const eip6963 = getEip6963Providers();
18639
- for (const { provider, walletId } of eip6963) {
18640
- allProviders.push({
18641
- provider,
18642
- walletId: walletId === "unknown" ? "default" : walletId
18643
- });
18644
- }
18645
- if (allProviders.length === 0) {
18646
- if (win.phantom?.ethereum) {
18647
- allProviders.push({ provider: win.phantom.ethereum, walletId: "phantom" });
18648
- }
18649
- if (win.okxwallet) {
18650
- allProviders.push({ provider: win.okxwallet, walletId: "okx" });
18651
- }
18652
- if (win.coinbaseWalletExtension) {
18653
- allProviders.push({ provider: win.coinbaseWalletExtension, walletId: "coinbase" });
18654
- }
18655
- if (win.ethereum && !allProviders.some((p) => p.provider === win.ethereum)) {
18656
- allProviders.push({ provider: win.ethereum, walletId: "default" });
18657
- }
18658
- }
18659
- for (const { provider, walletId } of allProviders) {
18660
- if (!provider) continue;
18661
- try {
18662
- const accounts = await provider.request({ method: "eth_accounts" });
18663
- if (!accounts || accounts.length === 0) continue;
18664
- const resolved = identifyEthWallet(provider, walletId);
18665
- return { ...resolved, address: accounts[0] };
18666
- } catch {
18667
- }
18668
- }
18855
+ const candidates = buildCandidates(win, chainType);
18856
+ const preferred = getStoredWalletState();
18857
+ if (preferred && (!chainType || preferred.chainType === chainType)) {
18858
+ const idx = candidates.findIndex((c) => c.walletType === preferred.walletType);
18859
+ if (idx > 0) candidates.unshift(...candidates.splice(idx, 1));
18860
+ }
18861
+ for (const c of candidates) {
18862
+ const found = await c.detect();
18863
+ if (found) return found;
18669
18864
  }
18670
18865
  } catch (error) {
18671
18866
  console.error("[detectConnectedBrowserWallet] detection error:", error);
@@ -20811,6 +21006,7 @@ function BrowserWalletButton({
20811
21006
  if (solanaProvider?.isPhantom) {
20812
21007
  const { publicKey } = await solanaProvider.connect();
20813
21008
  setUserDisconnectedWallet(false);
21009
+ setStoredWalletState("phantom-solana");
20814
21010
  setWallet({
20815
21011
  type: "phantom-solana",
20816
21012
  name: "Phantom",
@@ -20830,8 +21026,10 @@ function BrowserWalletButton({
20830
21026
  if (accounts && accounts.length > 0) {
20831
21027
  setUserDisconnectedWallet(false);
20832
21028
  const isPhantom = ethProvider.isPhantom;
21029
+ const walletType = isPhantom ? "phantom-ethereum" : "metamask";
21030
+ setStoredWalletState(walletType);
20833
21031
  setWallet({
20834
- type: isPhantom ? "phantom-ethereum" : "metamask",
21032
+ type: walletType,
20835
21033
  name: isPhantom ? "Phantom" : "MetaMask",
20836
21034
  address: accounts[0],
20837
21035
  icon: isPhantom ? "phantom" : "metamask"
@@ -21141,7 +21339,11 @@ function CoinbaseConnect({
21141
21339
  onDisconnect,
21142
21340
  skipToHoldings,
21143
21341
  canGoBack = true,
21144
- onExecutionsChange
21342
+ onExecutionsChange,
21343
+ defaultSourceChainType,
21344
+ defaultSourceChainId,
21345
+ defaultSourceTokenAddress,
21346
+ defaultSourceSymbol
21145
21347
  }) {
21146
21348
  const { colors: colors2, fonts, components } = useTheme();
21147
21349
  const { projectConfig } = useProjectConfig({ publishableKey });
@@ -21206,6 +21408,21 @@ function CoinbaseConnect({
21206
21408
  params: defaultTokenParams,
21207
21409
  publishableKey
21208
21410
  });
21411
+ const defaultSourceCurrency = useMemo42(
21412
+ () => resolveDefaultSourceSymbol(supportedTokensData?.data, {
21413
+ defaultSourceChainType,
21414
+ defaultSourceChainId,
21415
+ defaultSourceTokenAddress,
21416
+ defaultSourceSymbol
21417
+ })?.toLowerCase() ?? null,
21418
+ [
21419
+ supportedTokensData,
21420
+ defaultSourceChainType,
21421
+ defaultSourceChainId,
21422
+ defaultSourceTokenAddress,
21423
+ defaultSourceSymbol
21424
+ ]
21425
+ );
21209
21426
  const sortedHoldings = useMemo42(() => {
21210
21427
  const supported = [];
21211
21428
  const unsupported = [];
@@ -21215,13 +21432,42 @@ function CoinbaseConnect({
21215
21432
  if (isSupported) supported.push(account);
21216
21433
  else unsupported.push(account);
21217
21434
  });
21435
+ if (defaultSourceCurrency) {
21436
+ const defaultIndex = supported.findIndex(
21437
+ (account) => account.currency.toLowerCase() === defaultSourceCurrency
21438
+ );
21439
+ if (defaultIndex > 0) {
21440
+ const [defaultHolding] = supported.splice(defaultIndex, 1);
21441
+ supported.unshift(defaultHolding);
21442
+ }
21443
+ }
21218
21444
  return [...supported, ...unsupported];
21219
- }, [holdings, supportedSymbols, exchangeSupportedCurrencies]);
21445
+ }, [
21446
+ holdings,
21447
+ supportedSymbols,
21448
+ exchangeSupportedCurrencies,
21449
+ defaultSourceCurrency
21450
+ ]);
21220
21451
  const selectedHoldingIsSupported = useMemo42(() => {
21221
21452
  if (!selectedHolding) return false;
21222
21453
  const currencyLower = selectedHolding.currency.toLowerCase();
21223
21454
  return (supportedSymbols.size === 0 || supportedSymbols.has(currencyLower)) && (exchangeSupportedCurrencies.size === 0 || exchangeSupportedCurrencies.has(currencyLower));
21224
21455
  }, [selectedHolding, supportedSymbols, exchangeSupportedCurrencies]);
21456
+ useEffect172(() => {
21457
+ if (!defaultSourceCurrency || selectedHolding) return;
21458
+ const defaultHolding = sortedHoldings.find((account) => {
21459
+ const currencyLower = account.currency.toLowerCase();
21460
+ return currencyLower === defaultSourceCurrency && (supportedSymbols.size === 0 || supportedSymbols.has(currencyLower)) && (exchangeSupportedCurrencies.size === 0 || exchangeSupportedCurrencies.has(currencyLower));
21461
+ });
21462
+ if (!defaultHolding) return;
21463
+ setSelectedHolding(defaultHolding);
21464
+ }, [
21465
+ defaultSourceCurrency,
21466
+ selectedHolding,
21467
+ sortedHoldings,
21468
+ supportedSymbols,
21469
+ exchangeSupportedCurrencies
21470
+ ]);
21225
21471
  const exchangeName = selectedExchange?.service_provider_display_name || "Exchange";
21226
21472
  const {
21227
21473
  executions: depositExecutions,
@@ -25370,6 +25616,60 @@ function useDepositQuote(params) {
25370
25616
  retryDelay: (attempt) => Math.min(1e3 * 2 ** attempt, 5e3)
25371
25617
  });
25372
25618
  }
25619
+ function useExternalWallets({
25620
+ publishableKey,
25621
+ enabled = true
25622
+ }) {
25623
+ const { data: wallets = [], isLoading } = useQuery13({
25624
+ queryKey: ["unifold", "external-wallets", publishableKey],
25625
+ queryFn: () => getExternalWallets(publishableKey).then((res) => res.data),
25626
+ enabled: enabled && !!publishableKey,
25627
+ staleTime: 1e3 * 60 * 30,
25628
+ refetchOnMount: false,
25629
+ refetchOnWindowFocus: false
25630
+ });
25631
+ return { wallets, isLoading };
25632
+ }
25633
+ var WALLET_BRAND_COLORS = {
25634
+ phantom: "#AB9FF2",
25635
+ metamask: "#F6851B",
25636
+ coinbase: "#0052FF",
25637
+ trust: "#3375BB",
25638
+ rainbow: "#5B6CFF",
25639
+ rabby: "#7084FF",
25640
+ okx: "#000000"
25641
+ };
25642
+ function normalizeWalletId(type) {
25643
+ return type.replace(/-(ethereum|solana)$/i, "").toLowerCase();
25644
+ }
25645
+ function getWalletBrandColor(type, mode = "dark") {
25646
+ if (!type) return void 0;
25647
+ const id = normalizeWalletId(type);
25648
+ const color = WALLET_BRAND_COLORS[id];
25649
+ if (!color) return void 0;
25650
+ if (id === "okx") return mode === "dark" ? "#FFFFFF" : "#111111";
25651
+ return color;
25652
+ }
25653
+ function getContrastingTextColor(hex) {
25654
+ const c = hex.replace("#", "");
25655
+ if (c.length !== 6) return "#FFFFFF";
25656
+ const r2 = parseInt(c.slice(0, 2), 16);
25657
+ const g = parseInt(c.slice(2, 4), 16);
25658
+ const b = parseInt(c.slice(4, 6), 16);
25659
+ const luminance = (0.299 * r2 + 0.587 * g + 0.114 * b) / 255;
25660
+ return luminance > 0.6 ? "#13111C" : "#FFFFFF";
25661
+ }
25662
+ function isMobileDevice() {
25663
+ if (typeof navigator === "undefined") return false;
25664
+ return /android|iphone|ipad|ipod|mobile/i.test(navigator.userAgent);
25665
+ }
25666
+ function getMobilePlatform() {
25667
+ if (typeof navigator === "undefined") return null;
25668
+ const ua = navigator.userAgent;
25669
+ if (/iphone|ipad|ipod/i.test(ua)) return "ios";
25670
+ if (/android/i.test(ua)) return "android";
25671
+ return null;
25672
+ }
25373
25673
  var WALLET_ICONS = {
25374
25674
  metamask: MetamaskIcon,
25375
25675
  phantom: PhantomIcon,
@@ -26375,18 +26675,46 @@ var WALLET_ICONS3 = {
26375
26675
  backpack: BackpackIcon,
26376
26676
  glow: GlowIcon
26377
26677
  };
26378
- var WALLET_DEFINITIONS = [
26379
- { id: "phantom", name: "Phantom", networks: ["ethereum", "solana"], installUrl: "https://phantom.app/" },
26380
- { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum", "solana"], installUrl: "https://www.coinbase.com/wallet" },
26381
- { id: "trust", name: "Trust Wallet", networks: ["ethereum", "solana"], installUrl: "https://trustwallet.com/" },
26382
- { id: "metamask", name: "MetaMask", networks: ["ethereum"], installUrl: "https://metamask.io/download/" },
26383
- { id: "rainbow", name: "Rainbow", networks: ["ethereum"], installUrl: "https://rainbow.me/" },
26384
- { id: "rabby", name: "Rabby", networks: ["ethereum"], installUrl: "https://rabby.io/" },
26385
- { id: "okx", name: "OKX Wallet", networks: ["ethereum"], installUrl: "https://www.okx.com/web3" },
26386
- { id: "solflare", name: "Solflare", networks: ["solana"], installUrl: "https://solflare.com/" },
26387
- { id: "backpack", name: "Backpack", networks: ["solana"], installUrl: "https://backpack.app/" },
26388
- { id: "glow", name: "Glow", networks: ["solana"], installUrl: "https://glow.app/" }
26678
+ var FALLBACK_WALLET_DEFINITIONS = [
26679
+ { id: "phantom", name: "Phantom", networks: ["ethereum", "solana"], installUrl: "https://phantom.app/", supportsMobileBrowse: true },
26680
+ { id: "coinbase", name: "Coinbase Wallet", networks: ["ethereum", "solana"], installUrl: "https://www.coinbase.com/wallet", supportsMobileBrowse: true },
26681
+ { id: "trust", name: "Trust Wallet", networks: ["ethereum", "solana"], installUrl: "https://trustwallet.com/", supportsMobileBrowse: true },
26682
+ { id: "metamask", name: "MetaMask", networks: ["ethereum"], installUrl: "https://metamask.io/download/", supportsMobileBrowse: true },
26683
+ { id: "rainbow", name: "Rainbow", networks: ["ethereum"], installUrl: "https://rainbow.me/", supportsMobileBrowse: true },
26684
+ { id: "rabby", name: "Rabby", networks: ["ethereum"], installUrl: "https://apps.apple.com/app/rabby-wallet/id6450663781", supportsMobileBrowse: true },
26685
+ { id: "okx", name: "OKX Wallet", networks: ["ethereum"], installUrl: "https://www.okx.com/web3", supportsMobileBrowse: true, mobileBrowsePlatforms: ["ios"] }
26389
26686
  ];
26687
+ function getMobileInstallUrl(walletId, defaultUrl) {
26688
+ if (!isMobileDevice()) return defaultUrl;
26689
+ const ua = typeof navigator !== "undefined" ? navigator.userAgent : "";
26690
+ const isIOS = /iPhone|iPad|iPod/i.test(ua);
26691
+ const stores = {
26692
+ rabby: {
26693
+ ios: "https://apps.apple.com/app/rabby-wallet/id6450663781",
26694
+ android: "https://play.google.com/store/apps/details?id=com.debank.rabbymobile"
26695
+ },
26696
+ glow: {
26697
+ ios: "https://apps.apple.com/us/app/glow-solana-wallet/id1599584512",
26698
+ android: "https://play.google.com/store/apps/details?id=com.luma.wallet.prod"
26699
+ }
26700
+ };
26701
+ const entry = stores[walletId];
26702
+ if (!entry) return defaultUrl;
26703
+ return isIOS ? entry.ios : entry.android;
26704
+ }
26705
+ function normalizeTokenAddress(address) {
26706
+ const normalized = (address ?? "").toLowerCase();
26707
+ if (normalized === "" || normalized === "native" || normalized === "0x0000000000000000000000000000000000000000") {
26708
+ return "native";
26709
+ }
26710
+ return normalized;
26711
+ }
26712
+ function balancesRepresentSameToken(a, b) {
26713
+ const tokenA = getTokenFromBalance(a);
26714
+ const tokenB = getTokenFromBalance(b);
26715
+ if (!tokenA || !tokenB) return false;
26716
+ return tokenA.chain_type === tokenB.chain_type && tokenA.chain_id === tokenB.chain_id && normalizeTokenAddress(tokenA.token_address) === normalizeTokenAddress(tokenB.token_address);
26717
+ }
26390
26718
  function getSolanaProviders() {
26391
26719
  if (typeof window === "undefined") return {};
26392
26720
  const win = window;
@@ -26409,7 +26737,7 @@ function getLegacyEvmProviders() {
26409
26737
  okxEthereum: win.okxwallet
26410
26738
  };
26411
26739
  }
26412
- function detectAvailableWallets(filterChainType) {
26740
+ function detectAvailableWallets(definitions, filterChainType) {
26413
26741
  const solProviders = getSolanaProviders();
26414
26742
  const legacyEvm = getLegacyEvmProviders();
26415
26743
  const eip6963List = getEip6963Providers();
@@ -26435,7 +26763,7 @@ function detectAvailableWallets(filterChainType) {
26435
26763
  return false;
26436
26764
  }
26437
26765
  });
26438
- return WALLET_DEFINITIONS.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
26766
+ return definitions.filter((w) => !filterChainType || w.networks.includes(filterChainType)).map((wallet) => {
26439
26767
  let isInstalled = false;
26440
26768
  const detectedNetworks = [];
26441
26769
  switch (wallet.id) {
@@ -26529,13 +26857,17 @@ function WalletConnect({
26529
26857
  checkoutRemainingBaseUnits,
26530
26858
  stablecoinParity = false,
26531
26859
  productType,
26860
+ defaultSourceChainType,
26861
+ defaultSourceChainId,
26862
+ defaultSourceTokenAddress,
26863
+ defaultSourceSymbol,
26532
26864
  onBack: parentOnBack,
26533
26865
  onClose,
26534
26866
  canGoBack = true,
26535
26867
  depositWalletsLoading = false,
26536
26868
  onExecutionsChange
26537
26869
  }) {
26538
- const { colors: colors2, fonts, components } = useTheme();
26870
+ const { colors: colors2, fonts, components, mode } = useTheme();
26539
26871
  const walletProvidedAtMount = React302.useRef(!!initialWalletInfo && !!initialDepositWallet);
26540
26872
  const [activeWalletInfo, setActiveWalletInfo] = React302.useState(initialWalletInfo ?? null);
26541
26873
  const [activeDepositWallet, setActiveDepositWallet] = React302.useState(initialDepositWallet ?? null);
@@ -26559,7 +26891,37 @@ function WalletConnect({
26559
26891
  setEip6963ProviderCount(providers.length);
26560
26892
  });
26561
26893
  }, []);
26562
- const availableWallets = React302.useMemo(() => detectAvailableWallets(), [eip6963ProviderCount]);
26894
+ const { wallets: backendWallets } = useExternalWallets({ publishableKey });
26895
+ const walletDefinitions = React302.useMemo(
26896
+ () => backendWallets.length > 0 ? backendWallets.map((w) => ({
26897
+ id: w.id,
26898
+ name: w.name,
26899
+ networks: w.chain_types,
26900
+ installUrl: w.install_url,
26901
+ supportsMobileBrowse: w.supports_mobile_browse,
26902
+ mobileBrowsePlatforms: w.mobile_browse_platforms ?? null
26903
+ })) : FALLBACK_WALLET_DEFINITIONS,
26904
+ [backendWallets]
26905
+ );
26906
+ const availableWallets = React302.useMemo(
26907
+ () => detectAvailableWallets(walletDefinitions),
26908
+ [walletDefinitions, eip6963ProviderCount]
26909
+ );
26910
+ const [isMobile, setIsMobile] = React302.useState(false);
26911
+ React302.useEffect(() => {
26912
+ setIsMobile(isMobileDevice());
26913
+ }, []);
26914
+ const mobileDepositAddresses = React302.useMemo(
26915
+ () => (depositWallets ?? []).map((w) => ({ chain_type: w.chain_type, address: w.address })),
26916
+ [depositWallets]
26917
+ );
26918
+ const mobileDepositWalletIds = React302.useMemo(
26919
+ () => (depositWallets ?? []).filter((w) => w.chain_type === "ethereum" || w.chain_type === "solana").map((w) => w.id),
26920
+ [depositWallets]
26921
+ );
26922
+ const [mobileRedirect, setMobileRedirect] = React302.useState(null);
26923
+ const [pendingMobileWallet, setPendingMobileWallet] = React302.useState(null);
26924
+ const [awaitingMobileDeposit, setAwaitingMobileDeposit] = React302.useState(false);
26563
26925
  React302.useEffect(() => {
26564
26926
  if (!standalone || autoResolved || detectingWallet) return;
26565
26927
  if (!detectedWallet) {
@@ -26618,10 +26980,37 @@ function WalletConnect({
26618
26980
  transform: isTransitioning ? "translateY(4px)" : "translateY(0)",
26619
26981
  transition: "opacity 150ms ease, transform 150ms ease"
26620
26982
  };
26621
- const handleWalletClick = (wallet) => {
26622
- if (!wallet.isInstalled) {
26623
- window.open(wallet.installUrl, "_blank", "noopener,noreferrer");
26624
- return;
26983
+ const openMobileWalletBrowse = async (wallet, depositAddresses) => {
26984
+ try {
26985
+ const res = await getWalletMobileDeepLink(
26986
+ wallet.id,
26987
+ depositAddresses,
26988
+ publishableKey
26989
+ );
26990
+ if (res.deeplink) {
26991
+ setMobileRedirect({ walletId: wallet.id, walletName: wallet.name, deeplink: res.deeplink });
26992
+ setAwaitingMobileDeposit(true);
26993
+ transitionTo("mobile_redirect");
26994
+ window.location.href = res.deeplink;
26995
+ return true;
26996
+ }
26997
+ } catch {
26998
+ }
26999
+ return false;
27000
+ };
27001
+ const handleWalletClick = async (wallet) => {
27002
+ if (!wallet.isInstalled) {
27003
+ const platform2 = getMobilePlatform();
27004
+ const platformAllowed = !wallet.mobileBrowsePlatforms || wallet.mobileBrowsePlatforms.includes(platform2 ?? "");
27005
+ if (isMobileDevice() && wallet.supportsMobileBrowse !== false && platformAllowed) {
27006
+ if (mobileDepositAddresses.length === 0) {
27007
+ setPendingMobileWallet(wallet);
27008
+ return;
27009
+ }
27010
+ if (await openMobileWalletBrowse(wallet, mobileDepositAddresses)) return;
27011
+ }
27012
+ window.open(getMobileInstallUrl(wallet.id, wallet.installUrl), "_blank", "noopener,noreferrer");
27013
+ return;
26625
27014
  }
26626
27015
  setSelectedWalletDef(wallet);
26627
27016
  setWalletError(null);
@@ -26636,6 +27025,27 @@ function WalletConnect({
26636
27025
  if (!selectedWalletDef) return;
26637
27026
  handleConnectWallet(selectedWalletDef, network);
26638
27027
  };
27028
+ React302.useEffect(() => {
27029
+ if (!pendingMobileWallet) return;
27030
+ if (mobileDepositAddresses.length > 0) {
27031
+ const wallet = pendingMobileWallet;
27032
+ setPendingMobileWallet(null);
27033
+ void (async () => {
27034
+ if (!await openMobileWalletBrowse(wallet, mobileDepositAddresses)) {
27035
+ window.open(getMobileInstallUrl(wallet.id, wallet.installUrl), "_blank", "noopener,noreferrer");
27036
+ }
27037
+ })();
27038
+ return;
27039
+ }
27040
+ const timeout = setTimeout(() => {
27041
+ setPendingMobileWallet((current) => {
27042
+ if (!current) return null;
27043
+ window.open(getMobileInstallUrl(current.id, current.installUrl), "_blank", "noopener,noreferrer");
27044
+ return null;
27045
+ });
27046
+ }, 8e3);
27047
+ return () => clearTimeout(timeout);
27048
+ }, [pendingMobileWallet, mobileDepositAddresses]);
26639
27049
  const handleConnectWallet = async (wallet, network) => {
26640
27050
  setConnectingNetwork(network);
26641
27051
  transitionTo("connecting");
@@ -26689,6 +27099,7 @@ function WalletConnect({
26689
27099
  metamask: "metamask"
26690
27100
  };
26691
27101
  const walletType = walletIdToType[wallet.id] || "metamask";
27102
+ setStoredWalletState(walletType);
26692
27103
  connectedInfo = { type: walletType, name: wallet.name, address: accounts[0], icon: wallet.id };
26693
27104
  } else {
26694
27105
  const solProviders = getSolanaProviders();
@@ -26717,6 +27128,7 @@ function WalletConnect({
26717
27128
  const response = await provider.connect();
26718
27129
  setUserDisconnectedWallet(false);
26719
27130
  const walletType = wallet.id === "solflare" ? "solflare" : wallet.id === "backpack" ? "backpack" : wallet.id === "glow" ? "glow" : "phantom-solana";
27131
+ setStoredWalletState(walletType);
26720
27132
  connectedInfo = { type: walletType, name: wallet.name, address: response.publicKey.toString(), icon: wallet.id };
26721
27133
  }
26722
27134
  const walletChainType = network === "solana" ? "solana" : "ethereum";
@@ -26778,14 +27190,32 @@ function WalletConnect({
26778
27190
  userId,
26779
27191
  publishableKey,
26780
27192
  clientSecret,
27193
+ // In-tab flow: poll the single connected deposit wallet.
26781
27194
  depositWalletId: activeDepositWallet?.id ?? "",
26782
- enabled: hasSignedTransaction && !!activeDepositWallet,
27195
+ // Mobile redirect flow: the deposit chain isn't known up front, so /poll every
27196
+ // chain's deposit wallet. Detection still happens via the single /query by
27197
+ // external_user_id, which already spans all chains.
27198
+ depositWalletIds: awaitingMobileDeposit ? mobileDepositWalletIds : void 0,
27199
+ enabled: hasSignedTransaction && !!activeDepositWallet || awaitingMobileDeposit,
26783
27200
  onDepositSuccess,
26784
27201
  onDepositError
26785
27202
  });
26786
27203
  React302.useEffect(() => {
26787
27204
  onExecutionsChange?.(depositExecutions);
26788
27205
  }, [depositExecutions, onExecutionsChange]);
27206
+ const latestDepositExecution = React302.useMemo(() => {
27207
+ if (depositExecutions.length === 0) return null;
27208
+ return [...depositExecutions].sort((a, b) => {
27209
+ const ta = a.created_at ? new Date(a.created_at).getTime() : 0;
27210
+ const tb = b.created_at ? new Date(b.created_at).getTime() : 0;
27211
+ return tb - ta;
27212
+ })[0];
27213
+ }, [depositExecutions]);
27214
+ React302.useEffect(() => {
27215
+ if (awaitingMobileDeposit && latestDepositExecution && (viewRef.current === "mobile_redirect" || viewRef.current === "connecting")) {
27216
+ transitionTo("mobile_deposit_status");
27217
+ }
27218
+ }, [awaitingMobileDeposit, latestDepositExecution, transitionTo]);
26789
27219
  React302.useEffect(() => {
26790
27220
  if (!prefillAmountUsd || !tokenChainDetails || view !== "enter_amount") return;
26791
27221
  const minDeposit = tokenChainDetails.minimum_deposit_amount_usd || 0;
@@ -26831,18 +27261,33 @@ function WalletConnect({
26831
27261
  getAddressBalances(activeWalletInfo.address, sct, publishableKey).then((response) => {
26832
27262
  if (cancelled) return;
26833
27263
  const nonZero = response.balances.filter((b) => b.amount !== "0");
26834
- const sorted = [...nonZero].sort((a, b) => {
26835
- const ae = isBalanceEligible(a);
26836
- const be = isBalanceEligible(b);
26837
- if (ae && !be) return -1;
26838
- if (!ae && be) return 1;
26839
- return 0;
26840
- });
27264
+ const defaultSource = {
27265
+ defaultSourceChainType,
27266
+ defaultSourceChainId,
27267
+ defaultSourceTokenAddress,
27268
+ defaultSourceSymbol
27269
+ };
27270
+ const sorted = [...nonZero].sort(
27271
+ (a, b) => compareBalancesWithDefaultSource(a, b, defaultSource)
27272
+ );
26841
27273
  setBalances(sorted);
26842
27274
  const totalUsd = nonZero.reduce((sum, b) => b.amount_usd ? sum + parseFloat(b.amount_usd) : sum, 0);
26843
27275
  if (totalUsd > 0) setTotalBalanceUsd(totalUsd.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 }));
26844
27276
  const eligible = sorted.filter(isBalanceEligible);
26845
- if (eligible.length === 1) setSelectedBalance(eligible[0]);
27277
+ const defaultBalance = sorted.find(
27278
+ (balance) => isDefaultSourceBalance(balance, defaultSource)
27279
+ );
27280
+ setSelectedBalance((current) => {
27281
+ if (current) {
27282
+ const currentInNewBalances = sorted.find(
27283
+ (balance) => balancesRepresentSameToken(balance, current)
27284
+ );
27285
+ if (currentInNewBalances) return currentInNewBalances;
27286
+ }
27287
+ if (defaultBalance) return defaultBalance;
27288
+ if (eligible.length === 1) return eligible[0];
27289
+ return null;
27290
+ });
26846
27291
  }).catch((err) => {
26847
27292
  if (!cancelled) {
26848
27293
  console.error("[WalletConnect] Error fetching balances:", err);
@@ -26854,7 +27299,15 @@ function WalletConnect({
26854
27299
  return () => {
26855
27300
  cancelled = true;
26856
27301
  };
26857
- }, [activeWalletInfo?.address, activeDepositWallet?.chain_type, publishableKey]);
27302
+ }, [
27303
+ activeWalletInfo?.address,
27304
+ activeDepositWallet?.chain_type,
27305
+ publishableKey,
27306
+ defaultSourceChainType,
27307
+ defaultSourceChainId,
27308
+ defaultSourceTokenAddress,
27309
+ defaultSourceSymbol
27310
+ ]);
26858
27311
  const usdToTokenRate = React302.useMemo(() => {
26859
27312
  if (!selectedBalance || !selectedBalance.amount_usd || !selectedToken) return 0;
26860
27313
  const balanceAmount = Number(selectedBalance.amount) / 10 ** selectedToken.decimals;
@@ -26893,6 +27346,16 @@ function WalletConnect({
26893
27346
  setSelectedWalletDef(null);
26894
27347
  setConnectingNetwork(null);
26895
27348
  break;
27349
+ case "mobile_redirect":
27350
+ transitionTo("select_wallet");
27351
+ setMobileRedirect(null);
27352
+ setAwaitingMobileDeposit(false);
27353
+ break;
27354
+ case "mobile_deposit_status":
27355
+ transitionTo("select_wallet");
27356
+ setMobileRedirect(null);
27357
+ setAwaitingMobileDeposit(false);
27358
+ break;
26896
27359
  case "select_token":
26897
27360
  if (walletProvidedAtMount.current) parentOnBack?.();
26898
27361
  else transitionTo("select_wallet");
@@ -27078,33 +27541,40 @@ function WalletConnect({
27078
27541
  return /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
27079
27542
  /* @__PURE__ */ jsx54(DepositHeader, { title: "Connect Wallet", showBack: canGoBack, onBack: handleBack, onClose }),
27080
27543
  /* @__PURE__ */ jsxs48("div", { className: "uf-pb-4", children: [
27081
- /* @__PURE__ */ jsx54("p", { className: "uf-text-sm uf-text-center uf-pb-4", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: "Select a wallet to connect" }),
27082
- /* @__PURE__ */ jsx54("div", { className: "uf-space-y-2", style: { maxHeight: 330, overflowY: "auto" }, children: availableWallets.map((wallet) => /* @__PURE__ */ jsxs48(
27083
- "button",
27084
- {
27085
- onClick: () => handleWalletClick(wallet),
27086
- disabled: isWalletConnecting,
27087
- 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",
27088
- style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
27089
- children: [
27090
- /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
27091
- WALLET_ICONS3[wallet.id] ? /* @__PURE__ */ jsx54(WalletIconWithNetwork, { WalletIcon: WALLET_ICONS3[wallet.id], networks: wallet.networks, size: 40, className: "uf-rounded-lg" }) : /* @__PURE__ */ jsx54("div", { className: "uf-w-10 uf-h-10 uf-rounded-lg uf-bg-gray-500" }),
27092
- /* @__PURE__ */ jsx54("div", { className: "uf-text-sm uf-font-medium", style: { color: components.card.titleColor, fontFamily: fonts.medium }, children: wallet.name })
27093
- ] }),
27094
- wallet.isInstalled ? /* @__PURE__ */ jsx54("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__ */ jsxs48("div", { className: "uf-flex uf-items-center uf-gap-1", children: [
27095
- /* @__PURE__ */ jsx54("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: "Install" }),
27096
- /* @__PURE__ */ jsx54(ExternalLink, { className: "uf-w-3 uf-h-3", style: { color: colors2.foregroundMuted } })
27097
- ] })
27098
- ]
27099
- },
27100
- wallet.id
27101
- )) }),
27544
+ /* @__PURE__ */ jsx54("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" }),
27545
+ /* @__PURE__ */ jsx54("div", { className: "uf-space-y-2", style: { maxHeight: 330, overflowY: "auto" }, children: availableWallets.map((wallet) => {
27546
+ const walletPlatformAllowed = !wallet.mobileBrowsePlatforms || wallet.mobileBrowsePlatforms.includes(getMobilePlatform() ?? "");
27547
+ const showOpenInApp = isMobile && !wallet.isInstalled && wallet.supportsMobileBrowse !== false && walletPlatformAllowed;
27548
+ const isPending = pendingMobileWallet?.id === wallet.id;
27549
+ return /* @__PURE__ */ jsxs48(
27550
+ "button",
27551
+ {
27552
+ onClick: () => void handleWalletClick(wallet),
27553
+ disabled: isWalletConnecting || !!pendingMobileWallet,
27554
+ 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",
27555
+ style: { backgroundColor: components.card.backgroundColor, borderRadius: components.card.borderRadius, border: `${components.card.borderWidth}px solid ${components.card.borderColor}` },
27556
+ children: [
27557
+ /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
27558
+ WALLET_ICONS3[wallet.id] ? /* @__PURE__ */ jsx54(WalletIconWithNetwork, { WalletIcon: WALLET_ICONS3[wallet.id], networks: wallet.networks, size: 40, className: "uf-rounded-lg" }) : /* @__PURE__ */ jsx54("div", { className: "uf-w-10 uf-h-10 uf-rounded-lg uf-bg-gray-500" }),
27559
+ /* @__PURE__ */ jsx54("div", { className: "uf-text-sm uf-font-medium", style: { color: components.card.titleColor, fontFamily: fonts.medium }, children: wallet.name })
27560
+ ] }),
27561
+ isPending ? /* @__PURE__ */ jsx54(LoaderCircle, { className: "uf-w-4 uf-h-4 uf-animate-spin", style: { color: colors2.primary } }) : wallet.isInstalled ? /* @__PURE__ */ jsx54("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__ */ jsxs48("div", { className: "uf-flex uf-items-center uf-gap-1", children: [
27562
+ /* @__PURE__ */ jsx54("span", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: showOpenInApp ? "Open" : "Install" }),
27563
+ /* @__PURE__ */ jsx54(ExternalLink, { className: "uf-w-3 uf-h-3", style: { color: colors2.foregroundMuted } })
27564
+ ] })
27565
+ ]
27566
+ },
27567
+ wallet.id
27568
+ );
27569
+ }) }),
27102
27570
  walletError && /* @__PURE__ */ jsx54("div", { className: "uf-text-center uf-text-sm uf-mt-4 uf-px-4", style: { color: "#ef4444" }, children: walletError })
27103
27571
  ] })
27104
27572
  ] });
27105
27573
  }
27574
+ const preConnectAccent = selectedWalletDef ? getWalletBrandColor(selectedWalletDef.id, mode) : void 0;
27575
+ const preConnectFg = preConnectAccent ? getContrastingTextColor(preConnectAccent) : void 0;
27106
27576
  if (view === "select_network" && selectedWalletDef) {
27107
- return /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
27577
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
27108
27578
  /* @__PURE__ */ jsx54(DepositHeader, { title: "Select Network", showBack: true, onBack: handleBack, onClose }),
27109
27579
  /* @__PURE__ */ jsxs48("div", { className: "uf-pb-4", children: [
27110
27580
  /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-flex-col uf-items-center uf-pb-4", children: [
@@ -27134,10 +27604,10 @@ function WalletConnect({
27134
27604
  )) }),
27135
27605
  walletError && /* @__PURE__ */ jsx54("div", { className: "uf-text-center uf-text-sm uf-mt-4 uf-px-4", style: { color: "#ef4444" }, children: walletError })
27136
27606
  ] })
27137
- ] });
27607
+ ] }) });
27138
27608
  }
27139
27609
  if (view === "connecting") {
27140
- return /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
27610
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
27141
27611
  /* @__PURE__ */ jsx54(DepositHeader, { title: "Connecting...", showBack: true, onBack: handleBack, onClose }),
27142
27612
  /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-16", children: [
27143
27613
  /* @__PURE__ */ jsx54(LoaderCircle, { className: "uf-w-12 uf-h-12 uf-animate-spin uf-mb-4", style: { color: colors2.primary } }),
@@ -27148,24 +27618,132 @@ function WalletConnect({
27148
27618
  ] }),
27149
27619
  /* @__PURE__ */ jsx54("div", { className: "uf-text-sm uf-mt-2", style: { color: colors2.foregroundMuted }, children: "Please approve the connection in your wallet" })
27150
27620
  ] })
27151
- ] });
27621
+ ] }) });
27622
+ }
27623
+ if (view === "mobile_redirect" && mobileRedirect) {
27624
+ const Icon22 = WALLET_ICONS3[mobileRedirect.walletId];
27625
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
27626
+ /* @__PURE__ */ jsx54(DepositHeader, { title: mobileRedirect.walletName, showBack: true, onBack: handleBack, onClose }),
27627
+ /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-px-6 uf-py-10", children: [
27628
+ Icon22 ? /* @__PURE__ */ jsx54(Icon22, { size: 64, className: "uf-rounded-2xl uf-mb-5" }) : /* @__PURE__ */ jsx54("div", { className: "uf-w-16 uf-h-16 uf-rounded-2xl uf-bg-gray-500 uf-mb-5" }),
27629
+ /* @__PURE__ */ jsxs48(
27630
+ "div",
27631
+ {
27632
+ className: "uf-text-base uf-font-medium uf-text-center uf-mb-1",
27633
+ style: { color: colors2.foreground, fontFamily: fonts.medium },
27634
+ children: [
27635
+ "Continue in ",
27636
+ mobileRedirect.walletName
27637
+ ]
27638
+ }
27639
+ ),
27640
+ /* @__PURE__ */ jsxs48(
27641
+ "div",
27642
+ {
27643
+ className: "uf-text-sm uf-text-center uf-mb-6",
27644
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
27645
+ children: [
27646
+ "Complete your deposit in the ",
27647
+ mobileRedirect.walletName,
27648
+ " app"
27649
+ ]
27650
+ }
27651
+ ),
27652
+ /* @__PURE__ */ jsxs48(
27653
+ "button",
27654
+ {
27655
+ type: "button",
27656
+ onClick: () => {
27657
+ window.location.href = mobileRedirect.deeplink;
27658
+ },
27659
+ 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",
27660
+ style: {
27661
+ backgroundColor: components.card.backgroundColor,
27662
+ borderRadius: components.card.borderRadius,
27663
+ border: `${components.card.borderWidth}px solid ${components.card.borderColor}`,
27664
+ color: components.card.titleColor,
27665
+ fontFamily: fonts.medium
27666
+ },
27667
+ children: [
27668
+ /* @__PURE__ */ jsx54(ExternalLink, { className: "uf-w-4 uf-h-4", style: { color: components.card.iconColor } }),
27669
+ /* @__PURE__ */ jsxs48("span", { className: "uf-text-sm uf-font-medium", children: [
27670
+ "Open in ",
27671
+ mobileRedirect.walletName
27672
+ ] })
27673
+ ]
27674
+ }
27675
+ ),
27676
+ awaitingMobileDeposit && /* @__PURE__ */ jsxs48("div", { className: "uf-flex uf-items-center uf-justify-center uf-gap-2 uf-mt-6", children: [
27677
+ /* @__PURE__ */ jsx54(
27678
+ LoaderCircle,
27679
+ {
27680
+ className: "uf-w-4 uf-h-4 uf-animate-spin",
27681
+ style: { color: colors2.foregroundMuted }
27682
+ }
27683
+ ),
27684
+ /* @__PURE__ */ jsx54(
27685
+ "span",
27686
+ {
27687
+ className: "uf-text-sm",
27688
+ style: { color: colors2.foregroundMuted, fontFamily: fonts.regular },
27689
+ children: "Checking for deposit..."
27690
+ }
27691
+ )
27692
+ ] })
27693
+ ] })
27694
+ ] }) });
27695
+ }
27696
+ if (view === "mobile_deposit_status" && latestDepositExecution) {
27697
+ const isComplete = latestDepositExecution.status === ExecutionStatus.SUCCEEDED;
27698
+ const isFailed = latestDepositExecution.status === ExecutionStatus.FAILED;
27699
+ const title = isComplete ? "Payment Complete" : isFailed ? "Payment Failed" : "Payment Processing";
27700
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: preConnectAccent, accentForeground: preConnectFg, children: /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
27701
+ /* @__PURE__ */ jsx54(
27702
+ DepositHeader,
27703
+ {
27704
+ title,
27705
+ showBack: false,
27706
+ onClose: isComplete && onDone ? onDone : onClose
27707
+ }
27708
+ ),
27709
+ /* @__PURE__ */ jsx54(DepositDetailContent, { execution: latestDepositExecution }),
27710
+ isComplete && /* @__PURE__ */ jsx54("div", { className: "uf-flex uf-gap-2 uf-px-2 uf-pt-4 uf-pb-4", children: /* @__PURE__ */ jsx54(
27711
+ "button",
27712
+ {
27713
+ type: "button",
27714
+ onClick: onDone ? onDone : onNewDeposit ? onNewDeposit : onClose ?? (() => {
27715
+ }),
27716
+ className: "uf-flex-1 uf-py-4 uf-text-sm uf-font-medium uf-transition-opacity hover:uf-opacity-80",
27717
+ style: {
27718
+ backgroundColor: colors2.primary,
27719
+ color: colors2.primaryForeground,
27720
+ fontFamily: fonts.medium,
27721
+ borderRadius: components.button.borderRadius,
27722
+ border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
27723
+ },
27724
+ children: "Done"
27725
+ }
27726
+ ) })
27727
+ ] }) });
27152
27728
  }
27153
27729
  if (!hasWallet) return null;
27730
+ const walletAccent = getWalletBrandColor(walletInfo.type, mode);
27731
+ const walletAccentForeground = walletAccent ? getContrastingTextColor(walletAccent) : void 0;
27154
27732
  if (view === "select_token") {
27155
- return /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(SelectTokenView, { walletInfo, projectName, assetCdnUrl, balances, isLoading, error, selectedBalance, totalBalanceUsd, onTokenSelect: handleTokenSelect, onContinue: handleContinueToAmount, onBack: handleBack, onClose: onClose ?? (() => {
27156
- }), onDisconnectWallet: onWalletDisconnect ? () => void handleDisconnect() : void 0, isDisconnectingWallet, checkoutAmountUsd, checkoutReceivedUsd }) });
27733
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(SelectTokenView, { walletInfo, projectName, assetCdnUrl, balances, isLoading, error, selectedBalance, totalBalanceUsd, onTokenSelect: handleTokenSelect, onContinue: handleContinueToAmount, onBack: handleBack, onClose: onClose ?? (() => {
27734
+ }), onDisconnectWallet: onWalletDisconnect ? () => void handleDisconnect() : void 0, isDisconnectingWallet, checkoutAmountUsd, checkoutReceivedUsd }) }) });
27157
27735
  }
27158
27736
  if (view === "enter_amount" && selectedToken && selectedBalance) {
27159
- return /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(EnterAmountView, { walletInfo, selectedBalance, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, inputUsdNum, maxUsdAmount, isValidAmount, error, onAmountChange: setAmountUsd, onMaxClick: handleMaxClick, onReview: handleReview, onBack: handleBack, onClose: onClose ?? (() => {
27160
- }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd }) });
27737
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(EnterAmountView, { walletInfo, selectedBalance, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, inputUsdNum, maxUsdAmount, isValidAmount, error, onAmountChange: setAmountUsd, onMaxClick: handleMaxClick, onReview: handleReview, onBack: handleBack, onClose: onClose ?? (() => {
27738
+ }), quickSelectMode: amountQuickSelect, checkoutAmountUsd, checkoutReceivedUsd }) }) });
27161
27739
  }
27162
27740
  if (view === "review" && selectedToken) {
27163
- return /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(ReviewView, { walletInfo, recipientAddress, assetCdnUrl, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, loadingTokenDetails, showTransactionDetails, isConfirming, error, onToggleDetails: () => setShowTransactionDetails(!showTransactionDetails), onConfirm: handleConfirm, onBack: handleBack, onClose: onClose ?? (() => {
27164
- }) }) });
27741
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(ReviewView, { walletInfo, recipientAddress, assetCdnUrl, selectedToken, amountUsd, formattedTokenAmount, tokenChainDetails, loadingTokenDetails, showTransactionDetails, isConfirming, error, onToggleDetails: () => setShowTransactionDetails(!showTransactionDetails), onConfirm: handleConfirm, onBack: handleBack, onClose: onClose ?? (() => {
27742
+ }) }) }) });
27165
27743
  }
27166
27744
  if (view === "confirming") {
27167
- return /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(ConfirmingView, { isConfirming, onClose: onClose ?? (() => {
27168
- }), executions: depositExecutions, isPolling, onNewDeposit, onDone, paymentIntentStatus, amountReceivedUsd: checkoutReceivedUsd, amountReceivedUsdAtSubmission: receivedUsdAtSubmission }) });
27745
+ return /* @__PURE__ */ jsx54(AccentColorOverride, { accentColor: walletAccent, accentForeground: walletAccentForeground, children: /* @__PURE__ */ jsx54("div", { style: viewTransitionStyle, children: /* @__PURE__ */ jsx54(ConfirmingView, { isConfirming, onClose: onClose ?? (() => {
27746
+ }), executions: depositExecutions, isPolling, onNewDeposit, onDone, paymentIntentStatus, amountReceivedUsd: checkoutReceivedUsd, amountReceivedUsdAtSubmission: receivedUsdAtSubmission }) }) });
27169
27747
  }
27170
27748
  return null;
27171
27749
  }
@@ -27209,16 +27787,17 @@ function DepositModal({
27209
27787
  defaultSourceChainId,
27210
27788
  defaultSourceTokenAddress,
27211
27789
  defaultSourceSymbol,
27212
- hideDepositTracker = false,
27790
+ hideDepositTracker,
27213
27791
  showBalanceHeader = false,
27214
27792
  transferInputVariant = "double_input",
27215
27793
  depositConfirmationMode = "auto_ui",
27216
- enableConnectWallet = false,
27794
+ enableTransferCrypto,
27795
+ enableConnectWallet,
27217
27796
  browserWalletAmountQuickSelect = "percentage",
27218
27797
  enablePayWithExchange,
27219
27798
  enableFiatOnramp,
27220
- enableConnectExchange = false,
27221
- enableCashApp = false,
27799
+ enableConnectExchange,
27800
+ enableCashApp,
27222
27801
  hideDepositFlowInfo = false,
27223
27802
  hideDisplayDescription = false,
27224
27803
  onDepositSuccess,
@@ -27236,12 +27815,13 @@ function DepositModal({
27236
27815
  const { colors: colors2, fonts, components } = useTheme();
27237
27816
  const effectiveInitialScreen = useMemo10(() => {
27238
27817
  const s = initialScreen ?? "main";
27239
- if (s === "tracker" && hideDepositTracker) return "main";
27240
- if (s === "cashapp" && !enableCashApp) return "main";
27818
+ if (s === "tracker" && hideDepositTracker === true) return "main";
27819
+ if (s === "cashapp" && enableCashApp === false) return "main";
27241
27820
  if (s === "card" && enableFiatOnramp === false) return "main";
27242
27821
  if (s === "pay_with_exchange") return enablePayWithExchange === false ? "main" : "exchange";
27243
- if (s === "exchange_connect") return enableConnectExchange ? "coinbase_connect" : "main";
27244
- if (s === "wallet_connect") return enableConnectWallet ? "wallet_connect" : "main";
27822
+ if (s === "exchange_connect")
27823
+ return enableConnectExchange === false ? "main" : "coinbase_connect";
27824
+ if (s === "wallet_connect") return enableConnectWallet === false ? "main" : "wallet_connect";
27245
27825
  return s;
27246
27826
  }, [
27247
27827
  initialScreen,
@@ -27270,26 +27850,36 @@ function DepositModal({
27270
27850
  const [browserWalletModalOpen, setBrowserWalletModalOpen] = useState32(false);
27271
27851
  const [browserWalletInfo, setBrowserWalletInfo] = useState32(null);
27272
27852
  const [walletSelectionModalOpen, setWalletSelectionModalOpen] = useState32(false);
27273
- const [browserWalletChainType, setBrowserWalletChainType] = useState32(() => getStoredWalletChainType());
27853
+ const [browserWalletChainType, setBrowserWalletChainType] = useState32(() => getStoredWalletState()?.chainType);
27274
27854
  const [quotesCount, setQuotesCount] = useState32(0);
27275
27855
  const [allExecutions, setAllExecutions] = useState32([]);
27276
27856
  const [selectedExecution, setSelectedExecution] = useState32(null);
27277
27857
  const [depositExecutions, setDepositExecutions] = useState32([]);
27278
- const isMobileView = useIsMobileViewport();
27858
+ const { projectConfig } = useProjectConfig({
27859
+ publishableKey,
27860
+ enabled: open
27861
+ });
27862
+ const showTransferCrypto = enableTransferCrypto ?? projectConfig?.transfer_crypto?.enabled ?? true;
27863
+ const showConnectWallet = enableConnectWallet ?? projectConfig?.connect_wallet?.enabled ?? true;
27864
+ const showPayWithExchange = enablePayWithExchange ?? projectConfig?.pay_with_exchange?.enabled ?? true;
27865
+ const showFiatOnramp = enableFiatOnramp ?? projectConfig?.fiat_onramp?.enabled ?? true;
27866
+ const showConnectExchange = enableConnectExchange ?? projectConfig?.connect_exchange?.enabled ?? true;
27867
+ const showCashApp = enableCashApp ?? projectConfig?.cash_app?.enabled ?? true;
27868
+ const showDepositTracker = hideDepositTracker ? false : projectConfig?.deposit_tracker?.enabled ?? true;
27279
27869
  const [integrationExchanges, setIntegrationExchanges] = useState32([]);
27280
27870
  useEffect26(() => {
27281
- if (!enableConnectExchange || !open) return;
27871
+ if (!showConnectExchange || !open) return;
27282
27872
  getIntegrationExchanges(publishableKey).then((res) => setIntegrationExchanges(res.data)).catch(() => {
27283
27873
  });
27284
- }, [enableConnectExchange, open, publishableKey]);
27874
+ }, [showConnectExchange, open, publishableKey]);
27285
27875
  const [connectedExchange, setConnectedExchange] = useState32(() => {
27286
- if (!enableConnectExchange) return null;
27876
+ if (!showConnectExchange) return null;
27287
27877
  const stored = getStoredIntegrationToken(IntegrationProvider.COINBASE);
27288
27878
  if (!stored) return null;
27289
27879
  return { name: "Coinbase", iconUrl: void 0, balanceUsd: null, isLoading: true };
27290
27880
  });
27291
27881
  useEffect26(() => {
27292
- if (!enableConnectExchange || !open || view !== "main") return;
27882
+ if (!showConnectExchange || !open || view !== "main") return;
27293
27883
  const stored = getStoredIntegrationToken(IntegrationProvider.COINBASE);
27294
27884
  if (!stored) {
27295
27885
  setConnectedExchange(null);
@@ -27324,7 +27914,7 @@ function DepositModal({
27324
27914
  setConnectedExchange(null);
27325
27915
  }
27326
27916
  });
27327
- }, [enableConnectExchange, open, view, publishableKey]);
27917
+ }, [showConnectExchange, open, view, publishableKey]);
27328
27918
  useEffect26(() => {
27329
27919
  if (!connectedExchange || integrationExchanges.length === 0) return;
27330
27920
  const cbExchange = integrationExchanges.find(
@@ -27363,18 +27953,33 @@ function DepositModal({
27363
27953
  setResolvedTheme(theme);
27364
27954
  }
27365
27955
  }, [theme]);
27366
- const { projectConfig } = useProjectConfig({
27367
- publishableKey,
27368
- enabled: open
27369
- });
27370
- const showPayWithExchange = enablePayWithExchange ?? projectConfig?.pay_with_exchange?.enabled ?? true;
27371
- const showFiatOnramp = enableFiatOnramp ?? projectConfig?.fiat_onramp?.enabled ?? true;
27372
27956
  useEffect26(() => {
27373
27957
  if (view === "card" && !showFiatOnramp) {
27374
27958
  setView("main");
27375
27959
  setCardView("amount");
27960
+ } else if (view === "transfer" && !showTransferCrypto) {
27961
+ setView("main");
27962
+ } else if (view === "exchange" && !showPayWithExchange) {
27963
+ setView("main");
27964
+ } else if (view === "cashapp" && !showCashApp) {
27965
+ setView("main");
27966
+ } else if (view === "tracker" && !showDepositTracker) {
27967
+ setView("main");
27968
+ } else if (view === "coinbase_connect" && !showConnectExchange) {
27969
+ setView("main");
27970
+ } else if (view === "wallet_connect" && !showConnectWallet) {
27971
+ setView("main");
27376
27972
  }
27377
- }, [view, showFiatOnramp]);
27973
+ }, [
27974
+ view,
27975
+ showFiatOnramp,
27976
+ showTransferCrypto,
27977
+ showPayWithExchange,
27978
+ showCashApp,
27979
+ showDepositTracker,
27980
+ showConnectExchange,
27981
+ showConnectWallet
27982
+ ]);
27378
27983
  useEffect26(() => {
27379
27984
  if (view === "exchange" && !showPayWithExchange) {
27380
27985
  setView("main");
@@ -27464,7 +28069,7 @@ function DepositModal({
27464
28069
  depositPrerequisiteBody = standaloneNeedsDepositPrereq ? /* @__PURE__ */ jsx55(SkeletonButton, { variant: "with-icons" }) : /* @__PURE__ */ jsxs49(Fragment11, { children: [
27465
28070
  /* @__PURE__ */ jsx55(SkeletonButton, { variant: "with-icons" }),
27466
28071
  /* @__PURE__ */ jsx55(SkeletonButton, { variant: "with-icons" }),
27467
- !hideDepositTracker && /* @__PURE__ */ jsx55(SkeletonButton, {})
28072
+ showDepositTracker && /* @__PURE__ */ jsx55(SkeletonButton, {})
27468
28073
  ] });
27469
28074
  } else if (countryError) {
27470
28075
  depositPrerequisiteBody = /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-8 uf-px-4 uf-text-center", children: [
@@ -27496,7 +28101,7 @@ function DepositModal({
27496
28101
  const themeClass = resolvedTheme === "dark" ? "uf-dark" : "";
27497
28102
  const handleWalletDisconnect = () => {
27498
28103
  setUserDisconnectedWallet(true);
27499
- clearStoredWalletChainType();
28104
+ clearStoredWalletState();
27500
28105
  setBrowserWalletChainType(void 0);
27501
28106
  setBrowserWalletInfo(null);
27502
28107
  setBrowserWalletModalOpen(false);
@@ -27574,7 +28179,7 @@ function DepositModal({
27574
28179
  };
27575
28180
  const handleBrowserWalletClick = (walletInfo) => {
27576
28181
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
27577
- setStoredWalletChainType(walletChainType);
28182
+ setStoredWalletState(walletInfo.type);
27578
28183
  setBrowserWalletChainType(walletChainType);
27579
28184
  const matchingDepositWallet = wallets.find(
27580
28185
  (w) => w.chain_type === walletChainType
@@ -27605,7 +28210,7 @@ function DepositModal({
27605
28210
  };
27606
28211
  const handleWalletConnected = (walletInfo) => {
27607
28212
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
27608
- setStoredWalletChainType(walletChainType);
28213
+ setStoredWalletState(walletInfo.type);
27609
28214
  setBrowserWalletChainType(walletChainType);
27610
28215
  const matchingDepositWallet = wallets.find(
27611
28216
  (w) => w.chain_type === walletChainType
@@ -27645,7 +28250,7 @@ function DepositModal({
27645
28250
  open: hideOverlay || open,
27646
28251
  onOpenChange: hideOverlay ? void 0 : handleClose,
27647
28252
  modal: !hideOverlay,
27648
- children: /* @__PURE__ */ jsx55(
28253
+ children: /* @__PURE__ */ jsxs49(
27649
28254
  DialogContent2,
27650
28255
  {
27651
28256
  ref: hideOverlay ? containerCallbackRef : void 0,
@@ -27654,378 +28259,389 @@ function DepositModal({
27654
28259
  style: { backgroundColor: colors2.background },
27655
28260
  onPointerDownOutside: (e) => e.preventDefault(),
27656
28261
  onInteractOutside: (e) => e.preventDefault(),
27657
- children: /* @__PURE__ */ jsx55(ThemeStyleInjector, { children: view === "main" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
27658
- /* @__PURE__ */ jsx55(
27659
- DepositHeader,
27660
- {
27661
- title: modalTitle || "Deposit",
27662
- showClose: !hideOverlay,
27663
- onClose: handleClose,
27664
- showBalance: showBalanceHeader,
27665
- balanceAddress: recipientAddress,
27666
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
27667
- balanceChainId: destinationChainId,
27668
- balanceTokenAddress: destinationTokenAddress,
27669
- projectName: projectConfig?.project_name,
27670
- publishableKey
27671
- }
27672
- ),
27673
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
27674
- /* @__PURE__ */ jsx55("div", { className: "uf-space-y-3", children: depositPrerequisiteBody ?? /* @__PURE__ */ jsxs49(Fragment11, { children: [
27675
- /* @__PURE__ */ jsx55(
27676
- TransferCryptoButton,
27677
- {
27678
- onClick: () => setView("transfer"),
27679
- title: transferCryptoTitle,
27680
- subtitle: t7.transferCrypto.subtitle,
27681
- featuredTokens: projectConfig?.transfer_crypto.networks
27682
- }
27683
- ),
27684
- enableConnectWallet && !isMobileView && /* @__PURE__ */ jsx55(
27685
- BrowserWalletButton,
28262
+ children: [
28263
+ /* @__PURE__ */ jsx55(DialogTitle2, { className: "uf-sr-only", children: modalTitle || "Deposit" }),
28264
+ /* @__PURE__ */ jsx55(ThemeStyleInjector, { children: view === "main" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
28265
+ /* @__PURE__ */ jsx55(
28266
+ DepositHeader,
28267
+ {
28268
+ title: modalTitle || "Deposit",
28269
+ showClose: !hideOverlay,
28270
+ onClose: handleClose,
28271
+ showBalance: showBalanceHeader,
28272
+ balanceAddress: recipientAddress,
28273
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
28274
+ balanceChainId: destinationChainId,
28275
+ balanceTokenAddress: destinationTokenAddress,
28276
+ projectName: projectConfig?.project_name,
28277
+ publishableKey
28278
+ }
28279
+ ),
28280
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28281
+ /* @__PURE__ */ jsx55("div", { className: "uf-space-y-3", children: depositPrerequisiteBody ?? /* @__PURE__ */ jsxs49(Fragment11, { children: [
28282
+ showTransferCrypto && /* @__PURE__ */ jsx55(
28283
+ TransferCryptoButton,
28284
+ {
28285
+ onClick: () => setView("transfer"),
28286
+ title: transferCryptoTitle,
28287
+ subtitle: t7.transferCrypto.subtitle,
28288
+ featuredTokens: projectConfig?.transfer_crypto.networks
28289
+ }
28290
+ ),
28291
+ showConnectWallet && /* @__PURE__ */ jsx55(
28292
+ BrowserWalletButton,
28293
+ {
28294
+ onClick: handleBrowserWalletClick,
28295
+ onConnectClick: handleWalletConnectClick,
28296
+ onDisconnect: handleWalletDisconnect,
28297
+ chainType: browserWalletChainType,
28298
+ publishableKey,
28299
+ featuredWallets: projectConfig?.connect_wallet?.wallets
28300
+ }
28301
+ ),
28302
+ showFiatOnramp && /* @__PURE__ */ jsx55(
28303
+ DepositWithCardButton,
28304
+ {
28305
+ onClick: () => setView("card"),
28306
+ title: depositWithCardTitle,
28307
+ subtitle: t7.depositWithCard.subtitle,
28308
+ paymentNetworks: projectConfig?.payment_networks.networks
28309
+ }
28310
+ ),
28311
+ showPayWithExchange && /* @__PURE__ */ jsx55(
28312
+ PayWithExchangeButton,
28313
+ {
28314
+ onClick: () => setView("exchange"),
28315
+ title: payWithExchangeTitle,
28316
+ subtitle: t7.payWithExchange.subtitle,
28317
+ exchanges,
28318
+ loading: exchangesLoading
28319
+ }
28320
+ ),
28321
+ showConnectExchange && connectedExchange && /* @__PURE__ */ jsx55(
28322
+ ConnectExchangeButton,
28323
+ {
28324
+ onClick: () => {
28325
+ setCoinbaseSkipToHoldings(true);
28326
+ setView("coinbase_connect");
28327
+ },
28328
+ onDisconnect: handleExchangeDisconnect,
28329
+ title: i18n2.connectExchange.title,
28330
+ subtitle: i18n2.connectExchange.subtitle,
28331
+ exchanges: integrationExchanges,
28332
+ connectedExchange
28333
+ }
28334
+ ),
28335
+ showConnectExchange && !connectedExchange && /* @__PURE__ */ jsx55(
28336
+ ConnectExchangeButton,
28337
+ {
28338
+ onClick: () => {
28339
+ setCoinbaseSkipToHoldings(false);
28340
+ setView("coinbase_connect");
28341
+ },
28342
+ title: i18n2.connectExchange.title,
28343
+ subtitle: i18n2.connectExchange.subtitle,
28344
+ exchanges: integrationExchanges
28345
+ }
28346
+ ),
28347
+ showCashApp && /* @__PURE__ */ jsx55(
28348
+ CashAppButton,
28349
+ {
28350
+ onClick: () => setView("cashapp"),
28351
+ title: "Pay with Cash App",
28352
+ subtitle: "Deposit via Cash App",
28353
+ iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
28354
+ }
28355
+ ),
28356
+ showDepositTracker && /* @__PURE__ */ jsx55(
28357
+ DepositTrackerButton,
28358
+ {
28359
+ onClick: () => {
28360
+ setAllExecutions(depositExecutions);
28361
+ setView("tracker");
28362
+ },
28363
+ title: depositTrackerTitle,
28364
+ subtitle: depositTrackerSubTitle,
28365
+ badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
28366
+ }
28367
+ )
28368
+ ] }) }),
28369
+ depositPoweredByFooter
28370
+ ] })
28371
+ ] }) : view === "transfer" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
28372
+ /* @__PURE__ */ jsx55(
28373
+ DepositHeader,
28374
+ {
28375
+ title: transferCryptoTitle,
28376
+ showBack: showBackTransfer,
28377
+ onBack: handleBack,
28378
+ onClose: handleClose,
28379
+ showBalance: showBalanceHeader,
28380
+ balanceAddress: recipientAddress,
28381
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
28382
+ balanceChainId: destinationChainId,
28383
+ balanceTokenAddress: destinationTokenAddress,
28384
+ projectName: projectConfig?.project_name,
28385
+ publishableKey
28386
+ }
28387
+ ),
28388
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28389
+ standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ jsx55("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : transferInputVariant === "single_input" ? /* @__PURE__ */ jsx55(
28390
+ TransferCryptoSingleInput,
27686
28391
  {
27687
- onClick: handleBrowserWalletClick,
27688
- onConnectClick: handleWalletConnectClick,
27689
- onDisconnect: handleWalletDisconnect,
27690
- chainType: browserWalletChainType,
28392
+ userId,
27691
28393
  publishableKey,
27692
- featuredWallets: projectConfig?.connect_wallet?.wallets
28394
+ recipientAddress,
28395
+ destinationChainType,
28396
+ destinationChainId,
28397
+ destinationTokenAddress,
28398
+ defaultSourceChainType,
28399
+ defaultSourceChainId,
28400
+ defaultSourceTokenAddress,
28401
+ defaultSourceSymbol,
28402
+ depositConfirmationMode,
28403
+ onExecutionsChange: setDepositExecutions,
28404
+ onDepositSuccess,
28405
+ onDepositError,
28406
+ wallets
27693
28407
  }
27694
- ),
27695
- showFiatOnramp && /* @__PURE__ */ jsx55(
27696
- DepositWithCardButton,
28408
+ ) : /* @__PURE__ */ jsx55(
28409
+ TransferCryptoDoubleInput,
27697
28410
  {
27698
- onClick: () => setView("card"),
27699
- title: depositWithCardTitle,
27700
- subtitle: t7.depositWithCard.subtitle,
27701
- paymentNetworks: projectConfig?.payment_networks.networks
28411
+ userId,
28412
+ publishableKey,
28413
+ recipientAddress,
28414
+ destinationChainType,
28415
+ destinationChainId,
28416
+ destinationTokenAddress,
28417
+ defaultSourceChainType,
28418
+ defaultSourceChainId,
28419
+ defaultSourceTokenAddress,
28420
+ defaultSourceSymbol,
28421
+ depositConfirmationMode,
28422
+ onExecutionsChange: setDepositExecutions,
28423
+ onDepositSuccess,
28424
+ onDepositError,
28425
+ wallets
27702
28426
  }
27703
28427
  ),
27704
- showPayWithExchange && /* @__PURE__ */ jsx55(
27705
- PayWithExchangeButton,
28428
+ depositPoweredByFooter
28429
+ ] })
28430
+ ] }) : view === "tracker" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
28431
+ /* @__PURE__ */ jsx55(
28432
+ DepositHeader,
28433
+ {
28434
+ title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
28435
+ showBack: showBackTracker,
28436
+ onBack: handleBack,
28437
+ onClose: handleClose
28438
+ }
28439
+ ),
28440
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28441
+ /* @__PURE__ */ jsx55("div", { className: "uf-h-[460px] uf-overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: selectedExecution ? /* @__PURE__ */ jsx55(DepositDetailContent, { execution: selectedExecution }) : /* @__PURE__ */ jsx55("div", { className: "uf-space-y-2 uf-pb-8", children: allExecutions.length === 0 ? /* @__PURE__ */ jsx55("div", { className: "uf-py-8 uf-px-4 uf-text-center", children: /* @__PURE__ */ jsx55(
28442
+ "div",
27706
28443
  {
27707
- onClick: () => setView("exchange"),
27708
- title: payWithExchangeTitle,
27709
- subtitle: t7.payWithExchange.subtitle,
27710
- exchanges,
27711
- loading: exchangesLoading
28444
+ className: "uf-text-sm",
28445
+ style: { color: components.container.subtitleColor, fontFamily: fonts.regular },
28446
+ children: "No deposits yet"
27712
28447
  }
27713
- ),
27714
- enableConnectExchange && connectedExchange && /* @__PURE__ */ jsx55(
27715
- ConnectExchangeButton,
28448
+ ) }) : allExecutions.map((execution) => /* @__PURE__ */ jsx55(
28449
+ DepositExecutionItem,
27716
28450
  {
27717
- onClick: () => {
27718
- setCoinbaseSkipToHoldings(true);
27719
- setView("coinbase_connect");
27720
- },
27721
- onDisconnect: handleExchangeDisconnect,
27722
- title: i18n2.connectExchange.title,
27723
- subtitle: i18n2.connectExchange.subtitle,
27724
- exchanges: integrationExchanges,
27725
- connectedExchange
27726
- }
27727
- ),
27728
- enableConnectExchange && !connectedExchange && /* @__PURE__ */ jsx55(
27729
- ConnectExchangeButton,
28451
+ execution,
28452
+ onClick: () => setSelectedExecution(execution)
28453
+ },
28454
+ execution.id
28455
+ )) }) }),
28456
+ depositPoweredByFooter
28457
+ ] })
28458
+ ] }) : view === "card" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
28459
+ /* @__PURE__ */ jsx55(
28460
+ DepositHeader,
28461
+ {
28462
+ title: cardView === "quotes" ? t7.quotes : depositWithCardTitle,
28463
+ showBack: showBackCard,
28464
+ onBack: handleBack,
28465
+ onClose: handleClose,
28466
+ badge: cardView === "quotes" ? { count: quotesCount } : void 0,
28467
+ showBalance: showBalanceHeader,
28468
+ balanceAddress: recipientAddress,
28469
+ balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
28470
+ balanceChainId: destinationChainId,
28471
+ balanceTokenAddress: destinationTokenAddress,
28472
+ projectName: projectConfig?.project_name,
28473
+ publishableKey
28474
+ }
28475
+ ),
28476
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28477
+ standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ jsx55("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : /* @__PURE__ */ jsx55(
28478
+ BuyWithCard,
27730
28479
  {
27731
- onClick: () => {
27732
- setCoinbaseSkipToHoldings(false);
27733
- setView("coinbase_connect");
27734
- },
27735
- title: i18n2.connectExchange.title,
27736
- subtitle: i18n2.connectExchange.subtitle,
27737
- exchanges: integrationExchanges
28480
+ userId,
28481
+ publishableKey,
28482
+ view: cardView,
28483
+ onViewChange: handleCardViewChange,
28484
+ destinationTokenSymbol,
28485
+ recipientAddress,
28486
+ destinationChainType,
28487
+ destinationChainId,
28488
+ destinationTokenAddress,
28489
+ onDepositSuccess,
28490
+ onDepositError,
28491
+ onEvent,
28492
+ themeClass,
28493
+ wallets,
28494
+ assetCdnUrl: projectConfig?.asset_cdn_url,
28495
+ hideDepositFlowInfo,
28496
+ hideDisplayDescription
27738
28497
  }
27739
28498
  ),
27740
- enableCashApp && /* @__PURE__ */ jsx55(
27741
- CashAppButton,
28499
+ depositPoweredByFooter
28500
+ ] })
28501
+ ] }) : view === "exchange" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
28502
+ /* @__PURE__ */ jsx55(
28503
+ DepositHeader,
28504
+ {
28505
+ title: payWithExchangeTitle,
28506
+ showBack: exchangeView === "pending" || sessionOpenedFromMenu,
28507
+ onBack: handleBack,
28508
+ onClose: handleClose
28509
+ }
28510
+ ),
28511
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28512
+ /* @__PURE__ */ jsx55(
28513
+ PayWithExchange,
27742
28514
  {
27743
- onClick: () => setView("cashapp"),
27744
- title: "Pay with Cash App",
27745
- subtitle: "Deposit via Cash App",
27746
- iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
28515
+ userId,
28516
+ publishableKey,
28517
+ exchanges,
28518
+ view: exchangeView,
28519
+ onViewChange: setExchangeView,
28520
+ destinationTokenSymbol,
28521
+ recipientAddress,
28522
+ destinationChainType,
28523
+ destinationChainId,
28524
+ destinationTokenAddress,
28525
+ onDepositSuccess,
28526
+ onDepositError,
28527
+ wallets,
28528
+ defaultToken: defaultToken ?? null
27747
28529
  }
27748
28530
  ),
27749
- !hideDepositTracker && /* @__PURE__ */ jsx55(
27750
- DepositTrackerButton,
27751
- {
27752
- onClick: () => {
27753
- setAllExecutions(depositExecutions);
27754
- setView("tracker");
27755
- },
27756
- title: depositTrackerTitle,
27757
- subtitle: depositTrackerSubTitle,
27758
- badge: depositExecutions.length > 0 ? depositExecutions.length : void 0
27759
- }
27760
- )
27761
- ] }) }),
27762
- depositPoweredByFooter
27763
- ] })
27764
- ] }) : view === "transfer" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
27765
- /* @__PURE__ */ jsx55(
27766
- DepositHeader,
27767
- {
27768
- title: transferCryptoTitle,
27769
- showBack: showBackTransfer,
27770
- onBack: handleBack,
27771
- onClose: handleClose,
27772
- showBalance: showBalanceHeader,
27773
- balanceAddress: recipientAddress,
27774
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
27775
- balanceChainId: destinationChainId,
27776
- balanceTokenAddress: destinationTokenAddress,
27777
- projectName: projectConfig?.project_name,
27778
- publishableKey
27779
- }
27780
- ),
27781
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
27782
- standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ jsx55("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : transferInputVariant === "single_input" ? /* @__PURE__ */ jsx55(
27783
- TransferCryptoSingleInput,
28531
+ depositPoweredByFooter
28532
+ ] })
28533
+ ] }) : view === "coinbase_connect" ? /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28534
+ /* @__PURE__ */ jsx55(
28535
+ CoinbaseConnect,
27784
28536
  {
27785
- userId,
27786
28537
  publishableKey,
27787
- recipientAddress,
27788
- destinationChainType,
27789
- destinationChainId,
27790
- destinationTokenAddress,
27791
- defaultSourceChainType,
27792
- defaultSourceChainId,
27793
- defaultSourceTokenAddress,
27794
- defaultSourceSymbol,
27795
- depositConfirmationMode,
27796
- onExecutionsChange: setDepositExecutions,
27797
- onDepositSuccess,
27798
- onDepositError,
27799
- wallets
27800
- }
27801
- ) : /* @__PURE__ */ jsx55(
27802
- TransferCryptoDoubleInput,
27803
- {
27804
28538
  userId,
27805
- publishableKey,
28539
+ wallets,
27806
28540
  recipientAddress,
27807
- destinationChainType,
27808
- destinationChainId,
27809
- destinationTokenAddress,
28541
+ destinationTokenAddress: destinationTokenAddress ?? "",
28542
+ destinationChainId: destinationChainId ?? "",
28543
+ destinationChainType: destinationChainType ?? "",
28544
+ onTransferSuccess: (result) => {
28545
+ onDepositSuccess?.({
28546
+ message: "Transfer completed via Coinbase Connect",
28547
+ transaction: result
28548
+ });
28549
+ },
28550
+ onTransferError: (error) => {
28551
+ onDepositError?.({
28552
+ message: error.message,
28553
+ error
28554
+ });
28555
+ },
28556
+ onBack: handleBack,
28557
+ onClose: handleClose,
28558
+ onDisconnect: handleExchangeDisconnect,
28559
+ skipToHoldings: coinbaseSkipToHoldings,
28560
+ canGoBack: sessionOpenedFromMenu,
28561
+ onExecutionsChange: setDepositExecutions,
27810
28562
  defaultSourceChainType,
27811
28563
  defaultSourceChainId,
27812
28564
  defaultSourceTokenAddress,
27813
- defaultSourceSymbol,
27814
- depositConfirmationMode,
27815
- onExecutionsChange: setDepositExecutions,
27816
- onDepositSuccess,
27817
- onDepositError,
27818
- wallets
28565
+ defaultSourceSymbol
27819
28566
  }
27820
28567
  ),
27821
28568
  depositPoweredByFooter
27822
- ] })
27823
- ] }) : view === "tracker" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
27824
- /* @__PURE__ */ jsx55(
27825
- DepositHeader,
27826
- {
27827
- title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
27828
- showBack: showBackTracker,
27829
- onBack: handleBack,
27830
- onClose: handleClose
27831
- }
27832
- ),
27833
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
27834
- /* @__PURE__ */ jsx55("div", { className: "uf-h-[460px] uf-overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: selectedExecution ? /* @__PURE__ */ jsx55(DepositDetailContent, { execution: selectedExecution }) : /* @__PURE__ */ jsx55("div", { className: "uf-space-y-2 uf-pb-8", children: allExecutions.length === 0 ? /* @__PURE__ */ jsx55("div", { className: "uf-py-8 uf-px-4 uf-text-center", children: /* @__PURE__ */ jsx55(
27835
- "div",
27836
- {
27837
- className: "uf-text-sm",
27838
- style: { color: components.container.subtitleColor, fontFamily: fonts.regular },
27839
- children: "No deposits yet"
27840
- }
27841
- ) }) : allExecutions.map((execution) => /* @__PURE__ */ jsx55(
27842
- DepositExecutionItem,
27843
- {
27844
- execution,
27845
- onClick: () => setSelectedExecution(execution)
27846
- },
27847
- execution.id
27848
- )) }) }),
27849
- depositPoweredByFooter
27850
- ] })
27851
- ] }) : view === "card" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
27852
- /* @__PURE__ */ jsx55(
27853
- DepositHeader,
27854
- {
27855
- title: cardView === "quotes" ? t7.quotes : depositWithCardTitle,
27856
- showBack: showBackCard,
27857
- onBack: handleBack,
27858
- onClose: handleClose,
27859
- badge: cardView === "quotes" ? { count: quotesCount } : void 0,
27860
- showBalance: showBalanceHeader,
27861
- balanceAddress: recipientAddress,
27862
- balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" ? destinationChainType : void 0,
27863
- balanceChainId: destinationChainId,
27864
- balanceTokenAddress: destinationTokenAddress,
27865
- projectName: projectConfig?.project_name,
27866
- publishableKey
27867
- }
27868
- ),
27869
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
27870
- standaloneNeedsDepositPrereq && depositPrerequisiteBody !== null ? /* @__PURE__ */ jsx55("div", { className: "uf-pb-4 uf-space-y-3", children: depositPrerequisiteBody }) : /* @__PURE__ */ jsx55(
27871
- BuyWithCard,
27872
- {
27873
- userId,
27874
- publishableKey,
27875
- view: cardView,
27876
- onViewChange: handleCardViewChange,
27877
- destinationTokenSymbol,
27878
- recipientAddress,
27879
- destinationChainType,
27880
- destinationChainId,
27881
- destinationTokenAddress,
27882
- onDepositSuccess,
27883
- onDepositError,
27884
- onEvent,
27885
- themeClass,
27886
- wallets,
27887
- assetCdnUrl: projectConfig?.asset_cdn_url,
27888
- hideDepositFlowInfo,
27889
- hideDisplayDescription
27890
- }
27891
- ),
27892
- depositPoweredByFooter
27893
- ] })
27894
- ] }) : view === "exchange" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
27895
- /* @__PURE__ */ jsx55(
27896
- DepositHeader,
27897
- {
27898
- title: payWithExchangeTitle,
27899
- showBack: exchangeView === "pending" || sessionOpenedFromMenu,
27900
- onBack: handleBack,
27901
- onClose: handleClose
27902
- }
27903
- ),
27904
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28569
+ ] }) : view === "wallet_connect" ? /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
27905
28570
  /* @__PURE__ */ jsx55(
27906
- PayWithExchange,
28571
+ WalletConnect,
27907
28572
  {
28573
+ walletInfo: browserWalletInfo ?? void 0,
28574
+ depositWallet: browserWalletInfo?.depositWallet ?? void 0,
28575
+ wallets,
27908
28576
  userId,
27909
28577
  publishableKey,
27910
- exchanges,
27911
- view: exchangeView,
27912
- onViewChange: setExchangeView,
27913
- destinationTokenSymbol,
27914
- recipientAddress,
27915
- destinationChainType,
27916
- destinationChainId,
27917
- destinationTokenAddress,
28578
+ assetCdnUrl: projectConfig?.asset_cdn_url,
28579
+ projectName: projectConfig?.project_name,
28580
+ onSuccess: (txHash) => {
28581
+ onDepositSuccess?.({
28582
+ message: "Transaction sent successfully",
28583
+ transaction: { txHash }
28584
+ });
28585
+ },
28586
+ onError: (error) => {
28587
+ onDepositError?.({
28588
+ message: error.message,
28589
+ error
28590
+ });
28591
+ },
27918
28592
  onDepositSuccess,
27919
28593
  onDepositError,
27920
- wallets,
27921
- defaultToken: defaultToken ?? null
28594
+ amountQuickSelect: browserWalletAmountQuickSelect,
28595
+ onWalletDisconnect: handleWalletDisconnect,
28596
+ onWalletConnected: (info, dw) => {
28597
+ setBrowserWalletInfo({ ...info, depositWallet: dw });
28598
+ setStoredWalletState(info.type);
28599
+ setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
28600
+ },
28601
+ onBack: handleBack,
28602
+ onClose: handleClose,
28603
+ defaultSourceChainType,
28604
+ defaultSourceChainId,
28605
+ defaultSourceTokenAddress,
28606
+ defaultSourceSymbol,
28607
+ canGoBack: sessionOpenedFromMenu,
28608
+ depositWalletsLoading: walletsLoading
27922
28609
  }
27923
28610
  ),
27924
28611
  depositPoweredByFooter
27925
- ] })
27926
- ] }) : view === "coinbase_connect" ? /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
27927
- /* @__PURE__ */ jsx55(
27928
- CoinbaseConnect,
27929
- {
27930
- publishableKey,
27931
- userId,
27932
- wallets,
27933
- recipientAddress,
27934
- destinationTokenAddress: destinationTokenAddress ?? "",
27935
- destinationChainId: destinationChainId ?? "",
27936
- destinationChainType: destinationChainType ?? "",
27937
- onTransferSuccess: (result) => {
27938
- onDepositSuccess?.({
27939
- message: "Transfer completed via Coinbase Connect",
27940
- transaction: result
27941
- });
27942
- },
27943
- onTransferError: (error) => {
27944
- onDepositError?.({
27945
- message: error.message,
27946
- error
27947
- });
27948
- },
27949
- onBack: handleBack,
27950
- onClose: handleClose,
27951
- onDisconnect: handleExchangeDisconnect,
27952
- skipToHoldings: coinbaseSkipToHoldings,
27953
- canGoBack: sessionOpenedFromMenu,
27954
- onExecutionsChange: setDepositExecutions
27955
- }
27956
- ),
27957
- depositPoweredByFooter
27958
- ] }) : view === "wallet_connect" ? /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
27959
- /* @__PURE__ */ jsx55(
27960
- WalletConnect,
27961
- {
27962
- walletInfo: browserWalletInfo ?? void 0,
27963
- depositWallet: browserWalletInfo?.depositWallet ?? void 0,
27964
- wallets,
27965
- userId,
27966
- publishableKey,
27967
- assetCdnUrl: projectConfig?.asset_cdn_url,
27968
- projectName: projectConfig?.project_name,
27969
- onSuccess: (txHash) => {
27970
- onDepositSuccess?.({
27971
- message: "Transaction sent successfully",
27972
- transaction: { txHash }
27973
- });
27974
- },
27975
- onError: (error) => {
27976
- onDepositError?.({
27977
- message: error.message,
27978
- error
27979
- });
27980
- },
27981
- onDepositSuccess,
27982
- onDepositError,
27983
- amountQuickSelect: browserWalletAmountQuickSelect,
27984
- onWalletDisconnect: handleWalletDisconnect,
27985
- onWalletConnected: (info, dw) => {
27986
- setBrowserWalletInfo({ ...info, depositWallet: dw });
27987
- setStoredWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
27988
- setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
27989
- },
27990
- onBack: handleBack,
27991
- onClose: handleClose,
27992
- canGoBack: sessionOpenedFromMenu,
27993
- depositWalletsLoading: walletsLoading
27994
- }
27995
- ),
27996
- depositPoweredByFooter
27997
- ] }) : view === "cashapp" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
27998
- /* @__PURE__ */ jsx55(
27999
- DepositHeader,
28000
- {
28001
- title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
28002
- showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
28003
- onBack: handleBack,
28004
- onClose: handleClose
28005
- }
28006
- ),
28007
- /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28612
+ ] }) : view === "cashapp" ? /* @__PURE__ */ jsxs49(Fragment11, { children: [
28008
28613
  /* @__PURE__ */ jsx55(
28009
- PayWithCashApp,
28614
+ DepositHeader,
28010
28615
  {
28011
- userId,
28012
- publishableKey,
28013
- recipientAddress,
28014
- destinationChainType,
28015
- destinationChainId,
28016
- destinationTokenAddress,
28017
- cashAppIconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0,
28018
- view: cashAppView,
28019
- onViewChange: setCashAppView,
28020
- onAmountChange: setCashAppAmount,
28021
- onEvent,
28022
- onDepositSuccess,
28023
- onDepositError
28616
+ title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
28617
+ showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
28618
+ onBack: handleBack,
28619
+ onClose: handleClose
28024
28620
  }
28025
28621
  ),
28026
- depositPoweredByFooter
28027
- ] })
28028
- ] }) : null })
28622
+ /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
28623
+ /* @__PURE__ */ jsx55(
28624
+ PayWithCashApp,
28625
+ {
28626
+ userId,
28627
+ publishableKey,
28628
+ recipientAddress,
28629
+ destinationChainType,
28630
+ destinationChainId,
28631
+ destinationTokenAddress,
28632
+ cashAppIconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0,
28633
+ view: cashAppView,
28634
+ onViewChange: setCashAppView,
28635
+ onAmountChange: setCashAppAmount,
28636
+ onEvent,
28637
+ onDepositSuccess,
28638
+ onDepositError
28639
+ }
28640
+ ),
28641
+ depositPoweredByFooter
28642
+ ] })
28643
+ ] }) : null })
28644
+ ]
28029
28645
  }
28030
28646
  )
28031
28647
  }
@@ -28044,7 +28660,7 @@ function usePaymentIntent(params) {
28044
28660
  enabled = true,
28045
28661
  pollingInterval = 3e3
28046
28662
  } = params;
28047
- return useQuery13({
28663
+ return useQuery14({
28048
28664
  queryKey: ["unifold", "paymentIntent", clientSecret, publishableKey],
28049
28665
  queryFn: () => retrievePaymentIntent(clientSecret, publishableKey),
28050
28666
  enabled: enabled && !!clientSecret && !!publishableKey,
@@ -28091,7 +28707,8 @@ function CheckoutModal({
28091
28707
  clientSecret,
28092
28708
  publishableKey,
28093
28709
  modalTitle,
28094
- enableConnectWallet = false,
28710
+ enableTransferCrypto,
28711
+ enableConnectWallet,
28095
28712
  defaultSourceChainType,
28096
28713
  defaultSourceChainId,
28097
28714
  defaultSourceTokenAddress,
@@ -28108,8 +28725,7 @@ function CheckoutModal({
28108
28725
  const [browserWalletModalOpen, setBrowserWalletModalOpen] = useState33(false);
28109
28726
  const [browserWalletInfo, setBrowserWalletInfo] = useState33(null);
28110
28727
  const [walletSelectionModalOpen, setWalletSelectionModalOpen] = useState33(false);
28111
- const [browserWalletChainType, setBrowserWalletChainType] = useState33(() => getStoredWalletChainType());
28112
- const isMobileView = useIsMobileViewport();
28728
+ const [browserWalletChainType, setBrowserWalletChainType] = useState33(() => getStoredWalletState()?.chainType);
28113
28729
  const [resolvedTheme, setResolvedTheme] = useState33(
28114
28730
  theme === "auto" ? "dark" : theme
28115
28731
  );
@@ -28141,6 +28757,15 @@ function CheckoutModal({
28141
28757
  publishableKey,
28142
28758
  enabled: open
28143
28759
  });
28760
+ const showTransferCrypto = enableTransferCrypto ?? projectConfig?.transfer_crypto?.enabled ?? true;
28761
+ const showConnectWallet = enableConnectWallet ?? projectConfig?.connect_wallet?.enabled ?? true;
28762
+ useEffect272(() => {
28763
+ if (view === "transfer" && !showTransferCrypto) {
28764
+ setView("main");
28765
+ } else if (view === "wallet_connect" && !showConnectWallet) {
28766
+ setView("main");
28767
+ }
28768
+ }, [showConnectWallet, showTransferCrypto, view]);
28144
28769
  const prevStatusRef = useRef102(null);
28145
28770
  useEffect272(() => {
28146
28771
  if (!paymentIntent) return;
@@ -28231,7 +28856,7 @@ function CheckoutModal({
28231
28856
  const handleBrowserWalletClick = useCallback62(
28232
28857
  (walletInfo) => {
28233
28858
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
28234
- setStoredWalletChainType(walletChainType);
28859
+ setStoredWalletState(walletInfo.type);
28235
28860
  setBrowserWalletChainType(walletChainType);
28236
28861
  const matchingDepositWallet = wallets.find(
28237
28862
  (w) => w.chain_type === walletChainType
@@ -28258,7 +28883,7 @@ function CheckoutModal({
28258
28883
  const handleWalletConnected = useCallback62(
28259
28884
  (walletInfo) => {
28260
28885
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
28261
- setStoredWalletChainType(walletChainType);
28886
+ setStoredWalletState(walletInfo.type);
28262
28887
  setBrowserWalletChainType(walletChainType);
28263
28888
  const matchingDepositWallet = wallets.find(
28264
28889
  (w) => w.chain_type === walletChainType
@@ -28282,7 +28907,7 @@ function CheckoutModal({
28282
28907
  );
28283
28908
  const handleWalletDisconnect = useCallback62(() => {
28284
28909
  setUserDisconnectedWallet(true);
28285
- clearStoredWalletChainType();
28910
+ clearStoredWalletState();
28286
28911
  setBrowserWalletChainType(void 0);
28287
28912
  setBrowserWalletInfo(null);
28288
28913
  setBrowserWalletModalOpen(false);
@@ -28517,7 +29142,7 @@ function CheckoutModal({
28517
29142
  ] }) : paymentIntent ? /* @__PURE__ */ jsxs50("div", { className: "uf-space-y-3", children: [
28518
29143
  progressSection,
28519
29144
  (paymentIntent.status === "requires_payment" || paymentIntent.status === "processing") && /* @__PURE__ */ jsxs50(Fragment12, { children: [
28520
- /* @__PURE__ */ jsx56(
29145
+ showTransferCrypto && /* @__PURE__ */ jsx56(
28521
29146
  TransferCryptoButton,
28522
29147
  {
28523
29148
  onClick: () => setView("transfer"),
@@ -28526,7 +29151,7 @@ function CheckoutModal({
28526
29151
  featuredTokens: projectConfig?.transfer_crypto.networks
28527
29152
  }
28528
29153
  ),
28529
- enableConnectWallet && !isMobileView && /* @__PURE__ */ jsx56(
29154
+ showConnectWallet && /* @__PURE__ */ jsx56(
28530
29155
  BrowserWalletButton,
28531
29156
  {
28532
29157
  onClick: handleBrowserWalletClick,
@@ -28667,14 +29292,18 @@ function CheckoutModal({
28667
29292
  onWalletDisconnect: handleWalletDisconnect,
28668
29293
  onWalletConnected: (info, dw) => {
28669
29294
  setBrowserWalletInfo({ ...info, depositWallet: dw });
28670
- setStoredWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
29295
+ setStoredWalletState(info.type);
28671
29296
  setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
28672
29297
  },
28673
29298
  onNewDeposit: () => setView("main"),
28674
29299
  onDone: () => setView("main"),
28675
29300
  paymentIntentStatus: paymentIntent.status,
28676
29301
  onBack: handleBack,
28677
- onClose: handleClose
29302
+ onClose: handleClose,
29303
+ defaultSourceChainType,
29304
+ defaultSourceChainId,
29305
+ defaultSourceTokenAddress,
29306
+ defaultSourceSymbol
28678
29307
  }
28679
29308
  ),
28680
29309
  poweredByFooter
@@ -28683,7 +29312,7 @@ function CheckoutModal({
28683
29312
  ) }) });
28684
29313
  }
28685
29314
  function useSupportedDestinationTokens(publishableKey, enabled = true) {
28686
- return useQuery14({
29315
+ return useQuery15({
28687
29316
  queryKey: ["unifold", "supportedDestinationTokens", publishableKey],
28688
29317
  queryFn: () => getSupportedDestinationTokens(publishableKey),
28689
29318
  staleTime: 1e3 * 60 * 5,
@@ -28718,7 +29347,7 @@ function useSourceTokenValidation(params) {
28718
29347
  enabled = true
28719
29348
  } = params;
28720
29349
  const hasParams = !!sourceChainType && !!sourceChainId && !!sourceTokenAddress;
28721
- return useQuery15({
29350
+ return useQuery16({
28722
29351
  queryKey: [
28723
29352
  "unifold",
28724
29353
  "sourceTokenValidation",
@@ -28774,7 +29403,7 @@ function useAddressBalance(params) {
28774
29403
  enabled = true
28775
29404
  } = params;
28776
29405
  const hasParams = !!address && !!chainType && !!chainId && !!tokenAddress;
28777
- return useQuery16({
29406
+ return useQuery17({
28778
29407
  queryKey: [
28779
29408
  "unifold",
28780
29409
  "addressBalance",
@@ -28823,7 +29452,7 @@ function useAddressBalance(params) {
28823
29452
  }
28824
29453
  function useExecutions(userId, publishableKey, options) {
28825
29454
  const actionType = options?.actionType ?? ActionType.Deposit;
28826
- return useQuery17({
29455
+ return useQuery18({
28827
29456
  queryKey: ["unifold", "executions", actionType, userId, publishableKey],
28828
29457
  queryFn: () => queryExecutions(userId, publishableKey, actionType),
28829
29458
  enabled: (options?.enabled ?? true) && !!userId,
@@ -29106,7 +29735,7 @@ function useVerifyRecipientAddress(params) {
29106
29735
  } = params;
29107
29736
  const trimmedAddress = recipientAddress?.trim() || "";
29108
29737
  const hasAllParams = !!chainType && !!chainId && !!tokenAddress && trimmedAddress.length > 0;
29109
- return useQuery18({
29738
+ return useQuery19({
29110
29739
  queryKey: [
29111
29740
  "unifold",
29112
29741
  "verifyRecipientAddress",
@@ -29148,7 +29777,7 @@ function useGetDepositAddress(params) {
29148
29777
  enabled = true
29149
29778
  } = params;
29150
29779
  const canFire = !!userId && !!recipientAddress && !!destinationChainType && !!destinationChainId && !!destinationTokenAddress;
29151
- return useQuery19({
29780
+ return useQuery20({
29152
29781
  queryKey: [
29153
29782
  "unifold",
29154
29783
  "getDepositAddress",
@@ -30431,6 +31060,16 @@ function UnifoldProvider2({
30431
31060
  });
30432
31061
  promise.catch(() => {
30433
31062
  });
31063
+ if (!config2.recipientAddress) {
31064
+ const error = {
31065
+ message: "beginDeposit requires a `recipientAddress`.",
31066
+ code: "MISSING_RECIPIENT"
31067
+ };
31068
+ console.error(`[UnifoldProvider] ${error.message}`);
31069
+ depositPromiseRef.current.reject(error);
31070
+ depositPromiseRef.current = null;
31071
+ return promise;
31072
+ }
30434
31073
  setDepositConfig(config2);
30435
31074
  setIsOpen(true);
30436
31075
  return promise;
@@ -30640,6 +31279,7 @@ function UnifoldProvider2({
30640
31279
  onOpenChange: closeCheckout,
30641
31280
  clientSecret: checkoutConfig.clientSecret,
30642
31281
  publishableKey,
31282
+ enableTransferCrypto: config?.enableTransferCrypto,
30643
31283
  enableConnectWallet: config?.enableConnectWallet,
30644
31284
  defaultSourceChainType: checkoutConfig.defaultSourceChainType,
30645
31285
  defaultSourceChainId: checkoutConfig.defaultSourceChainId,
@@ -30696,6 +31336,7 @@ function UnifoldProvider2({
30696
31336
  hideDepositTracker: config?.hideDepositTracker,
30697
31337
  showBalanceHeader: config?.showBalanceHeader,
30698
31338
  transferInputVariant: config?.transferInputVariant,
31339
+ enableTransferCrypto: config?.enableTransferCrypto,
30699
31340
  enableConnectWallet: config?.enableConnectWallet,
30700
31341
  enablePayWithExchange: config?.enablePayWithExchange,
30701
31342
  enableFiatOnramp: config?.enableFiatOnramp,