@unifold/ui-web 0.1.69 → 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 +615 -173
- package/dist/index.mjs +615 -173
- package/dist/styles-base.css +1 -1
- package/dist/styles.css +1 -1
- package/package.json +5 -5
package/dist/index.mjs
CHANGED
|
@@ -38400,7 +38400,10 @@ ${new this._window.XMLSerializer().serializeToString(e3)}`;
|
|
|
38400
38400
|
})()));
|
|
38401
38401
|
}
|
|
38402
38402
|
});
|
|
38403
|
-
var
|
|
38403
|
+
var UNIFOLD_CONTEXT_KEY = /* @__PURE__ */ Symbol.for("unifold.react-provider.context");
|
|
38404
|
+
var globalRef = globalThis;
|
|
38405
|
+
var UnifoldContext = globalRef[UNIFOLD_CONTEXT_KEY] ?? (0, import_react2.createContext)(null);
|
|
38406
|
+
globalRef[UNIFOLD_CONTEXT_KEY] = UnifoldContext;
|
|
38404
38407
|
var createQueryClient = () => new QueryClient({
|
|
38405
38408
|
defaultOptions: {
|
|
38406
38409
|
queries: {
|
|
@@ -43160,6 +43163,9 @@ var getDefaultConfig = () => {
|
|
|
43160
43163
|
};
|
|
43161
43164
|
};
|
|
43162
43165
|
var twMerge = /* @__PURE__ */ createTailwindMerge(getDefaultConfig);
|
|
43166
|
+
var __defProp22 = Object.defineProperty;
|
|
43167
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp22(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
43168
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
43163
43169
|
function formatStablecoinAmount(baseUnits, decimals) {
|
|
43164
43170
|
const raw = Number(baseUnits) / 10 ** decimals;
|
|
43165
43171
|
const floored = Math.floor(raw * 100) / 100;
|
|
@@ -43250,6 +43256,16 @@ var ActionType = /* @__PURE__ */ ((ActionType2) => {
|
|
|
43250
43256
|
ActionType2["Withdraw"] = "withdraw";
|
|
43251
43257
|
return ActionType2;
|
|
43252
43258
|
})(ActionType || {});
|
|
43259
|
+
var DepositAddressValidationError = class extends Error {
|
|
43260
|
+
constructor(message) {
|
|
43261
|
+
super(message);
|
|
43262
|
+
__publicField(this, "isDepositAddressValidationError", true);
|
|
43263
|
+
this.name = "DepositAddressValidationError";
|
|
43264
|
+
}
|
|
43265
|
+
};
|
|
43266
|
+
function isDepositAddressValidationError(error) {
|
|
43267
|
+
return error instanceof Error && error.isDepositAddressValidationError === true;
|
|
43268
|
+
}
|
|
43253
43269
|
async function createDepositAddress(overrides, publishableKey) {
|
|
43254
43270
|
if (!overrides?.external_user_id) {
|
|
43255
43271
|
throw new Error("external_user_id is required");
|
|
@@ -43277,6 +43293,13 @@ async function createDepositAddress(overrides, publishableKey) {
|
|
|
43277
43293
|
body: JSON.stringify(payload)
|
|
43278
43294
|
});
|
|
43279
43295
|
if (!response.ok) {
|
|
43296
|
+
if (response.status === 400) {
|
|
43297
|
+
const body = await response.json().catch(() => null);
|
|
43298
|
+
if (body?.error_type === "validation_error") {
|
|
43299
|
+
const firstError = Array.isArray(body.details?.errors) ? body.details?.errors[0] : void 0;
|
|
43300
|
+
throw new DepositAddressValidationError(firstError ?? "Invalid recipient address");
|
|
43301
|
+
}
|
|
43302
|
+
}
|
|
43280
43303
|
throw new Error(`Failed to create EOA: ${response.statusText}`);
|
|
43281
43304
|
}
|
|
43282
43305
|
return response.json();
|
|
@@ -43615,6 +43638,21 @@ async function getProjectConfig(publishableKey, options2) {
|
|
|
43615
43638
|
const data = await response.json();
|
|
43616
43639
|
return data;
|
|
43617
43640
|
}
|
|
43641
|
+
async function getPublicIncident(publishableKey) {
|
|
43642
|
+
const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
|
|
43643
|
+
validatePublishableKey(pk);
|
|
43644
|
+
const response = await fetch(`${API_BASE_URL}/v1/public/projects/incident`, {
|
|
43645
|
+
method: "GET",
|
|
43646
|
+
headers: {
|
|
43647
|
+
accept: "application/json",
|
|
43648
|
+
"x-publishable-key": pk
|
|
43649
|
+
}
|
|
43650
|
+
});
|
|
43651
|
+
if (!response.ok) {
|
|
43652
|
+
throw new Error(`Failed to fetch public incident: ${response.statusText}`);
|
|
43653
|
+
}
|
|
43654
|
+
return response.json();
|
|
43655
|
+
}
|
|
43618
43656
|
async function getIpAddress() {
|
|
43619
43657
|
const response = await fetch(`${API_BASE_URL}/v1/public/ip_address`, {
|
|
43620
43658
|
method: "GET",
|
|
@@ -43670,7 +43708,7 @@ async function getExternalWallets(publishableKey) {
|
|
|
43670
43708
|
const data = await response.json();
|
|
43671
43709
|
return data;
|
|
43672
43710
|
}
|
|
43673
|
-
async function getWalletMobileDeepLink(wallet, depositAddresses, publishableKey) {
|
|
43711
|
+
async function getWalletMobileDeepLink(wallet, depositAddresses, publishableKey, amountUsd) {
|
|
43674
43712
|
const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
|
|
43675
43713
|
validatePublishableKey(pk);
|
|
43676
43714
|
const response = await fetch(`${API_BASE_URL}/v1/public/external_wallets/mobile_deeplink`, {
|
|
@@ -43680,7 +43718,11 @@ async function getWalletMobileDeepLink(wallet, depositAddresses, publishableKey)
|
|
|
43680
43718
|
accept: "application/json",
|
|
43681
43719
|
"x-publishable-key": pk
|
|
43682
43720
|
},
|
|
43683
|
-
body: JSON.stringify({
|
|
43721
|
+
body: JSON.stringify({
|
|
43722
|
+
wallet,
|
|
43723
|
+
deposit_addresses: depositAddresses,
|
|
43724
|
+
...amountUsd ? { amount_usd: amountUsd } : {}
|
|
43725
|
+
})
|
|
43684
43726
|
});
|
|
43685
43727
|
if (!response.ok) {
|
|
43686
43728
|
throw new Error(`Failed to generate wallet deep link: ${response.statusText}`);
|
|
@@ -43725,6 +43767,15 @@ async function verifyRecipientAddress(request, publishableKey) {
|
|
|
43725
43767
|
body: JSON.stringify(request)
|
|
43726
43768
|
});
|
|
43727
43769
|
if (!response.ok) {
|
|
43770
|
+
const body = await response.json().catch(() => null);
|
|
43771
|
+
if (response.status === 400 && body?.error_type === "validation_error") {
|
|
43772
|
+
const firstError = Array.isArray(body.details?.errors) ? body.details?.errors[0] : void 0;
|
|
43773
|
+
return {
|
|
43774
|
+
valid: false,
|
|
43775
|
+
failure_code: "validation_error",
|
|
43776
|
+
message: firstError ?? "Invalid recipient address"
|
|
43777
|
+
};
|
|
43778
|
+
}
|
|
43728
43779
|
throw new Error(`Failed to verify recipient address: ${response.statusText}`);
|
|
43729
43780
|
}
|
|
43730
43781
|
return response.json();
|
|
@@ -51316,7 +51367,13 @@ function useDepositAddress(params) {
|
|
|
51316
51367
|
// 24 hours in cache
|
|
51317
51368
|
refetchOnMount: false,
|
|
51318
51369
|
refetchOnWindowFocus: false,
|
|
51319
|
-
retry
|
|
51370
|
+
// Don't retry recipient-address validation errors — they're deterministic
|
|
51371
|
+
// (a 400 won't succeed on retry) and we want to surface the invalid-address
|
|
51372
|
+
// screen immediately rather than after 3 backoff attempts.
|
|
51373
|
+
retry: (failureCount, error) => {
|
|
51374
|
+
if (isDepositAddressValidationError(error)) return false;
|
|
51375
|
+
return failureCount < 3;
|
|
51376
|
+
},
|
|
51320
51377
|
retryDelay: (attempt) => Math.min(1e3 * 2 ** attempt, 1e4)
|
|
51321
51378
|
// 1s, 2s, 4s (max 10s)
|
|
51322
51379
|
});
|
|
@@ -51524,7 +51581,8 @@ function DepositHeader({
|
|
|
51524
51581
|
balanceChainId,
|
|
51525
51582
|
balanceTokenAddress,
|
|
51526
51583
|
projectName,
|
|
51527
|
-
publishableKey
|
|
51584
|
+
publishableKey,
|
|
51585
|
+
incident
|
|
51528
51586
|
}) {
|
|
51529
51587
|
const { colors: colors2, fonts, components } = useTheme();
|
|
51530
51588
|
const [balance, setBalance] = (0, import_react10.useState)(null);
|
|
@@ -51622,19 +51680,64 @@ function DepositHeader({
|
|
|
51622
51680
|
balanceTokenAddress,
|
|
51623
51681
|
publishableKey
|
|
51624
51682
|
]);
|
|
51625
|
-
|
|
51626
|
-
|
|
51627
|
-
|
|
51628
|
-
|
|
51629
|
-
|
|
51630
|
-
|
|
51631
|
-
|
|
51632
|
-
|
|
51633
|
-
|
|
51634
|
-
|
|
51635
|
-
|
|
51636
|
-
|
|
51637
|
-
|
|
51683
|
+
const incidentMessages = incident?.messages ?? [];
|
|
51684
|
+
const showIncident = incident?.enabled && incidentMessages.length > 0;
|
|
51685
|
+
const incidentSeverity = incident?.severity ?? "degraded";
|
|
51686
|
+
const incidentSeverityLabel = incidentSeverity === "outage" ? "Outage" : incidentSeverity === "info" ? "Info" : "Degraded service";
|
|
51687
|
+
const incidentStyles = incidentSeverity === "outage" ? {
|
|
51688
|
+
bg: "rgba(239, 68, 68, 0.12)",
|
|
51689
|
+
border: "rgba(239, 68, 68, 0.35)",
|
|
51690
|
+
text: "#fca5a5",
|
|
51691
|
+
link: "#fca5a5"
|
|
51692
|
+
} : incidentSeverity === "info" ? {
|
|
51693
|
+
bg: "rgba(59, 130, 246, 0.12)",
|
|
51694
|
+
border: "rgba(59, 130, 246, 0.35)",
|
|
51695
|
+
text: "#93c5fd",
|
|
51696
|
+
link: "#93c5fd"
|
|
51697
|
+
} : {
|
|
51698
|
+
bg: "rgba(245, 158, 11, 0.12)",
|
|
51699
|
+
border: "rgba(245, 158, 11, 0.35)",
|
|
51700
|
+
text: "#fcd34d",
|
|
51701
|
+
link: "#fcd34d"
|
|
51702
|
+
};
|
|
51703
|
+
const IncidentIcon = incidentSeverity === "info" ? Info : TriangleAlert;
|
|
51704
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
|
|
51705
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "uf-flex uf-items-center uf-justify-between uf-pb-6", children: [
|
|
51706
|
+
showBack ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
51707
|
+
"button",
|
|
51708
|
+
{
|
|
51709
|
+
onClick: onBack,
|
|
51710
|
+
className: "hover:uf-bg-secondary uf-rounded-lg uf-p-1 uf-transition-colors",
|
|
51711
|
+
style: { color: components.header.buttonColor },
|
|
51712
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ArrowLeft, { className: "uf-w-5 uf-h-5" })
|
|
51713
|
+
}
|
|
51714
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "uf-w-5 uf-h-5 uf-invisible" }),
|
|
51715
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "uf-flex uf-flex-col uf-items-center", children: [
|
|
51716
|
+
badge ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-2", children: [
|
|
51717
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
51718
|
+
DialogTitle2,
|
|
51719
|
+
{
|
|
51720
|
+
className: "uf-text-center uf-text-base",
|
|
51721
|
+
style: {
|
|
51722
|
+
color: components.header.titleColor,
|
|
51723
|
+
fontFamily: fonts.medium
|
|
51724
|
+
},
|
|
51725
|
+
children: title
|
|
51726
|
+
}
|
|
51727
|
+
),
|
|
51728
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
51729
|
+
"div",
|
|
51730
|
+
{
|
|
51731
|
+
className: "uf-px-2 uf-py-0.5 uf-rounded-full uf-text-[10px]",
|
|
51732
|
+
style: {
|
|
51733
|
+
backgroundColor: colors2.card,
|
|
51734
|
+
color: colors2.foregroundMuted,
|
|
51735
|
+
fontFamily: fonts.regular
|
|
51736
|
+
},
|
|
51737
|
+
children: badge.count
|
|
51738
|
+
}
|
|
51739
|
+
)
|
|
51740
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
51638
51741
|
DialogTitle2,
|
|
51639
51742
|
{
|
|
51640
51743
|
className: "uf-text-center uf-text-base",
|
|
@@ -51645,61 +51748,91 @@ function DepositHeader({
|
|
|
51645
51748
|
children: title
|
|
51646
51749
|
}
|
|
51647
51750
|
),
|
|
51648
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
51751
|
+
subtitle ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
51649
51752
|
"div",
|
|
51650
51753
|
{
|
|
51651
|
-
className: "uf-
|
|
51754
|
+
className: "uf-text-xs uf-mt-1",
|
|
51652
51755
|
style: {
|
|
51653
|
-
backgroundColor: colors2.card,
|
|
51654
51756
|
color: colors2.foregroundMuted,
|
|
51655
51757
|
fontFamily: fonts.regular
|
|
51656
51758
|
},
|
|
51657
|
-
children:
|
|
51759
|
+
children: subtitle
|
|
51658
51760
|
}
|
|
51659
|
-
)
|
|
51660
|
-
|
|
51661
|
-
|
|
51662
|
-
|
|
51663
|
-
|
|
51664
|
-
|
|
51665
|
-
|
|
51666
|
-
|
|
51667
|
-
|
|
51668
|
-
|
|
51669
|
-
|
|
51670
|
-
),
|
|
51671
|
-
|
|
51672
|
-
"
|
|
51673
|
-
{
|
|
51674
|
-
className: "uf-text-xs uf-mt-1",
|
|
51675
|
-
style: {
|
|
51676
|
-
color: colors2.foregroundMuted,
|
|
51677
|
-
fontFamily: fonts.regular
|
|
51678
|
-
},
|
|
51679
|
-
children: subtitle
|
|
51680
|
-
}
|
|
51681
|
-
) : 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)(
|
|
51682
|
-
"div",
|
|
51761
|
+
) : 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)(
|
|
51762
|
+
"div",
|
|
51763
|
+
{
|
|
51764
|
+
className: "uf-text-xs uf-mt-1",
|
|
51765
|
+
style: {
|
|
51766
|
+
color: colors2.foregroundMuted,
|
|
51767
|
+
fontFamily: fonts.regular
|
|
51768
|
+
},
|
|
51769
|
+
children: formatBalanceDisplay(balance, projectName)
|
|
51770
|
+
}
|
|
51771
|
+
) : null : null
|
|
51772
|
+
] }),
|
|
51773
|
+
showClose ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
51774
|
+
"button",
|
|
51683
51775
|
{
|
|
51684
|
-
|
|
51685
|
-
|
|
51686
|
-
|
|
51687
|
-
|
|
51688
|
-
},
|
|
51689
|
-
children: formatBalanceDisplay(balance, projectName)
|
|
51776
|
+
onClick: onClose,
|
|
51777
|
+
className: "hover:uf-bg-secondary uf-rounded-lg uf-p-1 uf-transition-colors",
|
|
51778
|
+
style: { color: components.header.buttonColor },
|
|
51779
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(X, { className: "uf-w-5 uf-h-5" })
|
|
51690
51780
|
}
|
|
51691
|
-
) :
|
|
51781
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "uf-w-5 uf-h-5 uf-invisible" })
|
|
51692
51782
|
] }),
|
|
51693
|
-
|
|
51694
|
-
"
|
|
51783
|
+
showIncident && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
51784
|
+
"div",
|
|
51695
51785
|
{
|
|
51696
|
-
|
|
51697
|
-
|
|
51698
|
-
|
|
51699
|
-
|
|
51786
|
+
className: "uf-rounded-lg uf-px-3 uf-py-2.5 uf-mb-4",
|
|
51787
|
+
style: {
|
|
51788
|
+
backgroundColor: incidentStyles.bg,
|
|
51789
|
+
border: `1px solid ${incidentStyles.border}`
|
|
51790
|
+
},
|
|
51791
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "uf-flex uf-items-start uf-gap-2.5", children: [
|
|
51792
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
51793
|
+
IncidentIcon,
|
|
51794
|
+
{
|
|
51795
|
+
className: "uf-w-4 uf-h-4 uf-mt-0.5 uf-shrink-0",
|
|
51796
|
+
style: { color: incidentStyles.text }
|
|
51797
|
+
}
|
|
51798
|
+
),
|
|
51799
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "uf-min-w-0 uf-flex-1", children: [
|
|
51800
|
+
/* @__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)(
|
|
51801
|
+
"span",
|
|
51802
|
+
{
|
|
51803
|
+
className: "uf-text-[11px] uf-leading-none uf-px-1.5 uf-py-1 uf-rounded-md",
|
|
51804
|
+
style: {
|
|
51805
|
+
color: incidentStyles.text,
|
|
51806
|
+
border: `1px solid ${incidentStyles.border}`,
|
|
51807
|
+
fontFamily: fonts.medium
|
|
51808
|
+
},
|
|
51809
|
+
children: incidentSeverityLabel
|
|
51810
|
+
}
|
|
51811
|
+
) }),
|
|
51812
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
51813
|
+
"div",
|
|
51814
|
+
{
|
|
51815
|
+
className: "uf-space-y-1",
|
|
51816
|
+
style: { color: incidentStyles.text, fontFamily: fonts.regular },
|
|
51817
|
+
children: incidentMessages.map((message, index2) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "uf-text-xs uf-leading-relaxed", children: message }, `${message}-${index2}`))
|
|
51818
|
+
}
|
|
51819
|
+
),
|
|
51820
|
+
incident.statusPageUrl && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
51821
|
+
"a",
|
|
51822
|
+
{
|
|
51823
|
+
href: incident.statusPageUrl,
|
|
51824
|
+
target: "_blank",
|
|
51825
|
+
rel: "noreferrer",
|
|
51826
|
+
className: "uf-inline-block uf-mt-1.5 uf-text-xs uf-underline uf-underline-offset-2",
|
|
51827
|
+
style: { color: incidentStyles.link, fontFamily: fonts.medium },
|
|
51828
|
+
children: "View status"
|
|
51829
|
+
}
|
|
51830
|
+
)
|
|
51831
|
+
] })
|
|
51832
|
+
] })
|
|
51700
51833
|
}
|
|
51701
|
-
)
|
|
51702
|
-
] })
|
|
51834
|
+
)
|
|
51835
|
+
] });
|
|
51703
51836
|
}
|
|
51704
51837
|
function CurrencyListItem({ currency, isSelected, onSelect }) {
|
|
51705
51838
|
const { colors: colors2, fonts, components } = useTheme();
|
|
@@ -52019,7 +52152,8 @@ var en_default2 = {
|
|
|
52019
52152
|
},
|
|
52020
52153
|
stripeLink: {
|
|
52021
52154
|
title: "Pay with Link",
|
|
52022
|
-
subtitle: "Buy with card or bank"
|
|
52155
|
+
subtitle: "Buy with card or bank",
|
|
52156
|
+
unavailableInRegionMessage: "Pay with Link is currently unavailable in your region."
|
|
52023
52157
|
},
|
|
52024
52158
|
browserWallet: {
|
|
52025
52159
|
title: "Connect Wallet",
|
|
@@ -58326,7 +58460,7 @@ function AppleLogo({ className, style }) {
|
|
|
58326
58460
|
}
|
|
58327
58461
|
);
|
|
58328
58462
|
}
|
|
58329
|
-
function ApplePayButton({ onClick, title, subtitle }) {
|
|
58463
|
+
function ApplePayButton({ onClick, title, subtitle, iconUrl }) {
|
|
58330
58464
|
const { colors: colors2, fonts, components } = useTheme();
|
|
58331
58465
|
const [isHovered, setIsHovered] = React142.useState(false);
|
|
58332
58466
|
const [isTouchDevice, setIsTouchDevice] = React142.useState(false);
|
|
@@ -58348,7 +58482,14 @@ function ApplePayButton({ onClick, title, subtitle }) {
|
|
|
58348
58482
|
},
|
|
58349
58483
|
children: [
|
|
58350
58484
|
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-3", children: [
|
|
58351
|
-
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "uf-rounded-lg uf-
|
|
58485
|
+
/* @__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)(
|
|
58486
|
+
"div",
|
|
58487
|
+
{
|
|
58488
|
+
className: "uf-w-9 uf-h-9 uf-rounded-lg uf-flex uf-items-center uf-justify-center",
|
|
58489
|
+
style: { backgroundColor: "#000" },
|
|
58490
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(AppleLogo, { className: "uf-w-5 uf-h-5", style: { color: "#fff" } })
|
|
58491
|
+
}
|
|
58492
|
+
) }),
|
|
58352
58493
|
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "uf-text-left", children: [
|
|
58353
58494
|
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
58354
58495
|
"div",
|
|
@@ -58564,13 +58705,6 @@ function solanaCandidate(provider, type, name, icon) {
|
|
|
58564
58705
|
if (provider.isConnected && provider.publicKey) {
|
|
58565
58706
|
return { type, name, address: provider.publicKey.toString(), icon };
|
|
58566
58707
|
}
|
|
58567
|
-
try {
|
|
58568
|
-
const resp = await provider.connect({ onlyIfTrusted: true });
|
|
58569
|
-
if (resp.publicKey) {
|
|
58570
|
-
return { type, name, address: resp.publicKey.toString(), icon };
|
|
58571
|
-
}
|
|
58572
|
-
} catch {
|
|
58573
|
-
}
|
|
58574
58708
|
return null;
|
|
58575
58709
|
}
|
|
58576
58710
|
};
|
|
@@ -58794,6 +58928,178 @@ async function disconnectInjectedBrowserWallet(wallet) {
|
|
|
58794
58928
|
collectEthereumProvidersForDisconnect(window)
|
|
58795
58929
|
);
|
|
58796
58930
|
}
|
|
58931
|
+
var STORED_TYPE_TO_EIP6963_WALLET_ID = {
|
|
58932
|
+
metamask: "metamask",
|
|
58933
|
+
"phantom-ethereum": "phantom",
|
|
58934
|
+
coinbase: "coinbase",
|
|
58935
|
+
trust: "trust",
|
|
58936
|
+
rainbow: "rainbow",
|
|
58937
|
+
rabby: "rabby",
|
|
58938
|
+
okx: "okx"
|
|
58939
|
+
};
|
|
58940
|
+
var EIP6963_WALLET_ID_TO_INFO = {
|
|
58941
|
+
metamask: { walletType: "metamask", name: "MetaMask", icon: "metamask" },
|
|
58942
|
+
phantom: { walletType: "phantom-ethereum", name: "Phantom", icon: "phantom" },
|
|
58943
|
+
coinbase: { walletType: "coinbase", name: "Coinbase Wallet", icon: "coinbase" },
|
|
58944
|
+
trust: { walletType: "trust", name: "Trust Wallet", icon: "trust" },
|
|
58945
|
+
rainbow: { walletType: "rainbow", name: "Rainbow", icon: "rainbow" },
|
|
58946
|
+
rabby: { walletType: "rabby", name: "Rabby", icon: "rabby" },
|
|
58947
|
+
okx: { walletType: "okx", name: "OKX Wallet", icon: "okx" }
|
|
58948
|
+
};
|
|
58949
|
+
var WALLET_ID_TO_WALLET_TYPE = {
|
|
58950
|
+
phantom: "phantom-ethereum",
|
|
58951
|
+
coinbase: "coinbase",
|
|
58952
|
+
trust: "trust",
|
|
58953
|
+
rainbow: "rainbow",
|
|
58954
|
+
rabby: "rabby",
|
|
58955
|
+
okx: "okx",
|
|
58956
|
+
metamask: "metamask"
|
|
58957
|
+
};
|
|
58958
|
+
var WALLET_TYPE_TO_WALLET_ID = {
|
|
58959
|
+
"phantom-ethereum": "phantom",
|
|
58960
|
+
coinbase: "coinbase",
|
|
58961
|
+
trust: "trust",
|
|
58962
|
+
okx: "okx",
|
|
58963
|
+
rainbow: "rainbow",
|
|
58964
|
+
rabby: "rabby",
|
|
58965
|
+
metamask: "metamask"
|
|
58966
|
+
};
|
|
58967
|
+
function isWalletType(value) {
|
|
58968
|
+
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";
|
|
58969
|
+
}
|
|
58970
|
+
function walletIdToWalletType(walletId) {
|
|
58971
|
+
return WALLET_ID_TO_WALLET_TYPE[walletId] || "metamask";
|
|
58972
|
+
}
|
|
58973
|
+
function walletTypeToWalletId(walletType) {
|
|
58974
|
+
return WALLET_TYPE_TO_WALLET_ID[walletType] || walletType;
|
|
58975
|
+
}
|
|
58976
|
+
function getLegacyEvmProviders(win) {
|
|
58977
|
+
if (!win) return {};
|
|
58978
|
+
const anyWin = win;
|
|
58979
|
+
return {
|
|
58980
|
+
ethereum: anyWin.ethereum,
|
|
58981
|
+
phantomEthereum: anyWin.phantom?.ethereum,
|
|
58982
|
+
coinbaseEthereum: anyWin.coinbaseWalletExtension,
|
|
58983
|
+
trustEthereum: anyWin.trustwallet?.ethereum,
|
|
58984
|
+
okxEthereum: anyWin.okxwallet
|
|
58985
|
+
};
|
|
58986
|
+
}
|
|
58987
|
+
function getInjectedSolanaProviders(win) {
|
|
58988
|
+
if (!win) return {};
|
|
58989
|
+
const anyWin = win;
|
|
58990
|
+
return {
|
|
58991
|
+
phantomSolana: anyWin.phantom?.solana,
|
|
58992
|
+
solflare: anyWin.solflare,
|
|
58993
|
+
backpack: anyWin.backpack,
|
|
58994
|
+
glow: anyWin.glow,
|
|
58995
|
+
coinbaseSolana: anyWin.coinbaseSolana || anyWin.coinbaseWalletExtension?.solana,
|
|
58996
|
+
trustSolana: anyWin.trustwallet?.solana
|
|
58997
|
+
};
|
|
58998
|
+
}
|
|
58999
|
+
function describeEip6963Provider(wp) {
|
|
59000
|
+
const mapped = EIP6963_WALLET_ID_TO_INFO[wp.walletId];
|
|
59001
|
+
return {
|
|
59002
|
+
provider: wp.provider,
|
|
59003
|
+
walletType: mapped?.walletType ?? "metamask",
|
|
59004
|
+
name: mapped?.name ?? wp.info.name,
|
|
59005
|
+
icon: mapped?.icon ?? wp.info.icon
|
|
59006
|
+
};
|
|
59007
|
+
}
|
|
59008
|
+
function resolveQuickConnectEvmProvider(win) {
|
|
59009
|
+
const eip6963Providers = getEip6963Providers();
|
|
59010
|
+
if (eip6963Providers.length > 0) {
|
|
59011
|
+
const stored = getStoredWalletState();
|
|
59012
|
+
const preferredWalletId = stored?.walletType && isWalletType(stored.walletType) ? STORED_TYPE_TO_EIP6963_WALLET_ID[stored.walletType] : void 0;
|
|
59013
|
+
if (preferredWalletId) {
|
|
59014
|
+
const preferred = findProviderByWalletId(preferredWalletId);
|
|
59015
|
+
if (preferred) return describeEip6963Provider(preferred);
|
|
59016
|
+
}
|
|
59017
|
+
if (eip6963Providers.length === 1) {
|
|
59018
|
+
return describeEip6963Provider(eip6963Providers[0]);
|
|
59019
|
+
}
|
|
59020
|
+
return void 0;
|
|
59021
|
+
}
|
|
59022
|
+
const anyWin = win;
|
|
59023
|
+
const legacy = anyWin.phantom?.ethereum || anyWin.ethereum;
|
|
59024
|
+
if (!legacy) return void 0;
|
|
59025
|
+
const isPhantom = legacy.isPhantom;
|
|
59026
|
+
return {
|
|
59027
|
+
provider: legacy,
|
|
59028
|
+
walletType: isPhantom ? "phantom-ethereum" : "metamask",
|
|
59029
|
+
name: isPhantom ? "Phantom" : "MetaMask",
|
|
59030
|
+
icon: isPhantom ? "phantom" : "metamask"
|
|
59031
|
+
};
|
|
59032
|
+
}
|
|
59033
|
+
function resolveSolanaPublicKey(provider, response) {
|
|
59034
|
+
if (response?.publicKey) return { publicKey: response.publicKey };
|
|
59035
|
+
if (provider.publicKey) return { publicKey: provider.publicKey };
|
|
59036
|
+
return null;
|
|
59037
|
+
}
|
|
59038
|
+
function isUserRejectedSolanaConnectError(error) {
|
|
59039
|
+
if (!error || typeof error !== "object") return false;
|
|
59040
|
+
const maybeCode = "code" in error ? error.code : void 0;
|
|
59041
|
+
if (maybeCode === 4001) return true;
|
|
59042
|
+
const msg = "message" in error && typeof error.message === "string" ? error.message.toLowerCase() : "";
|
|
59043
|
+
return msg.includes("user rejected") || msg.includes("user denied") || msg.includes("rejected the request") || msg.includes("declined");
|
|
59044
|
+
}
|
|
59045
|
+
function isSolanaConnectTimeoutError(error) {
|
|
59046
|
+
return error instanceof Error && error.message.toLowerCase().includes("did not respond to the connection request");
|
|
59047
|
+
}
|
|
59048
|
+
async function connectSolanaProviderWithRecovery(provider, walletId, walletName) {
|
|
59049
|
+
if (provider.isConnected && provider.publicKey) {
|
|
59050
|
+
return { publicKey: provider.publicKey };
|
|
59051
|
+
}
|
|
59052
|
+
const connectOnce = () => provider.connect(walletId === "solflare" ? { onlyIfTrusted: false } : void 0);
|
|
59053
|
+
const withTimeout = async (ms = 2e4) => await Promise.race([
|
|
59054
|
+
connectOnce(),
|
|
59055
|
+
new Promise(
|
|
59056
|
+
(resolve, reject) => setTimeout(() => {
|
|
59057
|
+
const connected = resolveSolanaPublicKey(provider);
|
|
59058
|
+
if (connected) {
|
|
59059
|
+
resolve(connected);
|
|
59060
|
+
return;
|
|
59061
|
+
}
|
|
59062
|
+
reject(
|
|
59063
|
+
new Error(
|
|
59064
|
+
`${walletName} did not respond to the connection request. Please unlock the wallet and try again.`
|
|
59065
|
+
)
|
|
59066
|
+
);
|
|
59067
|
+
}, ms)
|
|
59068
|
+
)
|
|
59069
|
+
]);
|
|
59070
|
+
if (walletId === "solflare") {
|
|
59071
|
+
await provider.disconnect?.().catch(() => {
|
|
59072
|
+
});
|
|
59073
|
+
}
|
|
59074
|
+
const connectAndResolve = async () => {
|
|
59075
|
+
try {
|
|
59076
|
+
const response = await withTimeout();
|
|
59077
|
+
const resolved = resolveSolanaPublicKey(provider, response);
|
|
59078
|
+
if (resolved) return resolved;
|
|
59079
|
+
await new Promise((resolve) => setTimeout(resolve, 120));
|
|
59080
|
+
const delayedResolved = resolveSolanaPublicKey(provider);
|
|
59081
|
+
if (delayedResolved) return delayedResolved;
|
|
59082
|
+
throw new Error(`${walletName} connected but did not expose a public key.`);
|
|
59083
|
+
} catch (error) {
|
|
59084
|
+
const connected = resolveSolanaPublicKey(provider);
|
|
59085
|
+
if (connected) return connected;
|
|
59086
|
+
throw error;
|
|
59087
|
+
}
|
|
59088
|
+
};
|
|
59089
|
+
try {
|
|
59090
|
+
return await connectAndResolve();
|
|
59091
|
+
} catch (err) {
|
|
59092
|
+
if (isUserRejectedSolanaConnectError(err)) throw err;
|
|
59093
|
+
if (isSolanaConnectTimeoutError(err)) throw err;
|
|
59094
|
+
if (walletId === "solflare") {
|
|
59095
|
+
await provider.disconnect?.().catch(() => {
|
|
59096
|
+
});
|
|
59097
|
+
await new Promise((resolve) => setTimeout(resolve, 150));
|
|
59098
|
+
return await connectAndResolve();
|
|
59099
|
+
}
|
|
59100
|
+
throw err;
|
|
59101
|
+
}
|
|
59102
|
+
}
|
|
58797
59103
|
function MetamaskIcon({ size: size4 = 24, className, variant = "color" }) {
|
|
58798
59104
|
const id = React172.useId();
|
|
58799
59105
|
if (variant === "light" || variant === "dark") {
|
|
@@ -60653,21 +60959,19 @@ function BrowserWalletButton({
|
|
|
60653
60959
|
}
|
|
60654
60960
|
}
|
|
60655
60961
|
if (!chainType || chainType === "ethereum") {
|
|
60656
|
-
const
|
|
60657
|
-
if (
|
|
60658
|
-
const accounts = await
|
|
60962
|
+
const resolved = resolveQuickConnectEvmProvider(window);
|
|
60963
|
+
if (resolved) {
|
|
60964
|
+
const accounts = await resolved.provider.request({
|
|
60659
60965
|
method: "eth_requestAccounts"
|
|
60660
60966
|
});
|
|
60661
60967
|
if (accounts && accounts.length > 0) {
|
|
60662
60968
|
setUserDisconnectedWallet(false);
|
|
60663
|
-
|
|
60664
|
-
const walletType = isPhantom ? "phantom-ethereum" : "metamask";
|
|
60665
|
-
setStoredWalletState(walletType);
|
|
60969
|
+
setStoredWalletState(resolved.walletType);
|
|
60666
60970
|
setWallet({
|
|
60667
|
-
type: walletType,
|
|
60668
|
-
name:
|
|
60971
|
+
type: resolved.walletType,
|
|
60972
|
+
name: resolved.name,
|
|
60669
60973
|
address: accounts[0],
|
|
60670
|
-
icon:
|
|
60974
|
+
icon: resolved.icon
|
|
60671
60975
|
});
|
|
60672
60976
|
}
|
|
60673
60977
|
}
|
|
@@ -60701,7 +61005,10 @@ function BrowserWalletButton({
|
|
|
60701
61005
|
if (isLoading) {
|
|
60702
61006
|
return null;
|
|
60703
61007
|
}
|
|
60704
|
-
const
|
|
61008
|
+
const eip6963EvmProviderCount = getEip6963Providers().length;
|
|
61009
|
+
const legacyEvmProviders = getLegacyEvmProviders(window);
|
|
61010
|
+
const hasLegacyEvmProvider = eip6963EvmProviderCount === 0 && !!(legacyEvmProviders.ethereum || legacyEvmProviders.phantomEthereum || legacyEvmProviders.coinbaseEthereum || legacyEvmProviders.trustEthereum || legacyEvmProviders.okxEthereum);
|
|
61011
|
+
const hasWalletExtension = (!chainType || chainType === "ethereum") && eip6963EvmProviderCount > 0 || (!chainType || chainType === "solana") && (window.phantom?.solana?.isPhantom || window.solana?.isPhantom) || (!chainType || chainType === "ethereum") && hasLegacyEvmProvider;
|
|
60705
61012
|
if (!onConnectClick && !wallet && !hasWalletExtension) {
|
|
60706
61013
|
return null;
|
|
60707
61014
|
}
|
|
@@ -60711,11 +61018,25 @@ function BrowserWalletButton({
|
|
|
60711
61018
|
border: `${components.card.borderWidth}px solid ${components.card.borderColor}`
|
|
60712
61019
|
};
|
|
60713
61020
|
const sortedWallets = featuredWallets ? [...featuredWallets].sort((a, b) => a.position - b.position) : [];
|
|
61021
|
+
const isImageIcon = !!wallet && (wallet.icon.startsWith("data:") || wallet.icon.startsWith("http"));
|
|
60714
61022
|
const walletIconBlock = wallet ? WALLET_ICON_COMPONENTS[wallet.icon] ? React292.createElement(WALLET_ICON_COMPONENTS[wallet.icon], {
|
|
60715
61023
|
size: 36,
|
|
60716
61024
|
className: "uf-rounded-lg",
|
|
60717
61025
|
variant: "color"
|
|
60718
|
-
}) :
|
|
61026
|
+
}) : isImageIcon ? (
|
|
61027
|
+
// Wallet announced via EIP-6963 with no internal icon component: render its
|
|
61028
|
+
// own advertised icon (`info.icon`) rather than a generic placeholder.
|
|
61029
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
61030
|
+
"img",
|
|
61031
|
+
{
|
|
61032
|
+
src: wallet.icon,
|
|
61033
|
+
alt: wallet.name,
|
|
61034
|
+
width: 36,
|
|
61035
|
+
height: 36,
|
|
61036
|
+
className: "uf-rounded-lg uf-w-9 uf-h-9"
|
|
61037
|
+
}
|
|
61038
|
+
)
|
|
61039
|
+
) : /* @__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 } }) });
|
|
60719
61040
|
const titleSubtitleBlock = /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "uf-text-left uf-min-w-0", children: [
|
|
60720
61041
|
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
60721
61042
|
"div",
|
|
@@ -66673,6 +66994,24 @@ function useExchanges({
|
|
|
66673
66994
|
});
|
|
66674
66995
|
return { exchanges, isLoading };
|
|
66675
66996
|
}
|
|
66997
|
+
function usePublicIncident({
|
|
66998
|
+
publishableKey,
|
|
66999
|
+
enabled = true
|
|
67000
|
+
}) {
|
|
67001
|
+
const {
|
|
67002
|
+
data: incident,
|
|
67003
|
+
isLoading,
|
|
67004
|
+
error
|
|
67005
|
+
} = useQuery({
|
|
67006
|
+
queryKey: ["unifold", "publicIncident", publishableKey],
|
|
67007
|
+
queryFn: () => getPublicIncident(publishableKey),
|
|
67008
|
+
enabled,
|
|
67009
|
+
staleTime: 1e3 * 30,
|
|
67010
|
+
refetchInterval: 1e3 * 30,
|
|
67011
|
+
refetchOnWindowFocus: true
|
|
67012
|
+
});
|
|
67013
|
+
return { incident, isLoading, error: error ?? null };
|
|
67014
|
+
}
|
|
66676
67015
|
function useApplePayProviders({
|
|
66677
67016
|
publishableKey,
|
|
66678
67017
|
enabled = true
|
|
@@ -66768,6 +67107,7 @@ function useAddressValidation({
|
|
|
66768
67107
|
return {
|
|
66769
67108
|
isValid: null,
|
|
66770
67109
|
failureCode: null,
|
|
67110
|
+
message: null,
|
|
66771
67111
|
metadata: null,
|
|
66772
67112
|
isLoading: false,
|
|
66773
67113
|
error: null
|
|
@@ -66776,6 +67116,7 @@ function useAddressValidation({
|
|
|
66776
67116
|
return {
|
|
66777
67117
|
isValid: data?.valid ?? null,
|
|
66778
67118
|
failureCode: data?.failure_code ?? null,
|
|
67119
|
+
message: data?.message ?? null,
|
|
66779
67120
|
metadata: data?.metadata ?? null,
|
|
66780
67121
|
isLoading,
|
|
66781
67122
|
error: error ?? null
|
|
@@ -67601,6 +67942,37 @@ function TokenSelectorSheet({
|
|
|
67601
67942
|
var getChainKey = (chainId, chainType) => {
|
|
67602
67943
|
return `${chainType}:${chainId}`;
|
|
67603
67944
|
};
|
|
67945
|
+
function getStoredSelection(key) {
|
|
67946
|
+
if (typeof window === "undefined") return null;
|
|
67947
|
+
try {
|
|
67948
|
+
const raw = localStorage.getItem(key);
|
|
67949
|
+
if (!raw) return null;
|
|
67950
|
+
const parsed = JSON.parse(raw);
|
|
67951
|
+
if (parsed && typeof parsed.symbol === "string" && typeof parsed.chainType === "string" && typeof parsed.chainId === "string") {
|
|
67952
|
+
return parsed;
|
|
67953
|
+
}
|
|
67954
|
+
} catch {
|
|
67955
|
+
}
|
|
67956
|
+
return null;
|
|
67957
|
+
}
|
|
67958
|
+
function saveStoredSelection(key, symbol, chainType, chainId) {
|
|
67959
|
+
if (typeof window === "undefined") return;
|
|
67960
|
+
try {
|
|
67961
|
+
localStorage.setItem(key, JSON.stringify({ symbol, chainType, chainId }));
|
|
67962
|
+
} catch {
|
|
67963
|
+
}
|
|
67964
|
+
}
|
|
67965
|
+
function resolveFromStorage(tokens, stored) {
|
|
67966
|
+
for (const t13 of tokens) {
|
|
67967
|
+
if (t13.symbol !== stored.symbol) continue;
|
|
67968
|
+
const matchedChain = t13.chains.find(
|
|
67969
|
+
(c) => c.chain_type === stored.chainType && c.chain_id === stored.chainId
|
|
67970
|
+
);
|
|
67971
|
+
if (matchedChain) return { token: t13, chain: matchedChain };
|
|
67972
|
+
if (t13.chains.length > 0) return { token: t13, chain: t13.chains[0] };
|
|
67973
|
+
}
|
|
67974
|
+
return null;
|
|
67975
|
+
}
|
|
67604
67976
|
function resolveToken(tokens, defaultChainType, defaultChainId, defaultTokenAddress, defaultSymbol) {
|
|
67605
67977
|
if (!tokens.length) return null;
|
|
67606
67978
|
let selectedToken;
|
|
@@ -67650,27 +68022,73 @@ function useDefaultToken({
|
|
|
67650
68022
|
defaultChainType,
|
|
67651
68023
|
defaultChainId,
|
|
67652
68024
|
defaultTokenAddress,
|
|
67653
|
-
defaultSymbol
|
|
68025
|
+
defaultSymbol,
|
|
68026
|
+
storageKey: storageKey2
|
|
67654
68027
|
}) {
|
|
67655
|
-
const [token,
|
|
67656
|
-
const [chain,
|
|
68028
|
+
const [token, setTokenState] = (0, import_react28.useState)(null);
|
|
68029
|
+
const [chain, setChainState] = (0, import_react28.useState)(null);
|
|
67657
68030
|
const [initialSelectionDone, setInitialSelectionDone] = (0, import_react28.useState)(false);
|
|
67658
68031
|
const appliedDefaultsRef = (0, import_react28.useRef)("");
|
|
68032
|
+
const tokenRef = (0, import_react28.useRef)(null);
|
|
68033
|
+
const chainRef = (0, import_react28.useRef)(null);
|
|
68034
|
+
tokenRef.current = token;
|
|
68035
|
+
chainRef.current = chain;
|
|
68036
|
+
const setToken = (0, import_react28.useCallback)(
|
|
68037
|
+
(newToken) => {
|
|
68038
|
+
tokenRef.current = newToken;
|
|
68039
|
+
setTokenState(newToken);
|
|
68040
|
+
if (storageKey2 && chainRef.current) {
|
|
68041
|
+
const [chainType, chainId] = chainRef.current.split(":");
|
|
68042
|
+
saveStoredSelection(storageKey2, newToken, chainType, chainId);
|
|
68043
|
+
}
|
|
68044
|
+
},
|
|
68045
|
+
[storageKey2]
|
|
68046
|
+
);
|
|
68047
|
+
const setChain = (0, import_react28.useCallback)(
|
|
68048
|
+
(newChain) => {
|
|
68049
|
+
chainRef.current = newChain;
|
|
68050
|
+
setChainState(newChain);
|
|
68051
|
+
if (storageKey2 && tokenRef.current) {
|
|
68052
|
+
const [chainType, chainId] = newChain.split(":");
|
|
68053
|
+
saveStoredSelection(storageKey2, tokenRef.current, chainType, chainId);
|
|
68054
|
+
}
|
|
68055
|
+
},
|
|
68056
|
+
[storageKey2]
|
|
68057
|
+
);
|
|
67659
68058
|
(0, import_react28.useEffect)(() => {
|
|
67660
68059
|
if (!tokens.length) return;
|
|
67661
68060
|
const defaultsKey = `${defaultTokenAddress ?? ""}|${defaultSymbol ?? ""}|${defaultChainType ?? ""}|${defaultChainId ?? ""}`;
|
|
67662
68061
|
const defaultsChanged = appliedDefaultsRef.current !== defaultsKey;
|
|
67663
68062
|
if (initialSelectionDone && !defaultsChanged) return;
|
|
67664
|
-
const
|
|
67665
|
-
|
|
67666
|
-
|
|
67667
|
-
|
|
67668
|
-
|
|
67669
|
-
|
|
67670
|
-
|
|
68063
|
+
const hasExplicitDefaults = defaultTokenAddress && defaultChainType && defaultChainId || defaultSymbol && defaultChainType && defaultChainId;
|
|
68064
|
+
let result = null;
|
|
68065
|
+
if (hasExplicitDefaults) {
|
|
68066
|
+
result = resolveToken(
|
|
68067
|
+
tokens,
|
|
68068
|
+
defaultChainType,
|
|
68069
|
+
defaultChainId,
|
|
68070
|
+
defaultTokenAddress,
|
|
68071
|
+
defaultSymbol
|
|
68072
|
+
);
|
|
68073
|
+
if (result) {
|
|
68074
|
+
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;
|
|
68075
|
+
if (!matched) {
|
|
68076
|
+
result = null;
|
|
68077
|
+
}
|
|
68078
|
+
}
|
|
68079
|
+
}
|
|
68080
|
+
if (!result && storageKey2) {
|
|
68081
|
+
const stored = getStoredSelection(storageKey2);
|
|
68082
|
+
if (stored) {
|
|
68083
|
+
result = resolveFromStorage(tokens, stored);
|
|
68084
|
+
}
|
|
68085
|
+
}
|
|
68086
|
+
if (!result) {
|
|
68087
|
+
result = resolveToken(tokens);
|
|
68088
|
+
}
|
|
67671
68089
|
if (result) {
|
|
67672
|
-
|
|
67673
|
-
|
|
68090
|
+
setTokenState(result.token.symbol);
|
|
68091
|
+
setChainState(getChainKey(result.chain.chain_id, result.chain.chain_type));
|
|
67674
68092
|
appliedDefaultsRef.current = defaultsKey;
|
|
67675
68093
|
setInitialSelectionDone(true);
|
|
67676
68094
|
}
|
|
@@ -67680,7 +68098,8 @@ function useDefaultToken({
|
|
|
67680
68098
|
defaultSymbol,
|
|
67681
68099
|
defaultChainType,
|
|
67682
68100
|
defaultChainId,
|
|
67683
|
-
initialSelectionDone
|
|
68101
|
+
initialSelectionDone,
|
|
68102
|
+
storageKey2
|
|
67684
68103
|
]);
|
|
67685
68104
|
(0, import_react28.useEffect)(() => {
|
|
67686
68105
|
if (!tokens.length || !token) return;
|
|
@@ -67691,11 +68110,12 @@ function useDefaultToken({
|
|
|
67691
68110
|
});
|
|
67692
68111
|
if (!isChainAvailable) {
|
|
67693
68112
|
const firstChain = currentToken.chains[0];
|
|
67694
|
-
|
|
68113
|
+
setChainState(getChainKey(firstChain.chain_id, firstChain.chain_type));
|
|
67695
68114
|
}
|
|
67696
68115
|
}, [token, tokens, chain]);
|
|
67697
68116
|
return { token, chain, setToken, setChain, initialSelectionDone };
|
|
67698
68117
|
}
|
|
68118
|
+
var STORAGE_KEY2 = "unifold_last_deposit_from_token";
|
|
67699
68119
|
function useDefaultSourceToken({
|
|
67700
68120
|
supportedTokens,
|
|
67701
68121
|
defaultSourceChainType,
|
|
@@ -67708,7 +68128,8 @@ function useDefaultSourceToken({
|
|
|
67708
68128
|
defaultChainType: defaultSourceChainType,
|
|
67709
68129
|
defaultChainId: defaultSourceChainId,
|
|
67710
68130
|
defaultTokenAddress: defaultSourceTokenAddress,
|
|
67711
|
-
defaultSymbol: defaultSourceSymbol
|
|
68131
|
+
defaultSymbol: defaultSourceSymbol,
|
|
68132
|
+
storageKey: STORAGE_KEY2
|
|
67712
68133
|
});
|
|
67713
68134
|
}
|
|
67714
68135
|
function DepositFooterLinks({ onGlossaryClick, leftElement }) {
|
|
@@ -70720,33 +71141,11 @@ function balancesRepresentSameToken(a, b) {
|
|
|
70720
71141
|
if (!tokenA || !tokenB) return false;
|
|
70721
71142
|
return tokenA.chain_type === tokenB.chain_type && tokenA.chain_id === tokenB.chain_id && normalizeTokenAddress(tokenA.token_address) === normalizeTokenAddress(tokenB.token_address);
|
|
70722
71143
|
}
|
|
70723
|
-
function getSolanaProviders() {
|
|
70724
|
-
if (typeof window === "undefined") return {};
|
|
70725
|
-
const win = window;
|
|
70726
|
-
return {
|
|
70727
|
-
phantomSolana: win.phantom?.solana,
|
|
70728
|
-
solflare: win.solflare,
|
|
70729
|
-
backpack: win.backpack,
|
|
70730
|
-
glow: win.glow,
|
|
70731
|
-
coinbaseSolana: win.coinbaseSolana || win.coinbaseWalletExtension?.solana
|
|
70732
|
-
};
|
|
70733
|
-
}
|
|
70734
|
-
function getLegacyEvmProviders() {
|
|
70735
|
-
if (typeof window === "undefined") return {};
|
|
70736
|
-
const win = window;
|
|
70737
|
-
return {
|
|
70738
|
-
ethereum: win.ethereum,
|
|
70739
|
-
phantomEthereum: win.phantom?.ethereum,
|
|
70740
|
-
coinbaseEthereum: win.coinbaseWalletExtension,
|
|
70741
|
-
trustEthereum: win.trustwallet?.ethereum,
|
|
70742
|
-
okxEthereum: win.okxwallet
|
|
70743
|
-
};
|
|
70744
|
-
}
|
|
70745
71144
|
function detectAvailableWallets(definitions, recentWalletId, filterChainType) {
|
|
70746
|
-
const solProviders = getSolanaProviders();
|
|
70747
|
-
const legacyEvm = getLegacyEvmProviders();
|
|
70748
|
-
const eip6963List = getEip6963Providers();
|
|
70749
71145
|
const win = typeof window !== "undefined" ? window : null;
|
|
71146
|
+
const solProviders = getInjectedSolanaProviders(win);
|
|
71147
|
+
const legacyEvm = getLegacyEvmProviders(win);
|
|
71148
|
+
const eip6963List = getEip6963Providers();
|
|
70750
71149
|
const hasEip6963 = (walletId) => eip6963List.some((d) => {
|
|
70751
71150
|
const rdns = d.info?.rdns || "";
|
|
70752
71151
|
switch (walletId) {
|
|
@@ -71015,10 +71414,13 @@ function WalletConnect({
|
|
|
71015
71414
|
};
|
|
71016
71415
|
const openMobileWalletBrowse = async (wallet, depositAddresses) => {
|
|
71017
71416
|
try {
|
|
71417
|
+
const cleanedAmountUsd = amountUsd?.replace(/[^0-9.]/g, "") ?? "";
|
|
71418
|
+
const forwardedAmountUsd = parseFloat(cleanedAmountUsd) > 0 ? cleanedAmountUsd : void 0;
|
|
71018
71419
|
const res = await getWalletMobileDeepLink(
|
|
71019
71420
|
wallet.id,
|
|
71020
71421
|
depositAddresses,
|
|
71021
|
-
publishableKey
|
|
71422
|
+
publishableKey,
|
|
71423
|
+
forwardedAmountUsd
|
|
71022
71424
|
);
|
|
71023
71425
|
if (res.deeplink) {
|
|
71024
71426
|
setMobileRedirect({ walletId: wallet.id, walletName: wallet.name, deeplink: res.deeplink });
|
|
@@ -71107,7 +71509,7 @@ function WalletConnect({
|
|
|
71107
71509
|
const eip6963Match = findProviderByWalletId(wallet.id);
|
|
71108
71510
|
let provider = eip6963Match?.provider;
|
|
71109
71511
|
if (!provider) {
|
|
71110
|
-
const legacyEvm = getLegacyEvmProviders();
|
|
71512
|
+
const legacyEvm = getLegacyEvmProviders(win);
|
|
71111
71513
|
switch (wallet.id) {
|
|
71112
71514
|
case "metamask":
|
|
71113
71515
|
if (legacyEvm.ethereum?.isMetaMask && !legacyEvm.ethereum?.isPhantom)
|
|
@@ -71139,16 +71541,7 @@ function WalletConnect({
|
|
|
71139
71541
|
const accounts = await provider.request({ method: "eth_requestAccounts" });
|
|
71140
71542
|
if (!accounts?.length) throw new Error("No accounts returned from wallet");
|
|
71141
71543
|
setUserDisconnectedWallet(false);
|
|
71142
|
-
const
|
|
71143
|
-
phantom: "phantom-ethereum",
|
|
71144
|
-
coinbase: "coinbase",
|
|
71145
|
-
trust: "trust",
|
|
71146
|
-
rainbow: "rainbow",
|
|
71147
|
-
rabby: "rabby",
|
|
71148
|
-
okx: "okx",
|
|
71149
|
-
metamask: "metamask"
|
|
71150
|
-
};
|
|
71151
|
-
const walletType = walletIdToType[wallet.id] || "metamask";
|
|
71544
|
+
const walletType = walletIdToWalletType(wallet.id);
|
|
71152
71545
|
setStoredWalletState(walletType);
|
|
71153
71546
|
connectedInfo = {
|
|
71154
71547
|
type: walletType,
|
|
@@ -71157,7 +71550,7 @@ function WalletConnect({
|
|
|
71157
71550
|
icon: wallet.id
|
|
71158
71551
|
};
|
|
71159
71552
|
} else {
|
|
71160
|
-
const solProviders =
|
|
71553
|
+
const solProviders = getInjectedSolanaProviders(win);
|
|
71161
71554
|
let provider;
|
|
71162
71555
|
switch (wallet.id) {
|
|
71163
71556
|
case "phantom":
|
|
@@ -71176,11 +71569,11 @@ function WalletConnect({
|
|
|
71176
71569
|
provider = solProviders.coinbaseSolana || win?.coinbaseWalletExtension?.solana;
|
|
71177
71570
|
break;
|
|
71178
71571
|
case "trust":
|
|
71179
|
-
provider =
|
|
71572
|
+
provider = solProviders.trustSolana;
|
|
71180
71573
|
break;
|
|
71181
71574
|
}
|
|
71182
71575
|
if (!provider) throw new Error(`${wallet.name} Solana wallet not found.`);
|
|
71183
|
-
const response = await provider.
|
|
71576
|
+
const response = await connectSolanaProviderWithRecovery(provider, wallet.id, wallet.name);
|
|
71184
71577
|
setUserDisconnectedWallet(false);
|
|
71185
71578
|
const walletType = wallet.id === "solflare" ? "solflare" : wallet.id === "backpack" ? "backpack" : wallet.id === "glow" ? "glow" : "phantom-solana";
|
|
71186
71579
|
setStoredWalletState(walletType);
|
|
@@ -71531,16 +71924,7 @@ function WalletConnect({
|
|
|
71531
71924
|
return (integerPart + decimalPart.padEnd(decimals, "0").slice(0, decimals)).replace(/^0+/, "") || "0";
|
|
71532
71925
|
};
|
|
71533
71926
|
const resolveEvmProvider = () => {
|
|
71534
|
-
const
|
|
71535
|
-
"phantom-ethereum": "phantom",
|
|
71536
|
-
coinbase: "coinbase",
|
|
71537
|
-
trust: "trust",
|
|
71538
|
-
okx: "okx",
|
|
71539
|
-
rainbow: "rainbow",
|
|
71540
|
-
rabby: "rabby",
|
|
71541
|
-
metamask: "metamask"
|
|
71542
|
-
};
|
|
71543
|
-
const lookupId = walletIdMap[walletInfo.type] || walletInfo.type;
|
|
71927
|
+
const lookupId = walletTypeToWalletId(walletInfo.type);
|
|
71544
71928
|
const eip6963Match = findProviderByWalletId(lookupId);
|
|
71545
71929
|
let provider = eip6963Match?.provider;
|
|
71546
71930
|
if (!provider) {
|
|
@@ -72269,6 +72653,7 @@ function DepositModal({
|
|
|
72269
72653
|
applePayTitle = "Pay with Apple Pay",
|
|
72270
72654
|
applePaySubTitle = "Instant",
|
|
72271
72655
|
enableBankTransfer,
|
|
72656
|
+
enableIncidentBanner = false,
|
|
72272
72657
|
// No default: left undefined so the backend `stripe_link.enabled` can govern
|
|
72273
72658
|
// (via the `??` chain in showStripeLink) once a dashboard toggle exists.
|
|
72274
72659
|
enableStripeLink,
|
|
@@ -72314,7 +72699,7 @@ function DepositModal({
|
|
|
72314
72699
|
const s = initialScreen ?? "main";
|
|
72315
72700
|
if (s === "tracker" && hideDepositTracker === true) return "main";
|
|
72316
72701
|
if (s === "cashapp" && enableCashApp === false) return "main";
|
|
72317
|
-
if (s === "stripe_link" &&
|
|
72702
|
+
if (s === "stripe_link" && enableStripeLink === false) return "main";
|
|
72318
72703
|
if (s === "apple_pay" && enableApplePay === false) return "main";
|
|
72319
72704
|
if (s === "card" && enableFiatOnramp === false) return "main";
|
|
72320
72705
|
if (s === "pay_with_exchange") return enablePayWithExchange === false ? "main" : "exchange";
|
|
@@ -72373,6 +72758,16 @@ function DepositModal({
|
|
|
72373
72758
|
const showApplePay = enableApplePay ?? projectConfig?.apple_pay?.enabled ?? true;
|
|
72374
72759
|
const showBankTransfer = enableBankTransfer ?? projectConfig?.bank_transfer?.enabled ?? true;
|
|
72375
72760
|
const showDepositTracker = hideDepositTracker ? false : projectConfig?.deposit_tracker?.enabled ?? true;
|
|
72761
|
+
const { incident: publicIncident } = usePublicIncident({
|
|
72762
|
+
publishableKey,
|
|
72763
|
+
enabled: open && enableIncidentBanner
|
|
72764
|
+
});
|
|
72765
|
+
const activeIncident = enableIncidentBanner && publicIncident?.enabled && (publicIncident.messages?.length ?? 0) > 0 ? {
|
|
72766
|
+
enabled: true,
|
|
72767
|
+
messages: publicIncident.messages,
|
|
72768
|
+
severity: publicIncident.severity,
|
|
72769
|
+
statusPageUrl: publicIncident.status_page_url
|
|
72770
|
+
} : void 0;
|
|
72376
72771
|
const [integrationExchanges, setIntegrationExchanges] = (0, import_react3.useState)([]);
|
|
72377
72772
|
(0, import_react3.useEffect)(() => {
|
|
72378
72773
|
if (!showConnectExchange || !open) return;
|
|
@@ -72439,7 +72834,11 @@ function DepositModal({
|
|
|
72439
72834
|
setConnectedExchange((prev) => prev ? { ...prev, iconUrl } : prev);
|
|
72440
72835
|
}
|
|
72441
72836
|
}, [integrationExchanges, connectedExchange]);
|
|
72442
|
-
const {
|
|
72837
|
+
const {
|
|
72838
|
+
data: depositAddressResponse,
|
|
72839
|
+
isLoading: walletsLoading,
|
|
72840
|
+
error: walletsError
|
|
72841
|
+
} = useDepositAddress({
|
|
72443
72842
|
userId,
|
|
72444
72843
|
publishableKey,
|
|
72445
72844
|
recipientAddress,
|
|
@@ -72572,6 +72971,7 @@ function DepositModal({
|
|
|
72572
72971
|
const {
|
|
72573
72972
|
isValid: isAddressValid,
|
|
72574
72973
|
failureCode: addressFailureCode,
|
|
72974
|
+
message: addressFailureMessage,
|
|
72575
72975
|
metadata: addressFailureMetadata,
|
|
72576
72976
|
isLoading: isAddressValidationLoading
|
|
72577
72977
|
} = useAddressValidation({
|
|
@@ -72585,17 +72985,31 @@ function DepositModal({
|
|
|
72585
72985
|
refetchOnMount: "always"
|
|
72586
72986
|
});
|
|
72587
72987
|
const addressValidationMessages = i18n2.transferCrypto.addressValidation;
|
|
72588
|
-
const getAddressValidationErrorMessage = (code, metadata) => {
|
|
72988
|
+
const getAddressValidationErrorMessage = (message, code, metadata) => {
|
|
72989
|
+
if (message && message.trim().length > 0) return message;
|
|
72589
72990
|
if (!code) return addressValidationMessages.defaultError;
|
|
72590
72991
|
const errors = addressValidationMessages.errors;
|
|
72591
72992
|
const template = errors[code] ?? addressValidationMessages.defaultError;
|
|
72592
72993
|
return interpolate(template, metadata);
|
|
72593
72994
|
};
|
|
72995
|
+
const walletsRecipientError = isDepositAddressValidationError(walletsError) ? walletsError.message : null;
|
|
72996
|
+
const isRecipientAddressInvalid = isAddressValid === false || walletsRecipientError !== null;
|
|
72997
|
+
const recipientInvalidMessage = getAddressValidationErrorMessage(
|
|
72998
|
+
addressFailureMessage ?? walletsRecipientError,
|
|
72999
|
+
addressFailureCode,
|
|
73000
|
+
addressFailureMetadata
|
|
73001
|
+
);
|
|
72594
73002
|
const openingScreen = effectiveInitialScreen;
|
|
72595
73003
|
const sessionOpenedFromMenu = openingScreen === "main";
|
|
72596
73004
|
const standaloneNeedsDepositPrereq = openingScreen !== "main" && (view === "transfer" || view === "card");
|
|
72597
73005
|
let depositPrerequisiteBody;
|
|
72598
|
-
if (
|
|
73006
|
+
if (isRecipientAddressInvalid) {
|
|
73007
|
+
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: [
|
|
73008
|
+
/* @__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" }) }),
|
|
73009
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("h3", { className: "uf-text-lg uf-font-semibold uf-text-foreground uf-mb-2", children: addressValidationMessages.unableToReceiveFunds }),
|
|
73010
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("p", { className: "uf-text-sm uf-text-muted-foreground uf-max-w-[280px]", children: recipientInvalidMessage })
|
|
73011
|
+
] });
|
|
73012
|
+
} else if (isCountryLoading || isAddressValidationLoading || tokensLoading || walletsLoading || !projectConfig || // Bank-transfer row visibility depends on the country-gated providers
|
|
72599
73013
|
// fetch — block the menu on it so the row never flashes in or out.
|
|
72600
73014
|
showBankTransfer && bankTransferProvidersLoading || // Same for Apple Pay: row visibility depends on the geo/platform-gated
|
|
72601
73015
|
// providers fetch — block the menu so the row doesn't pop in or out.
|
|
@@ -72617,12 +73031,6 @@ function DepositModal({
|
|
|
72617
73031
|
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("h3", { className: "uf-text-lg uf-font-semibold uf-text-foreground uf-mb-2", children: "No Tokens Available" }),
|
|
72618
73032
|
/* @__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." })
|
|
72619
73033
|
] });
|
|
72620
|
-
} else if (isAddressValid === false) {
|
|
72621
|
-
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: [
|
|
72622
|
-
/* @__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" }) }),
|
|
72623
|
-
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("h3", { className: "uf-text-lg uf-font-semibold uf-text-foreground uf-mb-2", children: addressValidationMessages.unableToReceiveFunds }),
|
|
72624
|
-
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("p", { className: "uf-text-sm uf-text-muted-foreground uf-max-w-[280px]", children: getAddressValidationErrorMessage(addressFailureCode, addressFailureMetadata) })
|
|
72625
|
-
] });
|
|
72626
73034
|
} else {
|
|
72627
73035
|
depositPrerequisiteBody = null;
|
|
72628
73036
|
}
|
|
@@ -73116,6 +73524,7 @@ function DepositModal({
|
|
|
73116
73524
|
title: modalTitle || "Deposit",
|
|
73117
73525
|
showClose: !hideOverlay,
|
|
73118
73526
|
onClose: handleClose,
|
|
73527
|
+
incident: activeIncident,
|
|
73119
73528
|
showBalance: showBalanceHeader,
|
|
73120
73529
|
balanceAddress: recipientAddress,
|
|
73121
73530
|
balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
|
|
@@ -73135,6 +73544,7 @@ function DepositModal({
|
|
|
73135
73544
|
showBack: showBackTransfer,
|
|
73136
73545
|
onBack: handleBack,
|
|
73137
73546
|
onClose: handleClose,
|
|
73547
|
+
incident: activeIncident,
|
|
73138
73548
|
showBalance: showBalanceHeader,
|
|
73139
73549
|
balanceAddress: recipientAddress,
|
|
73140
73550
|
balanceChainType: destinationChainType === "ethereum" || destinationChainType === "solana" || destinationChainType === "bitcoin" || destinationChainType === "n1" ? destinationChainType : void 0,
|
|
@@ -73195,7 +73605,8 @@ function DepositModal({
|
|
|
73195
73605
|
title: selectedExecution ? "Deposit Details" : depositTrackerTitle,
|
|
73196
73606
|
showBack: showBackTracker,
|
|
73197
73607
|
onBack: handleBack,
|
|
73198
|
-
onClose: handleClose
|
|
73608
|
+
onClose: handleClose,
|
|
73609
|
+
incident: activeIncident
|
|
73199
73610
|
}
|
|
73200
73611
|
),
|
|
73201
73612
|
/* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
@@ -73227,6 +73638,7 @@ function DepositModal({
|
|
|
73227
73638
|
showBack: showBackCard,
|
|
73228
73639
|
onBack: handleBack,
|
|
73229
73640
|
onClose: handleClose,
|
|
73641
|
+
incident: activeIncident,
|
|
73230
73642
|
badge: cardView === "quotes" ? { count: quotesCount } : void 0,
|
|
73231
73643
|
showBalance: showBalanceHeader,
|
|
73232
73644
|
balanceAddress: recipientAddress,
|
|
@@ -73276,7 +73688,8 @@ function DepositModal({
|
|
|
73276
73688
|
title: payWithExchangeTitle,
|
|
73277
73689
|
showBack: exchangeView === "pending" || sessionOpenedFromMenu,
|
|
73278
73690
|
onBack: handleBack,
|
|
73279
|
-
onClose: handleClose
|
|
73691
|
+
onClose: handleClose,
|
|
73692
|
+
incident: activeIncident
|
|
73280
73693
|
}
|
|
73281
73694
|
),
|
|
73282
73695
|
/* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
@@ -73390,7 +73803,8 @@ function DepositModal({
|
|
|
73390
73803
|
title: t8.bankTransfer.title,
|
|
73391
73804
|
showBack: bankTransferView !== "providers" || sessionOpenedFromMenu,
|
|
73392
73805
|
onBack: handleBack,
|
|
73393
|
-
onClose: handleClose
|
|
73806
|
+
onClose: handleClose,
|
|
73807
|
+
incident: activeIncident
|
|
73394
73808
|
}
|
|
73395
73809
|
),
|
|
73396
73810
|
/* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
@@ -73424,26 +73838,24 @@ function DepositModal({
|
|
|
73424
73838
|
title: "Deposit with Link",
|
|
73425
73839
|
showBack: stripeLinkStep !== "checkout" && stripeLinkStep !== "success",
|
|
73426
73840
|
onBack: handleBack,
|
|
73841
|
+
incident: activeIncident,
|
|
73427
73842
|
showClose: stripeLinkStep !== "checkout" && stripeLinkStep !== "auth",
|
|
73428
73843
|
onClose: handleClose
|
|
73429
73844
|
}
|
|
73430
73845
|
),
|
|
73431
73846
|
/* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
73432
73847
|
isLoadingIp ? (
|
|
73433
|
-
//
|
|
73434
|
-
// PayWithStripeLink (which kicks off config/OAuth work) for a
|
|
73435
|
-
// deep-link user who turns out to be outside the US.
|
|
73848
|
+
// Wait for location so the first config fetch is region-aware.
|
|
73436
73849
|
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(SkeletonButton, { variant: "with-icons" })
|
|
73437
73850
|
) : !showStripeLink ? (
|
|
73438
|
-
//
|
|
73439
|
-
//
|
|
73440
|
-
//
|
|
73441
|
-
// the Link UI.
|
|
73851
|
+
// Direct opens (initialScreen="stripe_link") have no menu row
|
|
73852
|
+
// to fall back to, so render an unavailable state when backend
|
|
73853
|
+
// config resolves Stripe Link disabled/hidden.
|
|
73442
73854
|
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
73443
73855
|
GeoRestrictionScreen,
|
|
73444
73856
|
{
|
|
73445
73857
|
methodName: t8.stripeLink.title,
|
|
73446
|
-
message:
|
|
73858
|
+
message: t8.stripeLink.unavailableInRegionMessage
|
|
73447
73859
|
}
|
|
73448
73860
|
)
|
|
73449
73861
|
) : /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
@@ -73476,7 +73888,8 @@ function DepositModal({
|
|
|
73476
73888
|
title: cashAppView !== "amount" && cashAppAmount ? `Pay $${cashAppAmount} via Cash App` : "Pay with Cash App",
|
|
73477
73889
|
showBack: cashAppView !== "amount" || sessionOpenedFromMenu,
|
|
73478
73890
|
onBack: handleBack,
|
|
73479
|
-
onClose: handleClose
|
|
73891
|
+
onClose: handleClose,
|
|
73892
|
+
incident: activeIncident
|
|
73480
73893
|
}
|
|
73481
73894
|
),
|
|
73482
73895
|
/* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
@@ -73512,7 +73925,8 @@ function DepositModal({
|
|
|
73512
73925
|
const handled = applePayHandleRef.current?.requestBack() ?? false;
|
|
73513
73926
|
if (!handled) handleBack();
|
|
73514
73927
|
},
|
|
73515
|
-
onClose: handleClose
|
|
73928
|
+
onClose: handleClose,
|
|
73929
|
+
incident: activeIncident
|
|
73516
73930
|
}
|
|
73517
73931
|
),
|
|
73518
73932
|
/* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
@@ -73627,6 +74041,7 @@ function CheckoutModal({
|
|
|
73627
74041
|
modalTitle,
|
|
73628
74042
|
enableTransferCrypto,
|
|
73629
74043
|
enableConnectWallet,
|
|
74044
|
+
enableIncidentBanner = false,
|
|
73630
74045
|
defaultSourceChainType,
|
|
73631
74046
|
defaultSourceChainId,
|
|
73632
74047
|
defaultSourceTokenAddress,
|
|
@@ -73698,6 +74113,16 @@ function CheckoutModal({
|
|
|
73698
74113
|
});
|
|
73699
74114
|
const showTransferCrypto = enableTransferCrypto ?? projectConfig?.transfer_crypto?.enabled ?? true;
|
|
73700
74115
|
const showConnectWallet = enableConnectWallet ?? projectConfig?.connect_wallet?.enabled ?? true;
|
|
74116
|
+
const { incident: publicIncident } = usePublicIncident({
|
|
74117
|
+
publishableKey,
|
|
74118
|
+
enabled: open && enableIncidentBanner
|
|
74119
|
+
});
|
|
74120
|
+
const activeIncident = enableIncidentBanner && publicIncident?.enabled && (publicIncident.messages?.length ?? 0) > 0 ? {
|
|
74121
|
+
enabled: true,
|
|
74122
|
+
messages: publicIncident.messages,
|
|
74123
|
+
severity: publicIncident.severity,
|
|
74124
|
+
statusPageUrl: publicIncident.status_page_url
|
|
74125
|
+
} : void 0;
|
|
73701
74126
|
(0, import_react35.useEffect)(() => {
|
|
73702
74127
|
if (view === "transfer" && !showTransferCrypto) {
|
|
73703
74128
|
setView("main");
|
|
@@ -73999,7 +74424,15 @@ function CheckoutModal({
|
|
|
73999
74424
|
{
|
|
74000
74425
|
className: view === "wallet_connect" ? "uf-flex uf-min-h-0 uf-flex-col" : void 0,
|
|
74001
74426
|
children: view === "main" ? /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)(import_jsx_runtime83.Fragment, { children: [
|
|
74002
|
-
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
|
|
74427
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
|
|
74428
|
+
DepositHeader,
|
|
74429
|
+
{
|
|
74430
|
+
title: modalTitle || "Checkout",
|
|
74431
|
+
showClose: true,
|
|
74432
|
+
onClose: handleClose,
|
|
74433
|
+
incident: activeIncident
|
|
74434
|
+
}
|
|
74435
|
+
),
|
|
74003
74436
|
/* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
74004
74437
|
piLoading ? /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "uf-space-y-3", children: [
|
|
74005
74438
|
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
|
|
@@ -74097,7 +74530,8 @@ function CheckoutModal({
|
|
|
74097
74530
|
title: modalTitle || "Checkout",
|
|
74098
74531
|
showBack: true,
|
|
74099
74532
|
onBack: handleBack,
|
|
74100
|
-
onClose: handleClose
|
|
74533
|
+
onClose: handleClose,
|
|
74534
|
+
incident: activeIncident
|
|
74101
74535
|
}
|
|
74102
74536
|
),
|
|
74103
74537
|
/* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "uf-flex uf-flex-col uf-gap-1.5", children: [
|
|
@@ -74267,6 +74701,7 @@ function useSupportedDestinationTokens(publishableKey, enabled = true) {
|
|
|
74267
74701
|
enabled
|
|
74268
74702
|
});
|
|
74269
74703
|
}
|
|
74704
|
+
var STORAGE_KEY3 = "unifold_last_withdraw_to_token";
|
|
74270
74705
|
function useDefaultDestinationToken({
|
|
74271
74706
|
destinationTokens,
|
|
74272
74707
|
defaultDestinationChainType,
|
|
@@ -74279,7 +74714,8 @@ function useDefaultDestinationToken({
|
|
|
74279
74714
|
defaultChainType: defaultDestinationChainType,
|
|
74280
74715
|
defaultChainId: defaultDestinationChainId,
|
|
74281
74716
|
defaultTokenAddress: defaultDestinationTokenAddress,
|
|
74282
|
-
defaultSymbol: defaultDestinationSymbol
|
|
74717
|
+
defaultSymbol: defaultDestinationSymbol,
|
|
74718
|
+
storageKey: STORAGE_KEY3
|
|
74283
74719
|
});
|
|
74284
74720
|
}
|
|
74285
74721
|
function useSourceTokenValidation(params) {
|
|
@@ -74953,6 +75389,9 @@ function WithdrawForm({
|
|
|
74953
75389
|
if (isDebouncing || isVerifyingAddress) return null;
|
|
74954
75390
|
if (verifyError) return t10.invalidAddress;
|
|
74955
75391
|
if (addressVerification && !addressVerification.valid) {
|
|
75392
|
+
if (addressVerification.message && addressVerification.message.trim().length > 0) {
|
|
75393
|
+
return addressVerification.message;
|
|
75394
|
+
}
|
|
74956
75395
|
if (addressVerification.failure_code === "account_not_found")
|
|
74957
75396
|
return `Account not found on ${selectedChain?.chain_name}`;
|
|
74958
75397
|
if (addressVerification.failure_code === "not_opted_in")
|
|
@@ -76209,6 +76648,7 @@ function UnifoldProvider2({
|
|
|
76209
76648
|
const [isWithdrawOpen, setIsWithdrawOpen] = (0, import_react.useState)(false);
|
|
76210
76649
|
const [withdrawConfig, setWithdrawConfig] = (0, import_react.useState)(null);
|
|
76211
76650
|
const [resolvedTheme, setResolvedTheme] = import_react.default.useState("dark");
|
|
76651
|
+
const incidentBannerEnabled = config?.notifications?.incidentBanner;
|
|
76212
76652
|
(0, import_react.useEffect)(() => {
|
|
76213
76653
|
if (publishableKey) {
|
|
76214
76654
|
setApiConfig({ publishableKey });
|
|
@@ -76506,6 +76946,7 @@ function UnifoldProvider2({
|
|
|
76506
76946
|
publishableKey,
|
|
76507
76947
|
enableTransferCrypto: config?.enableTransferCrypto,
|
|
76508
76948
|
enableConnectWallet: config?.enableConnectWallet,
|
|
76949
|
+
enableIncidentBanner: incidentBannerEnabled,
|
|
76509
76950
|
defaultSourceChainType: checkoutConfig.defaultSourceChainType,
|
|
76510
76951
|
defaultSourceChainId: checkoutConfig.defaultSourceChainId,
|
|
76511
76952
|
defaultSourceTokenAddress: checkoutConfig.defaultSourceTokenAddress,
|
|
@@ -76573,6 +77014,7 @@ function UnifoldProvider2({
|
|
|
76573
77014
|
enableConnectExchange: config?.enableConnectExchange,
|
|
76574
77015
|
enableCashApp: config?.enableCashApp,
|
|
76575
77016
|
enableStripeLink: config?.enableStripeLink,
|
|
77017
|
+
enableIncidentBanner: incidentBannerEnabled,
|
|
76576
77018
|
enableApplePay: config?.enableApplePay,
|
|
76577
77019
|
applePayTitle: config?.applePayTitle,
|
|
76578
77020
|
applePaySubTitle: config?.applePaySubTitle,
|