@volr/react-ui 0.1.120 → 0.1.121
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.cjs +143 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +143 -2
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.cts
CHANGED
|
@@ -61,6 +61,7 @@ declare const VolrUIProvider: React$1.FC<VolrUIProviderProps>;
|
|
|
61
61
|
/**
|
|
62
62
|
* Passkey Enrollment View Component
|
|
63
63
|
* Modern passkey setup with device-specific biometric icons
|
|
64
|
+
* Includes cross-domain migration detection and guidance
|
|
64
65
|
*/
|
|
65
66
|
interface PasskeyEnrollViewProps {
|
|
66
67
|
onComplete: () => void;
|
|
@@ -194,6 +195,19 @@ declare const en: {
|
|
|
194
195
|
readonly default: "Please use this device's biometric.";
|
|
195
196
|
readonly note: "Using other devices or apps may not work.";
|
|
196
197
|
};
|
|
198
|
+
readonly migration: {
|
|
199
|
+
readonly title: "Set up passkey for this site";
|
|
200
|
+
readonly description: "Your wallet was created on {{sourceDomain}}. To use it here, you need to set up a new passkey for this site.";
|
|
201
|
+
readonly descriptionGeneric: "Your wallet was created on a different site. To use it here, you need to set up a new passkey for this site.";
|
|
202
|
+
readonly currentDomain: "Current site";
|
|
203
|
+
readonly sourceDomain: "Original site";
|
|
204
|
+
readonly benefits: "Your wallet address and balance will remain the same.";
|
|
205
|
+
readonly cta: "Set up passkey";
|
|
206
|
+
readonly later: "Do it later";
|
|
207
|
+
readonly inProgress: "Setting up...";
|
|
208
|
+
readonly success: "Passkey set up successfully!";
|
|
209
|
+
readonly error: "Failed to set up passkey. Please try again.";
|
|
210
|
+
};
|
|
197
211
|
};
|
|
198
212
|
readonly success: {
|
|
199
213
|
readonly title: "Success!";
|
package/dist/index.d.ts
CHANGED
|
@@ -61,6 +61,7 @@ declare const VolrUIProvider: React$1.FC<VolrUIProviderProps>;
|
|
|
61
61
|
/**
|
|
62
62
|
* Passkey Enrollment View Component
|
|
63
63
|
* Modern passkey setup with device-specific biometric icons
|
|
64
|
+
* Includes cross-domain migration detection and guidance
|
|
64
65
|
*/
|
|
65
66
|
interface PasskeyEnrollViewProps {
|
|
66
67
|
onComplete: () => void;
|
|
@@ -194,6 +195,19 @@ declare const en: {
|
|
|
194
195
|
readonly default: "Please use this device's biometric.";
|
|
195
196
|
readonly note: "Using other devices or apps may not work.";
|
|
196
197
|
};
|
|
198
|
+
readonly migration: {
|
|
199
|
+
readonly title: "Set up passkey for this site";
|
|
200
|
+
readonly description: "Your wallet was created on {{sourceDomain}}. To use it here, you need to set up a new passkey for this site.";
|
|
201
|
+
readonly descriptionGeneric: "Your wallet was created on a different site. To use it here, you need to set up a new passkey for this site.";
|
|
202
|
+
readonly currentDomain: "Current site";
|
|
203
|
+
readonly sourceDomain: "Original site";
|
|
204
|
+
readonly benefits: "Your wallet address and balance will remain the same.";
|
|
205
|
+
readonly cta: "Set up passkey";
|
|
206
|
+
readonly later: "Do it later";
|
|
207
|
+
readonly inProgress: "Setting up...";
|
|
208
|
+
readonly success: "Passkey set up successfully!";
|
|
209
|
+
readonly error: "Failed to set up passkey. Please try again.";
|
|
210
|
+
};
|
|
197
211
|
};
|
|
198
212
|
readonly success: {
|
|
199
213
|
readonly title: "Success!";
|
package/dist/index.js
CHANGED
|
@@ -570,6 +570,19 @@ var en = {
|
|
|
570
570
|
windows: "Please use your phone via QR code. (Windows Hello is not supported)",
|
|
571
571
|
default: "Please use this device's biometric.",
|
|
572
572
|
note: "Using other devices or apps may not work."
|
|
573
|
+
},
|
|
574
|
+
migration: {
|
|
575
|
+
title: "Set up passkey for this site",
|
|
576
|
+
description: "Your wallet was created on {{sourceDomain}}. To use it here, you need to set up a new passkey for this site.",
|
|
577
|
+
descriptionGeneric: "Your wallet was created on a different site. To use it here, you need to set up a new passkey for this site.",
|
|
578
|
+
currentDomain: "Current site",
|
|
579
|
+
sourceDomain: "Original site",
|
|
580
|
+
benefits: "Your wallet address and balance will remain the same.",
|
|
581
|
+
cta: "Set up passkey",
|
|
582
|
+
later: "Do it later",
|
|
583
|
+
inProgress: "Setting up...",
|
|
584
|
+
success: "Passkey set up successfully!",
|
|
585
|
+
error: "Failed to set up passkey. Please try again."
|
|
573
586
|
}
|
|
574
587
|
},
|
|
575
588
|
success: {
|
|
@@ -799,6 +812,19 @@ var ko = {
|
|
|
799
812
|
windows: "QR \uCF54\uB4DC\uB85C \uD734\uB300\uD3F0\uC744 \uC0AC\uC6A9\uD574\uC8FC\uC138\uC694. (Windows Hello\uB294 \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4)",
|
|
800
813
|
default: "\uC774 \uAE30\uAE30\uC758 \uC0DD\uCCB4 \uC778\uC99D\uC744 \uC0AC\uC6A9\uD574\uC8FC\uC138\uC694.",
|
|
801
814
|
note: "\uB2E4\uB978 \uAE30\uAE30\uB098 \uC571 \uC0AC\uC6A9 \uC2DC \uB3D9\uC791\uD558\uC9C0 \uC54A\uC744 \uC218 \uC788\uC2B5\uB2C8\uB2E4."
|
|
815
|
+
},
|
|
816
|
+
migration: {
|
|
817
|
+
title: "\uC774 \uC0AC\uC774\uD2B8\uC6A9 \uD328\uC2A4\uD0A4 \uC124\uC815",
|
|
818
|
+
description: "\uC9C0\uAC11\uC774 {{sourceDomain}}\uC5D0\uC11C \uC0DD\uC131\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uC774 \uC0AC\uC774\uD2B8\uC5D0\uC11C \uC0AC\uC6A9\uD558\uB824\uBA74 \uC0C8 \uD328\uC2A4\uD0A4\uB97C \uC124\uC815\uD574\uC57C \uD569\uB2C8\uB2E4.",
|
|
819
|
+
descriptionGeneric: "\uC9C0\uAC11\uC774 \uB2E4\uB978 \uC0AC\uC774\uD2B8\uC5D0\uC11C \uC0DD\uC131\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uC774 \uC0AC\uC774\uD2B8\uC5D0\uC11C \uC0AC\uC6A9\uD558\uB824\uBA74 \uC0C8 \uD328\uC2A4\uD0A4\uB97C \uC124\uC815\uD574\uC57C \uD569\uB2C8\uB2E4.",
|
|
820
|
+
currentDomain: "\uD604\uC7AC \uC0AC\uC774\uD2B8",
|
|
821
|
+
sourceDomain: "\uC6D0\uBCF8 \uC0AC\uC774\uD2B8",
|
|
822
|
+
benefits: "\uC9C0\uAC11 \uC8FC\uC18C\uC640 \uC794\uC561\uC740 \uADF8\uB300\uB85C \uC720\uC9C0\uB429\uB2C8\uB2E4.",
|
|
823
|
+
cta: "\uD328\uC2A4\uD0A4 \uC124\uC815\uD558\uAE30",
|
|
824
|
+
later: "\uB098\uC911\uC5D0 \uD558\uAE30",
|
|
825
|
+
inProgress: "\uC124\uC815 \uC911...",
|
|
826
|
+
success: "\uD328\uC2A4\uD0A4 \uC124\uC815\uC774 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4!",
|
|
827
|
+
error: "\uD328\uC2A4\uD0A4 \uC124\uC815\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694."
|
|
802
828
|
}
|
|
803
829
|
},
|
|
804
830
|
success: {
|
|
@@ -1858,6 +1884,84 @@ function PasskeyCompatibilityScreen({
|
|
|
1858
1884
|
] })
|
|
1859
1885
|
] });
|
|
1860
1886
|
}
|
|
1887
|
+
function PasskeyMigrationView({
|
|
1888
|
+
sourcePasskey,
|
|
1889
|
+
currentDomain,
|
|
1890
|
+
onMigrate,
|
|
1891
|
+
onSkip,
|
|
1892
|
+
onError,
|
|
1893
|
+
isOpen = true,
|
|
1894
|
+
wrapInModal = true
|
|
1895
|
+
}) {
|
|
1896
|
+
const { t } = useI18n();
|
|
1897
|
+
const [isMigrating, setIsMigrating] = useState(false);
|
|
1898
|
+
const [error, setError] = useState(null);
|
|
1899
|
+
const biometricType = getBiometricType();
|
|
1900
|
+
const handleMigrate = async () => {
|
|
1901
|
+
try {
|
|
1902
|
+
setIsMigrating(true);
|
|
1903
|
+
setError(null);
|
|
1904
|
+
await onMigrate();
|
|
1905
|
+
} catch (err) {
|
|
1906
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
1907
|
+
setError(t("passkey.migration.error"));
|
|
1908
|
+
if (onError) {
|
|
1909
|
+
onError(err instanceof Error ? err : new Error(errorMessage));
|
|
1910
|
+
}
|
|
1911
|
+
} finally {
|
|
1912
|
+
setIsMigrating(false);
|
|
1913
|
+
}
|
|
1914
|
+
};
|
|
1915
|
+
const content = /* @__PURE__ */ jsxs("div", { children: [
|
|
1916
|
+
/* @__PURE__ */ jsx("p", { className: "volr:text-xl volr:font-semibold volr:mb-4", children: t("passkey.migration.title") }),
|
|
1917
|
+
/* @__PURE__ */ jsx("div", { className: "volr:my-6 volr:flex volr:justify-center", children: /* @__PURE__ */ jsx(BiometricIcon, { type: biometricType, size: 48 }) }),
|
|
1918
|
+
/* @__PURE__ */ jsx("p", { className: "volr:text-sm volr:mb-4 volr:text-center volr-text-secondary", children: sourcePasskey.rpId ? t("passkey.migration.description").replace(
|
|
1919
|
+
"{{sourceDomain}}",
|
|
1920
|
+
sourcePasskey.rpId
|
|
1921
|
+
) : t("passkey.migration.descriptionGeneric") }),
|
|
1922
|
+
/* @__PURE__ */ jsxs("div", { className: "volr:mb-4 volr:p-3 volr:rounded-lg volr:border volr:border-slate-200 volr:bg-slate-50", children: [
|
|
1923
|
+
/* @__PURE__ */ jsxs("div", { className: "volr:flex volr:justify-between volr:items-center volr:text-sm volr:mb-2", children: [
|
|
1924
|
+
/* @__PURE__ */ jsx("span", { className: "volr-text-secondary", children: t("passkey.migration.sourceDomain") }),
|
|
1925
|
+
/* @__PURE__ */ jsx("span", { className: "volr:font-mono volr:text-xs", children: sourcePasskey.rpId })
|
|
1926
|
+
] }),
|
|
1927
|
+
/* @__PURE__ */ jsxs("div", { className: "volr:flex volr:justify-between volr:items-center volr:text-sm", children: [
|
|
1928
|
+
/* @__PURE__ */ jsx("span", { className: "volr-text-secondary", children: t("passkey.migration.currentDomain") }),
|
|
1929
|
+
/* @__PURE__ */ jsx("span", { className: "volr:font-mono volr:text-xs", children: currentDomain })
|
|
1930
|
+
] })
|
|
1931
|
+
] }),
|
|
1932
|
+
/* @__PURE__ */ jsx("div", { className: "volr:mb-6 volr:p-3 volr:rounded-lg volr-hint", children: /* @__PURE__ */ jsxs("p", { className: "volr:text-sm volr:flex volr:items-start volr:gap-2", children: [
|
|
1933
|
+
/* @__PURE__ */ jsx("span", { className: "volr:text-base", children: "\u2713" }),
|
|
1934
|
+
/* @__PURE__ */ jsx("span", { children: t("passkey.migration.benefits") })
|
|
1935
|
+
] }) }),
|
|
1936
|
+
error && /* @__PURE__ */ jsx("div", { className: "volr:mb-4 volr:p-3 volr:rounded-lg volr:border volr:text-sm volr:text-left volr-error", children: /* @__PURE__ */ jsx("span", { children: error }) }),
|
|
1937
|
+
/* @__PURE__ */ jsxs("div", { className: "volr:flex volr:flex-col volr:gap-3", children: [
|
|
1938
|
+
/* @__PURE__ */ jsx(
|
|
1939
|
+
Button,
|
|
1940
|
+
{
|
|
1941
|
+
variant: "primary",
|
|
1942
|
+
fullWidth: true,
|
|
1943
|
+
onClick: handleMigrate,
|
|
1944
|
+
disabled: isMigrating,
|
|
1945
|
+
children: isMigrating ? t("passkey.migration.inProgress") : t("passkey.migration.cta")
|
|
1946
|
+
}
|
|
1947
|
+
),
|
|
1948
|
+
onSkip && /* @__PURE__ */ jsx(
|
|
1949
|
+
Button,
|
|
1950
|
+
{
|
|
1951
|
+
variant: "ghost",
|
|
1952
|
+
fullWidth: true,
|
|
1953
|
+
onClick: onSkip,
|
|
1954
|
+
disabled: isMigrating,
|
|
1955
|
+
children: t("passkey.migration.later")
|
|
1956
|
+
}
|
|
1957
|
+
)
|
|
1958
|
+
] })
|
|
1959
|
+
] });
|
|
1960
|
+
if (!wrapInModal) {
|
|
1961
|
+
return content;
|
|
1962
|
+
}
|
|
1963
|
+
return /* @__PURE__ */ jsx(Modal, { open: isOpen, onOpenChange: (open) => !open && onSkip?.(), children: content });
|
|
1964
|
+
}
|
|
1861
1965
|
function PasskeyEnrollView({
|
|
1862
1966
|
onComplete,
|
|
1863
1967
|
onError,
|
|
@@ -1886,14 +1990,34 @@ function PasskeyEnrollView({
|
|
|
1886
1990
|
[compatibility.platform]
|
|
1887
1991
|
);
|
|
1888
1992
|
const hasPasskey = user?.keyStorageType === "passkey";
|
|
1993
|
+
const currentDomain = useMemo(() => {
|
|
1994
|
+
if (typeof window === "undefined") return "localhost";
|
|
1995
|
+
return window.location.hostname;
|
|
1996
|
+
}, []);
|
|
1997
|
+
const migrationInfo = useMemo(() => {
|
|
1998
|
+
if (!user?.registeredPasskeys || user.registeredPasskeys.length === 0) {
|
|
1999
|
+
return { needsMigration: false, sourcePasskey: null };
|
|
2000
|
+
}
|
|
2001
|
+
const hasPasskeyOnCurrentDomain = user.registeredPasskeys.some(
|
|
2002
|
+
(pk) => pk.rpId === currentDomain
|
|
2003
|
+
);
|
|
2004
|
+
if (hasPasskeyOnCurrentDomain) {
|
|
2005
|
+
return { needsMigration: false, sourcePasskey: null };
|
|
2006
|
+
}
|
|
2007
|
+
const sourcePasskey = user.registeredPasskeys[0];
|
|
2008
|
+
return { needsMigration: true, sourcePasskey };
|
|
2009
|
+
}, [user?.registeredPasskeys, currentDomain]);
|
|
1889
2010
|
useEffect(() => {
|
|
1890
2011
|
console.log("[PasskeyEnrollView] User state:", {
|
|
1891
2012
|
user,
|
|
1892
2013
|
keyStorageType: user?.keyStorageType,
|
|
1893
2014
|
evmAddress: user?.evmAddress,
|
|
1894
|
-
hasPasskey
|
|
2015
|
+
hasPasskey,
|
|
2016
|
+
registeredPasskeys: user?.registeredPasskeys,
|
|
2017
|
+
currentDomain,
|
|
2018
|
+
migrationInfo
|
|
1895
2019
|
});
|
|
1896
|
-
}, [user, hasPasskey]);
|
|
2020
|
+
}, [user, hasPasskey, currentDomain, migrationInfo]);
|
|
1897
2021
|
useEffect(() => {
|
|
1898
2022
|
if (hasPasskey && !user?.evmAddress && !isRefreshing) {
|
|
1899
2023
|
const refreshUserData = async () => {
|
|
@@ -2031,6 +2155,23 @@ function PasskeyEnrollView({
|
|
|
2031
2155
|
}
|
|
2032
2156
|
return /* @__PURE__ */ jsx(Modal, { open: isOpen, onOpenChange: (open) => !open && onLogout?.(), children: compatibilityContent });
|
|
2033
2157
|
}
|
|
2158
|
+
if (migrationInfo.needsMigration && migrationInfo.sourcePasskey) {
|
|
2159
|
+
const handleMigration = async () => {
|
|
2160
|
+
await handleEnroll();
|
|
2161
|
+
};
|
|
2162
|
+
return /* @__PURE__ */ jsx(
|
|
2163
|
+
PasskeyMigrationView,
|
|
2164
|
+
{
|
|
2165
|
+
sourcePasskey: migrationInfo.sourcePasskey,
|
|
2166
|
+
currentDomain,
|
|
2167
|
+
onMigrate: handleMigration,
|
|
2168
|
+
onSkip: handleLogout,
|
|
2169
|
+
onError,
|
|
2170
|
+
isOpen,
|
|
2171
|
+
wrapInModal
|
|
2172
|
+
}
|
|
2173
|
+
);
|
|
2174
|
+
}
|
|
2034
2175
|
if (hasPasskey) {
|
|
2035
2176
|
const handleClose = () => {
|
|
2036
2177
|
if (onClose) {
|