@volr/react-ui 0.1.125 → 0.1.127

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
@@ -1,6 +1,6 @@
1
1
  import React13, { createContext, useContext, useState, useMemo, useEffect, useCallback, useRef, useId, useReducer } from 'react';
2
2
  import { createPortal } from 'react-dom';
3
- import { useVolrContext, useInternalAuth, usePasskeyEnrollment, checkPrfCompatibility, getPlatformHint, useMpcConnection, VolrProvider, useVolrAuthCallback, useVolrPaymentApi, useUserBalances, useVolrLogin, useVolr, useWithdraw, useDepositListener, createGetNetworkInfo, useEIP6963 } from '@volr/react';
3
+ import { useVolrContext, useInternalAuth, usePasskeyEnrollment, checkPrfCompatibility, getPlatformHint, useMpcConnection, VolrProvider, useVolrAuthCallback, useVolrPaymentApi, completeMigration, requestMigration, decryptEntropyForMigration, listenForSeedRequests, useUserBalances, useVolrLogin, useVolr, useWithdraw, useDepositListener, createGetNetworkInfo, useEIP6963 } from '@volr/react';
4
4
  export { VolrProvider, useDepositListener, usePasskeyEnrollment, useVolr, useVolrLogin, useVolrPaymentApi } from '@volr/react';
5
5
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
6
6
  import { clsx } from 'clsx';
@@ -2157,7 +2157,12 @@ function PasskeyEnrollView({
2157
2157
  }
2158
2158
  if (migrationInfo.needsMigration && migrationInfo.sourcePasskey) {
2159
2159
  const handleMigration = async () => {
2160
- await handleEnroll();
2160
+ const targetOrigin = typeof window !== "undefined" ? window.location.origin : "";
2161
+ const sourceRpId = migrationInfo.sourcePasskey.rpId;
2162
+ const sourceOrigin = sourceRpId === "localhost" ? "http://localhost" : `https://${sourceRpId}`;
2163
+ const url = new URL(sourceOrigin);
2164
+ url.searchParams.set("volr_migrate_to", targetOrigin);
2165
+ window.open(url.toString(), "_blank", "noopener,noreferrer");
2161
2166
  };
2162
2167
  return /* @__PURE__ */ jsx(
2163
2168
  PasskeyMigrationView,
@@ -6798,6 +6803,13 @@ function VolrUIProviderInner({
6798
6803
  keyStorageType
6799
6804
  },
6800
6805
  children: /* @__PURE__ */ jsxs(VolrModalProvider, { children: [
6806
+ /* @__PURE__ */ jsx(
6807
+ MigrationCoordinator,
6808
+ {
6809
+ onShowOnboarding: () => setShowOnboarding(true),
6810
+ onHideOnboarding: () => setShowOnboarding(false)
6811
+ }
6812
+ ),
6801
6813
  /* @__PURE__ */ jsx(
6802
6814
  OAuthCallbackHandler,
6803
6815
  {
@@ -6840,6 +6852,130 @@ function VolrUIProviderInner({
6840
6852
  }
6841
6853
  ) }) });
6842
6854
  }
6855
+ function normalizeOrigin(input) {
6856
+ try {
6857
+ const u = new URL(input);
6858
+ return `${u.protocol}//${u.host}`;
6859
+ } catch {
6860
+ return input;
6861
+ }
6862
+ }
6863
+ function MigrationCoordinator({
6864
+ onShowOnboarding,
6865
+ onHideOnboarding
6866
+ }) {
6867
+ const { user, setUser } = useVolrContext();
6868
+ const { client } = useInternalAuth();
6869
+ const [running, setRunning] = useState(false);
6870
+ useEffect(() => {
6871
+ if (typeof window === "undefined") return;
6872
+ const handler = (event) => {
6873
+ const data = event.data;
6874
+ if (data?.type === "VOLR_MIGRATION_DONE") {
6875
+ client.refreshSession().then((u) => u && setUser(u)).catch(() => void 0);
6876
+ onHideOnboarding();
6877
+ }
6878
+ };
6879
+ window.addEventListener("message", handler);
6880
+ return () => window.removeEventListener("message", handler);
6881
+ }, [client, setUser, onHideOnboarding]);
6882
+ useEffect(() => {
6883
+ if (typeof window === "undefined") return;
6884
+ if (running) return;
6885
+ const params = new URLSearchParams(window.location.search);
6886
+ const migrationToken = params.get("migration_token");
6887
+ const sourceOriginParam = params.get("source_origin");
6888
+ const isTargetPopup = Boolean(migrationToken && sourceOriginParam);
6889
+ const migrateTo = params.get("volr_migrate_to");
6890
+ const isSourceFlow = Boolean(migrateTo);
6891
+ if (!isTargetPopup && !isSourceFlow) {
6892
+ return;
6893
+ }
6894
+ const run = async () => {
6895
+ setRunning(true);
6896
+ try {
6897
+ if (isTargetPopup) {
6898
+ const sourceOrigin2 = normalizeOrigin(sourceOriginParam);
6899
+ const token2 = migrationToken;
6900
+ const refreshedUser2 = await client.refreshSession();
6901
+ const effectiveUser2 = refreshedUser2 ?? user;
6902
+ if (refreshedUser2) setUser(refreshedUser2);
6903
+ if (!effectiveUser2?.id || !effectiveUser2?.projectId) {
6904
+ throw new Error(
6905
+ "Migration requires an active session on the target site. Please log in first."
6906
+ );
6907
+ }
6908
+ const { requestSeedFromOpener } = await import('@volr/react');
6909
+ const seed = await requestSeedFromOpener(sourceOrigin2, token2);
6910
+ await completeMigration({
6911
+ client,
6912
+ userId: seed.userId,
6913
+ projectId: seed.projectId,
6914
+ migrationToken: token2,
6915
+ masterSeed: seed.masterSeed,
6916
+ rpName: effectiveUser2.projectName ?? "Volr",
6917
+ userEmail: effectiveUser2.email ?? null
6918
+ });
6919
+ try {
6920
+ window.opener?.postMessage({ type: "VOLR_MIGRATION_DONE" }, "*");
6921
+ } catch {
6922
+ }
6923
+ window.close();
6924
+ return;
6925
+ }
6926
+ const targetOrigin = normalizeOrigin(migrateTo);
6927
+ const sourceOrigin = window.location.origin;
6928
+ const refreshedUser = await client.refreshSession();
6929
+ const effectiveUser = refreshedUser ?? user;
6930
+ if (refreshedUser) setUser(refreshedUser);
6931
+ if (!effectiveUser?.id || !effectiveUser?.projectId) {
6932
+ throw new Error(
6933
+ "Migration requires an active session on the source site. Please log in first."
6934
+ );
6935
+ }
6936
+ const currentRpId = getCurrentRpId();
6937
+ const sourcePasskey = effectiveUser.registeredPasskeys?.find((p) => p?.rpId === currentRpId) ?? null;
6938
+ if (!sourcePasskey?.credentialId || !sourcePasskey?.blobUrl || !sourcePasskey?.prfInput) {
6939
+ throw new Error(
6940
+ `No passkey registered for source rpId=${currentRpId}. Cannot migrate from this site.`
6941
+ );
6942
+ }
6943
+ const token = await requestMigration({ client, targetOrigin });
6944
+ const entropy = await decryptEntropyForMigration({
6945
+ client,
6946
+ userId: effectiveUser.id,
6947
+ blobUrl: sourcePasskey.blobUrl,
6948
+ prfInput: sourcePasskey.prfInput,
6949
+ credentialId: sourcePasskey.credentialId,
6950
+ rpName: effectiveUser.projectName ?? "Volr"
6951
+ });
6952
+ const cleanup = listenForSeedRequests(
6953
+ [targetOrigin],
6954
+ async () => entropy,
6955
+ () => ({ userId: effectiveUser.id, projectId: effectiveUser.projectId })
6956
+ );
6957
+ const url = new URL(targetOrigin);
6958
+ url.searchParams.set("migration_token", token.migrationToken);
6959
+ url.searchParams.set("source_origin", sourceOrigin);
6960
+ window.open(
6961
+ url.toString(),
6962
+ "volr_migration",
6963
+ "width=500,height=650,left=100,top=100,popup=1"
6964
+ );
6965
+ onShowOnboarding();
6966
+ setTimeout(() => cleanup(), 2 * 60 * 1e3);
6967
+ return;
6968
+ } finally {
6969
+ setRunning(false);
6970
+ }
6971
+ };
6972
+ run().catch((e) => {
6973
+ console.error("[MigrationCoordinator] failed:", e);
6974
+ setRunning(false);
6975
+ });
6976
+ }, [client, user, setUser, running, onShowOnboarding, onHideOnboarding]);
6977
+ return null;
6978
+ }
6843
6979
  function AccountModalPortal() {
6844
6980
  const { isOpen, mode, close } = useVolrModal();
6845
6981
  const [portalRoot, setPortalRoot] = useState(null);