@volr/react 0.1.90 → 0.1.92

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 CHANGED
@@ -9781,7 +9781,9 @@ async function restorePasskey(params) {
9781
9781
  userId,
9782
9782
  blobUrl,
9783
9783
  prfInput,
9784
- credentialId: providedCredentialId
9784
+ credentialId: providedCredentialId,
9785
+ rpId = typeof window !== "undefined" ? window.location.hostname : "localhost",
9786
+ rpName = "Volr"
9785
9787
  } = params;
9786
9788
  const credentialId = providedCredentialId || prfInput.credentialId || safeStorage.getItem(STORAGE_KEYS.credentialId);
9787
9789
  if (!credentialId) {
@@ -9810,7 +9812,7 @@ async function restorePasskey(params) {
9810
9812
  `volr/master-seed/v1|${userId}|${keyStorageType}|${version5}`
9811
9813
  );
9812
9814
  const passkeyAdapter = createPasskeyAdapter({
9813
- rpId: typeof window !== "undefined" ? window.location.hostname : "localhost"});
9815
+ rpId});
9814
9816
  const provider = sdkCore.createPasskeyProvider(passkeyAdapter, {
9815
9817
  prfInput: {
9816
9818
  ...prfInput,
@@ -18701,6 +18703,8 @@ function useVolrLogin() {
18701
18703
  const toVolrUser = react.useCallback((u) => {
18702
18704
  return {
18703
18705
  id: u.id,
18706
+ projectId: u.projectId,
18707
+ projectName: u.projectName,
18704
18708
  email: u.email,
18705
18709
  accountId: u.accountId ?? void 0,
18706
18710
  evmAddress: u.evmAddress,
@@ -18916,6 +18920,8 @@ function useVolrAuthCallback(options = {}) {
18916
18920
  const toVolrUser = react.useCallback((u) => {
18917
18921
  return {
18918
18922
  id: u.id,
18923
+ projectId: u.projectId,
18924
+ projectName: u.projectName,
18919
18925
  email: u.email,
18920
18926
  accountId: u.accountId ?? void 0,
18921
18927
  evmAddress: u.evmAddress,
@@ -19182,7 +19188,7 @@ async function enrollPasskey(params) {
19182
19188
  userEvmAddress,
19183
19189
  projectId,
19184
19190
  rpId = typeof window !== "undefined" ? window.location.hostname : "localhost",
19185
- rpName = "Volr"
19191
+ rpName
19186
19192
  } = params;
19187
19193
  if (!userId) {
19188
19194
  throw new Error("userId is required");
@@ -19190,6 +19196,9 @@ async function enrollPasskey(params) {
19190
19196
  if (!projectId) {
19191
19197
  throw new Error("projectId is required");
19192
19198
  }
19199
+ if (!rpName) {
19200
+ throw new Error("rpName is required");
19201
+ }
19193
19202
  if (!baseUrl) {
19194
19203
  throw new Error("baseUrl is required");
19195
19204
  }
@@ -19203,9 +19212,7 @@ async function enrollPasskey(params) {
19203
19212
  crypto.getRandomValues(challenge2);
19204
19213
  const userHandle = new TextEncoder().encode(userId);
19205
19214
  const tempCredentialId = "temp-" + Date.now();
19206
- const origin = typeof window !== "undefined" ? window.location.origin : "https://localhost";
19207
19215
  const tempPrfInput = {
19208
- origin,
19209
19216
  projectId,
19210
19217
  credentialId: tempCredentialId
19211
19218
  };
@@ -19248,7 +19255,6 @@ async function enrollPasskey(params) {
19248
19255
  const prfOutputBuffer = extensionResults.prf.results.first;
19249
19256
  const prfOutput = new Uint8Array(prfOutputBuffer);
19250
19257
  const prfInput = {
19251
- origin,
19252
19258
  projectId,
19253
19259
  credentialId
19254
19260
  };
@@ -19284,7 +19290,6 @@ async function enrollPasskey(params) {
19284
19290
  apiKey,
19285
19291
  accessToken,
19286
19292
  blob
19287
- // Don't pass axiosInstance - let uploadBlob create its own
19288
19293
  });
19289
19294
  if (!blobUrl) {
19290
19295
  throw new Error("Failed to upload blob: missing key");
@@ -19297,7 +19302,6 @@ async function enrollPasskey(params) {
19297
19302
  credentialId,
19298
19303
  blobUrl,
19299
19304
  prfInput: {
19300
- origin,
19301
19305
  projectId,
19302
19306
  credentialId
19303
19307
  },
@@ -19345,7 +19349,17 @@ function usePasskeyEnrollment() {
19345
19349
  "Access token is required for passkey enrollment. Please login first."
19346
19350
  );
19347
19351
  }
19348
- const projectId = user.id;
19352
+ if (!user.projectId) {
19353
+ throw new Error(
19354
+ "Project ID is required for passkey enrollment. User data may be incomplete."
19355
+ );
19356
+ }
19357
+ if (!user.projectName) {
19358
+ throw new Error(
19359
+ "Project name is required for passkey enrollment. User data may be incomplete."
19360
+ );
19361
+ }
19362
+ const projectId = user.projectId;
19349
19363
  setStep("encrypting");
19350
19364
  const result = await enrollPasskey({
19351
19365
  client,
@@ -19354,7 +19368,8 @@ function usePasskeyEnrollment() {
19354
19368
  userId: user.id,
19355
19369
  userEmail: user.email ?? null,
19356
19370
  userEvmAddress: user.evmAddress ?? null,
19357
- projectId
19371
+ projectId,
19372
+ rpName: user.projectName
19358
19373
  });
19359
19374
  setStep("registering");
19360
19375
  if (typeof window !== "undefined") {
@@ -19362,7 +19377,7 @@ function usePasskeyEnrollment() {
19362
19377
  }
19363
19378
  const passkeyAdapter = createPasskeyAdapter({
19364
19379
  rpId: typeof window !== "undefined" ? window.location.hostname : "localhost",
19365
- rpName: "Volr"
19380
+ rpName: user.projectName
19366
19381
  });
19367
19382
  const provider = sdkCore.createPasskeyProvider(passkeyAdapter, {
19368
19383
  prfInput: result.prfInput,
@@ -19971,6 +19986,232 @@ async function checkPrfExtensionAvailable() {
19971
19986
  const { prfSupported } = checkPrfSupport();
19972
19987
  return prfSupported;
19973
19988
  }
19989
+ async function requestMigration(params) {
19990
+ const { client, targetOrigin } = params;
19991
+ const response = await client.post("/wallet/migration/request", { targetOrigin });
19992
+ return {
19993
+ migrationToken: response.migrationToken,
19994
+ targetOrigin: response.targetOrigin,
19995
+ expiresAt: response.expiresAt
19996
+ };
19997
+ }
19998
+ function openMigrationPopup(targetOrigin, migrationToken, migrationPath = "/wallet/migrate") {
19999
+ const url = new URL(migrationPath, targetOrigin);
20000
+ url.searchParams.set("migration_token", migrationToken);
20001
+ const width = 500;
20002
+ const height = 600;
20003
+ const left = window.screenX + (window.outerWidth - width) / 2;
20004
+ const top = window.screenY + (window.outerHeight - height) / 2;
20005
+ return window.open(
20006
+ url.toString(),
20007
+ "volr_migration",
20008
+ `width=${width},height=${height},left=${left},top=${top},popup=1`
20009
+ );
20010
+ }
20011
+ function sendSeedToPopup(masterSeed, userId, projectId, targetOrigin, popup) {
20012
+ const response = {
20013
+ type: "VOLR_MIGRATION_SEED_RESPONSE",
20014
+ masterSeed: Array.from(masterSeed),
20015
+ userId,
20016
+ projectId
20017
+ };
20018
+ popup.postMessage(response, targetOrigin);
20019
+ }
20020
+ function listenForSeedRequests(allowedOrigins, getMasterSeed, getUserInfo) {
20021
+ const handleMessage = async (event) => {
20022
+ if (!allowedOrigins.includes(event.origin)) {
20023
+ return;
20024
+ }
20025
+ const data = event.data;
20026
+ if (data?.type !== "VOLR_MIGRATION_SEED_REQUEST") {
20027
+ return;
20028
+ }
20029
+ try {
20030
+ const masterSeed = await getMasterSeed();
20031
+ const { userId, projectId } = getUserInfo();
20032
+ const response = {
20033
+ type: "VOLR_MIGRATION_SEED_RESPONSE",
20034
+ masterSeed: Array.from(masterSeed),
20035
+ userId,
20036
+ projectId
20037
+ };
20038
+ event.source?.postMessage(response, { targetOrigin: event.origin });
20039
+ } catch (error) {
20040
+ const errorResponse = {
20041
+ type: "VOLR_MIGRATION_ERROR",
20042
+ code: "SEED_RETRIEVAL_FAILED",
20043
+ message: error instanceof Error ? error.message : "Failed to retrieve master seed"
20044
+ };
20045
+ event.source?.postMessage(errorResponse, { targetOrigin: event.origin });
20046
+ }
20047
+ };
20048
+ window.addEventListener("message", handleMessage);
20049
+ return () => {
20050
+ window.removeEventListener("message", handleMessage);
20051
+ };
20052
+ }
20053
+ function requestSeedFromOpener(sourceOrigin, migrationToken, timeout = 6e4) {
20054
+ return new Promise((resolve, reject) => {
20055
+ if (!window.opener) {
20056
+ reject(new Error("No opener window found. This page must be opened as a popup."));
20057
+ return;
20058
+ }
20059
+ const timeoutId = setTimeout(() => {
20060
+ window.removeEventListener("message", handleMessage);
20061
+ reject(new Error("Seed request timed out"));
20062
+ }, timeout);
20063
+ const handleMessage = (event) => {
20064
+ if (event.origin !== sourceOrigin) {
20065
+ return;
20066
+ }
20067
+ const data = event.data;
20068
+ if (data?.type === "VOLR_MIGRATION_SEED_RESPONSE") {
20069
+ clearTimeout(timeoutId);
20070
+ window.removeEventListener("message", handleMessage);
20071
+ resolve({
20072
+ masterSeed: new Uint8Array(data.masterSeed),
20073
+ userId: data.userId,
20074
+ projectId: data.projectId
20075
+ });
20076
+ } else if (data?.type === "VOLR_MIGRATION_ERROR") {
20077
+ clearTimeout(timeoutId);
20078
+ window.removeEventListener("message", handleMessage);
20079
+ reject(new Error(`${data.code}: ${data.message}`));
20080
+ }
20081
+ };
20082
+ window.addEventListener("message", handleMessage);
20083
+ const request = {
20084
+ type: "VOLR_MIGRATION_SEED_REQUEST",
20085
+ migrationToken
20086
+ };
20087
+ window.opener.postMessage(request, sourceOrigin);
20088
+ });
20089
+ }
20090
+ function detectPlatform3() {
20091
+ if (typeof navigator === "undefined") return "Unknown";
20092
+ const ua = navigator.userAgent;
20093
+ const platform = navigator.platform || "";
20094
+ if (/iPhone|iPad|iPod/.test(ua) || platform === "MacIntel" && navigator.maxTouchPoints > 1) {
20095
+ return "iOS";
20096
+ }
20097
+ if (/Android/.test(ua)) return "Android";
20098
+ if (/Mac/.test(platform)) return "macOS";
20099
+ if (/Win/.test(platform)) return "Windows";
20100
+ if (/CrOS/.test(ua)) return "ChromeOS";
20101
+ if (/Linux/.test(platform)) return "Linux";
20102
+ return "Unknown";
20103
+ }
20104
+ async function completeMigration(params) {
20105
+ const {
20106
+ client,
20107
+ baseUrl,
20108
+ apiKey,
20109
+ userId,
20110
+ projectId,
20111
+ migrationToken,
20112
+ masterSeed,
20113
+ rpId = typeof window !== "undefined" ? window.location.hostname : "localhost",
20114
+ rpName = "Volr",
20115
+ userEmail
20116
+ } = params;
20117
+ if (!navigator.credentials || !navigator.credentials.create) {
20118
+ throw new Error("WebAuthn API is not supported");
20119
+ }
20120
+ const challenge2 = new Uint8Array(32);
20121
+ crypto.getRandomValues(challenge2);
20122
+ const userHandle = new TextEncoder().encode(userId);
20123
+ const displayName = userEmail || `Volr Wallet (${userId.substring(0, 8)}...)`;
20124
+ const tempCredentialId = "temp-" + Date.now();
20125
+ const tempPrfInput = {
20126
+ projectId,
20127
+ credentialId: tempCredentialId
20128
+ };
20129
+ const prfSalt = sdkCore.deriveWrapKey(tempPrfInput);
20130
+ const publicKeyCredentialCreationOptions = {
20131
+ challenge: challenge2,
20132
+ rp: {
20133
+ name: rpName,
20134
+ id: rpId
20135
+ },
20136
+ user: {
20137
+ id: userHandle,
20138
+ name: displayName,
20139
+ displayName
20140
+ },
20141
+ pubKeyCredParams: PUBKEY_CRED_PARAMS,
20142
+ authenticatorSelection: AUTHENTICATOR_SELECTION,
20143
+ timeout: WEBAUTHN_TIMEOUT,
20144
+ attestation: ATTESTATION,
20145
+ extensions: {
20146
+ prf: {
20147
+ eval: {
20148
+ first: prfSalt.buffer
20149
+ }
20150
+ }
20151
+ }
20152
+ };
20153
+ const credential = await navigator.credentials.create({
20154
+ publicKey: publicKeyCredentialCreationOptions
20155
+ });
20156
+ if (!credential || !("response" in credential)) {
20157
+ throw new Error("Failed to create passkey credential");
20158
+ }
20159
+ const credentialId = Array.from(new Uint8Array(credential.rawId)).map((b) => b.toString(16).padStart(2, "0")).join("");
20160
+ const extensionResults = credential.getClientExtensionResults();
20161
+ if (!extensionResults.prf?.results?.first) {
20162
+ throw new Error("PRF extension not supported or PRF output missing");
20163
+ }
20164
+ const prfOutputBuffer = extensionResults.prf.results.first;
20165
+ const prfOutput = new Uint8Array(prfOutputBuffer);
20166
+ const wrapKey = prfOutput;
20167
+ const keyStorageType = "passkey";
20168
+ const version5 = "v1";
20169
+ const aadBytes = new TextEncoder().encode(
20170
+ `volr/master-seed/v1|${userId}|${keyStorageType}|${version5}`
20171
+ );
20172
+ const encryptedBlob = await sdkCore.sealMasterSeed(masterSeed, wrapKey, aadBytes);
20173
+ const blob = new Blob(
20174
+ [
20175
+ encryptedBlob.cipher,
20176
+ encryptedBlob.nonce
20177
+ ],
20178
+ { type: "application/octet-stream" }
20179
+ );
20180
+ const accessToken = client.getAccessToken();
20181
+ if (!accessToken) {
20182
+ throw new Error("Access token is required");
20183
+ }
20184
+ const { key: blobUrl } = await sdkCore.uploadBlob({
20185
+ baseUrl,
20186
+ apiKey,
20187
+ accessToken,
20188
+ blob
20189
+ });
20190
+ if (!blobUrl) {
20191
+ throw new Error("Failed to upload blob");
20192
+ }
20193
+ const platform = detectPlatform3();
20194
+ await client.post("/wallet/migration/complete", {
20195
+ migrationToken,
20196
+ credentialId,
20197
+ blobUrl,
20198
+ prfInput: {
20199
+ projectId,
20200
+ credentialId
20201
+ },
20202
+ rpId,
20203
+ platform
20204
+ });
20205
+ return {
20206
+ credentialId,
20207
+ blobUrl,
20208
+ rpId
20209
+ };
20210
+ }
20211
+ async function getUserCredentials(client) {
20212
+ const response = await client.get("/wallet/credentials");
20213
+ return response.credentials;
20214
+ }
19974
20215
  /*! Bundled license information:
19975
20216
 
19976
20217
  @noble/hashes/esm/utils.js:
@@ -20026,6 +20267,7 @@ exports.checkPrfExtensionAvailable = checkPrfExtensionAvailable;
20026
20267
  exports.checkPrfSupport = checkPrfSupport;
20027
20268
  exports.compareERC20Balances = compareERC20Balances;
20028
20269
  exports.compareWalletStates = compareWalletStates;
20270
+ exports.completeMigration = completeMigration;
20029
20271
  exports.createGetNetworkInfo = createGetNetworkInfo;
20030
20272
  exports.createPasskeyAdapter = createPasskeyAdapter;
20031
20273
  exports.debugTransactionFailure = debugTransactionFailure;
@@ -20033,11 +20275,17 @@ exports.defaultIdempotencyKey = defaultIdempotencyKey;
20033
20275
  exports.diagnoseTransactionFailure = diagnoseTransactionFailure;
20034
20276
  exports.getERC20Balance = getERC20Balance;
20035
20277
  exports.getPasskeyAuthGuidance = getPasskeyAuthGuidance;
20278
+ exports.getUserCredentials = getUserCredentials;
20036
20279
  exports.getWalletState = getWalletState;
20037
20280
  exports.isEIP7702Delegated = isEIP7702Delegated;
20038
20281
  exports.isUserCancelledError = isUserCancelledError;
20282
+ exports.listenForSeedRequests = listenForSeedRequests;
20039
20283
  exports.normalizeHex = normalizeHex;
20040
20284
  exports.normalizeHexArray = normalizeHexArray;
20285
+ exports.openMigrationPopup = openMigrationPopup;
20286
+ exports.requestMigration = requestMigration;
20287
+ exports.requestSeedFromOpener = requestSeedFromOpener;
20288
+ exports.sendSeedToPopup = sendSeedToPopup;
20041
20289
  exports.uploadBlobViaPresign = uploadBlobViaPresign;
20042
20290
  exports.useDepositListener = useDepositListener;
20043
20291
  exports.useInternalAuth = useInternalAuth;