@unifold/ui-web 0.1.68 → 0.1.70-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -37116,6 +37116,7 @@ var import_jsx_runtime11 = __toESM(require_jsx_runtime(), 1);
37116
37116
  var React211 = __toESM(require_react(), 1);
37117
37117
  var import_jsx_runtime12 = __toESM(require_jsx_runtime(), 1);
37118
37118
  var import_jsx_runtime13 = __toESM(require_jsx_runtime(), 1);
37119
+ var React522 = __toESM(require_react(), 1);
37119
37120
  var import_react7 = __toESM(require_react(), 1);
37120
37121
  var import_react8 = __toESM(require_react(), 1);
37121
37122
  var import_react9 = __toESM(require_react(), 1);
@@ -37134,7 +37135,7 @@ var import_jsx_runtime19 = __toESM(require_jsx_runtime(), 1);
37134
37135
  var import_jsx_runtime20 = __toESM(require_jsx_runtime(), 1);
37135
37136
  var import_jsx_runtime21 = __toESM(require_jsx_runtime(), 1);
37136
37137
  var import_jsx_runtime22 = __toESM(require_jsx_runtime(), 1);
37137
- var React522 = __toESM(require_react(), 1);
37138
+ var React622 = __toESM(require_react(), 1);
37138
37139
  var import_react15 = __toESM(require_react(), 1);
37139
37140
  var import_react16 = __toESM(require_react(), 1);
37140
37141
  var import_jsx_runtime23 = __toESM(require_jsx_runtime(), 1);
@@ -37148,55 +37149,55 @@ var import_jsx_runtime26 = __toESM(require_jsx_runtime(), 1);
37148
37149
  var import_react21 = __toESM(require_react(), 1);
37149
37150
  var import_jsx_runtime27 = __toESM(require_jsx_runtime(), 1);
37150
37151
  var import_jsx_runtime28 = __toESM(require_jsx_runtime(), 1);
37151
- var React622 = __toESM(require_react(), 1);
37152
- var import_jsx_runtime29 = __toESM(require_jsx_runtime(), 1);
37153
37152
  var React72 = __toESM(require_react(), 1);
37154
- var import_jsx_runtime30 = __toESM(require_jsx_runtime(), 1);
37153
+ var import_jsx_runtime29 = __toESM(require_jsx_runtime(), 1);
37155
37154
  var React82 = __toESM(require_react(), 1);
37155
+ var import_jsx_runtime30 = __toESM(require_jsx_runtime(), 1);
37156
+ var React92 = __toESM(require_react(), 1);
37156
37157
  var import_jsx_runtime31 = __toESM(require_jsx_runtime(), 1);
37158
+ var React112 = __toESM(require_react(), 1);
37157
37159
  var React102 = __toESM(require_react(), 1);
37158
- var React92 = __toESM(require_react(), 1);
37159
37160
  var React25 = __toESM(require_react(), 1);
37160
37161
  var import_jsx_runtime32 = __toESM(require_jsx_runtime(), 1);
37161
37162
  var import_jsx_runtime33 = __toESM(require_jsx_runtime(), 1);
37162
37163
  var import_jsx_runtime34 = __toESM(require_jsx_runtime(), 1);
37163
- var React112 = __toESM(require_react(), 1);
37164
- var import_jsx_runtime35 = __toESM(require_jsx_runtime(), 1);
37165
37164
  var React122 = __toESM(require_react(), 1);
37166
- var import_jsx_runtime36 = __toESM(require_jsx_runtime(), 1);
37165
+ var import_jsx_runtime35 = __toESM(require_jsx_runtime(), 1);
37167
37166
  var React132 = __toESM(require_react(), 1);
37168
- var import_jsx_runtime37 = __toESM(require_jsx_runtime(), 1);
37167
+ var import_jsx_runtime36 = __toESM(require_jsx_runtime(), 1);
37169
37168
  var React142 = __toESM(require_react(), 1);
37170
- var import_jsx_runtime38 = __toESM(require_jsx_runtime(), 1);
37171
- var React282 = __toESM(require_react(), 1);
37169
+ var import_jsx_runtime37 = __toESM(require_jsx_runtime(), 1);
37172
37170
  var React152 = __toESM(require_react(), 1);
37171
+ var import_jsx_runtime38 = __toESM(require_jsx_runtime(), 1);
37172
+ var React292 = __toESM(require_react(), 1);
37173
37173
  var React162 = __toESM(require_react(), 1);
37174
- var import_jsx_runtime39 = __toESM(require_jsx_runtime(), 1);
37175
37174
  var React172 = __toESM(require_react(), 1);
37176
- var import_jsx_runtime40 = __toESM(require_jsx_runtime(), 1);
37175
+ var import_jsx_runtime39 = __toESM(require_jsx_runtime(), 1);
37177
37176
  var React182 = __toESM(require_react(), 1);
37178
- var import_jsx_runtime41 = __toESM(require_jsx_runtime(), 1);
37177
+ var import_jsx_runtime40 = __toESM(require_jsx_runtime(), 1);
37179
37178
  var React192 = __toESM(require_react(), 1);
37180
- var import_jsx_runtime42 = __toESM(require_jsx_runtime(), 1);
37179
+ var import_jsx_runtime41 = __toESM(require_jsx_runtime(), 1);
37181
37180
  var React202 = __toESM(require_react(), 1);
37182
- var import_jsx_runtime43 = __toESM(require_jsx_runtime(), 1);
37181
+ var import_jsx_runtime42 = __toESM(require_jsx_runtime(), 1);
37183
37182
  var React212 = __toESM(require_react(), 1);
37184
- var import_jsx_runtime44 = __toESM(require_jsx_runtime(), 1);
37183
+ var import_jsx_runtime43 = __toESM(require_jsx_runtime(), 1);
37185
37184
  var React2222 = __toESM(require_react(), 1);
37186
- var import_jsx_runtime45 = __toESM(require_jsx_runtime(), 1);
37185
+ var import_jsx_runtime44 = __toESM(require_jsx_runtime(), 1);
37187
37186
  var React232 = __toESM(require_react(), 1);
37188
- var import_jsx_runtime46 = __toESM(require_jsx_runtime(), 1);
37187
+ var import_jsx_runtime45 = __toESM(require_jsx_runtime(), 1);
37189
37188
  var React242 = __toESM(require_react(), 1);
37190
- var import_jsx_runtime47 = __toESM(require_jsx_runtime(), 1);
37189
+ var import_jsx_runtime46 = __toESM(require_jsx_runtime(), 1);
37191
37190
  var React252 = __toESM(require_react(), 1);
37192
- var import_jsx_runtime48 = __toESM(require_jsx_runtime(), 1);
37191
+ var import_jsx_runtime47 = __toESM(require_jsx_runtime(), 1);
37193
37192
  var React262 = __toESM(require_react(), 1);
37194
- var import_jsx_runtime49 = __toESM(require_jsx_runtime(), 1);
37193
+ var import_jsx_runtime48 = __toESM(require_jsx_runtime(), 1);
37195
37194
  var React272 = __toESM(require_react(), 1);
37195
+ var import_jsx_runtime49 = __toESM(require_jsx_runtime(), 1);
37196
+ var React282 = __toESM(require_react(), 1);
37196
37197
  var import_jsx_runtime50 = __toESM(require_jsx_runtime(), 1);
37197
37198
  var import_jsx_runtime51 = __toESM(require_jsx_runtime(), 1);
37198
37199
  var import_jsx_runtime52 = __toESM(require_jsx_runtime(), 1);
37199
- var React292 = __toESM(require_react(), 1);
37200
+ var React302 = __toESM(require_react(), 1);
37200
37201
  var import_jsx_runtime53 = __toESM(require_jsx_runtime(), 1);
37201
37202
  var import_react22 = __toESM(require_react(), 1);
37202
37203
  var import_jsx_runtime54 = __toESM(require_jsx_runtime(), 1);
@@ -37206,7 +37207,7 @@ var import_react24 = __toESM(require_react(), 1);
37206
37207
  var import_jsx_runtime56 = __toESM(require_jsx_runtime(), 1);
37207
37208
  var import_react25 = __toESM(require_react(), 1);
37208
37209
  var import_react26 = __toESM(require_react(), 1);
37209
- var React312 = __toESM(require_react(), 1);
37210
+ var React322 = __toESM(require_react(), 1);
37210
37211
  var import_jsx_runtime57 = __toESM(require_jsx_runtime(), 1);
37211
37212
  var import_jsx_runtime58 = __toESM(require_jsx_runtime(), 1);
37212
37213
  var import_jsx_runtime59 = __toESM(require_jsx_runtime(), 1);
@@ -37216,7 +37217,7 @@ var import_react28 = __toESM(require_react(), 1);
37216
37217
  var import_jsx_runtime61 = __toESM(require_jsx_runtime(), 1);
37217
37218
  var import_jsx_runtime62 = __toESM(require_jsx_runtime(), 1);
37218
37219
  var import_react29 = __toESM(require_react(), 1);
37219
- var React322 = __toESM(require_react(), 1);
37220
+ var React332 = __toESM(require_react(), 1);
37220
37221
  var React31 = __toESM(require_react(), 1);
37221
37222
  var React29 = __toESM(require_react(), 1);
37222
37223
  var React26 = __toESM(require_react(), 1);
@@ -37233,7 +37234,7 @@ var import_jsx_runtime67 = __toESM(require_jsx_runtime(), 1);
37233
37234
  var import_jsx_runtime68 = __toESM(require_jsx_runtime(), 1);
37234
37235
  var import_jsx_runtime69 = __toESM(require_jsx_runtime(), 1);
37235
37236
  var import_react31 = __toESM(require_react(), 1);
37236
- var React332 = __toESM(require_react(), 1);
37237
+ var React342 = __toESM(require_react(), 1);
37237
37238
  var React35 = __toESM(require_react(), 1);
37238
37239
  var ReactDOM4 = __toESM(require_react_dom(), 1);
37239
37240
  var import_react32 = __toESM(require_react(), 1);
@@ -37246,7 +37247,7 @@ var React34 = __toESM(require_react(), 1);
37246
37247
  var import_jsx_runtime73 = __toESM(require_jsx_runtime(), 1);
37247
37248
  var import_jsx_runtime74 = __toESM(require_jsx_runtime(), 1);
37248
37249
  var import_jsx_runtime75 = __toESM(require_jsx_runtime(), 1);
37249
- var React342 = __toESM(require_react(), 1);
37250
+ var React352 = __toESM(require_react(), 1);
37250
37251
  var import_jsx_runtime76 = __toESM(require_jsx_runtime(), 1);
37251
37252
  var import_jsx_runtime77 = __toESM(require_jsx_runtime(), 1);
37252
37253
  var import_jsx_runtime78 = __toESM(require_jsx_runtime(), 1);
@@ -38412,7 +38413,10 @@ ${new this._window.XMLSerializer().serializeToString(e3)}`;
38412
38413
  })()));
38413
38414
  }
38414
38415
  });
38415
- var UnifoldContext = (0, import_react2.createContext)(null);
38416
+ var UNIFOLD_CONTEXT_KEY = /* @__PURE__ */ Symbol.for("unifold.react-provider.context");
38417
+ var globalRef = globalThis;
38418
+ var UnifoldContext = globalRef[UNIFOLD_CONTEXT_KEY] ?? (0, import_react2.createContext)(null);
38419
+ globalRef[UNIFOLD_CONTEXT_KEY] = UnifoldContext;
38416
38420
  var createQueryClient = () => new QueryClient({
38417
38421
  defaultOptions: {
38418
38422
  queries: {
@@ -43172,6 +43176,9 @@ var getDefaultConfig = () => {
43172
43176
  };
43173
43177
  };
43174
43178
  var twMerge = /* @__PURE__ */ createTailwindMerge(getDefaultConfig);
43179
+ var __defProp22 = Object.defineProperty;
43180
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp22(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
43181
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
43175
43182
  function formatStablecoinAmount(baseUnits, decimals) {
43176
43183
  const raw = Number(baseUnits) / 10 ** decimals;
43177
43184
  const floored = Math.floor(raw * 100) / 100;
@@ -43262,6 +43269,16 @@ var ActionType = /* @__PURE__ */ ((ActionType2) => {
43262
43269
  ActionType2["Withdraw"] = "withdraw";
43263
43270
  return ActionType2;
43264
43271
  })(ActionType || {});
43272
+ var DepositAddressValidationError = class extends Error {
43273
+ constructor(message) {
43274
+ super(message);
43275
+ __publicField(this, "isDepositAddressValidationError", true);
43276
+ this.name = "DepositAddressValidationError";
43277
+ }
43278
+ };
43279
+ function isDepositAddressValidationError(error) {
43280
+ return error instanceof Error && error.isDepositAddressValidationError === true;
43281
+ }
43265
43282
  async function createDepositAddress(overrides, publishableKey) {
43266
43283
  if (!overrides?.external_user_id) {
43267
43284
  throw new Error("external_user_id is required");
@@ -43289,6 +43306,13 @@ async function createDepositAddress(overrides, publishableKey) {
43289
43306
  body: JSON.stringify(payload)
43290
43307
  });
43291
43308
  if (!response.ok) {
43309
+ if (response.status === 400) {
43310
+ const body = await response.json().catch(() => null);
43311
+ if (body?.error_type === "validation_error") {
43312
+ const firstError = Array.isArray(body.details?.errors) ? body.details?.errors[0] : void 0;
43313
+ throw new DepositAddressValidationError(firstError ?? "Invalid recipient address");
43314
+ }
43315
+ }
43292
43316
  throw new Error(`Failed to create EOA: ${response.statusText}`);
43293
43317
  }
43294
43318
  return response.json();
@@ -43458,6 +43482,27 @@ async function getFiatCurrencies(publishableKey) {
43458
43482
  }
43459
43483
  return response.json();
43460
43484
  }
43485
+ async function getFiatExchangeRates(options2 = {}, publishableKey) {
43486
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43487
+ validatePublishableKey(pk);
43488
+ const params = new URLSearchParams();
43489
+ if (options2.currencies && options2.currencies.length > 0) {
43490
+ params.set("currencies", options2.currencies.join(","));
43491
+ }
43492
+ const queryString = params.toString();
43493
+ const url = `${API_BASE_URL}/v1/public/exchange_rates/fiat_currencies${queryString ? `?${queryString}` : ""}`;
43494
+ const response = await fetch(url, {
43495
+ method: "GET",
43496
+ headers: {
43497
+ accept: "application/json",
43498
+ "x-publishable-key": pk
43499
+ }
43500
+ });
43501
+ if (!response.ok) {
43502
+ throw new Error(`Failed to fetch fiat exchange rates: ${response.statusText}`);
43503
+ }
43504
+ return response.json();
43505
+ }
43461
43506
  async function getOnrampQuotes(request, publishableKey) {
43462
43507
  const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43463
43508
  validatePublishableKey(pk);
@@ -43606,6 +43651,21 @@ async function getProjectConfig(publishableKey, options2) {
43606
43651
  const data = await response.json();
43607
43652
  return data;
43608
43653
  }
43654
+ async function getPublicIncident(publishableKey) {
43655
+ const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43656
+ validatePublishableKey(pk);
43657
+ const response = await fetch(`${API_BASE_URL}/v1/public/projects/incident`, {
43658
+ method: "GET",
43659
+ headers: {
43660
+ accept: "application/json",
43661
+ "x-publishable-key": pk
43662
+ }
43663
+ });
43664
+ if (!response.ok) {
43665
+ throw new Error(`Failed to fetch public incident: ${response.statusText}`);
43666
+ }
43667
+ return response.json();
43668
+ }
43609
43669
  async function getIpAddress() {
43610
43670
  const response = await fetch(`${API_BASE_URL}/v1/public/ip_address`, {
43611
43671
  method: "GET",
@@ -43661,7 +43721,7 @@ async function getExternalWallets(publishableKey) {
43661
43721
  const data = await response.json();
43662
43722
  return data;
43663
43723
  }
43664
- async function getWalletMobileDeepLink(wallet, depositAddresses, publishableKey) {
43724
+ async function getWalletMobileDeepLink(wallet, depositAddresses, publishableKey, amountUsd) {
43665
43725
  const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43666
43726
  validatePublishableKey(pk);
43667
43727
  const response = await fetch(`${API_BASE_URL}/v1/public/external_wallets/mobile_deeplink`, {
@@ -43671,7 +43731,11 @@ async function getWalletMobileDeepLink(wallet, depositAddresses, publishableKey)
43671
43731
  accept: "application/json",
43672
43732
  "x-publishable-key": pk
43673
43733
  },
43674
- body: JSON.stringify({ wallet, deposit_addresses: depositAddresses })
43734
+ body: JSON.stringify({
43735
+ wallet,
43736
+ deposit_addresses: depositAddresses,
43737
+ ...amountUsd ? { amount_usd: amountUsd } : {}
43738
+ })
43675
43739
  });
43676
43740
  if (!response.ok) {
43677
43741
  throw new Error(`Failed to generate wallet deep link: ${response.statusText}`);
@@ -43716,6 +43780,15 @@ async function verifyRecipientAddress(request, publishableKey) {
43716
43780
  body: JSON.stringify(request)
43717
43781
  });
43718
43782
  if (!response.ok) {
43783
+ const body = await response.json().catch(() => null);
43784
+ if (response.status === 400 && body?.error_type === "validation_error") {
43785
+ const firstError = Array.isArray(body.details?.errors) ? body.details?.errors[0] : void 0;
43786
+ return {
43787
+ valid: false,
43788
+ failure_code: "validation_error",
43789
+ message: firstError ?? "Invalid recipient address"
43790
+ };
43791
+ }
43719
43792
  throw new Error(`Failed to verify recipient address: ${response.statusText}`);
43720
43793
  }
43721
43794
  return response.json();
@@ -44122,6 +44195,7 @@ async function stripeGetDefaultToken(params, publishableKey) {
44122
44195
  chain_type: params.chainType
44123
44196
  });
44124
44197
  if (params.countryCode) query.append("country_code", params.countryCode);
44198
+ if (params.subdivisionCode) query.append("subdivision_code", params.subdivisionCode);
44125
44199
  const response = await fetch(
44126
44200
  `${API_BASE_URL}${HEADLESS_STRIPE_BASE}/default_token?${query.toString()}`,
44127
44201
  {
@@ -51306,7 +51380,13 @@ function useDepositAddress(params) {
51306
51380
  // 24 hours in cache
51307
51381
  refetchOnMount: false,
51308
51382
  refetchOnWindowFocus: false,
51309
- retry: 3,
51383
+ // Don't retry recipient-address validation errors — they're deterministic
51384
+ // (a 400 won't succeed on retry) and we want to surface the invalid-address
51385
+ // screen immediately rather than after 3 backoff attempts.
51386
+ retry: (failureCount, error) => {
51387
+ if (isDepositAddressValidationError(error)) return false;
51388
+ return failureCount < 3;
51389
+ },
51310
51390
  retryDelay: (attempt) => Math.min(1e3 * 2 ** attempt, 1e4)
51311
51391
  // 1s, 2s, 4s (max 10s)
51312
51392
  });
@@ -51514,7 +51594,8 @@ function DepositHeader({
51514
51594
  balanceChainId,
51515
51595
  balanceTokenAddress,
51516
51596
  projectName,
51517
- publishableKey
51597
+ publishableKey,
51598
+ incident
51518
51599
  }) {
51519
51600
  const { colors: colors2, fonts, components } = useTheme();
51520
51601
  const [balance, setBalance] = (0, import_react10.useState)(null);
@@ -51612,19 +51693,64 @@ function DepositHeader({
51612
51693
  balanceTokenAddress,
51613
51694
  publishableKey
51614
51695
  ]);
51615
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "uf-flex uf-items-center uf-justify-between uf-pb-6", children: [
51616
- showBack ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
51617
- "button",
51618
- {
51619
- onClick: onBack,
51620
- className: "hover:uf-bg-secondary uf-rounded-lg uf-p-1 uf-transition-colors",
51621
- style: { color: components.header.buttonColor },
51622
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ArrowLeft, { className: "uf-w-5 uf-h-5" })
51623
- }
51624
- ) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "uf-w-5 uf-h-5 uf-invisible" }),
51625
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center", children: [
51626
- badge ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
51627
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
51696
+ const incidentMessages = incident?.messages ?? [];
51697
+ const showIncident = incident?.enabled && incidentMessages.length > 0;
51698
+ const incidentSeverity = incident?.severity ?? "degraded";
51699
+ const incidentSeverityLabel = incidentSeverity === "outage" ? "Outage" : incidentSeverity === "info" ? "Info" : "Degraded service";
51700
+ const incidentStyles = incidentSeverity === "outage" ? {
51701
+ bg: "rgba(239, 68, 68, 0.12)",
51702
+ border: "rgba(239, 68, 68, 0.35)",
51703
+ text: "#fca5a5",
51704
+ link: "#fca5a5"
51705
+ } : incidentSeverity === "info" ? {
51706
+ bg: "rgba(59, 130, 246, 0.12)",
51707
+ border: "rgba(59, 130, 246, 0.35)",
51708
+ text: "#93c5fd",
51709
+ link: "#93c5fd"
51710
+ } : {
51711
+ bg: "rgba(245, 158, 11, 0.12)",
51712
+ border: "rgba(245, 158, 11, 0.35)",
51713
+ text: "#fcd34d",
51714
+ link: "#fcd34d"
51715
+ };
51716
+ const IncidentIcon = incidentSeverity === "info" ? Info : TriangleAlert;
51717
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
51718
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "uf-flex uf-items-center uf-justify-between uf-pb-6", children: [
51719
+ showBack ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
51720
+ "button",
51721
+ {
51722
+ onClick: onBack,
51723
+ className: "hover:uf-bg-secondary uf-rounded-lg uf-p-1 uf-transition-colors",
51724
+ style: { color: components.header.buttonColor },
51725
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ArrowLeft, { className: "uf-w-5 uf-h-5" })
51726
+ }
51727
+ ) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "uf-w-5 uf-h-5 uf-invisible" }),
51728
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center", children: [
51729
+ badge ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
51730
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
51731
+ DialogTitle2,
51732
+ {
51733
+ className: "uf-text-center uf-text-base",
51734
+ style: {
51735
+ color: components.header.titleColor,
51736
+ fontFamily: fonts.medium
51737
+ },
51738
+ children: title
51739
+ }
51740
+ ),
51741
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
51742
+ "div",
51743
+ {
51744
+ className: "uf-px-2 uf-py-0.5 uf-rounded-full uf-text-[10px]",
51745
+ style: {
51746
+ backgroundColor: colors2.card,
51747
+ color: colors2.foregroundMuted,
51748
+ fontFamily: fonts.regular
51749
+ },
51750
+ children: badge.count
51751
+ }
51752
+ )
51753
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
51628
51754
  DialogTitle2,
51629
51755
  {
51630
51756
  className: "uf-text-center uf-text-base",
@@ -51635,61 +51761,91 @@ function DepositHeader({
51635
51761
  children: title
51636
51762
  }
51637
51763
  ),
51638
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
51764
+ subtitle ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
51639
51765
  "div",
51640
51766
  {
51641
- className: "uf-px-2 uf-py-0.5 uf-rounded-full uf-text-[10px]",
51767
+ className: "uf-text-xs uf-mt-1",
51642
51768
  style: {
51643
- backgroundColor: colors2.card,
51644
51769
  color: colors2.foregroundMuted,
51645
51770
  fontFamily: fonts.regular
51646
51771
  },
51647
- children: badge.count
51772
+ children: subtitle
51648
51773
  }
51649
- )
51650
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
51651
- DialogTitle2,
51652
- {
51653
- className: "uf-text-center uf-text-base",
51654
- style: {
51655
- color: components.header.titleColor,
51656
- fontFamily: fonts.medium
51657
- },
51658
- children: title
51659
- }
51660
- ),
51661
- subtitle ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
51662
- "div",
51663
- {
51664
- className: "uf-text-xs uf-mt-1",
51665
- style: {
51666
- color: colors2.foregroundMuted,
51667
- fontFamily: fonts.regular
51668
- },
51669
- children: subtitle
51670
- }
51671
- ) : showBalanceBlock ? isLoadingBalance && showBalanceSkeleton ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "uf-h-3 uf-w-32 uf-bg-muted uf-rounded uf-animate-pulse uf-mt-1" }) : balance ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
51672
- "div",
51774
+ ) : showBalanceBlock ? isLoadingBalance && showBalanceSkeleton ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "uf-h-3 uf-w-32 uf-bg-muted uf-rounded uf-animate-pulse uf-mt-1" }) : balance ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
51775
+ "div",
51776
+ {
51777
+ className: "uf-text-xs uf-mt-1",
51778
+ style: {
51779
+ color: colors2.foregroundMuted,
51780
+ fontFamily: fonts.regular
51781
+ },
51782
+ children: formatBalanceDisplay(balance, projectName)
51783
+ }
51784
+ ) : null : null
51785
+ ] }),
51786
+ showClose ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
51787
+ "button",
51673
51788
  {
51674
- className: "uf-text-xs uf-mt-1",
51675
- style: {
51676
- color: colors2.foregroundMuted,
51677
- fontFamily: fonts.regular
51678
- },
51679
- children: formatBalanceDisplay(balance, projectName)
51789
+ onClick: onClose,
51790
+ className: "hover:uf-bg-secondary uf-rounded-lg uf-p-1 uf-transition-colors",
51791
+ style: { color: components.header.buttonColor },
51792
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(X, { className: "uf-w-5 uf-h-5" })
51680
51793
  }
51681
- ) : null : null
51794
+ ) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "uf-w-5 uf-h-5 uf-invisible" })
51682
51795
  ] }),
51683
- showClose ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
51684
- "button",
51796
+ showIncident && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
51797
+ "div",
51685
51798
  {
51686
- onClick: onClose,
51687
- className: "hover:uf-bg-secondary uf-rounded-lg uf-p-1 uf-transition-colors",
51688
- style: { color: components.header.buttonColor },
51689
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(X, { className: "uf-w-5 uf-h-5" })
51799
+ className: "uf-rounded-lg uf-px-3 uf-py-2.5 uf-mb-4",
51800
+ style: {
51801
+ backgroundColor: incidentStyles.bg,
51802
+ border: `1px solid ${incidentStyles.border}`
51803
+ },
51804
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "uf-flex uf-items-start uf-gap-2.5", children: [
51805
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
51806
+ IncidentIcon,
51807
+ {
51808
+ className: "uf-w-4 uf-h-4 uf-mt-0.5 uf-shrink-0",
51809
+ style: { color: incidentStyles.text }
51810
+ }
51811
+ ),
51812
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "uf-min-w-0 uf-flex-1", children: [
51813
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "uf-flex uf-items-center uf-gap-2 uf-mb-1.5", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
51814
+ "span",
51815
+ {
51816
+ className: "uf-text-[11px] uf-leading-none uf-px-1.5 uf-py-1 uf-rounded-md",
51817
+ style: {
51818
+ color: incidentStyles.text,
51819
+ border: `1px solid ${incidentStyles.border}`,
51820
+ fontFamily: fonts.medium
51821
+ },
51822
+ children: incidentSeverityLabel
51823
+ }
51824
+ ) }),
51825
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
51826
+ "div",
51827
+ {
51828
+ className: "uf-space-y-1",
51829
+ style: { color: incidentStyles.text, fontFamily: fonts.regular },
51830
+ children: incidentMessages.map((message, index2) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "uf-text-xs uf-leading-relaxed", children: message }, `${message}-${index2}`))
51831
+ }
51832
+ ),
51833
+ incident.statusPageUrl && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
51834
+ "a",
51835
+ {
51836
+ href: incident.statusPageUrl,
51837
+ target: "_blank",
51838
+ rel: "noreferrer",
51839
+ className: "uf-inline-block uf-mt-1.5 uf-text-xs uf-underline uf-underline-offset-2",
51840
+ style: { color: incidentStyles.link, fontFamily: fonts.medium },
51841
+ children: "View status"
51842
+ }
51843
+ )
51844
+ ] })
51845
+ ] })
51690
51846
  }
51691
- ) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "uf-w-5 uf-h-5 uf-invisible" })
51692
- ] }) });
51847
+ )
51848
+ ] });
51693
51849
  }
51694
51850
  function CurrencyListItem({ currency, isSelected, onSelect }) {
51695
51851
  const { colors: colors2, fonts, components } = useTheme();
@@ -52009,7 +52165,8 @@ var en_default2 = {
52009
52165
  },
52010
52166
  stripeLink: {
52011
52167
  title: "Pay with Link",
52012
- subtitle: "Buy with card or bank"
52168
+ subtitle: "Buy with card or bank",
52169
+ unavailableInRegionMessage: "Pay with Link is currently unavailable in your region."
52013
52170
  },
52014
52171
  browserWallet: {
52015
52172
  title: "Connect Wallet",
@@ -53175,13 +53332,25 @@ function BuyWithCard({
53175
53332
  wallets: externalWallets,
53176
53333
  assetCdnUrl,
53177
53334
  hideDepositFlowInfo = false,
53178
- hideDisplayDescription = false
53335
+ hideDisplayDescription = false,
53336
+ prefilledAmountUsd
53179
53337
  }) {
53180
53338
  const { colors: colors2, fonts, components } = useTheme();
53181
- const [amount, setAmount] = (0, import_react7.useState)("");
53339
+ const cleanedPrefilledAmountUsd = React522.useMemo(() => {
53340
+ if (!prefilledAmountUsd) return "";
53341
+ return prefilledAmountUsd.replace(/[^0-9.]/g, "");
53342
+ }, [prefilledAmountUsd]);
53343
+ const parsedPrefilledAmountUsd = React522.useMemo(() => {
53344
+ const parsed = parseFloat(cleanedPrefilledAmountUsd);
53345
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
53346
+ }, [cleanedPrefilledAmountUsd]);
53347
+ const shouldAutoConvertPrefilledRef = (0, import_react7.useRef)(!!cleanedPrefilledAmountUsd);
53348
+ const [amount, setAmount] = (0, import_react7.useState)(() => cleanedPrefilledAmountUsd);
53182
53349
  const [currency, setCurrency] = (0, import_react7.useState)("usd");
53183
53350
  const [hasManualCurrencySelection, setHasManualCurrencySelection] = (0, import_react7.useState)(false);
53184
- const [hasManualAmountEntry, setHasManualAmountEntry] = (0, import_react7.useState)(false);
53351
+ const [hasManualAmountEntry, setHasManualAmountEntry] = (0, import_react7.useState)(
53352
+ () => !!cleanedPrefilledAmountUsd
53353
+ );
53185
53354
  const [showCurrencyModal, setShowCurrencyModal] = (0, import_react7.useState)(false);
53186
53355
  const [quotes, setQuotes] = (0, import_react7.useState)([]);
53187
53356
  const [quotesLoading, setQuotesLoading] = (0, import_react7.useState)(false);
@@ -53238,6 +53407,71 @@ function BuyWithCard({
53238
53407
  const [preferredCurrencyCodes, setPreferredCurrencyCodes] = (0, import_react7.useState)([]);
53239
53408
  const [currenciesLoading, setCurrenciesLoading] = (0, import_react7.useState)(true);
53240
53409
  const [destinationToken, setDestinationToken] = (0, import_react7.useState)(null);
53410
+ (0, import_react7.useEffect)(() => {
53411
+ const hasPrefilledAmount = !!cleanedPrefilledAmountUsd;
53412
+ shouldAutoConvertPrefilledRef.current = hasPrefilledAmount;
53413
+ if (!hasPrefilledAmount) return;
53414
+ setAmount(cleanedPrefilledAmountUsd);
53415
+ setHasManualAmountEntry(true);
53416
+ }, [cleanedPrefilledAmountUsd]);
53417
+ const { data: fiatExchangeRatesResponse, isLoading: isFiatExchangeRatesLoading } = useQuery({
53418
+ queryKey: ["fiat-exchange-rates", publishableKey],
53419
+ staleTime: 3e4,
53420
+ refetchInterval: 3e4,
53421
+ queryFn: async () => {
53422
+ try {
53423
+ return await getFiatExchangeRates({}, publishableKey);
53424
+ } catch (error) {
53425
+ console.error("Error fetching fiat exchange rates:", error);
53426
+ return { base_currency: "usd", rates: {} };
53427
+ }
53428
+ }
53429
+ });
53430
+ const fiatExchangeRates = fiatExchangeRatesResponse?.rates ?? {};
53431
+ const convertAmountBetweenCurrencies = React522.useCallback(
53432
+ (rawAmount, fromCurrencyCode, toCurrencyCode) => {
53433
+ const parsedAmount = parseFloat(rawAmount);
53434
+ if (!Number.isFinite(parsedAmount) || parsedAmount <= 0) return null;
53435
+ const fromCode = fromCurrencyCode.toLowerCase();
53436
+ const toCode = toCurrencyCode.toLowerCase();
53437
+ const fromRate = fromCode === "usd" ? 1 : fiatExchangeRates[fromCode];
53438
+ const toRate = toCode === "usd" ? 1 : fiatExchangeRates[toCode];
53439
+ if (!Number.isFinite(fromRate) || fromRate <= 0) return null;
53440
+ if (!Number.isFinite(toRate) || toRate <= 0) return null;
53441
+ const usdAmount = parsedAmount / fromRate;
53442
+ return parseFloat((usdAmount * toRate).toFixed(2)).toString();
53443
+ },
53444
+ [fiatExchangeRates]
53445
+ );
53446
+ const getConvertedPrefilledAmount = React522.useCallback(
53447
+ (targetCurrencyCode) => {
53448
+ if (!parsedPrefilledAmountUsd) return null;
53449
+ const normalizedTargetCurrency = targetCurrencyCode.toLowerCase();
53450
+ const rate = normalizedTargetCurrency === "usd" ? 1 : fiatExchangeRates[normalizedTargetCurrency];
53451
+ if (!Number.isFinite(rate) || rate <= 0) return null;
53452
+ return parseFloat((parsedPrefilledAmountUsd * rate).toFixed(2)).toString();
53453
+ },
53454
+ [parsedPrefilledAmountUsd, fiatExchangeRates]
53455
+ );
53456
+ (0, import_react7.useEffect)(() => {
53457
+ if (!cleanedPrefilledAmountUsd || !shouldAutoConvertPrefilledRef.current) return;
53458
+ const convertedAmount = getConvertedPrefilledAmount(currency);
53459
+ if (!convertedAmount) {
53460
+ if (isFiatExchangeRatesLoading) return;
53461
+ const targetCurrency = currency.toLowerCase();
53462
+ if (targetCurrency !== "usd") {
53463
+ setCurrency("usd");
53464
+ }
53465
+ return;
53466
+ }
53467
+ setAmount(convertedAmount);
53468
+ setHasManualAmountEntry(true);
53469
+ }, [
53470
+ cleanedPrefilledAmountUsd,
53471
+ currency,
53472
+ getConvertedPrefilledAmount,
53473
+ isFiatExchangeRatesLoading
53474
+ ]);
53241
53475
  const depositWalletId = defaultToken ? getWalletByChainType(wallets, defaultToken.destination_token_metadata.chain_type)?.id : void 0;
53242
53476
  const { executions, isPolling, showWaitingUi } = useDepositPolling({
53243
53477
  userId,
@@ -53268,6 +53502,7 @@ function BuyWithCard({
53268
53502
  }, [publishableKey]);
53269
53503
  (0, import_react7.useEffect)(() => {
53270
53504
  if (hasManualCurrencySelection) return;
53505
+ if (hasManualAmountEntry && !shouldAutoConvertPrefilledRef.current) return;
53271
53506
  if (fiatCurrencies.length === 0 || !userIpInfo?.alpha2) return;
53272
53507
  const userCountryCode = userIpInfo.alpha2;
53273
53508
  const matchingCurrency = fiatCurrencies.find((c) => c.country_codes.includes(userCountryCode));
@@ -53286,7 +53521,15 @@ function BuyWithCard({
53286
53521
  const prevCurrencyRef = (0, import_react7.useRef)(null);
53287
53522
  (0, import_react7.useEffect)(() => {
53288
53523
  if (fiatCurrencies.length === 0) return;
53524
+ if (shouldAutoConvertPrefilledRef.current) {
53525
+ prevCurrencyRef.current = currency;
53526
+ return;
53527
+ }
53289
53528
  if (prevCurrencyRef.current !== null && prevCurrencyRef.current !== currency) {
53529
+ if (hasManualAmountEntry) {
53530
+ prevCurrencyRef.current = currency;
53531
+ return;
53532
+ }
53290
53533
  const currentCurrency = fiatCurrencies.find(
53291
53534
  (c) => c.currency_code.toLowerCase() === currency.toLowerCase()
53292
53535
  );
@@ -53295,7 +53538,7 @@ function BuyWithCard({
53295
53538
  }
53296
53539
  }
53297
53540
  prevCurrencyRef.current = currency;
53298
- }, [currency]);
53541
+ }, [currency, fiatCurrencies, hasManualAmountEntry]);
53299
53542
  (0, import_react7.useEffect)(() => {
53300
53543
  async function fetchDestinationToken() {
53301
53544
  try {
@@ -53472,6 +53715,7 @@ function BuyWithCard({
53472
53715
  return () => clearInterval(timer);
53473
53716
  }, [quotes.length, amount]);
53474
53717
  const handleAmountChange = (value) => {
53718
+ shouldAutoConvertPrefilledRef.current = false;
53475
53719
  if (value === "") {
53476
53720
  setAmount(value);
53477
53721
  setHasManualAmountEntry(true);
@@ -53485,6 +53729,7 @@ function BuyWithCard({
53485
53729
  }
53486
53730
  };
53487
53731
  const handleQuickAmount = (quickAmount) => {
53732
+ shouldAutoConvertPrefilledRef.current = false;
53488
53733
  setAmount(quickAmount.toString());
53489
53734
  setHasManualAmountEntry(true);
53490
53735
  };
@@ -54088,8 +54333,43 @@ function BuyWithCard({
54088
54333
  preferredCurrencyCodes,
54089
54334
  selectedCurrency: currency,
54090
54335
  onSelectCurrency: (currencyCode) => {
54091
- setCurrency(currencyCode.toLowerCase());
54336
+ const nextCurrency = currencyCode.toLowerCase();
54337
+ if (nextCurrency === currency.toLowerCase()) {
54338
+ setHasManualCurrencySelection(true);
54339
+ return;
54340
+ }
54341
+ const currentCurrency = currency;
54092
54342
  setHasManualCurrencySelection(true);
54343
+ if (shouldAutoConvertPrefilledRef.current) {
54344
+ const convertedAmount = getConvertedPrefilledAmount(nextCurrency);
54345
+ if (convertedAmount) {
54346
+ setCurrency(nextCurrency);
54347
+ setAmount(convertedAmount);
54348
+ setHasManualAmountEntry(true);
54349
+ } else {
54350
+ if (isFiatExchangeRatesLoading) return;
54351
+ const fallbackUsdAmount = getConvertedPrefilledAmount("usd");
54352
+ setCurrency("usd");
54353
+ if (fallbackUsdAmount) {
54354
+ setAmount(fallbackUsdAmount);
54355
+ setHasManualAmountEntry(true);
54356
+ }
54357
+ }
54358
+ return;
54359
+ }
54360
+ if (hasManualAmountEntry && amount) {
54361
+ const convertedAmount = convertAmountBetweenCurrencies(
54362
+ amount,
54363
+ currentCurrency,
54364
+ nextCurrency
54365
+ );
54366
+ if (convertedAmount) {
54367
+ setCurrency(nextCurrency);
54368
+ setAmount(convertedAmount);
54369
+ }
54370
+ return;
54371
+ }
54372
+ setCurrency(nextCurrency);
54093
54373
  },
54094
54374
  themeClass
54095
54375
  }
@@ -54334,7 +54614,7 @@ function parseCoinbasePostMessage(raw) {
54334
54614
  } : void 0
54335
54615
  };
54336
54616
  }
54337
- var BuyWithApplePay = React522.forwardRef(
54617
+ var BuyWithApplePay = React622.forwardRef(
54338
54618
  function BuyWithApplePay2({
54339
54619
  userId,
54340
54620
  publishableKey,
@@ -54493,7 +54773,7 @@ var BuyWithApplePay = React522.forwardRef(
54493
54773
  popupRef.current = null;
54494
54774
  };
54495
54775
  }, []);
54496
- React522.useImperativeHandle(
54776
+ React622.useImperativeHandle(
54497
54777
  ref,
54498
54778
  () => ({
54499
54779
  requestBack: () => {
@@ -55803,7 +56083,7 @@ function LegalDisclaimer({ legalAgreements, loading }) {
55803
56083
  children: [
55804
56084
  "By continuing, you agree to Coinbase's",
55805
56085
  " ",
55806
- agreements.map((a, idx, arr) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(React522.Fragment, { children: [
56086
+ agreements.map((a, idx, arr) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(React622.Fragment, { children: [
55807
56087
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
55808
56088
  "a",
55809
56089
  {
@@ -56232,6 +56512,7 @@ var POLL_INTERVAL_MS2 = 5e3;
56232
56512
  var FALLBACK_MIN_USD = 5;
56233
56513
  var SUGGESTED_AMOUNTS = [25, 50, 100];
56234
56514
  var t3 = i18n2.depositModal.cashApp;
56515
+ var sanitizePrefilledUsd = (value) => value?.replace(/[^0-9.]/g, "") ?? "";
56235
56516
  function PayWithCashApp({
56236
56517
  userId,
56237
56518
  publishableKey,
@@ -56246,6 +56527,7 @@ function PayWithCashApp({
56246
56527
  onEvent,
56247
56528
  onDepositSuccess,
56248
56529
  onDepositError,
56530
+ prefilledAmountUsd,
56249
56531
  wallets = []
56250
56532
  }) {
56251
56533
  const { colors: colors2, fonts, components } = useTheme();
@@ -56261,7 +56543,7 @@ function PayWithCashApp({
56261
56543
  const { data: limits, isLoading: limitsLoading } = useCashAppLimits({ publishableKey });
56262
56544
  const minUsd = limits?.minimum_amount ?? FALLBACK_MIN_USD;
56263
56545
  const maxUsd = limits?.maximum_amount ?? null;
56264
- const [amount, setAmount] = (0, import_react18.useState)("");
56546
+ const [amount, setAmount] = (0, import_react18.useState)(() => sanitizePrefilledUsd(prefilledAmountUsd));
56265
56547
  const [loading, setLoading] = (0, import_react18.useState)(false);
56266
56548
  const [session, setSession] = (0, import_react18.useState)(null);
56267
56549
  const [status, setStatus] = (0, import_react18.useState)("pending");
@@ -56384,6 +56666,13 @@ function PayWithCashApp({
56384
56666
  return () => clearInterval(interval);
56385
56667
  }, [session, view, status, publishableKey, onDepositSuccess, onDepositError]);
56386
56668
  const [softExpired, setSoftExpired] = (0, import_react18.useState)(false);
56669
+ (0, import_react18.useEffect)(() => {
56670
+ if (!prefilledAmountUsd) return;
56671
+ const cleaned = sanitizePrefilledUsd(prefilledAmountUsd);
56672
+ if (!cleaned) return;
56673
+ setAmount(cleaned);
56674
+ onAmountChange?.(cleaned);
56675
+ }, [prefilledAmountUsd, onAmountChange]);
56387
56676
  (0, import_react18.useEffect)(() => {
56388
56677
  if (!session?.expires_at || view !== "payment") return;
56389
56678
  const expiresMs = new Date(session.expires_at).getTime();
@@ -56776,7 +57065,8 @@ function BankTransfer({
56776
57065
  assetCdnUrl,
56777
57066
  onDepositSuccess,
56778
57067
  onEvent,
56779
- onDepositError
57068
+ onDepositError,
57069
+ prefilledAmountUsd
56780
57070
  }) {
56781
57071
  const { colors: colors2, fonts, components } = useTheme();
56782
57072
  const [internalView, setInternalView] = (0, import_react21.useState)("providers");
@@ -56786,6 +57076,10 @@ function BankTransfer({
56786
57076
  const [requestBase, setRequestBase] = (0, import_react21.useState)(null);
56787
57077
  const [activeRequest, setActiveRequest] = (0, import_react21.useState)(null);
56788
57078
  const [amount, setAmount] = (0, import_react21.useState)("");
57079
+ const [fiatExchangeRates, setFiatExchangeRates] = (0, import_react21.useState)({
57080
+ usd: 1
57081
+ });
57082
+ const providerSelectionRequestIdRef = (0, import_react21.useRef)(0);
56789
57083
  const currentView = externalView ?? internalView;
56790
57084
  const setView = (v) => {
56791
57085
  setInternalView(v);
@@ -56835,7 +57129,38 @@ function BankTransfer({
56835
57129
  () => destinationTokenSymbol?.toUpperCase() ?? defaultToken?.destination_token_metadata?.symbol?.toUpperCase() ?? defaultToken?.destination_currency?.toUpperCase() ?? "USDC",
56836
57130
  [destinationTokenSymbol, defaultToken]
56837
57131
  );
56838
- const handleProviderClick = (provider) => {
57132
+ const resolvePrefilledSourceAmount = (0, import_react21.useCallback)(
57133
+ async (sourceCurrencyCode) => {
57134
+ const cleanedPrefilled = prefilledAmountUsd?.replace(/[^0-9.]/g, "") ?? "";
57135
+ if (!cleanedPrefilled) return "";
57136
+ const prefilledUsd = parseFloat(cleanedPrefilled);
57137
+ if (!Number.isFinite(prefilledUsd) || prefilledUsd <= 0) return "";
57138
+ const sourceCurrency2 = sourceCurrencyCode.toLowerCase();
57139
+ let rate = sourceCurrency2 === "usd" ? 1 : fiatExchangeRates[sourceCurrency2];
57140
+ if ((!rate || rate <= 0) && sourceCurrency2 !== "usd") {
57141
+ try {
57142
+ const response = await getFiatExchangeRates({}, publishableKey);
57143
+ if (response?.rates) {
57144
+ setFiatExchangeRates((prev) => ({
57145
+ ...prev,
57146
+ ...response.rates,
57147
+ usd: 1
57148
+ }));
57149
+ }
57150
+ const fetchedRate = response.rates?.[sourceCurrency2];
57151
+ if (Number.isFinite(fetchedRate) && fetchedRate > 0) {
57152
+ rate = fetchedRate;
57153
+ }
57154
+ } catch (error) {
57155
+ console.error("Error fetching fiat exchange rates for bank transfer:", error);
57156
+ }
57157
+ }
57158
+ if (!rate || rate <= 0) return sourceCurrency2 === "usd" ? cleanedPrefilled : "";
57159
+ return parseFloat((prefilledUsd * rate).toFixed(2)).toString();
57160
+ },
57161
+ [fiatExchangeRates, prefilledAmountUsd, publishableKey]
57162
+ );
57163
+ const handleProviderClick = async (provider) => {
56839
57164
  if (!provider.enabled) return;
56840
57165
  setSessionError(null);
56841
57166
  if (!defaultToken) {
@@ -56854,6 +57179,7 @@ function BankTransfer({
56854
57179
  });
56855
57180
  return;
56856
57181
  }
57182
+ const requestId = ++providerSelectionRequestIdRef.current;
56857
57183
  setRequestBase({
56858
57184
  service_provider: provider.service_provider,
56859
57185
  country_code: (userIpInfo?.alpha2 || "DE").toUpperCase(),
@@ -56867,7 +57193,10 @@ function BankTransfer({
56867
57193
  payment_method: provider.payment_methods[0]
56868
57194
  });
56869
57195
  setActiveProvider(provider);
56870
- setAmount("100");
57196
+ const convertedPrefilled = await resolvePrefilledSourceAmount(provider.source_currency);
57197
+ if (requestId !== providerSelectionRequestIdRef.current) return;
57198
+ const hasPrefilledAmount = !!prefilledAmountUsd?.replace(/[^0-9.]/g, "");
57199
+ setAmount(hasPrefilledAmount ? convertedPrefilled : "100");
56871
57200
  setView("amount");
56872
57201
  };
56873
57202
  const handleAmountChange = (value) => {
@@ -56965,7 +57294,7 @@ function BankTransfer({
56965
57294
  return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
56966
57295
  "button",
56967
57296
  {
56968
- onClick: () => handleProviderClick(provider),
57297
+ onClick: () => void handleProviderClick(provider),
56969
57298
  onMouseEnter: () => !disabled && setHoveredId(provider.service_provider),
56970
57299
  onMouseLeave: () => setHoveredId(null),
56971
57300
  disabled,
@@ -57534,9 +57863,9 @@ function TransferCryptoButton({
57534
57863
  featuredTokens
57535
57864
  }) {
57536
57865
  const { colors: colors2, fonts, components } = useTheme();
57537
- const [isHovered, setIsHovered] = React622.useState(false);
57538
- const [isTouchDevice, setIsTouchDevice] = React622.useState(false);
57539
- React622.useEffect(() => {
57866
+ const [isHovered, setIsHovered] = React72.useState(false);
57867
+ const [isTouchDevice, setIsTouchDevice] = React72.useState(false);
57868
+ React72.useEffect(() => {
57540
57869
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
57541
57870
  }, []);
57542
57871
  const sortedTokens = featuredTokens ? [...featuredTokens].sort((a, b) => a.position - b.position) : [];
@@ -57616,9 +57945,9 @@ function DepositWithCardButton({
57616
57945
  paymentNetworks
57617
57946
  }) {
57618
57947
  const { colors: colors2, fonts, components } = useTheme();
57619
- const [isHovered, setIsHovered] = React72.useState(false);
57620
- const [isTouchDevice, setIsTouchDevice] = React72.useState(false);
57621
- React72.useEffect(() => {
57948
+ const [isHovered, setIsHovered] = React82.useState(false);
57949
+ const [isTouchDevice, setIsTouchDevice] = React82.useState(false);
57950
+ React82.useEffect(() => {
57622
57951
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
57623
57952
  }, []);
57624
57953
  return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
@@ -57697,9 +58026,9 @@ function PayWithExchangeButton({
57697
58026
  loading = false
57698
58027
  }) {
57699
58028
  const { colors: colors2, fonts, components } = useTheme();
57700
- const [isHovered, setIsHovered] = React82.useState(false);
57701
- const [isTouchDevice, setIsTouchDevice] = React82.useState(false);
57702
- React82.useEffect(() => {
58029
+ const [isHovered, setIsHovered] = React92.useState(false);
58030
+ const [isTouchDevice, setIsTouchDevice] = React92.useState(false);
58031
+ React92.useEffect(() => {
57703
58032
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
57704
58033
  }, []);
57705
58034
  if (loading) {
@@ -57801,11 +58130,11 @@ var buttonVariants = cva(
57801
58130
  }
57802
58131
  }
57803
58132
  );
57804
- var Button = React92.forwardRef(
58133
+ var Button = React102.forwardRef(
57805
58134
  ({ className, variant, size: size4, asChild = false, style, ...props }, ref) => {
57806
58135
  const Comp = asChild ? Slot2 : "button";
57807
58136
  const { components, fonts } = useTheme();
57808
- const themeStyle = React92.useMemo(() => {
58137
+ const themeStyle = React102.useMemo(() => {
57809
58138
  const baseStyle = { ...style };
57810
58139
  if (variant === "default" || !variant) {
57811
58140
  baseStyle.backgroundColor = components.button.primaryBackground;
@@ -57840,9 +58169,9 @@ function ConnectExchangeButton({
57840
58169
  connectedExchange
57841
58170
  }) {
57842
58171
  const { colors: colors2, fonts, components } = useTheme();
57843
- const [isHovered, setIsHovered] = React102.useState(false);
57844
- const [isTouchDevice, setIsTouchDevice] = React102.useState(false);
57845
- React102.useEffect(() => {
58172
+ const [isHovered, setIsHovered] = React112.useState(false);
58173
+ const [isTouchDevice, setIsTouchDevice] = React112.useState(false);
58174
+ React112.useEffect(() => {
57846
58175
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
57847
58176
  }, []);
57848
58177
  const isConnected = connectedExchange != null;
@@ -57987,9 +58316,9 @@ function DepositTrackerButton({
57987
58316
  badge
57988
58317
  }) {
57989
58318
  const { colors: colors2, fonts, components } = useTheme();
57990
- const [isHovered, setIsHovered] = React112.useState(false);
57991
- const [isTouchDevice, setIsTouchDevice] = React112.useState(false);
57992
- React112.useEffect(() => {
58319
+ const [isHovered, setIsHovered] = React122.useState(false);
58320
+ const [isTouchDevice, setIsTouchDevice] = React122.useState(false);
58321
+ React122.useEffect(() => {
57993
58322
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
57994
58323
  }, []);
57995
58324
  return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
@@ -58060,9 +58389,9 @@ function DepositTrackerButton({
58060
58389
  }
58061
58390
  function CashAppButton({ onClick, title, subtitle, iconUrl }) {
58062
58391
  const { colors: colors2, fonts, components } = useTheme();
58063
- const [isHovered, setIsHovered] = React122.useState(false);
58064
- const [isTouchDevice, setIsTouchDevice] = React122.useState(false);
58065
- React122.useEffect(() => {
58392
+ const [isHovered, setIsHovered] = React132.useState(false);
58393
+ const [isTouchDevice, setIsTouchDevice] = React132.useState(false);
58394
+ React132.useEffect(() => {
58066
58395
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
58067
58396
  }, []);
58068
58397
  return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
@@ -58144,11 +58473,11 @@ function AppleLogo({ className, style }) {
58144
58473
  }
58145
58474
  );
58146
58475
  }
58147
- function ApplePayButton({ onClick, title, subtitle }) {
58476
+ function ApplePayButton({ onClick, title, subtitle, iconUrl }) {
58148
58477
  const { colors: colors2, fonts, components } = useTheme();
58149
- const [isHovered, setIsHovered] = React132.useState(false);
58150
- const [isTouchDevice, setIsTouchDevice] = React132.useState(false);
58151
- React132.useEffect(() => {
58478
+ const [isHovered, setIsHovered] = React142.useState(false);
58479
+ const [isTouchDevice, setIsTouchDevice] = React142.useState(false);
58480
+ React142.useEffect(() => {
58152
58481
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
58153
58482
  }, []);
58154
58483
  return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
@@ -58166,7 +58495,14 @@ function ApplePayButton({ onClick, title, subtitle }) {
58166
58495
  },
58167
58496
  children: [
58168
58497
  /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
58169
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "uf-rounded-lg uf-p-2", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(AppleLogo, { className: "uf-w-5 uf-h-5", style: { color: components.card.iconColor } }) }),
58498
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "uf-rounded-lg uf-overflow-hidden uf-w-9 uf-h-9 uf-flex uf-items-center uf-justify-center", children: iconUrl ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("img", { src: iconUrl, alt: "Apple Pay", width: 36, height: 36, className: "uf-rounded-lg" }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
58499
+ "div",
58500
+ {
58501
+ className: "uf-w-9 uf-h-9 uf-rounded-lg uf-flex uf-items-center uf-justify-center",
58502
+ style: { backgroundColor: "#000" },
58503
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(AppleLogo, { className: "uf-w-5 uf-h-5", style: { color: "#fff" } })
58504
+ }
58505
+ ) }),
58170
58506
  /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "uf-text-left", children: [
58171
58507
  /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
58172
58508
  "div",
@@ -58210,9 +58546,9 @@ function BankTransferButton({
58210
58546
  comingSoon = false
58211
58547
  }) {
58212
58548
  const { colors: colors2, fonts, components } = useTheme();
58213
- const [isHovered, setIsHovered] = React142.useState(false);
58214
- const [isTouchDevice, setIsTouchDevice] = React142.useState(false);
58215
- React142.useEffect(() => {
58549
+ const [isHovered, setIsHovered] = React152.useState(false);
58550
+ const [isTouchDevice, setIsTouchDevice] = React152.useState(false);
58551
+ React152.useEffect(() => {
58216
58552
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
58217
58553
  }, []);
58218
58554
  return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
@@ -58382,13 +58718,6 @@ function solanaCandidate(provider, type, name, icon) {
58382
58718
  if (provider.isConnected && provider.publicKey) {
58383
58719
  return { type, name, address: provider.publicKey.toString(), icon };
58384
58720
  }
58385
- try {
58386
- const resp = await provider.connect({ onlyIfTrusted: true });
58387
- if (resp.publicKey) {
58388
- return { type, name, address: resp.publicKey.toString(), icon };
58389
- }
58390
- } catch {
58391
- }
58392
58721
  return null;
58393
58722
  }
58394
58723
  };
@@ -58461,18 +58790,18 @@ async function detectConnectedBrowserWallet(chainType) {
58461
58790
  }
58462
58791
  function useDetectedBrowserWallet(opts = {}) {
58463
58792
  const { chainType, enabled = true, onDisconnect } = opts;
58464
- const [wallet, setWallet] = React152.useState(null);
58465
- const [isLoading, setIsLoading] = React152.useState(enabled);
58466
- const [eip6963ProviderCount, setEip6963ProviderCount] = React152.useState(0);
58467
- const onDisconnectRef = React152.useRef(onDisconnect);
58793
+ const [wallet, setWallet] = React162.useState(null);
58794
+ const [isLoading, setIsLoading] = React162.useState(enabled);
58795
+ const [eip6963ProviderCount, setEip6963ProviderCount] = React162.useState(0);
58796
+ const onDisconnectRef = React162.useRef(onDisconnect);
58468
58797
  onDisconnectRef.current = onDisconnect;
58469
- React152.useEffect(() => {
58798
+ React162.useEffect(() => {
58470
58799
  const store = getEip6963Store();
58471
58800
  if (!store) return;
58472
58801
  setEip6963ProviderCount(store.getProviders().length);
58473
58802
  return store.subscribe((providers) => setEip6963ProviderCount(providers.length));
58474
58803
  }, []);
58475
- React152.useEffect(() => {
58804
+ React162.useEffect(() => {
58476
58805
  if (!enabled) {
58477
58806
  setWallet(null);
58478
58807
  setIsLoading(false);
@@ -58612,8 +58941,180 @@ async function disconnectInjectedBrowserWallet(wallet) {
58612
58941
  collectEthereumProvidersForDisconnect(window)
58613
58942
  );
58614
58943
  }
58944
+ var STORED_TYPE_TO_EIP6963_WALLET_ID = {
58945
+ metamask: "metamask",
58946
+ "phantom-ethereum": "phantom",
58947
+ coinbase: "coinbase",
58948
+ trust: "trust",
58949
+ rainbow: "rainbow",
58950
+ rabby: "rabby",
58951
+ okx: "okx"
58952
+ };
58953
+ var EIP6963_WALLET_ID_TO_INFO = {
58954
+ metamask: { walletType: "metamask", name: "MetaMask", icon: "metamask" },
58955
+ phantom: { walletType: "phantom-ethereum", name: "Phantom", icon: "phantom" },
58956
+ coinbase: { walletType: "coinbase", name: "Coinbase Wallet", icon: "coinbase" },
58957
+ trust: { walletType: "trust", name: "Trust Wallet", icon: "trust" },
58958
+ rainbow: { walletType: "rainbow", name: "Rainbow", icon: "rainbow" },
58959
+ rabby: { walletType: "rabby", name: "Rabby", icon: "rabby" },
58960
+ okx: { walletType: "okx", name: "OKX Wallet", icon: "okx" }
58961
+ };
58962
+ var WALLET_ID_TO_WALLET_TYPE = {
58963
+ phantom: "phantom-ethereum",
58964
+ coinbase: "coinbase",
58965
+ trust: "trust",
58966
+ rainbow: "rainbow",
58967
+ rabby: "rabby",
58968
+ okx: "okx",
58969
+ metamask: "metamask"
58970
+ };
58971
+ var WALLET_TYPE_TO_WALLET_ID = {
58972
+ "phantom-ethereum": "phantom",
58973
+ coinbase: "coinbase",
58974
+ trust: "trust",
58975
+ okx: "okx",
58976
+ rainbow: "rainbow",
58977
+ rabby: "rabby",
58978
+ metamask: "metamask"
58979
+ };
58980
+ function isWalletType(value) {
58981
+ return value === "phantom-solana" || value === "phantom-ethereum" || value === "metamask" || value === "coinbase" || value === "solflare" || value === "backpack" || value === "glow" || value === "trust" || value === "rainbow" || value === "rabby" || value === "okx";
58982
+ }
58983
+ function walletIdToWalletType(walletId) {
58984
+ return WALLET_ID_TO_WALLET_TYPE[walletId] || "metamask";
58985
+ }
58986
+ function walletTypeToWalletId(walletType) {
58987
+ return WALLET_TYPE_TO_WALLET_ID[walletType] || walletType;
58988
+ }
58989
+ function getLegacyEvmProviders(win) {
58990
+ if (!win) return {};
58991
+ const anyWin = win;
58992
+ return {
58993
+ ethereum: anyWin.ethereum,
58994
+ phantomEthereum: anyWin.phantom?.ethereum,
58995
+ coinbaseEthereum: anyWin.coinbaseWalletExtension,
58996
+ trustEthereum: anyWin.trustwallet?.ethereum,
58997
+ okxEthereum: anyWin.okxwallet
58998
+ };
58999
+ }
59000
+ function getInjectedSolanaProviders(win) {
59001
+ if (!win) return {};
59002
+ const anyWin = win;
59003
+ return {
59004
+ phantomSolana: anyWin.phantom?.solana,
59005
+ solflare: anyWin.solflare,
59006
+ backpack: anyWin.backpack,
59007
+ glow: anyWin.glow,
59008
+ coinbaseSolana: anyWin.coinbaseSolana || anyWin.coinbaseWalletExtension?.solana,
59009
+ trustSolana: anyWin.trustwallet?.solana
59010
+ };
59011
+ }
59012
+ function describeEip6963Provider(wp) {
59013
+ const mapped = EIP6963_WALLET_ID_TO_INFO[wp.walletId];
59014
+ return {
59015
+ provider: wp.provider,
59016
+ walletType: mapped?.walletType ?? "metamask",
59017
+ name: mapped?.name ?? wp.info.name,
59018
+ icon: mapped?.icon ?? wp.info.icon
59019
+ };
59020
+ }
59021
+ function resolveQuickConnectEvmProvider(win) {
59022
+ const eip6963Providers = getEip6963Providers();
59023
+ if (eip6963Providers.length > 0) {
59024
+ const stored = getStoredWalletState();
59025
+ const preferredWalletId = stored?.walletType && isWalletType(stored.walletType) ? STORED_TYPE_TO_EIP6963_WALLET_ID[stored.walletType] : void 0;
59026
+ if (preferredWalletId) {
59027
+ const preferred = findProviderByWalletId(preferredWalletId);
59028
+ if (preferred) return describeEip6963Provider(preferred);
59029
+ }
59030
+ if (eip6963Providers.length === 1) {
59031
+ return describeEip6963Provider(eip6963Providers[0]);
59032
+ }
59033
+ return void 0;
59034
+ }
59035
+ const anyWin = win;
59036
+ const legacy = anyWin.phantom?.ethereum || anyWin.ethereum;
59037
+ if (!legacy) return void 0;
59038
+ const isPhantom = legacy.isPhantom;
59039
+ return {
59040
+ provider: legacy,
59041
+ walletType: isPhantom ? "phantom-ethereum" : "metamask",
59042
+ name: isPhantom ? "Phantom" : "MetaMask",
59043
+ icon: isPhantom ? "phantom" : "metamask"
59044
+ };
59045
+ }
59046
+ function resolveSolanaPublicKey(provider, response) {
59047
+ if (response?.publicKey) return { publicKey: response.publicKey };
59048
+ if (provider.publicKey) return { publicKey: provider.publicKey };
59049
+ return null;
59050
+ }
59051
+ function isUserRejectedSolanaConnectError(error) {
59052
+ if (!error || typeof error !== "object") return false;
59053
+ const maybeCode = "code" in error ? error.code : void 0;
59054
+ if (maybeCode === 4001) return true;
59055
+ const msg = "message" in error && typeof error.message === "string" ? error.message.toLowerCase() : "";
59056
+ return msg.includes("user rejected") || msg.includes("user denied") || msg.includes("rejected the request") || msg.includes("declined");
59057
+ }
59058
+ function isSolanaConnectTimeoutError(error) {
59059
+ return error instanceof Error && error.message.toLowerCase().includes("did not respond to the connection request");
59060
+ }
59061
+ async function connectSolanaProviderWithRecovery(provider, walletId, walletName) {
59062
+ if (provider.isConnected && provider.publicKey) {
59063
+ return { publicKey: provider.publicKey };
59064
+ }
59065
+ const connectOnce = () => provider.connect(walletId === "solflare" ? { onlyIfTrusted: false } : void 0);
59066
+ const withTimeout = async (ms = 2e4) => await Promise.race([
59067
+ connectOnce(),
59068
+ new Promise(
59069
+ (resolve, reject) => setTimeout(() => {
59070
+ const connected = resolveSolanaPublicKey(provider);
59071
+ if (connected) {
59072
+ resolve(connected);
59073
+ return;
59074
+ }
59075
+ reject(
59076
+ new Error(
59077
+ `${walletName} did not respond to the connection request. Please unlock the wallet and try again.`
59078
+ )
59079
+ );
59080
+ }, ms)
59081
+ )
59082
+ ]);
59083
+ if (walletId === "solflare") {
59084
+ await provider.disconnect?.().catch(() => {
59085
+ });
59086
+ }
59087
+ const connectAndResolve = async () => {
59088
+ try {
59089
+ const response = await withTimeout();
59090
+ const resolved = resolveSolanaPublicKey(provider, response);
59091
+ if (resolved) return resolved;
59092
+ await new Promise((resolve) => setTimeout(resolve, 120));
59093
+ const delayedResolved = resolveSolanaPublicKey(provider);
59094
+ if (delayedResolved) return delayedResolved;
59095
+ throw new Error(`${walletName} connected but did not expose a public key.`);
59096
+ } catch (error) {
59097
+ const connected = resolveSolanaPublicKey(provider);
59098
+ if (connected) return connected;
59099
+ throw error;
59100
+ }
59101
+ };
59102
+ try {
59103
+ return await connectAndResolve();
59104
+ } catch (err) {
59105
+ if (isUserRejectedSolanaConnectError(err)) throw err;
59106
+ if (isSolanaConnectTimeoutError(err)) throw err;
59107
+ if (walletId === "solflare") {
59108
+ await provider.disconnect?.().catch(() => {
59109
+ });
59110
+ await new Promise((resolve) => setTimeout(resolve, 150));
59111
+ return await connectAndResolve();
59112
+ }
59113
+ throw err;
59114
+ }
59115
+ }
58615
59116
  function MetamaskIcon({ size: size4 = 24, className, variant = "color" }) {
58616
- const id = React162.useId();
59117
+ const id = React172.useId();
58617
59118
  if (variant === "light" || variant === "dark") {
58618
59119
  return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
58619
59120
  "svg",
@@ -58734,7 +59235,7 @@ function MetamaskIcon({ size: size4 = 24, className, variant = "color" }) {
58734
59235
  );
58735
59236
  }
58736
59237
  function PhantomIcon({ size: size4 = 24, className, variant = "color" }) {
58737
- const id = React172.useId();
59238
+ const id = React182.useId();
58738
59239
  if (variant === "light") {
58739
59240
  return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
58740
59241
  "svg",
@@ -58801,7 +59302,7 @@ function PhantomIcon({ size: size4 = 24, className, variant = "color" }) {
58801
59302
  );
58802
59303
  }
58803
59304
  function CoinbaseIcon({ size: size4 = 24, className, variant = "color" }) {
58804
- const id = React182.useId();
59305
+ const id = React192.useId();
58805
59306
  if (variant === "light") {
58806
59307
  return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
58807
59308
  "svg",
@@ -58881,7 +59382,7 @@ function CoinbaseIcon({ size: size4 = 24, className, variant = "color" }) {
58881
59382
  );
58882
59383
  }
58883
59384
  function RabbyIcon({ size: size4 = 24, className, variant = "color" }) {
58884
- const id = React192.useId();
59385
+ const id = React202.useId();
58885
59386
  if (variant === "light") {
58886
59387
  return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
58887
59388
  "svg",
@@ -59228,7 +59729,7 @@ function RabbyIcon({ size: size4 = 24, className, variant = "color" }) {
59228
59729
  );
59229
59730
  }
59230
59731
  function RainbowIcon({ size: size4 = 24, className, variant = "color" }) {
59231
- const id = React202.useId();
59732
+ const id = React212.useId();
59232
59733
  if (variant === "light") {
59233
59734
  return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
59234
59735
  "svg",
@@ -59642,7 +60143,7 @@ function RainbowIcon({ size: size4 = 24, className, variant = "color" }) {
59642
60143
  );
59643
60144
  }
59644
60145
  function TrustIcon({ size: size4 = 24, className, variant = "color" }) {
59645
- const id = React212.useId();
60146
+ const id = React2222.useId();
59646
60147
  if (variant === "light") {
59647
60148
  return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
59648
60149
  "svg",
@@ -59725,7 +60226,7 @@ function TrustIcon({ size: size4 = 24, className, variant = "color" }) {
59725
60226
  );
59726
60227
  }
59727
60228
  function OkxIcon({ size: size4 = 24, className, variant = "color" }) {
59728
- const id = React2222.useId();
60229
+ const id = React232.useId();
59729
60230
  if (variant === "light") {
59730
60231
  return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
59731
60232
  "svg",
@@ -59780,7 +60281,7 @@ function OkxIcon({ size: size4 = 24, className, variant = "color" }) {
59780
60281
  );
59781
60282
  }
59782
60283
  function GlowIcon({ size: size4 = 24, className, variant = "color" }) {
59783
- const id = React232.useId();
60284
+ const id = React242.useId();
59784
60285
  if (variant === "light") {
59785
60286
  return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
59786
60287
  "svg",
@@ -59881,7 +60382,7 @@ function GlowIcon({ size: size4 = 24, className, variant = "color" }) {
59881
60382
  );
59882
60383
  }
59883
60384
  function BackpackIcon({ size: size4 = 24, className, variant = "color" }) {
59884
- const id = React242.useId();
60385
+ const id = React252.useId();
59885
60386
  if (variant === "light") {
59886
60387
  return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
59887
60388
  "svg",
@@ -59954,7 +60455,7 @@ function BackpackIcon({ size: size4 = 24, className, variant = "color" }) {
59954
60455
  );
59955
60456
  }
59956
60457
  function SolflareIcon({ size: size4 = 24, className, variant = "color" }) {
59957
- const id = React252.useId();
60458
+ const id = React262.useId();
59958
60459
  if (variant === "light") {
59959
60460
  return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
59960
60461
  "svg",
@@ -60021,7 +60522,7 @@ function SolflareIcon({ size: size4 = 24, className, variant = "color" }) {
60021
60522
  );
60022
60523
  }
60023
60524
  function EthereumIcon({ size: size4 = 24, className, variant = "color" }) {
60024
- const id = React262.useId();
60525
+ const id = React272.useId();
60025
60526
  if (variant === "light") {
60026
60527
  return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
60027
60528
  "svg",
@@ -60145,7 +60646,7 @@ function EthereumIcon({ size: size4 = 24, className, variant = "color" }) {
60145
60646
  );
60146
60647
  }
60147
60648
  function SolanaIcon({ size: size4 = 24, className, variant = "color" }) {
60148
- const id = React272.useId();
60649
+ const id = React282.useId();
60149
60650
  if (variant === "light") {
60150
60651
  return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
60151
60652
  "svg",
@@ -60390,19 +60891,19 @@ function BrowserWalletButton({
60390
60891
  subtitle = i18n2.depositModal.browserWallet.subtitle
60391
60892
  }) {
60392
60893
  const { colors: colors2, fonts, components } = useTheme();
60393
- const [isHovered, setIsHovered] = React282.useState(false);
60394
- const [isTouchDevice, setIsTouchDevice] = React282.useState(false);
60894
+ const [isHovered, setIsHovered] = React292.useState(false);
60895
+ const [isTouchDevice, setIsTouchDevice] = React292.useState(false);
60395
60896
  const { wallet, isLoading, setWallet } = useDetectedBrowserWallet({ chainType, onDisconnect });
60396
- const [isConnecting, setIsConnecting] = React282.useState(false);
60397
- const [balanceText, setBalanceText] = React282.useState(null);
60398
- const [isLoadingBalance, setIsLoadingBalance] = React282.useState(false);
60399
- const [isDisconnecting, setIsDisconnecting] = React282.useState(false);
60400
- const onDisconnectRef = React282.useRef(onDisconnect);
60897
+ const [isConnecting, setIsConnecting] = React292.useState(false);
60898
+ const [balanceText, setBalanceText] = React292.useState(null);
60899
+ const [isLoadingBalance, setIsLoadingBalance] = React292.useState(false);
60900
+ const [isDisconnecting, setIsDisconnecting] = React292.useState(false);
60901
+ const onDisconnectRef = React292.useRef(onDisconnect);
60401
60902
  onDisconnectRef.current = onDisconnect;
60402
- React282.useEffect(() => {
60903
+ React292.useEffect(() => {
60403
60904
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
60404
60905
  }, []);
60405
- React282.useEffect(() => {
60906
+ React292.useEffect(() => {
60406
60907
  if (!wallet || !publishableKey) {
60407
60908
  setBalanceText(null);
60408
60909
  return;
@@ -60471,21 +60972,19 @@ function BrowserWalletButton({
60471
60972
  }
60472
60973
  }
60473
60974
  if (!chainType || chainType === "ethereum") {
60474
- const ethProvider = window.phantom?.ethereum || window.ethereum;
60475
- if (ethProvider) {
60476
- const accounts = await ethProvider.request({
60975
+ const resolved = resolveQuickConnectEvmProvider(window);
60976
+ if (resolved) {
60977
+ const accounts = await resolved.provider.request({
60477
60978
  method: "eth_requestAccounts"
60478
60979
  });
60479
60980
  if (accounts && accounts.length > 0) {
60480
60981
  setUserDisconnectedWallet(false);
60481
- const isPhantom = ethProvider.isPhantom;
60482
- const walletType = isPhantom ? "phantom-ethereum" : "metamask";
60483
- setStoredWalletState(walletType);
60982
+ setStoredWalletState(resolved.walletType);
60484
60983
  setWallet({
60485
- type: walletType,
60486
- name: isPhantom ? "Phantom" : "MetaMask",
60984
+ type: resolved.walletType,
60985
+ name: resolved.name,
60487
60986
  address: accounts[0],
60488
- icon: isPhantom ? "phantom" : "metamask"
60987
+ icon: resolved.icon
60489
60988
  });
60490
60989
  }
60491
60990
  }
@@ -60519,7 +61018,10 @@ function BrowserWalletButton({
60519
61018
  if (isLoading) {
60520
61019
  return null;
60521
61020
  }
60522
- const hasWalletExtension = (!chainType || chainType === "ethereum") && getEip6963Providers().length > 0 || (!chainType || chainType === "solana") && (window.phantom?.solana?.isPhantom || window.solana?.isPhantom) || (!chainType || chainType === "ethereum") && (window.phantom?.ethereum || window.ethereum);
61021
+ const eip6963EvmProviderCount = getEip6963Providers().length;
61022
+ const legacyEvmProviders = getLegacyEvmProviders(window);
61023
+ const hasLegacyEvmProvider = eip6963EvmProviderCount === 0 && !!(legacyEvmProviders.ethereum || legacyEvmProviders.phantomEthereum || legacyEvmProviders.coinbaseEthereum || legacyEvmProviders.trustEthereum || legacyEvmProviders.okxEthereum);
61024
+ const hasWalletExtension = (!chainType || chainType === "ethereum") && eip6963EvmProviderCount > 0 || (!chainType || chainType === "solana") && (window.phantom?.solana?.isPhantom || window.solana?.isPhantom) || (!chainType || chainType === "ethereum") && hasLegacyEvmProvider;
60523
61025
  if (!onConnectClick && !wallet && !hasWalletExtension) {
60524
61026
  return null;
60525
61027
  }
@@ -60529,11 +61031,25 @@ function BrowserWalletButton({
60529
61031
  border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
60530
61032
  };
60531
61033
  const sortedWallets = featuredWallets ? [...featuredWallets].sort((a, b) => a.position - b.position) : [];
60532
- const walletIconBlock = wallet ? WALLET_ICON_COMPONENTS[wallet.icon] ? React282.createElement(WALLET_ICON_COMPONENTS[wallet.icon], {
61034
+ const isImageIcon = !!wallet && (wallet.icon.startsWith("data:") || wallet.icon.startsWith("http"));
61035
+ const walletIconBlock = wallet ? WALLET_ICON_COMPONENTS[wallet.icon] ? React292.createElement(WALLET_ICON_COMPONENTS[wallet.icon], {
60533
61036
  size: 36,
60534
61037
  className: "uf-rounded-lg",
60535
61038
  variant: "color"
60536
- }) : /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "uf-w-9 uf-h-9 uf-rounded-lg uf-bg-gray-500" }) : /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "uf-rounded-lg uf-p-2", children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Wallet, { className: "uf-w-5 uf-h-5", style: { color: components.card.iconColor } }) });
61039
+ }) : isImageIcon ? (
61040
+ // Wallet announced via EIP-6963 with no internal icon component: render its
61041
+ // own advertised icon (`info.icon`) rather than a generic placeholder.
61042
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
61043
+ "img",
61044
+ {
61045
+ src: wallet.icon,
61046
+ alt: wallet.name,
61047
+ width: 36,
61048
+ height: 36,
61049
+ className: "uf-rounded-lg uf-w-9 uf-h-9"
61050
+ }
61051
+ )
61052
+ ) : /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "uf-w-9 uf-h-9 uf-rounded-lg uf-bg-gray-500" }) : /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "uf-rounded-lg uf-p-2", children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Wallet, { className: "uf-w-5 uf-h-5", style: { color: components.card.iconColor } }) });
60537
61053
  const titleSubtitleBlock = /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "uf-text-left uf-min-w-0", children: [
60538
61054
  /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
60539
61055
  "div",
@@ -60680,9 +61196,9 @@ function StripeLinkButton({
60680
61196
  iconUrl
60681
61197
  }) {
60682
61198
  const { colors: colors2, fonts, components } = useTheme();
60683
- const [isHovered, setIsHovered] = React292.useState(false);
60684
- const [isTouchDevice, setIsTouchDevice] = React292.useState(false);
60685
- React292.useEffect(() => {
61199
+ const [isHovered, setIsHovered] = React302.useState(false);
61200
+ const [isTouchDevice, setIsTouchDevice] = React302.useState(false);
61201
+ React302.useEffect(() => {
60686
61202
  setIsTouchDevice("ontouchstart" in window || navigator.maxTouchPoints > 0);
60687
61203
  }, []);
60688
61204
  return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
@@ -61168,6 +61684,8 @@ function PayWithStripeLink({
61168
61684
  destinationChainType,
61169
61685
  destinationChainId,
61170
61686
  destinationTokenAddress,
61687
+ countryCode,
61688
+ subdivisionCode,
61171
61689
  wallets: externalWallets,
61172
61690
  email: emailProp,
61173
61691
  iconUrl,
@@ -61562,7 +62080,9 @@ function PayWithStripeLink({
61562
62080
  {
61563
62081
  tokenAddress: destinationTokenAddress,
61564
62082
  chainId: destinationChainId,
61565
- chainType: destinationChainType
62083
+ chainType: destinationChainType,
62084
+ countryCode,
62085
+ subdivisionCode
61566
62086
  },
61567
62087
  publishableKey
61568
62088
  ).then((token) => {
@@ -61581,7 +62101,14 @@ function PayWithStripeLink({
61581
62101
  return () => {
61582
62102
  cancelled = true;
61583
62103
  };
61584
- }, [publishableKey, destinationTokenAddress, destinationChainId, destinationChainType]);
62104
+ }, [
62105
+ publishableKey,
62106
+ destinationTokenAddress,
62107
+ destinationChainId,
62108
+ destinationChainType,
62109
+ countryCode,
62110
+ subdivisionCode
62111
+ ]);
61585
62112
  const destinationCurrency = stripeDestCurrency;
61586
62113
  const authInnerRef = (0, import_react22.useRef)(null);
61587
62114
  const paymentInnerRef = (0, import_react22.useRef)(null);
@@ -64557,7 +65084,8 @@ function CoinbaseConnect({
64557
65084
  defaultSourceChainType,
64558
65085
  defaultSourceChainId,
64559
65086
  defaultSourceTokenAddress,
64560
- defaultSourceSymbol
65087
+ defaultSourceSymbol,
65088
+ prefilledAmountUsd
64561
65089
  }) {
64562
65090
  const { colors: colors2, fonts, components } = useTheme();
64563
65091
  const { projectConfig } = useProjectConfig({ publishableKey });
@@ -64880,7 +65408,8 @@ function CoinbaseConnect({
64880
65408
  };
64881
65409
  const handleSelectAsset = (asset) => {
64882
65410
  setSelectedAsset(asset);
64883
- setSendAmount("");
65411
+ const cleanedPrefilled = prefilledAmountUsd?.replace(/[^0-9.]/g, "") ?? "";
65412
+ setSendAmount(cleanedPrefilled);
64884
65413
  transitionTo("enter_amount");
64885
65414
  };
64886
65415
  const handleCreateTransfer = async () => {
@@ -66478,6 +67007,24 @@ function useExchanges({
66478
67007
  });
66479
67008
  return { exchanges, isLoading };
66480
67009
  }
67010
+ function usePublicIncident({
67011
+ publishableKey,
67012
+ enabled = true
67013
+ }) {
67014
+ const {
67015
+ data: incident,
67016
+ isLoading,
67017
+ error
67018
+ } = useQuery({
67019
+ queryKey: ["unifold", "publicIncident", publishableKey],
67020
+ queryFn: () => getPublicIncident(publishableKey),
67021
+ enabled,
67022
+ staleTime: 1e3 * 30,
67023
+ refetchInterval: 1e3 * 30,
67024
+ refetchOnWindowFocus: true
67025
+ });
67026
+ return { incident, isLoading, error: error ?? null };
67027
+ }
66481
67028
  function useApplePayProviders({
66482
67029
  publishableKey,
66483
67030
  enabled = true
@@ -66573,6 +67120,7 @@ function useAddressValidation({
66573
67120
  return {
66574
67121
  isValid: null,
66575
67122
  failureCode: null,
67123
+ message: null,
66576
67124
  metadata: null,
66577
67125
  isLoading: false,
66578
67126
  error: null
@@ -66581,6 +67129,7 @@ function useAddressValidation({
66581
67129
  return {
66582
67130
  isValid: data?.valid ?? null,
66583
67131
  failureCode: data?.failure_code ?? null,
67132
+ message: data?.message ?? null,
66584
67133
  metadata: data?.metadata ?? null,
66585
67134
  isLoading,
66586
67135
  error: error ?? null
@@ -66591,7 +67140,7 @@ function ThemeStyleInjector({
66591
67140
  className
66592
67141
  }) {
66593
67142
  const { colors: colors2, fonts, mode } = useTheme();
66594
- const cssVars = React312.useMemo(() => {
67143
+ const cssVars = React322.useMemo(() => {
66595
67144
  const hexToHSL = (hex) => {
66596
67145
  hex = hex.replace("#", "");
66597
67146
  const r2 = parseInt(hex.slice(0, 2), 16) / 255;
@@ -66651,7 +67200,7 @@ function ThemeStyleInjector({
66651
67200
  ...fonts.regular ? { "--uf-font-family": fonts.regular } : {}
66652
67201
  };
66653
67202
  }, [colors2, fonts.regular]);
66654
- React312.useEffect(() => {
67203
+ React322.useEffect(() => {
66655
67204
  if (typeof document === "undefined") return;
66656
67205
  if (fonts.regular) {
66657
67206
  document.documentElement.style.setProperty("--uf-font-family", fonts.regular);
@@ -67406,6 +67955,37 @@ function TokenSelectorSheet({
67406
67955
  var getChainKey = (chainId, chainType) => {
67407
67956
  return `${chainType}:${chainId}`;
67408
67957
  };
67958
+ function getStoredSelection(key) {
67959
+ if (typeof window === "undefined") return null;
67960
+ try {
67961
+ const raw = localStorage.getItem(key);
67962
+ if (!raw) return null;
67963
+ const parsed = JSON.parse(raw);
67964
+ if (parsed && typeof parsed.symbol === "string" && typeof parsed.chainType === "string" && typeof parsed.chainId === "string") {
67965
+ return parsed;
67966
+ }
67967
+ } catch {
67968
+ }
67969
+ return null;
67970
+ }
67971
+ function saveStoredSelection(key, symbol, chainType, chainId) {
67972
+ if (typeof window === "undefined") return;
67973
+ try {
67974
+ localStorage.setItem(key, JSON.stringify({ symbol, chainType, chainId }));
67975
+ } catch {
67976
+ }
67977
+ }
67978
+ function resolveFromStorage(tokens, stored) {
67979
+ for (const t13 of tokens) {
67980
+ if (t13.symbol !== stored.symbol) continue;
67981
+ const matchedChain = t13.chains.find(
67982
+ (c) => c.chain_type === stored.chainType && c.chain_id === stored.chainId
67983
+ );
67984
+ if (matchedChain) return { token: t13, chain: matchedChain };
67985
+ if (t13.chains.length > 0) return { token: t13, chain: t13.chains[0] };
67986
+ }
67987
+ return null;
67988
+ }
67409
67989
  function resolveToken(tokens, defaultChainType, defaultChainId, defaultTokenAddress, defaultSymbol) {
67410
67990
  if (!tokens.length) return null;
67411
67991
  let selectedToken;
@@ -67455,27 +68035,73 @@ function useDefaultToken({
67455
68035
  defaultChainType,
67456
68036
  defaultChainId,
67457
68037
  defaultTokenAddress,
67458
- defaultSymbol
68038
+ defaultSymbol,
68039
+ storageKey: storageKey2
67459
68040
  }) {
67460
- const [token, setToken] = (0, import_react28.useState)(null);
67461
- const [chain, setChain] = (0, import_react28.useState)(null);
68041
+ const [token, setTokenState] = (0, import_react28.useState)(null);
68042
+ const [chain, setChainState] = (0, import_react28.useState)(null);
67462
68043
  const [initialSelectionDone, setInitialSelectionDone] = (0, import_react28.useState)(false);
67463
68044
  const appliedDefaultsRef = (0, import_react28.useRef)("");
68045
+ const tokenRef = (0, import_react28.useRef)(null);
68046
+ const chainRef = (0, import_react28.useRef)(null);
68047
+ tokenRef.current = token;
68048
+ chainRef.current = chain;
68049
+ const setToken = (0, import_react28.useCallback)(
68050
+ (newToken) => {
68051
+ tokenRef.current = newToken;
68052
+ setTokenState(newToken);
68053
+ if (storageKey2 && chainRef.current) {
68054
+ const [chainType, chainId] = chainRef.current.split(":");
68055
+ saveStoredSelection(storageKey2, newToken, chainType, chainId);
68056
+ }
68057
+ },
68058
+ [storageKey2]
68059
+ );
68060
+ const setChain = (0, import_react28.useCallback)(
68061
+ (newChain) => {
68062
+ chainRef.current = newChain;
68063
+ setChainState(newChain);
68064
+ if (storageKey2 && tokenRef.current) {
68065
+ const [chainType, chainId] = newChain.split(":");
68066
+ saveStoredSelection(storageKey2, tokenRef.current, chainType, chainId);
68067
+ }
68068
+ },
68069
+ [storageKey2]
68070
+ );
67464
68071
  (0, import_react28.useEffect)(() => {
67465
68072
  if (!tokens.length) return;
67466
68073
  const defaultsKey = `${defaultTokenAddress ?? ""}|${defaultSymbol ?? ""}|${defaultChainType ?? ""}|${defaultChainId ?? ""}`;
67467
68074
  const defaultsChanged = appliedDefaultsRef.current !== defaultsKey;
67468
68075
  if (initialSelectionDone && !defaultsChanged) return;
67469
- const result = resolveToken(
67470
- tokens,
67471
- defaultChainType,
67472
- defaultChainId,
67473
- defaultTokenAddress,
67474
- defaultSymbol
67475
- );
68076
+ const hasExplicitDefaults = defaultTokenAddress && defaultChainType && defaultChainId || defaultSymbol && defaultChainType && defaultChainId;
68077
+ let result = null;
68078
+ if (hasExplicitDefaults) {
68079
+ result = resolveToken(
68080
+ tokens,
68081
+ defaultChainType,
68082
+ defaultChainId,
68083
+ defaultTokenAddress,
68084
+ defaultSymbol
68085
+ );
68086
+ if (result) {
68087
+ const matched = defaultTokenAddress && result.chain.token_address.toLowerCase() === defaultTokenAddress.toLowerCase() && result.chain.chain_type === defaultChainType && result.chain.chain_id === defaultChainId || defaultSymbol && result.token.symbol === defaultSymbol && result.chain.chain_type === defaultChainType && result.chain.chain_id === defaultChainId;
68088
+ if (!matched) {
68089
+ result = null;
68090
+ }
68091
+ }
68092
+ }
68093
+ if (!result && storageKey2) {
68094
+ const stored = getStoredSelection(storageKey2);
68095
+ if (stored) {
68096
+ result = resolveFromStorage(tokens, stored);
68097
+ }
68098
+ }
68099
+ if (!result) {
68100
+ result = resolveToken(tokens);
68101
+ }
67476
68102
  if (result) {
67477
- setToken(result.token.symbol);
67478
- setChain(getChainKey(result.chain.chain_id, result.chain.chain_type));
68103
+ setTokenState(result.token.symbol);
68104
+ setChainState(getChainKey(result.chain.chain_id, result.chain.chain_type));
67479
68105
  appliedDefaultsRef.current = defaultsKey;
67480
68106
  setInitialSelectionDone(true);
67481
68107
  }
@@ -67485,7 +68111,8 @@ function useDefaultToken({
67485
68111
  defaultSymbol,
67486
68112
  defaultChainType,
67487
68113
  defaultChainId,
67488
- initialSelectionDone
68114
+ initialSelectionDone,
68115
+ storageKey2
67489
68116
  ]);
67490
68117
  (0, import_react28.useEffect)(() => {
67491
68118
  if (!tokens.length || !token) return;
@@ -67496,11 +68123,12 @@ function useDefaultToken({
67496
68123
  });
67497
68124
  if (!isChainAvailable) {
67498
68125
  const firstChain = currentToken.chains[0];
67499
- setChain(getChainKey(firstChain.chain_id, firstChain.chain_type));
68126
+ setChainState(getChainKey(firstChain.chain_id, firstChain.chain_type));
67500
68127
  }
67501
68128
  }, [token, tokens, chain]);
67502
68129
  return { token, chain, setToken, setChain, initialSelectionDone };
67503
68130
  }
68131
+ var STORAGE_KEY2 = "unifold_last_deposit_from_token";
67504
68132
  function useDefaultSourceToken({
67505
68133
  supportedTokens,
67506
68134
  defaultSourceChainType,
@@ -67513,7 +68141,8 @@ function useDefaultSourceToken({
67513
68141
  defaultChainType: defaultSourceChainType,
67514
68142
  defaultChainId: defaultSourceChainId,
67515
68143
  defaultTokenAddress: defaultSourceTokenAddress,
67516
- defaultSymbol: defaultSourceSymbol
68144
+ defaultSymbol: defaultSourceSymbol,
68145
+ storageKey: STORAGE_KEY2
67517
68146
  });
67518
68147
  }
67519
68148
  function DepositFooterLinks({ onGlossaryClick, leftElement }) {
@@ -67796,14 +68425,14 @@ function useCopyAddress() {
67796
68425
  return { copied, handleCopy };
67797
68426
  }
67798
68427
  var TooltipProvider2 = Provider;
67799
- var TooltipContext = React322.createContext({
68428
+ var TooltipContext = React332.createContext({
67800
68429
  open: false,
67801
68430
  onOpenChange: () => {
67802
68431
  }
67803
68432
  });
67804
- var TooltipTrigger2 = React322.forwardRef(({ onClick, ...props }, ref) => {
67805
- const { open, onOpenChange } = React322.useContext(TooltipContext);
67806
- const handleClick = React322.useCallback(
68433
+ var TooltipTrigger2 = React332.forwardRef(({ onClick, ...props }, ref) => {
68434
+ const { open, onOpenChange } = React332.useContext(TooltipContext);
68435
+ const handleClick = React332.useCallback(
67807
68436
  (e) => {
67808
68437
  onOpenChange(!open);
67809
68438
  onClick?.(e);
@@ -67813,7 +68442,7 @@ var TooltipTrigger2 = React322.forwardRef(({ onClick, ...props }, ref) => {
67813
68442
  return /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(Trigger, { ref, onClick: handleClick, ...props });
67814
68443
  });
67815
68444
  TooltipTrigger2.displayName = Trigger.displayName;
67816
- var TooltipContent2 = React322.forwardRef(({ className, sideOffset = 4, ...props }, ref) => {
68445
+ var TooltipContent2 = React332.forwardRef(({ className, sideOffset = 4, ...props }, ref) => {
67817
68446
  const { themeClass, colors: colors2 } = useTheme();
67818
68447
  return /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(Portal3, { children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
67819
68448
  Content22,
@@ -67923,6 +68552,7 @@ function TransferCryptoSingleInput({
67923
68552
  onDepositError,
67924
68553
  wallets: externalWallets,
67925
68554
  onSourceTokenChange,
68555
+ prefilledAmountUsd,
67926
68556
  checkoutQuote,
67927
68557
  isCheckoutQuoteLoading = false,
67928
68558
  persistCheckingIndicator = false,
@@ -68066,6 +68696,22 @@ function TransferCryptoSingleInput({
68066
68696
  const maxSlippage = currentChainFromBackend?.max_slippage_percent ?? 0.25;
68067
68697
  const processingTime = currentChainFromBackend?.estimated_processing_time ?? null;
68068
68698
  const minDepositUsd = currentChainFromBackend?.minimum_deposit_amount_usd ?? 3;
68699
+ const parsedPrefilledUsd = (0, import_react25.useMemo)(() => {
68700
+ const value = parseFloat(prefilledAmountUsd ?? "");
68701
+ return Number.isFinite(value) && value > 0 ? value : null;
68702
+ }, [prefilledAmountUsd]);
68703
+ const effectivePrefilledUsd = (0, import_react25.useMemo)(() => {
68704
+ if (parsedPrefilledUsd === null) return null;
68705
+ return Math.max(parsedPrefilledUsd, minDepositUsd);
68706
+ }, [parsedPrefilledUsd, minDepositUsd]);
68707
+ const prefillDisplay = (0, import_react25.useMemo)(() => {
68708
+ if (effectivePrefilledUsd === null) return null;
68709
+ const usdLabel = `$${effectivePrefilledUsd.toFixed(2)}`;
68710
+ if (selectedToken?.is_stablecoin) {
68711
+ return `${effectivePrefilledUsd.toFixed(2)} ${selectedToken.symbol} (${usdLabel})`;
68712
+ }
68713
+ return `${usdLabel} USD`;
68714
+ }, [effectivePrefilledUsd, selectedToken]);
68069
68715
  return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(TooltipProvider2, { delayDuration: 0, skipDelayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
68070
68716
  "div",
68071
68717
  {
@@ -68192,7 +68838,7 @@ function TransferCryptoSingleInput({
68192
68838
  /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { children: "Retrying automatically every 5 seconds..." })
68193
68839
  ] })
68194
68840
  ] }),
68195
- (checkoutQuote || isCheckoutQuoteLoading) && /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
68841
+ (checkoutQuote || isCheckoutQuoteLoading || prefillDisplay) && /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
68196
68842
  "div",
68197
68843
  {
68198
68844
  className: "uf-rounded-xl uf-px-3 uf-py-2 uf-flex uf-items-center uf-justify-between",
@@ -68236,6 +68882,13 @@ function TransferCryptoSingleInput({
68236
68882
  )
68237
68883
  ]
68238
68884
  }
68885
+ ) : prefillDisplay ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
68886
+ "span",
68887
+ {
68888
+ className: "uf-text-sm uf-font-semibold",
68889
+ style: { color: components.card.titleColor, fontFamily: fonts.semibold },
68890
+ children: prefillDisplay
68891
+ }
68239
68892
  ) : /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
68240
68893
  "div",
68241
68894
  {
@@ -68565,7 +69218,7 @@ function TransferCryptoSingleInput({
68565
69218
  }
68566
69219
  var Select2 = Root23;
68567
69220
  var SelectValue2 = Value;
68568
- var SelectTrigger2 = React332.forwardRef(({ className, style, children, ...props }, ref) => {
69221
+ var SelectTrigger2 = React342.forwardRef(({ className, style, children, ...props }, ref) => {
68569
69222
  const { components } = useTheme();
68570
69223
  return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(
68571
69224
  Trigger2,
@@ -68589,7 +69242,7 @@ var SelectTrigger2 = React332.forwardRef(({ className, style, children, ...props
68589
69242
  );
68590
69243
  });
68591
69244
  SelectTrigger2.displayName = Trigger2.displayName;
68592
- var SelectScrollUpButton2 = React332.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
69245
+ var SelectScrollUpButton2 = React342.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
68593
69246
  ScrollUpButton,
68594
69247
  {
68595
69248
  ref,
@@ -68599,7 +69252,7 @@ var SelectScrollUpButton2 = React332.forwardRef(({ className, ...props }, ref) =
68599
69252
  }
68600
69253
  ));
68601
69254
  SelectScrollUpButton2.displayName = ScrollUpButton.displayName;
68602
- var SelectScrollDownButton2 = React332.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
69255
+ var SelectScrollDownButton2 = React342.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
68603
69256
  ScrollDownButton,
68604
69257
  {
68605
69258
  ref,
@@ -68609,7 +69262,7 @@ var SelectScrollDownButton2 = React332.forwardRef(({ className, ...props }, ref)
68609
69262
  }
68610
69263
  ));
68611
69264
  SelectScrollDownButton2.displayName = ScrollDownButton.displayName;
68612
- var SelectContent2 = React332.forwardRef(({ className, style, children, position = "popper", ...props }, ref) => {
69265
+ var SelectContent2 = React342.forwardRef(({ className, style, children, position = "popper", ...props }, ref) => {
68613
69266
  const { themeClass, colors: colors2, components } = useTheme();
68614
69267
  return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(Portal4, { children: /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(
68615
69268
  Content23,
@@ -68647,7 +69300,7 @@ var SelectContent2 = React332.forwardRef(({ className, style, children, position
68647
69300
  ) });
68648
69301
  });
68649
69302
  SelectContent2.displayName = Content23.displayName;
68650
- var SelectLabel2 = React332.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
69303
+ var SelectLabel2 = React342.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
68651
69304
  Label,
68652
69305
  {
68653
69306
  ref,
@@ -68656,7 +69309,7 @@ var SelectLabel2 = React332.forwardRef(({ className, ...props }, ref) => /* @__P
68656
69309
  }
68657
69310
  ));
68658
69311
  SelectLabel2.displayName = Label.displayName;
68659
- var SelectItem2 = React332.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(
69312
+ var SelectItem2 = React342.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(
68660
69313
  Item,
68661
69314
  {
68662
69315
  ref,
@@ -68672,7 +69325,7 @@ var SelectItem2 = React332.forwardRef(({ className, children, ...props }, ref) =
68672
69325
  }
68673
69326
  ));
68674
69327
  SelectItem2.displayName = Item.displayName;
68675
- var SelectSeparator2 = React332.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
69328
+ var SelectSeparator2 = React342.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
68676
69329
  Separator,
68677
69330
  {
68678
69331
  ref,
@@ -68700,6 +69353,7 @@ function TransferCryptoDoubleInput({
68700
69353
  defaultSourceChainId,
68701
69354
  defaultSourceTokenAddress,
68702
69355
  defaultSourceSymbol,
69356
+ prefilledAmountUsd,
68703
69357
  depositConfirmationMode = "auto_ui",
68704
69358
  onExecutionsChange,
68705
69359
  onDepositSuccess,
@@ -68824,6 +69478,22 @@ function TransferCryptoDoubleInput({
68824
69478
  const maxSlippage = currentChainFromBackend?.max_slippage_percent ?? 0.25;
68825
69479
  const processingTime = currentChainFromBackend?.estimated_processing_time ?? null;
68826
69480
  const minDepositUsd = currentChainFromBackend?.minimum_deposit_amount_usd ?? 3;
69481
+ const parsedPrefilledUsd = (0, import_react31.useMemo)(() => {
69482
+ const value = parseFloat(prefilledAmountUsd ?? "");
69483
+ return Number.isFinite(value) && value > 0 ? value : null;
69484
+ }, [prefilledAmountUsd]);
69485
+ const effectivePrefilledUsd = (0, import_react31.useMemo)(() => {
69486
+ if (parsedPrefilledUsd === null) return null;
69487
+ return Math.max(parsedPrefilledUsd, minDepositUsd);
69488
+ }, [parsedPrefilledUsd, minDepositUsd]);
69489
+ const prefillDisplay = (0, import_react31.useMemo)(() => {
69490
+ if (effectivePrefilledUsd === null) return null;
69491
+ const usdLabel = `$${effectivePrefilledUsd.toFixed(2)}`;
69492
+ if (selectedToken?.is_stablecoin) {
69493
+ return `${effectivePrefilledUsd.toFixed(2)} ${selectedToken.symbol} (${usdLabel})`;
69494
+ }
69495
+ return `${usdLabel} USD`;
69496
+ }, [effectivePrefilledUsd, selectedToken]);
68827
69497
  const renderTokenItem = (tokenData) => {
68828
69498
  return /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
68829
69499
  /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
@@ -69004,6 +69674,35 @@ function TransferCryptoDoubleInput({
69004
69674
  /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { children: "Retrying automatically every 5 seconds..." })
69005
69675
  ] })
69006
69676
  ] }),
69677
+ prefillDisplay && /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)(
69678
+ "div",
69679
+ {
69680
+ className: "uf-rounded-xl uf-px-3 uf-py-2 uf-flex uf-items-center uf-justify-between",
69681
+ style: {
69682
+ backgroundColor: components.card.backgroundColor,
69683
+ border: `${components.card.borderWidth}px solid ${components.card.borderColor}`,
69684
+ borderRadius: components.card.borderRadius
69685
+ },
69686
+ children: [
69687
+ /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
69688
+ "span",
69689
+ {
69690
+ className: "uf-text-xs",
69691
+ style: { color: components.card.subtitleColor, fontFamily: fonts.regular },
69692
+ children: "You send"
69693
+ }
69694
+ ),
69695
+ /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
69696
+ "span",
69697
+ {
69698
+ className: "uf-text-sm uf-font-semibold",
69699
+ style: { color: components.card.titleColor, fontFamily: fonts.semibold },
69700
+ children: prefillDisplay
69701
+ }
69702
+ )
69703
+ ]
69704
+ }
69705
+ ),
69007
69706
  /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-pt-2", children: [
69008
69707
  /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
69009
69708
  "div",
@@ -70455,33 +71154,11 @@ function balancesRepresentSameToken(a, b) {
70455
71154
  if (!tokenA || !tokenB) return false;
70456
71155
  return tokenA.chain_type === tokenB.chain_type && tokenA.chain_id === tokenB.chain_id && normalizeTokenAddress(tokenA.token_address) === normalizeTokenAddress(tokenB.token_address);
70457
71156
  }
70458
- function getSolanaProviders() {
70459
- if (typeof window === "undefined") return {};
70460
- const win = window;
70461
- return {
70462
- phantomSolana: win.phantom?.solana,
70463
- solflare: win.solflare,
70464
- backpack: win.backpack,
70465
- glow: win.glow,
70466
- coinbaseSolana: win.coinbaseSolana || win.coinbaseWalletExtension?.solana
70467
- };
70468
- }
70469
- function getLegacyEvmProviders() {
70470
- if (typeof window === "undefined") return {};
70471
- const win = window;
70472
- return {
70473
- ethereum: win.ethereum,
70474
- phantomEthereum: win.phantom?.ethereum,
70475
- coinbaseEthereum: win.coinbaseWalletExtension,
70476
- trustEthereum: win.trustwallet?.ethereum,
70477
- okxEthereum: win.okxwallet
70478
- };
70479
- }
70480
71157
  function detectAvailableWallets(definitions, recentWalletId, filterChainType) {
70481
- const solProviders = getSolanaProviders();
70482
- const legacyEvm = getLegacyEvmProviders();
70483
- const eip6963List = getEip6963Providers();
70484
71158
  const win = typeof window !== "undefined" ? window : null;
71159
+ const solProviders = getInjectedSolanaProviders(win);
71160
+ const legacyEvm = getLegacyEvmProviders(win);
71161
+ const eip6963List = getEip6963Providers();
70485
71162
  const hasEip6963 = (walletId) => eip6963List.some((d) => {
70486
71163
  const rdns = d.info?.rdns || "";
70487
71164
  switch (walletId) {
@@ -70591,7 +71268,7 @@ function WalletConnect({
70591
71268
  amountQuickSelect = "percentage",
70592
71269
  onWalletDisconnect,
70593
71270
  onWalletConnected,
70594
- prefillAmountUsd,
71271
+ prefilledAmountUsd,
70595
71272
  checkoutAmountUsd,
70596
71273
  checkoutReceivedUsd,
70597
71274
  onNewDeposit,
@@ -70613,28 +71290,28 @@ function WalletConnect({
70613
71290
  onExecutionsChange
70614
71291
  }) {
70615
71292
  const { colors: colors2, fonts, components, mode } = useTheme();
70616
- const walletProvidedAtMount = React342.useRef(!!initialWalletInfo && !!initialDepositWallet);
70617
- const [activeWalletInfo, setActiveWalletInfo] = React342.useState(
71293
+ const walletProvidedAtMount = React352.useRef(!!initialWalletInfo && !!initialDepositWallet);
71294
+ const [activeWalletInfo, setActiveWalletInfo] = React352.useState(
70618
71295
  initialWalletInfo ?? null
70619
71296
  );
70620
- const [activeDepositWallet, setActiveDepositWallet] = React342.useState(
71297
+ const [activeDepositWallet, setActiveDepositWallet] = React352.useState(
70621
71298
  initialDepositWallet ?? null
70622
71299
  );
70623
71300
  const initialView = initialWalletInfo && initialDepositWallet ? "select_token" : "select_wallet";
70624
- const [view, setView] = React342.useState(initialView);
70625
- const [isTransitioning, setIsTransitioning] = React342.useState(false);
70626
- const viewRef = React342.useRef(initialView);
71301
+ const [view, setView] = React352.useState(initialView);
71302
+ const [isTransitioning, setIsTransitioning] = React352.useState(false);
71303
+ const viewRef = React352.useRef(initialView);
70627
71304
  const standalone = !canGoBack && !walletProvidedAtMount.current;
70628
71305
  const { wallet: detectedWallet, isLoading: detectingWallet } = useDetectedBrowserWallet({
70629
71306
  enabled: standalone
70630
71307
  });
70631
- const [autoResolved, setAutoResolved] = React342.useState(false);
70632
- const [selectedWalletDef, setSelectedWalletDef] = React342.useState(null);
70633
- const [connectingNetwork, setConnectingNetwork] = React342.useState(null);
70634
- const [walletError, setWalletError] = React342.useState(null);
70635
- const [isWalletConnecting, setIsWalletConnecting] = React342.useState(false);
70636
- const [eip6963ProviderCount, setEip6963ProviderCount] = React342.useState(0);
70637
- React342.useEffect(() => {
71308
+ const [autoResolved, setAutoResolved] = React352.useState(false);
71309
+ const [selectedWalletDef, setSelectedWalletDef] = React352.useState(null);
71310
+ const [connectingNetwork, setConnectingNetwork] = React352.useState(null);
71311
+ const [walletError, setWalletError] = React352.useState(null);
71312
+ const [isWalletConnecting, setIsWalletConnecting] = React352.useState(false);
71313
+ const [eip6963ProviderCount, setEip6963ProviderCount] = React352.useState(0);
71314
+ React352.useEffect(() => {
70638
71315
  const store = getEip6963Store();
70639
71316
  if (!store) return;
70640
71317
  setEip6963ProviderCount(store.getProviders().length);
@@ -70643,7 +71320,7 @@ function WalletConnect({
70643
71320
  });
70644
71321
  }, []);
70645
71322
  const { wallets: backendWallets } = useExternalWallets({ publishableKey });
70646
- const walletDefinitions = React342.useMemo(
71323
+ const walletDefinitions = React352.useMemo(
70647
71324
  () => backendWallets.length > 0 ? backendWallets.map((w) => ({
70648
71325
  id: w.id,
70649
71326
  name: w.name,
@@ -70654,32 +71331,32 @@ function WalletConnect({
70654
71331
  })) : FALLBACK_WALLET_DEFINITIONS,
70655
71332
  [backendWallets]
70656
71333
  );
70657
- const [recentWalletId, setRecentWalletIdState] = React342.useState(getLastOpenedWallet);
70658
- React342.useEffect(() => {
71334
+ const [recentWalletId, setRecentWalletIdState] = React352.useState(getLastOpenedWallet);
71335
+ React352.useEffect(() => {
70659
71336
  if (view === "select_wallet") {
70660
71337
  setRecentWalletIdState(getLastOpenedWallet());
70661
71338
  }
70662
71339
  }, [view]);
70663
- const availableWallets = React342.useMemo(
71340
+ const availableWallets = React352.useMemo(
70664
71341
  () => detectAvailableWallets(walletDefinitions, recentWalletId),
70665
71342
  [walletDefinitions, eip6963ProviderCount, recentWalletId]
70666
71343
  );
70667
- const [isMobile, setIsMobile] = React342.useState(false);
70668
- React342.useEffect(() => {
71344
+ const [isMobile, setIsMobile] = React352.useState(false);
71345
+ React352.useEffect(() => {
70669
71346
  setIsMobile(isMobileDevice());
70670
71347
  }, []);
70671
- const mobileDepositAddresses = React342.useMemo(
71348
+ const mobileDepositAddresses = React352.useMemo(
70672
71349
  () => (depositWallets ?? []).map((w) => ({ chain_type: w.chain_type, address: w.address })),
70673
71350
  [depositWallets]
70674
71351
  );
70675
- const mobileDepositWalletIds = React342.useMemo(
71352
+ const mobileDepositWalletIds = React352.useMemo(
70676
71353
  () => (depositWallets ?? []).filter((w) => w.chain_type === "ethereum" || w.chain_type === "solana").map((w) => w.id),
70677
71354
  [depositWallets]
70678
71355
  );
70679
- const [mobileRedirect, setMobileRedirect] = React342.useState(null);
70680
- const [pendingMobileWallet, setPendingMobileWallet] = React342.useState(null);
70681
- const [awaitingMobileDeposit, setAwaitingMobileDeposit] = React342.useState(false);
70682
- React342.useEffect(() => {
71356
+ const [mobileRedirect, setMobileRedirect] = React352.useState(null);
71357
+ const [pendingMobileWallet, setPendingMobileWallet] = React352.useState(null);
71358
+ const [awaitingMobileDeposit, setAwaitingMobileDeposit] = React352.useState(false);
71359
+ React352.useEffect(() => {
70683
71360
  if (!standalone || autoResolved || detectingWallet) return;
70684
71361
  if (!detectedWallet) {
70685
71362
  setAutoResolved(true);
@@ -70705,32 +71382,36 @@ function WalletConnect({
70705
71382
  depositWallets,
70706
71383
  depositWalletsLoading
70707
71384
  ]);
70708
- React342.useEffect(() => {
71385
+ React352.useEffect(() => {
70709
71386
  if (!standalone || autoResolved) return;
70710
71387
  const t13 = setTimeout(() => setAutoResolved(true), 5e3);
70711
71388
  return () => clearTimeout(t13);
70712
71389
  }, [standalone, autoResolved]);
70713
- const [balances, setBalances] = React342.useState([]);
70714
- const [isLoading, setIsLoading] = React342.useState(false);
70715
- const [selectedBalance, setSelectedBalance] = React342.useState(null);
70716
- const [totalBalanceUsd, setTotalBalanceUsd] = React342.useState(null);
70717
- const [error, setError] = React342.useState(null);
70718
- const [isDisconnectingWallet, setIsDisconnectingWallet] = React342.useState(false);
70719
- const [amountUsd, setAmountUsd] = React342.useState(prefillAmountUsd ?? "");
70720
- const [isConfirming, setIsConfirming] = React342.useState(false);
70721
- const [hasSignedTransaction, setHasSignedTransaction] = React342.useState(false);
70722
- const [tokenChainDetails, setTokenChainDetails] = React342.useState(null);
70723
- const [loadingTokenDetails, setLoadingTokenDetails] = React342.useState(false);
70724
- const [showTransactionDetails, setShowTransactionDetails] = React342.useState(false);
70725
- const [receivedUsdAtSubmission, setReceivedUsdAtSubmission] = React342.useState(null);
71390
+ const [balances, setBalances] = React352.useState([]);
71391
+ const [isLoading, setIsLoading] = React352.useState(false);
71392
+ const [selectedBalance, setSelectedBalance] = React352.useState(null);
71393
+ const [totalBalanceUsd, setTotalBalanceUsd] = React352.useState(null);
71394
+ const [error, setError] = React352.useState(null);
71395
+ const [isDisconnectingWallet, setIsDisconnectingWallet] = React352.useState(false);
71396
+ const [amountUsd, setAmountUsd] = React352.useState(prefilledAmountUsd ?? "");
71397
+ const [isConfirming, setIsConfirming] = React352.useState(false);
71398
+ const [hasSignedTransaction, setHasSignedTransaction] = React352.useState(false);
71399
+ const [tokenChainDetails, setTokenChainDetails] = React352.useState(null);
71400
+ const [loadingTokenDetails, setLoadingTokenDetails] = React352.useState(false);
71401
+ const [showTransactionDetails, setShowTransactionDetails] = React352.useState(false);
71402
+ const [receivedUsdAtSubmission, setReceivedUsdAtSubmission] = React352.useState(null);
70726
71403
  const walletInfo = activeWalletInfo;
70727
71404
  const depositWallet = activeDepositWallet;
70728
71405
  const hasWallet = !!activeWalletInfo && !!activeDepositWallet;
71406
+ React352.useEffect(() => {
71407
+ const cleanedPrefilled = prefilledAmountUsd?.replace(/[^0-9.]/g, "") ?? "";
71408
+ setAmountUsd(cleanedPrefilled);
71409
+ }, [prefilledAmountUsd]);
70729
71410
  const chainType = activeDepositWallet?.chain_type ?? "ethereum";
70730
71411
  const recipientAddress = activeDepositWallet?.address ?? "";
70731
71412
  const isCheckoutMode = !!checkoutAmountUsd;
70732
71413
  const supportedChainType = chainType === "algorand" || chainType === "xrpl" || chainType === "cardano" || chainType === "n1" ? "ethereum" : chainType;
70733
- const transitionTo = React342.useCallback((nextView) => {
71414
+ const transitionTo = React352.useCallback((nextView) => {
70734
71415
  if (nextView === viewRef.current) return;
70735
71416
  setIsTransitioning(true);
70736
71417
  setTimeout(() => {
@@ -70746,10 +71427,13 @@ function WalletConnect({
70746
71427
  };
70747
71428
  const openMobileWalletBrowse = async (wallet, depositAddresses) => {
70748
71429
  try {
71430
+ const cleanedAmountUsd = amountUsd?.replace(/[^0-9.]/g, "") ?? "";
71431
+ const forwardedAmountUsd = parseFloat(cleanedAmountUsd) > 0 ? cleanedAmountUsd : void 0;
70749
71432
  const res = await getWalletMobileDeepLink(
70750
71433
  wallet.id,
70751
71434
  depositAddresses,
70752
- publishableKey
71435
+ publishableKey,
71436
+ forwardedAmountUsd
70753
71437
  );
70754
71438
  if (res.deeplink) {
70755
71439
  setMobileRedirect({ walletId: wallet.id, walletName: wallet.name, deeplink: res.deeplink });
@@ -70795,7 +71479,7 @@ function WalletConnect({
70795
71479
  if (!selectedWalletDef) return;
70796
71480
  handleConnectWallet(selectedWalletDef, network);
70797
71481
  };
70798
- React342.useEffect(() => {
71482
+ React352.useEffect(() => {
70799
71483
  if (!pendingMobileWallet) return;
70800
71484
  if (mobileDepositAddresses.length > 0) {
70801
71485
  const wallet = pendingMobileWallet;
@@ -70838,7 +71522,7 @@ function WalletConnect({
70838
71522
  const eip6963Match = findProviderByWalletId(wallet.id);
70839
71523
  let provider = eip6963Match?.provider;
70840
71524
  if (!provider) {
70841
- const legacyEvm = getLegacyEvmProviders();
71525
+ const legacyEvm = getLegacyEvmProviders(win);
70842
71526
  switch (wallet.id) {
70843
71527
  case "metamask":
70844
71528
  if (legacyEvm.ethereum?.isMetaMask && !legacyEvm.ethereum?.isPhantom)
@@ -70870,16 +71554,7 @@ function WalletConnect({
70870
71554
  const accounts = await provider.request({ method: "eth_requestAccounts" });
70871
71555
  if (!accounts?.length) throw new Error("No accounts returned from wallet");
70872
71556
  setUserDisconnectedWallet(false);
70873
- const walletIdToType = {
70874
- phantom: "phantom-ethereum",
70875
- coinbase: "coinbase",
70876
- trust: "trust",
70877
- rainbow: "rainbow",
70878
- rabby: "rabby",
70879
- okx: "okx",
70880
- metamask: "metamask"
70881
- };
70882
- const walletType = walletIdToType[wallet.id] || "metamask";
71557
+ const walletType = walletIdToWalletType(wallet.id);
70883
71558
  setStoredWalletState(walletType);
70884
71559
  connectedInfo = {
70885
71560
  type: walletType,
@@ -70888,7 +71563,7 @@ function WalletConnect({
70888
71563
  icon: wallet.id
70889
71564
  };
70890
71565
  } else {
70891
- const solProviders = getSolanaProviders();
71566
+ const solProviders = getInjectedSolanaProviders(win);
70892
71567
  let provider;
70893
71568
  switch (wallet.id) {
70894
71569
  case "phantom":
@@ -70907,11 +71582,11 @@ function WalletConnect({
70907
71582
  provider = solProviders.coinbaseSolana || win?.coinbaseWalletExtension?.solana;
70908
71583
  break;
70909
71584
  case "trust":
70910
- provider = win?.trustwallet?.solana;
71585
+ provider = solProviders.trustSolana;
70911
71586
  break;
70912
71587
  }
70913
71588
  if (!provider) throw new Error(`${wallet.name} Solana wallet not found.`);
70914
- const response = await provider.connect();
71589
+ const response = await connectSolanaProviderWithRecovery(provider, wallet.id, wallet.name);
70915
71590
  setUserDisconnectedWallet(false);
70916
71591
  const walletType = wallet.id === "solflare" ? "solflare" : wallet.id === "backpack" ? "backpack" : wallet.id === "glow" ? "glow" : "phantom-solana";
70917
71592
  setStoredWalletState(walletType);
@@ -70959,7 +71634,7 @@ function WalletConnect({
70959
71634
  publishableKey,
70960
71635
  enabled: !!activeWalletInfo && !!recipientAddress
70961
71636
  });
70962
- const effectiveDestinationAmount = React342.useMemo(() => {
71637
+ const effectiveDestinationAmount = React352.useMemo(() => {
70963
71638
  if (!checkoutRemainingBaseUnits || checkoutRemainingBaseUnits === "0") return "0";
70964
71639
  if (!checkoutAmountUsd) return checkoutRemainingBaseUnits;
70965
71640
  const remaining = BigInt(checkoutRemainingBaseUnits);
@@ -70987,7 +71662,7 @@ function WalletConnect({
70987
71662
  stablecoinParity,
70988
71663
  enabled: isCheckoutMode && !!selectedToken && !!checkoutDestination && effectiveDestinationAmount !== "0"
70989
71664
  });
70990
- const activeCheckoutQuote = React342.useMemo(() => {
71665
+ const activeCheckoutQuote = React352.useMemo(() => {
70991
71666
  if (!isCheckoutMode) return null;
70992
71667
  if (walletCheckoutQuote)
70993
71668
  return {
@@ -71017,10 +71692,10 @@ function WalletConnect({
71017
71692
  onDepositSuccess,
71018
71693
  onDepositError
71019
71694
  });
71020
- React342.useEffect(() => {
71695
+ React352.useEffect(() => {
71021
71696
  onExecutionsChange?.(depositExecutions);
71022
71697
  }, [depositExecutions, onExecutionsChange]);
71023
- const latestDepositExecution = React342.useMemo(() => {
71698
+ const latestDepositExecution = React352.useMemo(() => {
71024
71699
  if (depositExecutions.length === 0) return null;
71025
71700
  return [...depositExecutions].sort((a, b) => {
71026
71701
  const ta = a.created_at ? new Date(a.created_at).getTime() : 0;
@@ -71028,21 +71703,21 @@ function WalletConnect({
71028
71703
  return tb - ta;
71029
71704
  })[0];
71030
71705
  }, [depositExecutions]);
71031
- React342.useEffect(() => {
71706
+ React352.useEffect(() => {
71032
71707
  if (awaitingMobileDeposit && latestDepositExecution && (viewRef.current === "mobile_redirect" || viewRef.current === "connecting")) {
71033
71708
  transitionTo("mobile_deposit_status");
71034
71709
  }
71035
71710
  }, [awaitingMobileDeposit, latestDepositExecution, transitionTo]);
71036
- React342.useEffect(() => {
71037
- if (!prefillAmountUsd || !tokenChainDetails || view !== "enter_amount") return;
71711
+ React352.useEffect(() => {
71712
+ if (!isCheckoutMode || !tokenChainDetails || view !== "enter_amount") return;
71038
71713
  const minDeposit = tokenChainDetails.minimum_deposit_amount_usd || 0;
71039
71714
  const currentAmount = parseFloat(amountUsd) || 0;
71040
71715
  if (currentAmount > 0 && currentAmount < minDeposit) setAmountUsd(minDeposit.toFixed(2));
71041
- }, [tokenChainDetails, view, prefillAmountUsd]);
71042
- React342.useEffect(() => {
71716
+ }, [isCheckoutMode, tokenChainDetails, view, amountUsd]);
71717
+ React352.useEffect(() => {
71043
71718
  if (view === "review") setShowTransactionDetails(false);
71044
71719
  }, [view]);
71045
- React342.useEffect(() => {
71720
+ React352.useEffect(() => {
71046
71721
  if (view !== "enter_amount" && view !== "review" || !selectedBalance || !activeDepositWallet)
71047
71722
  return;
71048
71723
  let cancelled = false;
@@ -71079,7 +71754,7 @@ function WalletConnect({
71079
71754
  cancelled = true;
71080
71755
  };
71081
71756
  }, [view, selectedBalance, publishableKey, activeDepositWallet]);
71082
- React342.useEffect(() => {
71757
+ React352.useEffect(() => {
71083
71758
  if (!activeWalletInfo || !activeDepositWallet) return;
71084
71759
  let cancelled = false;
71085
71760
  setIsLoading(true);
@@ -71144,21 +71819,21 @@ function WalletConnect({
71144
71819
  defaultSourceTokenAddress,
71145
71820
  defaultSourceSymbol
71146
71821
  ]);
71147
- const usdToTokenRate = React342.useMemo(() => {
71822
+ const usdToTokenRate = React352.useMemo(() => {
71148
71823
  if (!selectedBalance || !selectedBalance.amount_usd || !selectedToken) return 0;
71149
71824
  const balanceAmount = Number(selectedBalance.amount) / 10 ** selectedToken.decimals;
71150
71825
  const balanceUsd = parseFloat(selectedBalance.amount_usd);
71151
71826
  if (balanceAmount === 0 || balanceUsd === 0) return 0;
71152
71827
  return balanceAmount / balanceUsd;
71153
71828
  }, [selectedBalance, selectedToken]);
71154
- const tokenAmount = React342.useMemo(() => {
71829
+ const tokenAmount = React352.useMemo(() => {
71155
71830
  if (isCheckoutMode && activeCheckoutQuote && selectedToken)
71156
71831
  return Number(activeCheckoutQuote.sourceAmount) / 10 ** activeCheckoutQuote.sourceTokenDecimals;
71157
71832
  const usdNum = parseFloat(amountUsd) || 0;
71158
71833
  if (usdNum === 0 || usdToTokenRate === 0) return 0;
71159
71834
  return usdNum * usdToTokenRate;
71160
71835
  }, [amountUsd, usdToTokenRate, isCheckoutMode, activeCheckoutQuote, selectedToken]);
71161
- React342.useEffect(() => {
71836
+ React352.useEffect(() => {
71162
71837
  if (isCheckoutMode && activeCheckoutQuote?.sourceAmountUsd && view === "enter_amount")
71163
71838
  setAmountUsd(activeCheckoutQuote.sourceAmountUsd);
71164
71839
  }, [isCheckoutMode, activeCheckoutQuote, view]);
@@ -71167,7 +71842,7 @@ function WalletConnect({
71167
71842
  const inputUsdNum = parseFloat(amountUsd) || 0;
71168
71843
  const minDepositUsd = tokenChainDetails?.minimum_deposit_amount_usd || 0;
71169
71844
  const isValidAmount = isCheckoutMode && activeCheckoutQuote ? tokenAmount > 0 && tokenAmount <= maxTokenAmount : inputUsdNum > 0 && inputUsdNum <= maxUsdAmount && inputUsdNum >= minDepositUsd;
71170
- const formattedTokenAmount = React342.useMemo(() => {
71845
+ const formattedTokenAmount = React352.useMemo(() => {
71171
71846
  if (tokenAmount === 0 || !selectedToken) return null;
71172
71847
  return `${tokenAmount.toFixed(6)} ${selectedToken.symbol}`.replace(/\.?0+$/, "");
71173
71848
  }, [tokenAmount, selectedToken]);
@@ -71200,7 +71875,7 @@ function WalletConnect({
71200
71875
  break;
71201
71876
  case "enter_amount":
71202
71877
  transitionTo("select_token");
71203
- setAmountUsd(prefillAmountUsd ?? "");
71878
+ setAmountUsd(prefilledAmountUsd ?? "");
71204
71879
  setTokenChainDetails(null);
71205
71880
  break;
71206
71881
  case "review":
@@ -71232,7 +71907,7 @@ function WalletConnect({
71232
71907
  setSelectedBalance(null);
71233
71908
  setBalances([]);
71234
71909
  setTotalBalanceUsd(null);
71235
- setAmountUsd(prefillAmountUsd ?? "");
71910
+ setAmountUsd(prefilledAmountUsd ?? "");
71236
71911
  setError(null);
71237
71912
  };
71238
71913
  if (standalone) {
@@ -71262,16 +71937,7 @@ function WalletConnect({
71262
71937
  return (integerPart + decimalPart.padEnd(decimals, "0").slice(0, decimals)).replace(/^0+/, "") || "0";
71263
71938
  };
71264
71939
  const resolveEvmProvider = () => {
71265
- const walletIdMap = {
71266
- "phantom-ethereum": "phantom",
71267
- coinbase: "coinbase",
71268
- trust: "trust",
71269
- okx: "okx",
71270
- rainbow: "rainbow",
71271
- rabby: "rabby",
71272
- metamask: "metamask"
71273
- };
71274
- const lookupId = walletIdMap[walletInfo.type] || walletInfo.type;
71940
+ const lookupId = walletTypeToWalletId(walletInfo.type);
71275
71941
  const eip6963Match = findProviderByWalletId(lookupId);
71276
71942
  let provider = eip6963Match?.provider;
71277
71943
  if (!provider) {
@@ -71956,6 +72622,15 @@ function SkeletonButton({ variant = "default" }) {
71956
72622
  ] });
71957
72623
  }
71958
72624
  var t8 = i18n2.depositModal;
72625
+ function normalizePrefilledUsdAmount(value) {
72626
+ if (!value) return void 0;
72627
+ const cleaned = value.replace(/[^0-9.]/g, "");
72628
+ if (!cleaned) return void 0;
72629
+ const normalizedNumeric = cleaned.replace(/(\..*)\./g, "$1");
72630
+ const parsed = parseFloat(normalizedNumeric);
72631
+ if (!Number.isFinite(parsed) || parsed <= 0) return void 0;
72632
+ return parseFloat(parsed.toFixed(2)).toString();
72633
+ }
71959
72634
  function depositTabForScreen(screen) {
71960
72635
  return screen === "card" || screen === "cashapp" || screen === "bank_transfer" || screen === "stripe_link" || screen === "apple_pay" ? "cash" : "crypto";
71961
72636
  }
@@ -71975,6 +72650,7 @@ function DepositModal({
71975
72650
  defaultSourceChainId,
71976
72651
  defaultSourceTokenAddress,
71977
72652
  defaultSourceSymbol,
72653
+ prefilledAmountUsd,
71978
72654
  hideDepositTracker,
71979
72655
  showBalanceHeader = false,
71980
72656
  transferInputVariant = "double_input",
@@ -71990,6 +72666,7 @@ function DepositModal({
71990
72666
  applePayTitle = "Pay with Apple Pay",
71991
72667
  applePaySubTitle = "Instant",
71992
72668
  enableBankTransfer,
72669
+ enableIncidentBanner = false,
71993
72670
  // No default: left undefined so the backend `stripe_link.enabled` can govern
71994
72671
  // (via the `??` chain in showStripeLink) once a dashboard toggle exists.
71995
72672
  enableStripeLink,
@@ -72010,6 +72687,10 @@ function DepositModal({
72010
72687
  depositTrackerSubTitle = t8.depositTracker.subtitle
72011
72688
  }) {
72012
72689
  const { colors: colors2, fonts, components } = useTheme();
72690
+ const normalizedPrefilledAmountUsd = (0, import_react3.useMemo)(
72691
+ () => normalizePrefilledUsdAmount(prefilledAmountUsd),
72692
+ [prefilledAmountUsd]
72693
+ );
72013
72694
  const onDepositSuccessFor = (0, import_react3.useCallback)(
72014
72695
  (method) => onDepositSuccess || onEvent ? (data) => {
72015
72696
  const payload = { ...data, method };
@@ -72031,7 +72712,7 @@ function DepositModal({
72031
72712
  const s = initialScreen ?? "main";
72032
72713
  if (s === "tracker" && hideDepositTracker === true) return "main";
72033
72714
  if (s === "cashapp" && enableCashApp === false) return "main";
72034
- if (s === "stripe_link" && !enableStripeLink) return "main";
72715
+ if (s === "stripe_link" && enableStripeLink === false) return "main";
72035
72716
  if (s === "apple_pay" && enableApplePay === false) return "main";
72036
72717
  if (s === "card" && enableFiatOnramp === false) return "main";
72037
72718
  if (s === "pay_with_exchange") return enablePayWithExchange === false ? "main" : "exchange";
@@ -72090,6 +72771,16 @@ function DepositModal({
72090
72771
  const showApplePay = enableApplePay ?? projectConfig?.apple_pay?.enabled ?? true;
72091
72772
  const showBankTransfer = enableBankTransfer ?? projectConfig?.bank_transfer?.enabled ?? true;
72092
72773
  const showDepositTracker = hideDepositTracker ? false : projectConfig?.deposit_tracker?.enabled ?? true;
72774
+ const { incident: publicIncident } = usePublicIncident({
72775
+ publishableKey,
72776
+ enabled: open && enableIncidentBanner
72777
+ });
72778
+ const activeIncident = enableIncidentBanner && publicIncident?.enabled && (publicIncident.messages?.length ?? 0) > 0 ? {
72779
+ enabled: true,
72780
+ messages: publicIncident.messages,
72781
+ severity: publicIncident.severity,
72782
+ statusPageUrl: publicIncident.status_page_url
72783
+ } : void 0;
72093
72784
  const [integrationExchanges, setIntegrationExchanges] = (0, import_react3.useState)([]);
72094
72785
  (0, import_react3.useEffect)(() => {
72095
72786
  if (!showConnectExchange || !open) return;
@@ -72156,7 +72847,11 @@ function DepositModal({
72156
72847
  setConnectedExchange((prev) => prev ? { ...prev, iconUrl } : prev);
72157
72848
  }
72158
72849
  }, [integrationExchanges, connectedExchange]);
72159
- const { data: depositAddressResponse, isLoading: walletsLoading } = useDepositAddress({
72850
+ const {
72851
+ data: depositAddressResponse,
72852
+ isLoading: walletsLoading,
72853
+ error: walletsError
72854
+ } = useDepositAddress({
72160
72855
  userId,
72161
72856
  publishableKey,
72162
72857
  recipientAddress,
@@ -72289,6 +72984,7 @@ function DepositModal({
72289
72984
  const {
72290
72985
  isValid: isAddressValid,
72291
72986
  failureCode: addressFailureCode,
72987
+ message: addressFailureMessage,
72292
72988
  metadata: addressFailureMetadata,
72293
72989
  isLoading: isAddressValidationLoading
72294
72990
  } = useAddressValidation({
@@ -72302,17 +72998,31 @@ function DepositModal({
72302
72998
  refetchOnMount: "always"
72303
72999
  });
72304
73000
  const addressValidationMessages = i18n2.transferCrypto.addressValidation;
72305
- const getAddressValidationErrorMessage = (code, metadata) => {
73001
+ const getAddressValidationErrorMessage = (message, code, metadata) => {
73002
+ if (message && message.trim().length > 0) return message;
72306
73003
  if (!code) return addressValidationMessages.defaultError;
72307
73004
  const errors = addressValidationMessages.errors;
72308
73005
  const template = errors[code] ?? addressValidationMessages.defaultError;
72309
73006
  return interpolate(template, metadata);
72310
73007
  };
73008
+ const walletsRecipientError = isDepositAddressValidationError(walletsError) ? walletsError.message : null;
73009
+ const isRecipientAddressInvalid = isAddressValid === false || walletsRecipientError !== null;
73010
+ const recipientInvalidMessage = getAddressValidationErrorMessage(
73011
+ addressFailureMessage ?? walletsRecipientError,
73012
+ addressFailureCode,
73013
+ addressFailureMetadata
73014
+ );
72311
73015
  const openingScreen = effectiveInitialScreen;
72312
73016
  const sessionOpenedFromMenu = openingScreen === "main";
72313
73017
  const standaloneNeedsDepositPrereq = openingScreen !== "main" && (view === "transfer" || view === "card");
72314
73018
  let depositPrerequisiteBody;
72315
- if (isCountryLoading || isAddressValidationLoading || tokensLoading || walletsLoading || !projectConfig || // Bank-transfer row visibility depends on the country-gated providers
73019
+ if (isRecipientAddressInvalid) {
73020
+ depositPrerequisiteBody = /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-8 uf-px-4 uf-text-center", children: [
73021
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "uf-w-16 uf-h-16 uf-rounded-full uf-bg-muted uf-flex uf-items-center uf-justify-center uf-mb-4", children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(TriangleAlert, { className: "uf-w-8 uf-h-8 uf-text-muted-foreground" }) }),
73022
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("h3", { className: "uf-text-lg uf-font-semibold uf-text-foreground uf-mb-2", children: addressValidationMessages.unableToReceiveFunds }),
73023
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("p", { className: "uf-text-sm uf-text-muted-foreground uf-max-w-[280px]", children: recipientInvalidMessage })
73024
+ ] });
73025
+ } else if (isCountryLoading || isAddressValidationLoading || tokensLoading || walletsLoading || !projectConfig || // Bank-transfer row visibility depends on the country-gated providers
72316
73026
  // fetch — block the menu on it so the row never flashes in or out.
72317
73027
  showBankTransfer && bankTransferProvidersLoading || // Same for Apple Pay: row visibility depends on the geo/platform-gated
72318
73028
  // providers fetch — block the menu so the row doesn't pop in or out.
@@ -72334,12 +73044,6 @@ function DepositModal({
72334
73044
  /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("h3", { className: "uf-text-lg uf-font-semibold uf-text-foreground uf-mb-2", children: "No Tokens Available" }),
72335
73045
  /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("p", { className: "uf-text-sm uf-text-muted-foreground uf-max-w-[280px]", children: "There are no supported tokens available from your current location." })
72336
73046
  ] });
72337
- } else if (isAddressValid === false) {
72338
- depositPrerequisiteBody = /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center uf-justify-center uf-py-8 uf-px-4 uf-text-center", children: [
72339
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "uf-w-16 uf-h-16 uf-rounded-full uf-bg-muted uf-flex uf-items-center uf-justify-center uf-mb-4", children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(TriangleAlert, { className: "uf-w-8 uf-h-8 uf-text-muted-foreground" }) }),
72340
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("h3", { className: "uf-text-lg uf-font-semibold uf-text-foreground uf-mb-2", children: addressValidationMessages.unableToReceiveFunds }),
72341
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("p", { className: "uf-text-sm uf-text-muted-foreground uf-max-w-[280px]", children: getAddressValidationErrorMessage(addressFailureCode, addressFailureMetadata) })
72342
- ] });
72343
73047
  } else {
72344
73048
  depositPrerequisiteBody = null;
72345
73049
  }
@@ -72833,6 +73537,7 @@ function DepositModal({
72833
73537
  title: modalTitle || "Deposit",
72834
73538
  showClose: !hideOverlay,
72835
73539
  onClose: handleClose,
73540
+ incident: activeIncident,
72836
73541
  showBalance: showBalanceHeader,
72837
73542
  balanceAddress: recipientAddress,
72838
73543
  balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
@@ -72852,6 +73557,7 @@ function DepositModal({
72852
73557
  showBack: showBackTransfer,
72853
73558
  onBack: handleBack,
72854
73559
  onClose: handleClose,
73560
+ incident: activeIncident,
72855
73561
  showBalance: showBalanceHeader,
72856
73562
  balanceAddress: recipientAddress,
72857
73563
  balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
@@ -72875,6 +73581,7 @@ function DepositModal({
72875
73581
  defaultSourceChainId,
72876
73582
  defaultSourceTokenAddress,
72877
73583
  defaultSourceSymbol,
73584
+ prefilledAmountUsd: normalizedPrefilledAmountUsd,
72878
73585
  depositConfirmationMode,
72879
73586
  onExecutionsChange: setDepositExecutions,
72880
73587
  onDepositSuccess: onDepositSuccessFor("transfer"),
@@ -72894,6 +73601,7 @@ function DepositModal({
72894
73601
  defaultSourceChainId,
72895
73602
  defaultSourceTokenAddress,
72896
73603
  defaultSourceSymbol,
73604
+ prefilledAmountUsd: normalizedPrefilledAmountUsd,
72897
73605
  depositConfirmationMode,
72898
73606
  onExecutionsChange: setDepositExecutions,
72899
73607
  onDepositSuccess: onDepositSuccessFor("transfer"),
@@ -72910,7 +73618,8 @@ function DepositModal({
72910
73618
  title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
72911
73619
  showBack: showBackTracker,
72912
73620
  onBack: handleBack,
72913
- onClose: handleClose
73621
+ onClose: handleClose,
73622
+ incident: activeIncident
72914
73623
  }
72915
73624
  ),
72916
73625
  /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
@@ -72942,6 +73651,7 @@ function DepositModal({
72942
73651
  showBack: showBackCard,
72943
73652
  onBack: handleBack,
72944
73653
  onClose: handleClose,
73654
+ incident: activeIncident,
72945
73655
  badge: cardView === "quotes" ? { count: quotesCount } : void 0,
72946
73656
  showBalance: showBalanceHeader,
72947
73657
  balanceAddress: recipientAddress,
@@ -72978,7 +73688,8 @@ function DepositModal({
72978
73688
  wallets,
72979
73689
  assetCdnUrl: projectConfig?.asset_cdn_url,
72980
73690
  hideDepositFlowInfo,
72981
- hideDisplayDescription
73691
+ hideDisplayDescription,
73692
+ prefilledAmountUsd: normalizedPrefilledAmountUsd
72982
73693
  }
72983
73694
  ),
72984
73695
  depositPoweredByFooter
@@ -72990,7 +73701,8 @@ function DepositModal({
72990
73701
  title: payWithExchangeTitle,
72991
73702
  showBack: exchangeView === "pending" || sessionOpenedFromMenu,
72992
73703
  onBack: handleBack,
72993
- onClose: handleClose
73704
+ onClose: handleClose,
73705
+ incident: activeIncident
72994
73706
  }
72995
73707
  ),
72996
73708
  /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
@@ -73043,7 +73755,8 @@ function DepositModal({
73043
73755
  defaultSourceChainType,
73044
73756
  defaultSourceChainId,
73045
73757
  defaultSourceTokenAddress,
73046
- defaultSourceSymbol
73758
+ defaultSourceSymbol,
73759
+ prefilledAmountUsd: normalizedPrefilledAmountUsd
73047
73760
  }
73048
73761
  ),
73049
73762
  depositPoweredByFooter
@@ -73075,6 +73788,7 @@ function DepositModal({
73075
73788
  onDepositSuccess: onDepositSuccessFor("wallet_connect"),
73076
73789
  onDepositError: onDepositErrorFor("wallet_connect"),
73077
73790
  amountQuickSelect: browserWalletAmountQuickSelect,
73791
+ prefilledAmountUsd: normalizedPrefilledAmountUsd,
73078
73792
  onWalletDisconnect: handleWalletDisconnect,
73079
73793
  onWalletConnected: (info, dw) => {
73080
73794
  setBrowserWalletInfo({ ...info, depositWallet: dw });
@@ -73102,7 +73816,8 @@ function DepositModal({
73102
73816
  title: t8.bankTransfer.title,
73103
73817
  showBack: bankTransferView !== "providers" || sessionOpenedFromMenu,
73104
73818
  onBack: handleBack,
73105
- onClose: handleClose
73819
+ onClose: handleClose,
73820
+ incident: activeIncident
73106
73821
  }
73107
73822
  ),
73108
73823
  /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
@@ -73123,7 +73838,8 @@ function DepositModal({
73123
73838
  assetCdnUrl: projectConfig?.asset_cdn_url,
73124
73839
  onEvent,
73125
73840
  onDepositSuccess,
73126
- onDepositError
73841
+ onDepositError,
73842
+ prefilledAmountUsd: normalizedPrefilledAmountUsd
73127
73843
  }
73128
73844
  ),
73129
73845
  depositPoweredByFooter
@@ -73135,26 +73851,24 @@ function DepositModal({
73135
73851
  title: "Deposit with Link",
73136
73852
  showBack: stripeLinkStep !== "checkout" && stripeLinkStep !== "success",
73137
73853
  onBack: handleBack,
73138
- showClose: stripeLinkStep !== "checkout",
73854
+ incident: activeIncident,
73855
+ showClose: stripeLinkStep !== "checkout" && stripeLinkStep !== "auth",
73139
73856
  onClose: handleClose
73140
73857
  }
73141
73858
  ),
73142
73859
  /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
73143
73860
  isLoadingIp ? (
73144
- // Hold the geo decision until IP resolves so we don't mount
73145
- // PayWithStripeLink (which kicks off config/OAuth work) for a
73146
- // deep-link user who turns out to be outside the US.
73861
+ // Wait for location so the first config fetch is region-aware.
73147
73862
  /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(SkeletonButton, { variant: "with-icons" })
73148
73863
  ) : !showStripeLink ? (
73149
- // Stripe Link's crypto on-ramp is US-only. On a direct open
73150
- // (initialScreen="stripe_link") the row isn't in a menu to
73151
- // fall back to, so show a geo-restriction screen rather than
73152
- // the Link UI.
73864
+ // Direct opens (initialScreen="stripe_link") have no menu row
73865
+ // to fall back to, so render an unavailable state when backend
73866
+ // config resolves Stripe Link disabled/hidden.
73153
73867
  /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
73154
73868
  GeoRestrictionScreen,
73155
73869
  {
73156
73870
  methodName: t8.stripeLink.title,
73157
- message: "Pay with Link is only available in the US."
73871
+ message: t8.stripeLink.unavailableInRegionMessage
73158
73872
  }
73159
73873
  )
73160
73874
  ) : /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
@@ -73166,6 +73880,8 @@ function DepositModal({
73166
73880
  destinationChainType,
73167
73881
  destinationChainId,
73168
73882
  destinationTokenAddress,
73883
+ countryCode: userIpInfo?.alpha2,
73884
+ subdivisionCode: userIpInfo?.subdivisionCode ?? void 0,
73169
73885
  wallets,
73170
73886
  email: userEmail,
73171
73887
  iconUrl: projectConfig?.asset_cdn_url ? `${projectConfig.asset_cdn_url}/api/public/icons/onramps/svg/link.svg` : void 0,
@@ -73185,7 +73901,8 @@ function DepositModal({
73185
73901
  title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
73186
73902
  showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
73187
73903
  onBack: handleBack,
73188
- onClose: handleClose
73904
+ onClose: handleClose,
73905
+ incident: activeIncident
73189
73906
  }
73190
73907
  ),
73191
73908
  /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
@@ -73205,6 +73922,7 @@ function DepositModal({
73205
73922
  onEvent,
73206
73923
  onDepositSuccess: onDepositSuccessFor("cashapp"),
73207
73924
  onDepositError: onDepositErrorFor("cashapp"),
73925
+ prefilledAmountUsd: normalizedPrefilledAmountUsd,
73208
73926
  wallets
73209
73927
  }
73210
73928
  ),
@@ -73220,7 +73938,8 @@ function DepositModal({
73220
73938
  const handled = applePayHandleRef.current?.requestBack() ?? false;
73221
73939
  if (!handled) handleBack();
73222
73940
  },
73223
- onClose: handleClose
73941
+ onClose: handleClose,
73942
+ incident: activeIncident
73224
73943
  }
73225
73944
  ),
73226
73945
  /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
@@ -73335,6 +74054,7 @@ function CheckoutModal({
73335
74054
  modalTitle,
73336
74055
  enableTransferCrypto,
73337
74056
  enableConnectWallet,
74057
+ enableIncidentBanner = false,
73338
74058
  defaultSourceChainType,
73339
74059
  defaultSourceChainId,
73340
74060
  defaultSourceTokenAddress,
@@ -73406,6 +74126,16 @@ function CheckoutModal({
73406
74126
  });
73407
74127
  const showTransferCrypto = enableTransferCrypto ?? projectConfig?.transfer_crypto?.enabled ?? true;
73408
74128
  const showConnectWallet = enableConnectWallet ?? projectConfig?.connect_wallet?.enabled ?? true;
74129
+ const { incident: publicIncident } = usePublicIncident({
74130
+ publishableKey,
74131
+ enabled: open && enableIncidentBanner
74132
+ });
74133
+ const activeIncident = enableIncidentBanner && publicIncident?.enabled && (publicIncident.messages?.length ?? 0) > 0 ? {
74134
+ enabled: true,
74135
+ messages: publicIncident.messages,
74136
+ severity: publicIncident.severity,
74137
+ statusPageUrl: publicIncident.status_page_url
74138
+ } : void 0;
73409
74139
  (0, import_react35.useEffect)(() => {
73410
74140
  if (view === "transfer" && !showTransferCrypto) {
73411
74141
  setView("main");
@@ -73707,7 +74437,15 @@ function CheckoutModal({
73707
74437
  {
73708
74438
  className: view === "wallet_connect" ? "uf-flex uf-min-h-0 uf-flex-col" : void 0,
73709
74439
  children: view === "main" ? /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)(import_jsx_runtime83.Fragment, { children: [
73710
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(DepositHeader, { title: modalTitle || "Checkout", showClose: true, onClose: handleClose }),
74440
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
74441
+ DepositHeader,
74442
+ {
74443
+ title: modalTitle || "Checkout",
74444
+ showClose: true,
74445
+ onClose: handleClose,
74446
+ incident: activeIncident
74447
+ }
74448
+ ),
73711
74449
  /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
73712
74450
  piLoading ? /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "uf-space-y-3", children: [
73713
74451
  /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
@@ -73805,7 +74543,8 @@ function CheckoutModal({
73805
74543
  title: modalTitle || "Checkout",
73806
74544
  showBack: true,
73807
74545
  onBack: handleBack,
73808
- onClose: handleClose
74546
+ onClose: handleClose,
74547
+ incident: activeIncident
73809
74548
  }
73810
74549
  ),
73811
74550
  /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
@@ -73904,7 +74643,7 @@ function CheckoutModal({
73904
74643
  userId: paymentIntent.user_id || "",
73905
74644
  publishableKey,
73906
74645
  clientSecret,
73907
- prefillAmountUsd: remainingAmountUsd,
74646
+ prefilledAmountUsd: remainingAmountUsd,
73908
74647
  checkoutAmountUsd: paymentIntent.amount_usd,
73909
74648
  checkoutReceivedUsd: paymentIntent.amount_received_usd,
73910
74649
  checkoutDestination: {
@@ -73975,6 +74714,7 @@ function useSupportedDestinationTokens(publishableKey, enabled = true) {
73975
74714
  enabled
73976
74715
  });
73977
74716
  }
74717
+ var STORAGE_KEY3 = "unifold_last_withdraw_to_token";
73978
74718
  function useDefaultDestinationToken({
73979
74719
  destinationTokens,
73980
74720
  defaultDestinationChainType,
@@ -73987,7 +74727,8 @@ function useDefaultDestinationToken({
73987
74727
  defaultChainType: defaultDestinationChainType,
73988
74728
  defaultChainId: defaultDestinationChainId,
73989
74729
  defaultTokenAddress: defaultDestinationTokenAddress,
73990
- defaultSymbol: defaultDestinationSymbol
74730
+ defaultSymbol: defaultDestinationSymbol,
74731
+ storageKey: STORAGE_KEY3
73991
74732
  });
73992
74733
  }
73993
74734
  function useSourceTokenValidation(params) {
@@ -74661,6 +75402,9 @@ function WithdrawForm({
74661
75402
  if (isDebouncing || isVerifyingAddress) return null;
74662
75403
  if (verifyError) return t10.invalidAddress;
74663
75404
  if (addressVerification && !addressVerification.valid) {
75405
+ if (addressVerification.message && addressVerification.message.trim().length > 0) {
75406
+ return addressVerification.message;
75407
+ }
74664
75408
  if (addressVerification.failure_code === "account_not_found")
74665
75409
  return `Account not found on ${selectedChain?.chain_name}`;
74666
75410
  if (addressVerification.failure_code === "not_opted_in")
@@ -75917,6 +76661,7 @@ function UnifoldProvider2({
75917
76661
  const [isWithdrawOpen, setIsWithdrawOpen] = (0, import_react.useState)(false);
75918
76662
  const [withdrawConfig, setWithdrawConfig] = (0, import_react.useState)(null);
75919
76663
  const [resolvedTheme, setResolvedTheme] = import_react.default.useState("dark");
76664
+ const incidentBannerEnabled = config?.notifications?.incidentBanner;
75920
76665
  (0, import_react.useEffect)(() => {
75921
76666
  if (publishableKey) {
75922
76667
  setApiConfig({ publishableKey });
@@ -76214,6 +76959,7 @@ function UnifoldProvider2({
76214
76959
  publishableKey,
76215
76960
  enableTransferCrypto: config?.enableTransferCrypto,
76216
76961
  enableConnectWallet: config?.enableConnectWallet,
76962
+ enableIncidentBanner: incidentBannerEnabled,
76217
76963
  defaultSourceChainType: checkoutConfig.defaultSourceChainType,
76218
76964
  defaultSourceChainId: checkoutConfig.defaultSourceChainId,
76219
76965
  defaultSourceTokenAddress: checkoutConfig.defaultSourceTokenAddress,
@@ -76267,6 +77013,7 @@ function UnifoldProvider2({
76267
77013
  defaultSourceChainId: depositConfig.defaultSourceChainId,
76268
77014
  defaultSourceTokenAddress: depositConfig.defaultSourceTokenAddress,
76269
77015
  defaultSourceSymbol: depositConfig.defaultSourceSymbol,
77016
+ prefilledAmountUsd: depositConfig.prefilledAmountUsd,
76270
77017
  userEmail: depositConfig.user?.email,
76271
77018
  depositConfirmationMode: depositConfig.depositConfirmationMode ?? "auto_ui",
76272
77019
  hideDepositTracker: config?.hideDepositTracker,
@@ -76280,6 +77027,7 @@ function UnifoldProvider2({
76280
77027
  enableConnectExchange: config?.enableConnectExchange,
76281
77028
  enableCashApp: config?.enableCashApp,
76282
77029
  enableStripeLink: config?.enableStripeLink,
77030
+ enableIncidentBanner: incidentBannerEnabled,
76283
77031
  enableApplePay: config?.enableApplePay,
76284
77032
  applePayTitle: config?.applePayTitle,
76285
77033
  applePaySubTitle: config?.applePaySubTitle,