@unifold/connect-react 0.1.61 → 0.1.63

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1145,10 +1145,10 @@ ${new this._window.XMLSerializer().serializeToString(e3)}`;
1145
1145
 
1146
1146
  // src/provider.tsx
1147
1147
  import React38, {
1148
- useState as useState30,
1148
+ useState as useState31,
1149
1149
  useCallback as useCallback13,
1150
1150
  useMemo as useMemo15,
1151
- useEffect as useEffect31
1151
+ useEffect as useEffect33
1152
1152
  } from "react";
1153
1153
 
1154
1154
  // ../react-provider/dist/index.mjs
@@ -1225,11 +1225,11 @@ function useUnifold() {
1225
1225
 
1226
1226
  // ../ui-react/dist/index.mjs
1227
1227
  import {
1228
- useState as useState31,
1229
- useEffect as useEffect25,
1228
+ useState as useState32,
1229
+ useEffect as useEffect26,
1230
1230
  useLayoutEffect as useLayoutEffect22,
1231
1231
  useCallback as useCallback52,
1232
- useRef as useRef82,
1232
+ useRef as useRef92,
1233
1233
  useMemo as useMemo10
1234
1234
  } from "react";
1235
1235
 
@@ -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
  }
@@ -6667,9 +6701,7 @@ function getExchangeSessionStartUrl(request, publishableKey) {
6667
6701
  if (request.source_amount) {
6668
6702
  params.append("source_amount", request.source_amount);
6669
6703
  }
6670
- if (request.external_id) {
6671
- params.append("external_id", request.external_id);
6672
- }
6704
+ params.append("external_id", request.external_id ?? generatePrefixedKSUID("exc"));
6673
6705
  return `${API_BASE_URL}/v1/public/onramps/exchanges/sessions/start?${params.toString()}`;
6674
6706
  }
6675
6707
  async function getIntegrationExchanges(publishableKey) {
@@ -7003,40 +7035,6 @@ async function getCashAppSessionStatus(externalId, publishableKey) {
7003
7035
  }
7004
7036
  return response.json();
7005
7037
  }
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
7038
  var DepositEventType = /* @__PURE__ */ ((DepositEventType2) => {
7041
7039
  DepositEventType2["ONRAMP_SESSION_CREATED"] = "onramp_session.created";
7042
7040
  return DepositEventType2;
@@ -7355,7 +7353,7 @@ import * as React102 from "react";
7355
7353
  import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
7356
7354
  import * as React112 from "react";
7357
7355
  import { jsx as jsx222, jsxs as jsxs19 } from "react/jsx-runtime";
7358
- import * as React242 from "react";
7356
+ import * as React252 from "react";
7359
7357
 
7360
7358
  // ../../node_modules/.pnpm/mipd@0.0.7_typescript@5.9.3/node_modules/mipd/dist/esm/utils.js
7361
7359
  function requestProviders(listener) {
@@ -7413,32 +7411,33 @@ function createStore() {
7413
7411
 
7414
7412
  // ../ui-react/dist/index.mjs
7415
7413
  import * as React122 from "react";
7416
- import { jsx as jsx232, jsxs as jsxs20 } from "react/jsx-runtime";
7417
7414
  import * as React132 from "react";
7418
- import { jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
7415
+ import { jsx as jsx232, jsxs as jsxs20 } from "react/jsx-runtime";
7419
7416
  import * as React142 from "react";
7420
- import { jsx as jsx25, jsxs as jsxs222 } from "react/jsx-runtime";
7417
+ import { jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
7421
7418
  import * as React152 from "react";
7422
- import { jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
7419
+ import { jsx as jsx25, jsxs as jsxs222 } from "react/jsx-runtime";
7423
7420
  import * as React162 from "react";
7424
- import { jsx as jsx27, jsxs as jsxs24 } from "react/jsx-runtime";
7421
+ import { jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
7425
7422
  import * as React172 from "react";
7426
- import { jsx as jsx28, jsxs as jsxs25 } from "react/jsx-runtime";
7423
+ import { jsx as jsx27, jsxs as jsxs24 } from "react/jsx-runtime";
7427
7424
  import * as React182 from "react";
7428
- import { jsx as jsx29, jsxs as jsxs26 } from "react/jsx-runtime";
7425
+ import { jsx as jsx28, jsxs as jsxs25 } from "react/jsx-runtime";
7429
7426
  import * as React192 from "react";
7430
- import { jsx as jsx30, jsxs as jsxs27 } from "react/jsx-runtime";
7427
+ import { jsx as jsx29, jsxs as jsxs26 } from "react/jsx-runtime";
7431
7428
  import * as React202 from "react";
7432
- import { jsx as jsx31, jsxs as jsxs28 } from "react/jsx-runtime";
7429
+ import { jsx as jsx30, jsxs as jsxs27 } from "react/jsx-runtime";
7433
7430
  import * as React212 from "react";
7434
- import { jsx as jsx322, jsxs as jsxs29 } from "react/jsx-runtime";
7431
+ import { jsx as jsx31, jsxs as jsxs28 } from "react/jsx-runtime";
7435
7432
  import * as React222 from "react";
7436
- import { jsx as jsx33, jsxs as jsxs30 } from "react/jsx-runtime";
7433
+ import { jsx as jsx322, jsxs as jsxs29 } from "react/jsx-runtime";
7437
7434
  import * as React232 from "react";
7435
+ import { jsx as jsx33, jsxs as jsxs30 } from "react/jsx-runtime";
7436
+ import * as React242 from "react";
7438
7437
  import { jsx as jsx34, jsxs as jsxs31 } from "react/jsx-runtime";
7439
7438
  import { jsx as jsx35, jsxs as jsxs322 } from "react/jsx-runtime";
7440
7439
  import { jsx as jsx36, jsxs as jsxs33 } from "react/jsx-runtime";
7441
- import { useState as useState212, useEffect as useEffect162, useCallback as useCallback22, useMemo as useMemo42, useRef as useRef52 } from "react";
7440
+ import { useState as useState222, useEffect as useEffect172, useCallback as useCallback22, useMemo as useMemo42, useRef as useRef62 } from "react";
7442
7441
  import { useQuery as useQuery4 } from "@tanstack/react-query";
7443
7442
  import { useQuery as useQuery5 } from "@tanstack/react-query";
7444
7443
  import { useQuery as useQuery6 } from "@tanstack/react-query";
@@ -7447,13 +7446,13 @@ import { useQuery as useQuery7 } from "@tanstack/react-query";
7447
7446
  import { useQuery as useQuery8 } from "@tanstack/react-query";
7448
7447
  import { useQuery as useQuery9 } from "@tanstack/react-query";
7449
7448
  import { useQuery as useQuery10 } from "@tanstack/react-query";
7450
- import { useState as useState27, useEffect as useEffect212, useMemo as useMemo72 } from "react";
7451
- import { useEffect as useEffect182, useState as useState222 } from "react";
7452
- import * as React262 from "react";
7449
+ import { useState as useState28, useEffect as useEffect222, useMemo as useMemo72 } from "react";
7450
+ import { useEffect as useEffect192, useState as useState232 } from "react";
7451
+ import * as React272 from "react";
7453
7452
  import { jsx as jsx38 } from "react/jsx-runtime";
7454
7453
  import { jsx as jsx39, jsxs as jsxs35 } from "react/jsx-runtime";
7455
7454
  import { Fragment as Fragment52, jsx as jsx40, jsxs as jsxs36 } from "react/jsx-runtime";
7456
- import { useState as useState232, useMemo as useMemo62, useEffect as useEffect192 } from "react";
7455
+ import { useState as useState242, useMemo as useMemo62, useEffect as useEffect202 } from "react";
7457
7456
 
7458
7457
  // ../../node_modules/.pnpm/fuse.js@7.4.0/node_modules/fuse.js/dist/fuse.mjs
7459
7458
  function isArray(value) {
@@ -9455,11 +9454,11 @@ Fuse.use = function(...plugins) {
9455
9454
 
9456
9455
  // ../ui-react/dist/index.mjs
9457
9456
  import { jsx as jsx41, jsxs as jsxs37 } from "react/jsx-runtime";
9458
- import { useState as useState242, useEffect as useEffect202, useRef as useRef62 } from "react";
9457
+ import { useState as useState252, useEffect as useEffect212, useRef as useRef72 } from "react";
9459
9458
  import { jsx as jsx422, jsxs as jsxs38 } from "react/jsx-runtime";
9460
9459
  import { Fragment as Fragment62, jsx as jsx43, jsxs as jsxs39 } from "react/jsx-runtime";
9461
- import { useState as useState252 } from "react";
9462
- import * as React272 from "react";
9460
+ import { useState as useState262 } from "react";
9461
+ import * as React282 from "react";
9463
9462
 
9464
9463
  // ../../node_modules/.pnpm/@radix-ui+react-tooltip@1.2.8_@types+react-dom@19.2.3_@types+react@19.2.9__@types+react@19.2._udyjcec5g7ve3mpsxbgla63vgi/node_modules/@radix-ui/react-tooltip/dist/index.mjs
9465
9464
  import * as React31 from "react";
@@ -12200,8 +12199,8 @@ import { jsx as jsx44 } from "react/jsx-runtime";
12200
12199
  import { useQuery as useQuery11 } from "@tanstack/react-query";
12201
12200
  import { jsx as jsx45, jsxs as jsxs40 } from "react/jsx-runtime";
12202
12201
  import { Fragment as Fragment72, jsx as jsx46, jsxs as jsxs41 } from "react/jsx-runtime";
12203
- import { useState as useState28, useEffect as useEffect222, useMemo as useMemo82 } from "react";
12204
- import * as React282 from "react";
12202
+ import { useState as useState29, useEffect as useEffect232, useMemo as useMemo82 } from "react";
12203
+ import * as React292 from "react";
12205
12204
 
12206
12205
  // ../../node_modules/.pnpm/@radix-ui+react-select@2.2.6_@types+react-dom@19.2.3_@types+react@19.2.9__@types+react@19.2.9_cot3leusltbsophitaz3dgdqdm/node_modules/@radix-ui/react-select/dist/index.mjs
12207
12206
  import * as React35 from "react";
@@ -13438,55 +13437,79 @@ var Separator = SelectSeparator;
13438
13437
  // ../ui-react/dist/index.mjs
13439
13438
  import { jsx as jsx47, jsxs as jsxs422 } from "react/jsx-runtime";
13440
13439
  import { jsx as jsx48, jsxs as jsxs43 } from "react/jsx-runtime";
13441
- import * as React292 from "react";
13440
+ import * as React302 from "react";
13442
13441
  import { useQuery as useQuery12 } from "@tanstack/react-query";
13443
13442
  import { jsx as jsx49 } from "react/jsx-runtime";
13444
13443
  import { jsx as jsx50, jsxs as jsxs44 } from "react/jsx-runtime";
13445
13444
  import { Fragment as Fragment82, jsx as jsx51, jsxs as jsxs45 } from "react/jsx-runtime";
13446
13445
  import { Fragment as Fragment9, jsx as jsx522, jsxs as jsxs46 } from "react/jsx-runtime";
13447
- import { useEffect as useEffect232, useState as useState292 } from "react";
13446
+ import { useEffect as useEffect242, useState as useState302 } from "react";
13448
13447
  import { Fragment as Fragment10, jsx as jsx53, jsxs as jsxs47 } from "react/jsx-runtime";
13449
13448
  import { jsx as jsx54, jsxs as jsxs48 } from "react/jsx-runtime";
13450
13449
  import { Fragment as Fragment11, jsx as jsx55, jsxs as jsxs49 } from "react/jsx-runtime";
13451
13450
  import {
13452
- useState as useState32,
13453
- useEffect as useEffect262,
13451
+ useState as useState33,
13452
+ useEffect as useEffect272,
13454
13453
  useLayoutEffect as useLayoutEffect32,
13455
13454
  useCallback as useCallback62,
13456
- useRef as useRef92,
13455
+ useRef as useRef102,
13457
13456
  useMemo as useMemo112
13458
13457
  } from "react";
13459
13458
  import { useQuery as useQuery13 } from "@tanstack/react-query";
13460
13459
  import { Fragment as Fragment12, jsx as jsx56, jsxs as jsxs50 } from "react/jsx-runtime";
13461
13460
  import {
13462
- useState as useState36,
13463
- useEffect as useEffect30,
13461
+ useState as useState37,
13462
+ useEffect as useEffect31,
13464
13463
  useLayoutEffect as useLayoutEffect42,
13465
13464
  useCallback as useCallback82,
13466
- useRef as useRef112
13465
+ useRef as useRef122
13467
13466
  } from "react";
13468
13467
  import { useQuery as useQuery14 } from "@tanstack/react-query";
13469
13468
  import { useQuery as useQuery15 } from "@tanstack/react-query";
13470
13469
  import { useQuery as useQuery16 } from "@tanstack/react-query";
13471
13470
  import { useQuery as useQuery17 } from "@tanstack/react-query";
13472
- import { useState as useState33, useEffect as useEffect272, useRef as useRef102 } from "react";
13471
+ import { useState as useState34, useEffect as useEffect282, useRef as useRef112 } from "react";
13473
13472
  import { jsx as jsx57, jsxs as jsxs51 } from "react/jsx-runtime";
13474
- import { useState as useState34, useCallback as useCallback72, useMemo as useMemo132, useEffect as useEffect282 } from "react";
13473
+ import { useState as useState35, useCallback as useCallback72, useMemo as useMemo132, useEffect as useEffect292 } from "react";
13475
13474
  import { useQuery as useQuery18 } from "@tanstack/react-query";
13476
13475
  import { useMemo as useMemo122 } from "react";
13477
13476
  import { useQuery as useQuery19 } from "@tanstack/react-query";
13478
13477
  import { Fragment as Fragment13, jsx as jsx58, jsxs as jsxs52 } from "react/jsx-runtime";
13479
13478
  import { jsx as jsx59, jsxs as jsxs53 } from "react/jsx-runtime";
13480
- import { useState as useState35, useEffect as useEffect292 } from "react";
13479
+ import { useState as useState36, useEffect as useEffect302 } from "react";
13481
13480
  import { Fragment as Fragment14, jsx as jsx60, jsxs as jsxs54 } from "react/jsx-runtime";
13482
13481
  import { Fragment as Fragment15, jsx as jsx61, jsxs as jsxs55 } from "react/jsx-runtime";
13483
- import { useState as useState37, useMemo as useMemo142 } from "react";
13482
+ import { useState as useState38, useMemo as useMemo142 } from "react";
13484
13483
  import { jsx as jsx622, jsxs as jsxs56 } from "react/jsx-runtime";
13485
13484
  function cn(...inputs) {
13486
13485
  return twMerge(clsx(inputs));
13487
13486
  }
13488
- var WALLET_CHAIN_TYPE_STORAGE_KEY = "unifold_last_wallet_type";
13487
+ var WALLET_STATE_STORAGE_KEY = "unifold_wallet_state";
13488
+ var LEGACY_WALLET_KEYS = [
13489
+ "unifold_last_wallet_type",
13490
+ "unifold_last_connected_wallet"
13491
+ ];
13489
13492
  var WALLET_USER_DISCONNECTED_KEY = "unifold_wallet_user_disconnected";
13493
+ var SOLANA_WALLET_TYPES = /* @__PURE__ */ new Set([
13494
+ "phantom-solana",
13495
+ "solflare",
13496
+ "backpack",
13497
+ "glow"
13498
+ ]);
13499
+ var ETHEREUM_WALLET_TYPES = /* @__PURE__ */ new Set([
13500
+ "metamask",
13501
+ "phantom-ethereum",
13502
+ "coinbase",
13503
+ "trust",
13504
+ "rainbow",
13505
+ "rabby",
13506
+ "okx"
13507
+ ]);
13508
+ function walletTypeToChain(t12) {
13509
+ if (SOLANA_WALLET_TYPES.has(t12)) return "solana";
13510
+ if (ETHEREUM_WALLET_TYPES.has(t12)) return "ethereum";
13511
+ return void 0;
13512
+ }
13490
13513
  function getUserDisconnectedWallet() {
13491
13514
  if (typeof window === "undefined") return false;
13492
13515
  try {
@@ -13506,26 +13529,35 @@ function setUserDisconnectedWallet(disconnected) {
13506
13529
  } catch {
13507
13530
  }
13508
13531
  }
13509
- function getStoredWalletChainType() {
13532
+ function getStoredWalletState() {
13510
13533
  if (typeof window === "undefined") return void 0;
13511
13534
  try {
13512
- const stored = localStorage.getItem(WALLET_CHAIN_TYPE_STORAGE_KEY);
13513
- if (stored === "ethereum" || stored === "solana") return stored;
13535
+ const raw = localStorage.getItem(WALLET_STATE_STORAGE_KEY);
13536
+ if (!raw) return void 0;
13537
+ const chainType = walletTypeToChain(raw);
13538
+ if (!chainType) {
13539
+ localStorage.removeItem(WALLET_STATE_STORAGE_KEY);
13540
+ return void 0;
13541
+ }
13542
+ return { walletType: raw, chainType };
13514
13543
  } catch {
13544
+ return void 0;
13515
13545
  }
13516
- return void 0;
13517
13546
  }
13518
- function setStoredWalletChainType(chainType) {
13547
+ function setStoredWalletState(walletType) {
13519
13548
  if (typeof window === "undefined") return;
13549
+ if (!walletTypeToChain(walletType)) return;
13520
13550
  try {
13521
- localStorage.setItem(WALLET_CHAIN_TYPE_STORAGE_KEY, chainType);
13551
+ localStorage.setItem(WALLET_STATE_STORAGE_KEY, walletType);
13552
+ for (const key of LEGACY_WALLET_KEYS) localStorage.removeItem(key);
13522
13553
  } catch {
13523
13554
  }
13524
13555
  }
13525
- function clearStoredWalletChainType() {
13556
+ function clearStoredWalletState() {
13526
13557
  if (typeof window === "undefined") return;
13527
13558
  try {
13528
- localStorage.removeItem(WALLET_CHAIN_TYPE_STORAGE_KEY);
13559
+ localStorage.removeItem(WALLET_STATE_STORAGE_KEY);
13560
+ for (const key of LEGACY_WALLET_KEYS) localStorage.removeItem(key);
13529
13561
  } catch {
13530
13562
  }
13531
13563
  }
@@ -14088,6 +14120,60 @@ function useDepositAddress(params) {
14088
14120
  // 1s, 2s, 4s (max 10s)
14089
14121
  });
14090
14122
  }
14123
+ var normalize = (value) => value?.toLowerCase();
14124
+ function sourceTokenMatchesDefaultSource(token, defaultSource) {
14125
+ if (!token || !defaultSource.defaultSourceChainType || !defaultSource.defaultSourceChainId) {
14126
+ return false;
14127
+ }
14128
+ if (token.chain_type !== defaultSource.defaultSourceChainType || token.chain_id !== defaultSource.defaultSourceChainId) {
14129
+ return false;
14130
+ }
14131
+ if (defaultSource.defaultSourceTokenAddress && normalize(token.token_address) === normalize(defaultSource.defaultSourceTokenAddress)) {
14132
+ return true;
14133
+ }
14134
+ if (defaultSource.defaultSourceTokenAddress) {
14135
+ return false;
14136
+ }
14137
+ return !!defaultSource.defaultSourceSymbol && normalize(token.symbol) === normalize(defaultSource.defaultSourceSymbol);
14138
+ }
14139
+ function isDefaultSourceBalance(balance, defaultSource) {
14140
+ return isBalanceEligible(balance) && sourceTokenMatchesDefaultSource(getTokenFromBalance(balance), defaultSource);
14141
+ }
14142
+ function compareBalancesWithDefaultSource(a, b, defaultSource) {
14143
+ const aDefault = isDefaultSourceBalance(a, defaultSource);
14144
+ const bDefault = isDefaultSourceBalance(b, defaultSource);
14145
+ if (aDefault && !bDefault) return -1;
14146
+ if (!aDefault && bDefault) return 1;
14147
+ const aEligible = isBalanceEligible(a);
14148
+ const bEligible = isBalanceEligible(b);
14149
+ if (aEligible && !bEligible) return -1;
14150
+ if (!aEligible && bEligible) return 1;
14151
+ return 0;
14152
+ }
14153
+ function resolveDefaultSourceSymbol(supportedTokens, defaultSource) {
14154
+ if (!supportedTokens?.length || !defaultSource.defaultSourceChainType || !defaultSource.defaultSourceChainId) {
14155
+ return null;
14156
+ }
14157
+ if (defaultSource.defaultSourceTokenAddress) {
14158
+ for (const token of supportedTokens) {
14159
+ const matchingChain = token.chains.find(
14160
+ (chain) => chain.chain_type === defaultSource.defaultSourceChainType && chain.chain_id === defaultSource.defaultSourceChainId && normalize(chain.token_address) === normalize(defaultSource.defaultSourceTokenAddress)
14161
+ );
14162
+ if (matchingChain) return token.symbol;
14163
+ }
14164
+ }
14165
+ if (!defaultSource.defaultSourceSymbol) return null;
14166
+ for (const token of supportedTokens) {
14167
+ if (normalize(token.symbol) !== normalize(defaultSource.defaultSourceSymbol)) {
14168
+ continue;
14169
+ }
14170
+ const matchingChain = token.chains.find(
14171
+ (chain) => chain.chain_type === defaultSource.defaultSourceChainType && chain.chain_id === defaultSource.defaultSourceChainId
14172
+ );
14173
+ if (matchingChain) return token.symbol;
14174
+ }
14175
+ return null;
14176
+ }
14091
14177
  function formatUsdFromBalancePercent(maxUsdAmount, percent) {
14092
14178
  if (maxUsdAmount <= 0 || percent < 0) return "";
14093
14179
  const raw = maxUsdAmount * percent / 100;
@@ -18563,6 +18649,226 @@ function collectAllEip6963EthProviders() {
18563
18649
  if (!store) return [];
18564
18650
  return store.getProviders().map((d) => d.provider);
18565
18651
  }
18652
+ function identifyEthWallet(provider, hint) {
18653
+ switch (hint) {
18654
+ case "metamask":
18655
+ return { type: "metamask", name: "MetaMask", icon: "metamask" };
18656
+ case "phantom":
18657
+ return { type: "phantom-ethereum", name: "Phantom", icon: "phantom" };
18658
+ case "coinbase":
18659
+ return { type: "coinbase", name: "Coinbase Wallet", icon: "coinbase" };
18660
+ case "okx":
18661
+ return { type: "okx", name: "OKX Wallet", icon: "okx" };
18662
+ case "rabby":
18663
+ return { type: "rabby", name: "Rabby", icon: "rabby" };
18664
+ case "trust":
18665
+ return { type: "trust", name: "Trust Wallet", icon: "trust" };
18666
+ case "rainbow":
18667
+ return { type: "rainbow", name: "Rainbow", icon: "rainbow" };
18668
+ }
18669
+ const anyProvider = provider;
18670
+ if (provider.isPhantom) {
18671
+ return { type: "phantom-ethereum", name: "Phantom", icon: "phantom" };
18672
+ }
18673
+ if (anyProvider.isCoinbaseWallet) {
18674
+ return { type: "coinbase", name: "Coinbase Wallet", icon: "coinbase" };
18675
+ }
18676
+ if (anyProvider.isRabby) {
18677
+ return { type: "rabby", name: "Rabby", icon: "rabby" };
18678
+ }
18679
+ if (anyProvider.isTrust) {
18680
+ return { type: "trust", name: "Trust Wallet", icon: "trust" };
18681
+ }
18682
+ if (anyProvider.isRainbow) {
18683
+ return { type: "rainbow", name: "Rainbow", icon: "rainbow" };
18684
+ }
18685
+ if (provider.isMetaMask && !provider.isPhantom) {
18686
+ return { type: "metamask", name: "MetaMask", icon: "metamask" };
18687
+ }
18688
+ return { type: "metamask", name: "Wallet", icon: "metamask" };
18689
+ }
18690
+ var EIP6963_ID_TO_WALLET_TYPE = {
18691
+ metamask: "metamask",
18692
+ phantom: "phantom-ethereum",
18693
+ coinbase: "coinbase",
18694
+ trust: "trust",
18695
+ rainbow: "rainbow",
18696
+ rabby: "rabby",
18697
+ okx: "okx"
18698
+ };
18699
+ function inferEthWalletType(provider, walletId) {
18700
+ if (EIP6963_ID_TO_WALLET_TYPE[walletId]) return EIP6963_ID_TO_WALLET_TYPE[walletId];
18701
+ const any = provider;
18702
+ if (provider.isPhantom) return "phantom-ethereum";
18703
+ if (any.isCoinbaseWallet) return "coinbase";
18704
+ if (any.isRabby) return "rabby";
18705
+ if (any.isTrust) return "trust";
18706
+ if (any.isRainbow) return "rainbow";
18707
+ if (any.isOkxWallet) return "okx";
18708
+ if (provider.isMetaMask && !provider.isPhantom) return "metamask";
18709
+ return null;
18710
+ }
18711
+ function solanaCandidate(provider, type, name, icon) {
18712
+ return {
18713
+ walletType: type,
18714
+ detect: async () => {
18715
+ if (!provider) return null;
18716
+ if (provider.isConnected && provider.publicKey) {
18717
+ return { type, name, address: provider.publicKey.toString(), icon };
18718
+ }
18719
+ try {
18720
+ const resp = await provider.connect({ onlyIfTrusted: true });
18721
+ if (resp.publicKey) {
18722
+ return { type, name, address: resp.publicKey.toString(), icon };
18723
+ }
18724
+ } catch {
18725
+ }
18726
+ return null;
18727
+ }
18728
+ };
18729
+ }
18730
+ function ethereumCandidate(provider, walletId) {
18731
+ return {
18732
+ walletType: inferEthWalletType(provider, walletId),
18733
+ detect: async () => {
18734
+ try {
18735
+ const accounts = await provider.request({ method: "eth_accounts" });
18736
+ if (!accounts?.length) return null;
18737
+ const resolved = identifyEthWallet(provider, walletId);
18738
+ return { ...resolved, address: accounts[0] };
18739
+ } catch {
18740
+ return null;
18741
+ }
18742
+ }
18743
+ };
18744
+ }
18745
+ function buildCandidates(win, chainType) {
18746
+ const candidates = [];
18747
+ if (!chainType || chainType === "solana") {
18748
+ candidates.push(
18749
+ solanaCandidate(win.phantom?.solana, "phantom-solana", "Phantom", "phantom"),
18750
+ solanaCandidate(win.solflare, "solflare", "Solflare", "solflare"),
18751
+ solanaCandidate(win.backpack, "backpack", "Backpack", "backpack"),
18752
+ solanaCandidate(win.glow, "glow", "Glow", "glow")
18753
+ );
18754
+ }
18755
+ if (!chainType || chainType === "ethereum") {
18756
+ const seen = /* @__PURE__ */ new Set();
18757
+ const addEth = (provider, walletId) => {
18758
+ if (!provider || seen.has(provider)) return;
18759
+ seen.add(provider);
18760
+ candidates.push(ethereumCandidate(provider, walletId));
18761
+ };
18762
+ for (const { provider, walletId } of getEip6963Providers()) {
18763
+ addEth(
18764
+ provider,
18765
+ walletId === "unknown" ? "default" : walletId
18766
+ );
18767
+ }
18768
+ addEth(win.phantom?.ethereum, "phantom");
18769
+ addEth(win.coinbaseWalletExtension, "coinbase");
18770
+ addEth(win.okxwallet, "okx");
18771
+ addEth(win.trustwallet?.ethereum, "trust");
18772
+ addEth(win.ethereum, "default");
18773
+ }
18774
+ return candidates;
18775
+ }
18776
+ async function detectConnectedBrowserWallet(chainType) {
18777
+ if (typeof window === "undefined") return null;
18778
+ if (getUserDisconnectedWallet()) return null;
18779
+ try {
18780
+ const win = window;
18781
+ const candidates = buildCandidates(win, chainType);
18782
+ const preferred = getStoredWalletState();
18783
+ if (preferred && (!chainType || preferred.chainType === chainType)) {
18784
+ const idx = candidates.findIndex((c) => c.walletType === preferred.walletType);
18785
+ if (idx > 0) candidates.unshift(...candidates.splice(idx, 1));
18786
+ }
18787
+ for (const c of candidates) {
18788
+ const found = await c.detect();
18789
+ if (found) return found;
18790
+ }
18791
+ } catch (error) {
18792
+ console.error("[detectConnectedBrowserWallet] detection error:", error);
18793
+ }
18794
+ return null;
18795
+ }
18796
+ function useDetectedBrowserWallet(opts = {}) {
18797
+ const { chainType, enabled = true, onDisconnect } = opts;
18798
+ const [wallet, setWallet] = React122.useState(null);
18799
+ const [isLoading, setIsLoading] = React122.useState(enabled);
18800
+ const [eip6963ProviderCount, setEip6963ProviderCount] = React122.useState(0);
18801
+ const onDisconnectRef = React122.useRef(onDisconnect);
18802
+ onDisconnectRef.current = onDisconnect;
18803
+ React122.useEffect(() => {
18804
+ const store = getEip6963Store();
18805
+ if (!store) return;
18806
+ setEip6963ProviderCount(store.getProviders().length);
18807
+ return store.subscribe((providers) => setEip6963ProviderCount(providers.length));
18808
+ }, []);
18809
+ React122.useEffect(() => {
18810
+ if (!enabled) {
18811
+ setWallet(null);
18812
+ setIsLoading(false);
18813
+ return;
18814
+ }
18815
+ let mounted = true;
18816
+ const detect = async () => {
18817
+ if (!mounted) return;
18818
+ setIsLoading(true);
18819
+ const detected = await detectConnectedBrowserWallet(chainType);
18820
+ if (!mounted) return;
18821
+ setWallet(detected);
18822
+ setIsLoading(false);
18823
+ };
18824
+ detect();
18825
+ const onChange = () => detect();
18826
+ const onDisc = () => {
18827
+ onDisconnectRef.current?.();
18828
+ detect();
18829
+ };
18830
+ const onEthAccounts = (accounts) => {
18831
+ if (Array.isArray(accounts) && accounts.length === 0) onDisconnectRef.current?.();
18832
+ detect();
18833
+ };
18834
+ const win = typeof window !== "undefined" ? window : void 0;
18835
+ const solanaProvider = win?.phantom?.solana || win?.solana;
18836
+ if (solanaProvider) {
18837
+ solanaProvider.on("connect", onChange);
18838
+ solanaProvider.on("disconnect", onDisc);
18839
+ solanaProvider.on("accountChanged", onChange);
18840
+ }
18841
+ const ethProviders = [];
18842
+ for (const { provider } of getEip6963Providers()) {
18843
+ const p = provider;
18844
+ if (p && !ethProviders.includes(p)) ethProviders.push(p);
18845
+ }
18846
+ if (win?.ethereum && !ethProviders.includes(win.ethereum)) ethProviders.push(win.ethereum);
18847
+ if (win?.phantom?.ethereum && !ethProviders.includes(win.phantom.ethereum)) {
18848
+ ethProviders.push(win.phantom.ethereum);
18849
+ }
18850
+ for (const p of ethProviders) {
18851
+ p.on("accountsChanged", onEthAccounts);
18852
+ p.on("chainChanged", onChange);
18853
+ }
18854
+ return () => {
18855
+ mounted = false;
18856
+ if (solanaProvider) {
18857
+ solanaProvider.off?.("connect", onChange);
18858
+ solanaProvider.off?.("disconnect", onDisc);
18859
+ solanaProvider.off?.("accountChanged", onChange);
18860
+ }
18861
+ for (const p of ethProviders) {
18862
+ const off = p.off?.bind(p) ?? p.removeListener?.bind(p);
18863
+ if (off) {
18864
+ off("accountsChanged", onEthAccounts);
18865
+ off("chainChanged", onChange);
18866
+ }
18867
+ }
18868
+ };
18869
+ }, [chainType, eip6963ProviderCount, enabled]);
18870
+ return { wallet, isLoading, setWallet };
18871
+ }
18566
18872
  var SOLANA_DISCONNECT_TYPES = [
18567
18873
  "phantom-solana",
18568
18874
  "solflare",
@@ -18650,7 +18956,7 @@ function MetamaskIcon({
18650
18956
  className,
18651
18957
  variant = "color"
18652
18958
  }) {
18653
- const id = React122.useId();
18959
+ const id = React132.useId();
18654
18960
  if (variant === "light" || variant === "dark") {
18655
18961
  return /* @__PURE__ */ jsxs20(
18656
18962
  "svg",
@@ -18775,7 +19081,7 @@ function PhantomIcon({
18775
19081
  className,
18776
19082
  variant = "color"
18777
19083
  }) {
18778
- const id = React132.useId();
19084
+ const id = React142.useId();
18779
19085
  if (variant === "light") {
18780
19086
  return /* @__PURE__ */ jsx24(
18781
19087
  "svg",
@@ -18846,7 +19152,7 @@ function CoinbaseIcon({
18846
19152
  className,
18847
19153
  variant = "color"
18848
19154
  }) {
18849
- const id = React142.useId();
19155
+ const id = React152.useId();
18850
19156
  if (variant === "light") {
18851
19157
  return /* @__PURE__ */ jsxs222(
18852
19158
  "svg",
@@ -18930,7 +19236,7 @@ function RabbyIcon({
18930
19236
  className,
18931
19237
  variant = "color"
18932
19238
  }) {
18933
- const id = React152.useId();
19239
+ const id = React162.useId();
18934
19240
  if (variant === "light") {
18935
19241
  return /* @__PURE__ */ jsxs23(
18936
19242
  "svg",
@@ -19281,7 +19587,7 @@ function RainbowIcon({
19281
19587
  className,
19282
19588
  variant = "color"
19283
19589
  }) {
19284
- const id = React162.useId();
19590
+ const id = React172.useId();
19285
19591
  if (variant === "light") {
19286
19592
  return /* @__PURE__ */ jsxs24(
19287
19593
  "svg",
@@ -19747,7 +20053,7 @@ function TrustIcon({
19747
20053
  className,
19748
20054
  variant = "color"
19749
20055
  }) {
19750
- const id = React172.useId();
20056
+ const id = React182.useId();
19751
20057
  if (variant === "light") {
19752
20058
  return /* @__PURE__ */ jsx28(
19753
20059
  "svg",
@@ -19840,7 +20146,7 @@ function OkxIcon({
19840
20146
  className,
19841
20147
  variant = "color"
19842
20148
  }) {
19843
- const id = React182.useId();
20149
+ const id = React192.useId();
19844
20150
  if (variant === "light") {
19845
20151
  return /* @__PURE__ */ jsx29(
19846
20152
  "svg",
@@ -19911,7 +20217,7 @@ function GlowIcon({
19911
20217
  className,
19912
20218
  variant = "color"
19913
20219
  }) {
19914
- const id = React192.useId();
20220
+ const id = React202.useId();
19915
20221
  if (variant === "light") {
19916
20222
  return /* @__PURE__ */ jsx30(
19917
20223
  "svg",
@@ -20016,7 +20322,7 @@ function BackpackIcon({
20016
20322
  className,
20017
20323
  variant = "color"
20018
20324
  }) {
20019
- const id = React202.useId();
20325
+ const id = React212.useId();
20020
20326
  if (variant === "light") {
20021
20327
  return /* @__PURE__ */ jsx31(
20022
20328
  "svg",
@@ -20093,7 +20399,7 @@ function SolflareIcon({
20093
20399
  className,
20094
20400
  variant = "color"
20095
20401
  }) {
20096
- const id = React212.useId();
20402
+ const id = React222.useId();
20097
20403
  if (variant === "light") {
20098
20404
  return /* @__PURE__ */ jsx322(
20099
20405
  "svg",
@@ -20164,7 +20470,7 @@ function EthereumIcon({
20164
20470
  className,
20165
20471
  variant = "color"
20166
20472
  }) {
20167
- const id = React222.useId();
20473
+ const id = React232.useId();
20168
20474
  if (variant === "light") {
20169
20475
  return /* @__PURE__ */ jsxs30(
20170
20476
  "svg",
@@ -20298,7 +20604,7 @@ function SolanaIcon({
20298
20604
  className,
20299
20605
  variant = "color"
20300
20606
  }) {
20301
- const id = React232.useId();
20607
+ const id = React242.useId();
20302
20608
  if (variant === "light") {
20303
20609
  return /* @__PURE__ */ jsx34(
20304
20610
  "svg",
@@ -20547,44 +20853,6 @@ function truncateAddress3(address) {
20547
20853
  if (address.length <= 10) return address;
20548
20854
  return `${address.slice(0, 4)}...${address.slice(-4)}`;
20549
20855
  }
20550
- function identifyEthWallet(provider, _win, hint) {
20551
- switch (hint) {
20552
- case "metamask":
20553
- return { type: "metamask", name: "MetaMask", icon: "metamask" };
20554
- case "phantom":
20555
- return { type: "phantom-ethereum", name: "Phantom", icon: "phantom" };
20556
- case "coinbase":
20557
- return { type: "coinbase", name: "Coinbase Wallet", icon: "coinbase" };
20558
- case "okx":
20559
- return { type: "okx", name: "OKX Wallet", icon: "okx" };
20560
- case "rabby":
20561
- return { type: "rabby", name: "Rabby", icon: "rabby" };
20562
- case "trust":
20563
- return { type: "trust", name: "Trust Wallet", icon: "trust" };
20564
- case "rainbow":
20565
- return { type: "rainbow", name: "Rainbow", icon: "rainbow" };
20566
- }
20567
- const anyProvider = provider;
20568
- if (provider.isPhantom) {
20569
- return { type: "phantom-ethereum", name: "Phantom", icon: "phantom" };
20570
- }
20571
- if (anyProvider.isCoinbaseWallet) {
20572
- return { type: "coinbase", name: "Coinbase Wallet", icon: "coinbase" };
20573
- }
20574
- if (anyProvider.isRabby) {
20575
- return { type: "rabby", name: "Rabby", icon: "rabby" };
20576
- }
20577
- if (anyProvider.isTrust) {
20578
- return { type: "trust", name: "Trust Wallet", icon: "trust" };
20579
- }
20580
- if (anyProvider.isRainbow) {
20581
- return { type: "rainbow", name: "Rainbow", icon: "rainbow" };
20582
- }
20583
- if (provider.isMetaMask && !provider.isPhantom) {
20584
- return { type: "metamask", name: "MetaMask", icon: "metamask" };
20585
- }
20586
- return { type: "metamask", name: "Wallet", icon: "metamask" };
20587
- }
20588
20856
  function BrowserWalletButton({
20589
20857
  onClick,
20590
20858
  onConnectClick,
@@ -20595,30 +20863,19 @@ function BrowserWalletButton({
20595
20863
  subtitle = i18n2.depositModal.browserWallet.subtitle
20596
20864
  }) {
20597
20865
  const { colors: colors2, fonts, components } = useTheme();
20598
- const [isHovered, setIsHovered] = React242.useState(false);
20599
- const [isTouchDevice, setIsTouchDevice] = React242.useState(false);
20600
- const [wallet, setWallet] = React242.useState(null);
20601
- const [isLoading, setIsLoading] = React242.useState(true);
20602
- const [isConnecting, setIsConnecting] = React242.useState(false);
20603
- const [balanceText, setBalanceText] = React242.useState(null);
20604
- const [isLoadingBalance, setIsLoadingBalance] = React242.useState(false);
20605
- const [isDisconnecting, setIsDisconnecting] = React242.useState(false);
20606
- const onDisconnectRef = React242.useRef(onDisconnect);
20866
+ const [isHovered, setIsHovered] = React252.useState(false);
20867
+ const [isTouchDevice, setIsTouchDevice] = React252.useState(false);
20868
+ const { wallet, isLoading, setWallet } = useDetectedBrowserWallet({ chainType, onDisconnect });
20869
+ const [isConnecting, setIsConnecting] = React252.useState(false);
20870
+ const [balanceText, setBalanceText] = React252.useState(null);
20871
+ const [isLoadingBalance, setIsLoadingBalance] = React252.useState(false);
20872
+ const [isDisconnecting, setIsDisconnecting] = React252.useState(false);
20873
+ const onDisconnectRef = React252.useRef(onDisconnect);
20607
20874
  onDisconnectRef.current = onDisconnect;
20608
- React242.useEffect(() => {
20875
+ React252.useEffect(() => {
20609
20876
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
20610
20877
  }, []);
20611
- const [eip6963ProviderCount, setEip6963ProviderCount] = React242.useState(0);
20612
- React242.useEffect(() => {
20613
- const store = getEip6963Store();
20614
- if (!store) return;
20615
- setEip6963ProviderCount(store.getProviders().length);
20616
- const unsubscribe = store.subscribe((providers) => {
20617
- setEip6963ProviderCount(providers.length);
20618
- });
20619
- return unsubscribe;
20620
- }, []);
20621
- React242.useEffect(() => {
20878
+ React252.useEffect(() => {
20622
20879
  if (!wallet || !publishableKey) {
20623
20880
  setBalanceText(null);
20624
20881
  return;
@@ -20659,206 +20916,6 @@ function BrowserWalletButton({
20659
20916
  cancelled = true;
20660
20917
  };
20661
20918
  }, [wallet, publishableKey]);
20662
- React242.useEffect(() => {
20663
- let mounted = true;
20664
- const detectWallet = async () => {
20665
- if (!mounted) return;
20666
- setIsLoading(true);
20667
- try {
20668
- const win = typeof window !== "undefined" ? window : null;
20669
- if (!win) return;
20670
- if (getUserDisconnectedWallet()) {
20671
- if (mounted) {
20672
- setWallet(null);
20673
- setIsLoading(false);
20674
- }
20675
- return;
20676
- }
20677
- if (!chainType || chainType === "solana") {
20678
- const anyWin = win;
20679
- const trySilentSolana = async (provider, type, name, icon) => {
20680
- if (!provider) return false;
20681
- if (provider.isConnected && provider.publicKey) {
20682
- if (mounted) {
20683
- setWallet({
20684
- type,
20685
- name,
20686
- address: provider.publicKey.toString(),
20687
- icon
20688
- });
20689
- setIsLoading(false);
20690
- }
20691
- return true;
20692
- }
20693
- try {
20694
- const resp = await provider.connect({ onlyIfTrusted: true });
20695
- if (mounted && resp.publicKey) {
20696
- setWallet({
20697
- type,
20698
- name,
20699
- address: resp.publicKey.toString(),
20700
- icon
20701
- });
20702
- setIsLoading(false);
20703
- return true;
20704
- }
20705
- } catch {
20706
- }
20707
- return false;
20708
- };
20709
- if (await trySilentSolana(
20710
- win.phantom?.solana,
20711
- "phantom-solana",
20712
- "Phantom",
20713
- "phantom"
20714
- ))
20715
- return;
20716
- if (await trySilentSolana(
20717
- anyWin.solflare,
20718
- "solflare",
20719
- "Solflare",
20720
- "solflare"
20721
- ))
20722
- return;
20723
- if (await trySilentSolana(
20724
- anyWin.backpack,
20725
- "backpack",
20726
- "Backpack",
20727
- "backpack"
20728
- ))
20729
- return;
20730
- if (await trySilentSolana(
20731
- anyWin.glow,
20732
- "glow",
20733
- "Glow",
20734
- "glow"
20735
- ))
20736
- return;
20737
- }
20738
- if (!chainType || chainType === "ethereum") {
20739
- const anyWin = win;
20740
- const allProviders = [];
20741
- const eip6963 = getEip6963Providers();
20742
- for (const { provider, walletId } of eip6963) {
20743
- allProviders.push({
20744
- provider,
20745
- walletId: walletId === "unknown" ? "default" : walletId
20746
- });
20747
- }
20748
- if (allProviders.length === 0) {
20749
- if (win.phantom?.ethereum) {
20750
- allProviders.push({
20751
- provider: win.phantom.ethereum,
20752
- walletId: "phantom"
20753
- });
20754
- }
20755
- if (anyWin.okxwallet) {
20756
- allProviders.push({
20757
- provider: anyWin.okxwallet,
20758
- walletId: "okx"
20759
- });
20760
- }
20761
- if (anyWin.coinbaseWalletExtension) {
20762
- allProviders.push({
20763
- provider: anyWin.coinbaseWalletExtension,
20764
- walletId: "coinbase"
20765
- });
20766
- }
20767
- if (win.ethereum) {
20768
- const isDuplicate = allProviders.some(
20769
- (p) => p.provider === win.ethereum
20770
- );
20771
- if (!isDuplicate) {
20772
- allProviders.push({
20773
- provider: win.ethereum,
20774
- walletId: "default"
20775
- });
20776
- }
20777
- }
20778
- }
20779
- for (const { provider, walletId } of allProviders) {
20780
- if (!provider) continue;
20781
- try {
20782
- const accounts = await provider.request({
20783
- method: "eth_accounts"
20784
- });
20785
- if (!accounts || accounts.length === 0) continue;
20786
- const address = accounts[0];
20787
- const resolved = identifyEthWallet(provider, anyWin, walletId);
20788
- if (mounted) {
20789
- setWallet({ ...resolved, address });
20790
- setIsLoading(false);
20791
- }
20792
- return;
20793
- } catch {
20794
- }
20795
- }
20796
- }
20797
- if (mounted) {
20798
- setWallet(null);
20799
- setIsLoading(false);
20800
- }
20801
- } catch (error) {
20802
- console.error("[BrowserWalletButton] Error detecting wallet:", error);
20803
- if (mounted) {
20804
- setWallet(null);
20805
- setIsLoading(false);
20806
- }
20807
- }
20808
- };
20809
- detectWallet();
20810
- const handleAccountsChanged = () => {
20811
- detectWallet();
20812
- };
20813
- const handleDisconnect = () => {
20814
- onDisconnectRef.current?.();
20815
- detectWallet();
20816
- };
20817
- const handleEthAccountsChanged = (accounts) => {
20818
- if (Array.isArray(accounts) && accounts.length === 0) {
20819
- onDisconnectRef.current?.();
20820
- }
20821
- detectWallet();
20822
- };
20823
- const solanaProvider = window.phantom?.solana || window.solana;
20824
- if (solanaProvider) {
20825
- solanaProvider.on("connect", handleAccountsChanged);
20826
- solanaProvider.on("disconnect", handleDisconnect);
20827
- solanaProvider.on("accountChanged", handleAccountsChanged);
20828
- }
20829
- const ethProviders = [];
20830
- for (const { provider } of getEip6963Providers()) {
20831
- const p = provider;
20832
- if (p && !ethProviders.includes(p)) {
20833
- ethProviders.push(p);
20834
- }
20835
- }
20836
- if (window.ethereum && !ethProviders.includes(window.ethereum)) {
20837
- ethProviders.push(window.ethereum);
20838
- }
20839
- if (window.phantom?.ethereum && !ethProviders.includes(window.phantom.ethereum)) {
20840
- ethProviders.push(window.phantom.ethereum);
20841
- }
20842
- for (const provider of ethProviders) {
20843
- provider.on("accountsChanged", handleEthAccountsChanged);
20844
- provider.on("chainChanged", handleAccountsChanged);
20845
- }
20846
- return () => {
20847
- mounted = false;
20848
- if (solanaProvider) {
20849
- solanaProvider.off("connect", handleAccountsChanged);
20850
- solanaProvider.off("disconnect", handleDisconnect);
20851
- solanaProvider.off("accountChanged", handleAccountsChanged);
20852
- }
20853
- for (const provider of ethProviders) {
20854
- const off = provider.off?.bind(provider) ?? provider.removeListener?.bind(provider);
20855
- if (off) {
20856
- off("accountsChanged", handleEthAccountsChanged);
20857
- off("chainChanged", handleAccountsChanged);
20858
- }
20859
- }
20860
- };
20861
- }, [chainType, eip6963ProviderCount]);
20862
20919
  const handleConnect = async () => {
20863
20920
  if (wallet) {
20864
20921
  onClick(wallet);
@@ -20875,6 +20932,7 @@ function BrowserWalletButton({
20875
20932
  if (solanaProvider?.isPhantom) {
20876
20933
  const { publicKey } = await solanaProvider.connect();
20877
20934
  setUserDisconnectedWallet(false);
20935
+ setStoredWalletState("phantom-solana");
20878
20936
  setWallet({
20879
20937
  type: "phantom-solana",
20880
20938
  name: "Phantom",
@@ -20894,8 +20952,10 @@ function BrowserWalletButton({
20894
20952
  if (accounts && accounts.length > 0) {
20895
20953
  setUserDisconnectedWallet(false);
20896
20954
  const isPhantom = ethProvider.isPhantom;
20955
+ const walletType = isPhantom ? "phantom-ethereum" : "metamask";
20956
+ setStoredWalletState(walletType);
20897
20957
  setWallet({
20898
- type: isPhantom ? "phantom-ethereum" : "metamask",
20958
+ type: walletType,
20899
20959
  name: isPhantom ? "Phantom" : "MetaMask",
20900
20960
  address: accounts[0],
20901
20961
  icon: isPhantom ? "phantom" : "metamask"
@@ -20942,7 +21002,7 @@ function BrowserWalletButton({
20942
21002
  border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
20943
21003
  };
20944
21004
  const sortedWallets = featuredWallets ? [...featuredWallets].sort((a, b) => a.position - b.position) : [];
20945
- const walletIconBlock = wallet ? WALLET_ICON_COMPONENTS[wallet.icon] ? React242.createElement(WALLET_ICON_COMPONENTS[wallet.icon], {
21005
+ const walletIconBlock = wallet ? WALLET_ICON_COMPONENTS[wallet.icon] ? React252.createElement(WALLET_ICON_COMPONENTS[wallet.icon], {
20946
21006
  size: 36,
20947
21007
  className: "uf-rounded-lg",
20948
21008
  variant: "color"
@@ -21204,7 +21264,12 @@ function CoinbaseConnect({
21204
21264
  onBack: parentOnBack,
21205
21265
  onDisconnect,
21206
21266
  skipToHoldings,
21207
- onExecutionsChange
21267
+ canGoBack = true,
21268
+ onExecutionsChange,
21269
+ defaultSourceChainType,
21270
+ defaultSourceChainId,
21271
+ defaultSourceTokenAddress,
21272
+ defaultSourceSymbol
21208
21273
  }) {
21209
21274
  const { colors: colors2, fonts, components } = useTheme();
21210
21275
  const { projectConfig } = useProjectConfig({ publishableKey });
@@ -21229,25 +21294,25 @@ function CoinbaseConnect({
21229
21294
  const appName = projectConfig?.project_name ?? "Unifold";
21230
21295
  const t12 = i18n2.connectExchange;
21231
21296
  const initialView = skipToHoldings && getStoredIntegrationToken(IntegrationProvider.COINBASE) ? "holdings" : "select_exchange";
21232
- const [view, setView] = useState212(initialView);
21233
- const [prevView, setPrevView] = useState212(initialView);
21234
- const [isTransitioning, setIsTransitioning] = useState212(false);
21235
- const [exchanges, setExchanges] = useState212([]);
21236
- const [exchangesLoading, setExchangesLoading] = useState212(true);
21237
- const [selectedExchange, setSelectedExchange] = useState212(null);
21238
- const [accessToken, setAccessToken] = useState212(null);
21239
- const [holdings, setHoldings] = useState212([]);
21240
- const [selectedHolding, setSelectedHolding] = useState212(null);
21241
- const [selectedAsset, setSelectedAsset] = useState212(null);
21242
- const [sendAmount, setSendAmount] = useState212("");
21243
- const [transferIntent, setTransferIntent] = useState212(null);
21244
- const [mfaCode, setMfaCode] = useState212("");
21245
- const [mfaError, setMfaError] = useState212(false);
21246
- const [errorMessage, setErrorMessage] = useState212("");
21247
- const [isLoading, setIsLoading] = useState212(initialView === "holdings");
21248
- const [confirmResult, setConfirmResult] = useState212(null);
21249
- const [showTransferDetails, setShowTransferDetails] = useState212(false);
21250
- const [transferDepositWalletId, setTransferDepositWalletId] = useState212(void 0);
21297
+ const [view, setView] = useState222(initialView);
21298
+ const [prevView, setPrevView] = useState222(initialView);
21299
+ const [isTransitioning, setIsTransitioning] = useState222(false);
21300
+ const [exchanges, setExchanges] = useState222([]);
21301
+ const [exchangesLoading, setExchangesLoading] = useState222(true);
21302
+ const [selectedExchange, setSelectedExchange] = useState222(null);
21303
+ const [accessToken, setAccessToken] = useState222(null);
21304
+ const [holdings, setHoldings] = useState222([]);
21305
+ const [selectedHolding, setSelectedHolding] = useState222(null);
21306
+ const [selectedAsset, setSelectedAsset] = useState222(null);
21307
+ const [sendAmount, setSendAmount] = useState222("");
21308
+ const [transferIntent, setTransferIntent] = useState222(null);
21309
+ const [mfaCode, setMfaCode] = useState222("");
21310
+ const [mfaError, setMfaError] = useState222(false);
21311
+ const [errorMessage, setErrorMessage] = useState222("");
21312
+ const [isLoading, setIsLoading] = useState222(initialView === "holdings");
21313
+ const [confirmResult, setConfirmResult] = useState222(null);
21314
+ const [showTransferDetails, setShowTransferDetails] = useState222(false);
21315
+ const [transferDepositWalletId, setTransferDepositWalletId] = useState222(void 0);
21251
21316
  const exchangeSupportedCurrencies = useMemo42(() => {
21252
21317
  const set = /* @__PURE__ */ new Set();
21253
21318
  selectedExchange?.supported_currencies.forEach((c) => set.add(c.toLowerCase()));
@@ -21269,6 +21334,21 @@ function CoinbaseConnect({
21269
21334
  params: defaultTokenParams,
21270
21335
  publishableKey
21271
21336
  });
21337
+ const defaultSourceCurrency = useMemo42(
21338
+ () => resolveDefaultSourceSymbol(supportedTokensData?.data, {
21339
+ defaultSourceChainType,
21340
+ defaultSourceChainId,
21341
+ defaultSourceTokenAddress,
21342
+ defaultSourceSymbol
21343
+ })?.toLowerCase() ?? null,
21344
+ [
21345
+ supportedTokensData,
21346
+ defaultSourceChainType,
21347
+ defaultSourceChainId,
21348
+ defaultSourceTokenAddress,
21349
+ defaultSourceSymbol
21350
+ ]
21351
+ );
21272
21352
  const sortedHoldings = useMemo42(() => {
21273
21353
  const supported = [];
21274
21354
  const unsupported = [];
@@ -21278,13 +21358,42 @@ function CoinbaseConnect({
21278
21358
  if (isSupported) supported.push(account);
21279
21359
  else unsupported.push(account);
21280
21360
  });
21361
+ if (defaultSourceCurrency) {
21362
+ const defaultIndex = supported.findIndex(
21363
+ (account) => account.currency.toLowerCase() === defaultSourceCurrency
21364
+ );
21365
+ if (defaultIndex > 0) {
21366
+ const [defaultHolding] = supported.splice(defaultIndex, 1);
21367
+ supported.unshift(defaultHolding);
21368
+ }
21369
+ }
21281
21370
  return [...supported, ...unsupported];
21282
- }, [holdings, supportedSymbols, exchangeSupportedCurrencies]);
21371
+ }, [
21372
+ holdings,
21373
+ supportedSymbols,
21374
+ exchangeSupportedCurrencies,
21375
+ defaultSourceCurrency
21376
+ ]);
21283
21377
  const selectedHoldingIsSupported = useMemo42(() => {
21284
21378
  if (!selectedHolding) return false;
21285
21379
  const currencyLower = selectedHolding.currency.toLowerCase();
21286
21380
  return (supportedSymbols.size === 0 || supportedSymbols.has(currencyLower)) && (exchangeSupportedCurrencies.size === 0 || exchangeSupportedCurrencies.has(currencyLower));
21287
21381
  }, [selectedHolding, supportedSymbols, exchangeSupportedCurrencies]);
21382
+ useEffect172(() => {
21383
+ if (!defaultSourceCurrency || selectedHolding) return;
21384
+ const defaultHolding = sortedHoldings.find((account) => {
21385
+ const currencyLower = account.currency.toLowerCase();
21386
+ return currencyLower === defaultSourceCurrency && (supportedSymbols.size === 0 || supportedSymbols.has(currencyLower)) && (exchangeSupportedCurrencies.size === 0 || exchangeSupportedCurrencies.has(currencyLower));
21387
+ });
21388
+ if (!defaultHolding) return;
21389
+ setSelectedHolding(defaultHolding);
21390
+ }, [
21391
+ defaultSourceCurrency,
21392
+ selectedHolding,
21393
+ sortedHoldings,
21394
+ supportedSymbols,
21395
+ exchangeSupportedCurrencies
21396
+ ]);
21288
21397
  const exchangeName = selectedExchange?.service_provider_display_name || "Exchange";
21289
21398
  const {
21290
21399
  executions: depositExecutions,
@@ -21302,12 +21411,12 @@ function CoinbaseConnect({
21302
21411
  } : void 0,
21303
21412
  onDepositError: onTransferError
21304
21413
  });
21305
- useEffect162(() => {
21414
+ useEffect172(() => {
21306
21415
  onExecutionsChange?.(depositExecutions);
21307
21416
  }, [depositExecutions, onExecutionsChange]);
21308
- const pollRef = useRef52(null);
21309
- const popupRef = useRef52(null);
21310
- const viewRef = useRef52(initialView);
21417
+ const pollRef = useRef62(null);
21418
+ const popupRef = useRef62(null);
21419
+ const viewRef = useRef62(initialView);
21311
21420
  const transitionTo = useCallback22((nextView) => {
21312
21421
  if (nextView === viewRef.current) return;
21313
21422
  setIsTransitioning(true);
@@ -21337,7 +21446,7 @@ function CoinbaseConnect({
21337
21446
  },
21338
21447
  [publishableKey]
21339
21448
  );
21340
- useEffect162(() => {
21449
+ useEffect172(() => {
21341
21450
  getIntegrationExchanges(publishableKey).then((res) => {
21342
21451
  setExchanges(res.data);
21343
21452
  if (!selectedExchange) {
@@ -21395,7 +21504,7 @@ function CoinbaseConnect({
21395
21504
  },
21396
21505
  [publishableKey, transitionTo, tryRefreshToken]
21397
21506
  );
21398
- useEffect162(() => {
21507
+ useEffect172(() => {
21399
21508
  return () => {
21400
21509
  if (pollRef.current) clearInterval(pollRef.current);
21401
21510
  };
@@ -21591,6 +21700,16 @@ function CoinbaseConnect({
21591
21700
  setIsLoading(false);
21592
21701
  }
21593
21702
  };
21703
+ const handleDisconnect = () => {
21704
+ onDisconnect?.();
21705
+ if (!canGoBack) {
21706
+ setAccessToken(null);
21707
+ setHoldings([]);
21708
+ setSelectedHolding(null);
21709
+ setSelectedAsset(null);
21710
+ transitionTo("select_exchange");
21711
+ }
21712
+ };
21594
21713
  const handleBack = () => {
21595
21714
  switch (view) {
21596
21715
  case "select_exchange":
@@ -21651,7 +21770,7 @@ function CoinbaseConnect({
21651
21770
  DepositHeader,
21652
21771
  {
21653
21772
  title: t12.title,
21654
- showBack: true,
21773
+ showBack: canGoBack,
21655
21774
  onBack: handleBack,
21656
21775
  onClose
21657
21776
  }
@@ -21664,7 +21783,7 @@ function CoinbaseConnect({
21664
21783
  DepositHeader,
21665
21784
  {
21666
21785
  title: t12.title,
21667
- showBack: true,
21786
+ showBack: canGoBack,
21668
21787
  onBack: handleBack,
21669
21788
  onClose
21670
21789
  }
@@ -22376,7 +22495,7 @@ function CoinbaseConnect({
22376
22495
  borderRadius: components.button.borderRadius,
22377
22496
  fontFamily: fonts.medium
22378
22497
  },
22379
- onClick: onDisconnect,
22498
+ onClick: handleDisconnect,
22380
22499
  children: t12.disconnect
22381
22500
  }
22382
22501
  )
@@ -23163,7 +23282,7 @@ function ThemeStyleInjector({
23163
23282
  className
23164
23283
  }) {
23165
23284
  const { colors: colors2, fonts, mode } = useTheme();
23166
- const cssVars = React262.useMemo(() => {
23285
+ const cssVars = React272.useMemo(() => {
23167
23286
  const hexToHSL = (hex) => {
23168
23287
  hex = hex.replace("#", "");
23169
23288
  const r2 = parseInt(hex.slice(0, 2), 16) / 255;
@@ -23223,7 +23342,7 @@ function ThemeStyleInjector({
23223
23342
  ...fonts.regular ? { "--uf-font-family": fonts.regular } : {}
23224
23343
  };
23225
23344
  }, [colors2, fonts.regular]);
23226
- React262.useEffect(() => {
23345
+ React272.useEffect(() => {
23227
23346
  if (typeof document === "undefined") return;
23228
23347
  if (fonts.regular) {
23229
23348
  document.documentElement.style.setProperty(
@@ -23305,9 +23424,9 @@ function DepositsModal({
23305
23424
  themeClass = ""
23306
23425
  }) {
23307
23426
  const { colors: colors2, fonts, components } = useTheme();
23308
- const [allExecutions, setAllExecutions] = useState222(sessionExecutions);
23309
- const [selectedExecution, setSelectedExecution] = useState222(null);
23310
- useEffect182(() => {
23427
+ const [allExecutions, setAllExecutions] = useState232(sessionExecutions);
23428
+ const [selectedExecution, setSelectedExecution] = useState232(null);
23429
+ useEffect192(() => {
23311
23430
  if (!open || !userId) return;
23312
23431
  const fetchExecutions = async () => {
23313
23432
  try {
@@ -23329,7 +23448,7 @@ function DepositsModal({
23329
23448
  clearInterval(pollInterval);
23330
23449
  };
23331
23450
  }, [open, userId, publishableKey, sessionExecutions]);
23332
- useEffect182(() => {
23451
+ useEffect192(() => {
23333
23452
  if (!open) {
23334
23453
  setSelectedExecution(null);
23335
23454
  }
@@ -23460,10 +23579,10 @@ function TokenSelectorSheet({
23460
23579
  }) {
23461
23580
  const { themeClass, colors: colors2, fonts, components } = useTheme();
23462
23581
  const isDarkMode = themeClass.includes("uf-dark");
23463
- const [searchQuery, setSearchQuery] = useState232("");
23464
- const [recentTokens, setRecentTokens] = useState232([]);
23465
- const [hoveredTokenKey, setHoveredTokenKey] = useState232(null);
23466
- useEffect192(() => {
23582
+ const [searchQuery, setSearchQuery] = useState242("");
23583
+ const [recentTokens, setRecentTokens] = useState242([]);
23584
+ const [hoveredTokenKey, setHoveredTokenKey] = useState242(null);
23585
+ useEffect202(() => {
23467
23586
  setRecentTokens(getRecentTokens());
23468
23587
  }, []);
23469
23588
  const allOptions = useMemo62(() => {
@@ -23947,11 +24066,11 @@ function useDefaultToken({
23947
24066
  defaultTokenAddress,
23948
24067
  defaultSymbol
23949
24068
  }) {
23950
- const [token, setToken] = useState242(null);
23951
- const [chain, setChain] = useState242(null);
23952
- const [initialSelectionDone, setInitialSelectionDone] = useState242(false);
23953
- const appliedDefaultsRef = useRef62("");
23954
- useEffect202(() => {
24069
+ const [token, setToken] = useState252(null);
24070
+ const [chain, setChain] = useState252(null);
24071
+ const [initialSelectionDone, setInitialSelectionDone] = useState252(false);
24072
+ const appliedDefaultsRef = useRef72("");
24073
+ useEffect212(() => {
23955
24074
  if (!tokens.length) return;
23956
24075
  const defaultsKey = `${defaultTokenAddress ?? ""}|${defaultSymbol ?? ""}|${defaultChainType ?? ""}|${defaultChainId ?? ""}`;
23957
24076
  const defaultsChanged = appliedDefaultsRef.current !== defaultsKey;
@@ -23977,7 +24096,7 @@ function useDefaultToken({
23977
24096
  defaultChainId,
23978
24097
  initialSelectionDone
23979
24098
  ]);
23980
- useEffect202(() => {
24099
+ useEffect212(() => {
23981
24100
  if (!tokens.length || !token) return;
23982
24101
  const currentToken = tokens.find((t12) => t12.symbol === token);
23983
24102
  if (!currentToken || currentToken.chains.length === 0) return;
@@ -24172,7 +24291,7 @@ function GlossaryModal({
24172
24291
  ) });
24173
24292
  }
24174
24293
  function useCopyAddress() {
24175
- const [copied, setCopied] = useState252(false);
24294
+ const [copied, setCopied] = useState262(false);
24176
24295
  const handleCopy = (address) => {
24177
24296
  if (!address) return;
24178
24297
  navigator.clipboard.writeText(address);
@@ -24182,14 +24301,14 @@ function useCopyAddress() {
24182
24301
  return { copied, handleCopy };
24183
24302
  }
24184
24303
  var TooltipProvider2 = Provider;
24185
- var TooltipContext = React272.createContext({
24304
+ var TooltipContext = React282.createContext({
24186
24305
  open: false,
24187
24306
  onOpenChange: () => {
24188
24307
  }
24189
24308
  });
24190
- var TooltipTrigger2 = React272.forwardRef(({ onClick, ...props }, ref) => {
24191
- const { open, onOpenChange } = React272.useContext(TooltipContext);
24192
- const handleClick = React272.useCallback(
24309
+ var TooltipTrigger2 = React282.forwardRef(({ onClick, ...props }, ref) => {
24310
+ const { open, onOpenChange } = React282.useContext(TooltipContext);
24311
+ const handleClick = React282.useCallback(
24193
24312
  (e) => {
24194
24313
  onOpenChange(!open);
24195
24314
  onClick?.(e);
@@ -24199,7 +24318,7 @@ var TooltipTrigger2 = React272.forwardRef(({ onClick, ...props }, ref) => {
24199
24318
  return /* @__PURE__ */ jsx44(Trigger, { ref, onClick: handleClick, ...props });
24200
24319
  });
24201
24320
  TooltipTrigger2.displayName = Trigger.displayName;
24202
- var TooltipContent2 = React272.forwardRef(({ className, sideOffset = 4, ...props }, ref) => {
24321
+ var TooltipContent2 = React282.forwardRef(({ className, sideOffset = 4, ...props }, ref) => {
24203
24322
  const { themeClass, colors: colors2 } = useTheme();
24204
24323
  return /* @__PURE__ */ jsx44(Portal3, { children: /* @__PURE__ */ jsx44(
24205
24324
  Content22,
@@ -24322,12 +24441,12 @@ function TransferCryptoSingleInput({
24322
24441
  }) {
24323
24442
  const { themeClass, colors: colors2, fonts, components } = useTheme();
24324
24443
  const isDarkMode = themeClass.includes("uf-dark");
24325
- const [copied, setCopied] = useState27(false);
24444
+ const [copied, setCopied] = useState28(false);
24326
24445
  const { copied: copiedRecipient, handleCopy: handleCopyRecipientAddress } = useCopyAddress();
24327
- const [glossaryOpen, setGlossaryOpen] = useState27(false);
24328
- const [detailsExpanded, setDetailsExpanded] = useState27(false);
24329
- const [depositsModalOpen, setDepositsModalOpen] = useState27(false);
24330
- const [tokenSelectorOpen, setTokenSelectorOpen] = useState27(false);
24446
+ const [glossaryOpen, setGlossaryOpen] = useState28(false);
24447
+ const [detailsExpanded, setDetailsExpanded] = useState28(false);
24448
+ const [depositsModalOpen, setDepositsModalOpen] = useState28(false);
24449
+ const [tokenSelectorOpen, setTokenSelectorOpen] = useState28(false);
24331
24450
  const { data: tokensResponse, isLoading: tokensLoading } = useSupportedDepositTokens(publishableKey, {
24332
24451
  destination_token_address: destinationTokenAddress,
24333
24452
  destination_chain_id: destinationChainId,
@@ -24400,7 +24519,7 @@ function TransferCryptoSingleInput({
24400
24519
  publishableKey,
24401
24520
  enabled: !!depositAddress && !!recipientAddress
24402
24521
  });
24403
- useEffect212(() => {
24522
+ useEffect222(() => {
24404
24523
  if (!onSourceTokenChange || !token || !chain || !initialSelectionDone) return;
24405
24524
  const { chainType, chainId } = parseChainKey(chain);
24406
24525
  const matchedToken = supportedTokens.find((t12) => t12.symbol === token);
@@ -24417,7 +24536,7 @@ function TransferCryptoSingleInput({
24417
24536
  isStablecoin: matchedToken?.is_stablecoin ?? false
24418
24537
  });
24419
24538
  }, [token, chain, initialSelectionDone, onSourceTokenChange, supportedTokens]);
24420
- useEffect212(() => {
24539
+ useEffect222(() => {
24421
24540
  if (onExecutionsChange) {
24422
24541
  onExecutionsChange(depositExecutions);
24423
24542
  }
@@ -24804,7 +24923,7 @@ function TransferCryptoSingleInput({
24804
24923
  }
24805
24924
  var Select2 = Root23;
24806
24925
  var SelectValue2 = Value;
24807
- var SelectTrigger2 = React282.forwardRef(({ className, style, children, ...props }, ref) => {
24926
+ var SelectTrigger2 = React292.forwardRef(({ className, style, children, ...props }, ref) => {
24808
24927
  const { components } = useTheme();
24809
24928
  return /* @__PURE__ */ jsxs422(
24810
24929
  Trigger2,
@@ -24828,7 +24947,7 @@ var SelectTrigger2 = React282.forwardRef(({ className, style, children, ...props
24828
24947
  );
24829
24948
  });
24830
24949
  SelectTrigger2.displayName = Trigger2.displayName;
24831
- var SelectScrollUpButton2 = React282.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx47(
24950
+ var SelectScrollUpButton2 = React292.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx47(
24832
24951
  ScrollUpButton,
24833
24952
  {
24834
24953
  ref,
@@ -24841,7 +24960,7 @@ var SelectScrollUpButton2 = React282.forwardRef(({ className, ...props }, ref) =
24841
24960
  }
24842
24961
  ));
24843
24962
  SelectScrollUpButton2.displayName = ScrollUpButton.displayName;
24844
- var SelectScrollDownButton2 = React282.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx47(
24963
+ var SelectScrollDownButton2 = React292.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx47(
24845
24964
  ScrollDownButton,
24846
24965
  {
24847
24966
  ref,
@@ -24854,7 +24973,7 @@ var SelectScrollDownButton2 = React282.forwardRef(({ className, ...props }, ref)
24854
24973
  }
24855
24974
  ));
24856
24975
  SelectScrollDownButton2.displayName = ScrollDownButton.displayName;
24857
- var SelectContent2 = React282.forwardRef(({ className, style, children, position = "popper", ...props }, ref) => {
24976
+ var SelectContent2 = React292.forwardRef(({ className, style, children, position = "popper", ...props }, ref) => {
24858
24977
  const { themeClass, colors: colors2, components } = useTheme();
24859
24978
  return /* @__PURE__ */ jsx47(Portal4, { children: /* @__PURE__ */ jsxs422(
24860
24979
  Content23,
@@ -24892,7 +25011,7 @@ var SelectContent2 = React282.forwardRef(({ className, style, children, position
24892
25011
  ) });
24893
25012
  });
24894
25013
  SelectContent2.displayName = Content23.displayName;
24895
- var SelectLabel2 = React282.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx47(
25014
+ var SelectLabel2 = React292.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx47(
24896
25015
  Label,
24897
25016
  {
24898
25017
  ref,
@@ -24904,7 +25023,7 @@ var SelectLabel2 = React282.forwardRef(({ className, ...props }, ref) => /* @__P
24904
25023
  }
24905
25024
  ));
24906
25025
  SelectLabel2.displayName = Label.displayName;
24907
- var SelectItem2 = React282.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs422(
25026
+ var SelectItem2 = React292.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs422(
24908
25027
  Item,
24909
25028
  {
24910
25029
  ref,
@@ -24920,7 +25039,7 @@ var SelectItem2 = React282.forwardRef(({ className, children, ...props }, ref) =
24920
25039
  }
24921
25040
  ));
24922
25041
  SelectItem2.displayName = Item.displayName;
24923
- var SelectSeparator2 = React282.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx47(
25042
+ var SelectSeparator2 = React292.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx47(
24924
25043
  Separator,
24925
25044
  {
24926
25045
  ref,
@@ -24956,11 +25075,11 @@ function TransferCryptoDoubleInput({
24956
25075
  }) {
24957
25076
  const { themeClass, colors: colors2, fonts, components } = useTheme();
24958
25077
  const isDarkMode = themeClass.includes("uf-dark");
24959
- const [copied, setCopied] = useState28(false);
25078
+ const [copied, setCopied] = useState29(false);
24960
25079
  const { copied: copiedRecipient, handleCopy: handleCopyRecipientAddress } = useCopyAddress();
24961
- const [glossaryOpen, setGlossaryOpen] = useState28(false);
24962
- const [detailsExpanded, setDetailsExpanded] = useState28(false);
24963
- const [depositsModalOpen, setDepositsModalOpen] = useState28(false);
25080
+ const [glossaryOpen, setGlossaryOpen] = useState29(false);
25081
+ const [detailsExpanded, setDetailsExpanded] = useState29(false);
25082
+ const [depositsModalOpen, setDepositsModalOpen] = useState29(false);
24964
25083
  const { data: tokensResponse, isLoading: tokensLoading } = useSupportedDepositTokens(publishableKey, {
24965
25084
  destination_token_address: destinationTokenAddress,
24966
25085
  destination_chain_id: destinationChainId,
@@ -25031,7 +25150,7 @@ function TransferCryptoDoubleInput({
25031
25150
  publishableKey,
25032
25151
  enabled: !!depositAddress && !!recipientAddress
25033
25152
  });
25034
- useEffect222(() => {
25153
+ useEffect232(() => {
25035
25154
  if (onExecutionsChange) {
25036
25155
  onExecutionsChange(depositExecutions);
25037
25156
  }
@@ -26305,13 +26424,13 @@ function ConfirmingView({
26305
26424
  amountReceivedUsdAtSubmission
26306
26425
  }) {
26307
26426
  const { colors: colors2, fonts, components } = useTheme();
26308
- const [fallbackSettled, setFallbackSettled] = useState292(false);
26427
+ const [fallbackSettled, setFallbackSettled] = useState302(false);
26309
26428
  const hasExecution = executions.length > 0;
26310
26429
  const isCheckoutMode = paymentIntentStatus != null;
26311
26430
  const isPaymentComplete = paymentIntentStatus === "succeeded";
26312
26431
  const amountChanged = amountReceivedUsdAtSubmission != null && amountReceivedUsd != null && amountReceivedUsd !== amountReceivedUsdAtSubmission;
26313
26432
  const piSettled = !isCheckoutMode || isPaymentComplete || amountChanged || fallbackSettled;
26314
- useEffect232(() => {
26433
+ useEffect242(() => {
26315
26434
  if (!hasExecution || piSettled) return;
26316
26435
  const timeout = setTimeout(() => setFallbackSettled(true), SETTLE_FALLBACK_MS);
26317
26436
  return () => clearTimeout(timeout);
@@ -26440,6 +26559,19 @@ var WALLET_DEFINITIONS = [
26440
26559
  { id: "backpack", name: "Backpack", networks: ["solana"], installUrl: "https://backpack.app/" },
26441
26560
  { id: "glow", name: "Glow", networks: ["solana"], installUrl: "https://glow.app/" }
26442
26561
  ];
26562
+ function normalizeTokenAddress(address) {
26563
+ const normalized = (address ?? "").toLowerCase();
26564
+ if (normalized === "" || normalized === "native" || normalized === "0x0000000000000000000000000000000000000000") {
26565
+ return "native";
26566
+ }
26567
+ return normalized;
26568
+ }
26569
+ function balancesRepresentSameToken(a, b) {
26570
+ const tokenA = getTokenFromBalance(a);
26571
+ const tokenB = getTokenFromBalance(b);
26572
+ if (!tokenA || !tokenB) return false;
26573
+ return tokenA.chain_type === tokenB.chain_type && tokenA.chain_id === tokenB.chain_id && normalizeTokenAddress(tokenA.token_address) === normalizeTokenAddress(tokenB.token_address);
26574
+ }
26443
26575
  function getSolanaProviders() {
26444
26576
  if (typeof window === "undefined") return {};
26445
26577
  const win = window;
@@ -26582,24 +26714,33 @@ function WalletConnect({
26582
26714
  checkoutRemainingBaseUnits,
26583
26715
  stablecoinParity = false,
26584
26716
  productType,
26717
+ defaultSourceChainType,
26718
+ defaultSourceChainId,
26719
+ defaultSourceTokenAddress,
26720
+ defaultSourceSymbol,
26585
26721
  onBack: parentOnBack,
26586
26722
  onClose,
26723
+ canGoBack = true,
26724
+ depositWalletsLoading = false,
26587
26725
  onExecutionsChange
26588
26726
  }) {
26589
26727
  const { colors: colors2, fonts, components } = useTheme();
26590
- const walletProvidedAtMount = React292.useRef(!!initialWalletInfo && !!initialDepositWallet);
26591
- const [activeWalletInfo, setActiveWalletInfo] = React292.useState(initialWalletInfo ?? null);
26592
- const [activeDepositWallet, setActiveDepositWallet] = React292.useState(initialDepositWallet ?? null);
26728
+ const walletProvidedAtMount = React302.useRef(!!initialWalletInfo && !!initialDepositWallet);
26729
+ const [activeWalletInfo, setActiveWalletInfo] = React302.useState(initialWalletInfo ?? null);
26730
+ const [activeDepositWallet, setActiveDepositWallet] = React302.useState(initialDepositWallet ?? null);
26593
26731
  const initialView = initialWalletInfo && initialDepositWallet ? "select_token" : "select_wallet";
26594
- const [view, setView] = React292.useState(initialView);
26595
- const [isTransitioning, setIsTransitioning] = React292.useState(false);
26596
- const viewRef = React292.useRef(initialView);
26597
- const [selectedWalletDef, setSelectedWalletDef] = React292.useState(null);
26598
- const [connectingNetwork, setConnectingNetwork] = React292.useState(null);
26599
- const [walletError, setWalletError] = React292.useState(null);
26600
- const [isWalletConnecting, setIsWalletConnecting] = React292.useState(false);
26601
- const [eip6963ProviderCount, setEip6963ProviderCount] = React292.useState(0);
26602
- React292.useEffect(() => {
26732
+ const [view, setView] = React302.useState(initialView);
26733
+ const [isTransitioning, setIsTransitioning] = React302.useState(false);
26734
+ const viewRef = React302.useRef(initialView);
26735
+ const standalone = !canGoBack && !walletProvidedAtMount.current;
26736
+ const { wallet: detectedWallet, isLoading: detectingWallet } = useDetectedBrowserWallet({ enabled: standalone });
26737
+ const [autoResolved, setAutoResolved] = React302.useState(false);
26738
+ const [selectedWalletDef, setSelectedWalletDef] = React302.useState(null);
26739
+ const [connectingNetwork, setConnectingNetwork] = React302.useState(null);
26740
+ const [walletError, setWalletError] = React302.useState(null);
26741
+ const [isWalletConnecting, setIsWalletConnecting] = React302.useState(false);
26742
+ const [eip6963ProviderCount, setEip6963ProviderCount] = React302.useState(0);
26743
+ React302.useEffect(() => {
26603
26744
  const store = getEip6963Store();
26604
26745
  if (!store) return;
26605
26746
  setEip6963ProviderCount(store.getProviders().length);
@@ -26607,20 +26748,44 @@ function WalletConnect({
26607
26748
  setEip6963ProviderCount(providers.length);
26608
26749
  });
26609
26750
  }, []);
26610
- const availableWallets = React292.useMemo(() => detectAvailableWallets(), [eip6963ProviderCount]);
26611
- const [balances, setBalances] = React292.useState([]);
26612
- const [isLoading, setIsLoading] = React292.useState(false);
26613
- const [selectedBalance, setSelectedBalance] = React292.useState(null);
26614
- const [totalBalanceUsd, setTotalBalanceUsd] = React292.useState(null);
26615
- const [error, setError] = React292.useState(null);
26616
- const [isDisconnectingWallet, setIsDisconnectingWallet] = React292.useState(false);
26617
- const [amountUsd, setAmountUsd] = React292.useState(prefillAmountUsd ?? "");
26618
- const [isConfirming, setIsConfirming] = React292.useState(false);
26619
- const [hasSignedTransaction, setHasSignedTransaction] = React292.useState(false);
26620
- const [tokenChainDetails, setTokenChainDetails] = React292.useState(null);
26621
- const [loadingTokenDetails, setLoadingTokenDetails] = React292.useState(false);
26622
- const [showTransactionDetails, setShowTransactionDetails] = React292.useState(false);
26623
- const [receivedUsdAtSubmission, setReceivedUsdAtSubmission] = React292.useState(null);
26751
+ const availableWallets = React302.useMemo(() => detectAvailableWallets(), [eip6963ProviderCount]);
26752
+ React302.useEffect(() => {
26753
+ if (!standalone || autoResolved || detectingWallet) return;
26754
+ if (!detectedWallet) {
26755
+ setAutoResolved(true);
26756
+ return;
26757
+ }
26758
+ const wct = detectedWallet.type === "phantom-solana" || detectedWallet.type === "solflare" || detectedWallet.type === "backpack" || detectedWallet.type === "glow" ? "solana" : "ethereum";
26759
+ const matching = depositWallets?.find((w) => w.chain_type === wct);
26760
+ if (!matching) {
26761
+ if (!depositWalletsLoading) setAutoResolved(true);
26762
+ return;
26763
+ }
26764
+ setActiveWalletInfo(detectedWallet);
26765
+ setActiveDepositWallet(matching);
26766
+ onWalletConnected?.(detectedWallet, matching);
26767
+ setView("select_token");
26768
+ viewRef.current = "select_token";
26769
+ setAutoResolved(true);
26770
+ }, [standalone, autoResolved, detectingWallet, detectedWallet, depositWallets, depositWalletsLoading]);
26771
+ React302.useEffect(() => {
26772
+ if (!standalone || autoResolved) return;
26773
+ const t12 = setTimeout(() => setAutoResolved(true), 5e3);
26774
+ return () => clearTimeout(t12);
26775
+ }, [standalone, autoResolved]);
26776
+ const [balances, setBalances] = React302.useState([]);
26777
+ const [isLoading, setIsLoading] = React302.useState(false);
26778
+ const [selectedBalance, setSelectedBalance] = React302.useState(null);
26779
+ const [totalBalanceUsd, setTotalBalanceUsd] = React302.useState(null);
26780
+ const [error, setError] = React302.useState(null);
26781
+ const [isDisconnectingWallet, setIsDisconnectingWallet] = React302.useState(false);
26782
+ const [amountUsd, setAmountUsd] = React302.useState(prefillAmountUsd ?? "");
26783
+ const [isConfirming, setIsConfirming] = React302.useState(false);
26784
+ const [hasSignedTransaction, setHasSignedTransaction] = React302.useState(false);
26785
+ const [tokenChainDetails, setTokenChainDetails] = React302.useState(null);
26786
+ const [loadingTokenDetails, setLoadingTokenDetails] = React302.useState(false);
26787
+ const [showTransactionDetails, setShowTransactionDetails] = React302.useState(false);
26788
+ const [receivedUsdAtSubmission, setReceivedUsdAtSubmission] = React302.useState(null);
26624
26789
  const walletInfo = activeWalletInfo;
26625
26790
  const depositWallet = activeDepositWallet;
26626
26791
  const hasWallet = !!activeWalletInfo && !!activeDepositWallet;
@@ -26628,7 +26793,7 @@ function WalletConnect({
26628
26793
  const recipientAddress = activeDepositWallet?.address ?? "";
26629
26794
  const isCheckoutMode = !!checkoutAmountUsd;
26630
26795
  const supportedChainType = chainType === "algorand" || chainType === "xrpl" ? "ethereum" : chainType;
26631
- const transitionTo = React292.useCallback((nextView) => {
26796
+ const transitionTo = React302.useCallback((nextView) => {
26632
26797
  if (nextView === viewRef.current) return;
26633
26798
  setIsTransitioning(true);
26634
26799
  setTimeout(() => {
@@ -26713,6 +26878,7 @@ function WalletConnect({
26713
26878
  metamask: "metamask"
26714
26879
  };
26715
26880
  const walletType = walletIdToType[wallet.id] || "metamask";
26881
+ setStoredWalletState(walletType);
26716
26882
  connectedInfo = { type: walletType, name: wallet.name, address: accounts[0], icon: wallet.id };
26717
26883
  } else {
26718
26884
  const solProviders = getSolanaProviders();
@@ -26741,6 +26907,7 @@ function WalletConnect({
26741
26907
  const response = await provider.connect();
26742
26908
  setUserDisconnectedWallet(false);
26743
26909
  const walletType = wallet.id === "solflare" ? "solflare" : wallet.id === "backpack" ? "backpack" : wallet.id === "glow" ? "glow" : "phantom-solana";
26910
+ setStoredWalletState(walletType);
26744
26911
  connectedInfo = { type: walletType, name: wallet.name, address: response.publicKey.toString(), icon: wallet.id };
26745
26912
  }
26746
26913
  const walletChainType = network === "solana" ? "solana" : "ethereum";
@@ -26765,7 +26932,7 @@ function WalletConnect({
26765
26932
  }
26766
26933
  };
26767
26934
  const selectedToken = selectedBalance ? getTokenFromBalance(selectedBalance) : null;
26768
- const effectiveDestinationAmount = React292.useMemo(() => {
26935
+ const effectiveDestinationAmount = React302.useMemo(() => {
26769
26936
  if (!checkoutRemainingBaseUnits || checkoutRemainingBaseUnits === "0") return "0";
26770
26937
  if (!checkoutAmountUsd) return checkoutRemainingBaseUnits;
26771
26938
  const remaining = BigInt(checkoutRemainingBaseUnits);
@@ -26793,7 +26960,7 @@ function WalletConnect({
26793
26960
  stablecoinParity,
26794
26961
  enabled: isCheckoutMode && !!selectedToken && !!checkoutDestination && effectiveDestinationAmount !== "0"
26795
26962
  });
26796
- const activeCheckoutQuote = React292.useMemo(() => {
26963
+ const activeCheckoutQuote = React302.useMemo(() => {
26797
26964
  if (!isCheckoutMode) return null;
26798
26965
  if (walletCheckoutQuote) return { sourceAmount: walletCheckoutQuote.source_amount, sourceTokenDecimals: walletCheckoutQuote.source_token_decimals, sourceTokenSymbol: walletCheckoutQuote.source_token_symbol, sourceAmountUsd: walletCheckoutQuote.source_amount_usd, slippageBufferPercent: walletCheckoutQuote.slippage_buffer_percent ?? null };
26799
26966
  return checkoutQuote ?? null;
@@ -26807,19 +26974,19 @@ function WalletConnect({
26807
26974
  onDepositSuccess,
26808
26975
  onDepositError
26809
26976
  });
26810
- React292.useEffect(() => {
26977
+ React302.useEffect(() => {
26811
26978
  onExecutionsChange?.(depositExecutions);
26812
26979
  }, [depositExecutions, onExecutionsChange]);
26813
- React292.useEffect(() => {
26980
+ React302.useEffect(() => {
26814
26981
  if (!prefillAmountUsd || !tokenChainDetails || view !== "enter_amount") return;
26815
26982
  const minDeposit = tokenChainDetails.minimum_deposit_amount_usd || 0;
26816
26983
  const currentAmount = parseFloat(amountUsd) || 0;
26817
26984
  if (currentAmount > 0 && currentAmount < minDeposit) setAmountUsd(minDeposit.toFixed(2));
26818
26985
  }, [tokenChainDetails, view, prefillAmountUsd]);
26819
- React292.useEffect(() => {
26986
+ React302.useEffect(() => {
26820
26987
  if (view === "review") setShowTransactionDetails(false);
26821
26988
  }, [view]);
26822
- React292.useEffect(() => {
26989
+ React302.useEffect(() => {
26823
26990
  if (view !== "enter_amount" && view !== "review" || !selectedBalance || !activeDepositWallet) return;
26824
26991
  let cancelled = false;
26825
26992
  const fetchTokenDetails = async () => {
@@ -26846,7 +27013,7 @@ function WalletConnect({
26846
27013
  cancelled = true;
26847
27014
  };
26848
27015
  }, [view, selectedBalance, publishableKey, activeDepositWallet]);
26849
- React292.useEffect(() => {
27016
+ React302.useEffect(() => {
26850
27017
  if (!activeWalletInfo || !activeDepositWallet) return;
26851
27018
  let cancelled = false;
26852
27019
  setIsLoading(true);
@@ -26855,18 +27022,33 @@ function WalletConnect({
26855
27022
  getAddressBalances(activeWalletInfo.address, sct, publishableKey).then((response) => {
26856
27023
  if (cancelled) return;
26857
27024
  const nonZero = response.balances.filter((b) => b.amount !== "0");
26858
- const sorted = [...nonZero].sort((a, b) => {
26859
- const ae = isBalanceEligible(a);
26860
- const be = isBalanceEligible(b);
26861
- if (ae && !be) return -1;
26862
- if (!ae && be) return 1;
26863
- return 0;
26864
- });
27025
+ const defaultSource = {
27026
+ defaultSourceChainType,
27027
+ defaultSourceChainId,
27028
+ defaultSourceTokenAddress,
27029
+ defaultSourceSymbol
27030
+ };
27031
+ const sorted = [...nonZero].sort(
27032
+ (a, b) => compareBalancesWithDefaultSource(a, b, defaultSource)
27033
+ );
26865
27034
  setBalances(sorted);
26866
27035
  const totalUsd = nonZero.reduce((sum, b) => b.amount_usd ? sum + parseFloat(b.amount_usd) : sum, 0);
26867
27036
  if (totalUsd > 0) setTotalBalanceUsd(totalUsd.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 }));
26868
27037
  const eligible = sorted.filter(isBalanceEligible);
26869
- if (eligible.length === 1) setSelectedBalance(eligible[0]);
27038
+ const defaultBalance = sorted.find(
27039
+ (balance) => isDefaultSourceBalance(balance, defaultSource)
27040
+ );
27041
+ setSelectedBalance((current) => {
27042
+ if (current) {
27043
+ const currentInNewBalances = sorted.find(
27044
+ (balance) => balancesRepresentSameToken(balance, current)
27045
+ );
27046
+ if (currentInNewBalances) return currentInNewBalances;
27047
+ }
27048
+ if (defaultBalance) return defaultBalance;
27049
+ if (eligible.length === 1) return eligible[0];
27050
+ return null;
27051
+ });
26870
27052
  }).catch((err) => {
26871
27053
  if (!cancelled) {
26872
27054
  console.error("[WalletConnect] Error fetching balances:", err);
@@ -26878,21 +27060,29 @@ function WalletConnect({
26878
27060
  return () => {
26879
27061
  cancelled = true;
26880
27062
  };
26881
- }, [activeWalletInfo?.address, activeDepositWallet?.chain_type, publishableKey]);
26882
- const usdToTokenRate = React292.useMemo(() => {
27063
+ }, [
27064
+ activeWalletInfo?.address,
27065
+ activeDepositWallet?.chain_type,
27066
+ publishableKey,
27067
+ defaultSourceChainType,
27068
+ defaultSourceChainId,
27069
+ defaultSourceTokenAddress,
27070
+ defaultSourceSymbol
27071
+ ]);
27072
+ const usdToTokenRate = React302.useMemo(() => {
26883
27073
  if (!selectedBalance || !selectedBalance.amount_usd || !selectedToken) return 0;
26884
27074
  const balanceAmount = Number(selectedBalance.amount) / 10 ** selectedToken.decimals;
26885
27075
  const balanceUsd = parseFloat(selectedBalance.amount_usd);
26886
27076
  if (balanceAmount === 0 || balanceUsd === 0) return 0;
26887
27077
  return balanceAmount / balanceUsd;
26888
27078
  }, [selectedBalance, selectedToken]);
26889
- const tokenAmount = React292.useMemo(() => {
27079
+ const tokenAmount = React302.useMemo(() => {
26890
27080
  if (isCheckoutMode && activeCheckoutQuote && selectedToken) return Number(activeCheckoutQuote.sourceAmount) / 10 ** activeCheckoutQuote.sourceTokenDecimals;
26891
27081
  const usdNum = parseFloat(amountUsd) || 0;
26892
27082
  if (usdNum === 0 || usdToTokenRate === 0) return 0;
26893
27083
  return usdNum * usdToTokenRate;
26894
27084
  }, [amountUsd, usdToTokenRate, isCheckoutMode, activeCheckoutQuote, selectedToken]);
26895
- React292.useEffect(() => {
27085
+ React302.useEffect(() => {
26896
27086
  if (isCheckoutMode && activeCheckoutQuote?.sourceAmountUsd && view === "enter_amount") setAmountUsd(activeCheckoutQuote.sourceAmountUsd);
26897
27087
  }, [isCheckoutMode, activeCheckoutQuote, view]);
26898
27088
  const maxTokenAmount = selectedBalance && selectedToken ? Number(selectedBalance.amount) / 10 ** selectedToken.decimals : 0;
@@ -26900,7 +27090,7 @@ function WalletConnect({
26900
27090
  const inputUsdNum = parseFloat(amountUsd) || 0;
26901
27091
  const minDepositUsd = tokenChainDetails?.minimum_deposit_amount_usd || 0;
26902
27092
  const isValidAmount = isCheckoutMode && activeCheckoutQuote ? tokenAmount > 0 && tokenAmount <= maxTokenAmount : inputUsdNum > 0 && inputUsdNum <= maxUsdAmount && inputUsdNum >= minDepositUsd;
26903
- const formattedTokenAmount = React292.useMemo(() => {
27093
+ const formattedTokenAmount = React302.useMemo(() => {
26904
27094
  if (tokenAmount === 0 || !selectedToken) return null;
26905
27095
  return `${tokenAmount.toFixed(6)} ${selectedToken.symbol}`.replace(/\.?0+$/, "");
26906
27096
  }, [tokenAmount, selectedToken]);
@@ -26948,16 +27138,25 @@ function WalletConnect({
26948
27138
  } catch (err) {
26949
27139
  console.warn("[WalletConnect] disconnect error:", err);
26950
27140
  } finally {
26951
- setActiveWalletInfo(null);
26952
- setActiveDepositWallet(null);
26953
- setSelectedBalance(null);
26954
- setBalances([]);
26955
- setTotalBalanceUsd(null);
26956
- setAmountUsd(prefillAmountUsd ?? "");
26957
- setError(null);
26958
27141
  setIsDisconnectingWallet(false);
26959
- if (onWalletDisconnect) onWalletDisconnect();
26960
- else parentOnBack?.();
27142
+ const clearWalletState = () => {
27143
+ setActiveWalletInfo(null);
27144
+ setActiveDepositWallet(null);
27145
+ setSelectedBalance(null);
27146
+ setBalances([]);
27147
+ setTotalBalanceUsd(null);
27148
+ setAmountUsd(prefillAmountUsd ?? "");
27149
+ setError(null);
27150
+ };
27151
+ if (standalone) {
27152
+ onWalletDisconnect?.();
27153
+ transitionTo("select_wallet");
27154
+ setTimeout(clearWalletState, 160);
27155
+ } else {
27156
+ clearWalletState();
27157
+ if (onWalletDisconnect) onWalletDisconnect();
27158
+ else parentOnBack?.();
27159
+ }
26961
27160
  }
26962
27161
  };
26963
27162
  const handleReview = () => {
@@ -27083,9 +27282,15 @@ function WalletConnect({
27083
27282
  setIsConfirming(false);
27084
27283
  }
27085
27284
  };
27285
+ if (standalone && !autoResolved) {
27286
+ return /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
27287
+ /* @__PURE__ */ jsx54(DepositHeader, { title: "Connect Wallet", showBack: canGoBack, onBack: handleBack, onClose }),
27288
+ /* @__PURE__ */ jsx54("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-16", children: /* @__PURE__ */ jsx54(LoaderCircle, { className: "uf-w-8 uf-h-8 uf-animate-spin", style: { color: colors2.primary } }) })
27289
+ ] });
27290
+ }
27086
27291
  if (view === "select_wallet") {
27087
27292
  return /* @__PURE__ */ jsxs48("div", { style: viewTransitionStyle, children: [
27088
- /* @__PURE__ */ jsx54(DepositHeader, { title: "Connect Wallet", showBack: true, onBack: handleBack, onClose }),
27293
+ /* @__PURE__ */ jsx54(DepositHeader, { title: "Connect Wallet", showBack: canGoBack, onBack: handleBack, onClose }),
27089
27294
  /* @__PURE__ */ jsxs48("div", { className: "uf-pb-4", children: [
27090
27295
  /* @__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" }),
27091
27296
  /* @__PURE__ */ jsx54("div", { className: "uf-space-y-2", style: { maxHeight: 330, overflowY: "auto" }, children: availableWallets.map((wallet) => /* @__PURE__ */ jsxs48(
@@ -27218,16 +27423,17 @@ function DepositModal({
27218
27423
  defaultSourceChainId,
27219
27424
  defaultSourceTokenAddress,
27220
27425
  defaultSourceSymbol,
27221
- hideDepositTracker = false,
27426
+ hideDepositTracker,
27222
27427
  showBalanceHeader = false,
27223
27428
  transferInputVariant = "double_input",
27224
27429
  depositConfirmationMode = "auto_ui",
27225
- enableConnectWallet = false,
27430
+ enableTransferCrypto,
27431
+ enableConnectWallet,
27226
27432
  browserWalletAmountQuickSelect = "percentage",
27227
27433
  enablePayWithExchange,
27228
27434
  enableFiatOnramp,
27229
- enableConnectExchange = false,
27230
- enableCashApp = false,
27435
+ enableConnectExchange,
27436
+ enableCashApp,
27231
27437
  hideDepositFlowInfo = false,
27232
27438
  hideDisplayDescription = false,
27233
27439
  onDepositSuccess,
@@ -27245,49 +27451,72 @@ function DepositModal({
27245
27451
  const { colors: colors2, fonts, components } = useTheme();
27246
27452
  const effectiveInitialScreen = useMemo10(() => {
27247
27453
  const s = initialScreen ?? "main";
27248
- if (s === "tracker" && hideDepositTracker) return "main";
27249
- if (s === "cashapp" && !enableCashApp) return "main";
27454
+ if (s === "tracker" && hideDepositTracker === true) return "main";
27455
+ if (s === "cashapp" && enableCashApp === false) return "main";
27250
27456
  if (s === "card" && enableFiatOnramp === false) return "main";
27457
+ if (s === "pay_with_exchange") return enablePayWithExchange === false ? "main" : "exchange";
27458
+ if (s === "exchange_connect")
27459
+ return enableConnectExchange === false ? "main" : "coinbase_connect";
27460
+ if (s === "wallet_connect") return enableConnectWallet === false ? "main" : "wallet_connect";
27251
27461
  return s;
27252
- }, [initialScreen, hideDepositTracker, enableCashApp, enableFiatOnramp]);
27253
- const [containerEl, setContainerEl] = useState31(null);
27462
+ }, [
27463
+ initialScreen,
27464
+ hideDepositTracker,
27465
+ enableCashApp,
27466
+ enableFiatOnramp,
27467
+ enablePayWithExchange,
27468
+ enableConnectExchange,
27469
+ enableConnectWallet
27470
+ ]);
27471
+ const [containerEl, setContainerEl] = useState32(null);
27254
27472
  const containerCallbackRef = useCallback52((el) => {
27255
27473
  setContainerEl(el);
27256
27474
  }, []);
27257
- const [view, setView] = useState31(
27475
+ const [view, setView] = useState32(
27258
27476
  effectiveInitialScreen
27259
27477
  );
27260
- const [coinbaseSkipToHoldings, setCoinbaseSkipToHoldings] = useState31(false);
27261
- const resetViewTimeoutRef = useRef82(null);
27262
- const [cardView, setCardView] = useState31(
27478
+ const [coinbaseSkipToHoldings, setCoinbaseSkipToHoldings] = useState32(false);
27479
+ const resetViewTimeoutRef = useRef92(null);
27480
+ const [cardView, setCardView] = useState32(
27263
27481
  "amount"
27264
27482
  );
27265
- const [exchangeView, setExchangeView] = useState31(
27483
+ const [exchangeView, setExchangeView] = useState32(
27266
27484
  "providers"
27267
27485
  );
27268
- const [browserWalletModalOpen, setBrowserWalletModalOpen] = useState31(false);
27269
- const [browserWalletInfo, setBrowserWalletInfo] = useState31(null);
27270
- const [walletSelectionModalOpen, setWalletSelectionModalOpen] = useState31(false);
27271
- const [browserWalletChainType, setBrowserWalletChainType] = useState31(() => getStoredWalletChainType());
27272
- const [quotesCount, setQuotesCount] = useState31(0);
27273
- const [allExecutions, setAllExecutions] = useState31([]);
27274
- const [selectedExecution, setSelectedExecution] = useState31(null);
27275
- const [depositExecutions, setDepositExecutions] = useState31([]);
27486
+ const [browserWalletModalOpen, setBrowserWalletModalOpen] = useState32(false);
27487
+ const [browserWalletInfo, setBrowserWalletInfo] = useState32(null);
27488
+ const [walletSelectionModalOpen, setWalletSelectionModalOpen] = useState32(false);
27489
+ const [browserWalletChainType, setBrowserWalletChainType] = useState32(() => getStoredWalletState()?.chainType);
27490
+ const [quotesCount, setQuotesCount] = useState32(0);
27491
+ const [allExecutions, setAllExecutions] = useState32([]);
27492
+ const [selectedExecution, setSelectedExecution] = useState32(null);
27493
+ const [depositExecutions, setDepositExecutions] = useState32([]);
27276
27494
  const isMobileView = useIsMobileViewport();
27277
- const [integrationExchanges, setIntegrationExchanges] = useState31([]);
27278
- useEffect25(() => {
27279
- if (!enableConnectExchange || !open) return;
27495
+ const { projectConfig } = useProjectConfig({
27496
+ publishableKey,
27497
+ enabled: open
27498
+ });
27499
+ const showTransferCrypto = enableTransferCrypto ?? projectConfig?.transfer_crypto?.enabled ?? true;
27500
+ const showConnectWallet = enableConnectWallet ?? projectConfig?.connect_wallet?.enabled ?? true;
27501
+ const showPayWithExchange = enablePayWithExchange ?? projectConfig?.pay_with_exchange?.enabled ?? true;
27502
+ const showFiatOnramp = enableFiatOnramp ?? projectConfig?.fiat_onramp?.enabled ?? true;
27503
+ const showConnectExchange = enableConnectExchange ?? projectConfig?.connect_exchange?.enabled ?? true;
27504
+ const showCashApp = enableCashApp ?? projectConfig?.cash_app?.enabled ?? true;
27505
+ const showDepositTracker = hideDepositTracker ? false : projectConfig?.deposit_tracker?.enabled ?? true;
27506
+ const [integrationExchanges, setIntegrationExchanges] = useState32([]);
27507
+ useEffect26(() => {
27508
+ if (!showConnectExchange || !open) return;
27280
27509
  getIntegrationExchanges(publishableKey).then((res) => setIntegrationExchanges(res.data)).catch(() => {
27281
27510
  });
27282
- }, [enableConnectExchange, open, publishableKey]);
27283
- const [connectedExchange, setConnectedExchange] = useState31(() => {
27284
- if (!enableConnectExchange) return null;
27511
+ }, [showConnectExchange, open, publishableKey]);
27512
+ const [connectedExchange, setConnectedExchange] = useState32(() => {
27513
+ if (!showConnectExchange) return null;
27285
27514
  const stored = getStoredIntegrationToken(IntegrationProvider.COINBASE);
27286
27515
  if (!stored) return null;
27287
27516
  return { name: "Coinbase", iconUrl: void 0, balanceUsd: null, isLoading: true };
27288
27517
  });
27289
- useEffect25(() => {
27290
- if (!enableConnectExchange || !open || view !== "main") return;
27518
+ useEffect26(() => {
27519
+ if (!showConnectExchange || !open || view !== "main") return;
27291
27520
  const stored = getStoredIntegrationToken(IntegrationProvider.COINBASE);
27292
27521
  if (!stored) {
27293
27522
  setConnectedExchange(null);
@@ -27322,8 +27551,8 @@ function DepositModal({
27322
27551
  setConnectedExchange(null);
27323
27552
  }
27324
27553
  });
27325
- }, [enableConnectExchange, open, view, publishableKey]);
27326
- useEffect25(() => {
27554
+ }, [showConnectExchange, open, view, publishableKey]);
27555
+ useEffect26(() => {
27327
27556
  if (!connectedExchange || integrationExchanges.length === 0) return;
27328
27557
  const cbExchange = integrationExchanges.find(
27329
27558
  (e) => e.service_provider === IntegrationProvider.COINBASE
@@ -27345,10 +27574,10 @@ function DepositModal({
27345
27574
  // Only fetch when modal is open
27346
27575
  });
27347
27576
  const wallets = depositAddressResponse?.data ?? [];
27348
- const [resolvedTheme, setResolvedTheme] = useState31(
27577
+ const [resolvedTheme, setResolvedTheme] = useState32(
27349
27578
  theme === "auto" ? "dark" : theme
27350
27579
  );
27351
- useEffect25(() => {
27580
+ useEffect26(() => {
27352
27581
  if (theme === "auto") {
27353
27582
  const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
27354
27583
  setResolvedTheme(mediaQuery.matches ? "dark" : "light");
@@ -27361,18 +27590,39 @@ function DepositModal({
27361
27590
  setResolvedTheme(theme);
27362
27591
  }
27363
27592
  }, [theme]);
27364
- const { projectConfig } = useProjectConfig({
27365
- publishableKey,
27366
- enabled: open
27367
- });
27368
- const showPayWithExchange = enablePayWithExchange ?? projectConfig?.pay_with_exchange?.enabled ?? true;
27369
- const showFiatOnramp = enableFiatOnramp ?? projectConfig?.fiat_onramp?.enabled ?? true;
27370
- useEffect25(() => {
27593
+ useEffect26(() => {
27371
27594
  if (view === "card" && !showFiatOnramp) {
27372
27595
  setView("main");
27373
27596
  setCardView("amount");
27597
+ } else if (view === "transfer" && !showTransferCrypto) {
27598
+ setView("main");
27599
+ } else if (view === "exchange" && !showPayWithExchange) {
27600
+ setView("main");
27601
+ } else if (view === "cashapp" && !showCashApp) {
27602
+ setView("main");
27603
+ } else if (view === "tracker" && !showDepositTracker) {
27604
+ setView("main");
27605
+ } else if (view === "coinbase_connect" && !showConnectExchange) {
27606
+ setView("main");
27607
+ } else if (view === "wallet_connect" && !showConnectWallet) {
27608
+ setView("main");
27374
27609
  }
27375
- }, [view, showFiatOnramp]);
27610
+ }, [
27611
+ view,
27612
+ showFiatOnramp,
27613
+ showTransferCrypto,
27614
+ showPayWithExchange,
27615
+ showCashApp,
27616
+ showDepositTracker,
27617
+ showConnectExchange,
27618
+ showConnectWallet
27619
+ ]);
27620
+ useEffect26(() => {
27621
+ if (view === "exchange" && !showPayWithExchange) {
27622
+ setView("main");
27623
+ setExchangeView("providers");
27624
+ }
27625
+ }, [view, showPayWithExchange]);
27376
27626
  const { exchanges, isLoading: exchangesLoading } = useExchanges({
27377
27627
  publishableKey,
27378
27628
  enabled: open && showPayWithExchange
@@ -27387,7 +27637,7 @@ function DepositModal({
27387
27637
  subdivisionCode: userIpInfo?.subdivisionCode ?? void 0,
27388
27638
  enabled: open && !isLoadingIp
27389
27639
  });
27390
- useEffect25(() => {
27640
+ useEffect26(() => {
27391
27641
  if (view !== "tracker" || !userId) return;
27392
27642
  const fetchExecutions = async () => {
27393
27643
  try {
@@ -27408,7 +27658,7 @@ function DepositModal({
27408
27658
  clearInterval(pollInterval);
27409
27659
  };
27410
27660
  }, [view, userId, publishableKey]);
27411
- useEffect25(() => {
27661
+ useEffect26(() => {
27412
27662
  if (view !== "tracker") {
27413
27663
  setSelectedExecution(null);
27414
27664
  }
@@ -27456,7 +27706,7 @@ function DepositModal({
27456
27706
  depositPrerequisiteBody = standaloneNeedsDepositPrereq ? /* @__PURE__ */ jsx55(SkeletonButton, { variant: "with-icons" }) : /* @__PURE__ */ jsxs49(Fragment11, { children: [
27457
27707
  /* @__PURE__ */ jsx55(SkeletonButton, { variant: "with-icons" }),
27458
27708
  /* @__PURE__ */ jsx55(SkeletonButton, { variant: "with-icons" }),
27459
- !hideDepositTracker && /* @__PURE__ */ jsx55(SkeletonButton, {})
27709
+ showDepositTracker && /* @__PURE__ */ jsx55(SkeletonButton, {})
27460
27710
  ] });
27461
27711
  } else if (countryError) {
27462
27712
  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: [
@@ -27488,11 +27738,11 @@ function DepositModal({
27488
27738
  const themeClass = resolvedTheme === "dark" ? "uf-dark" : "";
27489
27739
  const handleWalletDisconnect = () => {
27490
27740
  setUserDisconnectedWallet(true);
27491
- clearStoredWalletChainType();
27741
+ clearStoredWalletState();
27492
27742
  setBrowserWalletChainType(void 0);
27493
27743
  setBrowserWalletInfo(null);
27494
27744
  setBrowserWalletModalOpen(false);
27495
- if (view === "wallet_connect") setView("main");
27745
+ if (view === "wallet_connect" && sessionOpenedFromMenu) setView("main");
27496
27746
  };
27497
27747
  const handleExchangeDisconnect = () => {
27498
27748
  const stored = getStoredIntegrationToken(IntegrationProvider.COINBASE);
@@ -27501,7 +27751,7 @@ function DepositModal({
27501
27751
  }
27502
27752
  clearStoredIntegrationToken(IntegrationProvider.COINBASE);
27503
27753
  setConnectedExchange(null);
27504
- if (view === "coinbase_connect") setView("main");
27754
+ if (view === "coinbase_connect" && sessionOpenedFromMenu) setView("main");
27505
27755
  };
27506
27756
  const handleClose = () => {
27507
27757
  onOpenChange(false);
@@ -27513,6 +27763,7 @@ function DepositModal({
27513
27763
  setCardView("amount");
27514
27764
  setExchangeView("providers");
27515
27765
  setBrowserWalletInfo(null);
27766
+ setCoinbaseSkipToHoldings(false);
27516
27767
  resetViewTimeoutRef.current = null;
27517
27768
  }, 200);
27518
27769
  };
@@ -27527,8 +27778,9 @@ function DepositModal({
27527
27778
  setExchangeView("providers");
27528
27779
  setBrowserWalletInfo(null);
27529
27780
  setSelectedExecution(null);
27781
+ setCoinbaseSkipToHoldings(false);
27530
27782
  }, [open, effectiveInitialScreen]);
27531
- useEffect25(
27783
+ useEffect26(
27532
27784
  () => () => {
27533
27785
  if (resetViewTimeoutRef.current) {
27534
27786
  clearTimeout(resetViewTimeoutRef.current);
@@ -27536,8 +27788,8 @@ function DepositModal({
27536
27788
  },
27537
27789
  []
27538
27790
  );
27539
- const [cashAppView, setCashAppView] = useState31("amount");
27540
- const [cashAppAmount, setCashAppAmount] = useState31("");
27791
+ const [cashAppView, setCashAppView] = useState32("amount");
27792
+ const [cashAppAmount, setCashAppAmount] = useState32("");
27541
27793
  const handleBack = () => {
27542
27794
  if (view === "card" && cardView === "quotes") {
27543
27795
  setCardView("amount");
@@ -27564,7 +27816,7 @@ function DepositModal({
27564
27816
  };
27565
27817
  const handleBrowserWalletClick = (walletInfo) => {
27566
27818
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
27567
- setStoredWalletChainType(walletChainType);
27819
+ setStoredWalletState(walletInfo.type);
27568
27820
  setBrowserWalletChainType(walletChainType);
27569
27821
  const matchingDepositWallet = wallets.find(
27570
27822
  (w) => w.chain_type === walletChainType
@@ -27595,7 +27847,7 @@ function DepositModal({
27595
27847
  };
27596
27848
  const handleWalletConnected = (walletInfo) => {
27597
27849
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
27598
- setStoredWalletChainType(walletChainType);
27850
+ setStoredWalletState(walletInfo.type);
27599
27851
  setBrowserWalletChainType(walletChainType);
27600
27852
  const matchingDepositWallet = wallets.find(
27601
27853
  (w) => w.chain_type === walletChainType
@@ -27662,7 +27914,7 @@ function DepositModal({
27662
27914
  ),
27663
27915
  /* @__PURE__ */ jsxs49("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
27664
27916
  /* @__PURE__ */ jsx55("div", { className: "uf-space-y-3", children: depositPrerequisiteBody ?? /* @__PURE__ */ jsxs49(Fragment11, { children: [
27665
- /* @__PURE__ */ jsx55(
27917
+ showTransferCrypto && /* @__PURE__ */ jsx55(
27666
27918
  TransferCryptoButton,
27667
27919
  {
27668
27920
  onClick: () => setView("transfer"),
@@ -27671,7 +27923,7 @@ function DepositModal({
27671
27923
  featuredTokens: projectConfig?.transfer_crypto.networks
27672
27924
  }
27673
27925
  ),
27674
- enableConnectWallet && !isMobileView && /* @__PURE__ */ jsx55(
27926
+ showConnectWallet && !isMobileView && /* @__PURE__ */ jsx55(
27675
27927
  BrowserWalletButton,
27676
27928
  {
27677
27929
  onClick: handleBrowserWalletClick,
@@ -27701,7 +27953,7 @@ function DepositModal({
27701
27953
  loading: exchangesLoading
27702
27954
  }
27703
27955
  ),
27704
- enableConnectExchange && connectedExchange && /* @__PURE__ */ jsx55(
27956
+ showConnectExchange && connectedExchange && /* @__PURE__ */ jsx55(
27705
27957
  ConnectExchangeButton,
27706
27958
  {
27707
27959
  onClick: () => {
@@ -27715,7 +27967,7 @@ function DepositModal({
27715
27967
  connectedExchange
27716
27968
  }
27717
27969
  ),
27718
- enableConnectExchange && !connectedExchange && /* @__PURE__ */ jsx55(
27970
+ showConnectExchange && !connectedExchange && /* @__PURE__ */ jsx55(
27719
27971
  ConnectExchangeButton,
27720
27972
  {
27721
27973
  onClick: () => {
@@ -27727,7 +27979,7 @@ function DepositModal({
27727
27979
  exchanges: integrationExchanges
27728
27980
  }
27729
27981
  ),
27730
- enableCashApp && /* @__PURE__ */ jsx55(
27982
+ showCashApp && /* @__PURE__ */ jsx55(
27731
27983
  CashAppButton,
27732
27984
  {
27733
27985
  onClick: () => setView("cashapp"),
@@ -27736,7 +27988,7 @@ function DepositModal({
27736
27988
  iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/cashapp.svg` : void 0
27737
27989
  }
27738
27990
  ),
27739
- !hideDepositTracker && /* @__PURE__ */ jsx55(
27991
+ showDepositTracker && /* @__PURE__ */ jsx55(
27740
27992
  DepositTrackerButton,
27741
27993
  {
27742
27994
  onClick: () => {
@@ -27886,7 +28138,7 @@ function DepositModal({
27886
28138
  DepositHeader,
27887
28139
  {
27888
28140
  title: payWithExchangeTitle,
27889
- showBack: true,
28141
+ showBack: exchangeView === "pending" || sessionOpenedFromMenu,
27890
28142
  onBack: handleBack,
27891
28143
  onClose: handleClose
27892
28144
  }
@@ -27940,7 +28192,12 @@ function DepositModal({
27940
28192
  onClose: handleClose,
27941
28193
  onDisconnect: handleExchangeDisconnect,
27942
28194
  skipToHoldings: coinbaseSkipToHoldings,
27943
- onExecutionsChange: setDepositExecutions
28195
+ canGoBack: sessionOpenedFromMenu,
28196
+ onExecutionsChange: setDepositExecutions,
28197
+ defaultSourceChainType,
28198
+ defaultSourceChainId,
28199
+ defaultSourceTokenAddress,
28200
+ defaultSourceSymbol
27944
28201
  }
27945
28202
  ),
27946
28203
  depositPoweredByFooter
@@ -27973,11 +28230,17 @@ function DepositModal({
27973
28230
  onWalletDisconnect: handleWalletDisconnect,
27974
28231
  onWalletConnected: (info, dw) => {
27975
28232
  setBrowserWalletInfo({ ...info, depositWallet: dw });
27976
- setStoredWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
28233
+ setStoredWalletState(info.type);
27977
28234
  setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
27978
28235
  },
27979
28236
  onBack: handleBack,
27980
- onClose: handleClose
28237
+ onClose: handleClose,
28238
+ defaultSourceChainType,
28239
+ defaultSourceChainId,
28240
+ defaultSourceTokenAddress,
28241
+ defaultSourceSymbol,
28242
+ canGoBack: sessionOpenedFromMenu,
28243
+ depositWalletsLoading: walletsLoading
27981
28244
  }
27982
28245
  ),
27983
28246
  depositPoweredByFooter
@@ -27986,7 +28249,7 @@ function DepositModal({
27986
28249
  DepositHeader,
27987
28250
  {
27988
28251
  title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
27989
- showBack: true,
28252
+ showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
27990
28253
  onBack: handleBack,
27991
28254
  onClose: handleClose
27992
28255
  }
@@ -28078,7 +28341,8 @@ function CheckoutModal({
28078
28341
  clientSecret,
28079
28342
  publishableKey,
28080
28343
  modalTitle,
28081
- enableConnectWallet = false,
28344
+ enableTransferCrypto,
28345
+ enableConnectWallet,
28082
28346
  defaultSourceChainType,
28083
28347
  defaultSourceChainId,
28084
28348
  defaultSourceTokenAddress,
@@ -28088,19 +28352,19 @@ function CheckoutModal({
28088
28352
  onCheckoutError
28089
28353
  }) {
28090
28354
  const { colors: colors2, fonts, components } = useTheme();
28091
- const [view, setView] = useState32("main");
28092
- const resetViewTimeoutRef = useRef92(
28355
+ const [view, setView] = useState33("main");
28356
+ const resetViewTimeoutRef = useRef102(
28093
28357
  null
28094
28358
  );
28095
- const [browserWalletModalOpen, setBrowserWalletModalOpen] = useState32(false);
28096
- const [browserWalletInfo, setBrowserWalletInfo] = useState32(null);
28097
- const [walletSelectionModalOpen, setWalletSelectionModalOpen] = useState32(false);
28098
- const [browserWalletChainType, setBrowserWalletChainType] = useState32(() => getStoredWalletChainType());
28359
+ const [browserWalletModalOpen, setBrowserWalletModalOpen] = useState33(false);
28360
+ const [browserWalletInfo, setBrowserWalletInfo] = useState33(null);
28361
+ const [walletSelectionModalOpen, setWalletSelectionModalOpen] = useState33(false);
28362
+ const [browserWalletChainType, setBrowserWalletChainType] = useState33(() => getStoredWalletState()?.chainType);
28099
28363
  const isMobileView = useIsMobileViewport();
28100
- const [resolvedTheme, setResolvedTheme] = useState32(
28364
+ const [resolvedTheme, setResolvedTheme] = useState33(
28101
28365
  theme === "auto" ? "dark" : theme
28102
28366
  );
28103
- useEffect262(() => {
28367
+ useEffect272(() => {
28104
28368
  if (theme === "auto") {
28105
28369
  const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
28106
28370
  setResolvedTheme(mediaQuery.matches ? "dark" : "light");
@@ -28128,8 +28392,17 @@ function CheckoutModal({
28128
28392
  publishableKey,
28129
28393
  enabled: open
28130
28394
  });
28131
- const prevStatusRef = useRef92(null);
28132
- useEffect262(() => {
28395
+ const showTransferCrypto = enableTransferCrypto ?? projectConfig?.transfer_crypto?.enabled ?? true;
28396
+ const showConnectWallet = enableConnectWallet ?? projectConfig?.connect_wallet?.enabled ?? true;
28397
+ useEffect272(() => {
28398
+ if (view === "transfer" && !showTransferCrypto) {
28399
+ setView("main");
28400
+ } else if (view === "wallet_connect" && !showConnectWallet) {
28401
+ setView("main");
28402
+ }
28403
+ }, [showConnectWallet, showTransferCrypto, view]);
28404
+ const prevStatusRef = useRef102(null);
28405
+ useEffect272(() => {
28133
28406
  if (!paymentIntent) return;
28134
28407
  const prev = prevStatusRef.current;
28135
28408
  prevStatusRef.current = paymentIntent.status;
@@ -28175,7 +28448,7 @@ function CheckoutModal({
28175
28448
  const remaining = total - received;
28176
28449
  return remaining > 0n ? remaining.toString() : "0";
28177
28450
  }, [paymentIntent]);
28178
- const [selectedSource, setSelectedSource] = useState32(null);
28451
+ const [selectedSource, setSelectedSource] = useState33(null);
28179
28452
  const remainingDestinationAmount = useMemo112(() => {
28180
28453
  if (!paymentIntent) return "0";
28181
28454
  const remaining = BigInt(paymentIntent.destination_amount) - BigInt(paymentIntent.destination_amount_received);
@@ -28218,7 +28491,7 @@ function CheckoutModal({
28218
28491
  const handleBrowserWalletClick = useCallback62(
28219
28492
  (walletInfo) => {
28220
28493
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
28221
- setStoredWalletChainType(walletChainType);
28494
+ setStoredWalletState(walletInfo.type);
28222
28495
  setBrowserWalletChainType(walletChainType);
28223
28496
  const matchingDepositWallet = wallets.find(
28224
28497
  (w) => w.chain_type === walletChainType
@@ -28245,7 +28518,7 @@ function CheckoutModal({
28245
28518
  const handleWalletConnected = useCallback62(
28246
28519
  (walletInfo) => {
28247
28520
  const walletChainType = walletInfo.type === "phantom-solana" || walletInfo.type === "solflare" || walletInfo.type === "backpack" || walletInfo.type === "glow" ? "solana" : "ethereum";
28248
- setStoredWalletChainType(walletChainType);
28521
+ setStoredWalletState(walletInfo.type);
28249
28522
  setBrowserWalletChainType(walletChainType);
28250
28523
  const matchingDepositWallet = wallets.find(
28251
28524
  (w) => w.chain_type === walletChainType
@@ -28269,7 +28542,7 @@ function CheckoutModal({
28269
28542
  );
28270
28543
  const handleWalletDisconnect = useCallback62(() => {
28271
28544
  setUserDisconnectedWallet(true);
28272
- clearStoredWalletChainType();
28545
+ clearStoredWalletState();
28273
28546
  setBrowserWalletChainType(void 0);
28274
28547
  setBrowserWalletInfo(null);
28275
28548
  setBrowserWalletModalOpen(false);
@@ -28295,7 +28568,7 @@ function CheckoutModal({
28295
28568
  setView("main");
28296
28569
  setBrowserWalletInfo(null);
28297
28570
  }, [open]);
28298
- useEffect262(
28571
+ useEffect272(
28299
28572
  () => () => {
28300
28573
  if (resetViewTimeoutRef.current) {
28301
28574
  clearTimeout(resetViewTimeoutRef.current);
@@ -28504,7 +28777,7 @@ function CheckoutModal({
28504
28777
  ] }) : paymentIntent ? /* @__PURE__ */ jsxs50("div", { className: "uf-space-y-3", children: [
28505
28778
  progressSection,
28506
28779
  (paymentIntent.status === "requires_payment" || paymentIntent.status === "processing") && /* @__PURE__ */ jsxs50(Fragment12, { children: [
28507
- /* @__PURE__ */ jsx56(
28780
+ showTransferCrypto && /* @__PURE__ */ jsx56(
28508
28781
  TransferCryptoButton,
28509
28782
  {
28510
28783
  onClick: () => setView("transfer"),
@@ -28513,7 +28786,7 @@ function CheckoutModal({
28513
28786
  featuredTokens: projectConfig?.transfer_crypto.networks
28514
28787
  }
28515
28788
  ),
28516
- enableConnectWallet && !isMobileView && /* @__PURE__ */ jsx56(
28789
+ showConnectWallet && !isMobileView && /* @__PURE__ */ jsx56(
28517
28790
  BrowserWalletButton,
28518
28791
  {
28519
28792
  onClick: handleBrowserWalletClick,
@@ -28654,14 +28927,18 @@ function CheckoutModal({
28654
28927
  onWalletDisconnect: handleWalletDisconnect,
28655
28928
  onWalletConnected: (info, dw) => {
28656
28929
  setBrowserWalletInfo({ ...info, depositWallet: dw });
28657
- setStoredWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
28930
+ setStoredWalletState(info.type);
28658
28931
  setBrowserWalletChainType(dw.chain_type === "solana" ? "solana" : "ethereum");
28659
28932
  },
28660
28933
  onNewDeposit: () => setView("main"),
28661
28934
  onDone: () => setView("main"),
28662
28935
  paymentIntentStatus: paymentIntent.status,
28663
28936
  onBack: handleBack,
28664
- onClose: handleClose
28937
+ onClose: handleClose,
28938
+ defaultSourceChainType,
28939
+ defaultSourceChainId,
28940
+ defaultSourceTokenAddress,
28941
+ defaultSourceSymbol
28665
28942
  }
28666
28943
  ),
28667
28944
  poweredByFooter
@@ -28831,20 +29108,20 @@ function useWithdrawPolling({
28831
29108
  onWithdrawSuccess,
28832
29109
  onWithdrawError
28833
29110
  }) {
28834
- const [executions, setExecutions] = useState33([]);
28835
- const [isPolling, setIsPolling] = useState33(false);
28836
- const enabledAtRef = useRef102(/* @__PURE__ */ new Date());
28837
- const trackedRef = useRef102(/* @__PURE__ */ new Map());
28838
- const prevEnabledRef = useRef102(false);
28839
- const onSuccessRef = useRef102(onWithdrawSuccess);
28840
- const onErrorRef = useRef102(onWithdrawError);
28841
- useEffect272(() => {
29111
+ const [executions, setExecutions] = useState34([]);
29112
+ const [isPolling, setIsPolling] = useState34(false);
29113
+ const enabledAtRef = useRef112(/* @__PURE__ */ new Date());
29114
+ const trackedRef = useRef112(/* @__PURE__ */ new Map());
29115
+ const prevEnabledRef = useRef112(false);
29116
+ const onSuccessRef = useRef112(onWithdrawSuccess);
29117
+ const onErrorRef = useRef112(onWithdrawError);
29118
+ useEffect282(() => {
28842
29119
  onSuccessRef.current = onWithdrawSuccess;
28843
29120
  }, [onWithdrawSuccess]);
28844
- useEffect272(() => {
29121
+ useEffect282(() => {
28845
29122
  onErrorRef.current = onWithdrawError;
28846
29123
  }, [onWithdrawError]);
28847
- useEffect272(() => {
29124
+ useEffect282(() => {
28848
29125
  if (enabled && !prevEnabledRef.current) {
28849
29126
  enabledAtRef.current = /* @__PURE__ */ new Date();
28850
29127
  trackedRef.current.clear();
@@ -28854,7 +29131,7 @@ function useWithdrawPolling({
28854
29131
  }
28855
29132
  prevEnabledRef.current = enabled;
28856
29133
  }, [enabled]);
28857
- useEffect272(() => {
29134
+ useEffect282(() => {
28858
29135
  if (!userId || !enabled) return;
28859
29136
  const enabledAt = enabledAtRef.current;
28860
29137
  const poll = async () => {
@@ -28916,7 +29193,7 @@ function useWithdrawPolling({
28916
29193
  setIsPolling(false);
28917
29194
  };
28918
29195
  }, [userId, publishableKey, enabled]);
28919
- useEffect272(() => {
29196
+ useEffect282(() => {
28920
29197
  if (!enabled || !depositWalletId) return;
28921
29198
  const trigger = async () => {
28922
29199
  try {
@@ -29288,27 +29565,27 @@ function WithdrawForm({
29288
29565
  footerLeft
29289
29566
  }) {
29290
29567
  const { colors: colors2, fonts, components } = useTheme();
29291
- const [recipientAddress, setRecipientAddress] = useState34(recipientAddressProp || "");
29292
- const [amount, setAmount] = useState34("");
29293
- const [inputUnit, setInputUnit] = useState34("fiat");
29294
- const [isSubmitting, setIsSubmitting] = useState34(false);
29295
- const [submitError, setSubmitError] = useState34(null);
29296
- const [detailsExpanded, setDetailsExpanded] = useState34(false);
29297
- const [glossaryOpen, setGlossaryOpen] = useState34(false);
29298
- const [isMaxed, setIsMaxed] = useState34(false);
29299
- useEffect282(() => {
29568
+ const [recipientAddress, setRecipientAddress] = useState35(recipientAddressProp || "");
29569
+ const [amount, setAmount] = useState35("");
29570
+ const [inputUnit, setInputUnit] = useState35("fiat");
29571
+ const [isSubmitting, setIsSubmitting] = useState35(false);
29572
+ const [submitError, setSubmitError] = useState35(null);
29573
+ const [detailsExpanded, setDetailsExpanded] = useState35(false);
29574
+ const [glossaryOpen, setGlossaryOpen] = useState35(false);
29575
+ const [isMaxed, setIsMaxed] = useState35(false);
29576
+ useEffect292(() => {
29300
29577
  setRecipientAddress(recipientAddressProp || "");
29301
29578
  setAmount("");
29302
29579
  setInputUnit("fiat");
29303
29580
  setSubmitError(null);
29304
29581
  setIsMaxed(false);
29305
29582
  }, [recipientAddressProp]);
29306
- useEffect282(() => {
29583
+ useEffect292(() => {
29307
29584
  setIsMaxed(false);
29308
29585
  }, [balanceData?.balanceBaseUnit]);
29309
29586
  const trimmedAddress = recipientAddress.trim();
29310
- const [debouncedAddress, setDebouncedAddress] = useState34(trimmedAddress);
29311
- useEffect282(() => {
29587
+ const [debouncedAddress, setDebouncedAddress] = useState35(trimmedAddress);
29588
+ useEffect292(() => {
29312
29589
  const id = setTimeout(() => setDebouncedAddress(trimmedAddress), 500);
29313
29590
  return () => clearTimeout(id);
29314
29591
  }, [trimmedAddress]);
@@ -29950,9 +30227,9 @@ function WithdrawConfirmingView({
29950
30227
  onViewTracker
29951
30228
  }) {
29952
30229
  const { colors: colors2, fonts, components } = useTheme();
29953
- const [showButton, setShowButton] = useState35(false);
30230
+ const [showButton, setShowButton] = useState36(false);
29954
30231
  const latestExecution = executions.length > 0 ? executions[executions.length - 1] : null;
29955
- useEffect292(() => {
30232
+ useEffect302(() => {
29956
30233
  if (latestExecution) return;
29957
30234
  const timer = setTimeout(() => setShowButton(true), SHOW_BUTTON_DELAY_MS);
29958
30235
  return () => clearTimeout(timer);
@@ -30109,14 +30386,14 @@ function WithdrawModal({
30109
30386
  hideOverlay = false
30110
30387
  }) {
30111
30388
  const { colors: colors2, fonts, components } = useTheme();
30112
- const [containerEl, setContainerEl] = useState36(null);
30389
+ const [containerEl, setContainerEl] = useState37(null);
30113
30390
  const containerCallbackRef = useCallback82((el) => {
30114
30391
  setContainerEl(el);
30115
30392
  }, []);
30116
- const [resolvedTheme, setResolvedTheme] = useState36(
30393
+ const [resolvedTheme, setResolvedTheme] = useState37(
30117
30394
  theme === "auto" ? "dark" : theme
30118
30395
  );
30119
- useEffect30(() => {
30396
+ useEffect31(() => {
30120
30397
  if (theme === "auto") {
30121
30398
  const mq = window.matchMedia("(prefers-color-scheme: dark)");
30122
30399
  setResolvedTheme(mq.matches ? "dark" : "light");
@@ -30160,10 +30437,10 @@ function WithdrawModal({
30160
30437
  });
30161
30438
  const selectedToken = selectedTokenSymbol ? destinationTokens.find((t12) => t12.symbol === selectedTokenSymbol) ?? null : null;
30162
30439
  const selectedChain = selectedToken && selectedChainKey ? selectedToken.chains.find((c) => getChainKey5(c.chain_id, c.chain_type) === selectedChainKey) ?? null : null;
30163
- const [view, setView] = useState36("form");
30164
- const [withdrawDepositWalletId, setWithdrawDepositWalletId] = useState36();
30165
- const [selectedExecution, setSelectedExecution] = useState36(null);
30166
- const [submittedTxInfo, setSubmittedTxInfo] = useState36(null);
30440
+ const [view, setView] = useState37("form");
30441
+ const [withdrawDepositWalletId, setWithdrawDepositWalletId] = useState37();
30442
+ const [selectedExecution, setSelectedExecution] = useState37(null);
30443
+ const [submittedTxInfo, setSubmittedTxInfo] = useState37(null);
30167
30444
  const { executions: realtimeExecutions } = useWithdrawPolling({
30168
30445
  userId: externalUserId,
30169
30446
  publishableKey,
@@ -30202,7 +30479,7 @@ function WithdrawModal({
30202
30479
  setSubmittedTxInfo(txInfo);
30203
30480
  setView("confirming");
30204
30481
  }, []);
30205
- const resetViewTimeoutRef = useRef112(null);
30482
+ const resetViewTimeoutRef = useRef122(null);
30206
30483
  const handleClose = useCallback82(() => {
30207
30484
  onOpenChange(false);
30208
30485
  if (resetViewTimeoutRef.current) clearTimeout(resetViewTimeoutRef.current);
@@ -30225,7 +30502,7 @@ function WithdrawModal({
30225
30502
  setSubmittedTxInfo(null);
30226
30503
  setWithdrawDepositWalletId(void 0);
30227
30504
  }, [open]);
30228
- useEffect30(() => () => {
30505
+ useEffect31(() => () => {
30229
30506
  if (resetViewTimeoutRef.current) clearTimeout(resetViewTimeoutRef.current);
30230
30507
  }, []);
30231
30508
  const handleTokenSymbolChange = useCallback82((symbol) => {
@@ -30356,20 +30633,20 @@ function UnifoldProvider2({
30356
30633
  queryClient,
30357
30634
  config
30358
30635
  }) {
30359
- const [isOpen, setIsOpen] = useState30(false);
30360
- const [depositConfig, setDepositConfig] = useState30(
30636
+ const [isOpen, setIsOpen] = useState31(false);
30637
+ const [depositConfig, setDepositConfig] = useState31(
30361
30638
  null
30362
30639
  );
30363
- const [isCheckoutOpen, setIsCheckoutOpen] = useState30(false);
30364
- const [checkoutConfig, setCheckoutConfig] = useState30(
30640
+ const [isCheckoutOpen, setIsCheckoutOpen] = useState31(false);
30641
+ const [checkoutConfig, setCheckoutConfig] = useState31(
30365
30642
  null
30366
30643
  );
30367
- const [isWithdrawOpen, setIsWithdrawOpen] = useState30(false);
30368
- const [withdrawConfig, setWithdrawConfig] = useState30(
30644
+ const [isWithdrawOpen, setIsWithdrawOpen] = useState31(false);
30645
+ const [withdrawConfig, setWithdrawConfig] = useState31(
30369
30646
  null
30370
30647
  );
30371
30648
  const [resolvedTheme, setResolvedTheme] = React38.useState("dark");
30372
- useEffect31(() => {
30649
+ useEffect33(() => {
30373
30650
  if (publishableKey) {
30374
30651
  setApiConfig({ publishableKey });
30375
30652
  }
@@ -30627,6 +30904,7 @@ function UnifoldProvider2({
30627
30904
  onOpenChange: closeCheckout,
30628
30905
  clientSecret: checkoutConfig.clientSecret,
30629
30906
  publishableKey,
30907
+ enableTransferCrypto: config?.enableTransferCrypto,
30630
30908
  enableConnectWallet: config?.enableConnectWallet,
30631
30909
  defaultSourceChainType: checkoutConfig.defaultSourceChainType,
30632
30910
  defaultSourceChainId: checkoutConfig.defaultSourceChainId,
@@ -30683,6 +30961,7 @@ function UnifoldProvider2({
30683
30961
  hideDepositTracker: config?.hideDepositTracker,
30684
30962
  showBalanceHeader: config?.showBalanceHeader,
30685
30963
  transferInputVariant: config?.transferInputVariant,
30964
+ enableTransferCrypto: config?.enableTransferCrypto,
30686
30965
  enableConnectWallet: config?.enableConnectWallet,
30687
30966
  enablePayWithExchange: config?.enablePayWithExchange,
30688
30967
  enableFiatOnramp: config?.enableFiatOnramp,